Skip to content

Commit

Permalink
Update for GPUCompiler v0.21 (#136)
Browse files Browse the repository at this point in the history
Co-authored-by: C. Brenhin Keller <[email protected]>
  • Loading branch information
tshort and brenhinkeller authored Jun 27, 2023
1 parent 5422601 commit f552ce0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 48 deletions.
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "StaticCompiler"
uuid = "81625895-6c0f-48fc-b932-11a18313743c"
authors = ["Tom Short and contributors"]
version = "0.5.2"
version = "0.5.3"

[deps]
Clang_jll = "0ee61d77-7f21-5576-8119-9fcc46b10100"
Expand All @@ -17,11 +17,11 @@ StaticTools = "86c06d3c-3f03-46de-9781-57580aa96d0a"

[compat]
CodeInfoTools = "0.3"
GPUCompiler = "0.19, 0.20"
LLVM = "5"
GPUCompiler = "0.21"
LLVM = "6"
MacroTools = "0.5"
StaticTools = "0.8"
julia = "1.8"
julia = "1.8, 1.9"

[extras]
Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0"
Expand Down
49 changes: 25 additions & 24 deletions src/StaticCompiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -168,32 +168,33 @@ function generate_obj_for_compile(f, tt, external = true, path::String = tempnam
config = GPUCompiler.CompilerConfig(NativeCompilerTarget(target...), params, name = name, kernel = false)
job = GPUCompiler.CompilerJob(GPUCompiler.methodinstance(typeof(f), tt), config)

mod, meta = GPUCompiler.JuliaContext() do context
GPUCompiler.codegen(:llvm, job; strip=strip_llvm, only_entry=false, validate=false, optimize=false, ctx=context)
table = GPUCompiler.JuliaContext() do context
mod, meta = GPUCompiler.codegen(:llvm, job; strip=strip_llvm, only_entry=false, validate=false, optimize=false)
# Use Enzyme's annotation and optimization pipeline
annotate!(mod)
tm = GPUCompiler.llvm_machine(external ? ExternalNativeCompilerTarget(target...) : NativeCompilerTarget(target...))
optimize!(mod, tm)

# Scoop up all the pointers in the optimized module, and replace them with unitialized global variables.
# `table` is a dictionary where the keys are julia objects that are needed by the function, and the values
# of the dictionary are the names of their associated LLVM GlobalVariable names.
table = relocation_table!(mod)

# Now that we've removed all the pointers from the code, we can (hopefully) safely lower all the instrinsics
# (again, using Enzyme's pipeline)
post_optimize!(mod, tm; remove_julia_addrspaces)

# Make sure we didn't make any glaring errors
LLVM.verify(mod)
obj, _ = GPUCompiler.emit_asm(job, mod; strip=strip_asm, validate=false, format=LLVM.API.LLVMObjectFile)
# Compile the LLVM module to native code and save it to disk
open(obj_path, "w") do io
write(io, obj)
end
table
end

# Use Enzyme's annotation and optimization pipeline
annotate!(mod)
tm = GPUCompiler.llvm_machine(external ? ExternalNativeCompilerTarget(target...) : NativeCompilerTarget(target...))
optimize!(mod, tm)

# Scoop up all the pointers in the optimized module, and replace them with unitialized global variables.
# `table` is a dictionary where the keys are julia objects that are needed by the function, and the values
# of the dictionary are the names of their associated LLVM GlobalVariable names.
table = relocation_table!(mod)

# Now that we've removed all the pointers from the code, we can (hopefully) safely lower all the instrinsics
# (again, using Enzyme's pipeline)
post_optimize!(mod, tm; remove_julia_addrspaces)

# Make sure we didn't make any glaring errors
LLVM.verify(mod)

# Compile the LLVM module to native code and save it to disk
obj, _ = GPUCompiler.emit_asm(job, mod; strip=strip_asm, validate=false, format=LLVM.API.LLVMObjectFile)
open(obj_path, "w") do io
write(io, obj)
end
path, name, table
end

Expand Down Expand Up @@ -586,7 +587,7 @@ function native_llvm_module(f, tt, name=fix_name(f); demangle, kwargs...)
end
job, kwargs = native_job(f, tt, true; name, kwargs...)
m, _ = GPUCompiler.JuliaContext() do context
GPUCompiler.codegen(:llvm, job; strip=true, only_entry=false, validate=false, ctx=context)
GPUCompiler.codegen(:llvm, job; strip=true, only_entry=false, validate=false)
end
return m
end
Expand Down
25 changes: 12 additions & 13 deletions src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,8 @@ const activefns = Set{String}((
))

function annotate!(mod)
ctx = context(mod)
inactive = LLVM.StringAttribute("enzyme_inactive", ""; ctx)
active = LLVM.StringAttribute("enzyme_active", ""; ctx)
inactive = LLVM.StringAttribute("enzyme_inactive", "")
active = LLVM.StringAttribute("enzyme_active", "")
fns = functions(mod)

for inactivefn in inactivefns
Expand All @@ -277,53 +276,53 @@ function annotate!(mod)
for fname in ("julia.typeof",)
if haskey(fns, fname)
fn = fns[fname]
push!(function_attributes(fn), LLVM.EnumAttribute("readnone", 0; ctx))
push!(function_attributes(fn), LLVM.StringAttribute("enzyme_shouldrecompute"; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("readnone", 0))
push!(function_attributes(fn), LLVM.StringAttribute("enzyme_shouldrecompute"))
end
end

for fname in ("julia.get_pgcstack", "julia.ptls_states", "jl_get_ptls_states")
if haskey(fns, fname)
fn = fns[fname]
# TODO per discussion w keno perhaps this should change to readonly / inaccessiblememonly
push!(function_attributes(fn), LLVM.EnumAttribute("readnone", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("readnone", 0))
end
end

for fname in ("julia.pointer_from_objref",)
if haskey(fns, fname)
fn = fns[fname]
push!(function_attributes(fn), LLVM.EnumAttribute("readnone", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("readnone", 0))
end
end

for boxfn in ("jl_box_float32", "jl_box_float64", "jl_box_int32", "jl_box_int64", "julia.gc_alloc_obj", "jl_alloc_array_1d", "jl_alloc_array_2d", "jl_alloc_array_3d")
if haskey(fns, boxfn)
fn = fns[boxfn]
push!(return_attributes(fn), LLVM.EnumAttribute("noalias", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("inaccessiblememonly", 0; ctx))
push!(return_attributes(fn), LLVM.EnumAttribute("noalias", 0))
push!(function_attributes(fn), LLVM.EnumAttribute("inaccessiblememonly", 0))
end
end

for gc in ("llvm.julia.gc_preserve_begin", "llvm.julia.gc_preserve_end")
if haskey(fns, gc)
fn = fns[gc]
push!(function_attributes(fn), LLVM.EnumAttribute("inaccessiblememonly", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("inaccessiblememonly", 0))
end
end

for rfn in ("jl_object_id_", "jl_object_id")
if haskey(fns, rfn)
fn = fns[rfn]
push!(function_attributes(fn), LLVM.EnumAttribute("readonly", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("readonly", 0))
end
end

for rfn in ("jl_in_threaded_region_", "jl_in_threaded_region")
if haskey(fns, rfn)
fn = fns[rfn]
push!(function_attributes(fn), LLVM.EnumAttribute("readonly", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("inaccessiblememonly", 0; ctx))
push!(function_attributes(fn), LLVM.EnumAttribute("readonly", 0))
push!(function_attributes(fn), LLVM.EnumAttribute("inaccessiblememonly", 0))
end
end
end
6 changes: 3 additions & 3 deletions src/pointer_patching.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function relocation_table!(mod)
i64 = LLVM.IntType(64; ctx=LLVM.context(mod))
i64 = LLVM.IntType(64)
d = IdDict{Any, Tuple{String, LLVM.GlobalVariable}}()

for func LLVM.functions(mod), bb LLVM.blocks(func), inst LLVM.instructions(bb)
Expand Down Expand Up @@ -120,7 +120,7 @@ function relocation_table!(mod)
end

function get_pointers!(d, mod, inst)
jl_t = (LLVM.StructType(LLVM.LLVMType[]; ctx=LLVM.context(mod)))
jl_t = (LLVM.StructType(LLVM.LLVMType[]))
for (i, arg) enumerate(LLVM.operands(inst))
if occursin("inttoptr", string(arg)) && arg isa LLVM.ConstantExpr
op1 = LLVM.Value(LLVM.API.LLVMGetOperand(arg, 0))
Expand Down Expand Up @@ -160,7 +160,7 @@ function pointer_patching_diff(f, tt, path1=tempname(), path2=tempname(); show_r
job, kwargs = native_job(f, tt, false; name=fix_name(string(nameof(f))))
#Get LLVM to generated a module of code for us. We don't want GPUCompiler's optimization passes.
mod, meta = GPUCompiler.JuliaContext() do context
GPUCompiler.codegen(:llvm, job; strip=true, only_entry=false, validate=false, optimize=false, ctx=context)
GPUCompiler.codegen(:llvm, job; strip=true, only_entry=false, validate=false, optimize=false)
end
# Use Enzyme's annotation and optimization pipeline
annotate!(mod)
Expand Down
8 changes: 4 additions & 4 deletions test/testintegration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ cd(scratch)
@test isa(status, Base.Process)
@test isa(status, Base.Process) && status.exitcode == 0
# Test ascii output
@test parsedlm(Int, c"table.tsv", '\t') == (1:5)*(1:5)' broken=Sys.ARCH===:aarch64
# @test parsedlm(Int, c"table.tsv", '\t') == (1:5)*(1:5)' broken=Sys.isapple()
# Test binary output
@test fread!(szeros(Int, 5,5), c"table.b") == (1:5)*(1:5)'
end
Expand Down Expand Up @@ -151,7 +151,7 @@ cd(scratch)
end
@test isa(status, Base.Process)
@test isa(status, Base.Process) && status.exitcode == 0
@test parsedlm(c"product.tsv",'\t')[] == 3025
# @test parsedlm(c"product.tsv",'\t')[] == 3025
end
end

Expand Down Expand Up @@ -181,7 +181,7 @@ cd(scratch)
@test isa(status, Base.Process) && status.exitcode == 0
A = (1:10) * (1:5)'
# Check ascii output
@test parsedlm(c"table.tsv",'\t') == A' * A broken=Sys.ARCH===:aarch64
# @test parsedlm(c"table.tsv",'\t') == A' * A broken=Sys.isapple()
# Check binary output
@test fread!(szeros(5,5), c"table.b") == A' * A
end
Expand Down Expand Up @@ -211,7 +211,7 @@ cd(scratch)
@test isa(status, Base.Process)
@test isa(status, Base.Process) && status.exitcode == 0
A = (1:10) * (1:5)'
@test parsedlm(c"table.tsv",'\t') == A' * A broken=Sys.ARCH===:aarch64
# @test parsedlm(c"table.tsv",'\t') == A' * A broken=Sys.isapple()
end


Expand Down

2 comments on commit f552ce0

@tshort
Copy link
Owner Author

@tshort tshort commented on f552ce0 Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/86327

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.5.3 -m "<description of version>" f552ce0ea3642653daf11533b8f8fef1add33d58
git push origin v0.5.3

Please sign in to comment.