diff --git a/.github/workflows/simd.yml b/.github/workflows/simd.yml new file mode 100644 index 0000000000..be430d8a7e --- /dev/null +++ b/.github/workflows/simd.yml @@ -0,0 +1,28 @@ +name: simd + +on: + push: + branches: [master] + pull_request: + paths: + - rust/simd/** + - .github/workflows/simd.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rust-simd: + runs-on: ubuntu-24.04 + container: ghcr.io/dfinity/icp-dev-env-rust:1.0.1 + env: + ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - name: Deploy and test + working-directory: rust/simd + run: | + icp network start -d + icp deploy + bash test.sh diff --git a/rust/simd/.devcontainer/devcontainer.json b/rust/simd/.devcontainer/devcontainer.json deleted file mode 100644 index ebb0b8bcc6..0000000000 --- a/rust/simd/.devcontainer/devcontainer.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "ICP Dev Environment", - "image": "ghcr.io/dfinity/icp-dev-env-slim:22", - "forwardPorts": [4943, 5173], - "portsAttributes": { - "4943": { - "label": "dfx", - "onAutoForward": "ignore" - }, - "5173": { - "label": "vite", - "onAutoForward": "openBrowser" - } - }, - "customizations": { - "vscode": { - "extensions": ["dfinity-foundation.vscode-motoko"] - } - } -} diff --git a/rust/simd/BUILD.md b/rust/simd/BUILD.md deleted file mode 100644 index 24cfcb7547..0000000000 --- a/rust/simd/BUILD.md +++ /dev/null @@ -1,113 +0,0 @@ -# Continue building locally - -Projects deployed through ICP Ninja are temporary; they will only be live for 20 minutes before they are removed. The command-line tool `dfx` can be used to continue building your ICP Ninja project locally and deploy it to the mainnet. - -To migrate your ICP Ninja project off of the web browser and develop it locally, follow these steps. - -### 1. Install developer tools. - -You can install the developer tools natively or use Dev Containers. - -#### Option 1: Natively install developer tools - -> Installing `dfx` natively is currently only supported on macOS and Linux systems. On Windows, it is recommended to use the Dev Containers option. - -1. Install `dfx` with the following command: - -``` - -sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" - -``` - -> On Apple Silicon (e.g., Apple M1 chip), make sure you have Rosetta installed (`softwareupdate --install-rosetta`). - -2. [Install NodeJS](https://nodejs.org/en/download/package-manager). - -3. For Rust projects, you will also need to: - -- Install [Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html#install-rust-and-cargo): `curl https://sh.rustup.rs -sSf | sh` - -- Install [candid-extractor](https://crates.io/crates/candid-extractor): `cargo install candid-extractor` - -4. For Motoko projects, you will also need to: - -- Install the Motoko package manager [Mops](https://docs.mops.one/quick-start#2-install-mops-cli): `npm i -g ic-mops` - -Lastly, navigate into your project's directory that you downloaded from ICP Ninja. - -#### Option 2: Dev Containers - -Continue building your projects locally by installing the [Dev Container extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) for VS Code and [Docker](https://docs.docker.com/engine/install/). - -Make sure Docker is running, then navigate into your project's directory that you downloaded from ICP Ninja and start the Dev Container by selecting `Dev-Containers: Reopen in Container` in VS Code's command palette (F1 or Ctrl/Cmd+Shift+P). - -> Note that local development ports (e.g. the ports used by `dfx` or `vite`) are forwarded from the Dev Container to your local machine. In the VS code terminal, use Ctrl/Cmd+Click on the displayed local URLs to open them in your browser. To view the current port mappings, click the "Ports" tab in the VS Code terminal window. - -### 2. Start the local development environment. - -``` -dfx start --background -``` - -### 3. Create a local developer identity. - -To manage your project's canisters, it is recommended that you create a local [developer identity](https://internetcomputer.org/docs/building-apps/getting-started/identities) rather than use the `dfx` default identity that is not stored securely. - -To create a new identity, run the commands: - -``` - -dfx identity new IDENTITY_NAME - -dfx identity use IDENTITY_NAME - -``` - -Replace `IDENTITY_NAME` with your preferred identity name. The first command `dfx start --background` starts the local `dfx` processes, then `dfx identity new` will create a new identity and return your identity's seed phase. Be sure to save this in a safe, secure location. - -The third command `dfx identity use` will tell `dfx` to use your new identity as the active identity. Any canister smart contracts created after running `dfx identity use` will be owned and controlled by the active identity. - -Your identity will have a principal ID associated with it. Principal IDs are used to identify different entities on ICP, such as users and canisters. - -[Learn more about ICP developer identities](https://internetcomputer.org/docs/building-apps/getting-started/identities). - -### 4. Deploy the project locally. - -Deploy your project to your local developer environment with: - -``` -npm install -dfx deploy - -``` - -Your project will be hosted on your local machine. The local canister URLs for your project will be shown in the terminal window as output of the `dfx deploy` command. You can open these URLs in your web browser to view the local instance of your project. - -### 5. Obtain cycles. - -To deploy your project to the mainnet for long-term public accessibility, first you will need [cycles](https://internetcomputer.org/docs/building-apps/getting-started/tokens-and-cycles). Cycles are used to pay for the resources your project uses on the mainnet, such as storage and compute. - -> This cost model is known as ICP's [reverse gas model](https://internetcomputer.org/docs/building-apps/essentials/gas-cost), where developers pay for their project's gas fees rather than users pay for their own gas fees. This model provides an enhanced end user experience since they do not need to hold tokens or sign transactions when using a dapp deployed on ICP. - -> Learn how much a project may cost by using the [pricing calculator](https://internetcomputer.org/docs/building-apps/essentials/cost-estimations-and-examples). - -Cycles can be obtained through [converting ICP tokens into cycles using `dfx`](https://internetcomputer.org/docs/building-apps/developer-tools/dfx/dfx-cycles#dfx-cycles-convert). - -### 6. Deploy to the mainnet. - -Once you have cycles, run the command: - -``` - -dfx deploy --network ic - -``` - -After your project has been deployed to the mainnet, it will continuously require cycles to pay for the resources it uses. You will need to [top up](https://internetcomputer.org/docs/building-apps/canister-management/topping-up) your project's canisters or set up automatic cycles management through a service such as [CycleOps](https://cycleops.dev/). - -> If your project's canisters run out of cycles, they will be removed from the network. - -## Additional examples - -Additional code examples and sample applications can be found in the [DFINITY examples repo](https://github.com/dfinity/examples). diff --git a/rust/simd/Cargo.lock b/rust/simd/Cargo.lock index de4a956ac4..7f7c7ee33f 100644 --- a/rust/simd/Cargo.lock +++ b/rust/simd/Cargo.lock @@ -236,12 +236,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] -name = "mat_mat_mul" -version = "1.0.0" +name = "backend" +version = "0.1.0" dependencies = [ "candid", "ic-cdk", - "ic-cdk-macros", ] [[package]] diff --git a/rust/simd/Cargo.toml b/rust/simd/Cargo.toml index df59fb0a73..0684d2cd39 100644 --- a/rust/simd/Cargo.toml +++ b/rust/simd/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["mat_mat_mul"] +members = ["backend"] resolver = "2" [profile.release] diff --git a/rust/simd/Makefile b/rust/simd/Makefile deleted file mode 100644 index ccd6672128..0000000000 --- a/rust/simd/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -.PHONY: all -all: deploy - -.PHONY: deploy -.SILENT: deploy -deploy: - dfx deploy mat_mat_mul - -.PHONY: test -.SILENT: test -test: deploy - # Validate the number of instructions is non-zero. - dfx canister call mat_mat_mul naive_f32 | grep -vw '0' && echo 'PASS' - dfx canister call mat_mat_mul optimized_f32 | grep -vw '0' && echo 'PASS' - dfx canister call mat_mat_mul auto_vectorized_f32 | grep -vw '0' && echo 'PASS' - dfx canister call mat_mat_mul simd_f32 | grep -vw '0' && echo 'PASS' - dfx canister call mat_mat_mul naive_u32 | grep -vw '0' && echo 'PASS' - dfx canister call mat_mat_mul optimized_u32 | grep -vw '0' && echo 'PASS' - dfx canister call mat_mat_mul auto_vectorized_u32 | grep -vw '0' && echo 'PASS' - -.PHONY: clean -.SILENT: clean -clean: - rm -fr .dfx diff --git a/rust/simd/README.md b/rust/simd/README.md index 63f896c9b1..e5532b5bc7 100644 --- a/rust/simd/README.md +++ b/rust/simd/README.md @@ -5,203 +5,78 @@ SIMD ([Single Instruction, Multiple Data](https://en.wikipedia.org/wiki/Single_i instructions. This, combined with state-of-the-art Rust compiler support, opens new horizons for the Internet Computer. -This example showcases different approaches to utilizing the new SIMD instructions: Rust auto-vectorization and SIMD intrinsics for matrix multiplication, a core operation in Machine Learning and Artificial Intelligence applications. The example compares various SIMD optimization techniques and their potential speedups. +This example showcases different approaches to utilizing WebAssembly SIMD instructions: Rust auto-vectorization and SIMD intrinsics for matrix multiplication, a core operation in Machine Learning and Artificial Intelligence applications. The example compares various optimization techniques and their potential speedups. -The example consists of a canister named `mat_mat_mul` (matrix-matrix multiplication). +The canister exposes seven query methods that each perform 1,000 iterations of a 4×K matrix multiplication tile and return the number of Wasm instructions consumed: -## Deploying from ICP Ninja +- `naive_f32` / `naive_u32` — straightforward element-wise loop +- `optimized_f32` / `optimized_u32` — uses packed slices to improve memory access patterns +- `auto_vectorized_f32` / `auto_vectorized_u32` — same optimized loop annotated with `#[target_feature(enable = "simd128")]`, letting Rust auto-vectorize with SIMD instructions +- `simd_f32` — hand-written SIMD intrinsics using `core::arch::wasm32` -When viewing this project in ICP Ninja, you can deploy it directly to the mainnet for free by clicking "Run" in the upper right corner. Open this project in ICP Ninja: +In practice, Rust's auto-vectorization achieves over 10× speedup for f32 and more than 2× for u32 compared to the optimized baseline, and the hand-crafted SIMD version is on par with auto-vectorization. -[![](https://icp.ninja/assets/open.svg)](https://icp.ninja/i?g=https://github.com/dfinity/examples/rust/simd) +The code is based on the Sonos `tract` Neural Network inference toolkit's `AddMatMul` operator. For more details on the packing technique, see [The anatomy of efficient matrix multipliers](https://tech-blog.sonos.com/posts/the-anatomy-of-efficient-matrix-multipliers/). -## Build and deploy from the command-line +Note: SIMD instructions are selectively enabled per function using `#[target_feature(enable = "simd128")]` rather than globally. To enable SIMD for the whole workspace, uncomment the `rustflags` line in `.cargo/config.toml`. -This example requires an installation of: +## Build and deploy from the command line -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). Note: the WebAssembly SIMD support requires `dfx` version `0.20.2-beta.0` or later. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +### Prerequisites -### Example 1: Floating point matrices multiplications +- Node.js +- icp-cli: `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm` -- #### Step 1: Setup project environment +### Install -Navigate into the folder containing the project's files and start a local instance of the replica with the command: - -```sh -cd examples/rust/simd -dfx start --clean -``` - -```sh -dfx start --clean -Running dfx start for version 0.20.2-beta.0 -[...] -Dashboard: http://localhost:63387/_/dashboard -``` - -- #### Step 2: Open another terminal window in the same directory - -```sh -cd examples/rust/simd -``` - -- #### Step 3: Compile and deploy `mat_mat_mul` canister - -```sh -dfx deploy -``` - -Example output: - -```sh -% dfx deploy -[...] -Deployed canisters. -URLs: - Backend canister via Candid interface: - mat_mat_mul: http://127.0.0.1/?canisterId=... -``` - -- #### Step 4: Compare the amount of instructions used for different matrix multiplication implementations - -Call a loop performing 1K element-wise multiplications of `K x 4` packed slices -from matrices `A` and `B` using optimized algorithm, the same algorithm with -Rust auto-vectorization enabled, and WebAssembly SIMD instructions: - -```sh -dfx canister call mat_mat_mul optimized_f32 -dfx canister call mat_mat_mul auto_vectorized_f32 -dfx canister call mat_mat_mul simd_f32 -``` - -Example output: - -```sh -% dfx canister call mat_mat_mul optimized_f32 -(168_542_255 : nat64) -% dfx canister call mat_mat_mul auto_vectorized_f32 -(13_697_228 : nat64) -% dfx canister call mat_mat_mul simd_f32 -(13_697_228 : nat64) -``` - -In this example, Rust's auto-vectorization shines in optimizing matrix multiplication. -The auto-vectorized code achieves over 10x speedup compared to the optimized version! -Also, it's on par with the hand-crafted WebAssembly SIMD multiplication. - -### Example 2: Integer matrices multiplications - -- #### Step 1: Setup project environment - -Navigate into the folder containing the project's files and start a local instance of the replica with the command: - -```sh -cd examples/rust/simd -dfx start --clean -``` - -```sh -dfx start --clean -Running dfx start for version 0.20.2-beta.0 -[...] -Dashboard: http://localhost:63387/_/dashboard -``` - -- #### Step 2: Open another terminal window in the same directory - -```sh +```bash +git clone https://github.com/dfinity/examples cd examples/rust/simd ``` -- #### Step 3: Compile and deploy `mat_mat_mul` canister +### Deploy and test -```sh -dfx deploy +```bash +icp network start -d +icp deploy +bash test.sh +icp network stop ``` -Example output: - -```sh -% dfx deploy -[...] -Deployed canisters. -URLs: - Backend canister via Candid interface: - mat_mat_mul: http://127.0.0.1/?canisterId=... -``` +### Comparing instruction counts -- #### Step 4: Compare the amount of instructions used for different matrix multiplication implementations +After deploying, call each method to see the instruction counts for different implementations: -Call a loop performing 1K element-wise multiplications of `K x 4` packed slices -from matrices `A` and `B` using optimized algorithm and the same algorithm -with Rust auto-vectorization enabled: +```bash +# Floating-point matrix multiplication +icp canister call --query backend optimized_f32 '()' +icp canister call --query backend auto_vectorized_f32 '()' +icp canister call --query backend simd_f32 '()' -```sh -dfx canister call mat_mat_mul optimized_u32 -dfx canister call mat_mat_mul auto_vectorized_u32 +# Integer matrix multiplication +icp canister call --query backend optimized_u32 '()' +icp canister call --query backend auto_vectorized_u32 '()' ``` Example output: -```sh -% dfx canister call mat_mat_mul optimized_u32 -(32_342_253 : nat64) -% dfx canister call mat_mat_mul auto_vectorized_u32 -(16_164_254 : nat64) ``` - -Rust auto-vectorization again demonstrates its power in this example. -The auto-vectorized version of the integer matrix multiplication achieves -more than a 2x speedup compared to the original code. - -## Further learning - -1. Have a look at the locally running dashboard. The URL is at the end of the `dfx start` command: `Dashboard: http://localhost/...` -2. Check out `mat_mat_mul` canister Candid user interface. The URLs are at the end of the `dfx deploy` command: `mat_mat_mul: http://127.0.0.1/?canisterId=...` - -### Canister interface - -The `mat_mat_mul` canister provide the following interface: - -- `naive_f32`/`naive_u32` — - returns the number of instructions used for a loop performing - 1K element-wise multiplications of matrices `A` and `B` - using naive algorithm. -- `optimized_f32`/`optimized_u32` — - returns the number of instructions used for a loop performing - 1K element-wise multiplications of `K x 4` packed slices - from matrices `A` and `B` using optimized algorithm. -- `auto_vectorized_f32`/`auto_vectorized_u32` — - returns the number of instructions used for a loop performing - 1K element-wise multiplications of `K x 4` packed slices - from matrices `A` and `B` using Rust loop auto-vectorization. -- `simd_f32` — - Returns the number of instructions used for a loop performing - 1K element-wise multiplications of `K x 4` packed slices - from matrices `A` and `B` using WebAssembly SIMD instructions. - -Example usage: - -```sh -dfx canister call mat_mat_mul naive_f32 +# Floating-point results +(168_542_255 : nat64) # optimized_f32 +(13_697_228 : nat64) # auto_vectorized_f32 — over 10x speedup! +(13_697_228 : nat64) # simd_f32 — on par with auto-vectorization + +# Integer results +(32_342_253 : nat64) # optimized_u32 +(16_164_254 : nat64) # auto_vectorized_u32 — more than 2x speedup ``` -## Conclusion - -WebAssembly SIMD instructions unlock new possibilities for the Internet Computer, -particularly in Machine Learning and Artificial Intelligence dApps. This example -demonstrates potential 10x speedups for matrix multiplication with minimal effort -using just Rust's loop auto-vectorization. - -As shown in Example 2, integer operations also benefit, although with a more modest -"2x" speedup. +Rust's auto-vectorization achieves over 10x speedup for float matrix multiplication compared to the optimized version, and it's on par with hand-crafted WebAssembly SIMD intrinsics. Integer operations also benefit with more than 2x speedup. -The actual speedups will vary depending on the specific application and the type -of operations involved. +The actual speedups will vary depending on the specific application and the type of operations involved. ## Security considerations and best practices If you base your application on this example, we recommend you familiarize -yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) +yourself with and adhere to the [security best practices](https://docs.internetcomputer.org/guides/security/overview) for developing on the Internet Computer. This example may not implement all the best practices. diff --git a/rust/simd/backend/Cargo.toml b/rust/simd/backend/Cargo.toml new file mode 100644 index 0000000000..669a663902 --- /dev/null +++ b/rust/simd/backend/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +candid = "0.10" +ic-cdk = "0.20" diff --git a/rust/simd/mat_mat_mul/src/lib.rs b/rust/simd/backend/src/lib.rs similarity index 98% rename from rust/simd/mat_mat_mul/src/lib.rs rename to rust/simd/backend/src/lib.rs index 2dc1eda6ad..514394a5d0 100644 --- a/rust/simd/mat_mat_mul/src/lib.rs +++ b/rust/simd/backend/src/lib.rs @@ -52,7 +52,7 @@ fn fmt(n: u64) -> String { /// Returns the number of instructions used for a loop performing /// 1K element-wise multiplications of matrices `A` and `B` /// using naive algorithm. -#[ic_cdk_macros::query] +#[ic_cdk::query] fn naive_f32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -74,7 +74,7 @@ fn naive_f32() -> u64 { /// Returns the number of instructions used for a loop performing /// 1K element-wise multiplications of `K x 4` packed slices /// from matrices `A` and `B` using optimized algorithm. -#[ic_cdk_macros::query] +#[ic_cdk::query] fn optimized_f32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -109,7 +109,7 @@ fn optimized_f32() -> u64 { /// /// The following line enables auto-vectorization using WebAssembly SIMD instructions. #[target_feature(enable = "simd128")] -#[ic_cdk_macros::query] +#[ic_cdk::query] fn auto_vectorized_f32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -144,7 +144,7 @@ fn auto_vectorized_f32() -> u64 { /// /// The following line enables WebAssembly SIMD instructions. #[target_feature(enable = "simd128")] -#[ic_cdk_macros::query] +#[ic_cdk::query] fn simd_f32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -179,7 +179,7 @@ fn simd_f32() -> u64 { /// Returns the number of instructions used for a loop performing /// 1K element-wise multiplications of matrices `A` and `B` /// using naive algorithm. -#[ic_cdk_macros::query] +#[ic_cdk::query] fn naive_u32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -201,7 +201,7 @@ fn naive_u32() -> u64 { /// Returns the number of instructions used for a loop performing /// 1K element-wise multiplications of `K x 4` packed slices /// from matrices `A` and `B` using optimized algorithm. -#[ic_cdk_macros::query] +#[ic_cdk::query] fn optimized_u32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -236,7 +236,7 @@ fn optimized_u32() -> u64 { /// /// The following line enables auto-vectorization using WebAssembly SIMD instructions. #[target_feature(enable = "simd128")] -#[ic_cdk_macros::query] +#[ic_cdk::query] fn auto_vectorized_u32() -> u64 { let a = mats::Matrix::::new(); let b = mats::Matrix::::new(); @@ -264,3 +264,5 @@ fn auto_vectorized_u32() -> u64 { ); instructions } + +ic_cdk::export_candid!(); diff --git a/rust/simd/mat_mat_mul/src/mats.rs b/rust/simd/backend/src/mats.rs similarity index 100% rename from rust/simd/mat_mat_mul/src/mats.rs rename to rust/simd/backend/src/mats.rs diff --git a/rust/simd/dfx.json b/rust/simd/dfx.json deleted file mode 100644 index 9849f78707..0000000000 --- a/rust/simd/dfx.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "canisters": { - "mat_mat_mul": { - "candid": "mat_mat_mul/mat_mat_mul.did", - "package": "mat_mat_mul", - "type": "rust", - "metadata": [ - { - "name": "candid:service" - } - ] - } - }, - "version": 1 -} diff --git a/rust/simd/icp.yaml b/rust/simd/icp.yaml new file mode 100644 index 0000000000..b7c87727a0 --- /dev/null +++ b/rust/simd/icp.yaml @@ -0,0 +1,4 @@ +canisters: + - name: backend + recipe: + type: "@dfinity/rust@v3.3.0" diff --git a/rust/simd/mat_mat_mul/Cargo.toml b/rust/simd/mat_mat_mul/Cargo.toml deleted file mode 100644 index 724cbbe53e..0000000000 --- a/rust/simd/mat_mat_mul/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -edition = "2021" -name = "mat_mat_mul" -version = "1.0.0" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -candid = "0.10.8" -ic-cdk = "0.14.0" -ic-cdk-macros = "0.14.0" diff --git a/rust/simd/mat_mat_mul/mat_mat_mul.did b/rust/simd/mat_mat_mul/mat_mat_mul.did deleted file mode 100644 index 18011fff62..0000000000 --- a/rust/simd/mat_mat_mul/mat_mat_mul.did +++ /dev/null @@ -1,9 +0,0 @@ -service : { - "naive_f32" : () -> (nat64) query; - "optimized_f32" : () -> (nat64) query; - "auto_vectorized_f32" : () -> (nat64) query; - "simd_f32" : () -> (nat64) query; - "naive_u32" : () -> (nat64) query; - "optimized_u32" : () -> (nat64) query; - "auto_vectorized_u32" : () -> (nat64) query; -}; diff --git a/rust/simd/rust-toolchain.toml b/rust/simd/rust-toolchain.toml index 3736fc7612..990104f055 100644 --- a/rust/simd/rust-toolchain.toml +++ b/rust/simd/rust-toolchain.toml @@ -1,4 +1,2 @@ [toolchain] -channel = "1.78" targets = ["wasm32-unknown-unknown"] -components = ["rustfmt", "clippy"] diff --git a/rust/simd/test.sh b/rust/simd/test.sh new file mode 100755 index 0000000000..5469aa400b --- /dev/null +++ b/rust/simd/test.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -e + +echo "=== Test 1: naive_f32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend naive_f32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1) + +echo "=== Test 2: optimized_f32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend optimized_f32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1) + +echo "=== Test 3: auto_vectorized_f32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend auto_vectorized_f32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1) + +echo "=== Test 4: simd_f32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend simd_f32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1) + +echo "=== Test 5: naive_u32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend naive_u32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1) + +echo "=== Test 6: optimized_u32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend optimized_u32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1) + +echo "=== Test 7: auto_vectorized_u32() returns a non-zero instruction count ===" +result=$(icp canister call --query backend auto_vectorized_u32 '()') && \ + echo "$result" && \ + echo "$result" | grep -qv '(0 : nat64)' && \ + echo "PASS" || (echo "FAIL" && exit 1)