Image-sequencer: explore acceleration w WebAssembly

Created on 11 Oct 2018  ยท  51Comments  ยท  Source: publiclab/image-sequencer

WebAssembly seems like a way we might speed up pixel-by-pixel operations.

https://developer.mozilla.org/en-US/docs/WebAssembly

But would it suffer from the same issues as webworkers, i.e. a cost of passing the image data over?

enhancement help wanted performance project

Most helpful comment

I would love to see a prototype of this in a PR, yes please!

On Mon, Mar 4, 2019 at 6:32 PM Slytherin notifications@github.com wrote:

@jywarren https://github.com/jywarren in that case may I proceed with
nectarJs for applying the same to our PixelManipulation.js ?

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-469470300,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ7PbPE_HUQ839p_uyAA93tzOY76Gks5vTazagaJpZM4XXM4q
.

All 51 comments

Also note this way of writing WebAssembly:

https://github.com/ballercat/walt

GitMate.io thinks the contributor most likely able to help you is @ccpandhare.

A possibly related issue is https://github.com/publiclab/image-sequencer/issues/237 (Explore OpenCV.js module).

@jywarren Even I was thinking we can write the pixel manipulation code in c and create a js binding to it, is that the same as web assembly? I mean the code shows up as native code.

Interesting -- well, the WebAssembly approach means it'd be runnable at (near?) native speed in the browser, too! I think it could get really fast -- maybe not GPU speed, but maybe closer to video speed. For a speed reference we'd like to get closer to, see the Infragram WebGL demo: https://publiclab.github.io/infragram/

Walt seems like a good way to easily write webassembly code!

Provide a thin layer of syntax sugar on top of .wat text format. Preferably porting as much of JavaScript syntax to WebAssembly as possible. This improved syntax should give direct control over the WebAssembly output. Meaning there should be minimal to none post optimization to be done to the wast code generated. The re-use of JavaScript semantics is intentional as I do not wish to create a brand new language.

Also noting imagemagick has been compiled for webassembly... Wow!

https://github.com/KnicKnic/WASM-ImageMagick/blob/master/Readme.md

I think we could write a version of Pixelmanipulation following this example!

https://github.com/ballercat/walt/wiki/Walt-In-5-Minutes

...but would we be able to run a JavaScript function inside? I'm not sure about that. Would the function have to be compiled as well?

This is a great area for testing code snippets!

https://ballercat.github.io/walt/

Just asked over at the Walt project if their compiler runs in the browser. Otherwise we could look at precompiling these at build time.

So I think if the simple pixel manipulation function we pass into the PixelManipulation module is close enough to Walt syntax, which is actually WebAssembly, but "looks like" javascript... so if the inside of a function like this could be compiled almost directly, that'd be interesting:

https://github.com/publiclab/image-sequencer/blob/1311119787e6b7e7100cec80da59253adb0eba8b/src/modules/Brightness/Module.js#L22-L29

By comparison, here is a section of walt code:

  for (i = 0; i < total; i += 1) {
    particle = i * particleByteSize;
    particle = {
      x: width / 2.0,
      y: height / 2.0,
      vx: ((i * 7 % 200) - 100) / 100.0,
      vy: ((i * 19 % 200) - 100) / 100.0
    };
  }
const x: i32 = 2;
export function echo(): i32 {
  const x: i32 = 42;
  return x;
}

Walt folks responded to say that walt does indeed compile in the browser, on the fly! Awesome.

I was reading the above discussions and I think we can implement pixel manipulation code in c and then compile it into wasm file and then add it into the project. After that we can instantiate the WebAssembly module and use the functions written in pixel manipulation file, which is in c, in the js files!
cc @jywarren @tech4GT

that sounds great!

On Mon, Dec 31, 2018 at 5:23 AM Mridul97 notifications@github.com wrote:

I was reading the above discussions.. I am thinking to implement pixel
manipulation code in c and then compile it into wasm file and then add it
into the project. After that we can instantiate the module and use the
functions written in pixel manipulation file, which is in c, in the js
files.
cc @jywarren https://github.com/jywarren @tech4GT
https://github.com/tech4GT

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-450629581,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ_pwxOf22XeHB0vwioPE21wwQGCXks5u-eVxgaJpZM4XXM4q
.

Can I work on this issue?

yes please!!!

On Fri, Mar 1, 2019 at 5:05 PM Slytherin notifications@github.com wrote:

Can I work on this issue?

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-468828032,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ8aHsoHsbGj20VY8vcgdXh2_6iaZks5vSaQmgaJpZM4XXM4q
.

@jywarren @publiclab/is-reviewers nectarJs claims that it can compile js to native OS binaries for all platforms. This can be used to compile the lib for CLI maybe? It says that it can also create webassembly from js code. (It is under development though)

NectarJs github page

webpage

@jywarren your thoughts on nectarJs please?

Hmm, i thought webassembly is cross-platform anyways? But that is very cool!

Ah, i see that nectarJs seems to have an option to compile to WASM (which
should then be cross-platform as that's the WebAssembly format). Perhaps we
could do that with some portions of our code, like PixelManipulation, to
achieve our goal?

On Sat, Mar 2, 2019 at 12:09 AM Harsh Khandeparkar notifications@github.com
wrote:

@jywarren https://github.com/jywarren @publiclab/is-reviewers
https://github.com/orgs/publiclab/teams/is-reviewers nectarJs
https://codeburst.io/nectarjs-compiling-javascript-into-native-binaries-for-every-platform-2efb2083a4a
claims that it can compile js to native OS binaries for all platforms. This
can be used to compile the lib for CLI maybe?

NectarJs github page https://github.com/NectarJS/nectarjs webpage
https://nectar-lang.com

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-468886125,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ-kudtyWRA9nW-5Io2vxsoSk2PIIks5vSgdcgaJpZM4XXM4q
.

@jywarren in that case may I proceed with nectarJs for applying the same to our PixelManipulation.js ?

I would love to see a prototype of this in a PR, yes please!

On Mon, Mar 4, 2019 at 6:32 PM Slytherin notifications@github.com wrote:

@jywarren https://github.com/jywarren in that case may I proceed with
nectarJs for applying the same to our PixelManipulation.js ?

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-469470300,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ7PbPE_HUQ839p_uyAA93tzOY76Gks5vTazagaJpZM4XXM4q
.

Excited for this.
Thanks!

same!!!

On Mon, Mar 4, 2019 at 6:35 PM Slytherin notifications@github.com wrote:

Excited for this.
Thanks!

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-469471003,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ7BHsEFgRSJit5x80EFiOYjYEodZks5vTa2EgaJpZM4XXM4q
.

@jywarren just a note. In the NectarJs repo, there was a discussion about it not being fully open source. I don't know what it meant. I know one thing for sure and that is that the user needs to have an account on https://nectar-lang.com and should have a key to use NectarJs. Just wanted to warn everybody before using this. The dev said he wanted help from everyone to make Nectar fully open source(maybe it is already done?)

cc @Divy123

Ok! There are other ways of making wasm files listed above if we run into
trouble. Thanks!

On Tue, Mar 5, 2019, 12:17 PM Harsh Khandeparkar notifications@github.com
wrote:

@jywarren https://github.com/jywarren just a note. In the NectarJs
repo, there was a discussion about it not being fully open source. I don't
know what it meant. I know one thing for sure and that is that the user
needs to have an account on https://nectar-lang.com and should have a key
to use NectarJs. Just wanted to warn everybody before using this. The dev
said he wanted help from everyone to make Nectar fully open source(maybe it
is already done?)

cc @Divy124

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-469769521,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ5sfAnS7tiFl5vRbVTPqbul2Ph-cks5vTqaHgaJpZM4XXM4q
.

Thanks @HarshKhandeparkar .

@jywarren I looked into WASM, made these two little projects,
https://github.com/Divy123/canvas-wasmvas
https://github.com/Divy123/prime-with-wasm

I suggest we can proceed with writing native C code and compiling that with emscripten and utilizing the genrated glue JS files in our code which I feel can be quite handy.

Your opinion please!!

Ok, however did you see the library to generate wasm from JavaScript like
syntax? In either case, we should make a src/webassembly folder perhaps to
contain our source code and put the wasm files in dist, right? Thanks!!!

On Tue, Mar 12, 2019, 1:49 PM Slytherin notifications@github.com wrote:

@jywarren https://github.com/jywarren I looked into WASM, made these
two little projects,
https://github.com/Divy123/canvas-wasmvas
https://github.com/Divy123/prime-with-wasm

I suggest we can proceed with writing native C code and compiling that
with emscripten and utilizing the genrated glue JS files in our code which
I feel can be quite handy.

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-472110012,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ7HecZ8GWkdjxc5adD0tRiQmB009ks5vV-icgaJpZM4XXM4q
.

Ya I looked into but perhaps feel this can be more easy to go with as then we don't have the overhead of a library.
Yes we have to keep wasm files in src/webassembly and keep it in dist!!
What do you think?

OK, sounds good. We can always refactor to use a different wasm generator
later, so this could even be solved in parts. Best first get a
demonstration running of it working at all!

On Tue, Mar 12, 2019 at 3:04 PM Slytherin notifications@github.com wrote:

Ya I looked into but perhaps feel this can be more easy to go with as then
we don't have the overhead of a library.
Yes we have to keep wasm files in src/webassembly and keep it in dist!!
What do you think?

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-472139271,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJwXDb0z2BeSITLXSafke6Uq0qrUzks5vV_oggaJpZM4XXM4q
.

Sure !!

@jywarren just one thing that if you can suggest apart from PixelManipulation.js what are some other areas that we can apply wasm to include in our code base like can we add to different modules as well?
Thanks!!

Hi! Well, my thought was that PixelManipulation is used a LOT so if we
improve that, we'll see improvements across a lot of our codebase. And we
can start there to get a big improvement in one step, and then follow up to
see where else we could apply this. Many modules use PixelManipulation in
the same way, so it's a great leverage point to make a wide-ranging
optimization.

On Fri, Mar 22, 2019 at 5:06 PM Slytherin notifications@github.com wrote:

@jywarren https://github.com/jywarren just one thing that if you can
suggest apart from PixelManipulation.js what are some other areas that we
can apply wasm to include in our code base like can we add to different
modules as well?
Thanks!!

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-475782837,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJzbWiaoooj_YT0miRCRTiL_tRc01ks5vZUWtgaJpZM4XXM4q
.

Yes, this is absolutely true, the heavy lifting is done by pixelManipulation for almost all modules, so that should give us a significant boost in performance!

What abt gpu.js which I am trying to implement for PixelManipulation? It will also work in node and will process the pixels on gpu. Can that also be compiled to wasm? It uses a node library headless-gl(will use in the future). Currently it uses the canvas api.

Hi Harsh!
Can you explain a bit of your work here with gpu.js?

You can have a look at issue #849. Essentially it will manipulate all the pixels at the same time in parallel on a gpu.

I think we can pursue gl acceleration in a parallel track and use our new
benchmarks to compare!

On Sun, Mar 24, 2019, 3:49 AM Harsh Khandeparkar notifications@github.com
wrote:

You can have a look at issue #849
https://github.com/publiclab/image-sequencer/issues/849. Essentially it
will manipulate all the pixels at the same time in parallel on a gpu.

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400#issuecomment-475936367,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABfJ352UrS2hQaM9Ri8hD6SvhLB-99Cks5vZy3cgaJpZM4XXM4q
.

@jywarren @tech4GT I have been through PixelManipulation.js file and what I am able to understand that the whole code here can not be converted as there are lots of things like get-pixels and save-pixels that have to be passed to our C code. So can I get some help regarding exactly what parts of the code do we want to convert to C code or the whole PixelManipulation.js code?

Thanks !!

@jywarren can you please help on this?

Also noting @MargaretAN9 is interested in this!

Hmm. I think this may be a good question to ask @HarshKhandeparkar for a bit more info here. I had hoped we could take everything /between/ get-pixels and save-pixels and run that in webassembly.

Ok sure!! Thanks!

@MargaretAN9 can we collaborate on this??
Also this is my this week's target.
@HarshKhandeparkar any insights?

@jywarren this is my task for this week. So should I start working on this or wait for Harsh's reply?

If we don't get input from others in time, perhaps we could swap this
week's task with another to give people a little more time? Thanks!

On Mon, May 27, 2019 at 2:03 PM Slytherin notifications@github.com wrote:

Ok sure!! Thanks!

@MargaretAN9 https://github.com/MargaretAN9 can we collaborate on this??
Also this is my this week's target.
@HarshKhandeparkar https://github.com/HarshKhandeparkar any insights?

@jywarren https://github.com/jywarren this is my task for this week. SO
should I start working on this or wait for Harsh's reply?

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400?email_source=notifications&email_token=AAAF6J26JQATHEKNGPEV2V3PXQO6JA5CNFSM4F24ZYVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWKJNTY#issuecomment-496277199,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAF6J45ZUG2K5JD2UFNJJ3PXQO6JANCNFSM4F24ZYVA
.

@jywarren can I just send here a PR with a working demo and then proceed with everyone's suggestions. Meanwhile I can make preparations for the next weeks as well to speed up the things there??

oh that'd be great! always great to see working code to offer input on.
thank you!!!

On Tue, May 28, 2019 at 4:13 PM Slytherin notifications@github.com wrote:

@jywarren https://github.com/jywarren can I just send here a PR with a
working demo and then proceed with everyone's suggestions. Meanwhile I can
make preparations for the next weeks as well to speed up the things there??

โ€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/publiclab/image-sequencer/issues/400?email_source=notifications&email_token=AAAF6J44CEEVYPFYG7DCLHTPXWG5HA5CNFSM4F24ZYVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWNJTUY#issuecomment-496671187,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAF6JZBAPVKKH44H2VWERDPXWG5HANCNFSM4F24ZYVA
.

Thanks a lot Jeff!! :smile:

Screenshot from 2019-05-30 01-26-27
I have made a wasm file from wasm fiddle and here is my C code

int getPixels(int , int , int );

int setPixels(int, int, int, int);

int * changePixel(int, int, int, int, int, int);

void paceOp();

void consoleLog(int);

void manipulatePixel(int width, int height, int inBrowser, int test){
  consoleLog(100);
  for (int x = 0; x < width; x++) {
        for (int y = 0; y <height; y++) {
          int* pixel =changePixel(
            getPixels(x, y, 0),
            getPixels(x, y, 1),
             getPixels(x, y, 2),
             getPixels(x, y, 3),
            x,
            y
          );
          setPixels(x, y, 0, pixel[0]);
          setPixels(x, y, 1, pixel[1]);
          setPixels(x, y, 2, pixel[2]);
          setPixels(x, y, 3, pixel[3]);

          if (!inBrowser && !test) paceOp();
        }
      }
}

I was trying to convert this part of code for testing from PixelManipulation.js file


for (var x = 0; x < pixels.shape[0]; x++) {
      for (var y = 0; y < pixels.shape[1]; y++) {
       let pixel = options.changePixel(
         pixels.get(x, y, 0),
         pixels.get(x, y, 1),
          pixels.get(x, y, 2),
             pixels.get(x, y, 3),
           x,
           y
       );

        pixels.set(x, y, 0, pixel[0]);
        pixels.set(x, y, 1, pixel[1]);
          pixels.set(x, y, 2, pixel[2]);
          pixels.set(x, y, 3, pixel[3]);

          if (!options.inBrowser && !process.env.TEST) pace.op();
         }
       }

After adding the wasm file, the code looks like:

const imports = {
         env:{
           changePixel:options.changePixel,
           getPixels: pixels.get,
           setPixels: pixels.set,
           paceOp: require('pace').op,
           consoleLog:console.log // for testing 
         }
       }
      const inBrowser = (options.inBrowser)?1:0;
      const test = (process.env.TEST)?1:0
       WebAssembly.instantiateStreaming(fetch('./program.wasm'), imports)
           .then(wasm => {
      wasm.instance.exports.manipulatePixel(pixels.shape[0],pixels.shape[1],inBrowser, test)
           });

But I think the wasm file is not getting recognized, is it some bundler issue?
As of now I have kept it in src/no_module but is there something else I need to consider??
Am I required to include it in dist?If yes, then how to? I am not accustomed to it.

@jywarren @tech4GT @HarshKhandeparkar need your help here!!
Its something urgent. Please help !

Hi @Divy123 -- can you share a PR link, so we can take a look at how you've gotten it set up? Help us reproduce your error so we can help you solve it! I've also pinged folks in the weekly check-in to see if anyone there can help.

Thanks a lot @jywarren !!
Making a PR now

@jywarren here is the link:
https://github.com/publiclab/image-sequencer/pull/1093

Please look into it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blurry-x-face picture blurry-x-face  ยท  4Comments

harshkhandeparkar picture harshkhandeparkar  ยท  4Comments

harshkhandeparkar picture harshkhandeparkar  ยท  4Comments

Divy123 picture Divy123  ยท  5Comments

kindanduseful picture kindanduseful  ยท  5Comments