将 Emscripten 与 Fortran 一起使用:LAPACK 绑定

2022-01-14 00:00:00 fortran c lapack javascript emscripten

我的目标是将 LAPACK 与 Emscripten 一起使用.

My goal is to use LAPACK with Emscripten.

我的问题是:如何将 LAPACK 移植到 JS?我能想到的方法有两种: CLAPACK to JS 我的问题是:有人知道 3.2.1 之后的非官方版本吗?而另一种思路是:如何将FORTRAN移植到JS?

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 能够将 C 代码转换为 JavaScript.但不幸的是,LAPACK 3.5.0 (http://www.netlib.org/lapack/) 仅在 FORTRAN95 中可用.

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.

CLAPACK 项目 (http://www.netlib.org/clapack/) 基本上就是我想要的:C 版本的 LAPACK.但是这个已经过时了;最新的是 3.2.1.

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 仅适用于 FORTRAN 77.LAPACK 3.5.0 是用 FORTRAN 95 编写的.

F2C only works up to FORTRAN 77. LAPACK 3.5.0 was written in FORTRAN 95.

所以我现在的问题是:为什么没有 LAPACK 到 C 的更新端口?

So my question now is: why is there no newer port of LAPACK to C?

最好的方法是直接将LAPACK的FORTRAN95代码转换成带有clang和emscripten的javascript.但我只是不知道从哪里开始.

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 目前不支持 FORTRAN.但它处理 LLVM 位码,所以使用 clang 从 FORTRAN 文件生成 LLVM bc 应该不是问题.

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

它可以用clang hello.f -o hello -lgfortran"编译得很好.我无法将其转换为有效的位码.

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

这些方法都不起作用,因为 emscripten 一直在告诉我

None of these approaches works, because emscripten keeps telling me

emcc -c hello.o -o hello.js
hello.o is not valid LLVM bitcode

我不确定这是否可能,因为 LAPACK 显然需要 libgfortran 才能工作.而且我无法将库合并到 javascript 代码中...

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...

提前致谢!

我几乎设法将 BLAS 从 LAPACK 3.5.0 转换为 JS.我用dragonegg来完成这个.

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 ...
...

从中获得 LLVM 位码后:

After gaining LLVM bitcode from that:

emcc caxpy.s.ll cgerc.s.ll cher.s.ll ... -o blas.js -s EXPORTED_FUNCTIONS="['_caxpy_', ... , '_ztpsv_']"

但是 emscripten 仍然给我留下以下错误:

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?

问题是我认为 lgfortran 是预编译的.

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

注意我之前错过的m32"标志.

Note the "m32" flag which I missed earlier.

类似警告

warning: unresolved symbol: _gfortran_st_write

可以安全地忽略.Emscripten 在 JavaScript 文件中使用此名称创建空函数,因此如果根本不调用这些函数,则没有问题.如果它们被调用,您可以轻松地将它们替换为您自己的函数;这些名称有点描述性.此外,您可以查看 libgfortran 源代码(注意它是 GPL).

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).

有了这个 Emscripten 源可以手动扩展以支持 Fortran 文件.有一天我可能会在 github 上发布这个!

With this Emscripten source can be extended by hand to support Fortran files. Someday I may publish this on github!

相关文章