Skip to content

Fix collect of non-reshaped reinterpret of an IndexSCartesian2 array - #63352

Merged
jishnub merged 2 commits into
JuliaLang:masterfrom
greekera1000:fix-63305
Sep 26, 2026
Merged

jishnub merged 2 commits into
JuliaLang:masterfrom
greekera1000:fix-63305

Conversation

@greekera1000

Copy link
Copy Markdown
Contributor

Fixes #63305

A non-reshaped reinterpret inherited its parent's IndexSCartesian2{K} index style. But eachindex for that style is forwarded to the parent, so when the element size changes (and with it the array's axes), iteration and therefore collect visited the wrong elements. This makes it fall back to IndexCartesian() in that case. Same-size reinterprets keep the fast path.

The same pattern may also affect reinterpret(reshape, T, ...) when it drops the leading dimension of an IndexSCartesian2 parent. Happy to handle that here or in a follow-up.

Disclosure: I used claude to help find the root cause and draft this patch. I have reviewed the change and understand it.

@nhz2 nhz2 added arrays [a, r, r, a, y, s] bugfix This change fixes an existing bug labels Sep 25, 2026
Comment thread base/reinterpretarray.jl Outdated
function IndexStyle(::Type{ReinterpretArray{T,N,S,A,false}}) where {T,N,S,A<:AbstractArray{S,N}}
style = IndexStyle(A)
# a size change invalidates the parent's `IndexSCartesian2` (#63305)
style isa IndexSCartesian2 && aligned_sizeof(T) != aligned_sizeof(S) && return IndexCartesian()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would be safer to have a white list of IndexStyle to pass through, instead of an explicit set of IndexStyles that need to be blocked from passing through.

@greekera1000

Copy link
Copy Markdown
Contributor Author

Good point, thanks @nhz2 . I'll switch to a whitelist so that only IndexLinear passes through and everything else falls back to IndexCartesian.

@nhz2

nhz2 commented Sep 25, 2026

Copy link
Copy Markdown
Member

I'm having a hard time understanding IndexSCartesian2, the docs at https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array seem to imply only IndexLinear and IndexCartesian are valid IndexStyle.

@greekera1000

Copy link
Copy Markdown
Contributor Author

Yeah, that confused me at first too. IndexSCartesian2 isn't a documented style. It's an internal one defined in base/reinterpretarray.jl, and Base only uses it for reinterpret(reshape, T, A) when T is smaller than S and the parent is IndexLinear (like the reinterpret(reshape, UInt16, a) step in the issue). It speeds up iteration by assuming the new first axis is always 1:K.

The problem is that the non-reshaped reinterpret just forwarded its parent's style, and eachindex for IndexSCartesian2 gets forwarded to the parent too. So reinterpret(UInt8, ...) ended up iterating the 8×2 array as if it were still 4×2, which is why collect returned the wrong values.

With the whitelist change, this method now only ever returns IndexLinear or IndexCartesian, which matches the docs you linked.

@nhz2 nhz2 added the merge me PR is reviewed. When all tests are passing merge, making sure commit message is good. label Sep 25, 2026
@jishnub
jishnub merged commit 16f823d into JuliaLang:master Sep 26, 2026
11 checks passed
@adienes adienes removed the merge me PR is reviewed. When all tests are passing merge, making sure commit message is good. label Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrays [a, r, r, a, y, s] bugfix This change fixes an existing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

collect incorrect for nested reinterpret arrays.

5 participants