Add imaging_mode support (static compilation)
Requires https://github.com/JuliaLang/julia/pull/38642
We can tell Julia that we want it to emit symbols instead of session-specific pointers, making our code (potentially) relocatable. I'm not locked in on this API, but it was pretty easy to implement. Known issues include Symbols embedded in the IR; they show up as {}* null in the LLVM IR for some reason. I've tested that I can roundtrip very simple functions (including closures) through codegen(:obj, ...)+dlopen/dlsym.
Codecov Report
Merging #125 (b2524b5) into master (2c4a304) will decrease coverage by
8.15%. The diff coverage is20.00%.
:exclamation: Current head b2524b5 differs from pull request most recent head 4b3cf11. Consider uploading reports for the commit 4b3cf11 to get more accurate results
@@ Coverage Diff @@
## master #125 +/- ##
==========================================
- Coverage 79.79% 71.63% -8.16%
==========================================
Files 22 22
Lines 1628 1590 -38
==========================================
- Hits 1299 1139 -160
- Misses 329 451 +122
| Impacted Files | Coverage Δ | |
|---|---|---|
| src/jlgen.jl | 78.57% <ø> (+8.89%) |
:arrow_up: |
| src/native.jl | 0.00% <0.00%> (-100.00%) |
:arrow_down: |
| src/interface.jl | 51.11% <100.00%> (-26.86%) |
:arrow_down: |
| src/bpf.jl | 0.00% <0.00%> (-92.86%) |
:arrow_down: |
| src/gcn.jl | 0.00% <0.00%> (-67.68%) |
:arrow_down: |
| src/validation.jl | 56.11% <0.00%> (-40.69%) |
:arrow_down: |
| src/error.jl | 4.34% <0.00%> (-26.09%) |
:arrow_down: |
| src/GPUCompiler.jl | 81.81% <0.00%> (-18.19%) |
:arrow_down: |
| ... and 13 more |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update 2c4a304...4b3cf11. Read the comment docs.
Base PR has been merged; needs an update here?
Yes indeed! How do you feel about me having the extra field in FunctionSpec? Do you want me to remove this functionality from all except the Native backend for now?
I'm not sure. It's not really a property of the source function, is it? Maybe an extern_policy(::CompilerJob) interface? Aren't the Julia compiler policy (wether to emit symbols or pointers) and the code relocation models two different (if not related) aspects too?
I'm not sure. It's not really a property of the source function, is it? Maybe an extern_policy(::CompilerJob) interface?
~The reason I shoved static into FunctionSpec is that I assume that imaging mode for GPUCompiler could break some functionality, so I didn't want it enabled globally for any backend until I was sure it worked "perfectly".~ Nevermind, I misread your comment. Yes, that makes sense to me!
Aren't the Julia compiler policy (wether to emit symbols or pointers) and the code relocation models two different (if not related) aspects too?
I combined these under the assumption that if you're emitting symbols, you probably want to be able to emit relocatable code for shared libraries (since we can actually do that now!). If you want them to be split concepts, how should reloc be specified to llvm_machine?
I setup a few tests, although they won't get run unless you have a recent enough build of Julia. Some of them are skipped because they don't yet work with imaging mode (probably either bugs or missing functionality in Julia), but they should work eventually.
Some of them are skipped because they don't yet work with imaging mode (probably either bugs or missing functionality in Julia), but they should work eventually.
Better make those a @test_broken then so that we get informed when they start passing?
I combined these under the assumption that if you're emitting symbols, you probably want to be able to emit relocatable code for shared libraries (since we can actually do that now!). If you want them to be split concepts, how should
relocbe specified tollvm_machine?
Yeah I'm not sure, feel free to keep both aspects linked for now, it's not like GPUCompiler.jl has a stable API or anything :slightly_smiling_face:
Better make those a @test_broken then so that we get informed when they start passing?
Unfortunately, the thing that's broken is that the IR gets generated just slightly wrong, so we just get a segfault :slightly_smiling_face:
Yeah I'm not sure, feel free to keep both aspects linked for now, it's not like GPUCompiler.jl has a stable API or anything slightly_smiling_face
I definitely can separate them in the future, when users end up requesting the ability to differentiate.
Added an extern flag to the Native target which determines the policy, and left reloc to do exactly what it says.
Should I gate Julia global externalization/internalization behind an interface function, or are we okay with keeping it as always-on?
Should I gate Julia global externalization/internalization behind an interface function, or are we okay with keeping it as always-on?
Do we emit such globals in other scenarios? We're starting to have a lot of interface functions...
@jpsamaroo what was the state of this, I'm thinking of rebasing it since it's the most common error we are hitting right now.
Aside from this not actually switching on imaging mode (as I pointed out on Slack), I think this mostly was working.
I think the issue that this is has is that it doesn't do the processing of the global variables. So you end up with uninitialized GVs and no way to know what's supposed to go in there?
Even without global variables, seems like this could be useful for StaticCompiler if it lets us use more of libjulia!