6

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.

japedo
  • 368
  • 3
  • 15
  • CLAPACK says _"f2c'ed version of LAPACK_" in the title. I haven't tried this, but why don't you run `f2c` on LPACK 3.5.0? – Carsten Feb 24 '14 at 14:16
  • 1
    You write *So my question now is: why is there no newer port of LAPACK to C?* but that is not, any longer, your question. That line is a hang over from your earlier version of your question and has already been answered. I can't see, anywhere in this version of your question, the statement that `f2c` only works up to FORTRAN77; your response to @Carsten's comment was a bit snippy. – High Performance Mark Feb 24 '14 at 14:40
  • 1
    You are right. I did not mention that again, that is a copy and paste error from the previous question. Sorry Carsten ;) 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? – japedo Feb 24 '14 at 14:56
  • I'm wondering, what you final goal is. Do you want to write a numbercrunching app in JS? Sounds like a bad idea to me... – Stefan Feb 24 '14 at 17:53
  • I wanted to port a project to JS which makes heavy use of LAPACK at its lowest level. Otherwise I would agree with you! – japedo Feb 24 '14 at 20:06
  • 1
    Did you make progress on this? Did you see this github project for getting the sources to gfortran and compiling it. https://github.com/alexleach/gfortran-mlion. There is a SO thread discussing this here: http://stackoverflow.com/questions/12316780/how-to-compile-distributable-fortran-binaries-on-mac-os-x-mountain-lion – Trausti Kristjansson Apr 23 '14 at 01:29
  • we're having a discussion about this kind of stuff here: https://github.com/node-forward/discussions/issues/1 would love your input :) – mikeal Aug 13 '14 at 19:03
  • I am using kind of a "hackish" solution now. Please follow this thread https://github.com/kripken/emscripten/issues/998 on github. This is not really a satisfying solution but I don't have the time to work on this. Nevertheless this could be a good starting point for anyone trying to get it finally working :) – japedo Sep 02 '14 at 07:22
  • @japedo - did you manage to get ahead on this ? I'm really looking forward to some of this. – Sandeep Jan 16 '16 at 12:37
  • I am not responsible anymore for that project, so I did not try to fix this in a cleaner way. Anyway it should still be easily possible to implement this patch (https://github.com/kripken/emscripten/issues/998). – japedo Jan 17 '16 at 14:12

2 Answers2

5

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!

japedo
  • 368
  • 3
  • 15
  • How do you convert your bitcode into javascript? Thanks! Which emscripten command can do this? – user2407014 May 13 '14 at 15:00
  • I don't know if this is possible with an emscripten command. Internally it's done via >> shared.Building.llvm_as(fortran_llvm, output_file) # create .o file from .ll See: https://github.com/kripken/emscripten/issues/998 for a complete example – japedo Sep 02 '14 at 07:16
  • @japedo is there any chance you can put your code on github ? – Sandeep Jan 16 '16 at 13:28
2

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.
William Harvey
  • 371
  • 3
  • 4
  • The problem is that the question is about LAPACK 3.5. This new version is not compilable by f2c. I don't think anyone has problems with code that works with f2c because you can than use all you use normally for C codes. Quote from the question: *"F2C only works up to FORTRAN 77. LAPACK 3.5.0 was written in FORTRAN 95."* – Vladimir F Героям слава Nov 07 '15 at 13:57
  • 1
    @william - are you planning to take this project further. this is so cool that you should really build this out. For example if you could integrate one or two functions of lodash to leverage ARPACK directly... that would be huge! – Sandeep Jan 16 '16 at 12:13