Skip to content

Commit 75ee2e4

Browse files
committed
Extend test
Since `getindex`/`setindex!` might be strided-based, we use `WrapperArray{T,N,<:Array}` to make sure the general fallback is tested thoroughly.
1 parent 6cc5d9b commit 75ee2e4

File tree

2 files changed

+132
-91
lines changed

2 files changed

+132
-91
lines changed

test/reinterpretarray.jl

Lines changed: 129 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,28 @@ using .Main.OffsetArrays
66
isdefined(Main, :TSlow) || @eval Main include("testhelpers/arrayindexingtypes.jl")
77
using .Main: TSlow, WrapperArray
88

9+
tslow(a::AbstractArray) = TSlow(a)
10+
wrapper(a::AbstractArray) = WrapperArray(a)
11+
fcviews(a::AbstractArray) = view(a, ntuple(Returns(:),ndims(a)-1)..., axes(a)[end])
12+
fcviews(a::AbstractArray{<:Any, 0}) = view(a)
13+
tslow(t::Tuple) = map(tslow, t)
14+
wrapper(t::Tuple) = map(wrapper, t)
15+
fcviews(t::Tuple) = map(fcviews, t)
16+
17+
test_many_wrappers(testf, A, wrappers) = foreach(w -> testf(w(A)), wrappers)
18+
test_many_wrappers(testf, A) = test_many_wrappers(testf, A, (identity, tslow, wrapper, fcviews))
19+
920
A = Int64[1, 2, 3, 4]
10-
As = TSlow(A)
1121
Ars = Int64[1 3; 2 4]
12-
Arss = TSlow(Ars)
1322
B = Complex{Int64}[5+6im, 7+8im, 9+10im]
14-
Bs = TSlow(B)
1523
Av = [Int32[1,2], Int32[3,4]]
1624

17-
for Ar in (Ars, Arss)
25+
test_many_wrappers(Ars, (identity, tslow)) do Ar
1826
@test @inferred(ndims(reinterpret(reshape, Complex{Int64}, Ar))) == 1
1927
@test @inferred(axes(reinterpret(reshape, Complex{Int64}, Ar))) === (Base.OneTo(2),)
2028
@test @inferred(size(reinterpret(reshape, Complex{Int64}, Ar))) == (2,)
2129
end
22-
for _B in (B, Bs)
30+
test_many_wrappers(B, (identity, tslow)) do _B
2331
@test @inferred(ndims(reinterpret(reshape, Int64, _B))) == 2
2432
@test @inferred(axes(reinterpret(reshape, Int64, _B))) === (Base.OneTo(2), Base.OneTo(3))
2533
@test @inferred(size(reinterpret(reshape, Int64, _B))) == (2, 3)
@@ -42,24 +50,25 @@ end
4250
@test_throws ArgumentError("cannot reinterpret a zero-dimensional `UInt8` array to `UInt16` which is of a larger size") reinterpret(reshape, UInt16, reshape([0x01]))
4351

4452
# getindex
45-
for _A in (A, As)
53+
test_many_wrappers(A) do _A
4654
@test reinterpret(Complex{Int64}, _A) == [1 + 2im, 3 + 4im]
4755
@test reinterpret(Float64, _A) == reinterpret.(Float64, A)
4856
@test reinterpret(reshape, Float64, _A) == reinterpret.(Float64, A)
4957
end
50-
for Ar in (Ars, Arss)
58+
test_many_wrappers(Ars) do Ar
5159
@test reinterpret(reshape, Complex{Int64}, Ar) == [1 + 2im, 3 + 4im]
5260
@test reinterpret(reshape, Float64, Ar) == reinterpret.(Float64, Ars)
5361
end
5462

55-
for _B in (B, Bs)
63+
test_many_wrappers(B) do _B
5664
@test reinterpret(NTuple{3, Int64}, _B) == [(5,6,7),(8,9,10)]
5765
@test reinterpret(reshape, Int64, _B) == [5 7 9; 6 8 10]
5866
end
5967

6068
# setindex
61-
for (_A, Ar, _B) in ((A, Ars, B), (As, Arss, Bs))
62-
let Ac = copy(_A), Arsc = copy(Ar), Bc = copy(_B)
69+
test_many_wrappers((A, Ars, B)) do (A, Ars, B)
70+
_A, Ar, _B = deepcopy(A), deepcopy(Ars), deepcopy(B)
71+
let Ac = deepcopy(_A), Arsc = deepcopy(Ar), Bc = deepcopy(_B)
6372
reinterpret(Complex{Int64}, Ac)[2] = -1 - 2im
6473
@test Ac == [1, 2, -1, -2]
6574
reinterpret(Complex{Int64}, Arsc)[2] = -1 - 2im
@@ -94,50 +103,67 @@ for (_A, Ar, _B) in ((A, Ars, B), (As, Arss, Bs))
94103
end
95104
end
96105
A3 = collect(reshape(1:18, 2, 3, 3))
97-
A3r = reinterpret(reshape, Complex{Int}, A3)
98-
@test A3r[4] === A3r[1,2] === A3r[CartesianIndex(1, 2)] === 7+8im
99-
A3r[2,3] = -8-15im
100-
@test A3[1,2,3] == -8
101-
@test A3[2,2,3] == -15
102-
A3r[4] = 100+200im
103-
@test A3[1,1,2] == 100
104-
@test A3[2,1,2] == 200
105-
A3r[CartesianIndex(1,2)] = 300+400im
106-
@test A3[1,1,2] == 300
107-
@test A3[2,1,2] == 400
106+
test_many_wrappers(A3) do A3_
107+
A3 = deepcopy(A3_)
108+
A3r = reinterpret(reshape, Complex{Int}, A3)
109+
@test A3r[4] === A3r[1,2] === A3r[CartesianIndex(1, 2)] === 7+8im
110+
A3r[2,3] = -8-15im
111+
@test A3[1,2,3] == -8
112+
@test A3[2,2,3] == -15
113+
A3r[4] = 100+200im
114+
@test A3[1,1,2] == 100
115+
@test A3[2,1,2] == 200
116+
A3r[CartesianIndex(1,2)] = 300+400im
117+
@test A3[1,1,2] == 300
118+
@test A3[2,1,2] == 400
119+
end
108120

109121
# same-size reinterpret where one of the types is non-primitive
110-
let a = NTuple{4,UInt8}[(0x01,0x02,0x03,0x04)], ra = reinterpret(Float32, a)
111-
@test ra[1] == reinterpret(Float32, 0x04030201)
112-
@test setindex!(ra, 2.0) === ra
113-
@test reinterpret(Float32, a)[1] == 2.0
122+
let a = NTuple{4,UInt8}[(0x01,0x02,0x03,0x04)]
123+
test_many_wrappers(a, (identity, wrapper, fcviews)) do a_
124+
a = deepcopy(a_)
125+
ra = reinterpret(Float32, a)
126+
@test ra[1] == reinterpret(Float32, 0x04030201)
127+
@test setindex!(ra, 2.0) === ra
128+
@test reinterpret(Float32, a)[1] == 2.0
129+
end
114130
end
115-
let a = NTuple{4,UInt8}[(0x01,0x02,0x03,0x04)], ra = reinterpret(reshape, Float32, a)
116-
@test ra[1] == reinterpret(Float32, 0x04030201)
117-
@test setindex!(ra, 2.0) === ra
118-
@test reinterpret(reshape, Float32, a)[1] == 2.0
131+
let a = NTuple{4,UInt8}[(0x01,0x02,0x03,0x04)]
132+
test_many_wrappers(a, (identity, wrapper, fcviews)) do a_
133+
a = deepcopy(a_)
134+
ra = reinterpret(reshape, Float32, a)
135+
@test ra[1] == reinterpret(Float32, 0x04030201)
136+
@test setindex!(ra, 2.0) === ra
137+
@test reinterpret(reshape, Float32, a)[1] == 2.0
138+
end
119139
end
120140

121141
# Pass-through indexing
122142
B = Complex{Int64}[5+6im, 7+8im, 9+10im]
123-
Br = reinterpret(reshape, Int64, B)
124-
W = WrapperArray(Br)
125-
for (b, w) in zip(5:10, W)
126-
@test b == w
127-
end
128-
for (i, j) in zip(eachindex(W), 11:16)
129-
W[i] = j
143+
test_many_wrappers(B) do B_
144+
B = deepcopy(B_)
145+
Br = reinterpret(reshape, Int64, B)
146+
W = WrapperArray(Br)
147+
for (b, w) in zip(5:10, W)
148+
@test b == w
149+
end
150+
for (i, j) in zip(eachindex(W), 11:16)
151+
W[i] = j
152+
end
153+
@test B[1] === Complex{Int64}(11+12im)
154+
@test B[2] === Complex{Int64}(13+14im)
155+
@test B[3] === Complex{Int64}(15+16im)
130156
end
131-
@test B[1] === Complex{Int64}(11+12im)
132-
@test B[2] === Complex{Int64}(13+14im)
133-
@test B[3] === Complex{Int64}(15+16im)
134157
z3 = (0x00, 0x00, 0x00)
135158
Az = [z3 z3; z3 z3]
136-
Azr = reinterpret(reshape, UInt8, Az)
137-
W = WrapperArray(Azr)
138-
copyto!(W, fill(0x01, 3, 2, 2))
139-
@test all(isequal((0x01, 0x01, 0x01)), Az)
140-
@test eachindex(W, W) == eachindex(W)
159+
test_many_wrappers(Az, (identity, wrapper)) do Az_
160+
Az = deepcopy(Az_)
161+
Azr = reinterpret(reshape, UInt8, Az)
162+
W = WrapperArray(Azr)
163+
copyto!(W, fill(0x01, 3, 2, 2))
164+
@test all(isequal((0x01, 0x01, 0x01)), Az)
165+
@test eachindex(W, W) == eachindex(W)
166+
end
141167

142168
# ensure that reinterpret arrays aren't erroneously classified as strided
143169
let A = reshape(1:20, 5, 4)
@@ -169,7 +195,7 @@ function check_strides(A::AbstractArray)
169195
end
170196

171197
@testset "strides for NonReshapedReinterpretArray" begin
172-
A = Array{Int32}(reshape(1:88, 11, 8))
198+
A = WrapperArray(Array{Int32}(reshape(1:88, 11, 8)))
173199
for viewax2 in (1:8, 1:2:6, 7:-1:1, 5:-2:1, 2:3:8, 7:-6:1, 3:5:11)
174200
# dim1 is contiguous
175201
for T in (Int16, Float32)
@@ -200,7 +226,7 @@ end
200226
end
201227

202228
@testset "strides for ReshapedReinterpretArray" begin
203-
A = Array{Int32}(reshape(1:192, 3, 8, 8))
229+
A = WrapperArray(Array{Int32}(reshape(1:192, 3, 8, 8)))
204230
for viewax1 in (1:8, 1:2:8, 8:-1:1, 8:-2:1), viewax2 in (1:2, 4:-1:1)
205231
for T in (Int16, Float32)
206232
@test check_strides(reinterpret(reshape, T, view(A, 1:2, viewax1, viewax2)))
@@ -237,7 +263,8 @@ end
237263
end
238264

239265
# IndexStyle
240-
let a = fill(1.0, 5, 3)
266+
test_many_wrappers(fill(1.0, 5, 3), (identity, wrapper)) do a_
267+
a = deepcopy(a_)
241268
r = reinterpret(Int64, a)
242269
@test @inferred(IndexStyle(r)) == IndexLinear()
243270
fill!(r, 2)
@@ -290,14 +317,13 @@ let a = fill(1.0, 5, 3)
290317
@test setindex!(r, -5, goodinds...) === r
291318
@test r[goodinds...] == -5
292319
end
293-
294-
ar = [(1,2), (3,4)]
320+
end
321+
let ar = [(1,2), (3,4)]
295322
arr = reinterpret(reshape, Int, ar)
296323
@test @inferred(IndexStyle(arr)) == Base.IndexSCartesian2{2}()
297324
@test @inferred(eachindex(arr)) == Base.SCartesianIndices2{2}(Base.OneTo(2))
298325
@test @inferred(eachindex(arr, arr)) == Base.SCartesianIndices2{2}(Base.OneTo(2))
299326
end
300-
301327
# Error on reinterprets that would expose padding
302328
struct S1
303329
a::Int8
@@ -311,11 +337,14 @@ end
311337

312338
A1 = S1[S1(0, 0)]
313339
A2 = S2[S2(0, 0)]
314-
@test reinterpret(S1, A2)[1] == S1(0, 0)
315-
@test_throws Base.PaddingError (reinterpret(S1, A2)[1] = S2(1, 2))
316-
@test_throws Base.PaddingError reinterpret(S2, A1)[1]
317-
reinterpret(S2, A1)[1] = S2(1, 2)
318-
@test A1[1] == S1(1, 2)
340+
test_many_wrappers((A1, A2), (identity, wrapper)) do (A1_, A2_)
341+
A1, A2 = deepcopy(A1_), deepcopy(A2_)
342+
@test reinterpret(S1, A2)[1] == S1(0, 0)
343+
@test_throws Base.PaddingError (reinterpret(S1, A2)[1] = S2(1, 2))
344+
@test_throws Base.PaddingError reinterpret(S2, A1)[1]
345+
reinterpret(S2, A1)[1] = S2(1, 2)
346+
@test A1[1] == S1(1, 2)
347+
end
319348

320349
# Unconventional axes
321350
let a = [0.1 0.2; 0.3 0.4], at = reshape([(i,i+1) for i = 1:2:8], 2, 2)
@@ -368,50 +397,59 @@ end
368397

369398
# Test 0-dimensional Arrays
370399
A = zeros(UInt32)
371-
B = reinterpret(Int32, A)
372-
Brs = reinterpret(reshape,Int32, A)
373-
C = reinterpret(Tuple{UInt32}, A) # non-primitive type
374-
Crs = reinterpret(reshape, Tuple{UInt32}, A) # non-primitive type
375-
@test size(B) == size(Brs) == size(C) == size(Crs) == ()
376-
@test axes(B) == axes(Brs) == axes(C) == axes(Crs) == ()
377-
@test setindex!(B, Int32(5)) === B
378-
@test B[] === Int32(5)
379-
@test Brs[] === Int32(5)
380-
@test C[] === (UInt32(5),)
381-
@test Crs[] === (UInt32(5),)
382-
@test A[] === UInt32(5)
383-
@test setindex!(Brs, Int32(12)) === Brs
384-
@test A[] === UInt32(12)
385-
@test setindex!(C, (UInt32(7),)) === C
386-
@test A[] === UInt32(7)
387-
@test setindex!(Crs, (UInt32(3),)) === Crs
388-
@test A[] === UInt32(3)
389-
390-
391-
a = [(1.0,2.0)]
392-
af = @inferred(reinterpret(reshape, Float64, a))
393-
anew = @inferred(reinterpret(reshape, Tuple{Float64,Float64}, vec(af)))
394-
@test anew[1] == a[1]
395-
@test ndims(anew) == 0
400+
test_many_wrappers(A, (identity, wrapper)) do A_
401+
A = deepcopy(A_)
402+
B = reinterpret(Int32, A)
403+
Brs = reinterpret(reshape,Int32, A)
404+
C = reinterpret(Tuple{UInt32}, A) # non-primitive type
405+
Crs = reinterpret(reshape, Tuple{UInt32}, A) # non-primitive type
406+
@test size(B) == size(Brs) == size(C) == size(Crs) == ()
407+
@test axes(B) == axes(Brs) == axes(C) == axes(Crs) == ()
408+
@test setindex!(B, Int32(5)) === B
409+
@test B[] === Int32(5)
410+
@test Brs[] === Int32(5)
411+
@test C[] === (UInt32(5),)
412+
@test Crs[] === (UInt32(5),)
413+
@test A[] === UInt32(5)
414+
@test setindex!(Brs, Int32(12)) === Brs
415+
@test A[] === UInt32(12)
416+
@test setindex!(C, (UInt32(7),)) === C
417+
@test A[] === UInt32(7)
418+
@test setindex!(Crs, (UInt32(3),)) === Crs
419+
@test A[] === UInt32(3)
420+
end
421+
422+
test_many_wrappers([(1.0,2.0)], (identity, wrapper)) do a
423+
af = @inferred(reinterpret(reshape, Float64, a))
424+
anew = @inferred(reinterpret(reshape, Tuple{Float64,Float64}, vec(af)))
425+
@test anew[1] == a[1]
426+
@test ndims(anew) == 0
427+
end
396428

397429
# re-reinterpret
398430
a0 = reshape([0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04], 4, 2)
399-
a = reinterpret(reshape, NTuple{4,UInt8}, a0)
400-
@test a == [(0x22, 0x44, 0x88, 0xf0), (0x01, 0x02, 0x03, 0x04)]
401-
@test reinterpret(UInt8, a) == [0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04]
402-
@test reinterpret(reshape, UInt8, a) === a0
431+
test_many_wrappers(a0, (identity, wrapper)) do a0
432+
a = reinterpret(reshape, NTuple{4,UInt8}, a0)
433+
@test a == [(0x22, 0x44, 0x88, 0xf0), (0x01, 0x02, 0x03, 0x04)]
434+
@test reinterpret(UInt8, a) == [0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04]
435+
@test reinterpret(reshape, UInt8, a) === a0
436+
end
403437

404438
# reductions
405439
a = [(1,2,3), (4,5,6)]
406-
ars = reinterpret(reshape, Int, a)
407-
@test sum(ars) == 21
408-
@test sum(ars; dims=1) == [6 15]
409-
@test sum(ars; dims=2) == reshape([5,7,9], (3, 1))
410-
@test sum(ars; dims=(1,2)) == reshape([21], (1, 1))
440+
test_many_wrappers(a, (identity, wrapper)) do a
441+
ars = reinterpret(reshape, Int, a)
442+
@test sum(ars) == 21
443+
@test sum(ars; dims=1) == [6 15]
444+
@test sum(ars; dims=2) == reshape([5,7,9], (3, 1))
445+
@test sum(ars; dims=(1,2)) == reshape([21], (1, 1))
446+
end
411447
# also test large sizes for the pairwise algorithm
412448
a = [(k,k+1,k+2) for k = 1:3:4000]
413-
ars = reinterpret(reshape, Int, a)
414-
@test sum(ars) == 8010003
449+
test_many_wrappers(a, (identity, wrapper)) do a
450+
ars = reinterpret(reshape, Int, a)
451+
@test sum(ars) == 8010003
452+
end
415453

416454
@testset "similar(::ReinterpretArray)" begin
417455
a = reinterpret(NTuple{2,Float64}, TSlow(rand(Float64, 4, 4)))

test/testhelpers/arrayindexingtypes.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,6 @@ Base.axes(A::WrapperArray) = axes(A.parent)
6666
Base.getindex(A::WrapperArray, i::Int...) = A.parent[i...]
6767
Base.setindex!(A::WrapperArray, v, i::Int...) = A.parent[i...] = v
6868
Base.similar(A::WrapperArray, ::Type{T}, dims::Dims) where T = similar(A.parent, T, dims)
69+
Base.unsafe_convert(::Type{Ptr{T}}, A::WrapperArray{T}) where {T} = Base.unsafe_convert(Ptr{T}, A.parent)
70+
Base.strides(A::WrapperArray) = strides(A.parent)
71+
Base.elsize(::Type{WrapperArray{T,N,A}}) where {T,N,A<:AbstractArray{T,N}} = Base.elsize(A)

0 commit comments

Comments
 (0)