second-state / ssvm-napi-extensions

Apache License 2.0
4 stars 0 forks source link

Rust successfully compiles to Wasm but Wasm does not execute correctly - image rotation #9

Open tpmccallum opened 3 years ago

tpmccallum commented 3 years ago

The image rotate Rust code [1] compiles to wasm but produces an error when being executed over HTTP [2] via the FaaS. Evidently, for the same reason, the live demo [3] does not work.

The error produced by the failed execution is as follows

ERROR [default]     When executing function name: "rotate_an_image"

[1] https://github.com/second-state/wasm-learning/blob/master/faas/image-rotate/src/lib.rs [2] ERROR [default] When executing function name: "rotate_an_image" [3] https://second-state.github.io/wasm-learning/faas/image-rotate/html/index.html

hydai commented 3 years ago

First, I've created a simple script to trigger this function from js directly.

const { rotate_an_image } = require('../pkg/rotate_lib.js');

const fs = require('fs');
var data_img_hopper = fs.readFileSync("html/lean.png");

fs.writeFileSync("tmp.png", rotate_an_image(data_img_hopper));

Use it to run:

node index.js

And then I got this error:

Width: 501
Height: 707
Format detected: Png
Converting DynamicImage to ImageBuffer ...
Rotating image ...
thread '<unnamed>' panicked at 'The global thread pool has not been initialized.: ThreadPoolBuildError { kind: IOError(Custom { kind: Other, error: "operation not supported on this platform" }) }', /home/hydai/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:171:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2020-12-18 06:08:08,190 ERROR [default] execution failed: unreachable, Code: 0x89
2020-12-18 06:08:08,190 ERROR [default]     In instruction: unreachable (0x00) , Bytecode offset: 0x0005feed
2020-12-18 06:08:08,190 ERROR [default]     When executing function name: "rotate_an_image"
/home/hydai/workspace/wasm-learning/faas/image-rotate/pkg/rotate_lib.js:9
    let b = vm.RunUint8Array('rotate_an_image', img_buf);
               ^

Error: SSVM execution failed
    at module.exports.rotate_an_image (/home/hydai/workspace/wasm-learning/faas/image-rotate/pkg/rotate_lib.js:9:16)
    at Object.<anonymous> (/home/hydai/workspace/wasm-learning/faas/image-rotate/html/index.js:6:29)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'Error'
}

After I checked the imageproc documentation, I found this: https://github.com/image-rs/imageproc#crate-features

Imageproc is built with these features enabled by default: rayon enables multithreading for certain operations (e.g., geometric transformations) via rayon

So I am afraid that there is no multi-thread support on wasm platform. We should try to disable this multi-threading feature to figure out if this is not supported.

hydai commented 3 years ago

After I modified the imageproc dependency by:

imageproc = { version = "0.22.0", default-features = false }

I got the new error here:

Width: 501
Height: 707
Format detected: Png
Converting DynamicImage to ImageBuffer ...
Rotating image ...
Image rotated!
Creating byte array to return
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Unsupported(UnsupportedError { format: Unknown, kind: Format(Unknown) })', src/lib.rs:31:75
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2020-12-18 06:18:56,992 ERROR [default] execution failed: unreachable, Code: 0x89
2020-12-18 06:18:56,992 ERROR [default]     In instruction: unreachable (0x00) , Bytecode offset: 0x00044894
2020-12-18 06:18:56,992 ERROR [default]     When executing function name: "rotate_an_image"
/home/hydai/workspace/wasm-learning/faas/image-rotate/pkg/rotate_lib.js:9
    let b = vm.RunUint8Array('rotate_an_image', img_buf);
               ^

Error: SSVM execution failed
    at module.exports.rotate_an_image (/home/hydai/workspace/wasm-learning/faas/image-rotate/pkg/rotate_lib.js:9:16)
    at Object.<anonymous> (/home/hydai/workspace/wasm-learning/faas/image-rotate/html/index.js:6:29)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'Error'
}

Still investigating.

tpmccallum commented 3 years ago

Hi @hydai Thank you. I have made some progress on this. I have updated the Rust code to explicitly load_from_memory_with_format i.e.

    let img_to_write = match image::load_from_memory_with_format(&rotated_image.as_raw(), image::ImageFormat::Png) {
        Ok(i) => println!("OK"),
        Err(e) => println!("Error: {:?}", &e.to_string()),
    };

Which produces this error

Error: "Format error decoding Png: invalid signature"

It seems as though the rotated image data is not 100% correct. I will keep investigating this now. Chat soon Tim