Skip to content

Require support for arrays of isbits unions in the testsuite - #835

Draft
maleadt wants to merge 3 commits into
mainfrom
tb/isbits-union-tests
Draft

maleadt wants to merge 3 commits into
mainfrom
tb/isbits-union-tests

Conversation

@maleadt

@maleadt maleadt commented Oct 23, 2026

Copy link
Copy Markdown
Member

Arrays with an isbits-union element type (Union{Int32, Nothing}, Union{Missing, Bool}, Union{Nothing, Missing}, ...) store one selector byte per element after the data, like Array does. The back-ends either didn't support this or got it wrong in subtle ways: views read their parent's selector bytes, views of unions of singletons (which have no data, so no byte offset) did the same, fill! used memset and left stale selectors, resize! of a view or of a zero-size union broke. Without union support, Array(GPUArray(Union{Int,Nothing}[1, nothing])) silently returns wrong values. The testsuite only touched such arrays in passing, and only after checking at run time whether the back-end could construct one.

This PR makes union support part of the testsuite's contract. The new unions tests cover round trips and partial copies between host and device for unions with members of different sizes and alignments, elements padded beyond their sizeof (Union{Int64, NTuple{3, Int32}}, 12 bytes with a 16-byte stride), unions of singletons and nested unions; views with irregular data, checking that writes through them leave the rest of the parent alone; KernelAbstractions kernels on such arrays and on structs with a union field; fill! with unions memset could otherwise fill; broadcasting, any/all, mapreduce, findall, scalar indexing and resize!. The existing reinterpret and any/all tests for unions now run unconditionally. Unions stick to Int32, Float32 and smaller members, so Metal can run them.

JLArrays didn't support unions either: it stored no selector bytes and wrapped its memory as an Array. The first commit adds support with the same layout, tracking where an array's selector bytes start so that derived arrays advance them by element.

This needs the back-end PRs to land first:

Results of the unions, findall and base tests:

Back-end PR branch Base of the PR
JLArrays (Julia 1.10, 1.11, 1.13) pass 58 failed, 29 errored (registered JLArrays 0.4.2)
AMDGPU.jl (gfx1036) 331 passed 59 failed, 28 errored
CUDA.jl (RTX 5080) 331 passed 15 failed, 3 errored: views, zero-size union views, fill!, resize! of views
Metal.jl, OpenCL.jl, oneAPI.jl not run not run

The full JLArrays and Array suite passes on Julia 1.13.

JLArray accepted element types like `Union{Int, Nothing}`, but stored
no selector bytes and wrapped its memory as a plain `Array`, so reading
such an array back returned wrong values and kernels failed.

Store the elements and selector bytes like `Array` does: elements are
padded to `aligned_sizeof(T)`, and one selector byte per element
follows the data. Arrays track the offset of their first selector
byte, which derived arrays advance by element, so that views of unions
of singletons, which have no data, still find their own selectors.
Copies to, from and between JLArrays copy the selector bytes too, and
the device array loads and stores elements according to them. The
host algorithms that ran on a wrapped `Array` use the device array
for these element types instead.
Every back-end now supports arrays of isbits unions, but the testsuite
only covered them in passing, and only where the back-end supported
them. Add tests for them, based on the bugs that came up implementing
them in the back-ends: views whose selector bytes were taken from
their parent, views of unions of singletons (which have no data),
elements whose size is not a multiple of their alignment, `fill!`
fast paths that skip the selector bytes, and `resize!` of views.
The `reinterpret` and `any`/`all` tests of isbits-union arrays only
ran when the back-end could construct one. Run them unconditionally
now that the testsuite requires support for such arrays.

This branch has not been deployed

No deployments
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