Skip to content

Commit fd02bac

Browse files
maleadtclaude
andcommitted
Document dynamic allocation in kernels
Describe the per-work-item heap, its size, its failure mode and its cost in the kernel programming docs, and stop announcing the removal of the two quirks that were waiting for `malloc`: they stay for the reason they print. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fy9hCZkRFuf9fbRQNagCxf
1 parent 52aacfe commit fd02bac

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

docs/src/kernels.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,22 @@ and correspond to the standard OpenCL built-in functions. Note that the indices
6262
are 1-based, so they can be used to index Julia arrays directly. See
6363
[Device Intrinsics](device.md) for the full list.
6464

65+
66+
## Dynamic Memory Allocation
67+
68+
Kernels can allocate Julia objects: a `Ref` handed to a `@noinline` function, a struct with
69+
an `Any` field, or the exception object of a `throw` that survives optimization. Such
70+
allocations are served by a small heap private to each work-item: `oneAPI.HEAP_SIZE` bytes
71+
(1 KiB) of private memory, bump-allocated and released as a whole when the work-item
72+
exits. Nothing is freed before that, so a work-item that allocates more than the heap
73+
holds runs out of memory, reports it on the standard output of the process, and exits
74+
without finishing its work:
75+
76+
```
77+
ERROR: Out of dynamic GPU memory (trying to allocate 4 bytes)
78+
```
79+
80+
Only kernels that allocate reserve a heap, and Intel's compiler usually optimizes it away
81+
entirely when the allocated objects do not outlive the code it inlines. Allocations on a hot
82+
path are nonetheless a sign that the kernel is not fully specialized: restructure such code
83+
rather than rely on the heap.

src/device/quirks.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ end
3838
@print_and_throw "sincos(x) is only defined for finite x."
3939

4040
# diagonal.jl
41-
# XXX: remove when we have malloc
41+
# Base's version throws an ArgumentError; this one prints the reason
4242
import LinearAlgebra
4343
@device_override function Base.setindex!(D::LinearAlgebra.Diagonal, v, i::Int, j::Int)
4444
@boundscheck checkbounds(D, i, j)
@@ -51,7 +51,7 @@ import LinearAlgebra
5151
end
5252

5353
# number.jl
54-
# XXX: remove when we have malloc
54+
# Base's version throws a BoundsError; this one prints the reason
5555
@device_override @inline function Base.getindex(x::Number, I::Integer...)
5656
@boundscheck all(isone, I) ||
5757
@print_and_throw "Out-of-bounds access of scalar value"

0 commit comments

Comments
 (0)