diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 92261f6d1ac7..200a41e3a4eb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -389,6 +389,12 @@ jobs: - run: echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV if: matrix.target != '' + # Install OpenVINO for testing wasmtime-wasi-nn. + - uses: abrown/install-openvino-action@v6 + with: + version: 2022.3.0 + apt: true + # Fix an ICE for now in gcc when compiling zstd with debuginfo (??) - run: echo CFLAGS=-g0 >> $GITHUB_ENV if: matrix.target == 'x86_64-pc-windows-gnu' @@ -479,32 +485,6 @@ jobs: # Windows fails GitHub Actions will confusingly mark the failed Windows job # as cancelled instead of failed. - # Build and test the wasi-nn module. - test_wasi_nn: - needs: determine - if: needs.determine.outputs.run-full - name: Test wasi-nn module - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - uses: ./.github/actions/install-rust - - run: rustup target add wasm32-wasi - - uses: abrown/install-openvino-action@v6 - with: - version: 2022.3.0 - apt: true - - run: ./ci/run-wasi-nn-example.sh - env: - RUST_BACKTRACE: 1 - - # common logic to cancel the entire run if this job fails - - run: gh run cancel ${{ github.run_id }} - if: failure() && github.event_name != 'pull_request' - env: - GH_TOKEN: ${{ github.token }} - build-preview1-component-adapter: name: Build wasi-preview1-component-adapter needs: determine @@ -752,7 +732,6 @@ jobs: - checks - checks_winarm64 - fuzz_targets - - test_wasi_nn - bench - meta_deterministic_check - verify-publish diff --git a/ci/run-tests.sh b/ci/run-tests.sh index b29b6eb71d9b..bb37c9e4af0e 100755 --- a/ci/run-tests.sh +++ b/ci/run-tests.sh @@ -5,8 +5,10 @@ cargo test \ --features wasi-threads \ --features wasi-http \ --features component-model \ + --features wasmtime-wasi-nn/test-check \ --workspace \ - --exclude 'wasmtime-wasi-*' \ + --exclude 'wasmtime-wasi-http' \ + --exclude 'wasmtime-wasi-crypto' \ --exclude wasi-tests \ --exclude wasi-http-tests \ --exclude command-tests \ diff --git a/ci/run-wasi-nn-example.sh b/ci/run-wasi-nn-example.sh deleted file mode 100755 index 09947da16d65..000000000000 --- a/ci/run-wasi-nn-example.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# The following script demonstrates how to execute a machine learning inference -# using the wasi-nn module optionally compiled into Wasmtime. Calling it will -# download the necessary model and tensor files stored separately in $FIXTURE -# into $TMP_DIR (optionally pass a directory with existing files as the first -# argument to re-try the script). Then, it will compile and run several examples -# in the Wasmtime CLI. -set -e -WASMTIME_DIR=$(dirname "$0" | xargs dirname) -FIXTURE=https://github.com/intel/openvino-rs/raw/main/crates/openvino/tests/fixtures/mobilenet -if [ -z "${1+x}" ]; then - # If no temporary directory is specified, create one. - TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) - REMOVE_TMP_DIR=1 -else - # If a directory was specified, use it and avoid removing it. - TMP_DIR=$(realpath $1) - REMOVE_TMP_DIR=0 -fi - -# One of the examples expects to be in a specifically-named directory. -mkdir -p $TMP_DIR/mobilenet -TMP_DIR=$TMP_DIR/mobilenet - -# Build Wasmtime with wasi-nn enabled; we attempt this first to avoid extra work -# if the build fails. -cargo build -p wasmtime-cli --features wasi-nn - -# Download all necessary test fixtures to the temporary directory. -wget --no-clobber $FIXTURE/mobilenet.bin --output-document=$TMP_DIR/model.bin -wget --no-clobber $FIXTURE/mobilenet.xml --output-document=$TMP_DIR/model.xml -wget --no-clobber $FIXTURE/tensor-1x224x224x3-f32.bgr --output-document=$TMP_DIR/tensor.bgr - -# Now build an example that uses the wasi-nn API. Run the example in Wasmtime -# (note that the example uses `fixture` as the expected location of the -# model/tensor files). -pushd $WASMTIME_DIR/crates/wasi-nn/examples/classification-example -cargo build --release --target=wasm32-wasi -cp target/wasm32-wasi/release/wasi-nn-example.wasm $TMP_DIR -popd -cargo run -- run --mapdir fixture::$TMP_DIR \ - --wasi-modules=experimental-wasi-nn $TMP_DIR/wasi-nn-example.wasm - -# Build and run another example, this time using Wasmtime's graph flag to -# preload the model. -pushd $WASMTIME_DIR/crates/wasi-nn/examples/classification-example-named -cargo build --release --target=wasm32-wasi -cp target/wasm32-wasi/release/wasi-nn-example-named.wasm $TMP_DIR -popd -cargo run -- run --mapdir fixture::$TMP_DIR --wasi-nn-graph openvino::$TMP_DIR \ - --wasi-modules=experimental-wasi-nn $TMP_DIR/wasi-nn-example-named.wasm - -# Clean up the temporary directory only if it was not specified (users may want -# to keep the directory around). -if [[ $REMOVE_TMP_DIR -eq 1 ]]; then - rm -rf $TMP_DIR -fi diff --git a/tests/all/cli_tests.rs b/tests/all/cli_tests.rs index 1f8200cc82af..2a5626f14ca7 100644 --- a/tests/all/cli_tests.rs +++ b/tests/all/cli_tests.rs @@ -597,6 +597,44 @@ fn run_simple_with_wasi_threads() -> Result<()> { Ok(()) } +#[cfg(feature = "wasi-nn")] +#[test] +fn image_classification_with_wasi_nn() -> Result<()> { + wasmtime_wasi_nn::test_check!(); + let wasm = + wasmtime_wasi_nn::test_check::cargo_build("crates/wasi-nn/examples/image-classification"); + let artifacts_dir = wasmtime_wasi_nn::test_check::artifacts_dir(); + let artifacts_dir = artifacts_dir.display(); + let stdout = run_wasmtime(&[ + "run", + "--wasi-modules=experimental-wasi-nn", + &format!("--mapdir=fixture::{artifacts_dir}"), + &format!("{}", wasm.display()), + ])?; + assert!(stdout.contains("InferenceResult(963")); + Ok(()) +} + +#[cfg(feature = "wasi-nn")] +#[test] +fn image_classification_with_wasi_nn_and_named_models() -> Result<()> { + wasmtime_wasi_nn::test_check!(); + let wasm = wasmtime_wasi_nn::test_check::cargo_build( + "crates/wasi-nn/examples/image-classification-named", + ); + let artifacts_dir = wasmtime_wasi_nn::test_check::artifacts_dir(); + let artifacts_dir = artifacts_dir.display(); + let stdout = run_wasmtime(&[ + "run", + "--wasi-modules=experimental-wasi-nn", + &format!("--mapdir=fixture::{artifacts_dir}"), + &format!("--wasi-nn-graph=openvino::{artifacts_dir}"), + &format!("{}", wasm.display()), + ])?; + assert!(stdout.contains("InferenceResult(963")); + Ok(()) +} + #[test] fn wasm_flags() -> Result<()> { // Any argument after the wasm module should be interpreted as for the