Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
22e6783
temp
annxingyuan Jul 20, 2020
b6fd69f
updates
annxingyuan Jul 20, 2020
83379cc
works
annxingyuan Jul 20, 2020
8db1970
Merge branch 'master' into threads_wasm
annxingyuan Jul 21, 2020
6883c17
use tp
annxingyuan Jul 21, 2020
e1c2355
ctest
annxingyuan Jul 21, 2020
d644155
generate 3 builds
annxingyuan Jul 21, 2020
2f83aa1
fix build
annxingyuan Jul 21, 2020
a661eee
updates
annxingyuan Jul 21, 2020
49cbfe5
update
annxingyuan Jul 21, 2020
3ee07cc
fix feature test
annxingyuan Jul 22, 2020
f075dde
clean
annxingyuan Jul 22, 2020
5054af0
2 builds
annxingyuan Jul 22, 2020
0819bd7
redcue build
annxingyuan Jul 22, 2020
a2c07e7
fix
annxingyuan Jul 22, 2020
2c56435
fix
annxingyuan Jul 22, 2020
b3c69b2
fix comment
annxingyuan Jul 22, 2020
418860a
update
annxingyuan Jul 22, 2020
1277909
add
annxingyuan Jul 22, 2020
5a90867
bench
annxingyuan Jul 22, 2020
c3c77ce
add thread
annxingyuan Jul 24, 2020
649d794
Merge branch 'master' into threads_wasm
annxingyuan Jul 28, 2020
06ce3f9
update
annxingyuan Jul 28, 2020
cce44fc
update
annxingyuan Jul 28, 2020
ac8ed9b
pass in
annxingyuan Jul 28, 2020
f5348d8
fix
annxingyuan Jul 28, 2020
926d743
numcores
annxingyuan Jul 28, 2020
d99512a
Merge branch 'master' into threads_wasm
annxingyuan Jul 28, 2020
b6fb9bf
Merge branch 'master' into threads_wasm
annxingyuan Jul 30, 2020
7c02e0e
fix
annxingyuan Jul 30, 2020
c765acb
update size
annxingyuan Jul 30, 2020
2fc0b3d
poc
annxingyuan Jul 30, 2020
c14d418
clean
annxingyuan Jul 30, 2020
02b4890
rm
annxingyuan Jul 30, 2020
8600c45
Merge branch 'master' into wasm_standalone
annxingyuan Jul 30, 2020
e970088
revive
annxingyuan Jul 30, 2020
537ea6c
revive simd
annxingyuan Jul 30, 2020
a8b47d2
fix
annxingyuan Jul 30, 2020
1c30976
Merge branch 'master' into wasm_standalone
annxingyuan Jul 31, 2020
7fcf701
Merge branch 'master' into wasm_standalone
annxingyuan Jul 31, 2020
d2d82f6
rm standalone from top
annxingyuan Jul 31, 2020
5ab0abb
rm
annxingyuan Jul 31, 2020
56996aa
add comments
annxingyuan Aug 2, 2020
62ba467
Merge branch 'master' into threads_wasm
annxingyuan Aug 3, 2020
048f1e6
comments
annxingyuan Aug 3, 2020
8948d67
merge
annxingyuan Aug 3, 2020
2687bf7
clean
annxingyuan Aug 3, 2020
808a41a
comments
annxingyuan Aug 3, 2020
2a7ce21
revive
annxingyuan Aug 3, 2020
d2a3d70
clean
annxingyuan Aug 3, 2020
68aeee8
oops
annxingyuan Aug 3, 2020
27a7fc6
comments
annxingyuan Aug 3, 2020
0f66b83
delete
annxingyuan Aug 3, 2020
b5ab8c7
rm
annxingyuan Aug 3, 2020
a0dd945
remove
annxingyuan Aug 3, 2020
292434a
bench
annxingyuan Aug 3, 2020
fd83531
path
annxingyuan Aug 3, 2020
59ae99a
fix
annxingyuan Aug 3, 2020
23a7d5f
Merge branch 'master' into threads_wasm
annxingyuan Aug 3, 2020
280e4c0
update docs
annxingyuan Aug 3, 2020
073500b
docs
annxingyuan Aug 3, 2020
4dd92f2
docs
annxingyuan Aug 3, 2020
11e4a17
typo
annxingyuan Aug 3, 2020
9593878
add message
annxingyuan Aug 3, 2020
c8149d8
docsg
annxingyuan Aug 3, 2020
74889f2
docs
annxingyuan Aug 3, 2020
d49f21e
docs
annxingyuan Aug 3, 2020
de9d82b
eocs
annxingyuan Aug 3, 2020
d3e297c
clean
annxingyuan Aug 3, 2020
18470d5
lint
annxingyuan Aug 3, 2020
70d62e5
Merge branch 'master' into threads_wasm
annxingyuan Aug 3, 2020
5feb860
ignore
annxingyuan Aug 3, 2020
763f25f
Merge branch 'master' into threads_wasm
annxingyuan Aug 4, 2020
c9508bf
update
annxingyuan Aug 4, 2020
d7d818f
docs
annxingyuan Aug 4, 2020
9dc8885
fix test
annxingyuan Aug 4, 2020
840c16b
fix
annxingyuan Aug 4, 2020
3794dc3
use pixel4 benchmarks
annxingyuan Aug 4, 2020
43fc845
Merge branch 'master' into threads_wasm
annxingyuan Aug 4, 2020
e945562
pr comments
annxingyuan Aug 4, 2020
ae85df3
rename
annxingyuan Aug 4, 2020
57e3487
pr comments
annxingyuan Aug 4, 2020
7075b30
comments
annxingyuan Aug 5, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ tensorflow-tfjs-*.tgz
tfjs-backend-wasm/dist
tfjs-backend-wasm/wasm-out/*.js
tfjs-backend-wasm/wasm-out/*.wasm
tfjs-backend-wasm/wasm-out/*.worker.ts
yalc.lock
yarn-error.log
75 changes: 46 additions & 29 deletions tfjs-backend-wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,45 @@ bundlers such as Parcel and WebPack need to be able to serve the `.wasm` file in
production. See [starter/parcel](./starter/parcel/) and
[starter/webpack](./starter/webpack/) for how to setup your favorite bundler.

If your server is serving the `.wasm` file on a different path or a different
name, use `setWasmPath` before you initialize the backend:
If you are serving the `.wasm` files from a different directory, call
`setWasmPaths` with the location of that directory before you initialize the
backend:

```ts
import {setWasmPath} from '@tensorflow/tfjs-backend-wasm';
setWasmPath(yourCustomPath); // or tf.wasm.setWasmPath when using <script> tags.
import {setWasmPaths} from '@tensorflow/tfjs-backend-wasm';
// setWasmPaths accepts a `prefix` argument which indicates the path to the
// directory where your WASM binaries are located.
setWasmPaths('www.yourdomain.com/'); // or tf.wasm.setWasmPaths when using <script> tags.
tf.setBackend('wasm').then(() => {...});
```

If you are using platform that does not support fetch directly, please set the
optional `usePlatformFetch` to true:
Note that if you call `setWasmPaths` with a `prefix`, it will be used to load
each binary (SIMD-enabled, threading-enabled, etc.) However you can specify
overrides for individual WASM binaries via the second `fileMap` argument of
`setWasmPaths`. This is also helpful in case your binaries have been renamed.

For example:

```ts
import {setWasmPaths} from '@tensorflow/tfjs-backend-wasm';
setWasmPaths(null /* custom prefix */, {
'tfjs-backend-wasm.wasm': 'www.yourdomain.com/renamed.wasm',
'tfjs-backend-wasm-simd.wasm': 'www.yourdomain.com/renamed-simd.wasm',
'tfjs-backend-wasm-threaded-simd.wasm': 'www.yourdomain.com/renamed-threaded-simd.wasm'
});
tf.setBackend('wasm').then(() => {...});
```

If you are using a platform that does not support fetch directly, please set the
optional `usePlatformFetch` argument to `true`:

```ts
import {setWasmPath} from '@tensorflow/tfjs-backend-wasm';
const usePlatformFetch = true;
setWasmPath(yourCustomPath, usePlatformFetch); // or tf.wasm.setWasmPath when using <script> tags.
setWasmPaths(yourCustomPathPrefix, null /* file map */, usePlatformFetch);
tf.setBackend('wasm').then(() => {...});
```

## Benchmarks

The benchmarks below show inference times (ms) for two different edge-friendly
Expand All @@ -108,14 +129,14 @@ JS backend, and ~5.3-7.7X slower than the WebGL backend.

<img src="./mobilenet-v2-bench.svg">

| MobileNet inference (ms) | WASM | WebGL | Plain JS | WASM + SIMD |
|--------------------------|-------|-------|----------|-------------|
| iPhone X | 147.1 | 20.3 | 941.3 | N/A |
| iPhone XS | 140 | 18.1 | 426.4 | N/A |
| Pixel 3 | 266.2 | 77.3 | 2345.2 | N/A |
| Desktop Linux | 91.5 | 17.1 | 1049 | N/A |
| Desktop Windows | 123.1 | 41.6 | 1117 | 37.2 |
| Macbook Pro | 98.4 | 19.6 | 893.5 | 30.2 |
| MobileNet inference (ms) | WASM | WebGL | Plain JS | WASM + SIMD | WASM + SIMD + threads
|--------------------------|-------|-------|----------|-------------|----------------------
| iPhone X | 147.1 | 20.3 | 941.3 | N/A | N/A |
| iPhone XS | 140 | 18.1 | 426.4 | N/A | N/A |
| Pixel 4 | 197.3 | 68.3 | 2228.2 | 142.4 | N/A |
| Desktop Linux | 91.5 | 17.1 | 1049 | 61.9 | 30.0 |
| Desktop Windows | 123.1 | 41.6 | 1117 | 37.2 | N/A |
| Macbook Pro | 98.4 | 19.6 | 893.5 | 30.2 | 10.3 |



Expand All @@ -128,14 +149,14 @@ the device).

<img src="./face-detector-bench.svg">

| Face Detector inference (ms) | WASM | WebGL | Plain JS | WASM + SIMD |
|------------------------------|------|-------|----------|-------------|
| iPhone X | 22.4 | 13.5 | 318 | N/A |
| iPhone XS | 21.4 | 10.5 | 176.9 | N/A |
| Pixel 3 | 40.7 | 31.8 | 535.2 | N/A |
| Desktop Linux | 12.6 | 12.7 | 249.5 | N/A |
| Desktop Windows | 16.2 | 7.1 | 270.9 | 7.5 |
| Macbook Pro 15 2019 | 13.6 | 22.7 | 209.1 | 7.9 |
| Face Detector inference (ms) | WASM | WebGL | Plain JS | WASM + SIMD | WASM + SIMD + threads
|------------------------------|------|-------|----------|-------------|----------------------
| iPhone X | 22.4 | 13.5 | 318 | N/A | N/A |
| iPhone XS | 21.4 | 10.5 | 176.9 | N/A | N/A |
| Pixel 4 | 32.2 | 30.6 | 478.8 | 24.0 | N/A |
| Desktop Linux | 12.6 | 12.7 | 249.5 | 8.0 | 6.2 |
| Desktop Windows | 16.2 | 7.1 | 270.9 | 7.5 | N/A |
| Macbook Pro 15 2019 | 13.6 | 22.7 | 209.1 | 7.9 | 4.0 |

# FAQ

Expand Down Expand Up @@ -168,12 +189,8 @@ inference as fast as possible.
### Do you work in node?
Yes. If you run into issues, please let us know.

### Do you support SIMD?
Yes. We take advantage of SIMD wherever it is supported. If you intend to serve the WASM assets yourself, note that the SIMD-enabled WASM binary is separate from the default binary.

### Do you support multi-threading?
Multi-threading support is not a priority for us at this point since it is still
a proposal. We will keep a close eye on it as the proposal progresses.
### Do you support SIMD and multi-threading?
Yes. We take advantage of SIMD and multi-threading wherever they are supported by testing the capabilities of your runtime and loading the appropriate WASM binary. If you intend to serve the WASM binaries from a custom location (via `setWasmPaths`), please note that the SIMD-enabled and threading-enabled binaries are separate from the regular binary.

### How do I give feedback?
We'd love your feedback as we develop this backend! Please file an issue
Expand Down
8 changes: 5 additions & 3 deletions tfjs-backend-wasm/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ const karmaTypescriptConfig = {
compilerOptions: {allowJs: true, declaration: false},
bundlerOptions: {
sourceMap: true,
// Ignore the import of the `worker_threads` package used in a core test
// meant to run in node.
exclude: ['worker_threads'],
// Ignore the import of the `worker_threads`/`perf_hooks` packages meant to
// run in node.
exclude: ['worker_threads', 'perf_hooks'],
// worker_node_test in tfjs-core contains a conditional require statement
// that confuses the bundler of karma-typescript.
ignore: ['./worker_node_test'],
Expand Down Expand Up @@ -61,6 +61,8 @@ module.exports = function(config) {
{pattern: 'wasm-out/**/*.wasm', included: false},
// Import the generated js library from emscripten.
{pattern: 'wasm-out/**/*.js'},
// Import the generated worker file from emscripten.
{pattern: 'wasm-out/tfjs-backend-wasm-threaded-simd.worker.ts'},
// Import the rest of the sources.
{pattern: 'src/**/*.ts'},
],
Expand Down
2 changes: 2 additions & 0 deletions tfjs-backend-wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"build-deps": "cd ../tfjs-core && yarn && yarn build",
"build-deps-ci": "cd ../tfjs-core && yarn && yarn build-ci",
"build": "rimraf dist/ && tsc && ./scripts/build-wasm.sh",
"build-dev": "rimraf dist/ && tsc && ./scripts/build-wasm.sh --dev",
"publish-local": "rimraf dist/ && yarn build && rollup -c && yalc push",
"build-ci": "./scripts/build-ci.sh",
"build-npm": "./scripts/build-npm.sh",
Expand All @@ -25,6 +26,7 @@
"cpplint": "./scripts/cpplint.js",
"lint": "tslint -p . -t verbose && yarn cpplint",
"test": "yarn && yarn build-deps && yarn build && karma start",
"test-dev": "yarn && yarn build-deps && yarn build-dev && karma start",
"test-ci": "./scripts/test-ci.sh",
"test-node": "ts-node --skip-ignore -P tsconfig.test.json src/test_node.ts",
"test-bundle-size": "./scripts/test-bundle-size.js",
Expand Down
1 change: 1 addition & 0 deletions tfjs-backend-wasm/scripts/build-benchmark.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ yarn rollup -c
cp dist/tf-backend-wasm.js ../e2e/benchmarks/
cp wasm-out/tfjs-backend-wasm.wasm ../e2e/benchmarks/
cp wasm-out/tfjs-backend-wasm-simd.wasm ../e2e/benchmarks/
cp wasm-out/tfjs-backend-wasm-threaded-simd.wasm ../e2e/benchmarks/
22 changes: 16 additions & 6 deletions tfjs-backend-wasm/scripts/build-wasm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,22 @@ cp -f bazel-bin/src/cc/tfjs-backend-wasm.js \
bazel-bin/src/cc/tfjs-backend-wasm.wasm \
wasm-out/

# SIMD build.
yarn bazel build -c opt //src/cc:tfjs-backend-wasm-simd.js --config=wasm --copt="-msimd128"
cp -f bazel-bin/src/cc/tfjs-backend-wasm-simd.js \
bazel-bin/src/cc/tfjs-backend-wasm-simd.wasm \
wasm-out/
if [[ "$1" != "--dev" ]]; then
# SIMD build.
yarn bazel build -c opt //src/cc:tfjs-backend-wasm-simd.wasm --config=wasm --copt="-msimd128"
cp -f bazel-bin/src/cc/tfjs-backend-wasm-simd.wasm \
wasm-out/

# Threaded + SIMD build.
yarn bazel build -c opt //src/cc:tfjs-backend-wasm-threaded-simd.js --config=wasm --copt="-pthread" --copt="-msimd128"
cp -f bazel-bin/src/cc/tfjs-backend-wasm-threaded-simd.js \
bazel-bin/src/cc/tfjs-backend-wasm-threaded-simd.worker.js \
bazel-bin/src/cc/tfjs-backend-wasm-threaded-simd.wasm \
wasm-out/

node ./scripts/create-worker-module.js
fi

mkdir -p dist
# Only copying binary into dist because the js module gets bundled.
# Only copying binaries into dist because the js modules get bundled.
cp wasm-out/*.wasm dist/
35 changes: 35 additions & 0 deletions tfjs-backend-wasm/scripts/create-worker-module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/

/**
* This file creates a TypeScript module that exports the contents of the
* Emscripten-generated WASM worker script so that it can be inlined by the
* tf-backend-wasm bundle.
*/

const fs = require('fs');

const BASE_PATH = './wasm-out/';
const WORKER_PATH = `${BASE_PATH}tfjs-backend-wasm-threaded-simd.worker.js`;

// Write out a worker TypeScript module.
const workerContents = fs.readFileSync(WORKER_PATH, "utf8");
fs.writeFileSync(`${BASE_PATH}tfjs-backend-wasm-threaded-simd.worker.ts`,
`export const wasmWorkerContents = '${workerContents.trim()}';`);

// Delete the original worker file.
fs.unlinkSync(WORKER_PATH)
Loading