JuliaGPU / JuliaGPU/GPUCompiler.jl

Julia does not support cross-compilation to 32-bits

Open
#486 5 comments 1 reaction 0 assignees View on GitHub
upstream
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.