Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ABI handling for more than just specptr/jfptr #536

Open
vchuravy opened this issue Dec 15, 2023 · 0 comments
Open

ABI handling for more than just specptr/jfptr #536

vchuravy opened this issue Dec 15, 2023 · 0 comments

Comments

@vchuravy
Copy link
Member

Due to its heritage GPUCompiler currently only handles specptr and more recently jfptr.

In EnzymeAD/Enzyme.jl#1134 Enzyme is encountering a expectation mismatch. Esentially we ask GPUCompiler to produce a function with specptr ABI and receive a function with ABI japi

using Statistics

function f(temp)
     R_inv = [temp 0. 0. 0. 0. 0.; 
         0. temp 0. 0. 0. 0.; 
         0. 0. temp 0. 0. 0.; 
         0. 0. 0. temp 0. 0.; 
         0. 0. 0. 0. temp 0.; 
     ]

     return R_inv[1,1]
end

To exemplify the issue on 1.10-rc2 hvcat contains an invoke call. So trying to codegen the f function using GPUCompiler yields:

define double @julia_f_340(double %0) local_unnamed_addr {
....
   %47 = call nonnull {}* @ijl_invoke({}* inttoptr (i64 140379636017936 to {}*), {}** nonnull %.sub, i32 31, {}* inttoptr (i64 140379798006736 to {}*))
....

Enzyme then goes and extracts the method instance of the call target (Enzyme free reproducer below) and GPUCompiler produces a

;  @ abstractarray.jl:2114 within `hvcat`
define nonnull {}* @japi1_hvcat_800({}* %function, {}** noalias nocapture noundef readonly %args, i32 %nargs) local_unnamed_addr {

Enzyme most likely will need to handle the multiple ABI's, but I would prefer if there was a better way than just matching the name of the function. Julia internally has the calling convention during codegen and we may be able to put that in meta?

cc: @gbaraldi @wsmoses

Enzyme free reproducer

``` using GPUCompiler using Statistics

function f(temp)
R_inv = [temp 0. 0. 0. 0. 0.;
0. temp 0. 0. 0. 0.;
0. 0. temp 0. 0. 0.;
0. 0. 0. temp 0. 0.;
0. 0. 0. 0. temp 0.;
]

 return R_inv[1,1]

end

module Native
using GPUCompiler
using ReTestItems
setup = include(joinpath(dirname(pathof(GPUCompiler)), "..", "test", "native_testsetup.jl"))
cd(dirname(setup.file)) do
eval(setup.code)
end
end
asm = sprint(io->Native.code_llvm(io, f, (Float64,)))

r_invoke = r"@ijl_invoke({}* inttoptr (i64 (\d*) to {}*), {}** nonnull %.sub, i32 31, {}* inttoptr (i64 (\d*) to {}*))"
m = match(r_invoke, asm)

F = Base.unsafe_pointer_to_objref(Base.reinterpret(Ptr{Cvoid}, parse(UInt, m.captures[1])))
mi = Base.unsafe_pointer_to_objref(Base.reinterpret(Ptr{Cvoid}, parse(UInt, m.captures[2])))

target = Native.NativeCompilerTarget()
params = Native.CompilerParams(false, Native.test_method_table)
config = GPUCompiler.CompilerConfig(target, params; kernel=false, entry_abi=:specfunc, always_inline=false)
job = GPUCompiler.CompilerJob(mi, config)
GPUCompiler.code_llvm(job)

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant