Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "AMDGPU"
uuid = "21141c5a-9bdb-4563-92ae-f87d6854732e"
version = "2.6.0"
version = "2.6.1"
authors = ["Julian P Samaroo <jpsamaroo@jpsamaroo.me>", "Valentin Churavy <v.churavy@gmail.com>", "Anton Smirnov <tonysmn97@gmail.com>"]

[workspace]
Expand Down Expand Up @@ -60,11 +60,11 @@ ChainRulesCore = "1"
EnzymeCore = "0.8"
ExprTools = "0.1"
GPUArrays = "11.3.1"
GPUCompiler = "1"
GPUCompiler = "1.23.1"
GPUToolbox = "0.1.0, 0.2, 0.3, 1, 2, 3"
KernelAbstractions = "0.9.2"
LLD_jll = "15, 16, 17, 18, 19, 20, 21.1"
LLVM = "9"
LLVM = "10"
LLVM_jll = "15, 16, 17, 18, 19, 20, 21.1"
PrecompileTools = "1"
Preferences = "1"
Expand Down
2 changes: 1 addition & 1 deletion src/AMDGPU.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using GPUCompiler
using GPUArrays
using GPUArrays: allowscalar
using Libdl
using LLVM, LLVM.Interop
using LLVM
using Preferences
using Printf

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/Compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Core: LLVMPtr
import LLD_jll

using ..GPUCompiler
using ..LLVM
using ..LLVM, ..LLVM.IR, ..LLVM.Build, ..LLVM.Passes
using Printf

import ..AMDGPU
Expand Down
26 changes: 13 additions & 13 deletions src/compiler/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ function GPUCompiler.finish_module!(
wavefrontsize64=job.config.params.wavefrontsize64)

# Set kernel target cpu and features.
if LLVM.callconv(entry) == LLVM.API.LLVMAMDGPUKERNELCallConv
if entry.callconv == LLVM.API.LLVMAMDGPUKERNELCallConv
target_cpu_attr = StringAttribute("target-cpu", job.config.target.dev_isa)
target_features_attr = StringAttribute("target-features", job.config.target.features)
atomic_attr = StringAttribute("amdgpu-unsafe-fp-atomics", "true")

# TODO add convergent, mustprogress, willreturn attributes?

attrs = LLVM.function_attributes(entry)
attrs = entry.function_attributes
push!(attrs, target_cpu_attr)
push!(attrs, target_features_attr)
push!(attrs, atomic_attr)
Expand All @@ -82,10 +82,10 @@ function GPUCompiler.finish_module!(
"signal_exception", "report_exception", "malloc", "__throw_")
inline_attr = EnumAttribute("alwaysinline")

for fn in LLVM.functions(mod)
do_inline = any(occursin.(target_fns, LLVM.name(fn)))
for fn in mod.functions
do_inline = any(occursin.(target_fns, fn.name))
if job.config.params.unsafe_fp_atomics || do_inline
attrs = LLVM.function_attributes(fn)
attrs = fn.function_attributes

do_inline && inline_attr ∉ collect(attrs) &&
push!(attrs, inline_attr)
Expand All @@ -99,13 +99,13 @@ function GPUCompiler.finish_module!(
fp_binops = (LLVM.API.LLVMAtomicRMWBinOpFAdd, LLVM.API.LLVMAtomicRMWBinOpFSub,
LLVM.API.LLVMAtomicRMWBinOpFMax, LLVM.API.LLVMAtomicRMWBinOpFMin)
empty_md = MDNode(Metadata[])
for fn in LLVM.functions(mod), bb in LLVM.blocks(fn), inst in LLVM.instructions(bb)
for fn in mod.functions, bb in fn.blocks, inst in bb.instructions
inst isa LLVM.AtomicRMWInst || continue
op = LLVM.binop(inst)
op = inst.binop
op ∈ fp_binops || continue
md = LLVM.metadata(inst)
md = inst.metadata
md["amdgpu.no.fine.grained.memory"] = empty_md
if op == LLVM.API.LLVMAtomicRMWBinOpFAdd && LLVM.value_type(inst) == LLVM.FloatType()
if op == LLVM.API.LLVMAtomicRMWBinOpFAdd && inst.value_type isa LLVM.FloatType
md["amdgpu.ignore.denormal.mode"] = empty_md
end
end
Expand Down Expand Up @@ -208,8 +208,8 @@ function find_global_hostcalls(mod::LLVM.Module)
:malloc_hostcall, :free_hostcall, :print_hostcall, :printf_hostcall)

global_hostcalls = Symbol[]
for gbl in LLVM.globals(mod), gbl_name in global_hostcall_names
occursin("__$gbl_name", LLVM.name(gbl)) || continue
for gbl in mod.globals, gbl_name in global_hostcall_names
occursin("__$gbl_name", gbl.name) || continue
push!(global_hostcalls, gbl_name)
end
return global_hostcalls
Expand All @@ -236,8 +236,8 @@ function hipcompile(@nospecialize(job::CompilerJob))
"""
end

entry = LLVM.name(meta.entry)
extinit_globals = filter(isextinit, collect(LLVM.globals(meta.ir))) .|> LLVM.name
entry = meta.entry.name
extinit_globals = [gv.name for gv in meta.ir.globals if gv.externally_initialized]
if !isempty(extinit_globals)
@warn """
HIP backend does not support setting extinit globals.
Expand Down
12 changes: 6 additions & 6 deletions src/compiler/device_libs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,17 @@ function load_and_link!(devlib::DevLib, mod::LLVM.Module)
inline_attr = EnumAttribute("alwaysinline")
noinline_attr = EnumAttribute("noinline")

for f in LLVM.functions(lib)
fn_name = LLVM.name(f)
for f in lib.functions
fn_name = f.name

# FIXME: We should be able to inline this, that we can't means
# we are inserting calls to it late.
startswith(fn_name, "__ockl_hsa_signal") && continue

attrs = function_attributes(f)
attrs = f.function_attributes
inline = true
for attr in collect(attrs)
if kind(attr) == kind(noinline_attr)
if attr.kind == noinline_attr.kind
inline = false
break
end
Expand All @@ -95,8 +95,8 @@ function load_and_link!(devlib::DevLib, mod::LLVM.Module)
end

# override triple and datalayout to avoid warnings
triple!(lib, triple(mod))
datalayout!(lib, datalayout(mod))
lib.triple = mod.triple
lib.datalayout = mod.datalayout
LLVM.link!(mod, lib)
return
end
34 changes: 16 additions & 18 deletions src/compiler/zeroinit_lds.jl
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
# Calculate the size of an LLVM type.
llvmsize(::LLVM.LLVMHalf) = sizeof(Float16)
llvmsize(::LLVM.LLVMFloat) = sizeof(Float32)
llvmsize(::LLVM.LLVMDouble) = sizeof(Float64)
llvmsize(::LLVM.HalfType) = sizeof(Float16)
llvmsize(::LLVM.FloatType) = sizeof(Float32)
llvmsize(::LLVM.DoubleType) = sizeof(Float64)
function llvmsize(::LLVM.IntegerType)
div(Int(intwidth(GenericValue(LLVM.Int128Type(), -1))), 8)
div(Int(LLVM.GenericValue(LLVM.Int128Type(), -1).intwidth), 8)
end

llvmsize(ty::LLVM.ArrayType) = length(ty) * llvmsize(eltype(ty))
llvmsize(ty::LLVM.ArrayType) = ty.length * llvmsize(ty.element_type)
llvmsize(ty::LLVM.StructType) = ispacked(ty) ?
sum(llvmsize(elem) for elem in elements(ty)) :
8 * length(elements(ty)) # FIXME: Properly determine non-packed sizing
sum(llvmsize(elem) for elem in ty.elements) :
8 * length(ty.elements) # FIXME: Properly determine non-packed sizing
llvmsize(ty::LLVM.PointerType) = div(Sys.WORD_SIZE, 8)
llvmsize(ty::LLVM.VectorType) = size(ty)
llvmsize(ty::LLVM.VectorType) = ty.length
llvmsize(ty) = error("Unknown size for type: $ty, typeof: $(typeof(ty))")

function zeroinit_lds!(mod::LLVM.Module, entry::LLVM.Function)
if LLVM.callconv(entry) != LLVM.API.LLVMAMDGPUKERNELCallConv
if entry.callconv != LLVM.API.LLVMAMDGPUKERNELCallConv
return entry
end

to_init = []
for gbl in LLVM.globals(mod)
if startswith(LLVM.name(gbl), "__zeroinit")
vt = value_type(gbl)
as = LLVM.addrspace(vt)
for gbl in mod.globals
if startswith(gbl.name, "__zeroinit")
as = gbl.value_type.addrspace
if as == AMDGPU.Device.AS.Local
sz = llvmsize(global_value_type(gbl))
sz = llvmsize(gbl.global_value_type)
push!(to_init, (gbl, sz))
end
end
Expand All @@ -34,15 +33,14 @@ function zeroinit_lds!(mod::LLVM.Module, entry::LLVM.Function)

@dispose builder=IRBuilder() begin
# Make these the first operations we do.
block = first(LLVM.blocks(entry))
instruction = first(LLVM.instructions(block))
position!(builder, instruction)
instruction = first(entry.entry.instructions)
position!(builder, LLVM.before(instruction))

# Use memset to clear all values to 0.
for (gbl, sz) in to_init
sz == 0 && continue
LLVM.memset!(builder, gbl,
ConstantInt(UInt8(0)), ConstantInt(sz), LLVM.alignment(gbl))
ConstantInt(UInt8(0)), ConstantInt(sz), gbl.alignment)
end

# Synchronize the workgroup to prevent races.
Expand Down
3 changes: 1 addition & 2 deletions src/device/Device.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Device

using ..BFloat16s
using ..GPUCompiler
using ..LLVM
using ..LLVM, ..LLVM.IR, ..LLVM.Build
using ..LLVM.Interop

import ..Adapt
Expand All @@ -19,7 +19,6 @@ import .AMDGPU: aligned_sizeof
import ..UnsafeAtomics

include("addrspaces.jl")
include("globals.jl")
include("strings.jl")
include("exceptions.jl")
include("gcn.jl")
Expand Down
109 changes: 40 additions & 69 deletions src/device/gcn/indexing.jl
Original file line number Diff line number Diff line change
@@ -1,76 +1,47 @@
# Indexing and dimensions

@generated function _index(::Val{fname}, ::Val{name}, ::Val{range}) where {fname, name, range}
@dispose ctx=Context() begin
T_int32 = LLVM.Int32Type()

# create function
llvm_f, _ = create_function(T_int32)
mod = LLVM.parent(llvm_f)

# generate IR
@dispose builder=IRBuilder() begin
entry = BasicBlock(llvm_f, "entry")
position!(builder, entry)

# call the indexing intrinsic
intr_typ = LLVM.FunctionType(T_int32)
intr = LLVM.Function(mod, "llvm.amdgcn.$fname.id.$name", intr_typ)
idx = call!(builder, intr_typ, intr)

# attach range metadata
metadata(idx)[LLVM.MD_range] = MDNode([
ConstantInt(UInt32(range.start)),
ConstantInt(UInt32(range.stop))])
ret!(builder, idx)
end

call_function(llvm_f, UInt32)
end
@llvmgenerated builder function _index(::Val{fname}, ::Val{name}, ::Val{range})::UInt32 where {fname, name, range}
T_int32 = LLVM.Int32Type()

# call the indexing intrinsic
intr_typ = LLVM.FunctionType(T_int32)
intr = LLVM.Function(current_module(builder), "llvm.amdgcn.$fname.id.$name", intr_typ)
idx = call!(builder, intr_typ, intr)

# attach range metadata
idx.metadata[MD_range] = MDNode([
ConstantInt(UInt32(range.start)),
ConstantInt(UInt32(range.stop))])
idx
end

@generated function _dim(::Val{base}, ::Val{off}, ::Val{range}, ::Type{T}) where {base, off, range, T}
@dispose ctx=Context() begin
T_int8 = LLVM.Int8Type()
T_int32 = LLVM.Int32Type()

_as = convert(Int, AS.Constant)
T_ptr_i8 = LLVM.PointerType(T_int8, _as)
T_ptr_i32 = LLVM.PointerType(T_int32, _as)

T_T = convert(LLVMType, T)
T_ptr_T = LLVM.PointerType(T_T, _as)

# create function
llvm_f, _ = create_function(T_int32)
mod = LLVM.parent(llvm_f)

# generate IR
@dispose builder=IRBuilder() begin
entry = BasicBlock(llvm_f, "entry")
position!(builder, entry)

# get the kernel dispatch pointer
intr_typ = LLVM.FunctionType(T_ptr_i8)
intr = LLVM.Function(mod, "llvm.amdgcn.dispatch.ptr", intr_typ)
ptr = call!(builder, intr_typ, intr)

# load the index
offset = base + ((off - 1) * aligned_sizeof(T))
idx_ptr_i8 = inbounds_gep!(builder, T_int8, ptr, [ConstantInt(offset)])
idx_ptr_T = bitcast!(builder, idx_ptr_i8, T_ptr_T)
idx_T = load!(builder, T_T, idx_ptr_T)
idx = zext!(builder, idx_T, T_int32)

# attach range metadata
metadata(idx_T)[LLVM.MD_range] = MDNode([
ConstantInt(T(range.start)),
ConstantInt(T(range.stop))])
ret!(builder, idx)
end

call_function(llvm_f, UInt32)
end
@llvmgenerated builder function _dim(::Val{base}, ::Val{off}, ::Val{range}, ::Type{T})::UInt32 where {base, off, range, T}
T_int8 = LLVM.Int8Type()
T_int32 = LLVM.Int32Type()

_as = convert(Int, AS.Constant)
T_ptr_i8 = LLVM.PointerType(T_int8, _as)

T_T = convert(LLVMType, T)
T_ptr_T = LLVM.PointerType(T_T, _as)

# get the kernel dispatch pointer
intr_typ = LLVM.FunctionType(T_ptr_i8)
intr = LLVM.Function(current_module(builder), "llvm.amdgcn.dispatch.ptr", intr_typ)
ptr = call!(builder, intr_typ, intr)

# load the index
offset = base + ((off - 1) * aligned_sizeof(T))
idx_ptr_i8 = inbounds_gep!(builder, T_int8, ptr, [ConstantInt(offset)])
idx_ptr_T = bitcast!(builder, idx_ptr_i8, T_ptr_T)
idx_T = load!(builder, T_T, idx_ptr_T)
idx = zext!(builder, idx_T, T_int32)

# attach range metadata
idx_T.metadata[MD_range] = MDNode([
ConstantInt(T(range.start)),
ConstantInt(T(range.stop))])
idx
end

# TODO: look these up for the current device/queue
Expand Down
Loading