ArrayInterface.jl icon indicating copy to clipboard operation
ArrayInterface.jl copied to clipboard

Strides on when SubArray has a scalar sub index

Open Tokazama opened this issue 4 years ago • 2 comments
trafficstars

I've been getting incorrect results when using scalar indexing that doesn't start with one on views.

julia> A = zeros(3, 4, 5);

julia> A[:] = 1:60;

julia> Aview = view(A, :, 2, :);

julia> ArrayInterface.StrideIndex(Aview)[1,1]
1

julia> Aview[1,1]
4.0

julia> Aview = view(A, 2, :, :);

julia> ArrayInterface.StrideIndex(Aview)[1,1]
1

julia> Aview[1,1]
2.0

Should we be combining those scalar indices with strides?

Tokazama avatar Aug 11 '21 17:08 Tokazama

julia> A = zeros(3, 4, 5);

julia> A[:] = 1:60;

julia> Aview = view(A, :, 2, :);

julia> ArrayInterface.StrideIndex(Aview)[1,1]
1

julia> Aview[ArrayInterface.StrideIndex(Aview)[1,1]]
4.0

julia> Aview[1,1]
4.0

What's the desired behavior here? I guess (for efficiency), that it returns a linear index into the memory of the array?

In that case, the StrideIndex object should carry an offset. The offset should default to Zero() for most array types, for subarrays should be calculated using the offsets implied by the non-colon indices. E.g., (2 - offset(A,2)) * stride(A,2) for the first example, and (2 - offset(A,1)) * stride(A,1) for the second.

chriselrod avatar Aug 11 '21 18:08 chriselrod

Also, methods like pointer do the offsetting for you:

julia> using ArrayInterface

julia> A = zeros(3, 4, 5);

julia> A[:] = 1:60;

julia> Aview = view(A, :, 2, :);

julia> unsafe_load(pointer(Aview), ArrayInterface.StrideIndex(Aview)[1,1])
4.0

julia> Aview[1,1]
4.0

julia> Aview = view(A, 2, :, :);

julia> unsafe_load(pointer(Aview), ArrayInterface.StrideIndex(Aview)[1,1])
2.0

julia> Aview[1,1]
2.0

chriselrod avatar Aug 13 '21 04:08 chriselrod