Skip to content

starside/FortranWebAssembly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 

Repository files navigation

Setting up the tools

Flang - The NVIDIA fortran compiler

NVIDIA provides documenation on installation. I did not want to go through the build process, so I used a docker image. I pulled the first one I found:

docker pull tdd20/flang
docker run -it tdd20/flang bash

From inside the flang image, I can compile fortran to LLVM IR, which can be compiled to Webassembly. Translating IR to webassembly requires some additional tools. Instead of hassling with installation, I used another docker image.

docker pull chrisber/llvm-webassembly
docker run -it chrisber/llvm-webassembly bash

Using the tools

I want to understand how fortran compiles to Webassembly. A trial on a hello world program compiles to form that indicates a non-trivial run time that would need to be implemented in Javascript. Since this is non-essential behavior for this project, I will do it later if needed.

To demonstrate the toolchain, I will compile the following file (call it addtwo.f90)

function func(a,b) result(j)
    implicit none
    real, intent(in) :: a,b
    real             :: j
    j = a + b
end function func
program xfunc
    implicit none
    real :: i, res, func
    i = 3.1
    res = func(i, 3.2)
end program xfunc

Use the docker image for flang and run flang -Oz -emit-llvm --target=wasm32 -c addtwo.f90 -o addtwo.bc

This compiles to llvm bytecode (bitcode?). This can be converted to something human readable using llvm's dissassembler

llvm-dis addtwo.bc

The result of dissassebly is a file called addtwo.ll, which is human readable. The .ll file can be converted to webassembly with tools included in the chrisber/llvm-webassembly docker image. Specifically, it needs a build of clang with webassembly backend support, which is not enabled ny default in llvm.

To compile the .ll file in the webassembly docker:

llc addtwo.ll

It will produce a .s file. The last step is to run s2wasm

s2wasm addtwo.s

Webassembly will be dumped to stdout. Webassembly can be compiled to a form usable by a browser by running wat2wasm. wat2wasm is not included in any of the docker images, but it is simple to build on Ubuntu.

The result of this process is

(module
(type $FUNCSIG$vii (func (param i32 i32)))
(import "env" "fort_init" (func $fort_init (param i32 i32)))
(table 0 anyfunc)
(memory $0 1)
(data (i32.const 12) "\00\00\00\00")
(export "memory" (memory $0))
(export "func_" (func $func_))
(export "MAIN_" (func $MAIN_))
(func $func_ (param $0 i32) (param $1 i32) (result f32)
(f32.add
    (f32.load
      (get_local $1)
    )
    (f32.load
      (get_local $0)
    )
  )
)
(func $MAIN_
  (call $fort_init
    (i32.const 12)
    (i32.const 0)
  )
)
)

The above code works on a pass by value basis, as expected for fortran. Similar C code will pass data directly.

Questions

Why does flang need a modded version of clang? This is worrisome

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages