Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@
[submodule "mv2/wasm/executorch"]
path = mv2/wasm/executorch
url = https://github.com/pytorch/executorch.git

[submodule "efficient_sam/wasm/executorch"]
path = efficient_sam/wasm/executorch
url = https://github.com/pytorch/executorch.git
36 changes: 36 additions & 0 deletions efficient_sam/wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved.
#
# This source code is licensed under the BSD-style license found in the LICENSE
# file in the root directory of this source tree.

# Please this file formatted by running:
# ~~~
# cmake-format -i CMakeLists.txt
# ~~~

add_subdirectory("executorch")

add_executable(executorch_wasm_demo_lib)
target_link_libraries(executorch_wasm_demo_lib PRIVATE executorch_wasm
executorch_backends)
target_link_options(executorch_wasm_demo_lib PRIVATE -sALLOW_MEMORY_GROWTH
-sSTACK_SIZE=262144 -sENVIRONMENT=web)

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/demo.js
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/demo.js
${CMAKE_CURRENT_BINARY_DIR}/demo.js
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/demo.js
COMMENT "Copying demo.js to build output directory")

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/demo.html
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/demo.html
${CMAKE_CURRENT_BINARY_DIR}/demo.html
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/demo.html
COMMENT "Copying demo.html to build output directory")

add_custom_target(
executorch_wasm_demo
DEPENDS executorch_wasm_demo_lib ${CMAKE_CURRENT_BINARY_DIR}/demo.js
${CMAKE_CURRENT_BINARY_DIR}/demo.html)
67 changes: 67 additions & 0 deletions efficient_sam/wasm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# ExecuTorch JavaScript Bindings Demo

This demo showcases the capabilities of ExecuTorch's JavaScript bindings. It is able to load a model, run inference, and classify an image natively in the browser.

## Installing Emscripten

[Emscripten](https://emscripten.org/index.html) is necessary to compile ExecuTorch for Wasm. You can install Emscripten with these commands:

```bash
# Clone the emsdk repository
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk

# Download and install version 4.0.10 of the SDK
./emsdk install 4.0.10
./emsdk activate 4.0.10

# Add the Emscripten environment variables to your shell
source ./emsdk_env.sh
```

## Setting up ExecuTorch and Generating the Model File

Make sure you have the system requirements listed in the [Getting Started Guide](https://docs.pytorch.org/executorch/main/getting-started.html#system-requirements) before continuing.

1. Install ExecuTorch from PyPI.
```bash
pip3 install executorch
```

2. Update the ExecuTorch submodule.
```bash
git submodule update --init --recursive executorch
```

3. Generate the EfficientSAM binary file for this demo.

```bash
bash export.sh
```
It should output a file called `xnnpack_efficient_sam.pte`.

## Building and Running

Once you have Emscripten installed, ExecuTorch set up, and the model file generated, you can build and run the demo. Building may take up to 9 minutes.

```bash
cd efficient_sam/wasm # The directory containing this README

# Build the demo
bash build.sh

# Run the demo
python3 -m http.server --directory build/
```

The page will be available at http://localhost:8000/demo.html.

## Demo Features

- Load a model from a file
- This demo only supports the EfficientSAM model. Passing in a model with different input/output shapes will result in an error.
- Run inference on an image
- Supported formats: `.png`, `.gif`, `.jpeg`, `.jpg`
- Select a point on the image to run inference
- May take around 6.5 seconds to run inference
- Show and hide the segmentation mask
29 changes: 29 additions & 0 deletions efficient_sam/wasm/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

CMAKE_OUT=build

emcmake cmake . -DEXECUTORCH_BUILD_WASM=ON \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No XNNPACK yet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requires pytorch/executorch#13234
Looks like that's been merged so I can add that in now

-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
-DEXECUTORCH_BUILD_EXTENSION_FLAT_TENSOR=ON \
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \
-DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON \
-DEXECUTORCH_BUILD_XNNPACK=ON \
-DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
-DEXECUTORCH_BUILD_DEVTOOLS=ON \
-DFLATCC_ALLOW_WERROR=OFF \
-DCMAKE_BUILD_TYPE=Release \
-B"${CMAKE_OUT}"

if [ "$(uname)" == "Darwin" ]; then
CMAKE_JOBS=$(( $(sysctl -n hw.ncpu) - 1 ))
else
CMAKE_JOBS=$(( $(nproc) - 1 ))
fi

cmake --build ${CMAKE_OUT} --target executorch_wasm_demo -j ${CMAKE_JOBS}
29 changes: 29 additions & 0 deletions efficient_sam/wasm/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!--
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Executorch Wasm Demo</title>
</head>
<body>
<button type="button" id="upload_model_button">Upload pte file</button>
<button disabled type="button" id="upload_image_button">Upload image file</button>
<button disabled type="button" id="inference_button">Run model</button>
<button disabled type="button" id="mask_button">Show mask</button>
<button disabled type="button" id="etdump_button">Download etdump</button>
<p id="model_text">No model uploaded</p>
<div id="canvas-container" style="position: relative;">
<canvas id="canvas" width="1024" height="1024" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
<canvas id="mask_canvas" width="1024" height="1024" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
<canvas id="pointer_canvas" width="1024" height="1024" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
</div>
<script src="demo.js"></script>
<script src="executorch_wasm_demo_lib.js"></script>
</body>
</html>
Loading