Skip to content

Commit 88ac7bc

Browse files
committed
Add wasi p2 example using rustc native p2 target
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
1 parent b463022 commit 88ac7bc

File tree

9 files changed

+592
-9
lines changed

9 files changed

+592
-9
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,5 +478,8 @@ target/
478478

479479
# MSVC Windows builds of rustc generate these, which store debugging information
480480
*.pdb
481-
src/component_sample/**/*.wasm
481+
482+
# WebAssembly build artifacts
483+
*.wasm
484+
482485
src/wasmsamples/components/bindings/

Cargo.lock

Lines changed: 38 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Justfile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mkdir-arg := if os() == "windows" { "-Force" } else { "-p" }
55
latest-release:= if os() == "windows" {"$(git tag -l --sort=v:refname | select -last 2 | select -first 1)"} else {`git tag -l --sort=v:refname | tail -n 2 | head -n 1`}
66
wit-world := if os() == "windows" { "$env:WIT_WORLD=\"" + justfile_directory() + "\\src\\component_sample\\wit\\component-world.wasm" + "\";" } else { "WIT_WORLD=" + justfile_directory() + "/src/component_sample/wit/component-world.wasm" }
77
wit-world-c := if os() == "windows" { "$env:WIT_WORLD=\"" + justfile_directory() + "\\src\\wasmsamples\\components\\runcomponent-world.wasm" + "\";" } else { "WIT_WORLD=" + justfile_directory() + "/src/wasmsamples/components/runcomponent-world.wasm" }
8+
wit-world-monte-carlo := if os() == "windows" { "$env:WIT_WORLD=\"" + justfile_directory() + "\\src\\wasip2_guest\\monte-carlo-world.wasm" + "\";" } else { "WIT_WORLD=" + justfile_directory() + "/src/wasip2_guest/monte-carlo-world.wasm" }
89

910
set windows-shell := ["pwsh.exe", "-NoLogo", "-Command"]
1011

@@ -32,6 +33,7 @@ mkdir-redist target=default-target:
3233
compile-wit:
3334
wasm-tools component wit ./src/wasmsamples/components/runcomponent.wit -w -o ./src/wasmsamples/components/runcomponent-world.wasm
3435
wasm-tools component wit ./src/component_sample/wit/example.wit -w -o ./src/component_sample/wit/component-world.wasm
36+
wasm-tools component wit ./src/wasip2_guest/wit/monte-carlo.wit -w -o ./src/wasip2_guest/monte-carlo-world.wasm
3537

3638
build-examples target=default-target features="": (build-wasm-examples target features) (build-rust-wasm-examples target features) (build-rust-component-examples target features)
3739

@@ -50,6 +52,13 @@ build-rust-component-examples target=default-target features="": (compile-wit)
5052
cd ./src/component_sample && cargo component build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }}
5153
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/component_sample.aot
5254

55+
build-monte-carlo-example features="": (compile-wit) (mkdir-redist "release")
56+
# Monte Carlo Pi example using native wasm32-wasip2 + wit-bindgen
57+
# Always build in release mode to avoid WASI dependencies (debug mode pulls in entire WASI for some reason)
58+
rustup target add wasm32-wasip2
59+
cd ./src/wasip2_guest && cargo build --lib --target wasm32-wasip2 --release
60+
cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile {{ if features =~ "gdb" {"--debug"} else {""} }} --component ./src/wasip2_guest/target/wasm32-wasip2/release/monte_carlo.wasm ./x64/release/monte_carlo.aot
61+
5362
check target=default-target:
5463
cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
5564
cd src/rust_wasm_samples && cargo check --profile={{ if target == "debug" {"dev"} else { target } }}
@@ -99,9 +108,10 @@ examples-ci target=default-target features="": (build-rust-wasm-examples target)
99108
cargo run {{ if features =="" {''} else {"--no-default-features -F function_call_metrics," + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example metrics
100109
cargo run {{ if features =="" {"--no-default-features --features kvm,mshv3"} else {"--no-default-features -F function_call_metrics," + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example metrics
101110

102-
examples-components target=default-target features="": (build-rust-component-examples target)
111+
examples-components target=default-target features="": (build-rust-component-examples target) (build-monte-carlo-example)
103112
{{ wit-world }} cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example component_example
104113
{{ wit-world-c }} cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example c-component
114+
{{ wit-world-monte-carlo }} cargo run {{ if features =="" {''} else {"--no-default-features -F kvm -F " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} --example monte_carlo_example
105115

106116
# warning, compares to and then OVERWRITES the given baseline
107117
bench-ci baseline target="release" features="":

src/hyperlight_wasm/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ name = "interruption"
5959
path = "examples/interruption/main.rs"
6060
test = true
6161

62+
[[example]]
63+
name = "monte_carlo_example"
64+
path = "examples/monte_carlo_example/main.rs"
65+
test = true
66+
6267
[dependencies]
6368
hyperlight-host = { workspace = true }
6469
libc = { version = "0.2.180" }
@@ -92,6 +97,7 @@ tracing = "0.1.44"
9297
tracing-subscriber = {version = "0.3.22", features = ["std", "env-filter"]}
9398
tracing-opentelemetry = "0.32.1"
9499
uuid = { version = "1.19.0", features = ["v4"] }
100+
rand = "0.8"
95101

96102
[build-dependencies]
97103
cfg_aliases = "0.2.1"
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
Copyright 2024 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
//! Monte Carlo Pi Estimator - Host Example
18+
//!
19+
//! Demonstrates running a WASI P2 component built with native `wasm32-wasip2`
20+
//! target and `wit-bindgen`. The host provides a random number generator
21+
//! that the guest component imports to estimate Pi.
22+
//!
23+
//! Build the guest first: `just build-monte-carlo-example`
24+
//! Run: `just examples-components`
25+
26+
extern crate alloc;
27+
28+
use std::env;
29+
use std::path::Path;
30+
31+
use rand::rngs::StdRng;
32+
use rand::{Rng, SeedableRng};
33+
34+
mod bindings {
35+
hyperlight_component_macro::host_bindgen!("../wasip2_guest/monte-carlo-world.wasm");
36+
}
37+
38+
/// Host-provided RNG state for the guest component.
39+
///
40+
/// The guest cannot generate randomness in `no_std` mode, so the host
41+
/// provides random numbers via the imported `random` interface.
42+
struct State {
43+
rng: StdRng,
44+
}
45+
46+
impl State {
47+
fn new() -> Self {
48+
State {
49+
rng: StdRng::from_entropy(),
50+
}
51+
}
52+
}
53+
54+
impl bindings::my::monte_carlo::Random for State {
55+
fn random(&mut self) -> f32 {
56+
self.rng.r#gen::<f32>()
57+
}
58+
}
59+
60+
#[allow(refining_impl_trait)]
61+
impl bindings::my::monte_carlo::EstimatorImports for State {
62+
type Random = State;
63+
64+
fn random(&mut self) -> &mut Self::Random {
65+
self
66+
}
67+
}
68+
69+
fn main() {
70+
let state = State::new();
71+
72+
let mut sb: hyperlight_wasm::ProtoWasmSandbox = hyperlight_wasm::SandboxBuilder::new()
73+
.with_guest_input_buffer_size(1000000)
74+
.with_guest_heap_size(10000000)
75+
.with_guest_stack_size(1000000)
76+
.build()
77+
.unwrap();
78+
79+
let rt = bindings::register_host_functions(&mut sb, state);
80+
81+
let sb = sb.load_runtime().unwrap();
82+
83+
// Always look in x64/release since the guest is always built in release mode
84+
// (debug mode pulls in WASI dependencies that we don't support)
85+
let proj_dir = env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
86+
let mod_path = Path::new(&proj_dir)
87+
.join("../../x64/release/monte_carlo.aot")
88+
.canonicalize()
89+
.expect("Failed to find monte_carlo.aot - run 'just build-monte-carlo-example' first");
90+
let sb = sb.load_module(mod_path).unwrap();
91+
92+
let mut wrapped = bindings::EstimatorSandbox { sb, rt };
93+
94+
// Estimate pi with different sample sizes
95+
for samples in [100, 1000, 10000] {
96+
let pi_estimate =
97+
bindings::my::monte_carlo::EstimatorExports::estimate_pi(&mut wrapped, samples);
98+
println!(
99+
"Pi estimate with {} samples: {:.6} (error: {:.6})",
100+
samples,
101+
pi_estimate,
102+
(pi_estimate - std::f32::consts::PI).abs()
103+
);
104+
}
105+
}

0 commit comments

Comments
 (0)