JuliaGPU / JuliaGPU/GPUCompiler.jl
Julia does not support cross-compilation to 32-bits
- Dominant language
- Julia
- Stars
- 187
- Forks
- 68
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 28
Description
I'm trying to work out some kinks in the WebAssembly support in StaticCompiler. The main issue is addressing nested structs when I'm compiling on a 64-bit version of Julia. Here's an example that illustrates the problem:
```jl
# adapted from https://github.com/Alexander-Barth/FluidSimDemo-WebAssembly/blob/main/wasm_target.jl
# adapted from https://seelengrab.github.io/articles/Running%20Julia%20baremetal%20on%20an%20Arduino/
using GPUCompiler
struct WASMTarget <: GPUCompiler.AbstractCompilerTarget end
# GPUCompiler.llvm_triple(::WASMTarget) = "x86_64-pc-linux-gnu" # works
# GPUCompiler.llvm_triple(::WASMTarget) = "i686-pc-linux-gnu" # broken
GPUCompiler.llvm_triple(::WASMTarget) = "wasm32-unknown-unknown" # broken
GPUCompiler.runtime_slug(::GPUCompiler.CompilerJob{WASMTarget}) = "wasm-test"
struct WASMTargetParams <: GPUCompiler.AbstractCompilerParams end
module StaticRuntime
# the runtime library
signal_exception() = return
malloc(sz) = C_NULL
report_oom(sz) = return
report_exception(ex) = return
report_exception_name(ex) = return
report_exception_frame(idx, func, file, line) = return
end
GPUCompiler.runtime_module(::GPUCompiler.CompilerJob{<:Any,WASMTargetParams}) = StaticRuntime
GPUCompiler.runtime_module(::GPUCompiler.CompilerJob{WASMTarget}) = StaticRuntime
GPUCompiler.runtime_module(::GPUCompiler.CompilerJob{WASMTarget,WASMTargetParams}) = StaticRuntime
function wasm_job(@nospecialize(func), @nospecialize(types))
source = methodinstance(typeof(func), types)
target = WASMTarget()
params = WASMTargetParams()
config = GPUCompiler.CompilerConfig(target, params, name = string(func), kernel = false)
job = GPUCompiler.CompilerJob(source, config)
end
struct W{X,Y,Z}
x::X
y::Y
z::Z
end
w = W(W([10.0:-1:1;], [1.0:10;], 1.0), 1.0, 2.0)
WT = typeof(w)
f_y(w) = @inbounds w.x.y[1]
job = wasm_job(f_y, Base.to_tuple_type((WT,)))
GPUCompiler.code_llvm(job, dump_module = true)
```
Here's the result of that.
```llvm
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:10:11:12:13"
target triple = "wasm32-unknown-unknown"
; @ /home/tshort/wasm/wasm-mwe.jl:52 within `f_y`
define double @f_y({ { {}*, {}*, double }, double, double }* nocapture noundef nonnull readonly align 8 dereferenceable(40) %0) local_unnamed_addr #0 {
top:
; ┌ @ Base.jl:37 within `getproperty`
%1 = getelementptr inbounds { { {}*, {}*, double }, double, double }, { { {}*, {}*, double }, double, double }* %0, i32 0, i32 0, i32 2
%2 = bitcast double* %1 to double***
%3 = load atomic double**, double*** %2 unordered, align 8
; └
; ┌ @ essentials.jl:13 within `getindex`
%4 = load double*, double** %3, align 8
%5 = load double, double* %4, align 8
; └
ret double %5
}
```
The problem is the `getelementptr` line. At the end, there is a ` i32 2`. It should be a 1 instead of a 2 because it should be pointing at the second component of the nested struct using zero-based indexing.
I've tried some variations:
* It works fine when run in a 32-bit version of Julia.
* It works fine when I change the target to a 64-bit target. (And, it even works to compile that to WebAssembly.)
* In works fine if all three components of the first nested struct are arrays. It's only when the last one is a scalar that I get the error.
Anyone have hints or suggestions on how to track down the issue or correct an error in this?
Contributor guide
No contributing guide indexed for this repository
Research direction
Run the provided Julia reproducer and compare the LLVM IR for the 64-bit, i686, and wasm32 targets. Start with GPUCompiler.llvm_triple, wasm_job, and GPUCompiler.code_llvm, then trace the generated getelementptr for f_y. Done means the nested struct uses the correct zero-based field index and the reproducer produces correct output for the affected target.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia, wasm
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100