Skip to content

Commit

Permalink
[tfjs-react-native] Fix bundleResourceIO in release builds (#2345)
Browse files Browse the repository at this point in the history
Updates how files are resolved by the bundle resource loader in prod builds. Addresses #2177

INTERNAL
BUG
  • Loading branch information
tafsiri authored Nov 13, 2019
1 parent 98e3141 commit 928fdc0
Show file tree
Hide file tree
Showing 19 changed files with 259 additions and 30 deletions.
3 changes: 2 additions & 1 deletion tfjs-react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ module.exports = {
- Install @tensorflow/tfjs - `npm install @tensorflow/tfjs`
- Install @tensorflow/tfjs-react-native - `npm install @tensorflow/tfjs-react-native@alpha`

### Step 5: Install and configure async-storage
### Step 5: Install and configure other peerDependencies

- Install and configure [async-storage](https://github.com/react-native-community/async-storage)
- Install and configure [react-native-fs](https://www.npmjs.com/package/react-native-fs)

### Step 6: Test that it is working

Expand Down
4 changes: 3 additions & 1 deletion tfjs-react-native/integration_rn59/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
* =============================================================================
*/

apply plugin: "com.android.application"

import com.android.build.OutputFile
Expand Down Expand Up @@ -156,11 +156,13 @@ android {
}

dependencies {
implementation project(':react-native-fs')
implementation project(':@react-native-community_async-storage')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation "com.facebook.react:react-native:+" // From node_modules
addUnimodulesDependencies()
compile project(':react-native-fs')
}

// Run this once to be able to run the application with BUCK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import android.app.Application;
import com.facebook.react.ReactApplication;
import com.rnfs.RNFSPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
Expand All @@ -44,7 +45,7 @@ public boolean getUseDeveloperSupport() {

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(new MainReactPackage(),
return Arrays.<ReactPackage>asList(new MainReactPackage(), new RNFSPackage(),
new ModuleRegistryAdapter(mModuleRegistryProvider), new AsyncStoragePackage());
}

Expand Down
3 changes: 3 additions & 0 deletions tfjs-react-native/integration_rn59/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ includeUnimodulesProjects()
include ':@react-native-community_async-storage'
project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')

include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')

rootProject.name = 'integration_rn59'

include ':app'
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"weightsManifest": [{"paths": ["group1-shard1of1.bin"], "weights": [{"dtype": "float32", "shape": [1], "name": "StatefulPartitionedCall/sequential/dense_Dense2/BiasAdd/ReadVariableOp"}, {"dtype": "float32", "shape": [10, 1], "name": "StatefulPartitionedCall/sequential/dense_Dense2/MatMul/ReadVariableOp"}]}], "modelTopology": {"node": [{"attr": {"dtype": {"type": "DT_FLOAT"}, "shape": {"shape": {"dim": [{"size": "-1"}, {"size": "10"}]}}}, "name": "dense_dense2_input", "op": "Placeholder"}, {"input": ["^dense_dense2_input"], "attr": {"dtype": {"type": "DT_FLOAT"}, "value": {"tensor": {"dtype": "DT_FLOAT", "tensorShape": {"dim": [{"size": "1"}]}}}}, "name": "StatefulPartitionedCall/sequential/dense_Dense2/BiasAdd/ReadVariableOp", "op": "Const"}, {"input": ["^dense_dense2_input"], "attr": {"dtype": {"type": "DT_FLOAT"}, "value": {"tensor": {"dtype": "DT_FLOAT", "tensorShape": {"dim": [{"size": "10"}, {"size": "1"}]}}}}, "name": "StatefulPartitionedCall/sequential/dense_Dense2/MatMul/ReadVariableOp", "op": "Const"}, {"input": ["dense_dense2_input", "StatefulPartitionedCall/sequential/dense_Dense2/MatMul/ReadVariableOp"], "attr": {"transpose_b": {"b": false}, "transpose_a": {"b": false}, "T": {"type": "DT_FLOAT"}}, "name": "StatefulPartitionedCall/sequential/dense_Dense2/MatMul", "op": "MatMul"}, {"input": ["StatefulPartitionedCall/sequential/dense_Dense2/MatMul", "StatefulPartitionedCall/sequential/dense_Dense2/BiasAdd/ReadVariableOp"], "attr": {"T": {"type": "DT_FLOAT"}, "data_format": {"s": "TkhXQw=="}}, "name": "StatefulPartitionedCall/sequential/dense_Dense2/BiasAdd", "op": "BiasAdd"}, {"input": ["StatefulPartitionedCall/sequential/dense_Dense2/BiasAdd"], "attr": {"T": {"type": "DT_FLOAT"}}, "name": "Identity", "op": "Identity"}], "versions": {"minConsumer": 12, "producer": 134}}, "generatedBy": "1.15.0", "convertedBy": "TensorFlow.js Converter v1.3.1.1", "format": "graph-model"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"modelTopology":{"class_name":"Sequential","config":[{"class_name":"Dense","config":{"units":1,"activation":"linear","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense2","trainable":true,"batch_input_shape":[null,10],"dtype":"float32"}}],"keras_version":"tfjs-layers 1.2.7","backend":"tensor_flow.js"},"format":"layers-model","generatedBy":"TensorFlow.js tfjs-layers v1.2.7","convertedBy":null,"weightsManifest":[{"paths":["./bundleModelTest.weights.bin"],"weights":[{"name":"dense_Dense2/kernel","shape":[10,1],"dtype":"float32"},{"name":"dense_Dense2/bias","shape":[1],"dtype":"float32"}]}]}
{"modelTopology":{"class_name":"Sequential","config":[{"class_name":"Dense","config":{"units":1,"activation":"linear","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense2","trainable":true,"batch_input_shape":[null,10],"dtype":"float32"}}],"keras_version":"tfjs-layers 1.2.7","backend":"tensor_flow.js"},"format":"layers-model","generatedBy":"TensorFlow.js tfjs-layers v1.2.7","convertedBy":null,"weightsManifest":[{"paths":["./bundle_model_test_weights.bin"],"weights":[{"name":"dense_Dense2/kernel","shape":[10,1],"dtype":"float32"},{"name":"dense_Dense2/bias","shape":[1],"dtype":"float32"}]}]}
4 changes: 3 additions & 1 deletion tfjs-react-native/integration_rn59/components/diagnostic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Button, SafeAreaView, StyleSheet, ScrollView, View, StatusBar } from 'r

import * as tf from '@tensorflow/tfjs';
import { Run } from './run';
import { simpleOpRunner, precisionTestRunner, mobilenetRunner, localModelRunner, trainModelRunner, saveModelRunner } from './ml';
import { simpleOpRunner, precisionTestRunner, mobilenetRunner, localModelRunner, trainModelRunner, saveModelRunner, localGraphModelRunner } from './ml';

interface ScreenProps {
returnToMain: () => void;
Expand Down Expand Up @@ -77,6 +77,8 @@ export class Diagnostic extends React.Component<ScreenProps> {
getRunner={mobilenetRunner} numRuns={1}></Run>
<Run label='bundleStorageIO'
getRunner={localModelRunner} numRuns={1}></Run>
<Run label='bundleStorageIO - graph model'
getRunner={localGraphModelRunner} numRuns={1}></Run>
<Run label='train model'
getRunner={trainModelRunner} numRuns={1}></Run>
<Run label='asyncStorareIO'
Expand Down
17 changes: 17 additions & 0 deletions tfjs-react-native/integration_rn59/components/ml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ export async function localModelRunner() {
};
}

/**
* A runner that loads a model bundled with the app and runs a prediction
* through it.
*/
const modelJson2 = require('../assets/graph_model/model.json');
const modelWeights2 = require('../assets/graph_model/group1-shard1of1.bin');
export async function localGraphModelRunner() {
const model =
await tf.loadGraphModel(bundleResourceIO(modelJson2, modelWeights2));
return async () => {
const res = model.predict(tf.randomNormal([1, 10])) as tf.Tensor;
const data = await res.data();
return JSON.stringify(data);
};
}


/**
* A runner that traines a model.
*/
Expand Down
2 changes: 2 additions & 0 deletions tfjs-react-native/integration_rn59/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ target 'integration_rn59' do

pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-community/async-storage'

pod 'RNFS', :path => '../node_modules/react-native-fs'

target 'integration_rn59Tests' do
inherit! :search_paths
# Pods for testing
Expand Down
11 changes: 7 additions & 4 deletions tfjs-react-native/integration_rn59/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
"start-metro": "npx react-native start --reset-cache",
"test-integration": "wdio wdio.conf.js",
"test-ci": "./scripts/test-ci.sh",
"postinstall": "npm run prep-tests"
"postinstall": "npm run prep-tests",
"copycore": "\\cp -rf ../../tfjs-core/dist node_modules/@tensorflow/tfjs-react-native"
},
"dependencies": {
"@react-native-community/async-storage": "^1.6.1",
"@tensorflow-models/mobilenet": "^1.0.1",
"@tensorflow/tfjs": "^1.2.11",
"@tensorflow-models/mobilenet": "^2.0.4",
"@tensorflow/tfjs": "1.2.11",
"@tensorflow/tfjs-react-native": "0.1.0-alpha.2",
"expo-camera": "^6.0.0",
"expo-gl": "^6.0.0",
Expand All @@ -24,7 +25,9 @@
"jpeg-js": "^0.3.5",
"react": "16.8.3",
"react-native": "0.59.10",
"react-native-unimodules": "^0.5.4"
"react-native-fs": "^2.16.1",
"react-native-unimodules": "^0.5.4",
"rn-fetch-blob": "^0.10.15"
},
"devDependencies": {
"@babel/core": "^7.5.5",
Expand Down
5 changes: 4 additions & 1 deletion tfjs-react-native/integration_rn59/test/integration_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ describe('tfjs-core unit tests', () => {
const driver = browser;

const unitTestBtn = await driver.$('~unit-test-btn');
await unitTestBtn.waitForExist(INITIAL_LOAD_TIMEOUT);
await unitTestBtn.waitForExist(
INITIAL_LOAD_TIMEOUT, false,
'Could not find unit test button. \n' +
'The browserstacklocal tunnel was likely not established');
await unitTestBtn.waitForEnabled(INITIAL_LOAD_TIMEOUT);
await unitTestBtn.click();

Expand Down
50 changes: 44 additions & 6 deletions tfjs-react-native/integration_rn59/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -848,10 +848,10 @@
xcode "^2.0.0"
xmldoc "^0.4.0"

"@tensorflow-models/mobilenet@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@tensorflow-models/mobilenet/-/mobilenet-1.0.1.tgz#e0dfdfd4941bae780dfe09e927ebdeea00926d12"
integrity sha512-VaxVRCmJLK09yp2Qn/LvT29joZPT4aCBrSD4DwIkWghfJF7M/DGqxsiZSnjnUnYjzkZdNv7JCVJ4EY1PCmufQw==
"@tensorflow-models/mobilenet@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@tensorflow-models/mobilenet/-/mobilenet-2.0.4.tgz#7f40771fcc650f50febd49be72372d39c15f6f95"
integrity sha512-fkcxDBldlYitDCV88xETwAQoBIC8xYKdDu80uBDuBZBfNC4k/jeVbZHM28WjvTDsJN7d7dYO4NbIkRAH0XHKSQ==

"@tensorflow/[email protected]":
version "1.2.11"
Expand Down Expand Up @@ -891,7 +891,7 @@
base64-js "^1.3.0"
buffer "^5.2.1"

"@tensorflow/tfjs@^1.2.11":
"@tensorflow/[email protected]":
version "1.2.11"
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs/-/tfjs-1.2.11.tgz#3d5a6e535069fc6139e778d28e02a84331eb753c"
integrity sha512-q1SIEMiR+Vqq8Fnmt/YGBC5tNq97LXDvUEl8SwWedhLtK1GJCpLMJXQA54JrkFXGLv5hK4dEb+1dx28TJUET2g==
Expand Down Expand Up @@ -1638,6 +1638,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=

[email protected], base-64@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs=

base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.2.3, base64-js@^1.3.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
Expand Down Expand Up @@ -3184,6 +3189,18 @@ glob-parent@^5.0.0:
dependencies:
is-glob "^4.0.1"

[email protected]:
version "7.0.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.2"
once "^1.3.0"
path-is-absolute "^1.0.0"

glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1:
version "7.1.4"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
Expand Down Expand Up @@ -5070,7 +5087,7 @@ min-document@^2.19.0:
dependencies:
dom-walk "^0.1.0"

minimatch@^3.0.4, minimatch@~3.0.2:
minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
Expand Down Expand Up @@ -5942,6 +5959,14 @@ react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==

react-native-fs@^2.16.1:
version "2.16.1"
resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.16.1.tgz#a8f7e950eaf96e7cf3cf92a5340c5b1ab657d8af"
integrity sha512-bD/pkKwE585EPSimsakKXwJUa9RAZFLEel2jFsYaWObLERPcjnoYeIT8nVRImKSEP81EyTNCgXh5t2f3DWqI5g==
dependencies:
base-64 "^0.1.0"
utf8 "^3.0.0"

react-native-unimodules@^0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/react-native-unimodules/-/react-native-unimodules-0.5.4.tgz#d4d779576a027f0455b14d396b0e002cb57963fe"
Expand Down Expand Up @@ -6376,6 +6401,14 @@ rimraf@~2.5.2:
dependencies:
glob "^7.0.5"

rn-fetch-blob@^0.10.15:
version "0.10.16"
resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.10.16.tgz#bd54f66c94f7a8e06c213077483646478ae8d230"
integrity sha512-hZV+nF0HK4CWmspXGMw7/G8Q8qugpS/wbKiNLsFpdBZR8XYzjFZNvBWgGyC0F5JWQn3sjmK2w/FJjBlwdQWNQg==
dependencies:
base-64 "0.1.0"
glob "7.0.6"

rsvp@^3.3.3:
version "3.6.2"
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
Expand Down Expand Up @@ -7361,6 +7394,11 @@ use@^3.1.0:
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==

utf8@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1"
integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==

util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
Expand Down
2 changes: 2 additions & 0 deletions tfjs-react-native/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const karmaTypescriptConfig = {
'@react-native-community/async-storage':
'./src/test_utils/async_storage_mock.ts',
'expo-gl': './src/test_utils/gl_view_mock.ts',
'react-native-fs': './src/test_utils/react_native_fs_mock.ts',
'expo-asset': './src/test_utils/expo_asset_mock.ts'
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion tfjs-react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
"@types/base64-js": "^1.2.5",
"@types/jasmine": "~2.5.53",
"@types/react-native": "^0.60.2",
"@types/react-native-fs": "^2.13.0",
"clang-format": "~1.2.2",
"expo-gl": "^5.0.1",
"expo-asset": "^7.0.0",
"jasmine": "~3.1.0",
"jasmine-core": "~3.1.0",
"karma": "~4.2.0",
Expand Down Expand Up @@ -58,6 +60,8 @@
"@react-native-community/async-storage": "^1.4.2",
"@tensorflow/tfjs-core": ">=1.3.0",
"expo-gl": "^5.0.1",
"react-native": ">= 0.58.0"
"expo-asset": "^7.0.0",
"react-native": ">= 0.58.0",
"react-native-fs": "^2.16.1"
}
}
70 changes: 60 additions & 10 deletions tfjs-react-native/src/bundle_resource_io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
* =============================================================================
*/

import {io} from '@tensorflow/tfjs-core';
import {Image, ImageSourcePropType} from 'react-native';
import {io, util} from '@tensorflow/tfjs-core';
import {Asset} from 'expo-asset';
import {Platform} from 'react-native';
import * as RNFS from 'react-native-fs';

import {fetch} from './platform_react_native';

class BundleResourceHandler implements io.IOHandler {
Expand Down Expand Up @@ -56,21 +59,68 @@ class BundleResourceHandler implements io.IOHandler {
async load(): Promise<io.ModelArtifacts> {
const modelJson = this.modelJson;

// Load the weights
const weightsAssetPath =
Image.resolveAssetSource(this.modelWeightsId as ImageSourcePropType);
const requestInit: undefined = undefined;
const response =
await fetch(weightsAssetPath.uri, requestInit, {isBinary: true});
const weightData = await response.arrayBuffer();

if (modelJson.weightsManifest.length > 1) {
throw new Error(
'Bundle resource IO handler does not currently support loading ' +
'sharded weights and the modelJson indicates that this model has ' +
'sharded weights (more than one weights file).');
}

const weightsAsset = Asset.fromModule(this.modelWeightsId);
if (weightsAsset.uri.match('^http')) {
// In debug/dev mode RN will serve these assets over HTTP
return this.loadViaHttp(weightsAsset);
} else {
// In release mode the assets will be on the file system.
return this.loadLocalAsset(weightsAsset);
}
}

async loadViaHttp(weightsAsset: Asset): Promise<io.ModelArtifacts> {
const modelJson = this.modelJson;

// Load the weights
const url = weightsAsset.uri;
const requestInit: undefined = undefined;
const response = await fetch(url, requestInit, {isBinary: true});
const weightData = await response.arrayBuffer();

const modelArtifacts: io.ModelArtifacts = Object.assign({}, modelJson);
modelArtifacts.weightSpecs = modelJson.weightsManifest[0].weights;
//@ts-ignore
delete modelArtifacts.weightManifest;
modelArtifacts.weightData = weightData;
return modelArtifacts;
}

async loadLocalAsset(weightsAsset: Asset): Promise<io.ModelArtifacts> {
const modelJson = this.modelJson;

let base64Weights: string;
if (Platform.OS === 'android') {
// On android we get a resource id instead of a regular path. We need
// to load the weights from the res/raw folder using this id.
try {
const fileName = `${weightsAsset.uri}.${weightsAsset.type}`;
base64Weights = await RNFS.readFileRes(fileName, 'base64');
} catch (e) {
throw new Error(
`Error reading resource ${weightsAsset.uri}. Make sure the file is
in located in the res/raw folder of the bundle`,
);
}
} else {
try {
base64Weights = await RNFS.readFile(weightsAsset.uri, 'base64');
} catch (e) {
throw new Error(
`Error reading resource ${weightsAsset.uri}. Make sure the file is
in located in the res/raw folder of the bundle`,
);
}
}

const weightData = util.encodeString(base64Weights, 'base64').buffer;
const modelArtifacts: io.ModelArtifacts = Object.assign({}, modelJson);
modelArtifacts.weightSpecs = modelJson.weightsManifest[0].weights;
//@ts-ignore
Expand Down
Loading

0 comments on commit 928fdc0

Please sign in to comment.