How to test wasm32 target on Rust runtime binding

Hi @tqchen @jroesch and others, I was working for embedding TVM Rust runtime for WASM target (see here for the details), but came across some problems when building test-wasm32 crate.

Error elaboration

Firstly I need to clarify that I can build and run the test-wasm32 package successfully, but what I wanted is to build the lib rather than bin type of package, so I changed several lines in original main.rs and copy it to lib.rs:

extern "C" {
    static __tvm_module_ctx: i32;
}

#[no_mangle]
unsafe fn __get_tvm_module_ctx() -> i32 {
    // Refer a symbol in the libtest_wasm32.a to make sure that the link of the
    // library is not optimized out.
    __tvm_module_ctx
}

extern crate ndarray;
#[macro_use]
extern crate tvm_runtime;

use ndarray::Array;
use tvm_runtime::{DLTensor, Module as _, SystemLibModule};

#[no_mangle]
pub extern "C" fn run() {
    // try static
    let mut a = Array::from_vec(vec![1f32, 2., 3., 4.]);
    let mut b = Array::from_vec(vec![1f32, 0., 1., 0.]);
    let mut c = Array::from_vec(vec![0f32; 4]);
    let e = Array::from_vec(vec![2f32, 2., 4., 4.]);
    let mut a_dl: DLTensor = (&mut a).into();
    let mut b_dl: DLTensor = (&mut b).into();
    let mut c_dl: DLTensor = (&mut c).into();

    let syslib = SystemLibModule::default();
    let add = syslib
        .get_function("default_function")
        .expect("main function not found");
    call_packed!(add, &mut a_dl, &mut b_dl, &mut c_dl).unwrap();
    println!("{:?}", c_dl.data);
    assert!(c.all_close(&e, 1e-8f32));
}

But when I tried to compile the library, some errors occurred:

undefined symbol: __tvm_module_ctx

I was guessing something required to modified when changing the type from bin to lib, but I have no idea what to do about it because of missing the context, would be appreciated it if anyone could take a look.

I’ve tried your lib.rs and successfully created a static library. Please confirm that you set create-type to rlib in Cargo.toml. I could use the generated lib with the following simple main.rs.

extern crate test_wasm32;

fn main() {
    test_wasm32::run();
}

Hope this helps you :slight_smile:

@kazum Sorry for missing attaching the changes in Cargo.toml, actually I set crate-type to cdylib, is that something causing the problem?

Dynamic linking does not work with wasm as far as I know. Please specify rlib, or staticlib if you want to use it from non-Rust programs.

I think I get what you were meaning, but actually what I wanted is to compiled this lib into test_wasm.wasm file, so I guess cdylib type is required to be set in Cargo.toml, have you tried compiled the lib again using cdylib crate-type? Thanks!

That’s really frustrating, I have tried it again with cdylib, but even though I can compiled it into wasm file, but still can’t load it successfully using wasmtime.