♾️

Rust Wasm64 on IC

に公開

はじめに

分散型クラウドを実現するInternet ComputerCanisterがついにWasm64バイナリに対応しました。

アーキテクチャが32bitから64bitに変わることにより、プログラムで直接扱える最大メモリが4GiB (2^{32} bytes)から、理論上は16EiB (2^{64} bytes)になります。

Canisterの制約上、2025年6月時点では最大6GiBまでしかサポートされませんが、今後上限は引き上げられていくと思われますので、将来的にはLLMなど大量にメモリを必要とするような処理にも対応できる可能性は十分にあります。

Canister開発ツールは、今のところWasm32がデフォルトターゲットとなっているため、Wasm64化するためには、ビルド方法や設定を少し変更する必要があります。

本記事ではWasm32向けのサンプルプログラムをwasm64化して動作する手順を解説します。

参考情報

https://forum.dfinity.org/t/wasm64-beta-release-coming-soon/35791/16?u=marc0olo

The added benefit for the Wasm64-enabled canisters is that the heap size is now increased to 6 GiB (instead of the max 4 GiB given by the 32-bit address space). Getting to larger heap sizes is dependent on technical challenges related to deterministically tracking the amount of accessed memory pages during canister runtime. The execution team is investigating possible solutions to this problem and will come back to you with a timeline on when heaps can be increased beyond 6 GiB.

サンプルプログラム

1. プロジェクト作成

dfx newコマンドで生成されるプロジェクトは、2025年6月時点ではWasm32ベースとなっています。
まずはひな型を用意しましょう。Frontendは不要ですので--no-frontendを指定しています。

$ dfx new --no-frontend --type=rust hello
$ cd hello

生成されたサンプルプログラム

hello
├── .git
│    ︙
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── README.md
├── dfx.json
└── src
    └── hello_backend
        ├── Cargo.toml
        ├── src
        │   └── lib.rs
        └── hello_backend.did

src/hello_backend/src/lib.rs

どのアーキテクチャで動作しているかが分かるよう、サンプルのgree()関数を少し修正しましょう。

src/hello_backend/src/lib.rs
#[ic_cdk::query]
fn greet(name: String) -> String {
  let architecture = if cfg!(target_pointer_width = "32") {
    "wasm32"
  } else if cfg!(target_pointer_width = "64") {
    "wasm64"
  } else {
    "unknown"
  };

  format!("Hello, {}! Powered by {}", name, architecture) 
}

2. Local Canister Execution environment起動

$ dfx start --clean --background
$ dfx deploy

3. greet()メソッド呼び出し (既存; Wasm32)

$ dfx canister call hello_backend greet '("ICP")'
("Hello, ICP! Powered by wasm32")

Wasm64対応

1. Rust toolchainのnightly有効化

2025年6月現在、RustのtoolchainはWasm64ビルドは正式対応していないようです。

$ rustup --version
rustup 1.28.2 (e4f3ad6f8 2025-04-28)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.87.0 (17067e9ac 2025-05-09)`

$ rustup target add wasm64-unknown-unknown 
error: toolchain 'stable-x86_64-unknown-linux-gnu' does not support target 'wasm64-unknown-unknown';

以下のコマンドを実行することで、toolchainにnightlyを取り込むことで利用することが可能なようです。

$ rustup toolchain install nightly
︙

  nightly-x86_64-unknown-linux-gnu installed - rustc 1.89.0-nightly (8da623945 2025-06-13)
$  rustup component add rust-src --toolchain nightly

2. ビルド方法の変更

Canisterのビルドをカスタムにする必要があります。

(1) dfx.json

dfx.json(変更前)
{
  "canisters": {
    "hello_backend": {
      "candid": "src/hello_backend/hello_backend.did",
      "package": "hello_backend",
      "type": "rust"
    }
  },
dfx.json(変更後)
{
  "canisters": {
    "hello_backend": {
      "candid": "src/hello_backend/hello_backend.did",
      "build": "bash build.sh hello_backend",
      "type": "custom",
      "shrink": true,
      "gzip": true,
      "wasm": "target/wasm64-unknown-unknown/release/hello_backend.wasm",
      "metadata": [
        {
          "name": "candid:service"
        }
      ]
    }
  },

(2) Cargo.toml

2025年6月時点のdfx 0.27.0で生成されるIC関連crateのバージョンはWasm64未対応のようでランタイムエラーが発生しますので最新化しておく必要があります。

Cargo.toml(変更前)
[dependencies]
candid = "0.10"
ic-cdk = "0.17"
ic-cdk-timers = "0.11" # Feel free to remove this dependency if you don't need timers
Cargo.toml(変更後)
[dependencies]
candid = "0.10.14"
ic-cdk = "0.18.3"
ic-cdk-timers = "0.12.0"

あまりRustに詳しくないので他にもっと良い方法があれば教えてほしいのですが、
以下のようにいったん削除して、追加しなおすことで最新化することができます。

$ cargo remove candid ic-cdk ic-cdk-timers
$ cargo add candid ic-cdk ic-cdk-timers

(3) build.sh

Rustのtoolchainやdfxコマンドが正式にwasm64対応するまでの一時的なものになりますが、以下のようにcargo +nightly buildコマンドを実行します。

build.sh
#!/bin/bash

declare CANISTER_NAME=$1
cargo +nightly build -Z build-std=std,panic_abort --target wasm64-unknown-unknown --release -p ${CANISTER_NAME}

3. ビルド実行

$ dfx deploy

4. greet()メソッド呼び出し (Wasm64)

$ dfx canister call hello_backend greet '("ICP")'
("Hello, ICP! Powered by wasm64")

Discussion