My goal is to use LAPACK with Emscripten.
My question is: how to port LAPACK to JS? The are two ways I can think of: CLAPACK to JS where my question is: does anybody know an unofficial version that is later than 3.2.1? And the other way to think of is: how to port FORTRAN to JS?
Emscripten is capable of transforming C code to JavaScript. But unfortunately, LAPACK 3.5.0 (http://www.netlib.org/lapack/) is only available in FORTRAN95.
The CLAPACK project (http://www.netlib.org/clapack/) is basically what I want: a C version of LAPACK. But this one is outdated; the latest is 3.2.1.
F2C only works up to FORTRAN 77. LAPACK 3.5.0 was written in FORTRAN 95.
So my question now is: why is there no newer port of LAPACK to C?
The optimal way would be to directly transform the FORTRAN95 code of LAPACK to javascript with clang and emscripten. But I just don't know where to start.
Emscripten currently does not support FORTRAN. But it handles LLVM bitcode, so it should not be a problem to use clang to generate LLVM bc from a FORTRAN file.
For testing purpose, I have this file:
program hello
print *, "Hello World!"
end program hello
It compiles just fine with "clang hello.f -o hello -lgfortran". I am not capable of transforming this into valid bitcode.
clang -c -emit-llvm hello.f
clang -S -emit-llvm hello.f -o hello.bc -lgfortran
None of these approaches works, because emscripten keeps telling me
emcc -c hello.o -o hello.js
hello.o is not valid LLVM bitcode
I am not sure anyways if this would be even possible, because LAPACK obviously needs libgfortran to work. And I can't merge a library into javascript code...
Thanks in advance!
Edit:
I almost managed it to convert BLAS from LAPACK 3.5.0 to JS. I used dragonegg to accomplish this.
gfortran caxpy.f -flto -S -fplugin=/usr/lib/gcc/x86_64-linux-gnu/4.6/plugin/dragonegg.so
gfortran cgerc.f ...
...
After gaining LLVM bitcode from that:
emcc caxpy.s.ll cgerc.s.ll cher.s.ll ... -o blas.js -s EXPORTED_FUNCTIONS="['_caxpy_', ... , '_ztpsv_']"
But emscripten still leaves me with the following errors:
warning: unresolved symbol: _gfortran_st_write
warning: unresolved symbol: _gfortran_string_len_trim
warning: unresolved symbol: _gfortran_transfer_character_write
warning: unresolved symbol: _gfortran_transfer_integer_write
warning: unresolved symbol: _gfortran_st_write_done
warning: unresolved symbol: _gfortran_stop_string
warning: unresolved symbol: cabs
warning: unresolved symbol: cabsf
AssertionError: Did not receive forwarded data in an output - process failed?
The problem is that lgfortran is precompiled I think.
Thank you for your reply!
Indeed I did make progress on this. Finally it is working. I was very close, just follow these steps:
gfortran caxpy.f -S -flto -m32 -fplugin=dragonegg.so
mv caxpy.s caxpy.ll
llvm-as caxpy.ll -o caxpy.o
Note the "m32" flag which I missed earlier.
Warnings like
warning: unresolved symbol: _gfortran_st_write
can be ignored safely. Emscripten creates empty functions in the JavaScript file with this name so if these functions are not called at all there is no problem. If they get called you can easily substitute them with your own functions; the names are somewhat descriptive. Additionally you can have a look at the libgfortran source code (be aware it is GPL).
With this Emscripten source can be extended by hand to support Fortran files. Someday I may publish this on github!
I actually pulled this off recently (https://github.com/harveywi/arpack-js). The Github repo is mostly barren except for the output JS files, but I will be uploading source code, Makefiles, and other instructions soon. After wrangling unsuccessfully with dragonegg for a while, I found a different approach (not as great, but sufficient) which did the trick.
Here is roughly how I did it:
Download the ARPACK source code.
Run f2c on all of the Fortran files to convert them to C.
(This might be the trickiest part): Modify the Makefiles to use Emscripten and LLVM toolchains.
Make the project to produce an LLVM binary.
Use Emscripten again to transpile the LLVM binary to JS.
Related
I'm trying to build openCv.js javascript library from opencv source code at this github repository
I followed instructions at this official page
I installed cmake, python, and Emscripten.
when I run this python command :
python ./platforms/js/build_js.py build_js
I get the following error :
-- Could NOT find PythonInterp: Found unsuitable version "2.7.13", but required
is at least "3.4" (found E:/Github projects/emsdk-master/python/2.7.13.1_64bit/p
ython-2.7.13.amd64/python.exe)
-- Could NOT find PythonInterp: Found unsuitable version "2.7.13", but required
is at least "3.2" (found E:/Github projects/emsdk-master/python/2.7.13.1_64bit/p
ython-2.7.13.amd64/python.exe)
CMake Error at cmake/OpenCVCompilerOptimizations.cmake:505 (message):
Compiler doesn't support baseline optimization flags:
Call Stack (most recent call first):
cmake/OpenCVCompilerOptions.cmake:261 (ocv_compiler_optimization_options)
CMakeLists.txt:554 (include)
screenshot of the error
how can I fix this error and build opencv.js ?
You need to update python version to be at least 3.4
Looking at the following WasmFiddle, once compiled to wasm the file is 259bytes. I'm trying to from WasmFiddle move to my local environment, so i've downloaded and installed the Emscripten compiler.
Now, since the Emscripten environment adds extra features same code is 22KB.
Q: How can I compile the c code on my local machine, and keep it lean?
Even better how can I have the same output as the WasmFiddle?
You can see the sourcecode for the server-side component that WasmFiddle uses for compilation here:
https://github.com/wasdk/wasmexplorer-service/blob/master/scripts/compile.sh
It is very similar to c2wasm, which also provides a minimal output:
https://github.com/tpimh/wasm-toolchain
A couple options using Emscripten's emcc can keep your outputted wasm file lean.
Optimization:
-Oz
Only my code (removes Emscripten framework code):
-s ONLY_MY_CODE=1
These flags should bring you very close to your desired 259 bytes.
I'm using Browserify to transpile my JS code to be sure the final code is compatible with most browsers, and all is working perfectly with Chrome and Firefox.
But I'm using a package (dot-prop) that IE11 does not seem to like due to the name of some functions like get in get(obj, path, value) (https://github.com/sindresorhus/dot-prop/blob/master/index.js) and generate the classic error:
SCRIPT 1028 Expected identifier, string or number
Yet I'm using a whole bunch of transpilation tools:
browserify --extension=.jsx --transform [babelify --presets=es2015,stage-2,react --plugins=[babel-plugin-transform-es3-member-expression-literals,babel-plugin-transform-es3-property-literals]] --transform [es3ify] GUI/index.jsx --outfile dist/GUI/bundle.js
But as far as I understand the tools consider the code as valid, which it is for most browsers indeed.
I'm probably missing a transpilation component who might transform the get(...) in something like "get": function(...).
Am I missing something?
If the issue is real, can it be fixed with such a component?
Or should I fix the code myself, and if so what is the best way of doing so?
The issue was more subtle: as dot-prop is a dependency stored in node_modules by default it is ignored by Browserify hence not passed to Babel through Babelify for transpilation.
Until I find a clean way of asking Browerify to handle only this dependency I've found a simple workaround: pre-generating a transpiled version of the dependency.
I have a dedicated NPM script in my package.json:
"scripts": {
"precompile": "babel node_modules/dot-prop/index.js --out-file precompiled/dot-prop.js",
And I reference the resulting transpiled module in place of the original one.
e.g. in someModule.js:
const dotProp = require("../precompiled/dot-prop");
Hopefully it will help someone else. :-)
I am trying to compile the BPG decoder in order to get a Javascript equivalent (yes, I know one is already provided by the author); this is done via Emscripten. Unfortunately, I get the following error:
emcc -Os -Wall -MMD -fno-asynchronous-unwind-tables -fdata-sections -ffunction-sections -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -I. -DCONFIG_BPG_VERSION=\"0.9.5\" -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DHAVE_AV_CONFIG_H -std=c99 -D_GNU_SOURCE=1 -DUSE_VAR_BIT_DEPTH -c -o libavutil/buffer.js.o libavutil/buffer.c
In file included from libavutil/buffer.c:22:
In file included from libavutil/atomic.h:29:
libavutil/atomic_gcc.h:54:12: error: cannot compile this atomic library call yet
return __atomic_add_fetch(ptr, inc, __ATOMIC_SEQ_CST);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
ERROR root: compiler frontend failed to generate LLVM bitcode, halting
Makefile:202: recipe for target 'libavutil/buffer.js.o' failed
make: *** [libavutil/buffer.js.o] Error 1
Any ideas on how to solve it?
The issue was caused by the Emscripten compiler that comes with Ubuntu 14.10; I've upgraded and everything works now:
$ ./emcc -v
emcc (Emscripten GCC-like replacement + linker emulating GNU ld ) 1.29.0
clang version 3.4
A side note here is that I also needed a newer version of libpng.
The build instructions of V8 JavaScript Engine mention only Visual Studio 2005 and 2008. Has anybody been successful with MinGW on Windows XP/Vista?
You just need to change Scons a bit.
Take a look at C:\YourPythonFolder\Lib\site-packages\scons-YourSconsVersion\SCons\Script__ init__.py and go to line 560.
Change the linker to gnulink, the c compiler to mingw and the c++ compiler to g++.
Eventually it should look like this:
linkers = ['gnulink', 'mslink', 'ilink', 'linkloc', 'ilink32' ]
c_compilers = ['mingw', 'msvc', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++', 'bcc32' ]
Now MingW is activated by default :)
There is a patch for MinGW support: http://codereview.chromium.org/18309
See also:
http://code.google.com/p/v8/issues/detail?id=64
I've tried, but seems it automatically detect the WIN32 platform and tries to invoke the vc++ compiler, I tried to adding to the PATH the mingw-gcc compiler (I've not vc++ installed) and the build script correctly sees it, but doesn't compile out of the box.
I suppose deleting the "WIN32 flag" will do the work, since for successfully compiling under mingw the compiler needs to thinks to be on unix enviroment, but then even if it compiles probably it will have some problems due to the different platform.
V8 seems to use different parts of its code (especialy for the file system stuff) for different platforms.
I made a build under Cygwin which puts out a beautiful linux lib, which runs on linux but doesn't on Win. I think partwise this will be the same with MinGW if you erase the WIN32 flag!
At the moment I just can see 2 possibilities. One is simple: Use Visual Studio, it's free.
The second is very hard: write a makefile :)