Tfjs: Don't automatically attempt to load webgl backend

Created on 24 Jul 2018  Â·  9Comments  Â·  Source: tensorflow/tfjs

To get help from the community, check out our Google group.

TensorFlow.js version

0.12.3

Browser version

Node.js 10.6.0

Describe the problem or feature request

When I run a simple example with tfjs and tjfs-node in my terminal, I get warnings about tfjs failing to register the webgl backend. But I don't care about that, I only want the node/cpu backend. Is there a way to make tfjs _not_ attempt to register the webgl backend, or, to not throw those warnings/errors?

Code to reproduce the bug / link to feature request

import * as tf from '@tensorflow/tfjs';

// Node CPU backend
import '@tensorflow/tfjs-node';

...
    const sample: tf.Tensor1D = tf.tensor1d(new Array(5));
...

Errors:

  console.warn node_modules/@tensorflow/tfjs-core/dist/environment.js:186
    Registration of backend webgl failed

  console.warn node_modules/@tensorflow/tfjs-core/dist/environment.js:187
    Error: WebGL is not supported on this device
        at new MathBackendWebGL (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:392:13)
        at /myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1316:22
        at Environment.Object.<anonymous>.Environment.registerBackend (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:367:23)
        at Object.<anonymous> (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1315:7)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/node_modules/@tensorflow/tfjs-core/src/index.ts:21:1)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/node_modules/@tensorflow/tfjs/src/index.ts:18:1)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/guide/optimizers/CrossEntropy.ts:10:1)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/guide/test/CrossEntropyTests.ts:3:1)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at /myrepo/node_modules/jest-jasmine2/build/index.js:129:13
        at Generator.next (<anonymous>)
        at step (/myrepo/node_modules/jest-jasmine2/build/index.js:170:30)
        at /myrepo/node_modules/jest-jasmine2/build/index.js:189:14
        at new Promise (<anonymous>)
        at /myrepo/node_modules/jest-jasmine2/build/index.js:167:12
        at jasmine2 (/myrepo/node_modules/jest-jasmine2/build/index.js:138:17)
        at /myrepo/node_modules/jest-runner/build/run_test.js:148:24
        at Generator.next (<anonymous>)
        at step (/myrepo/node_modules/jest-runner/build/run_test.js:270:30)
        at /myrepo/node_modules/jest-runner/build/run_test.js:281:15
        at process._tickCallback (internal/process/next_tick.js:68:7)

Most helpful comment

So it turns out this problem is due to jest, or the interaction between jest and tfjs. The problem is jest, by default, seems to mock a browser-like environment, which tfjs detects and thus tries to load browser stuff like the webgl backend. Adding "testEnvironment": "node" to the jest config in my package.json resolved these issues. It's a bit annoying that the default behavior was like this with no obvious clues as to what was going on, but I can't say this is an issue with tfjs. Maybe there should be a comment in some readme somewhere about this :) Anyway, thanks again for looking into this, it's appreciated!

All 9 comments

Thanks for your suggestion. Unfortunately, even if I add a setBackend call to the backend I want, I still get the error about WebGL. Very strange! Any other ideas welcome!

One other possibly relevant thing is I'm running my code via jest, so I don't know if that messes up the environment at all -- feels like it shouldn't but just want to give all possible clues to figure out this issue. Thanks again!

@nkreeger do you know if there is a way to suppress this warning on systems where no GPU backend is expected?

@DABH which version of @tensorflow/tfjs and @tensorflow/tfjs-node are you using? Can you supply the full source in a Github gist? Can you also provide output from the Node app? Usually the backend will default to the JS-CPU backend if the node binding fails to load. This is strange that it is defaulting to GPU.

Here is a complete minimal example, I boiled down my code to this:

import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-node';

test('do the thing', () =>
{
    console.log('oh no');
});

The command I run is jest tests/test1.ts.
The full output I get is

 PASS  tests/test1.ts
  ✓ do the thing (11ms)

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
        at module.exports (/myrepo/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
        at HTMLCanvasElementImpl.getContext (/myrepo/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:42:5)
        at HTMLCanvasElement.getContext (/myrepo/node_modules/jsdom/lib/jsdom/living/generated/HTMLCanvasElement.js:50:45)
        at getWebGLRenderingContext (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment_util.ts:259:21)
        at Object.isWebGLVersionEnabled (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment_util.ts:85:10)
        at Environment.Object.<anonymous>.Environment.evaluateFeature (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:294:11)
        at Environment.Object.<anonymous>.Environment.get (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:238:35)
        at new MathBackendWebGL (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:391:13)
        at /myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1316:22
        at Environment.Object.<anonymous>.Environment.registerBackend (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:367:23) undefined

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
        at module.exports (/myrepo/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
        at HTMLCanvasElementImpl.getContext (/myrepo/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:42:5)
        at HTMLCanvasElement.getContext (/myrepo/node_modules/jsdom/lib/jsdom/living/generated/HTMLCanvasElement.js:50:45)
        at getWebGLRenderingContext (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment_util.ts:255:24)
        at Object.isWebGLVersionEnabled (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment_util.ts:85:10)
        at Environment.Object.<anonymous>.Environment.evaluateFeature (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:296:18)
        at Environment.Object.<anonymous>.Environment.get (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:238:35)
        at new MathBackendWebGL (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:391:13)
        at /myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1316:22
        at Environment.Object.<anonymous>.Environment.registerBackend (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:367:23) undefined

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
        at module.exports (/myrepo/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
        at HTMLCanvasElementImpl.getContext (/myrepo/node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:42:5)
        at HTMLCanvasElement.getContext (/myrepo/node_modules/jsdom/lib/jsdom/living/generated/HTMLCanvasElement.js:50:45)
        at getWebGLRenderingContext (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment_util.ts:256:24)
        at Object.isWebGLVersionEnabled (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment_util.ts:85:10)
        at Environment.Object.<anonymous>.Environment.evaluateFeature (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:296:18)
        at Environment.Object.<anonymous>.Environment.get (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:238:35)
        at new MathBackendWebGL (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:391:13)
        at /myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1316:22
        at Environment.Object.<anonymous>.Environment.registerBackend (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:367:23) undefined

  console.warn node_modules/@tensorflow/tfjs-core/dist/environment.js:186
    Registration of backend webgl failed

  console.warn node_modules/@tensorflow/tfjs-core/dist/environment.js:187
    Error: WebGL is not supported on this device
        at new MathBackendWebGL (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:392:13)
        at /myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1316:22
        at Environment.Object.<anonymous>.Environment.registerBackend (/myrepo/node_modules/@tensorflow/tfjs-core/src/environment.ts:367:23)
        at Object.<anonymous> (/myrepo/node_modules/@tensorflow/tfjs-core/src/kernels/backend_webgl.ts:1315:7)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/node_modules/@tensorflow/tfjs-core/src/index.ts:21:1)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/node_modules/@tensorflow/tfjs-node/dist/index.js:3:11)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at Runtime.requireModuleOrMock (/myrepo/node_modules/jest-runtime/build/index.js:463:19)
        at Object.<anonymous> (/myrepo/guide/test/CrossEntropyTests.ts:2:1)
        at Runtime._execModule (/myrepo/node_modules/jest-runtime/build/index.js:694:13)
        at Runtime.requireModule (/myrepo/node_modules/jest-runtime/build/index.js:376:14)
        at /myrepo/node_modules/jest-jasmine2/build/index.js:129:13
        at Generator.next (<anonymous>)
        at step (/myrepo/node_modules/jest-jasmine2/build/index.js:170:30)
        at /myrepo/node_modules/jest-jasmine2/build/index.js:189:14
        at new Promise (<anonymous>)
        at /myrepo/node_modules/jest-jasmine2/build/index.js:167:12
        at jasmine2 (/myrepo/node_modules/jest-jasmine2/build/index.js:138:17)
        at /myrepo/node_modules/jest-runner/build/run_test.js:148:24
        at Generator.next (<anonymous>)
        at step (/myrepo/node_modules/jest-runner/build/run_test.js:270:30)
        at /myrepo/node_modules/jest-runner/build/run_test.js:281:15
        at process._tickCallback (internal/process/next_tick.js:68:7)

  console.log tests/test1.ts:6
    oh no

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.561s
Ran all test suites matching /tests\/test1.ts/i.

(This includes some errors I reported in another issue, but ok.)

All I did was yarn add the packages, so they should be the latest versions; this is the relevant part of package.json showing what versions it grabbed:

  "dependencies": {
    "@tensorflow/tfjs": "^0.12.3",
    "@tensorflow/tfjs-node": "^0.1.9",
    "@tensorflow/tfjs-node-gpu": "^0.1.9",
...

Thanks again for investigating this!

@DABH something looks off - do you mind hosting this entire project on GitHub and sharing the link here?

Here you go! https://github.com/DABH/tftest

(Un)Fortunately I get the same errors with this simple test project. Run yarn to get packages and then jest ./BasicTests.ts to try to test. Hope it's helpful, would love to get to the bottom of this! Thanks!

So it turns out this problem is due to jest, or the interaction between jest and tfjs. The problem is jest, by default, seems to mock a browser-like environment, which tfjs detects and thus tries to load browser stuff like the webgl backend. Adding "testEnvironment": "node" to the jest config in my package.json resolved these issues. It's a bit annoying that the default behavior was like this with no obvious clues as to what was going on, but I can't say this is an issue with tfjs. Maybe there should be a comment in some readme somewhere about this :) Anyway, thanks again for looking into this, it's appreciated!

I experienced this behavior when importing tfjs-core in a static page that rendered a WebGL canvas on a Linux Mint 19.1 device running recent Chromium. There was no jest in this project...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kylemcdonald picture kylemcdonald  Â·  3Comments

weiji14 picture weiji14  Â·  3Comments

chrisdonahue picture chrisdonahue  Â·  3Comments

rumschuettel picture rumschuettel  Â·  3Comments

ritikrishu picture ritikrishu  Â·  4Comments