Skip to content

Commit d36160b

Browse files
authoredJun 24, 2024
wasi-nn: Add wasmedge-wasinn-example as smoke test (bytecodealliance#3554)
1 parent cfffb62 commit d36160b

File tree

4 files changed

+188
-33
lines changed

4 files changed

+188
-33
lines changed
 

‎.dockerignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# for now, it is used to speed up wasi-nn tests only.
2+
# you shall adapt below rules to incoming requirements
3+
4+
build
5+
*/build
6+
*/*/build
7+
*/*/*/build
8+
*/*/*/*/build
9+
*/*/*/*/*/build
10+
*/*/*/*/*/*/build
11+
.*
12+
13+
core/deps
14+
!core/deps/tensorflow-src
15+
samples
16+
tests

‎core/iwasm/libraries/wasi-nn/README.md

+18-22
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ For some historical reasons, there are two sets of functions in the header file.
2727

2828
There is a big difference between the two sets of functions, `tensor_type`.
2929

30-
``` c
30+
```c
3131
#if WASM_ENABLE_WASI_EPHEMERAL_NN != 0
3232
typedef enum { fp16 = 0, fp32, fp64, bf16, u8, i32, i64 } tensor_type;
3333
#else
@@ -147,39 +147,35 @@ Supported:
147147

148148
## Smoke test
149149

150-
Use [classification-example](https://github.com/bytecodealliance/wasi-nn/tree/main/rust/examples/classification-example) as a smoke test case to make sure the wasi-nn support in WAMR is working properly.
150+
### Testing with WasmEdge-WASINN Examples
151151

152-
> [!Important]
153-
> It requires openvino.
152+
To ensure everything is set up correctly, use the examples from [WasmEdge-WASINN-examples](https://github.com/second-state/WasmEdge-WASINN-examples/tree/master). These examples help verify that WASI-NN support in WAMR is functioning as expected.
154153

155-
### Prepare the model and the wasm
154+
> Note: The repository contains two types of examples. Some use the [standard wasi-nn](https://github.com/WebAssembly/wasi-nn), while others use [WasmEdge's version of wasi-nn](https://github.com/second-state/wasmedge-wasi-nn), which is enhanced to meet specific customer needs.
156155
157-
```bash
158-
$ pwd
159-
/workspaces/wasm-micro-runtime/core/iwasm/libraries/wasi-nn/test
160-
161-
$ docker build -t wasi-nn-example:v1.0 -f Dockerfile.wasi-nn-example .
162-
```
156+
The examples test the following machine learning backends:
163157

164-
There are model files(\*mobilenet\**) and wasm files(*wasi-nn-example.wasm*) in the directory */workspaces/wasi-nn/rust/examples/classification-example/build\* in the image of wasi-nn-example:v1.0.
158+
- OpenVINO
159+
- PyTorch
160+
- TensorFlow Lite
165161

166-
### build iwasm and test
162+
Due to the different requirements of each backend, we'll use a Docker container for a hassle-free testing environment.
167163

168-
_TODO: May need alternative steps to build the iwasm and test in the container of wasi-nn-example:v1.0_
164+
#### Prepare the execution environment
169165

170166
```bash
171167
$ pwd
172-
/workspaces/wasm-micro-runtime
168+
/workspaces/wasm-micro-runtime/
173169

174-
$ docker run --rm -it -v $(pwd):/workspaces/wasm-micro-runtime wasi-nn-example:v1.0 /bin/bash
170+
$ docker build -t wasi-nn-smoke:v1.0 -f Dockerfile.wasi-nn-smoke .
175171
```
176172

177-
> [!Caution]
178-
> The following steps are executed in the container of wasi-nn-example:v1.0.
173+
#### Execute
179174

180175
```bash
181-
$ cd /workspaces/wasm-micro-runtime/product-mini/platforms/linux
182-
$ cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_EPHEMERAL_NN=1
183-
$ cmake --build build
184-
$ ./build/iwasm -v=5 --map-dir=/workspaces/wasi-nn/rust/examples/classification-example/build/::fixture /workspaces/wasi-nn/rust/examples/classification-example/build/wasi-nn-example.wasm
176+
$ docker run --rm wasi-nn-smoke:v1.0
185177
```
178+
179+
### Testing with bytecodealliance wasi-nn
180+
181+
For another example, check out [classification-example](https://github.com/bytecodealliance/wasi-nn/tree/main/rust/examples/classification-example), which focuses on OpenVINO. You can run it using the same Docker container mentioned above.

‎core/iwasm/libraries/wasi-nn/test/Dockerfile.wasi-nn-example ‎core/iwasm/libraries/wasi-nn/test/Dockerfile.wasi-nn-smoke

+34-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (C) 2019 Intel Corporation. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
33

4-
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye
4+
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye@sha256:ddc1ee022d327f024c07484c9333db3fbbfd504bc096cdb66635653a2bebb33e
55

66
ARG DEBIAN_FRONTEND=noninteractive
77
ENV TZ=Asian/Shanghai
@@ -10,10 +10,6 @@ ENV TZ=Asian/Shanghai
1010
RUN apt-get update \
1111
&& apt-get upgrade -y
1212

13-
#
14-
# Rust targets
15-
RUN rustup target add wasm32-wasi wasm32-unknown-unknown
16-
1713
#
1814
# Openvino
1915
# Refer to
@@ -42,16 +38,43 @@ RUN tar -xf wasmtime-v21.0.0-x86_64-linux.tar.xz \
4238

4339
#
4440
# wasi-nn
41+
# compilation requirements
42+
RUN rustup target add wasm32-wasi wasm32-unknown-unknown
4543
WORKDIR /workspaces/wasi-nn
4644
RUN git clone --depth 1 https://github.com/bytecodealliance/wasi-nn.git .
4745
# hadolint ignore=DL3059
48-
RUN ./build.sh rust
49-
46+
#RUN ./build.sh rust
5047
# There are model files(mobilenet*) and wasm files(wasi-nn-example.wasm) in the directory,
5148
# /workspaces/wasi-nn/rust/examples/classification-example/build
5249

53-
RUN apt-get autoremove -y \
54-
&& apt-get clean -y \
55-
&& rm -rf /tmp/*
50+
#
51+
# wasmedge
52+
WORKDIR /tmp
53+
RUN wget -q https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh \
54+
&& chmod a+x ./install.sh
55+
RUN ./install.sh -p /opt/wasmedge --plugins wasi_nn-tensorflowlite
56+
ENV PATH=/opt/wasmedge/bin:${PATH}
57+
ENV WASMEDGE_LIB_DIR=/opt/wasmedge/lib
58+
59+
#
60+
# wasmedge-wasinn-examples
61+
WORKDIR /workspaces/wasmedge-wasinn-examples
62+
RUN git clone --depth 1 https://github.com/second-state/WasmEdge-WASINN-examples.git .
63+
64+
#
65+
# iwasm. build from source
66+
WORKDIR /workspaces/wamr
67+
COPY . .
68+
69+
WORKDIR /workspaces/wamr/product-mini/platforms/linux
70+
RUN cmake -S . -B build -DWAMR_BUILD_WASI_NN=1 -DWAMR_BUILD_WASI_EPHEMERAL_NN=1 \
71+
&& cmake --build build
72+
RUN ln -sf "$(realpath ./build/iwasm)" /usr/local/bin/iwasm
5673

57-
WORKDIR /workspaces
74+
#
75+
# add smoke test script
76+
COPY core/iwasm/libraries/wasi-nn/test/run_smoke_test.py /
77+
78+
#
79+
WORKDIR /workspaces/wasmedge-wasinn-examples
80+
CMD ["python3", "/run_smoke_test.py"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (C) 2019 Intel Corporation. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#
6+
7+
from pathlib import Path
8+
from pprint import pprint
9+
import re
10+
import shlex
11+
import shutil
12+
import subprocess
13+
from typing import List
14+
15+
16+
def execute_tflite_birds_v1_image_once(
17+
runtime_bin: str, runtime_args: List[str], cwd: Path
18+
) -> str:
19+
"""
20+
execute tflite_birds_v1_image example with
21+
22+
```
23+
iwasm --native-lib=somewhere/libwasi-nn-tflite.so --map-dir=.:. \
24+
./wasmedge-wasinn-example-tflite-bird-image.wasm \
25+
lite-model_aiy_vision_classifier_birds_V1_3.tflite \
26+
bird.jpg
27+
```
28+
29+
or
30+
31+
```
32+
wasmedge --dir=.:. \
33+
./wasmedge-wasinn-example-tflite-bird-image.wasm \
34+
lite-model_aiy_vision_classifier_birds_V1_3.tflite \
35+
bird.jpg
36+
```
37+
38+
assumption:
39+
- under the right directory, tflite-birds_v1-image
40+
- every materials are ready
41+
"""
42+
43+
wasm_file = "./wasmedge-wasinn-example-tflite-bird-image.wasm"
44+
wasm_args = ["lite-model_aiy_vision_classifier_birds_V1_3.tflite", "bird.jpg"]
45+
46+
cmd = [runtime_bin]
47+
cmd.extend(runtime_args)
48+
cmd.append(wasm_file)
49+
cmd.extend(wasm_args)
50+
51+
try:
52+
p = subprocess.run(
53+
cmd,
54+
cwd=cwd,
55+
capture_output=True,
56+
check=True,
57+
text=True,
58+
universal_newlines=True,
59+
)
60+
return p.stdout
61+
except subprocess.CalledProcessError as e:
62+
print(e.stderr)
63+
print()
64+
print(e.stdout)
65+
66+
67+
def filter_output_tflite_birds_v1_image(output: str) -> List[str]:
68+
"""
69+
not all output is needed for comparision
70+
71+
pick lines like: " 1.) [526](136)Cathartes burrovianus"
72+
"""
73+
filtered = []
74+
PATTERN = re.compile(r"^\s+\d\.\)\s+\[\d+\]\(\d+\)\w+")
75+
for line in output.split("\n"):
76+
if PATTERN.search(line):
77+
filtered.append(line.strip())
78+
79+
return filtered
80+
81+
82+
def execute_tflite_birds_v1_image(iwasm_bin: str, wasmedge_bin: str, cwd: Path):
83+
iwasm_output = execute_tflite_birds_v1_image_once(
84+
iwasm_bin,
85+
[
86+
"--native-lib=/workspaces/wamr/product-mini/platforms/linux/build/libwasi-nn-tflite.so",
87+
"--map-dir=.:.",
88+
],
89+
cwd,
90+
)
91+
iwasm_output = filter_output_tflite_birds_v1_image(iwasm_output)
92+
93+
wasmedge_output = execute_tflite_birds_v1_image_once(
94+
wasmedge_bin, ["--dir=.:."], cwd
95+
)
96+
wasmedge_output = filter_output_tflite_birds_v1_image(wasmedge_output)
97+
98+
if iwasm_output == wasmedge_output:
99+
print("- tflite_birds_v1_image. PASS")
100+
return
101+
102+
print("- tflite_birds_v1_image. FAILED")
103+
print("------------------------------------------------------------")
104+
pprint(iwasm_output)
105+
print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
106+
pprint(wasmedge_output)
107+
print("------------------------------------------------------------")
108+
109+
110+
def execute_wasmedge_wasinn_exmaples(iwasm_bin: str, wasmedge_bin: str):
111+
assert Path.cwd().name == "wasmedge-wasinn-examples"
112+
assert shutil.which(iwasm_bin)
113+
assert shutil.which(wasmedge_bin)
114+
115+
tflite_birds_v1_image_dir = Path.cwd().joinpath("./tflite-birds_v1-image")
116+
execute_tflite_birds_v1_image(iwasm_bin, wasmedge_bin, tflite_birds_v1_image_dir)
117+
118+
119+
if __name__ == "__main__":
120+
execute_wasmedge_wasinn_exmaples("iwasm", "wasmedge")

0 commit comments

Comments
 (0)
Please sign in to comment.