Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tfjs-react-native bundleResourceIo function Require Cycle yellowbox, -> TypeError: Network request failed. #2177

Closed
gitathrun opened this issue Oct 9, 2019 · 28 comments

Comments

@gitathrun
Copy link

gitathrun commented Oct 9, 2019

To get help from the community, we encourage using Stack Overflow and the tensorflow.js tag.

TensorFlow.js version

"@react-native-community/async-storage": "^1.6.1",
"@tensorflow/tfjs": "^1.2.8",
"@tensorflow/tfjs-react-native": "0.1.0-alpha.2",
"expo-gl": "^6.0.0",
"expo-gl-cpp": "^6.0.0",
"react": "16.8.3",
"react-native": "0.59.10",
"react-native-unimodules": "^0.7.0-rc.1",
"typescript": "^3.6.3"

Browser version

react-native app

Describe the problem or feature request

When I am trying to use the "bundleResourceio" function to load mdoel from local mobile device, Yellowbox occurs with following mention:
image

It is triggered by click on the buttom.

In the console, it shows:
image

From my understanding it is probably some require cycle between tfjs-react-native customised fetch and react-native fetch functions which causes the undefined fetch function?

But it is hard to debug and where to modified, I even tried use the demo ts file here, still got this error...

Any ideas?

Code to reproduce the bug / link to feature request

The react-native app consists:

  1. model files in the assets folder the same as the demo
    image
  2. Code for load the model in App.js:
import React, { Component } from "react";
import * as tf from '@tensorflow/tfjs';
import  { bundleResourceIO} from '@tensorflow/tfjs-react-native';
import { View, Text, Button } from 'react-native';

const modelJson = require('./assets/model.json');
const modelWeights = require('./assets/group1-shard1of1.bin');

const BACKEND_CONFIG = 'cpu';

export default class App extends Component {
  constructor(prop){
    super(prop);
    this.state = {
        isModelReady: false,
        useModel: {}
    }; 
};

  async componentDidMount() {

    await tf.setBackend(BACKEND_CONFIG);
    await tf.ready();
    // Signal to the app that tensorflow.js can now be used.
    console.log("componentDidMount: tf.ready is set");

    console.log("the MyModelLoadLocal component is mounted");
  }

  OnPressLoadLocalModel = async () =>{
    console.log("model loading button is pressed...");

    console.log(" start load local model");
    
    const beginModelLoadTs = new Date().getTime();

    const model = await tf.loadGraphModel(bundleResourceIO(modelJson, modelWeights));

    
    const endModelLoadTs = new Date().getTime();    
    console.log("mili sec for model loading: " + (endModelLoadTs - beginModelLoadTs));
    console.log("local model loading is done: " + model);

    this.setState({
        useModel: model,
        isModelReady: true
    });
}

    render() {
      return (
        <View>
        <Text>
            hello world
        </Text>
        <Text>
            current use model state: {this.state.isModelReady.toString()}
        </Text>
        <Button
            title="Load model"
            color="#f194ff"
            onPress={ this.OnPressLoadLocalModel }
        />
    </View>
      );

    }
}

If you would like to get help from the community, we encourage using Stack Overflow and the tensorflow.js tag.

GitHub issues for this repository are tracked in the tfjs union repository.

Please file your issue there, following the guidance in that issue template.

@rthadur rthadur added the type:bug Something isn't working label Oct 9, 2019
@rthadur
Copy link
Contributor

rthadur commented Oct 9, 2019

@gitathrun is it same with latest tfjs version as well ?

@tafsiri
Copy link
Contributor

tafsiri commented Oct 9, 2019

@gitathrun I'll take a look, two questions, could you check that the values for modelJson and modelWeights are what you expect. If you console.log/console.warn them you should see a json structure for the first one that corresponds to the file and for the second one you should see a number. Could you confirm that it is what you expect.

Also just confirming that you modified your metro config to allow the resolver to resolve .bin files assetExts: ['bin', 'txt', 'jpg'], (See https://github.com/tensorflow/tfjs/tree/master/tfjs-react-native#step-3-configure-metro)

@gitathrun
Copy link
Author

@rthadur I did not test with the latest tfjs version, because I try to keep the same dependencies version with the tfjs-react-native demo.

@gitathrun
Copy link
Author

@tafsiri I have update the code in App.js listed below, and the console result, All the key, value in modelJson can be fetched correctly, and the modelWeights is a Number with 1.

App.js

import React, { Component } from "react";
import * as tf from '@tensorflow/tfjs';
import  { bundleResourceIO} from '@tensorflow/tfjs-react-native';
import { View, Text, Button } from 'react-native';

const modelJson = require('./assets/model.json');
const modelWeights = require('./assets/group1-shard1of1.bin');

const BACKEND_CONFIG = 'cpu';

export default class App extends Component {
  constructor(prop){
    super(prop);
    this.state = {
        isModelReady: false,
        useModel: {}
    }; 
};

  async componentDidMount() {

    await tf.setBackend(BACKEND_CONFIG);
    await tf.ready();
    // Signal to the app that tensorflow.js can now be used.
    console.log("componentDidMount: tf.ready is set");

    //print out model.json and modelWeights
    console.log("modelWeights: " + modelWeights);
    console.log("modelJson: "+modelJson);
    Object.keys(modelJson).forEach(function (item) {
      console.log(item); // key
      console.log(modelJson[item]); // value
    });


    console.log("the MyModelLoadLocal component is mounted");
  }

  OnPressLoadLocalModel = async () =>{
    console.log("model loading button is pressed...");

    console.log("in MyConcatUSEModel.localModelLoader: start load local model");
    
    const beginModelLoadTs = new Date().getTime();

    const usemodelEncoder = await tf.loadGraphModel(bundleResourceIO(modelJson, modelWeights));

    const endModelLoadTs = new Date().getTime();    
    console.log("mili sec for model loading: " + (endModelLoadTs - beginModelLoadTs));
    console.log("local model loading is done: " + usemodelEncoder);

    this.setState({
        useModel: usemodelEncoder,
        isUSEReady: true
    });
}

    render() {
      return (
        <View>
        <Text>
            hello world.
        </Text>
        <Text>
            current use model state: {this.state.isModelReady.toString()}
        </Text>
        <Button
            title="Load model"
            color="#f194ff"
            onPress={ this.OnPressLoadLocalModel }
        />
    </View>
      );

    }
}

results in console.log
image

The metro config is exactly the same as Step 3, here is mine:

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */

// Change 1 (import the blacklist utility)
const blacklist = require('metro-config/src/defaults/blacklist');

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false,
      },
    }),
  },

  resolver: {
    // Change 2 (add 'bin' to assetExts)
    assetExts: ['bin', 'txt', 'jpg'],
    sourceExts: ['js', 'json', 'ts', 'tsx', 'jsx'],
    // Change 3 (add platform_node to blacklist)
    blacklistRE: blacklist([/platform_node/])
  },
};

@tafsiri tafsiri added the P0 label Oct 11, 2019
@gitathrun
Copy link
Author

@tafsiri Hello, any progress on this topic?

@gitathrun
Copy link
Author

@tafsiri Hello, I have tried with the same configuration but react-native version 0.60.

The result is the same, caused by require cycle of fetch:
image

@tafsiri
Copy link
Contributor

tafsiri commented Nov 4, 2019

Hi @gitathrun sorry for the delay in looking into this. I tried to reproduce this but was unable to do so exactly.

In debug mode, I don't get the require cycle warning related to fetch.

To help debug I created a branch https://github.com/tensorflow/tfjs/tree/2177-bundleResourceIO where the integration app has a new diagnostic test that loads a graphModel from the bundle.

With a release build I do have an issue, but that may have more to do with the android build settings, i'm going to continue to look into this but I'm not sure if it's the same as your issue.

To narrow this down:

  • Is it possible that you have another dependency loading a fetch library/polyfill? Could you post your package.json?
  • Are you running into this with a debug or release build? (given the messages above I assumed debug mode).
  • Are you able to run the integration_rn59 from the branch linked above app locally, do you get a similar result? I've included a screenshot below of what I am getting when i click the 'show diagnostic screen' button.

Screen Shot 2019-11-04 at 3 57 14 PM

@gitathrun
Copy link
Author

Hi, @tafsiri , thanks for the reply.

To your questions:

Is it possible that you have another dependency loading a fetch library/polyfill? Could you post your package.json?

My package.json

{
  "name": "tfjs_rn_demo_59",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.6.1",
    "@tensorflow-models/mobilenet": "^2.0.4",
    "@tensorflow/tfjs": "^1.2.8",
    "@tensorflow/tfjs-react-native": "0.1.0-alpha.2",
    "expo-gl": "^6.0.0",
    "expo-gl-cpp": "^6.0.0",
    "node-nlp-rn": "^3.5.2",
    "react": "16.8.3",
    "react-native": "0.59.10",
    "react-native-unimodules": "^0.7.0-rc.1",
    "typescript": "^3.6.3"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/runtime": "^7.5.5",
    "babel-jest": "^24.8.0",
    "jest": "^24.8.0",
    "metro-react-native-babel-preset": "^0.55.0",
    "react-test-renderer": "16.8.3"
  },
  "jest": {
    "preset": "react-native"
  }
}

Might be the "@tensorflow-models/mobilenet": "^2.0.4", got us into the issue? Since it do requie the developer to access internet and fetch the mobilenet model+weight from google storage?

Are you running into this with a debug or release build? (given the messages above I assumed debug mode).

Firstly, I do try to get it working in debug mode, not working, then I try to build a release apk, but with another problem, which is

> Task :app:mergeReleaseResources FAILED
[raw/group1shard1of1] /app/tfjs/tfjs_rn/tfjs_rn_demo_60/android/app/src/main/res/raw/group1shard1of1.bin      [raw/group1shard1of1] /app/tfjs/tfjs_rn/tfjs_rn_demo_60/android/app/build/generated/res/react/release/raw/group1shard1of1.bin: Error: Duplicate resources

This the error shows in rn 60 version, but this error also shows up in rn 59 version.

Are you able to run the integration_rn59 from the branch linked above app locally, do you get a similar result? I've included a screenshot below of what I am getting when i click the 'show diagnostic screen' button.

I will get the result back to you asap.

@gitathrun
Copy link
Author

hi, @tafsiri negative, I cant get the demo running, I got issues in bundle process:
image

@tafsiri
Copy link
Contributor

tafsiri commented Nov 5, 2019

Thanks for the info, i've dug into this a bit more and was able to reproduce some of your errors.

  • For your app could you update your tfjs version to "@tensorflow/tfjs": "1.2.11". Note that there is no ^ as you need that exact version, that is the most recent version that is compatible with the current release of tfjs-react-native, this should fix the network request issue.

If that does not work

  • Could you try changing the blacklistRE setting in metro.config.js to look like
    • blacklistRE: blacklist([/platform_node/, /@tensorflow.*_test.js/]) (note the addition of /@tensorflow.*_test.js/
  • In the demo app/your app could you try the default debug mode run command npx react-native run-android. I'm curious to see if there is different behavior than when using your custom build command.

This should get things running in debug mode. However through this I have discovered an issue when running this in release mode which will take a new release in order to fix. I'll post an update here when I work out a fix. If you still have have issues in debug mode, let me know.

@gitathrun
Copy link
Author

Hi, @tafsiri
I have tried the solutions you provide, it works but:

  1. It only works with react-nativer <=0.59, for react-native >= 0.60, it would not work.
  2. Even the model is loaded successfully, the require cycle yellow box still shows up, but only once, and does not effect the loading process.
    image

3, It only works in debug mode as you indicates. I have successfully create the bundle for Release, signed, install it on devices, checked in Android Studio make sure all files (the model files as well) included, but the "Network fetch error" still ocurred. So the app could not load model from a relased apk. This applies to both rn 0.59 and 0.60. I am wandering is it the "paths" parameters in model.json is not compat with bundled model weight file, because the .bin file name is changed during the bundle process?

  1. My suspection is the react-native-unimodules causes the problem. Because since I upgrade unimodules to 0.7.0, even my rn is 0.59, it still causes the "fetch" not working. Currently, only the unimodules version "0.5.4" works for me.

PS: is it possible to use tf.loadLayersModel() with an URL links to fetch the model from a cloud ? (Azure blob, for example) in tfjs-react-native? It seems from the mobilenet package code that the model from Google's open storage is fetched by using loadGraphModel() from tf.converter, not from tf.

Many thanks.

@alitsvin
Copy link

alitsvin commented Nov 6, 2019

I have the same issue and keep track of discussion!

@tafsiri
Copy link
Contributor

tafsiri commented Nov 6, 2019

@gitathrun

  1. Could you post the error you seeing RN 0.6x (in debug mode)
  2. Yep the issue in release mode is due to renaming/moving resources in the bundling process causing the resolved path from RNs resolver to be incorrect. (note the path in the json doesn't matter).
  3. Thanks for the info about the unimodules upgrade, I'll take a look at that after working out the .bin resolution issue.
  4. Yes you can use loadLayersModel with a url to fetch a model hosted on the web. This is how mobilenet works. loadLayersModel and loadGraphModel are functionally equivalent, but they load different kinds of models.

@gitathrun
Copy link
Author

gitathrun commented Nov 6, 2019

@tafsiri

  1. Could you post the error you seeing RN 0.6x (in debug mode)
    image

  2. Yep the issue in release mode is due to renaming/moving resources in the bundling process causing the resolved path from RNs resolver to be incorrect. (note the path in the json doesn't matter).
    Good, which means it is a RN resolver problem. I try to manually change the paths property in model.json into the file name shows in release apk, but it does not work.

  3. Thanks for the info about the unimodules upgrade, I'll take a look at that after working out the .bin resolution issue.
    That is my guess, since this is the only difference between 59 and 60. Other configurations such as app.js, model.json, etc are identical.

  4. Yes you can use loadLayersModel with a url to fetch a model hosted on the web. This is how mobilenet works. loadLayersModel and loadGraphModel are functionally equivalent, but they load different kinds of models.

That is great, mobilenet code, although it is loadGraphModel, but I think it can be changed to loadLayersModel.
Update: works for Azure Blob storage, but Blob container has to be public for model.json access.

tafsiri added a commit that referenced this issue Nov 13, 2019
Updates how files are resolved by the bundle resource loader in prod builds. Addresses #2177

INTERNAL
BUG
@tafsiri
Copy link
Contributor

tafsiri commented Nov 13, 2019

@gitathrun Just did a new release that should fix this issue. Try https://www.npmjs.com/package/@tensorflow/tfjs-react-native/v/0.1.0-alpha.3 and let me know if it solves the problem.

@tafsiri
Copy link
Contributor

tafsiri commented Nov 13, 2019

This version does need the latest version (1.3.x) of tfjs.

@gitathrun
Copy link
Author

Hi, @tafsiri
Sorry for the late reply, I do spend sometime to re-create project and test the new verision, here is what I got:

  1. I can confirm it works as expected in react-native version @0.59.x.

  2. But unfortunately, it could not work with react-native version >[email protected].
    With the rn version higher than 0.60.x, it can successfuly bundle, and installed to device, but when click the app, the app just flash crashed, without following errors shows in the log:

11-29 09:07:58.917  3656  3656 I MicroDetectionWorker: onReady
11-29 09:07:58.927  3656  6671 I MicroRecognitionRunner: Starting detection.
11-29 09:07:58.927  3656  6667 I MicrophoneInputStream: mic_starting  SR : 16000 CC : 16 SO : 6
11-29 09:07:58.928  1598  1656 E         : Request requires android.permission.RECORD_AUDIO
11-29 09:07:58.928  1598  1656 E AudioPolicyIntefaceImpl: getInputForAttr permission denied: recording not allowed for uid 10034 pid 3656
11-29 09:07:58.928  1598  1656 E AudioFlinger: createRecord() checkRecordThread_l failed
11-29 09:07:58.928  3656  6667 E IAudioFlinger: createRecord returned error -22
11-29 09:07:58.928  3656  6667 E AudioRecord: AudioFlinger could not create record track, status: -22
11-29 09:07:58.928  3656  6667 E AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -22.
11-29 09:07:58.928  3656  6667 E android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.
11-29 09:07:58.928  3656  6667 I MicrophoneInputStream: mic_started  SR : 16000 CC : 16 SO : 6
11-29 09:07:58.929  3656  6667 E ActivityThread: Failed to find provider info for com.google.android.apps.gsa.testing.ui.audio.recorded
11-29 09:07:58.929  3656  3656 I MicroDetectionWorker: onReady
11-29 09:07:58.930  3656  6667 I MicrophoneInputStream: mic_close  SR : 16000 CC : 16 SO : 6
11-29 09:07:58.930  3656  6671 I MicroRecognitionRunner: Detection finished
11-29 09:07:58.930  3656  6671 W ErrorReporter: reportError [type: 211, code: 524300]: Error reading from input stream
11-29 09:07:58.931  3656  3930 I MicroRecognitionRunner: Stopping hotword detection.
11-29 09:07:58.931  3656  6671 W ErrorProcessor: onFatalError, processing error from engine(4)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: com.google.android.apps.gsa.shared.speech.b.g: Error reading from input stream
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.staticplugins.microdetection.d.k.a(SourceFile:91)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.staticplugins.microdetection.d.l.run(Unknown Source:14)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.libraries.gsa.runner.a.a.b(SourceFile:32)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.libraries.gsa.runner.a.c.call(Unknown Source:4)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.shared.util.concurrent.b.g.run(Unknown Source:4)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.shared.util.concurrent.b.aw.run(SourceFile:4)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.shared.util.concurrent.b.aw.run(SourceFile:4)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.lang.Thread.run(Thread.java:764)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.shared.util.concurrent.b.i.run(SourceFile:6)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: Caused by: com.google.android.apps.gsa.shared.exception.GsaIOException: Error code: 393238 | Buffer overflow, no available space.
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.speech.audio.Tee.j(SourceFile:103)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.speech.audio.au.read(SourceFile:2)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.io.InputStream.read(InputStream.java:101)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.speech.audio.ao.run(SourceFile:17)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at com.google.android.apps.gsa.speech.audio.an.run(SourceFile:2)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
11-29 09:07:58.931  3656  6671 W ErrorProcessor: 	... 10 more
11-29 09:07:58.931  3656  6671 I AudioController: internalShutdown
11-29 09:07:58.932  3656  3656 I MicroDetector: Keeping mic open: false
11-29 09:07:58.932  3656  6672 I DeviceStateChecker: DeviceStateChecker cancelled
11-29 09:07:58.932  3656  3656 I MicroDetectionWorker: #onError(false)
11-29 09:07:59.010  7368  7387 D EGL_emulation: eglMakeCurrent: 0xec9dde20: ver 2 0 (tinfo 0xec96bbf0)
11-29 09:07:59.018  1756  2382 D gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
11-29 09:07:59.018  1756  2382 D         : HostConnection::get() New Host Connection established 0xeac5a0c0, tid 2382
11-29 09:07:59.023  1756  2382 D gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
11-29 09:07:59.024  1756  2382 D         : HostConnection::get() New Host Connection established 0xeac552c0, tid 2382
11-29 09:07:59.025  1756  2382 D gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
11-29 09:07:59.025  1756  2382 D         : HostConnection::get() New Host Connection established 0xeac552c0, tid 2382
11-29 09:07:59.025  1756  2382 D gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
11-29 09:07:59.039  1756  2382 W SurfaceFlinger: Attempting to destroy on removed layer: AppWindowToken{a50cb31 token=Token{d46cbd8 ActivityRecord{59d5abb u0 com.verify_simplebundledemo_60/.MainActivity t16}}}#0
11-29 09:07:59.093  1868  1868 E netmgr  : Failed to open QEMU pipe 'qemud:network': Invalid argument
11-29 09:07:59.093  1868  1868 E netmgr  : WifiForwarder unable to open QEMU pipe: Invalid argument
11-29 09:07:59.229  1923  2276 I GnssLocationProvider: WakeLock acquired by sendMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@ce8e03)
11-29 09:07:59.229  1923  1941 I GnssLocationProvider: WakeLock released by handleMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@ce8e03)
11-29 09:07:59.281  1923  1943 W Looper  : Slow dispatch took 452ms android.ui h=android.view.Choreographer$FrameHandler c=android.view.Choreographer$FrameDisplayEventReceiver@9a713dc m=0
11-29 09:07:59.281  1923  1943 W Looper  : Slow delivery took 538ms android.ui h=android.view.ViewRootImpl$ViewRootHandler c=null m=6
11-29 09:07:59.355  1923  1943 W Looper  : Drained
11-29 09:08:00.229  1923  2276 I GnssLocationProvider: WakeLock acquired by sendMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@cdd90f1)
11-29 09:08:00.229  1923  1941 I GnssLocationProvider: WakeLock released by handleMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@cdd90f1)
11-29 09:08:00.607  1825  1831 D gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
11-29 09:08:00.608  1825  1831 D         : HostConnection::get() New Host Connection established 0xf0ebc240, tid 1831
11-29 09:08:00.608  1825  1831 D gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
11-29 09:08:00.643  1825  1831 D         : HostConnection::get() New Host Connection established 0xf0ebc240, tid 1831
11-29 09:08:01.230  1923  2276 I GnssLocationProvider: WakeLock acquired by sendMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@7e654d6)
11-29 09:08:01.230  1923  1941 I GnssLocationProvider: WakeLock released by handleMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@7e654d6)
11-29 09:08:01.537  1825  1829 D hwcomposer: hw_composer sent 343 syncs in 60s
11-29 09:08:01.563  1580  1664 W audio_hw_generic: Not supplying enough data to HAL, expected position 1844103 , only wrote 1692000
11-29 09:08:02.230  1923  2276 I GnssLocationProvider: WakeLock acquired by sendMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@e6f8357)
11-29 09:08:02.230  1923  1941 I GnssLocationProvider: WakeLock released by handleMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@e6f8357)
11-29 09:08:02.293  1774  1812 E storaged: getDiskStats failed with result NOT_SUPPORTED and size 0
11-29 09:08:02.691  1923  1941 I UsageStatsService: User[0] Flushing usage stats to disk

I have a feeling that this is caused by the incompentency between react-native 0.60 and newly utilised react-native-fs, because when I am trying to configure the react-native-fs in rn 0.60 environment, it throws a lot of error such as fs error, and react-native-fs documentation is conflect about whether use auto or manul "react-native link" cmd if rn version is higher than 0.60. Use "react-native link react-native-fs" is obsolutely fine in rn 0.59, but it does not work in 0.60, for some of the configurations does not show in the build.gradle and MainApplication.java.

Many thanks.

@tafsiri
Copy link
Contributor

tafsiri commented Dec 2, 2019

@gitathrun from your error log it looks like the problem is with accessing a microphone (maybe a permissions error)? If you fix that do you get any other errors?

It also sounds like you weren't able to get react-native-fs set up where you using RN 0.60 or a version > 0.61. The readme for react-native-fs seems to suggest you need to use RN 0.61 or higher.

@gitathrun
Copy link
Author

@tafsiri Here is the weired part. I have never try to setup the microphone permission or usage in this simple demo, the code is identical with version 0.59. But the rn 60 asks for this permission? This is the part I am not certain about.

The second odd thing is, according to react-native-fs doc,

For RN >= 0.57 and/or Gradle >= 3 you MUST install react-native-fs at version >= @2.13.2!

But with this version 2.13.x, the android build failed as this indicates, update solved this problem in build, bundle process, but encountered the flash-crash problem.

May be it has to be react-native 0.61, I am not sure, but my current project are based on 0.60.

I will test this against 0.61, to see if it is the solution.

@rthadur
Copy link
Contributor

rthadur commented Jan 9, 2020

Automatically closing due to lack of recent activity. Please update the issue when new information becomes available, and we will reopen the issue. Thanks!

@rthadur rthadur closed this as completed Jan 9, 2020
@dkoo
Copy link

dkoo commented Jan 15, 2020

@tafsiri @gitathrun I have run into this same issue trying to use this library's custom fetch implementation in an Android emulator and was wondering if either of you have made any further progress on this? It seems like the issue was closed prematurely without resolution.

@tafsiri
Copy link
Contributor

tafsiri commented Jan 16, 2020

@dkoo are you getting the same error (a microphone exception?) Feel free to make a new issue with your setup and I can take a look. The main issue is that I haven't been able to reproduce this.

@dkoo
Copy link

dkoo commented Jan 16, 2020

@tafsiri In my case it's not due to a microphone exception (I'm not even using the microphone, I'm just trying to capture a still photo from React Native Camera or select one from the photo library). It seems related to the use of fetch to try to turn either a local file or base64 string into a binary stream for consumption by decodeJpeg. Code sample:

const convertImageToTensor = async ( image ) => {
	const binary = await fetch( image.uri, {}, { isBinary: true } ); // This is the line that is causing the `Network request failed` error in Android.
	const raw = await binary.arrayBuffer();
	const buffer = new Uint8Array( raw );

	const tensor = await decodeJpeg( buffer );

	classifyImage( tensor );
};

// Take a picture using camera component ref and pass to TensorFlow.
const capturePhoto = async () => {
	if ( cameraRef.current ) {
		const image = await cameraRef.current.takePictureAsync( {
			base64: true,
			doNotSave: true, // Do not save image file to device disk.
			exif: false,
			quality: 0.5
		} );

		if ( image.base64 ) {
			image.uri = 'data:image/jpeg;base64,' + image.base64;
		}

		convertImageToTensor( image );
	}
};

This works as expected on iOS, but the XHR request fails on Android. It also fails when trying to fetch a .jpg file from the device's disk, not just when fetching a base64 data URI. I thought it might have been related to this issue: facebook/react-native#23986

but that didn't seem to fix the problem. Debugging the custom fetch function, I saw that the request kept erroring out with a status of 0 before the content type could be determined. I then tried manually setting a content-type header to image/jpeg, but that didn't work either. So I ended up sidestepping the issue by manually building the binary instead:

// Revised function avoiding the use of `fetch` or XHR to convert the image to binary.
const convertImageToTensor = async ( image ) => {
	let binary,
		raw,
		buffer;

	if ( image.base64 ) {
		binary = atob( image.base64 );
		raw = new ArrayBuffer( binary.length );
		buffer = new Uint8Array( raw );

		for ( let i = 0; i < binary.length; i ++ ) {
			buffer[i] = binary.charCodeAt( i );
		}

		const tensor = await decodeJpeg( buffer );

		classifyImage( tensor );
	}
};

This seems to work on both iOS and Android. Still, it's more of a workaround than addressing the actual issue with the fetch method.

@tafsiri
Copy link
Contributor

tafsiri commented Jan 17, 2020

@dkoo thanks for the updated info. Could you also let me know what versions of tfjs and tfjs-react-native you are using? Also is this just in the simulator or also on device?

@dkoo
Copy link

dkoo commented Jan 29, 2020

@tafsiri Sorry for the delayed response. Versions I'm using:

    "@tensorflow/tfjs": "^1.5.1",
    "@tensorflow/tfjs-react-native": "0.1.0-alpha.3",

And this was in the Android Emulator.

@tafsiri
Copy link
Contributor

tafsiri commented Jan 29, 2020

Thanks, any chance you could try this on a physical device?

@rthadur
Copy link
Contributor

rthadur commented Mar 6, 2020

Automatically closing due to lack of recent activity. Please update the issue when new information becomes available, and we will reopen the issue. Thanks!

@rthadur rthadur closed this as completed Mar 6, 2020
@MareSeestern
Copy link

@tafsiri This problem only exists on an Android Emulator for me. On a physical device (Android/IOS) it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants