Skip to content

Check the alignment of arrays passed to kernels - #733

Merged
maleadt merged 2 commits into
mainfrom
tb/kernel-alignment-check
Oct 26, 2026
Merged

maleadt merged 2 commits into
mainfrom
tb/kernel-alignment-check

Conversation

@maleadt

@maleadt maleadt commented Oct 23, 2026

Copy link
Copy Markdown
Member

Since #570 stores oneArray offsets in bytes, reinterpret of a view can produce an array that isn't aligned for its element type. Copying such an array works, but kernels assume the element type's alignment, and on Intel GPUs they then access the wrong memory without any error. On an Arc A770:

julia> d = oneArray(UInt8.(0:63));
julia> v = reinterpret(UInt64, view(d, 2:17));   # starts at byte 1
julia> v .= v .+ 1;
julia> findall(Array(d) .!= 0:63) .- 1           # expected bytes 1 and 9 to change
Int64[]
julia> Array(v .+ 0x0)                           # reads bytes 0-15 instead of 1-16
2-element Vector{UInt64}:
 0x0706050403020100
 0x0f0e0d0c0b0a0908

This PR checks the pointer when a oneArray is converted to a device array, both when launching a kernel and in unsafe_convert, and throws an ArgumentError that suggests copy. Empty arrays are exempt. The check uses the alignment that device-side element accesses already assume, so nothing that currently works correctly is rejected. A device-side reinterpret to a type with a stronger alignment requirement (e.g. Int32 to Int64) checks the pointer as well. That required fixing device-side reinterpret first: it called an undefined _reinterpret_exception, so every kernel using it failed to compile (separate commit).

CUDA.jl makes the same change. On NVIDIA GPUs these kernels fault with ERROR_MISALIGNED_ADDRESS and leave the context unusable (x-ref JuliaGPU/CUDA.jl#3451). Raising the assumed alignment to the element size so that ComplexF32 or NTuple{4,Float32} get vector loads, as CUDA.jl also does, isn't worth it here: IGC already emits d32x2/d32x4 loads for those types on the A770, and the generated code and timings were identical with the higher alignment.

Tested on an Arc A770 by running array and execution. With the new tests but without the fix, the broadcast and unsafe_convert tests don't throw, and the device-side reinterpret reads 0x0000000200000000 instead of not storing.

@maleadt maleadt added kernels Writing and compiling kernels: device intrinsics, codegen, KernelAbstractions back-end. arrays The array abstraction: broadcasting, mapreduce, indexing, views, generic linear algebra. labels Oct 23, 2026
@maleadt
maleadt force-pushed the tb/kernel-alignment-check branch 2 times, most recently from ac690be to 09bb61e Compare October 25, 2026 06:17
`reinterpret` on a oneDeviceArray called `_reinterpret_exception`,
which oneAPI.jl doesn't define, so any kernel using it failed to
compile with an InvalidIRError. Call the GPUArrays function, as CUDA.jl
and Metal.jl do.
@maleadt
maleadt force-pushed the tb/kernel-alignment-check branch from 09bb61e to 51a7914 Compare October 25, 2026 18:03
Since oneArray offsets are stored in bytes (#570), `reinterpret` of a
view can yield an array that isn't aligned for its element type, e.g.
`reinterpret(UInt64, view(a::oneVector{UInt8}, 2:17))`. Copies handle
that fine, but kernels access elements assuming the element type's
alignment, and Intel GPUs then silently access the wrong memory: on an
Arc A770, loads of such an array read from the address rounded down to
8 bytes, and stores were lost.

Check the pointer when converting a oneArray to a device array and throw
an ArgumentError instead. Device-side `reinterpret` to a type with a
stronger alignment requirement checks the pointer too.

x-ref JuliaGPU/CUDA.jl#3451
@maleadt
maleadt force-pushed the tb/kernel-alignment-check branch from 51a7914 to de005dc Compare October 25, 2026 19:35
@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.64%. Comparing base (584af0b) to head (de005dc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #733      +/-   ##
==========================================
- Coverage   86.93%   86.64%   -0.30%     
==========================================
  Files          56       55       -1     
  Lines        5120     4993     -127     
==========================================
- Hits         4451     4326     -125     
+ Misses        669      667       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maleadt
maleadt merged commit 3a02a1f into main Oct 26, 2026
5 checks passed
@maleadt
maleadt deleted the tb/kernel-alignment-check branch October 26, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrays The array abstraction: broadcasting, mapreduce, indexing, views, generic linear algebra. kernels Writing and compiling kernels: device intrinsics, codegen, KernelAbstractions back-end.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant