From 1dcf31adf579f97871e2b217429e84eaa19abf52 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Wed, 10 Apr 2024 15:23:10 +0200 Subject: [PATCH] Update Rust gen to use .wit spec This commit updates the regeneration script for the Rust bindings to use `wasi-nn.wit` types instead of `wasi-nn.witx`. The scripts has also been run and the bindings (src/generated.rs) have been updated. This example currently compiles but fails at runtime because the version of the wasi-nn spec that wasmtime is using is not the latest. Once it has been updated this example should work (I've tested it with the version that wasmtime is currently on and it works but that requires changes to the examples in this repository). Signed-off-by: Daniel Bevenius --- .github/workflows/main.yaml | 2 +- build.sh | 12 +- rust/Cargo.lock | 281 +- rust/Cargo.toml | 3 +- rust/README.md | 4 +- .../classification-example/Cargo.lock | 2635 ++++++++++++++++- .../classification-example/Cargo.toml | 19 +- .../classification-example/bin/Cargo.toml | 16 + .../classification-example/bin/src/main.rs | 71 + .../classification-example/lib/Cargo.toml | 18 + .../lib/src/bindings.rs | 18 + .../{ => lib}/src/imagenet_classes.rs | 0 .../classification-example/lib/src/lib.rs | 111 + .../lib/wasi_snapshot_preview1.reactor.wasm | Bin 0 -> 96758 bytes .../classification-example/src/main.rs | 77 - .../classification-example/wit/example.wit | 5 + rust/scripts/regenerate-bindings-from-wit.sh | 44 + rust/scripts/regenerate-bindings-from-witx.sh | 50 - rust/src/error.rs | 103 - rust/src/generated.rs | 1354 +++++++-- rust/src/graph.rs | 537 ---- rust/src/lib.rs | 31 +- rust/src/tensor.rs | 98 - 23 files changed, 4187 insertions(+), 1302 deletions(-) create mode 100644 rust/examples/classification-example/bin/Cargo.toml create mode 100644 rust/examples/classification-example/bin/src/main.rs create mode 100644 rust/examples/classification-example/lib/Cargo.toml create mode 100644 rust/examples/classification-example/lib/src/bindings.rs rename rust/examples/classification-example/{ => lib}/src/imagenet_classes.rs (100%) create mode 100644 rust/examples/classification-example/lib/src/lib.rs create mode 100644 rust/examples/classification-example/lib/wasi_snapshot_preview1.reactor.wasm delete mode 100644 rust/examples/classification-example/src/main.rs create mode 100644 rust/examples/classification-example/wit/example.wit create mode 100755 rust/scripts/regenerate-bindings-from-wit.sh delete mode 100755 rust/scripts/regenerate-bindings-from-witx.sh delete mode 100644 rust/src/error.rs delete mode 100644 rust/src/graph.rs delete mode 100644 rust/src/tensor.rs diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 6bb9d96..ecbb7f2 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -69,7 +69,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Regenerate bindings - run: rust/scripts/regenerate-bindings-from-witx.sh + run: rust/scripts/regenerate-bindings-from-wit.sh - name: Verify no changes run: git diff --ignore-submodules --no-ext-diff --name-only --exit-code diff --git a/build.sh b/build.sh index f73621b..00cc505 100755 --- a/build.sh +++ b/build.sh @@ -24,17 +24,15 @@ else echo "The first argument: $1" FIXTURE=https://github.com/intel/openvino-rs/raw/main/crates/openvino/tests/fixtures/mobilenet pushd $WASI_NN_DIR/rust/ - cargo build --release --target=wasm32-wasi + cargo build --release --target wasm32-wasi mkdir -p $WASI_NN_DIR/rust/examples/classification-example/build RUST_BUILD_DIR=$(realpath $WASI_NN_DIR/rust/examples/classification-example/build/) - cp -rn examples/images $RUST_BUILD_DIR - pushd examples/classification-example - cargo build --release --target=wasm32-wasi - cp target/wasm32-wasi/release/wasi-nn-example.wasm $RUST_BUILD_DIR - pushd build + cp -r examples/images $RUST_BUILD_DIR wget --no-clobber --directory-prefix=$RUST_BUILD_DIR $FIXTURE/mobilenet.bin wget --no-clobber --directory-prefix=$RUST_BUILD_DIR $FIXTURE/mobilenet.xml - wasmtime run --mapdir fixture::$RUST_BUILD_DIR wasi-nn-example.wasm --wasi-modules=experimental-wasi-nn + pushd examples/classification-example + cargo component build -p wasi-nn-example-lib --release + cargo run -p wasi-nn-example-bin --release ;; *) echo "Unknown build type $BUILD_TYPE" diff --git a/rust/Cargo.lock b/rust/Cargo.lock index a1ee20e..ae2bf18 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,29 +2,155 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "spdx" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9" +dependencies = [ + "smallvec", +] + [[package]] name = "syn" -version = "2.0.18" +version = "2.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" dependencies = [ "proc-macro2", "quote", @@ -57,9 +183,150 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "wasi-nn" -version = "0.6.0" +version = "0.7.0" dependencies = [ "thiserror", + "wit-bindgen", +] + +[[package]] +name = "wasm-encoder" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-metadata" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd83062c17b9f4985d438603cde0a5e8c5c8198201a6937f778b607924c7da2" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_derive", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" +dependencies = [ + "bitflags", + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288f992ea30e6b5c531b52cdd5f3be81c148554b09ea416f058d16556ba92c27" +dependencies = [ + "bitflags", + "wit-bindgen-rt", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e85e72719ffbccf279359ad071497e47eb0675fe22106dea4ed2d8a7fcb60ba4" +dependencies = [ + "anyhow", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb8738270f32a2d6739973cbbb7c1b6dd8959ce515578a6e19165853272ee64" + +[[package]] +name = "wit-bindgen-rust" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a39a15d1ae2077688213611209849cad40e9e5cccf6e61951a425850677ff3" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d376d3ae5850526dfd00d937faea0d81a06fa18f7ac1e26f386d760f241a8f4b" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196d3ecfc4b759a8573bf86a9b3f8996b304b3732e4c7de81655f875f6efdca6" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", ] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4efe84d..31ff58b 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasi-nn" -version = "0.6.0" +version = "0.7.0" authors = ["The Bytecode Alliance Developers"] description = "High-level Rust bindings for wasi-nn" license = "Apache-2.0" @@ -19,5 +19,6 @@ targets = ["wasm32-wasi"] [dependencies] thiserror = "1" +wit-bindgen = { version = "0.22.0", default-features = true, features = ['macros'] } [workspace] diff --git a/rust/README.md b/rust/README.md index 00e0a31..3c3b0af 100644 --- a/rust/README.md +++ b/rust/README.md @@ -48,11 +48,11 @@ To build this crate from source, use: `cargo build --target wasm32-wasi`. ### Generation This crate contains code ([`src/generated.rs`](src/generated.rs)) generated by -[`witx-bindgen`](https://github.com/bytecodealliance/wasi/tree/main/crates/witx-bindgen). To +[`wit-bindgen`](https://github.com/bytecodealliance/wasi/tree/main/crates/wit-bindgen). To regenerate this code, run the following script: ```console -$ scripts/regenerate-bindings-from-witx.sh +$ scripts/regenerate-bindings-from-wit.sh ``` diff --git a/rust/examples/classification-example/Cargo.lock b/rust/examples/classification-example/Cargo.lock index 4e4bb3e..efe9aeb 100644 --- a/rust/examples/classification-example/Cargo.lock +++ b/rust/examples/classification-example/Cargo.lock @@ -2,35 +2,247 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "ambient-authority" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "async-trait" +version = "0.1.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object 0.32.2", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "1.2.1" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "bytemuck" -version = "1.12.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cap-fs-ext" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "769f8cd02eb04d57f14e2e371ebb533f96817f9b2525d73a5c72b61ca7973747" +dependencies = [ + "cap-primitives", + "cap-std", + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "cap-net-ext" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ff6d3fb274292a9af283417e383afe6ded1fe66f6472d2c781216d3d80c218" +dependencies = [ + "cap-primitives", + "cap-std", + "rustix", + "smallvec", +] + +[[package]] +name = "cap-primitives" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90a0b44fc796b1a84535a63753d50ba3972c4db55c7255c186f79140e63d56d0" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes", + "ipnet", + "maybe-owned", + "rustix", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "cap-rand" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4327f08daac33a99bb03c54ae18c8f32c3ba31c728a33ddf683c6c6a5043de68" +dependencies = [ + "ambient-authority", + "rand", +] + +[[package]] +name = "cap-std" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "266626ce180cf9709f317d0bf9754e3a5006359d87f4bf792f06c9c5f1b63c0f" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes", + "rustix", +] + +[[package]] +name = "cap-time-ext" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1353421ba83c19da60726e35db0a89abef984b3be183ff6f58c5b8084fcd0c5" +dependencies = [ + "ambient-authority", + "cap-primitives", + "iana-time-zone", + "once_cell", + "rustix", + "winx", +] + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +dependencies = [ + "jobserver", + "libc", +] [[package]] name = "cfg-if" @@ -44,206 +256,2407 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpp_demangle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.14.3", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" + +[[package]] +name = "cranelift-control" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-frontend" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" + +[[package]] +name = "cranelift-native" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.107.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools", + "log", + "smallvec", + "wasmparser", + "wasmtime-types", +] + [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] -name = "flate2" -version = "1.0.24" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "crc32fast", - "miniz_oxide", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "gif" -version = "0.11.2" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "color_quant", - "weezl", + "crossbeam-utils", ] [[package]] -name = "image" -version = "0.24.4" +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "gif", - "jpeg-decoder", - "num-rational", - "num-traits", - "png", - "scoped_threadpool", - "tiff", + "generic-array", + "typenum", ] [[package]] -name = "image2tensor" -version = "0.3.0" +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ - "image", + "uuid", ] [[package]] -name = "jpeg-decoder" -version = "0.2.6" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] [[package]] -name = "miniz_oxide" -version = "0.5.4" +name = "directories-next" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" dependencies = [ - "adler", + "cfg-if", + "dirs-sys-next", ] [[package]] -name = "num-integer" -version = "0.1.44" +name = "dirs" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "autocfg", - "num-traits", + "dirs-sys", ] [[package]] -name = "num-rational" -version = "0.4.1" +name = "dirs-sys" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "libc", + "redox_users", + "winapi", ] [[package]] -name = "num-traits" -version = "0.2.14" +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ - "autocfg", + "libc", + "redox_users", + "winapi", ] [[package]] -name = "png" -version = "0.17.6" +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "encoding_rs" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "bitflags", - "crc32fast", - "flate2", - "miniz_oxide", + "cfg-if", ] [[package]] -name = "proc-macro2" -version = "1.0.60" +name = "env_logger" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ - "unicode-ident", + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", ] [[package]] -name = "quote" -version = "1.0.28" +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "proc-macro2", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "scoped_threadpool" -version = "0.1.9" +name = "fallible-iterator" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] -name = "syn" -version = "2.0.18" +name = "fd-lock" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "cfg-if", + "rustix", + "windows-sys 0.52.0", ] [[package]] -name = "thiserror" -version = "1.0.40" +name = "fdeflate" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ - "thiserror-impl", + "simd-adler32", ] [[package]] -name = "thiserror-impl" -version = "1.0.40" +name = "flate2" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ - "proc-macro2", - "quote", - "syn", + "crc32fast", + "miniz_oxide", ] [[package]] -name = "tiff" -version = "0.7.3" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", + "percent-encoding", ] [[package]] -name = "unicode-ident" -version = "1.0.9" +name = "fs-set-times" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" +dependencies = [ + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", +] [[package]] -name = "wasi-nn" -version = "0.6.0" +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ - "thiserror", + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "wasi-nn-example" -version = "0.19.0" +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ - "image2tensor", - "wasi-nn", + "futures-core", + "futures-sink", ] [[package]] -name = "weezl" -version = "0.1.5" +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "fxprof-processed-profile" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" +dependencies = [ + "bitflags 2.4.2", + "debugid", + "fxhash", + "serde", + "serde_json", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "tiff", +] + +[[package]] +name = "image2tensor" +version = "0.3.1" +dependencies = [ + "image", +] + +[[package]] +name = "indexmap" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "io-extras" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c301e73fb90e8a29e600a9f402d095765f74310d582916a952f618836a1bd1ed" +dependencies = [ + "io-lifetimes", + "windows-sys 0.52.0", +] + +[[package]] +name = "io-lifetimes" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "ittapi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" +dependencies = [ + "anyhow", + "ittapi-sys", + "log", +] + +[[package]] +name = "ittapi-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" +dependencies = [ + "cc", +] + +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "object" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" +dependencies = [ + "crc32fast", + "hashbrown 0.14.3", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openvino" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24bd3a7ef39968e6a4f1b1206c1c876f9bd50cf739ccbcd69f8539bbac5dcc7a" +dependencies = [ + "openvino-finder", + "openvino-sys", + "thiserror", +] + +[[package]] +name = "openvino-finder" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d234d1394a413ea8adaf0c40806b9ad1946be6310b441f688840654a331973" +dependencies = [ + "cfg-if", + "log", +] + +[[package]] +name = "openvino-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c98acf37fc84ad9d7da4dc6c18f0f60ad209b43a6f555be01f9003d0a2a43d" +dependencies = [ + "env_logger", + "libloading", + "once_cell", + "openvino-finder", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "itoa", + "libc", + "linux-raw-sys", + "once_cell", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spdx" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9" +dependencies = [ + "smallvec", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-interface" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aef1f9d4c1dbdd1cb3a63be9efd2f04d8ddbc919d46112982c76818ffc2f1a7" +dependencies = [ + "bitflags 2.4.2", + "cap-fs-ext", + "cap-std", + "fd-lock", + "io-lifetimes", + "rustix", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c12219811e0c1ba077867254e5ad62ee2c9c190b0d957110750ac0cda1ae96cd" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi-common" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "bitflags 2.4.2", + "cap-fs-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "io-extras", + "io-lifetimes", + "log", + "once_cell", + "rustix", + "system-interface", + "thiserror", + "tracing", + "wasmtime", + "wiggle", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasi-nn" +version = "0.7.0" +dependencies = [ + "thiserror", + "wit-bindgen 0.22.0", +] + +[[package]] +name = "wasi-nn-example-bin" +version = "0.19.0" +dependencies = [ + "anyhow", + "cap-std", + "wasi-common", + "wasmtime", + "wasmtime-wasi", + "wasmtime-wasi-nn", +] + +[[package]] +name = "wasi-nn-example-lib" +version = "0.19.0" +dependencies = [ + "image2tensor", + "wasi-nn", + "wit-bindgen 0.21.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-encoder" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-metadata" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd83062c17b9f4985d438603cde0a5e8c5c8198201a6937f778b607924c7da2" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_derive", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" +dependencies = [ + "bitflags 2.4.2", + "indexmap", + "semver", +] + +[[package]] +name = "wasmprinter" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a67e66da702706ba08729a78e3c0079085f6bfcb1a62e4799e97bbf728c2c265" +dependencies = [ + "anyhow", + "wasmparser", +] + +[[package]] +name = "wasmtime" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "addr2line", + "anyhow", + "async-trait", + "bincode", + "bumpalo", + "cfg-if", + "encoding_rs", + "fxprof-processed-profile", + "gimli", + "indexmap", + "ittapi", + "libc", + "log", + "object 0.33.0", + "once_cell", + "paste", + "rayon", + "rustix", + "semver", + "serde", + "serde_derive", + "serde_json", + "target-lexicon", + "wasm-encoder", + "wasmparser", + "wasmtime-cache", + "wasmtime-component-macro", + "wasmtime-component-util", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", + "wasmtime-slab", + "wasmtime-winch", + "wat", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-cache" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "base64", + "bincode", + "directories-next", + "log", + "rustix", + "serde", + "serde_derive", + "sha2", + "toml", + "windows-sys 0.52.0", + "zstd", +] + +[[package]] +name = "wasmtime-component-macro" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" + +[[package]] +name = "wasmtime-cranelift" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli", + "log", + "object 0.33.0", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-native", + "gimli", + "object 0.33.0", + "target-lexicon", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-environ" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "bincode", + "cpp_demangle", + "cranelift-entity", + "gimli", + "indexmap", + "log", + "object 0.33.0", + "rustc-demangle", + "serde", + "serde_derive", + "target-lexicon", + "thiserror", + "wasm-encoder", + "wasmparser", + "wasmprinter", + "wasmtime-component-util", + "wasmtime-types", +] + +[[package]] +name = "wasmtime-fiber" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "rustix", + "wasmtime-asm-macros", + "wasmtime-versioned-export-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-jit-debug" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "object 0.33.0", + "once_cell", + "rustix", + "wasmtime-versioned-export-macros", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-runtime" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "cc", + "cfg-if", + "encoding_rs", + "indexmap", + "libc", + "log", + "mach2", + "memfd", + "memoffset", + "paste", + "psm", + "rustix", + "sptr", + "wasm-encoder", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit-debug", + "wasmtime-versioned-export-macros", + "wasmtime-wmemcheck", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-slab" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" + +[[package]] +name = "wasmtime-types" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "cranelift-entity", + "serde", + "serde_derive", + "thiserror", + "wasmparser", +] + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasmtime-wasi" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.4.2", + "bytes", + "cap-fs-ext", + "cap-net-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "futures", + "io-extras", + "io-lifetimes", + "once_cell", + "rustix", + "system-interface", + "thiserror", + "tokio", + "tracing", + "url", + "wasmtime", + "wiggle", + "windows-sys 0.52.0", +] + +[[package]] +name = "wasmtime-wasi-nn" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "openvino", + "thiserror", + "tracing", + "walkdir", + "wasmtime", + "wiggle", +] + +[[package]] +name = "wasmtime-winch" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "object 0.33.0", + "target-lexicon", + "wasmparser", + "wasmtime-cranelift", + "wasmtime-cranelift-shared", + "wasmtime-environ", + "winch-codegen", +] + +[[package]] +name = "wasmtime-wit-bindgen" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wit-parser", +] + +[[package]] +name = "wasmtime-wmemcheck" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" + +[[package]] +name = "wast" +version = "35.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" +dependencies = [ + "leb128", +] + +[[package]] +name = "wast" +version = "201.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ef6e1ef34d7da3e2b374fd2b1a9c0227aff6cad596e1b24df9b58d0f6222faa" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453d5b37a45b98dee4f4cb68015fc73634d7883bbef1c65e6e9c78d454cf3f32" +dependencies = [ + "wast 201.0.0", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "wiggle" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "async-trait", + "bitflags 2.4.2", + "thiserror", + "tracing", + "wasmtime", + "wiggle-macro", +] + +[[package]] +name = "wiggle-generate" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "heck", + "proc-macro2", + "quote", + "shellexpand", + "syn", + "witx", +] + +[[package]] +name = "wiggle-macro" +version = "20.0.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wiggle-generate", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winch-codegen" +version = "0.18.0" +source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c6d923ae3fddb191e1ebbd4f2c1cf58b98080950" +dependencies = [ + "anyhow", + "cranelift-codegen", + "gimli", + "regalloc2", + "smallvec", + "target-lexicon", + "wasmparser", + "wasmtime-environ", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + +[[package]] +name = "winx" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" +dependencies = [ + "bitflags 2.4.2", + "windows-sys 0.52.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbdedb8dd38c89c2cfa71e7450515f1c17f94cc2853881652d005b10f3f2559c" +dependencies = [ + "bitflags 2.4.2", + "wit-bindgen-rt 0.21.0", + "wit-bindgen-rust-macro 0.21.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288f992ea30e6b5c531b52cdd5f3be81c148554b09ea416f058d16556ba92c27" +dependencies = [ + "bitflags 2.4.2", + "wit-bindgen-rt 0.22.0", + "wit-bindgen-rust-macro 0.22.0", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebcbf07363368a9e6e8b89c18bff176c4f35ed2dd2f2f5f9c473bb56813369b" +dependencies = [ + "anyhow", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e85e72719ffbccf279359ad071497e47eb0675fe22106dea4ed2d8a7fcb60ba4" +dependencies = [ + "anyhow", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "026d24a27f6712541fa534f2954bd9e0eb66172f033c2157c0f31d106255c497" + +[[package]] +name = "wit-bindgen-rt" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb8738270f32a2d6739973cbbb7c1b6dd8959ce515578a6e19165853272ee64" + +[[package]] +name = "wit-bindgen-rust" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a4d36bf13b5ef534599d24dae792b1ae2b40fe1248c2754fd3f7343fb2ca70" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wasm-metadata", + "wit-bindgen-core 0.21.0", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a39a15d1ae2077688213611209849cad40e9e5cccf6e61951a425850677ff3" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "wasm-metadata", + "wit-bindgen-core 0.22.0", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4bf1b15b5227d1ca9ba7fc6a7850c72f9df0fbac3c46a0855763cc454ff11a" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core 0.21.0", + "wit-bindgen-rust 0.21.0", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d376d3ae5850526dfd00d937faea0d81a06fa18f7ac1e26f386d760f241a8f4b" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core 0.22.0", + "wit-bindgen-rust 0.22.0", +] + +[[package]] +name = "wit-component" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825" +dependencies = [ + "anyhow", + "bitflags 2.4.2", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.201.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196d3ecfc4b759a8573bf86a9b3f8996b304b3732e4c7de81655f875f6efdca6" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "witx" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b" +dependencies = [ + "anyhow", + "log", + "thiserror", + "wast 35.0.2", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zstd" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/rust/examples/classification-example/Cargo.toml b/rust/examples/classification-example/Cargo.toml index abc0b0e..a3a8149 100644 --- a/rust/examples/classification-example/Cargo.toml +++ b/rust/examples/classification-example/Cargo.toml @@ -1,16 +1,5 @@ -[package] -name = "wasi-nn-example" -version = "0.19.0" -authors = ["The Bytecode Alliance Developers"] -readme = "README.md" -edition = "2018" -publish = false - -[dependencies] -wasi-nn = { path = "../../" } -image2tensor = { path = "../../../image2tensor" } - -# This crate is built with the wasm32-wasi target, so it's separate -# from the main Wasmtime build, so use this directive to exclude it -# from the parent directory's workspace. [workspace] +members = [ + "lib", + "bin", +] diff --git a/rust/examples/classification-example/bin/Cargo.toml b/rust/examples/classification-example/bin/Cargo.toml new file mode 100644 index 0000000..b332f81 --- /dev/null +++ b/rust/examples/classification-example/bin/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "wasi-nn-example-bin" +version = "0.19.0" +authors = ["The Bytecode Alliance Developers"] +readme = "README.md" +edition = "2018" +publish = false + +[dependencies] +#wasi-nn = { path = "../../" } +wasmtime = { git = "https://github.com/bytecodealliance/wasmtime.git", branch="main", features = ["component-model"] } +wasmtime-wasi = { git = "https://github.com/bytecodealliance/wasmtime.git", branch="main"} +wasmtime-wasi-nn = { git = "https://github.com/bytecodealliance/wasmtime.git", branch="main" } +wasi-common = { git = "https://github.com/bytecodealliance/wasmtime.git", branch="main" } +anyhow = "1.0.71" +cap-std = "3.0.0" diff --git a/rust/examples/classification-example/bin/src/main.rs b/rust/examples/classification-example/bin/src/main.rs new file mode 100644 index 0000000..9f65e8f --- /dev/null +++ b/rust/examples/classification-example/bin/src/main.rs @@ -0,0 +1,71 @@ +use anyhow::Result; +use std::path::Path; +use wasi_common::sync::Dir; +use wasmtime::{Config, Engine, Store}; +use wasmtime_wasi::WasiCtx; +use wasmtime_wasi::{DirPerms, FilePerms, WasiCtxBuilder}; +use wasmtime_wasi::{ResourceTable, WasiView}; +use wasmtime_wasi_nn::{backend, Backend, InMemoryRegistry, WasiNnCtx}; + +use wasmtime::component::{Component, Linker as ComponentLinker}; + +fn main() -> wasmtime::Result<()> { + let module_path = Path::new("target/wasm32-wasi/release/wasi_nn_example_lib.wasm"); + let preopen_dir = Path::new("build"); + let mut config = Config::new(); + config.wasm_component_model(true); + + let engine = Engine::new(&config)?; + let backend = Backend::from(backend::openvino::OpenvinoBackend::default()); + let context = Ctx::new(preopen_dir, backend)?; + + let component = Component::from_file(&engine, &module_path).unwrap(); + + let mut component_linker = ComponentLinker::new(&engine); + wasmtime_wasi_nn::wit::ML::add_to_linker(&mut component_linker, |c: &mut Ctx| &mut c.wasi_nn)?; + wasmtime_wasi::command::sync::add_to_linker(&mut component_linker).unwrap(); + + let mut store = Store::new(&engine, context); + let instance = component_linker.instantiate(&mut store, &component)?; + let run_classification = { + let mut exports = instance.exports(&mut store); + exports.root().func("run-classification").unwrap() + }; + run_classification.call(&mut store, &[], &mut [])?; + Ok(()) +} + +struct Ctx { + table: ResourceTable, + wasi: WasiCtx, + wasi_nn: WasiNnCtx, +} + +impl WasiView for Ctx { + fn table(&mut self) -> &mut ResourceTable { + &mut self.table + } + fn ctx(&mut self) -> &mut WasiCtx { + &mut self.wasi + } +} + +impl Ctx { + fn new(preopen_dir: &Path, backend: Backend) -> Result { + // Create the WASI context. + let preopen_dir = Dir::open_ambient_dir(preopen_dir, cap_std::ambient_authority())?; + let wasi = WasiCtxBuilder::new() + .inherit_stdio() + .preopened_dir(preopen_dir, DirPerms::all(), FilePerms::all(), "build") + .build(); + + let registry = InMemoryRegistry::new(); + let wasi_nn = WasiNnCtx::new([backend.into()], registry.into()); + + Ok(Self { + table: ResourceTable::new(), + wasi, + wasi_nn, + }) + } +} diff --git a/rust/examples/classification-example/lib/Cargo.toml b/rust/examples/classification-example/lib/Cargo.toml new file mode 100644 index 0000000..3c6e802 --- /dev/null +++ b/rust/examples/classification-example/lib/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "wasi-nn-example-lib" +version = "0.19.0" +authors = ["The Bytecode Alliance Developers"] +readme = "README.md" +edition = "2018" +publish = false + +[dependencies] +wasi-nn = { path = "../../../" } +image2tensor = { path = "../../../../image2tensor" } +wit-bindgen = { version = "0.21.0", default-features = true, features = ['macros'] } + +[package.metadata.component] +adapter = "wasi_snapshot_preview1.reactor.wasm" + +[lib] +crate-type = ["cdylib"] diff --git a/rust/examples/classification-example/lib/src/bindings.rs b/rust/examples/classification-example/lib/src/bindings.rs new file mode 100644 index 0000000..a98fc8a --- /dev/null +++ b/rust/examples/classification-example/lib/src/bindings.rs @@ -0,0 +1,18 @@ +// Generated by `wit-bindgen` 0.21.0. DO NOT EDIT! +// Options used: + +#[cfg(target_arch = "wasm32")] +#[link_section = "component-type:wit-bindgen:0.21.0:wasi-nn-example-lib:encoded world"] +#[doc(hidden)] +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 197] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07<\x01A\x02\x01A\0\x04\ +\x011component:wasi-nn-example-lib/wasi-nn-example-lib\x04\0\x0b\x19\x01\0\x13wa\ +si-nn-example-lib\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-compone\ +nt\x070.201.0\x10wit-bindgen-rust\x060.21.0"; + +#[inline(never)] +#[doc(hidden)] +#[cfg(target_arch = "wasm32")] +pub fn __link_custom_section_describing_imports() { + wit_bindgen_rt::maybe_link_cabi_realloc(); +} diff --git a/rust/examples/classification-example/src/imagenet_classes.rs b/rust/examples/classification-example/lib/src/imagenet_classes.rs similarity index 100% rename from rust/examples/classification-example/src/imagenet_classes.rs rename to rust/examples/classification-example/lib/src/imagenet_classes.rs diff --git a/rust/examples/classification-example/lib/src/lib.rs b/rust/examples/classification-example/lib/src/lib.rs new file mode 100644 index 0000000..7a4dff4 --- /dev/null +++ b/rust/examples/classification-example/lib/src/lib.rs @@ -0,0 +1,111 @@ +use image2tensor::*; +use std::{convert::TryInto, fs}; +use wasi_nn; +mod imagenet_classes; + +wit_bindgen::generate!({ + path: "../wit/example.wit", + world: "classification-world", +}); + +struct Export; + +impl Guest for Export { + fn run_classification() { + let xml = fs::read_to_string("build/mobilenet.xml").unwrap(); + println!("Read graph XML, first 50 characters: {}", &xml[..50]); + + let weights = fs::read("build/mobilenet.bin").unwrap(); + println!("Read graph weights, size in bytes: {}", weights.len()); + + // Default is `Openvino` + `CPU`. + let builders = vec![xml.into_bytes(), weights]; + + let graph = wasi_nn::graph::load( + &builders, + wasi_nn::graph::GraphEncoding::Openvino, + wasi_nn::graph::ExecutionTarget::Cpu, + ) + .unwrap(); + println!("Loaded graph into wasi-nn with ID: {:?}", graph); + + let context = graph.init_execution_context().unwrap(); + println!("Created wasi-nn execution context with ID: {:?}", context); + + // Load a tensor that precisely matches the graph input tensor (see + // `fixture/frozen_inference_graph.xml`). + for i in 0..5 { + let filename: String = format!("{}{}{}", "build/images/", i, ".jpg"); + // Convert the image. If it fails just exit + let tensor_data = convert_image_to_tensor_bytes( + &filename, + 224, + 224, + TensorType::F32, + ColorOrder::BGR, + ) + .or_else(|e| Err(e)) + .unwrap(); + + println!("Read input tensor, size in bytes: {}", tensor_data.len()); + + // Set inference input. + let tensor = wasi_nn::tensor::Tensor::new( + &vec![1, 3, 224, 224], + wasi_nn::tensor::TensorType::Fp32, + &tensor_data, + ); + + context.set_input("0", tensor).unwrap(); + + // Execute the inference. + context.compute().unwrap(); + println!("Executed graph inference"); + + // Retrieve the output. + let output = context.get_output("0").unwrap(); + let results = bytes_to_f32_vec(output.data()); + let results = sort_results(&results); + println!("Found results, sorted top 5: {:?}", &results[..5]); + + for i in 0..5 { + println!( + "{}.) {}", + i + 1, + imagenet_classes::IMAGENET_CLASSES[results[i].0] + ); + } + } + } +} + +// Sort the buffer of probabilities. The graph places the match probability for each class at the +// index for that class (e.g. the probability of class 42 is placed at buffer[42]). Here we convert +// to a wrapping InferenceResult and sort the results. +fn sort_results(buffer: &[f32]) -> Vec { + let mut results: Vec = buffer + .iter() + // Skip the background class + .skip(1) + .enumerate() + .map(|(c, p)| InferenceResult(c, *p)) + .collect(); + results.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap()); + results +} + +pub fn bytes_to_f32_vec(data: Vec) -> Vec { + let chunks: Vec<&[u8]> = data.chunks(4).collect(); + let v: Vec = chunks + .into_iter() + .map(|c| f32::from_le_bytes(c.try_into().unwrap())) + .collect(); + + v.into_iter().collect() +} + +// A wrapper for class ID and match probabilities. +#[derive(Debug, PartialEq)] +struct InferenceResult(usize, f32); + +export!(Export); diff --git a/rust/examples/classification-example/lib/wasi_snapshot_preview1.reactor.wasm b/rust/examples/classification-example/lib/wasi_snapshot_preview1.reactor.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0717d984616e95be1e23795d02ace5606457075a GIT binary patch literal 96758 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 literal 0 HcmV?d00001 diff --git a/rust/examples/classification-example/src/main.rs b/rust/examples/classification-example/src/main.rs deleted file mode 100644 index 08ebd1e..0000000 --- a/rust/examples/classification-example/src/main.rs +++ /dev/null @@ -1,77 +0,0 @@ -use image2tensor::*; -use std::fs; -use wasi_nn; -mod imagenet_classes; - -pub fn main() { - let xml = fs::read_to_string("fixture/mobilenet.xml").unwrap(); - println!("Read graph XML, first 50 characters: {}", &xml[..50]); - - let weights = fs::read("fixture/mobilenet.bin").unwrap(); - println!("Read graph weights, size in bytes: {}", weights.len()); - - // Default is `Openvino` + `CPU`. - let graph = wasi_nn::GraphBuilder::default() - .build_from_bytes([xml.into_bytes(), weights]) - .unwrap(); - println!("Loaded graph into wasi-nn with ID: {:?}", graph); - - let mut context = graph.init_execution_context().unwrap(); - println!("Created wasi-nn execution context with ID: {:?}", context); - - // Load a tensor that precisely matches the graph input tensor (see - // `fixture/frozen_inference_graph.xml`). - for i in 0..5 { - let filename: String = format!("{}{}{}", "fixture/images/", i, ".jpg"); - // Convert the image. If it fails just exit - let tensor_data = - convert_image_to_tensor_bytes(&filename, 224, 224, TensorType::F32, ColorOrder::BGR) - .or_else(|e| Err(e)) - .unwrap(); - - println!("Read input tensor, size in bytes: {}", tensor_data.len()); - - // Set inference input. - let dimensions = [1, 3, 224, 224]; - context - .set_input(0, wasi_nn::TensorType::F32, &dimensions, &tensor_data) - .unwrap(); - - // Execute the inference. - context.compute().unwrap(); - println!("Executed graph inference"); - - // Retrieve the output. - let mut output_buffer = vec![0f32; 1001]; - context.get_output(0, &mut output_buffer).unwrap(); - - let results = sort_results(&output_buffer); - println!("Found results, sorted top 5: {:?}", &results[..5]); - - for i in 0..5 { - println!( - "{}.) {}", - i + 1, - imagenet_classes::IMAGENET_CLASSES[results[i].0] - ); - } - } -} - -// Sort the buffer of probabilities. The graph places the match probability for each class at the -// index for that class (e.g. the probability of class 42 is placed at buffer[42]). Here we convert -// to a wrapping InferenceResult and sort the results. -fn sort_results(buffer: &[f32]) -> Vec { - let mut results: Vec = buffer - .iter() - .skip(1) - .enumerate() - .map(|(c, p)| InferenceResult(c, *p)) - .collect(); - results.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap()); - results -} - -// A wrapper for class ID and match probabilities. -#[derive(Debug, PartialEq)] -struct InferenceResult(usize, f32); diff --git a/rust/examples/classification-example/wit/example.wit b/rust/examples/classification-example/wit/example.wit new file mode 100644 index 0000000..d65f2c4 --- /dev/null +++ b/rust/examples/classification-example/wit/example.wit @@ -0,0 +1,5 @@ +package wasi-nn:example; + +world classification-world { + export run-classification: func(); +} diff --git a/rust/scripts/regenerate-bindings-from-wit.sh b/rust/scripts/regenerate-bindings-from-wit.sh new file mode 100755 index 0000000..e2e02d0 --- /dev/null +++ b/rust/scripts/regenerate-bindings-from-wit.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -e + +# This script regenerates the Rust bindings for the wasi-nn specification. It has several steps: +# 1. retrieve and build `wit-bindgen` +# 2. retrieve the wasi-nn specification as WIT +# 3. use the WIT file to overwrite the `src/generated.rs` file +# +# Usage: $ regenerate-bindings-from-wit.sh +# +# The following environment variables can be overriden from the command line. Note that `*_REVISION` +# variables accept a commit hash, a branch, a tag, etc. +WIT_BINDGEN_REPOSITORY=${WIT_BINDGEN_REPOSITORY:-https://github.com/bytecodealliance/wit-bindgen.git} +WIT_BINDGEN_REVISION=${WIT_BINDGEN_REVISION:-main} +WASI_NN_RAW_URL=${WASI_NN_RAW_URL:-https://raw.githubusercontent.com/WebAssembly/wasi-nn} +WASI_NN_REVISION=${WASI_NN_REVISION:-main} + +echo "=== Retrieve and build 'wit-bindgen' ===" +TMP_DIR=$(mktemp -d /tmp/regenerate-bindings.XXXXXX) +pushd $TMP_DIR +# This block attempts to retrieve the least amount of Git history while allowing the user to pick +# any revision. +git init +git remote add origin ${WIT_BINDGEN_REPOSITORY} +git fetch --depth 1 origin ${WIT_BINDGEN_REVISION} +git checkout FETCH_HEAD +git submodule update --init --depth 1 +cargo build --bin wit-bindgen --release +popd + +echo +echo "=== Retrieve the wasi-nn specification as WIT ===" + +curl ${WASI_NN_RAW_URL}/${WASI_NN_REVISION}/wit/wasi-nn.wit --output ${TMP_DIR}/wasi-nn.wit + +echo "=== Overwrite the 'src/generated.rs' file ===" +# From https://stackoverflow.com/a/246128. +SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) +GENERATED_RS=$(realpath ${SCRIPT_DIR}/../src/generated.rs) +${TMP_DIR}/target/release/wit-bindgen rust ${TMP_DIR}/wasi-nn.wit --out-dir ${TMP_DIR} +cp ${TMP_DIR}/ml.rs ${GENERATED_RS} + +# Clean up +rm -rf $TMP_DIR diff --git a/rust/scripts/regenerate-bindings-from-witx.sh b/rust/scripts/regenerate-bindings-from-witx.sh deleted file mode 100755 index 93affd0..0000000 --- a/rust/scripts/regenerate-bindings-from-witx.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -set -e - -# This script regenerates the Rust bindings for the wasi-nn specification. It has several steps: -# 1. retrieve and build `witx-bindgen` -# 2. retrieve the wasi-nn specification as WITX -# 3. use the WITX file to overwrite the `src/generated.rs` file -# -# Usage: $ regenerate-bindings-from-witx.sh -# -# The following environment variables can be overriden from the command line. Note that `*_REVISION` -# variables accept a commit hash, a branch, a tag, etc. -WITX_BINDGEN_REPOSITORY=${WITX_BINDGEN_REPOSITORY:-https://github.com/bytecodealliance/wasi} -WITX_BINDGEN_REVISION=${WITX_BINDGEN_REVISION:-main} -WASI_NN_RAW_URL=${WASI_NN_RAW_URL:-https://raw.githubusercontent.com/WebAssembly/wasi-nn} -WASI_NN_REVISION=${WASI_NN_REVISION:-main} - -echo "=== Retrieve and build 'witx-bindgen' ===" -TMP_DIR=$(mktemp -d /tmp/regenerate-bindings.XXXXXX) -pushd $TMP_DIR -# This block attempts to retrieve the least amount of Git history while allowing the user to pick -# any revision. -git init -git remote add origin ${WITX_BINDGEN_REPOSITORY} -git fetch --depth 1 origin ${WITX_BINDGEN_REVISION} -git checkout FETCH_HEAD -git submodule update --init --depth 1 -cargo build --release -p witx-bindgen -popd - -echo -echo "=== Retrieve the wasi-nn specification as WITX ===" -curl ${WASI_NN_RAW_URL}/${WASI_NN_REVISION}/wasi-nn.witx --output ${TMP_DIR}/wasi-nn.witx - -echo -echo "=== Overwrite the 'src/generated.rs' file ===" -# From https://stackoverflow.com/a/246128. -SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) -GENERATED_RS=$(realpath ${SCRIPT_DIR}/../src/generated.rs) -${TMP_DIR}/target/release/witx-bindgen ${TMP_DIR}/wasi-nn.witx > ${GENERATED_RS} -# Also, here we fix up an issue in which `witx-bindgen` does not generate correct lifetimes; see -# https://github.com/bytecodealliance/wasi/issues/65. -sed -i "s/pub struct Tensor {/pub struct Tensor<'a> {/" ${GENERATED_RS} -sed -i "s/pub dimensions: TensorDimensions<'_>,/pub dimensions: TensorDimensions<'a>,/" ${GENERATED_RS} -sed -i "s/pub data: TensorData<'_>,/pub data: TensorData<'a>,/" ${GENERATED_RS} -sed -i "s/GraphBuilder<'_>/GraphBuilder<'a>/" ${GENERATED_RS} - - -# Clean up -rm -rf $TMP_DIR diff --git a/rust/src/error.rs b/rust/src/error.rs deleted file mode 100644 index 6426005..0000000 --- a/rust/src/error.rs +++ /dev/null @@ -1,103 +0,0 @@ -//! Wraps `wasi-nn` API errors. - -/// Wraps `wasi-nn` API errors. -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("IO Error: {0}")] - IoError(#[from] std::io::Error), - - #[error("Backend Error: {0}")] - BackendError(#[from] BackendError), -} - -#[derive(thiserror::Error, Debug)] -pub enum BackendError { - #[error("WASI-NN Backend Error: Caller module passed an invalid argument")] - InvalidArgument, - #[error("WASI-NN Backend Error: Invalid Encoding")] - InvalidEncoding, - #[error("WASI-NN Backend Error: Caller module is missing a memory export")] - MissingMemory, - #[error("WASI-NN Backend Error: Device or resource busy")] - Busy, - #[error("WASI-NN Backend Error: Runtime Error")] - RuntimeError, - #[error("WASI-NN Backend Error: Unsupported Operation")] - UnsupportedOperation, - #[error("WASI-NN Backend Error: Too Large")] - TooLarge, - #[error("WASI-NN Backend Error: Not Found")] - NotFound, - #[error("Unknown Wasi-NN Backend Error Code `{0}`")] - UnknownError(i32), -} - -impl From for BackendError { - fn from(value: i32) -> Self { - match value { - 1 => Self::InvalidArgument, - 2 => Self::InvalidEncoding, - 3 => Self::MissingMemory, - 4 => Self::Busy, - 5 => Self::RuntimeError, - 6 => Self::UnsupportedOperation, - 7 => Self::TooLarge, - 8 => Self::NotFound, - _ => Self::UnknownError(value), - } - } -} - -#[cfg(test)] -mod test { - use super::BackendError; - use crate::generated; - - macro_rules! test_enum_eq { - ( $v:expr, $enum_name:ident, $enum_element:ident ) => { - match $enum_name::from($v) { - $enum_name::$enum_element => {} - _ => { - assert!(false); - } - } - }; - } - - #[test] - fn test_wasi_nn_backend_error_from_i32() { - test_enum_eq!(1, BackendError, InvalidArgument); - test_enum_eq!(2, BackendError, InvalidEncoding); - test_enum_eq!(3, BackendError, MissingMemory); - test_enum_eq!(4, BackendError, Busy); - test_enum_eq!(5, BackendError, RuntimeError); - test_enum_eq!(6, BackendError, UnsupportedOperation); - test_enum_eq!(7, BackendError, TooLarge); - test_enum_eq!(8, BackendError, NotFound); - } - - #[test] - fn test_backend_error_with_generated() { - test_enum_eq!( - crate::generated::NN_ERRNO_INVALID_ARGUMENT.raw() as i32, - BackendError, - InvalidArgument - ); - test_enum_eq!( - generated::NN_ERRNO_INVALID_ENCODING.raw() as i32, - BackendError, - InvalidEncoding - ); - test_enum_eq!( - generated::NN_ERRNO_MISSING_MEMORY.raw() as i32, - BackendError, - MissingMemory - ); - test_enum_eq!(generated::NN_ERRNO_BUSY.raw() as i32, BackendError, Busy); - test_enum_eq!( - generated::NN_ERRNO_RUNTIME_ERROR.raw() as i32, - BackendError, - RuntimeError - ); - } -} diff --git a/rust/src/generated.rs b/rust/src/generated.rs index cabe53a..f090525 100644 --- a/rust/src/generated.rs +++ b/rust/src/generated.rs @@ -1,313 +1,1109 @@ -// This file is automatically generated, DO NOT EDIT -// -// To regenerate this file run the `crates/witx-bindgen` command - -use core::fmt; -use core::mem::MaybeUninit; -pub type BufferSize = u32; -#[repr(transparent)] -#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -pub struct NnErrno(u16); -pub const NN_ERRNO_SUCCESS: NnErrno = NnErrno(0); -pub const NN_ERRNO_INVALID_ARGUMENT: NnErrno = NnErrno(1); -pub const NN_ERRNO_INVALID_ENCODING: NnErrno = NnErrno(2); -pub const NN_ERRNO_MISSING_MEMORY: NnErrno = NnErrno(3); -pub const NN_ERRNO_BUSY: NnErrno = NnErrno(4); -pub const NN_ERRNO_RUNTIME_ERROR: NnErrno = NnErrno(5); -pub const NN_ERRNO_UNSUPPORTED_OPERATION: NnErrno = NnErrno(6); -pub const NN_ERRNO_TOO_LARGE: NnErrno = NnErrno(7); -pub const NN_ERRNO_NOT_FOUND: NnErrno = NnErrno(8); -impl NnErrno { - pub const fn raw(&self) -> u16 { - self.0 - } +// Generated by `wit-bindgen` 0.24.0. DO NOT EDIT! +// Options used: +#[allow(dead_code)] +pub mod wasi { + #[allow(dead_code)] + pub mod nn { + #[allow(dead_code, clippy::all)] + pub mod tensor { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + /// The dimensions of a tensor. + /// + /// The array length matches the tensor rank and each element in the array describes the size of + /// each dimension + pub type TensorDimensions = _rt::Vec::; + /// The type of the elements in a tensor. + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum TensorType { + Fp16, + Fp32, + Fp64, + Bf16, + U8, + I32, + I64, + } + impl ::core::fmt::Debug for TensorType { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + TensorType::Fp16 => { + f.debug_tuple("TensorType::Fp16").finish() + } + TensorType::Fp32 => { + f.debug_tuple("TensorType::Fp32").finish() + } + TensorType::Fp64 => { + f.debug_tuple("TensorType::Fp64").finish() + } + TensorType::Bf16 => { + f.debug_tuple("TensorType::Bf16").finish() + } + TensorType::U8 => { + f.debug_tuple("TensorType::U8").finish() + } + TensorType::I32 => { + f.debug_tuple("TensorType::I32").finish() + } + TensorType::I64 => { + f.debug_tuple("TensorType::I64").finish() + } + } + } + } + + impl TensorType{ + pub(crate) unsafe fn _lift(val: u8) -> TensorType{ + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } - pub fn name(&self) -> &'static str { - match self.0 { - 0 => "SUCCESS", - 1 => "INVALID_ARGUMENT", - 2 => "INVALID_ENCODING", - 3 => "MISSING_MEMORY", - 4 => "BUSY", - 5 => "RUNTIME_ERROR", - 6 => "UNSUPPORTED_OPERATION", - 7 => "TOO_LARGE", - 8 => "NOT_FOUND", - _ => unsafe { core::hint::unreachable_unchecked() }, + match val { + 0 => TensorType::Fp16, + 1 => TensorType::Fp32, + 2 => TensorType::Fp64, + 3 => TensorType::Bf16, + 4 => TensorType::U8, + 5 => TensorType::I32, + 6 => TensorType::I64, + + _ => panic!("invalid enum discriminant"), + } } - } - pub fn message(&self) -> &'static str { - match self.0 { - 0 => "", - 1 => "", - 2 => "", - 3 => "", - 4 => "", - 5 => "", - 6 => "", - 7 => "", - 8 => "", - _ => unsafe { core::hint::unreachable_unchecked() }, + } + + /// The tensor data. + /// + /// Initially conceived as a sparse representation, each empty cell would be filled with zeros + /// and the array length must match the product of all of the dimensions and the number of bytes + /// in the type (e.g., a 2x2 tensor with 4-byte f32 elements would have a data array of length + /// 16). Naturally, this representation requires some knowledge of how to lay out data in + /// memory--e.g., using row-major ordering--and could perhaps be improved. + pub type TensorData = _rt::Vec::; + + #[derive(Debug)] + #[repr(transparent)] + pub struct Tensor{ + handle: _rt::Resource, + } + + impl Tensor{ + #[doc(hidden)] + pub unsafe fn from_handle(handle: u32) -> Self { + Self { + handle: _rt::Resource::from_handle(handle), + } } - } -} -impl fmt::Debug for NnErrno { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("NnErrno") - .field("code", &self.0) - .field("name", &self.name()) - .field("message", &self.message()) - .finish() - } -} -impl fmt::Display for NnErrno { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} (error {})", self.name(), self.0) - } -} -#[cfg(feature = "std")] -extern crate std; -#[cfg(feature = "std")] -impl std::error::Error for NnErrno {} - -pub type TensorDimensions<'a> = &'a [u32]; -#[repr(transparent)] -#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -pub struct TensorType(u8); -pub const TENSOR_TYPE_F16: TensorType = TensorType(0); -pub const TENSOR_TYPE_F32: TensorType = TensorType(1); -pub const TENSOR_TYPE_F64: TensorType = TensorType(2); -pub const TENSOR_TYPE_U8: TensorType = TensorType(3); -pub const TENSOR_TYPE_I32: TensorType = TensorType(4); -pub const TENSOR_TYPE_I64: TensorType = TensorType(5); -impl TensorType { - pub const fn raw(&self) -> u8 { - self.0 - } + #[doc(hidden)] + pub fn take_handle(&self) -> u32 { + _rt::Resource::take_handle(&self.handle) + } - pub fn name(&self) -> &'static str { - match self.0 { - 0 => "F16", - 1 => "F32", - 2 => "F64", - 3 => "U8", - 4 => "I32", - 5 => "I64", - _ => unsafe { core::hint::unreachable_unchecked() }, + #[doc(hidden)] + pub fn handle(&self) -> u32 { + _rt::Resource::handle(&self.handle) } - } - pub fn message(&self) -> &'static str { - match self.0 { - 0 => "", - 1 => "", - 2 => "", - 3 => "", - 4 => "", - 5 => "", - _ => unsafe { core::hint::unreachable_unchecked() }, + } + + + unsafe impl _rt::WasmResource for Tensor{ + #[inline] + unsafe fn drop(_handle: u32) { + #[cfg(not(target_arch = "wasm32"))] + unreachable!(); + + #[cfg(target_arch = "wasm32")] + { + #[link(wasm_import_module = "wasi:nn/tensor")] + extern "C" { + #[link_name = "[resource-drop]tensor"] + fn drop(_: u32); + } + + drop(_handle); + } } - } -} -impl fmt::Debug for TensorType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TensorType") - .field("code", &self.0) - .field("name", &self.name()) - .field("message", &self.message()) - .finish() - } -} + } -pub type TensorData<'a> = &'a [u8]; -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct Tensor<'a> { - pub dimensions: TensorDimensions<'a>, - pub type_: TensorType, - pub data: TensorData<'a>, -} -pub type GraphBuilder<'a> = &'a [u8]; -pub type GraphBuilderArray<'a> = &'a [GraphBuilder<'a>]; -pub type Graph = u32; -#[repr(transparent)] -#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -pub struct GraphEncoding(u8); -pub const GRAPH_ENCODING_OPENVINO: GraphEncoding = GraphEncoding(0); -pub const GRAPH_ENCODING_ONNX: GraphEncoding = GraphEncoding(1); -pub const GRAPH_ENCODING_TENSORFLOW: GraphEncoding = GraphEncoding(2); -pub const GRAPH_ENCODING_PYTORCH: GraphEncoding = GraphEncoding(3); -pub const GRAPH_ENCODING_TENSORFLOWLITE: GraphEncoding = GraphEncoding(4); -pub const GRAPH_ENCODING_AUTODETECT: GraphEncoding = GraphEncoding(5); -impl GraphEncoding { - pub const fn raw(&self) -> u8 { - self.0 - } + impl Tensor { + #[allow(unused_unsafe, clippy::all)] + pub fn new(dimensions: &TensorDimensions,ty: TensorType,data: &TensorData,) -> Self{ + unsafe { + let vec0 = dimensions; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + let vec1 = data; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); - pub fn name(&self) -> &'static str { - match self.0 { - 0 => "OPENVINO", - 1 => "ONNX", - 2 => "TENSORFLOW", - 3 => "PYTORCH", - 4 => "TENSORFLOWLITE", - 5 => "AUTODETECT", - _ => unsafe { core::hint::unreachable_unchecked() }, + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/tensor")] + extern "C" { + #[link_name = "[constructor]tensor"] + fn wit_import(_: *mut u8, _: usize, _: i32, _: *mut u8, _: usize, ) -> i32; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8, _: usize, _: i32, _: *mut u8, _: usize, ) -> i32{ unreachable!() } + let ret = wit_import(ptr0.cast_mut(), len0, ty.clone() as i32, ptr1.cast_mut(), len1); + Tensor::from_handle(ret as u32) + } } - } - pub fn message(&self) -> &'static str { - match self.0 { - 0 => "", - 1 => "", - 2 => "", - 3 => "", - 4 => "", - 5 => "", - _ => unsafe { core::hint::unreachable_unchecked() }, + } + impl Tensor { + #[allow(unused_unsafe, clippy::all)] + /// Describe the size of the tensor (e.g., 2x2x2x2 -> [2, 2, 2, 2]). To represent a tensor + /// containing a single value, use `[1]` for the tensor dimensions. + pub fn dimensions(&self,) -> TensorDimensions{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/tensor")] + extern "C" { + #[link_name = "[method]tensor.dimensions"] + fn wit_import(_: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(4).cast::(); + let len3 = l2; + _rt::Vec::from_raw_parts(l1.cast(), len3, len3) + } } - } -} -impl fmt::Debug for GraphEncoding { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("GraphEncoding") - .field("code", &self.0) - .field("name", &self.name()) - .field("message", &self.message()) - .finish() - } -} + } + impl Tensor { + #[allow(unused_unsafe, clippy::all)] + /// Describe the type of element in the tensor (e.g., `f32`). + pub fn ty(&self,) -> TensorType{ + unsafe { -#[repr(transparent)] -#[derive(Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -pub struct ExecutionTarget(u8); -pub const EXECUTION_TARGET_CPU: ExecutionTarget = ExecutionTarget(0); -pub const EXECUTION_TARGET_GPU: ExecutionTarget = ExecutionTarget(1); -pub const EXECUTION_TARGET_TPU: ExecutionTarget = ExecutionTarget(2); -impl ExecutionTarget { - pub const fn raw(&self) -> u8 { - self.0 - } + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/tensor")] + extern "C" { + #[link_name = "[method]tensor.ty"] + fn wit_import(_: i32, ) -> i32; + } - pub fn name(&self) -> &'static str { - match self.0 { - 0 => "CPU", - 1 => "GPU", - 2 => "TPU", - _ => unsafe { core::hint::unreachable_unchecked() }, + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, ) -> i32{ unreachable!() } + let ret = wit_import((self).handle() as i32); + TensorType::_lift(ret as u8) + } } + } + impl Tensor { + #[allow(unused_unsafe, clippy::all)] + /// Return the tensor data. + pub fn data(&self,) -> TensorData{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/tensor")] + extern "C" { + #[link_name = "[method]tensor.data"] + fn wit_import(_: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(4).cast::(); + let len3 = l2; + _rt::Vec::from_raw_parts(l1.cast(), len3, len3) + } + } + } + } - pub fn message(&self) -> &'static str { - match self.0 { - 0 => "", - 1 => "", - 2 => "", - _ => unsafe { core::hint::unreachable_unchecked() }, + + #[allow(dead_code, clippy::all)] + pub mod errors { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum ErrorCode { + /// Caller module passed an invalid argument. + InvalidArgument, + /// Invalid encoding. + InvalidEncoding, + /// The operation timed out. + Timeout, + /// Runtime Error. + RuntimeError, + /// Unsupported operation. + UnsupportedOperation, + /// Graph is too large. + TooLarge, + /// Graph not found. + NotFound, + /// The operation is insecure or has insufficient privilege to be performed. + /// e.g., cannot access a hardware feature requested + Security, + /// The operation failed for an unspecified reason. + Unknown, + } + impl ::core::fmt::Debug for ErrorCode { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + ErrorCode::InvalidArgument => { + f.debug_tuple("ErrorCode::InvalidArgument").finish() + } + ErrorCode::InvalidEncoding => { + f.debug_tuple("ErrorCode::InvalidEncoding").finish() + } + ErrorCode::Timeout => { + f.debug_tuple("ErrorCode::Timeout").finish() + } + ErrorCode::RuntimeError => { + f.debug_tuple("ErrorCode::RuntimeError").finish() + } + ErrorCode::UnsupportedOperation => { + f.debug_tuple("ErrorCode::UnsupportedOperation").finish() + } + ErrorCode::TooLarge => { + f.debug_tuple("ErrorCode::TooLarge").finish() + } + ErrorCode::NotFound => { + f.debug_tuple("ErrorCode::NotFound").finish() + } + ErrorCode::Security => { + f.debug_tuple("ErrorCode::Security").finish() + } + ErrorCode::Unknown => { + f.debug_tuple("ErrorCode::Unknown").finish() + } + } + } + } + + impl ErrorCode{ + pub(crate) unsafe fn _lift(val: u8) -> ErrorCode{ + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } + + match val { + 0 => ErrorCode::InvalidArgument, + 1 => ErrorCode::InvalidEncoding, + 2 => ErrorCode::Timeout, + 3 => ErrorCode::RuntimeError, + 4 => ErrorCode::UnsupportedOperation, + 5 => ErrorCode::TooLarge, + 6 => ErrorCode::NotFound, + 7 => ErrorCode::Security, + 8 => ErrorCode::Unknown, + + _ => panic!("invalid enum discriminant"), + } + } + } + + + #[derive(Debug)] + #[repr(transparent)] + pub struct Error{ + handle: _rt::Resource, + } + + impl Error{ + #[doc(hidden)] + pub unsafe fn from_handle(handle: u32) -> Self { + Self { + handle: _rt::Resource::from_handle(handle), + } + } + + #[doc(hidden)] + pub fn take_handle(&self) -> u32 { + _rt::Resource::take_handle(&self.handle) + } + + #[doc(hidden)] + pub fn handle(&self) -> u32 { + _rt::Resource::handle(&self.handle) + } + } + + + unsafe impl _rt::WasmResource for Error{ + #[inline] + unsafe fn drop(_handle: u32) { + #[cfg(not(target_arch = "wasm32"))] + unreachable!(); + + #[cfg(target_arch = "wasm32")] + { + #[link(wasm_import_module = "wasi:nn/errors")] + extern "C" { + #[link_name = "[resource-drop]error"] + fn drop(_: u32); + } + + drop(_handle); + } + } + } + + impl Error { + #[allow(unused_unsafe, clippy::all)] + pub fn new(code: ErrorCode,data: &str,) -> Self{ + unsafe { + let vec0 = data; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/errors")] + extern "C" { + #[link_name = "[constructor]error"] + fn wit_import(_: i32, _: *mut u8, _: usize, ) -> i32; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, _: usize, ) -> i32{ unreachable!() } + let ret = wit_import(code.clone() as i32, ptr0.cast_mut(), len0); + Error::from_handle(ret as u32) + } } + } + impl Error { + #[allow(unused_unsafe, clippy::all)] + /// Return the error code. + pub fn code(&self,) -> ErrorCode{ + unsafe { + + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/errors")] + extern "C" { + #[link_name = "[method]error.code"] + fn wit_import(_: i32, ) -> i32; + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, ) -> i32{ unreachable!() } + let ret = wit_import((self).handle() as i32); + ErrorCode::_lift(ret as u8) + } + } + } + impl Error { + #[allow(unused_unsafe, clippy::all)] + /// Errors can propagated with backend specific status through a string value. + pub fn data(&self,) -> _rt::String{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/errors")] + extern "C" { + #[link_name = "[method]error.data"] + fn wit_import(_: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(4).cast::(); + let len3 = l2; + let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3); + _rt::string_lift(bytes3) + } + } + } + } -} -impl fmt::Debug for ExecutionTarget { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ExecutionTarget") - .field("code", &self.0) - .field("name", &self.name()) - .field("message", &self.message()) - .finish() + + #[allow(dead_code, clippy::all)] + pub mod inference { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Error = super::super::super::wasi::nn::errors::Error; + pub type Tensor = super::super::super::wasi::nn::tensor::Tensor; + /// Bind a `graph` to the input and output tensors for an inference. + /// + /// TODO: this may no longer be necessary in WIT + /// (https://github.com/WebAssembly/wasi-nn/issues/43) + + #[derive(Debug)] + #[repr(transparent)] + pub struct GraphExecutionContext{ + handle: _rt::Resource, + } + + impl GraphExecutionContext{ + #[doc(hidden)] + pub unsafe fn from_handle(handle: u32) -> Self { + Self { + handle: _rt::Resource::from_handle(handle), + } + } + + #[doc(hidden)] + pub fn take_handle(&self) -> u32 { + _rt::Resource::take_handle(&self.handle) + } + + #[doc(hidden)] + pub fn handle(&self) -> u32 { + _rt::Resource::handle(&self.handle) + } + } + + + unsafe impl _rt::WasmResource for GraphExecutionContext{ + #[inline] + unsafe fn drop(_handle: u32) { + #[cfg(not(target_arch = "wasm32"))] + unreachable!(); + + #[cfg(target_arch = "wasm32")] + { + #[link(wasm_import_module = "wasi:nn/inference")] + extern "C" { + #[link_name = "[resource-drop]graph-execution-context"] + fn drop(_: u32); + } + + drop(_handle); + } + } + } + + impl GraphExecutionContext { + #[allow(unused_unsafe, clippy::all)] + /// Define the inputs to use for inference. + pub fn set_input(&self,name: &str,tensor: Tensor,) -> Result<(),Error>{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let vec0 = name; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + let ptr1 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/inference")] + extern "C" { + #[link_name = "[method]graph-execution-context.set-input"] + fn wit_import(_: i32, _: *mut u8, _: usize, _: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, _: usize, _: i32, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0.cast_mut(), len0, (&tensor).take_handle() as i32, ptr1); + let l2 = i32::from(*ptr1.add(0).cast::()); + match l2 { + 0 => { + let e = (); + Ok(e) + } + 1 => { + let e = { + let l3 = *ptr1.add(4).cast::(); + + super::super::super::wasi::nn::errors::Error::from_handle(l3 as u32) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } + } + impl GraphExecutionContext { + #[allow(unused_unsafe, clippy::all)] + /// Compute the inference on the given inputs. + /// + /// Note the expected sequence of calls: `set-input`, `compute`, `get-output`. TODO: this + /// expectation could be removed as a part of + /// https://github.com/WebAssembly/wasi-nn/issues/43. + pub fn compute(&self,) -> Result<(),Error>{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/inference")] + extern "C" { + #[link_name = "[method]graph-execution-context.compute"] + fn wit_import(_: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0); + let l1 = i32::from(*ptr0.add(0).cast::()); + match l1 { + 0 => { + let e = (); + Ok(e) + } + 1 => { + let e = { + let l2 = *ptr0.add(4).cast::(); + + super::super::super::wasi::nn::errors::Error::from_handle(l2 as u32) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } + } + impl GraphExecutionContext { + #[allow(unused_unsafe, clippy::all)] + /// Extract the outputs after inference. + pub fn get_output(&self,name: &str,) -> Result{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let vec0 = name; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + let ptr1 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/inference")] + extern "C" { + #[link_name = "[method]graph-execution-context.get-output"] + fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); + let l2 = i32::from(*ptr1.add(0).cast::()); + match l2 { + 0 => { + let e = { + let l3 = *ptr1.add(4).cast::(); + + super::super::super::wasi::nn::tensor::Tensor::from_handle(l3 as u32) + }; + Ok(e) + } + 1 => { + let e = { + let l4 = *ptr1.add(4).cast::(); + + super::super::super::wasi::nn::errors::Error::from_handle(l4 as u32) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } + } + } -} -pub type GraphExecutionContext = u32; -pub unsafe fn load( - builder: GraphBuilderArray<'_>, - encoding: GraphEncoding, - target: ExecutionTarget, -) -> Result { - let mut rp0 = MaybeUninit::::uninit(); - let ret = wasi_ephemeral_nn::load( - builder.as_ptr() as i32, - builder.len() as i32, - encoding.0 as i32, - target.0 as i32, - rp0.as_mut_ptr() as i32, - ); - match ret { - 0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Graph)), - _ => Err(NnErrno(ret as u16)), + #[allow(dead_code, clippy::all)] + pub mod graph { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Error = super::super::super::wasi::nn::errors::Error; + pub type GraphExecutionContext = super::super::super::wasi::nn::inference::GraphExecutionContext; + /// An execution graph for performing inference (i.e., a model). + + #[derive(Debug)] + #[repr(transparent)] + pub struct Graph{ + handle: _rt::Resource, + } + + impl Graph{ + #[doc(hidden)] + pub unsafe fn from_handle(handle: u32) -> Self { + Self { + handle: _rt::Resource::from_handle(handle), + } + } + + #[doc(hidden)] + pub fn take_handle(&self) -> u32 { + _rt::Resource::take_handle(&self.handle) + } + + #[doc(hidden)] + pub fn handle(&self) -> u32 { + _rt::Resource::handle(&self.handle) + } + } + + + unsafe impl _rt::WasmResource for Graph{ + #[inline] + unsafe fn drop(_handle: u32) { + #[cfg(not(target_arch = "wasm32"))] + unreachable!(); + + #[cfg(target_arch = "wasm32")] + { + #[link(wasm_import_module = "wasi:nn/graph")] + extern "C" { + #[link_name = "[resource-drop]graph"] + fn drop(_: u32); + } + + drop(_handle); + } + } + } + + /// Describes the encoding of the graph. This allows the API to be implemented by various + /// backends that encode (i.e., serialize) their graph IR with different formats. + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum GraphEncoding { + Openvino, + Onnx, + Tensorflow, + Pytorch, + Tensorflowlite, + Ggml, + Autodetect, + } + impl ::core::fmt::Debug for GraphEncoding { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + GraphEncoding::Openvino => { + f.debug_tuple("GraphEncoding::Openvino").finish() + } + GraphEncoding::Onnx => { + f.debug_tuple("GraphEncoding::Onnx").finish() + } + GraphEncoding::Tensorflow => { + f.debug_tuple("GraphEncoding::Tensorflow").finish() + } + GraphEncoding::Pytorch => { + f.debug_tuple("GraphEncoding::Pytorch").finish() + } + GraphEncoding::Tensorflowlite => { + f.debug_tuple("GraphEncoding::Tensorflowlite").finish() + } + GraphEncoding::Ggml => { + f.debug_tuple("GraphEncoding::Ggml").finish() + } + GraphEncoding::Autodetect => { + f.debug_tuple("GraphEncoding::Autodetect").finish() + } + } + } + } + + impl GraphEncoding{ + pub(crate) unsafe fn _lift(val: u8) -> GraphEncoding{ + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } + + match val { + 0 => GraphEncoding::Openvino, + 1 => GraphEncoding::Onnx, + 2 => GraphEncoding::Tensorflow, + 3 => GraphEncoding::Pytorch, + 4 => GraphEncoding::Tensorflowlite, + 5 => GraphEncoding::Ggml, + 6 => GraphEncoding::Autodetect, + + _ => panic!("invalid enum discriminant"), + } + } + } + + /// Define where the graph should be executed. + #[repr(u8)] + #[derive(Clone, Copy, Eq, PartialEq)] + pub enum ExecutionTarget { + Cpu, + Gpu, + Tpu, + } + impl ::core::fmt::Debug for ExecutionTarget { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + ExecutionTarget::Cpu => { + f.debug_tuple("ExecutionTarget::Cpu").finish() + } + ExecutionTarget::Gpu => { + f.debug_tuple("ExecutionTarget::Gpu").finish() + } + ExecutionTarget::Tpu => { + f.debug_tuple("ExecutionTarget::Tpu").finish() + } + } + } + } + + impl ExecutionTarget{ + pub(crate) unsafe fn _lift(val: u8) -> ExecutionTarget{ + if !cfg!(debug_assertions) { + return ::core::mem::transmute(val); + } + + match val { + 0 => ExecutionTarget::Cpu, + 1 => ExecutionTarget::Gpu, + 2 => ExecutionTarget::Tpu, + + _ => panic!("invalid enum discriminant"), + } + } + } + + /// The graph initialization data. + /// + /// This gets bundled up into an array of buffers because implementing backends may encode their + /// graph IR in parts (e.g., OpenVINO stores its IR and weights separately). + pub type GraphBuilder = _rt::Vec::; + impl Graph { + #[allow(unused_unsafe, clippy::all)] + pub fn init_execution_context(&self,) -> Result{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/graph")] + extern "C" { + #[link_name = "[method]graph.init-execution-context"] + fn wit_import(_: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: i32, _: *mut u8, ){ unreachable!() } + wit_import((self).handle() as i32, ptr0); + let l1 = i32::from(*ptr0.add(0).cast::()); + match l1 { + 0 => { + let e = { + let l2 = *ptr0.add(4).cast::(); + + super::super::super::wasi::nn::inference::GraphExecutionContext::from_handle(l2 as u32) + }; + Ok(e) + } + 1 => { + let e = { + let l3 = *ptr0.add(4).cast::(); + + super::super::super::wasi::nn::errors::Error::from_handle(l3 as u32) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Load a `graph` from an opaque sequence of bytes to use for inference. + pub fn load(builder: &[GraphBuilder],encoding: GraphEncoding,target: ExecutionTarget,) -> Result{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let vec1 = builder; + let len1 = vec1.len(); + let layout1 = _rt::alloc::Layout::from_size_align_unchecked(vec1.len() * 8, 4); + let result1 = if layout1.size() != 0 { + let ptr = _rt::alloc::alloc(layout1).cast::(); + if ptr.is_null() + { + _rt::alloc::handle_alloc_error(layout1); + } + ptr + }else {{ + ::core::ptr::null_mut() + }}; + for (i, e) in vec1.into_iter().enumerate() { + let base = result1.add(i * 8); + { + let vec0 = e; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + *base.add(4).cast::() = len0; + *base.add(0).cast::<*mut u8>() = ptr0.cast_mut(); + } + } + let ptr2 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/graph")] + extern "C" { + #[link_name = "load"] + fn wit_import(_: *mut u8, _: usize, _: i32, _: i32, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8, _: usize, _: i32, _: i32, _: *mut u8, ){ unreachable!() } + wit_import(result1, len1, encoding.clone() as i32, target.clone() as i32, ptr2); + let l3 = i32::from(*ptr2.add(0).cast::()); + if layout1.size() != 0 { + _rt::alloc::dealloc(result1.cast(), layout1); + } + match l3 { + 0 => { + let e = { + let l4 = *ptr2.add(4).cast::(); + + Graph::from_handle(l4 as u32) + }; + Ok(e) + } + 1 => { + let e = { + let l5 = *ptr2.add(4).cast::(); + + super::super::super::wasi::nn::errors::Error::from_handle(l5 as u32) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } + #[allow(unused_unsafe, clippy::all)] + /// Load a `graph` by name. + /// + /// How the host expects the names to be passed and how it stores the graphs for retrieval via + /// this function is **implementation-specific**. This allows hosts to choose name schemes that + /// range from simple to complex (e.g., URLs?) and caching mechanisms of various kinds. + pub fn load_by_name(name: &str,) -> Result{ + unsafe { + #[repr(align(4))] + struct RetArea([::core::mem::MaybeUninit::; 8]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); + let vec0 = name; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + let ptr1 = ret_area.0.as_mut_ptr().cast::(); + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "wasi:nn/graph")] + extern "C" { + #[link_name = "load-by-name"] + fn wit_import(_: *mut u8, _: usize, _: *mut u8, ); + } + + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: *mut u8, _: usize, _: *mut u8, ){ unreachable!() } + wit_import(ptr0.cast_mut(), len0, ptr1); + let l2 = i32::from(*ptr1.add(0).cast::()); + match l2 { + 0 => { + let e = { + let l3 = *ptr1.add(4).cast::(); + + Graph::from_handle(l3 as u32) + }; + Ok(e) + } + 1 => { + let e = { + let l4 = *ptr1.add(4).cast::(); + + super::super::super::wasi::nn::errors::Error::from_handle(l4 as u32) + }; + Err(e) + } + _ => _rt::invalid_enum_discriminant(), + } + } + } + } + + } } +mod _rt { + pub use alloc_crate::vec::Vec; + + + use core::fmt; + use core::marker; + use core::sync::atomic::{AtomicU32, Ordering::Relaxed}; -pub unsafe fn load_by_name(name: &str) -> Result { - let mut rp0 = MaybeUninit::::uninit(); - let ret = wasi_ephemeral_nn::load_by_name( - name.as_ptr() as i32, - name.len() as i32, - rp0.as_mut_ptr() as i32, - ); - match ret { - 0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const Graph)), - _ => Err(NnErrno(ret as u16)), + /// A type which represents a component model resource, either imported or + /// exported into this component. + /// + /// This is a low-level wrapper which handles the lifetime of the resource + /// (namely this has a destructor). The `T` provided defines the component model + /// intrinsics that this wrapper uses. + /// + /// One of the chief purposes of this type is to provide `Deref` implementations + /// to access the underlying data when it is owned. + /// + /// This type is primarily used in generated code for exported and imported + /// resources. + #[repr(transparent)] + pub struct Resource { + // NB: This would ideally be `u32` but it is not. The fact that this has + // interior mutability is not exposed in the API of this type except for the + // `take_handle` method which is supposed to in theory be private. + // + // This represents, almost all the time, a valid handle value. When it's + // invalid it's stored as `u32::MAX`. + handle: AtomicU32, + _marker: marker::PhantomData, + } + + /// A trait which all wasm resources implement, namely providing the ability to + /// drop a resource. + /// + /// This generally is implemented by generated code, not user-facing code. + pub unsafe trait WasmResource { + /// Invokes the `[resource-drop]...` intrinsic. + unsafe fn drop(handle: u32); + } + + impl Resource { + #[doc(hidden)] + pub unsafe fn from_handle(handle: u32) -> Self { + debug_assert!(handle != u32::MAX); + Self { + handle: AtomicU32::new(handle), + _marker: marker::PhantomData, + } } -} -pub unsafe fn init_execution_context(graph: Graph) -> Result { - let mut rp0 = MaybeUninit::::uninit(); - let ret = wasi_ephemeral_nn::init_execution_context(graph as i32, rp0.as_mut_ptr() as i32); - match ret { - 0 => Ok(core::ptr::read( - rp0.as_mut_ptr() as i32 as *const GraphExecutionContext - )), - _ => Err(NnErrno(ret as u16)), + /// Takes ownership of the handle owned by `resource`. + /// + /// Note that this ideally would be `into_handle` taking `Resource` by + /// ownership. The code generator does not enable that in all situations, + /// unfortunately, so this is provided instead. + /// + /// Also note that `take_handle` is in theory only ever called on values + /// owned by a generated function. For example a generated function might + /// take `Resource` as an argument but then call `take_handle` on a + /// reference to that argument. In that sense the dynamic nature of + /// `take_handle` should only be exposed internally to generated code, not + /// to user code. + #[doc(hidden)] + pub fn take_handle(resource: &Resource) -> u32 { + resource.handle.swap(u32::MAX, Relaxed) } -} -pub unsafe fn set_input( - context: GraphExecutionContext, - index: u32, - tensor: Tensor, -) -> Result<(), NnErrno> { - let ret = - wasi_ephemeral_nn::set_input(context as i32, index as i32, &tensor as *const _ as i32); - match ret { - 0 => Ok(()), - _ => Err(NnErrno(ret as u16)), + #[doc(hidden)] + pub fn handle(resource: &Resource) -> u32 { + resource.handle.load(Relaxed) } -} + } -pub unsafe fn get_output( - context: GraphExecutionContext, - index: u32, - out_buffer: *mut u8, - out_buffer_max_size: BufferSize, -) -> Result { - let mut rp0 = MaybeUninit::::uninit(); - let ret = wasi_ephemeral_nn::get_output( - context as i32, - index as i32, - out_buffer as i32, - out_buffer_max_size as i32, - rp0.as_mut_ptr() as i32, - ); - match ret { - 0 => Ok(core::ptr::read(rp0.as_mut_ptr() as i32 as *const BufferSize)), - _ => Err(NnErrno(ret as u16)), + impl fmt::Debug for Resource { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Resource") + .field("handle", &self.handle) + .finish() } -} + } + + impl Drop for Resource { + fn drop(&mut self) { + unsafe { + match self.handle.load(Relaxed) { + // If this handle was "taken" then don't do anything in the + // destructor. + u32::MAX => {} -pub unsafe fn compute(context: GraphExecutionContext) -> Result<(), NnErrno> { - let ret = wasi_ephemeral_nn::compute(context as i32); - match ret { - 0 => Ok(()), - _ => Err(NnErrno(ret as u16)), + // ... but otherwise do actually destroy it with the imported + // component model intrinsic as defined through `T`. + other => T::drop(other), + } + } + } + } + pub use alloc_crate::string::String; + pub unsafe fn string_lift(bytes: Vec) -> String { + if cfg!(debug_assertions) { + String::from_utf8(bytes).unwrap() + } else { + String::from_utf8_unchecked(bytes) } + } + pub unsafe fn invalid_enum_discriminant() -> T { + if cfg!(debug_assertions) { + panic!("invalid enum discriminant") + } else { + core::hint::unreachable_unchecked() + } + } + pub use alloc_crate::alloc; + extern crate alloc as alloc_crate; } -pub mod wasi_ephemeral_nn { - #[link(wasm_import_module = "wasi_ephemeral_nn")] - extern "C" { - pub fn load(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32; - pub fn load_by_name(arg0: i32, arg1: i32, arg2: i32) -> i32; - pub fn init_execution_context(arg0: i32, arg1: i32) -> i32; - pub fn set_input(arg0: i32, arg1: i32, arg2: i32) -> i32; - pub fn get_output(arg0: i32, arg1: i32, arg2: i32, arg3: i32, arg4: i32) -> i32; - pub fn compute(arg0: i32) -> i32; - } +#[cfg(target_arch = "wasm32")] +#[link_section = "component-type:wit-bindgen:0.24.0:ml:encoded world"] +#[doc(hidden)] +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1493] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xdc\x0a\x01A\x02\x01\ +A\x0c\x01B\x11\x01py\x04\0\x11tensor-dimensions\x03\0\0\x01m\x07\x04FP16\x04FP32\ +\x04FP64\x04BF16\x02U8\x03I32\x03I64\x04\0\x0btensor-type\x03\0\x02\x01p}\x04\0\x0b\ +tensor-data\x03\0\x04\x04\0\x06tensor\x03\x01\x01i\x06\x01@\x03\x0adimensions\x01\ +\x02ty\x03\x04data\x05\0\x07\x04\0\x13[constructor]tensor\x01\x08\x01h\x06\x01@\x01\ +\x04self\x09\0\x01\x04\0\x19[method]tensor.dimensions\x01\x0a\x01@\x01\x04self\x09\ +\0\x03\x04\0\x11[method]tensor.ty\x01\x0b\x01@\x01\x04self\x09\0\x05\x04\0\x13[m\ +ethod]tensor.data\x01\x0c\x03\x01\x0ewasi:nn/tensor\x05\0\x01B\x0b\x01m\x09\x10i\ +nvalid-argument\x10invalid-encoding\x07timeout\x0druntime-error\x15unsupported-o\ +peration\x09too-large\x09not-found\x08security\x07unknown\x04\0\x0aerror-code\x03\ +\0\0\x04\0\x05error\x03\x01\x01i\x02\x01@\x02\x04code\x01\x04datas\0\x03\x04\0\x12\ +[constructor]error\x01\x04\x01h\x02\x01@\x01\x04self\x05\0\x01\x04\0\x12[method]\ +error.code\x01\x06\x01@\x01\x04self\x05\0s\x04\0\x12[method]error.data\x01\x07\x03\ +\x01\x0ewasi:nn/errors\x05\x01\x02\x03\0\x01\x05error\x02\x03\0\0\x06tensor\x02\x03\ +\0\0\x0btensor-data\x01B\x12\x02\x03\x02\x01\x02\x04\0\x05error\x03\0\0\x02\x03\x02\ +\x01\x03\x04\0\x06tensor\x03\0\x02\x02\x03\x02\x01\x04\x04\0\x0btensor-data\x03\0\ +\x04\x04\0\x17graph-execution-context\x03\x01\x01h\x06\x01i\x03\x01i\x01\x01j\0\x01\ +\x09\x01@\x03\x04self\x07\x04names\x06tensor\x08\0\x0a\x04\0)[method]graph-execu\ +tion-context.set-input\x01\x0b\x01@\x01\x04self\x07\0\x0a\x04\0'[method]graph-ex\ +ecution-context.compute\x01\x0c\x01j\x01\x08\x01\x09\x01@\x02\x04self\x07\x04nam\ +es\0\x0d\x04\0*[method]graph-execution-context.get-output\x01\x0e\x03\x01\x11was\ +i:nn/inference\x05\x05\x02\x03\0\x02\x17graph-execution-context\x01B\x1a\x02\x03\ +\x02\x01\x02\x04\0\x05error\x03\0\0\x02\x03\x02\x01\x03\x04\0\x06tensor\x03\0\x02\ +\x02\x03\x02\x01\x06\x04\0\x17graph-execution-context\x03\0\x04\x04\0\x05graph\x03\ +\x01\x01m\x07\x08openvino\x04onnx\x0atensorflow\x07pytorch\x0etensorflowlite\x04\ +ggml\x0aautodetect\x04\0\x0egraph-encoding\x03\0\x07\x01m\x03\x03cpu\x03gpu\x03t\ +pu\x04\0\x10execution-target\x03\0\x09\x01p}\x04\0\x0dgraph-builder\x03\0\x0b\x01\ +h\x06\x01i\x05\x01i\x01\x01j\x01\x0e\x01\x0f\x01@\x01\x04self\x0d\0\x10\x04\0$[m\ +ethod]graph.init-execution-context\x01\x11\x01p\x0c\x01i\x06\x01j\x01\x13\x01\x0f\ +\x01@\x03\x07builder\x12\x08encoding\x08\x06target\x0a\0\x14\x04\0\x04load\x01\x15\ +\x01@\x01\x04names\0\x14\x04\0\x0cload-by-name\x01\x16\x03\x01\x0dwasi:nn/graph\x05\ +\x07\x04\x01\x0awasi:nn/ml\x04\0\x0b\x08\x01\0\x02ml\x03\0\0\0G\x09producers\x01\ +\x0cprocessed-by\x02\x0dwit-component\x070.202.0\x10wit-bindgen-rust\x060.24.0"; + +#[inline(never)] +#[doc(hidden)] +#[cfg(target_arch = "wasm32")] +pub fn __link_custom_section_describing_imports() { + wit_bindgen::rt::maybe_link_cabi_realloc(); } + diff --git a/rust/src/graph.rs b/rust/src/graph.rs deleted file mode 100644 index b28c7fb..0000000 --- a/rust/src/graph.rs +++ /dev/null @@ -1,537 +0,0 @@ -//! The core graph definitions. - -use crate::{tensor::Tensor, Error, TensorType}; -use std::fmt::{Debug, Display, Formatter}; - -/// Describes the encoding of the graph. This allows the API to be implemented by various backends -/// that encode (i.e., serialize) their graph IR with different formats. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] -#[repr(C)] -pub enum GraphEncoding { - Openvino = 0, - Onnx, - Tensorflow, - Pytorch, - TensorflowLite, - Autodetec, -} - -/// Define where the graph should be executed. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] -#[repr(C)] -pub enum ExecutionTarget { - CPU = 0, - GPU, - TPU, - AUTO, -} - -/// A graph factory for configuring the properties of a new graph. -/// -/// Methods can be chained on it in order to configure it. -/// * Default Graph Encoding: `Openvino`. -/// * Default Execution Target: `CPU`. -/// -/// ### Examples -/// -/// #### Build a graph with default config ( `CPU` + `Openvino` ) -/// -/// ```no_run -/// # use wasi_nn::{GraphBuilder, GraphEncoding}; -/// let xml = "./mobilenet.xml"; -/// let weight = "./mobilenet.bin"; -/// let graph = GraphBuilder::default().build_from_files([xml, weight]).unwrap(); -/// ``` -/// -/// #### Build a graph with onnx backend and gpu device target -/// -/// ```no_run -/// # use wasi_nn::{GraphBuilder, GraphEncoding, ExecutionTarget}; -/// let graph = GraphBuilder::new(GraphEncoding::Onnx, ExecutionTarget::GPU) -/// .build_from_files(["./test.onnx"]).unwrap(); -/// ``` -/// -#[derive(Debug, Clone)] -pub struct GraphBuilder { - encoding: GraphEncoding, - target: ExecutionTarget, -} - -impl Default for GraphBuilder { - #[inline(always)] - fn default() -> Self { - Self::new(GraphEncoding::Openvino, ExecutionTarget::CPU) - } -} - -impl GraphBuilder { - /// Create a new [```GraphBuilder```]. - #[inline(always)] - #[must_use] - pub fn new(encoding: GraphEncoding, target: ExecutionTarget) -> Self { - Self { encoding, target } - } - - /// Set graph encoding. - #[inline(always)] - #[must_use] - pub fn encoding(mut self, encoding: GraphEncoding) -> Self { - self.encoding = encoding; - self - } - - /// Set graph execution target. - #[inline(always)] - #[must_use] - pub fn execution_target(mut self, execution_target: ExecutionTarget) -> Self { - self.target = execution_target; - self - } - - /// Set graph execution target to `CPU`. - #[inline(always)] - #[must_use] - pub fn cpu(mut self) -> Self { - self.target = ExecutionTarget::CPU; - self - } - - /// Set graph execution target to `GPU`. - #[inline(always)] - #[must_use] - pub fn gpu(mut self) -> Self { - self.target = ExecutionTarget::GPU; - self - } - - /// Set graph execution target to `TPU`. - #[inline(always)] - #[must_use] - pub fn tpu(mut self) -> Self { - self.target = ExecutionTarget::TPU; - self - } - - #[inline(always)] - pub fn build_from_bytes(self, bytes_array: impl AsRef<[B]>) -> Result - where - B: AsRef<[u8]>, - { - let graph_builder_array: Vec<&[u8]> = - bytes_array.as_ref().iter().map(AsRef::as_ref).collect(); - let graph_handle = - syscall::load(graph_builder_array.as_slice(), self.encoding, self.target)?; - Ok(Graph { - build_info: self, - graph_handle, - }) - } - - #[inline(always)] - pub fn build_from_files

(self, files: impl AsRef<[P]>) -> Result - where - P: AsRef, - { - let mut graph_contents = Vec::with_capacity(files.as_ref().len()); - for file in files.as_ref() { - graph_contents.push(std::fs::read(file).map_err(Into::::into)?); - } - let graph_builder_array: Vec<&[u8]> = graph_contents.iter().map(AsRef::as_ref).collect(); - let graph_handle = - syscall::load(graph_builder_array.as_slice(), self.encoding, self.target)?; - Ok(Graph { - build_info: self, - graph_handle, - }) - } - - #[inline(always)] - pub fn build_from_cache(self, name: &str) -> Result -where { - let graph_handle = syscall::load_by_name(name)?; - Ok(Graph { - build_info: self, - graph_handle, - }) - } -} - -/// An execution graph for performing inference (i.e., a model), which can create instances of -/// [`GraphExecutionContext`]. -/// -/// ### Example -/// -/// ```no_run -/// # use wasi_nn::{GraphBuilder, GraphEncoding, ExecutionTarget}; -/// // Create a graph using `GraphBuilder`. -/// let model_file = "./test.tflite"; -/// let graph = GraphBuilder::new(GraphEncoding::TensorflowLite, ExecutionTarget::CPU) -/// .build_from_files([model_file]) -/// .unwrap(); -/// -/// // Create an execution context using this graph. -/// let mut graph_exec_ctx = graph.init_execution_context().unwrap(); -/// -/// // Set input tensors. -/// // ... -/// -/// // Compute the inference on the given inputs. -/// graph_exec_ctx.compute().unwrap(); -/// -/// // Get output tensors and do post-processing. -/// // ... -/// ``` -pub struct Graph { - build_info: GraphBuilder, - graph_handle: syscall::GraphHandle, -} - -impl Graph { - /// Get the graph encoding. - #[inline(always)] - pub fn encoding(&self) -> GraphEncoding { - self.build_info.encoding - } - - /// Get the graph execution target. - #[inline(always)] - pub fn execution_target(&self) -> ExecutionTarget { - self.build_info.target - } - - /// Use this graph to create a new instances of [`GraphExecutionContext`]. - #[inline(always)] - pub fn init_execution_context(&self) -> Result { - let ctx_handle = syscall::init_execution_context(self.graph_handle)?; - Ok(GraphExecutionContext { - graph: self, - ctx_handle, - }) - } -} - -impl Display for Graph { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "Graph#{}", self.graph_handle) - } -} - -impl Debug for Graph { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.graph_handle) - } -} - -/// Bind a [`Graph`] to the input and output for an inference. -pub struct GraphExecutionContext<'a> { - graph: &'a Graph, - ctx_handle: syscall::GraphExecutionContextHandle, -} - -impl<'a> GraphExecutionContext<'a> { - /// Get the [`Graph`] instance for this [`GraphExecutionContext`] instance. - #[inline(always)] - pub fn graph(&self) -> &Graph { - self.graph - } - - /// Set input uses the `data`, not only [u8], but also [f32], [i32], etc. - pub fn set_input( - &mut self, - index: usize, - tensor_type: TensorType, - dimensions: &[usize], - data: impl AsRef<[T]>, - ) -> Result<(), Error> { - let data_slice = data.as_ref(); - let buf = unsafe { - core::slice::from_raw_parts( - data_slice.as_ptr().cast::(), - std::mem::size_of_val(data_slice), - ) - }; - let tensor_for_call = Tensor::new(dimensions, tensor_type, buf); - syscall::set_input(self.ctx_handle, index, tensor_for_call) - } - - /// Compute the inference on the given inputs. - #[inline(always)] - pub fn compute(&mut self) -> Result<(), Error> { - syscall::compute(self.ctx_handle) - } - - /// Copy output tensor to `out_buffer`, return the output's **size in bytes**. - #[inline(always)] - pub fn get_output(&self, index: usize, out_buffer: &mut [T]) -> Result { - let out_buf = unsafe { - core::slice::from_raw_parts_mut( - out_buffer.as_mut_ptr().cast::(), - std::mem::size_of_val(out_buffer), - ) - }; - syscall::get_output(self.ctx_handle, index, out_buf) - } -} - -impl<'a> Display for GraphExecutionContext<'a> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "GraphExecutionContext#{}", self.ctx_handle) - } -} - -impl<'a> Debug for GraphExecutionContext<'a> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.ctx_handle) - } -} - -#[cfg(all(target_arch = "wasm32", target_os = "wasi"))] -mod syscall { - use crate::generated::wasi_ephemeral_nn; - use crate::{error::BackendError, tensor::Tensor, Error, ExecutionTarget, GraphEncoding}; - use std::ffi::CString; - - pub(crate) type GraphHandle = i32; - pub(crate) type GraphExecutionContextHandle = i32; - - #[inline(always)] - pub(crate) fn load( - graph_builder_array: &[&[u8]], - encoding: GraphEncoding, - target: ExecutionTarget, - ) -> Result { - let mut graph_handle = 0; - let res = unsafe { - wasi_ephemeral_nn::load( - graph_builder_array.as_ptr() as i32, - graph_builder_array.len() as i32, - encoding as i32, - target as i32, - &mut graph_handle as *mut _ as i32, - ) - }; - - if res == 0 { - Ok(graph_handle) - } else { - Err(Error::BackendError(BackendError::from(res))) - } - } - - #[inline(always)] - pub(crate) fn load_by_name(name: &str) -> Result { - let mut graph_handle = 0; - let name_cstring = CString::new(name.clone()).unwrap_or_default(); - let name_ptr = name_cstring.as_ptr(); - let res = unsafe { - wasi_ephemeral_nn::load_by_name( - name_ptr as i32, - name.len() as i32, - &mut graph_handle as *mut _ as i32, - ) - }; - - if res == 0 { - Ok(graph_handle) - } else { - Err(Error::BackendError(BackendError::from(res))) - } - } - - #[inline(always)] - pub(crate) fn init_execution_context( - graph_handle: GraphHandle, - ) -> Result { - let mut ctx_handle = 0; - let res = unsafe { - wasi_ephemeral_nn::init_execution_context( - graph_handle, - &mut ctx_handle as *mut _ as i32, - ) - }; - - if res == 0 { - Ok(ctx_handle) - } else { - Err(Error::BackendError(BackendError::from(res))) - } - } - - #[inline(always)] - pub(crate) fn set_input( - ctx_handle: GraphExecutionContextHandle, - index: usize, - tensor: Tensor, - ) -> Result<(), Error> { - let res = unsafe { - wasi_ephemeral_nn::set_input(ctx_handle, index as i32, &tensor as *const _ as i32) - }; - if res == 0 { - Ok(()) - } else { - Err(Error::BackendError(BackendError::from(res))) - } - } - - #[inline(always)] - pub(crate) fn compute(ctx_handle: GraphExecutionContextHandle) -> Result<(), Error> { - let res = unsafe { wasi_ephemeral_nn::compute(ctx_handle) }; - if res == 0 { - Ok(()) - } else { - Err(Error::BackendError(BackendError::from(res))) - } - } - - #[inline(always)] - pub(crate) fn get_output( - ctx_handle: GraphExecutionContextHandle, - index: usize, - out_buf: &mut [u8], - ) -> Result { - let mut out_size = 0; - let res = unsafe { - wasi_ephemeral_nn::get_output( - ctx_handle, - index as i32, - out_buf.as_mut_ptr() as i32, - out_buf.len() as i32, - &mut out_size as *mut _ as i32, - ) - }; - - if res == 0 { - Ok(out_size) - } else { - Err(Error::BackendError(BackendError::from(res))) - } - } -} - -// These stubbed out functions are only necessary for running `cargo test`. -#[cfg(not(all(target_arch = "wasm32", target_os = "wasi")))] -mod syscall { - use crate::{tensor::Tensor, Error, ExecutionTarget, GraphEncoding}; - - pub(crate) type GraphHandle = i32; - pub(crate) type GraphExecutionContextHandle = i32; - - pub(crate) fn load( - _: &[&[u8]], - _: GraphEncoding, - _: ExecutionTarget, - ) -> Result { - unimplemented!("this crate is only intended to be used with `--target=wasm32-wasi`"); - } - - pub(crate) fn load_by_name(_: &str) -> Result { - unimplemented!("this crate is only intended to be used with `--target=wasm32-wasi`"); - } - - pub(crate) fn init_execution_context( - _: GraphHandle, - ) -> Result { - unimplemented!("this crate is only intended to be used with `--target=wasm32-wasi`"); - } - - pub(crate) fn set_input( - _: GraphExecutionContextHandle, - _: usize, - _: Tensor, - ) -> Result<(), Error> { - unimplemented!("this crate is only intended to be used with `--target=wasm32-wasi`"); - } - - pub(crate) fn compute(_: GraphExecutionContextHandle) -> Result<(), Error> { - unimplemented!("this crate is only intended to be used with `--target=wasm32-wasi`"); - } - - pub(crate) fn get_output( - _: GraphExecutionContextHandle, - _: usize, - _: &mut [u8], - ) -> Result { - unimplemented!("this crate is only intended to be used with `--target=wasm32-wasi`"); - } -} - -#[cfg(test)] -mod test { - use super::{ExecutionTarget, GraphBuilder, GraphEncoding}; - use crate::generated; - - #[test] - fn test_enum_graph_encoding() { - assert_eq!(GraphEncoding::Openvino as i32, 0); - assert_eq!(GraphEncoding::Onnx as i32, 1); - assert_eq!(GraphEncoding::Tensorflow as i32, 2); - assert_eq!(GraphEncoding::Pytorch as i32, 3); - assert_eq!(GraphEncoding::TensorflowLite as i32, 4); - } - - #[test] - fn test_graph_encoding_with_generated() { - assert_eq!( - GraphEncoding::Onnx as i32, - generated::GRAPH_ENCODING_ONNX.raw() as i32 - ); - assert_eq!( - GraphEncoding::Openvino as i32, - generated::GRAPH_ENCODING_OPENVINO.raw() as i32 - ); - assert_eq!( - GraphEncoding::Pytorch as i32, - generated::GRAPH_ENCODING_PYTORCH.raw() as i32 - ); - assert_eq!( - GraphEncoding::Tensorflow as i32, - generated::GRAPH_ENCODING_TENSORFLOW.raw() as i32 - ); - assert_eq!( - GraphEncoding::TensorflowLite as i32, - generated::GRAPH_ENCODING_TENSORFLOWLITE.raw() as i32 - ); - } - - #[test] - fn test_enum_graph_execution_target() { - assert_eq!(ExecutionTarget::CPU as i32, 0); - assert_eq!(ExecutionTarget::GPU as i32, 1); - assert_eq!(ExecutionTarget::TPU as i32, 2); - } - - #[test] - fn test_graph_execution_target_with_generated() { - assert_eq!( - ExecutionTarget::CPU as i32, - generated::EXECUTION_TARGET_CPU.raw() as i32 - ); - assert_eq!( - ExecutionTarget::GPU as i32, - generated::EXECUTION_TARGET_GPU.raw() as i32 - ); - assert_eq!( - ExecutionTarget::TPU as i32, - generated::EXECUTION_TARGET_TPU.raw() as i32 - ); - } - - #[test] - fn test_graph_builder() { - assert_eq!(GraphBuilder::default().encoding, GraphEncoding::Openvino); - assert_eq!(GraphBuilder::default().target, ExecutionTarget::CPU); - - assert_eq!(GraphBuilder::default().gpu().target, ExecutionTarget::GPU); - assert_eq!(GraphBuilder::default().tpu().target, ExecutionTarget::TPU); - assert_eq!( - GraphBuilder::default().tpu().cpu().target, - ExecutionTarget::CPU - ); - assert_eq!( - GraphBuilder::default() - .execution_target(ExecutionTarget::GPU) - .target, - ExecutionTarget::GPU - ); - } -} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 96b8ceb..6447425 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -17,19 +17,28 @@ //! // as u8, f32, etc. //! let input = vec![0f32; 224 * 224 * 3]; //! let input_dim = vec![1, 224, 224, 3]; -//! let mut output_buffer = vec![0f32; 1001]; //! //! // Build a tflite graph from a file and set an input tensor. -//! let graph = GraphBuilder::new(GraphEncoding::TensorflowLite, ExecutionTarget::CPU).build_from_files([model_path])?; -//! let mut ctx = graph.init_execution_context()?; +//! let graph = wasi_nn::graph::load( +//! &builders, +//! wasi_nn::graph::GraphEncoding::TensorflowLite, +//! wasi_nn::graph::ExecutionTarget::Cpu, +//! )?; +//! let ctx = wasi_nn::inference::init_execution_context(graph)?; //! ctx.set_input(0, TensorType::F32, &input_dim, &input)?; +//! let tensor = wasi_nn::tensor::Tensor { +//! dimensions: input_dim, +//! tensor_type: wasi_nn::tensor::TensorType::Fp32, +//! data: input, +//! }; +//! +//! wasi_nn::inference::set_input(context, 0, &tensor)?; //! //! // Do the inference. -//! ctx.compute()?; +//! wasi_nn::inference::compute(context)?; //! //! // Copy output to abuffer. -//! let output_bytes = ctx.get_output(0, &mut output_buffer)?; -//! assert_eq!(output_bytes, output_buffer.len() * std::mem::size_of::()); +//! let output_bytes = wasi_nn::inference::get_output(context, 0)?; //! Ok(()) //! } //! ``` @@ -39,16 +48,10 @@ //! This crate is experimental and will change to adapt the upstream [wasi-nn //! proposal](https://github.com/WebAssembly/wasi-nn/). //! -//! Now version is based on git commit ```f47f35c00c946cb0e3229f11f288bda9d3d12cff``` +//! Now version is based on git commit ```e2310b860db2ff1719c9d69816099b87e85fabdb``` //! #[allow(unused)] mod generated; -mod error; -mod graph; -mod tensor; - -pub use error::Error; -pub use graph::{ExecutionTarget, Graph, GraphBuilder, GraphEncoding, GraphExecutionContext}; -pub use tensor::TensorType; +pub use crate::generated::wasi::nn::*; diff --git a/rust/src/tensor.rs b/rust/src/tensor.rs deleted file mode 100644 index bb2b558..0000000 --- a/rust/src/tensor.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! Tensor-related definitions. - -/// The type of the elements in a tensor. -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] -#[repr(C)] -pub enum TensorType { - F16 = 0, - F32, - F64, - U8, - I32, - I64, -} - -impl TensorType { - #[inline(always)] - pub fn byte_size(&self) -> usize { - match self { - Self::U8 => 1, - Self::F16 => 2, - Self::F32 | Self::I32 => 4, - Self::F64 | Self::I64 => 8, - } - } -} - -/// Tensor for wasi-nn syscall, the dimensions is `usize` instead of `u32`. -#[repr(C)] -pub(crate) struct Tensor<'t> { - pub dimensions: &'t [usize], - pub tensor_type: TensorType, - pub data: &'t [u8], -} - -impl<'t> Tensor<'t> { - #[inline(always)] - pub fn new(dimensions: &'t [usize], tensor_type: TensorType, data: &'t [u8]) -> Self { - Self { - dimensions, - tensor_type, - data, - } - } -} - -#[cfg(test)] -mod test { - use super::TensorType; - use crate::generated; - - #[test] - fn test_enum_tensor_type() { - assert_eq!(TensorType::F16 as u32, 0); - assert_eq!(TensorType::F32 as u32, 1); - assert_eq!(TensorType::F64 as u32, 2); - assert_eq!(TensorType::U8 as u32, 3); - assert_eq!(TensorType::I32 as u32, 4); - assert_eq!(TensorType::I64 as u32, 5); - } - - #[test] - fn test_tensor_type_with_generated() { - assert_eq!( - TensorType::F16 as u32, - generated::TENSOR_TYPE_F16.raw() as u32 - ); - assert_eq!( - TensorType::F32 as u32, - generated::TENSOR_TYPE_F32.raw() as u32 - ); - assert_eq!( - TensorType::F64 as u32, - generated::TENSOR_TYPE_F64.raw() as u32 - ); - assert_eq!( - TensorType::U8 as u32, - generated::TENSOR_TYPE_U8.raw() as u32 - ); - assert_eq!( - TensorType::I32 as u32, - generated::TENSOR_TYPE_I32.raw() as u32 - ); - assert_eq!( - TensorType::I64 as u32, - generated::TENSOR_TYPE_I64.raw() as u32 - ); - } - - #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] - #[test] - fn test_tensor_tor_wasi_nn_syscall() { - assert_eq!(std::mem::size_of::(), std::mem::size_of::()); - assert_eq!( - std::mem::size_of::(), - std::mem::size_of::() - ); - } -}