Skip to content

Commit

Permalink
Merge pull request #366 from JuliaGPU/jps/mem-limit
Browse files Browse the repository at this point in the history
Add memory allocation limiters
  • Loading branch information
jpsamaroo authored Jan 30, 2023
2 parents dd9344c + b03d155 commit 3125820
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/runtime/kernel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,33 @@ function ROCKernel(kernel #= ::HostKernel =#; localmem::Int=0)
group_segment_size = executable_symbol_kernel_group_segment_size(exec_symbol)
group_segment_size = UInt32(group_segment_size + localmem)
private_segment_size = executable_symbol_kernel_private_segment_size(exec_symbol)
if private_segment_size > MAXIMUM_SCRATCH_ALLOCATION
@debug "Excessive scratch allocation requested\nReducing per-lane scratch to $(Int(MAXIMUM_SCRATCH_ALLOCATION)) bytes"
private_segment_size = MAXIMUM_SCRATCH_ALLOCATION
end

kernel = ROCKernel(device, exe, symbol, localmem, kernel_object,
kernarg_segment_size, group_segment_size,
private_segment_size, Ptr{Cvoid}(0))
return kernel
end

"Sets the maximum amount of per-lane scratch memory that can be allocated for a
kernel. Consider setting this to a value below 2^14 if encountering
`QueueError`s with the `HSA.STATUS_ERROR_OUT_OF_RESOURCES` code."
set_max_scratch!(scratch::Integer) =
@set_preferences!("max_scratch"=>scratch)
const MAXIMUM_SCRATCH_ALLOCATION = let
if haskey(ENV, "JULIA_AMDGPU_MAX_SCRATCH")
scratch = ENV["JULIA_AMDGPU_MAX_SCRATCH"]
scratch = if uppercase(scratch) == "MAX"
typemax(UInt32)
else
parse(UInt32, scratch)
end
set_max_scratch!(scratch)
scratch
else
UInt32(@load_preference("max_scratch", 8192))
end
end::UInt32
23 changes: 23 additions & 0 deletions src/runtime/memory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,19 @@ const USE_HIP_MALLOC_OVERRIDE = let
end
end

"Sets a limit for total GPU memory allocations."
set_memory_alloc_limit!(limit::Integer) =
@set_preferences!("memory_alloc_limit" => limit)
const MEMORY_ALLOC_LIMIT = let
if haskey(ENV, "JULIA_AMDGPU_MEMORY_ALLOC_LIMIT")
limit = parse(Int, ENV["JULIA_AMDGPU_MEMORY_ALLOC_LIMIT"])
set_memory_alloc_limit!(limit)
limit
else
@load_preference("memory_alloc_limit", typemax(Int))
end
end

"""
alloc(bytesize::Integer; coherent=false) -> Buffer
Expand Down Expand Up @@ -388,20 +401,29 @@ function alloc_or_retry!(f)
end
end
end
const ALL_ALLOCS = Threads.Atomic{Int64}(0)
function alloc(device::ROCDevice, pool::ROCMemoryPool, bytesize::Integer)
if ALL_ALLOCS[] + bytesize > MEMORY_ALLOC_LIMIT
check(HSA.STATUS_ERROR_OUT_OF_RESOURCES)
end
ptr_ref = Ref{Ptr{Cvoid}}()
alloc_or_retry!() do
HSA.amd_memory_pool_allocate(pool.pool, bytesize, 0, ptr_ref)
end
Threads.atomic_add!(ALL_ALLOCS, Int64(bytesize))
AMDGPU.hsaref!()
ptr = ptr_ref[]
return Buffer(ptr, C_NULL, ptr, Int64(bytesize), device, Runtime.pool_accessible_by_all(pool), true)
end
function alloc(device::ROCDevice, region::ROCMemoryRegion, bytesize::Integer)
if ALL_ALLOCS[] + bytesize > MEMORY_ALLOC_LIMIT
check(HSA.STATUS_ERROR_OUT_OF_RESOURCES)
end
ptr_ref = Ref{Ptr{Cvoid}}()
alloc_or_retry!() do
HSA.memory_allocate(region.region, bytesize, ptr_ref)
end
Threads.atomic_add!(ALL_ALLOCS, Int64(bytesize))
AMDGPU.hsaref!()
ptr = ptr_ref[]
return Buffer(ptr, C_NULL, ptr, Int64(bytesize), device, Runtime.region_host_accessible(region), false)
Expand Down Expand Up @@ -442,6 +464,7 @@ function free(buf::Buffer)
else
memory_check(HSA.amd_memory_pool_free(buf.base_ptr), buf.base_ptr)
end
Threads.atomic_sub!(ALL_ALLOCS, Int64(buf.bytesize))
else
memory_check(HSA.memory_free(buf.base_ptr), buf.base_ptr)
end
Expand Down

0 comments on commit 3125820

Please sign in to comment.