Question

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.

Was it helpful?

Solution

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!

OTHER TIPS

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:

  1. Download the ARPACK source code.
  2. Run f2c on all of the Fortran files to convert them to C.
  3. (This might be the trickiest part): Modify the Makefiles to use Emscripten and LLVM toolchains.
  4. Make the project to produce an LLVM binary.
  5. Use Emscripten again to transpile the LLVM binary to JS.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top