PackageCompiler.jl icon indicating copy to clipboard operation
PackageCompiler.jl copied to clipboard

Compiling Float16 code is broken

Open maleadt opened this issue 2 years ago • 3 comments

Given the following module:

module MyApp

function julia_main()::Cint
    try
        real_main()
    catch
        Base.invokelatest(Base.display_error, Base.catch_stack())
        return 1
    end
    return 0
end

function real_main()
    x = rand(Float32)
    f(x) = ccall("extern __gnu_f2h_ieee", llvmcall, Float16, (Float32,), x)
    @show f(x)
    return
end

if abspath(PROGRAM_FILE) == @__FILE__
    real_main()
end


end # module

Invoking directly works:

❯ jl --project=MyApp MyApp/src/MyApp.jl
f(x) = Float16(0.25)

Compiling doesn't:

julia> create_app("MyApp", "MyAppCompiled")
❯ ./MyAppCompiled/bin/MyApp
ERROR: could not load library "/home/tim/Julia/tmp/PackageCompiler.jl/examples/MyAppCompiled/lib/julia/sys.so"
/home/tim/Julia/tmp/PackageCompiler.jl/examples/MyAppCompiled/lib/julia/sys.so: undefined symbol: __gnu_f2h_ieee

I'm guessing this is because the __gnu_f2h_ieee -> julia__gnu_f2h_ieee mangling (either https://github.com/JuliaLang/julia/blob/0f269668c468ff6a2876221cdb21dfd78defb68c/src/jitlayers.cpp#L1408-L1414 or https://github.com/JuliaLang/julia/blob/0f269668c468ff6a2876221cdb21dfd78defb68c/src/aotcompile.cpp#L1017-L1030) isn't triggered by PackageCompiler.

cc @vchuravy

maleadt avatar Jun 15 '23 08:06 maleadt

Workaround: add the following definition to embedding_wrapper.c (when using create_app as I did above) or to julia_init.c (when using create_library):

extern uint16_t __gnu_f2h_ieee(float param);
JL_DLLEXPORT uint16_t __gnu_f2h_ieee(float param)
{
    return julia__gnu_f2h_ieee(param);
}

When invoking create_sysimage directly, I guess this should be written to a file based on julia_init.c and passed as julia_init_c_file?

It's also probably good to add the other aliases as well, so:

extern float julia__gnu_h2f_ieee(uint16_t param);
extern float __gnu_h2f_ieee(uint16_t param) {
    return julia__gnu_h2f_ieee(param);
}

extern uint16_t julia__gnu_f2h_ieee(float param);
extern uint16_t __gnu_f2h_ieee(float param) {
    return julia__gnu_f2h_ieee(param);
}

extern uint16_t julia__truncdfhf2(double param);
extern uint16_t __truncdfhf2(double param) {
    return julia__truncdfhf2(param);
}

maleadt avatar Jun 15 '23 08:06 maleadt

@maleadt Do you think these changes are just workarounds and the proper fix should happen elsewhere or do you think these changes should just be added here?

andreasnoack avatar Jun 15 '23 09:06 andreasnoack

There should probably be a proper fix so that Julia's mangling changes are applied to the code PackageCompiler saves. This is just a workaround to get your application working again. If a proper fix is impossible, I guess this could be put in a separate object file that's linked with every sysimage/library/app, but that would require maintaining a list of aliases in both places, and is not ideal.

maleadt avatar Jun 15 '23 09:06 maleadt