JuliaGPU / JuliaGPU/GPUCompiler.jl

Compilation error with `always_inline=true` with conversions within broadcasts

Open
#689 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
187
Forks
68
Avg merge
1d 12h
Merged PRs (30d)
28

Description

Here is a reproducer for [this CUDA.jl issue](https://github.com/JuliaGPU/CUDA.jl/issues/2722), but with the native backend and Julia 1.11.4.

The setup code for native compilation (same as within "test/helpers/native.jl"):
```julia
using GPUCompiler

Base.Experimental.@MethodTable(test_method_table)

struct CompilerParams <: GPUCompiler.AbstractCompilerParams
entry_safepoint::Bool
method_table

CompilerParams(entry_safepoint::Bool=false, method_table=test_method_table) =
new(entry_safepoint, method_table)
end

NativeCompilerJob = GPUCompiler.CompilerJob{GPUCompiler.NativeCompilerTarget, CompilerParams}

module TestRuntime
# dummy methods
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(::NativeCompilerJob) = TestRuntime
GPUCompiler.method_table(@nospecialize(job::NativeCompilerJob)) = job.config.params.method_table
GPUCompiler.can_safepoint(@nospecialize(job::NativeCompilerJob)) = job.config.params.entry_safepoint

function create_job(@nospecialize(func), @nospecialize(types);
entry_safepoint::Bool=false, method_table=test_method_table, kwargs...)
config_kwargs, kwargs = split_kwargs(kwargs, GPUCompiler.CONFIG_KWARGS)
source = methodinstance(typeof(func), Base.to_tuple_type(types), Base.get_world_counter())
target = NativeCompilerTarget()
params = CompilerParams(entry_safepoint, method_table)
config = CompilerConfig(target, params; kernel=false, config_kwargs...)
CompilerJob(source, config)
end

function compiler(job)
JuliaContext() do ctx
GPUCompiler.compile(:asm, job)
end
end
```

The actual reproducer:
```julia
using UnsafePointers

function mul_bcast(I, i, x, y, d)
(x[i], y[i]) = I .* d
return nothing
end

x_cpu = zeros(Int64, 100)
y_cpu = zeros(Int64, 100)

x_cpu_ptr = UnsafePtr(x_cpu)
y_cpu_ptr = UnsafePtr(y_cpu)

d = (rand(Float64), rand(Float64))

no_conv_args_types = Base.typesof((1.0, 1.0), 1, x_cpu_ptr, y_cpu_ptr, d)
conv_args_types = Base.typesof((1, 1), 1, x_cpu_ptr, y_cpu_ptr, d) # will convert `(1, 1)` within the broadcast to `NTuple{2, Float64}`

# This compiles fine
compiler(create_job(mul_bcast, no_conv_args_types; always_inline=false));
compiler(create_job(mul_bcast, no_conv_args_types; always_inline=true));
compiler(create_job(mul_bcast, conv_args_types; always_inline=false));

# This fails
compiler(create_job(mul_bcast, conv_args_types; always_inline=true));
```

Error stacktrace

```julia
ERROR: InvalidIRError: compiling MethodInstance for mul_bcast(::Tuple{Int64, Int64}, ::Int64, ::UnsafePtr{Int64}, ::UnsafePtr{Int64}, ::Tuple{Float64, Float64}) resulted in invalid LLVM IR
Reason: unsupported dynamic function invocation (call to getindex(t::Tuple, i::Int64) @ Base tuple.jl:31)
Stacktrace:
[1] _getindex
@ ./broadcast.jl:674
[2] _broadcast_getindex
@ ./broadcast.jl:650
[3] #17
@ ./broadcast.jl:1102
[4] ntuple
@ ./ntuple.jl:49
[5] copy
@ ./broadcast.jl:1102
[6] materialize
@ ./broadcast.jl:872
[7] mul_bcast
@ ./REPL[76]:2
```


Note that I tried it out with Julia 1.12.0-beta1, but I got the same issue as in #687, so I could not tell if the bug is still there.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the native compilation setup in test/helpers/native.jl and reproduce the four compiler calls using Julia 1.11.4. Trace the failing path through broadcast.jl and the always_inline configuration; done means the conversion-containing broadcast compiles without InvalidIRError.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.