tshort / StaticCompiler.jl

Compiles Julia code to a standalone library (experimental)
Other
498 stars 30 forks source link

Allow compilation to other target triples #109

Closed tshort closed 1 year ago

tshort commented 1 year ago

This would be handy for cross compilation and things like @Alexander-Barth's compilation to WebAssembly and @seelengrab's compilation to an Arduino.

tshort commented 1 year ago

I'm trying this lin:

x, obj_path = StaticCompiler.generate_obj(sin, Tuple{Float64}, true, tempname(); target = (triple = "wasm32-unknown-wasi", cpu = "wasm?", features = ""))

I'm getting a failure because it can't find the triple above in GPUCompiler.llvm_machine and LLVM.Target. I think Julia comes with WebAssembly compilation built in, so I'm confused here.

MasonProtter commented 1 year ago

It’s been a little while, but IIRC Julia’s default LLVM that it uses has had the cross compilation stuff stripped out of it to make it lighter. I think you’d need a version of julia with was built with cross compilation support

tshort commented 1 year ago

Hmm. The julia v1.8.5 that I'm using will run the WebAssembly compilation in the link above. The main difference that I see is that Alexander's code doesn't call GPUCompiler.llvm_machine. I think we do here to control the optimization.

Seelengrab commented 1 year ago

The LLVM julia ships currently builds/has these backends available:

https://github.com/JuliaLang/julia/blob/master/deps/llvm.mk#L67

So webassembly should (theoretically) work. The question is what error you get in particular, and if that is potentially due to error checking. sin can throw a DomainError at runtime after all, which any kind of statically compiled code really doesn't like.

It’s been a little while, but IIRC Julia’s default LLVM that it uses has had the cross compilation stuff stripped out of it to make it lighter.

There's nothing explicitly required for cross compilation support from LLVM - it's just providing an LLVM module targetting a given architecture that's supported by one of the backends LLVM has available. The problems you do encounter are mostly from mismatches between what julia codegen (i.e. the stuff that generates LLVM IR we pass to LLVM) expects to run on and what the target architecture actually requires (so stuff like pointersizes, not having a runtime etc.)

Seelengrab commented 1 year ago

One possibility - the original WASM example assumes that you run on 32 bit julia, so perhaps you want that or need to switch to a wasm64 target? https://github.com/Alexander-Barth/FluidSimDemo-WebAssembly/blob/858dd44fc541376ef5246eb4a7773fe967892a6e/test_fluid_sim.jl#L7

Alexander-Barth commented 1 year ago

Indeed, I had a lot of issues trying to use julia 64-bit. I was also not able to output wasm64 either (but did not tried too hard as the 32-bit version worked).

Alexander-Barth commented 1 year ago

architecture actually requires (so stuff like pointersizes, not having a runtime etc.)

For my case, the linker indeed required to have a memset function which is luckily simple enough to find a simple C implementation that can be compiled to WASM via clang.

tshort commented 1 year ago

My problem with missing targets was because we were trying to access the target before LLVM was fully initialized. We need to hit this initialization code (InitializeAllTargets(), ...). It was an easy fix to rearrange our code.

tshort commented 1 year ago

I think this is okay to go. The failing test also fails on master (#110 and #111).