Porting BLAS / LAPACK to JavaScript.
CLAPACK is compiled with emscripten.
npm install emlapack
Computing all eigenvalues of a real (upper triangular) symmetric matrix A
var emlapack = require('emlapack'),
n = 5,
dsyev = emlapack.cwrap('dsyev_', null, ['number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number']),
pjobz = emlapack._malloc(1),
puplo = emlapack._malloc(1),
pn = emlapack._malloc(4),
pa = emlapack._malloc(n * n * 8),
plda = emlapack._malloc(4),
pw = emlapack._malloc(n * 8),
plwork = emlapack._malloc(4),
pinfo = emlapack._malloc(4),
pworkopt = emlapack._malloc(4);
emlapack.setValue(pjobz, 'V'.charCodeAt(0), 'i8');
emlapack.setValue(puplo, 'U'.charCodeAt(0), 'i8');
emlapack.setValue(pn, n, 'i32');
emlapack.setValue(plda, n, 'i32');
emlapack.setValue(plwork, -1, 'i32');
var a = new Float64Array(emlapack.HEAPF64.buffer, pa, n * n);
var w = new Float64Array(emlapack.HEAPF64.buffer, pw, n);
a.set([1.96, 0, 0, 0, 0, -6.49, 3.8, 0, 0, 0, -0.47, -6.39, 4.17, 0, 0, -7.2, 1.5, -1.51, 5.7, 0, -0.65, -6.34, 2.67, 1.8, -7.1]);
dsyev(pjobz, puplo, pn, pa, plda, pw, pworkopt, plwork, pinfo);
var workopt = emlapack.getValue(pworkopt, 'double'),
pwork = emlapack._malloc(workopt * 8);
emlapack.setValue(plwork, workopt, 'i32');
dsyev(pjobz, puplo, pn, pa, plda, pw, pwork, plwork, pinfo);
console.log(w);
// { '0': -11.065575263268391,
// '1': -6.22874693239854,
// '2': 0.8640279752720624,
// '3': 8.865457108365518,
// '4': 16.09483711202934 }
To build, you'll need to install and set up Emscripten, then download clapack into ./clapack
.
First, configure clapack
by creating make.inc
:
$ cd clapack
$ cp make.inc.example make.inc
Next, follow the libf2c
installation instructions. You'll need to tell it to create *.h
from *.h0
files. The easiest way is to just make all
:
$ cd F2CLIBS/libf2c
$ make all
Now from the main emlapack directory, proceed with gulp build:
$ gulp build
This should take a while. Coffee, perhaps?
You can modify src/export-functions.js with the functions you are using to reduce the bundle size significantly.
If the bundle is too large and you know the specific set of functions you would like to use, you can create a file called custom/export-functions.js
which exports the list of functions you want.
You could copy the src/export-functions.js file to the custom directory and modify it to your needs.
The custom folder also contains a export-functions.example.js
you could copy and rename to export-functions.js
and modify.
For convenience, this repo also includes a Dockerfile so you can build everything in Docker.
If you need a custom build, just add your export-functions.js
file to the custom folder and execute the scripts/docker_build.sh script. All it does is build the container and then runs it.
NOTE: Make sure you run this script in the project root directory.
./scripts/docker_build.sh
After the script completes, you will see asmjs.js
, emlapack.wasm
, and wasm.js
outputted to the root of the project directory.
For more detail, see:
© 2015 Yosuke Onoue, BSD-3-Clause.