Skip to content

Define alias detection for every GPU array through a location hook - #811

Merged
maleadt merged 1 commit into
mainfrom
tb/alias-interface
Oct 9, 2026
Merged

maleadt merged 1 commit into
mainfrom
tb/alias-interface

Conversation

@maleadt

@maleadt maleadt commented Oct 9, 2026

Copy link
Copy Markdown
Member

Back-ends each defined their own Base.dataids and Base.mightalias, and they diverge. The aliasing testsuite added in 12.0.3 fails on CUDA, AMDGPU, oneAPI and OpenCL, because an empty contiguous view is reported as aliasing the array around it. Base's check for two SubArrays also converts GPU parents to pointers. That takes stream ownership on CUDA and throws for OpenCL buffers without a device address.

This PR defines alias detection once, for every AbstractGPUArray, on top of a new hook:

GPUArrays.memory_location(A) -> (base::UInt, offset::Int)   # default: nothing

base identifies the allocation (normally its address; a handle works for memory without one) and offset is the byte offset of the first element.

  • Base.mightalias: empty arrays alias nothing on every Julia version, including 1.10, which has no isempty check. Two arrays with a location alias when their byte ranges overlap. Isbits-union element types, whose selector bytes lie outside that range, and types without the hook are compared by dataids.
  • Base.dataids: the shared DataRef, the allocation's base and the array's start address, or () for empty arrays. Base compares these whenever an array is wrapped (e.g. in a SubArray), so wrapped arrays are compared by allocation, which is conservative.
  • Base._parentsmatch: two parents are the same memory if they have the same location, element size and size. GPU arrays are no longer converted to pointers. When parents don't match, Base falls back to dataids, which is always sound.

JLArrays implements the hook in place of its byte-range mightalias from #803. The behaviour for JLArrays is the same, except that isbits-union arrays are now compared by allocation. The docstring documents the contract, including what the hook cannot express: memory reachable at two addresses, and memory wrapped from a pointer into the middle of an allocation when it is compared through a wrapper.

The design was reviewed by two other agents (Codex and Claude). It was checked on Julia 1.10, 1.11, 1.12 and 1.13: the aliasing testsuite for JLArray and Array, JLArray broadcasting, CPU probes of the wrapper, union and mixed GPU/CPU paths, and no new method ambiguities.

This is a minor release: GPUArrays 12.1.0, and JLArrays 0.4.2, which requires it. Once this is merged, the back-ends replace their dataids/mightalias methods with the one-line hook (see NEWS.md).

Back-ends each defined `Base.dataids` and `Base.mightalias`, with diverging
handling of empty arrays (the new aliasing testsuite fails on CUDA, AMDGPU,
oneAPI and OpenCL) and with Base's SubArray check converting GPU arrays to
pointers, which takes stream ownership on CUDA and throws for OpenCL buffers
without an address.

GPUArrays now defines both for `AbstractGPUArray`, plus `Base._parentsmatch`,
from a new `GPUArrays.memory_location` hook: the coordinate of an array's
allocation and its byte offset. Bare arrays are compared by byte range, wrapped
ones by allocation, empty arrays alias nothing on every Julia version, and
isbits-union arrays and types without the hook stay at allocation granularity.
JLArrays implements the hook instead of its own `mightalias`.
@maleadt
maleadt merged commit 6b164fa into main Oct 9, 2026
17 of 18 checks passed
@maleadt
maleadt deleted the tb/alias-interface branch October 9, 2026 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant