Hello.
I found a memory leak in wasi-nn. When we call compute(), a tensor which is passed from wasm will be leaked because wasm pass its owenership but host doesn't comsume it.
I find this leak will be fixed with the following change.
https://github.com/seera-networks/wasmtime/commit/d1ac513d00b0cd3e2a869544c2bc067b5f6298b3
How can I contribute this change?
a pull request is the preferred way to propose code changes
cc @Andrew Brown for wasi-nn stuff
I memorized that within the Component model the host never frees data allocated by the guest directly, this is the purpose of the matching post_cabi function. Can you check whether this is the case here as well?
Yes, I believe you will want the guest to drop the tensor once you're done with it in whatever language you are using wasi-nn (what language are you using?). The appropriate self.table.delete(...) invocation happens in HostTensor::drop: https://github.com/bytecodealliance/wasmtime/blob/9d64c5250fa6d1eb1541c4e2d26da0ca6608ae21/crates/wasi-nn/src/wit.rs#L321-L324.
Thank you for your reply! I'm using Rust. I think that it is the best to invoke self.table.delete() in HostTensor::drop(), but I have no idea to invoke HostTensor::drop() from guest.
The following is my guest code:
let tensor = Tensor::new(&tensor_dim, TensorType::Fp32, &input_tensor);
let named_tensor = vec![("images".to_string(), tensor)];
let outputs = ctx.compute(named_tensor).unwrap();
In this code, the owenership of tensor will be passed, so HostTensor::drop will never be invoked. This is the reason why I suppose that we should invoke self.table.delete() in compute().
@Andrew Brown What do you think about my understanding? Do I misunderstand something?
I had thought that passing a resource in a WIT signature meant borrowing but your example makes me rethink that: Rust certainly expects ownership to transfer there. I guess I'm uncertain now: @Pat Hickey, does passing a resource as an argument transfer ownership or borrow the resource?
If the argument is wrapped in borrow<> it isn't consumed, as is the self argument in methods. But transfer clearly is the default.
Ok, this makes sense. I was unaware of the own/borrow notation when I switched wasi-nn from WITX to WIT long ago, so @Masahiro Kozuka's change makes complete sense if we are passing ownership of the tensor. @Masahiro Kozuka, do you want to submit a PR with this change?
In the future, we could debate changing the specification to borrow instead (probably the original intention), but for now this change would fix the bug.
Thanks. I will submit a PR in a few days.
@Andrew Brown I sent a PR.
Last updated: Dec 06 2025 at 06:05 UTC