WebAssembly array passing (input)

Posted by rathlon on Thu, 26 Dec 2019 18:12:22 +0100

Next, I will talk about the operation of input

Traditional law:

JS:

var ptr = Module._malloc(myTypedArray.length * myTypedArray.BYTES_PER_ELEMENT);
Module.HEAPF64.set(myTypedArray, ptr); //HEAPF64 is the storage location of double * in WebAssembly
Module.setValue(ptr * 8, myTypedArray.length); //8 for sizeof(double)

Type comparison table attached:

Memory array Corresponding type
HEAP8 char*
HEAP16 short int*
HEAP32 int*
HEAPU8 unsigned char*
HEAPU16 unsigned short int*
HEAPU32 unsigned int*
HEAPF32 float*
HEAPF64 double*

C++:

#include <emscripten/val.h>
#include <emscripten/bind.h>

using namespace std;
using namespace emscripten;

void setValue(int ptr, int len){
    double *data;
    data = (double *)ptr;
    for(int i = 0; i < len; i ++){
        cout << data[i] <<endl;
    }
}

Advantage: medium speed

Disadvantages: JS operation is required, which is troublesome

val class method:

JS:

Module.setValue(myTypedArray);

C++:

#include <emscripten/val.h>
#include <emscripten/bind.h>

using namespace std;
using namespace emscripten;

void setValue(val data){
    for(int i = 0; i < len; i ++){
        cout << data[i].as<double>() <<endl;
    }
}

val can convert js data to C + + native type through as < type > method

Advantages: js is easy to call and intuitive as a whole

Disadvantage: slowest

Return to nature:

double *getDoublePtrFrom1XArray(val arr, int *len = NULL){
	if(len == NULL) len = new int[1];
	*len = arr["length"].as<int>();
	double *ret = new double[*len];
	val module = val::global("Module");
	int ptr = (int)ret / sizeof(double);
	module["HEAPF64"].call<val>("set", arr, val(ptr));
	return ret;
}

Advantages: js is easy to call and the fastest

Disadvantages: not found yet

Another: attach the analysis of two-dimensional array

double **getDoublePtrFrom2XArray(val arr, int *y_len = NULL, int *x_len = NULL){
	if(y_len == NULL) x_len = new int[1];
	if(x_len == NULL) x_len = new int[1];
	*y_len = arr["length"].as<int>();

	val module = val::global("Module");
	int ptr;
	if(*y_len > 0){
		*x_len = arr[0]["length"].as<int>();
		double **ret = new double*[*y_len];
		for(int i = 0; i < *y_len; i ++){
			ret[i] = new double[*x_len];
			ptr = (int)ret[i] / sizeof(double);
			module["HEAPF64"].call<val>("set", arr[i], val(ptr));
		}
		return ret;
	} else {
		*x_len = 0;
		return NULL;
	}
}

 

Because there is no wasm group at present, we have built one: 866749590

You can help each other if you have problems