Skip to content

Commit

Permalink
Extend the type coverage, and give more control to back-ends. (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
troels authored Aug 25, 2021
1 parent 0ada3f9 commit adb914e
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 189 deletions.
21 changes: 16 additions & 5 deletions test/testsuite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,28 @@ function compare(f, AT::Type{<:Array}, xs...; kwargs...)
return true
end

function supported_eltypes()
(Float32, Float64, Int32, Int64, ComplexF32, ComplexF64)
end
# element types that are supported by the array type
supported_eltypes(AT, test) = supported_eltypes(AT)
supported_eltypes(AT) = supported_eltypes()
supported_eltypes() = (Int16, Int32, Int64,
Float16, Float32, Float64,
ComplexF16, ComplexF32, ComplexF64,
Complex{Int16}, Complex{Int32}, Complex{Int64})

# some convenience predicates for filtering test eltypes
isrealtype(T) = T <: Real
iscomplextype(T) = T <: Complex
isfloattype(T) = T <: AbstractFloat || T <: Complex{<:AbstractFloat}

# list of tests
const tests = Dict()
macro testsuite(name, ex)
safe_name = lowercase(replace(name, " "=>"_"))
safe_name = lowercase(replace(replace(name, " "=>"_"), "/"=>"_"))
fn = Symbol("test_$(safe_name)")
quote
$(esc(fn))(AT) = $(esc(ex))(AT)
# the supported element types can be overrided by passing in a different set,
# or by specializing the `supported_eltypes` function on the array type and test.
$(esc(fn))(AT; eltypes=supported_eltypes(AT, $(esc(fn)))) = $(esc(ex))(AT, eltypes)

@assert !haskey(tests, $name)
tests[$name] = $fn
Expand Down
52 changes: 27 additions & 25 deletions test/testsuite/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function ntuple_closure(ctx, result, ::Val{N}, testval) where N
return
end

@testsuite "base" AT->begin
@testsuite "base" (AT, eltypes)->begin
@testset "copyto!" begin
x = fill(0f0, (10, 10))
y = rand(Float32, (20, 10))
Expand Down Expand Up @@ -70,15 +70,15 @@ end
copyto!(a, r1, b, r2)
@test x == Array(a)

x = fill(0., (10,))
y = fill(1, (10,))
x = fill(0f0, (10,))
y = fill(1f0, (10,))
a = AT(x)
b = AT(y)
copyto!(a, b)
@test Float64.(y) == Array(a)
@test Float32.(y) == Array(a)

# wrapped gpu array to wrapped gpu array
x = rand(4, 4)
x = rand(Float32, 4, 4)
a = AT(x)
b = view(a, 2:3, 2:3)
c = AT{eltype(b)}(undef, size(b))
Expand All @@ -95,21 +95,23 @@ end

# bug in copyto!
## needless N type parameter
@test compare((x,y)->copyto!(y, selectdim(x, 2, 1)), AT, ones(2,2,2), zeros(2,2))
@test compare((x,y)->copyto!(y, selectdim(x, 2, 1)), AT, ones(Float32, 2, 2, 2), zeros(Float32, 2, 2))
## inability to copyto! smaller destination
## (this was broken on Julia <1.5)
@test compare((x,y)->copyto!(y, selectdim(x, 2, 1)), AT, ones(2,2,2), zeros(3,3))

# mismatched types
let src = rand(Float32, 4)
dst = AT{Float64}(undef, size(src))
copyto!(dst, src)
@test Array(dst) == src
end
let dst = Array{Float64}(undef, 4)
src = AT(rand(Float32, size(dst)))
copyto!(dst, src)
@test Array(src) == dst
@test compare((x,y)->copyto!(y, selectdim(x, 2, 1)), AT, ones(Float32, 2, 2, 2), zeros(Float32, 3, 3))

if (Float32 in eltypes && Float64 in eltypes)
# mismatched types
let src = rand(Float32, 4)
dst = AT{Float64}(undef, size(src))
copyto!(dst, src)
@test Array(dst) == src
end
let dst = Array{Float64}(undef, 4)
src = AT(rand(Float32, size(dst)))
copyto!(dst, src)
@test Array(src) == dst
end
end
end

Expand All @@ -123,11 +125,11 @@ end
end

@testset "reshape" begin
@test compare(reshape, AT, rand(10), Ref((10,)))
@test compare(reshape, AT, rand(10), Ref((10,1)))
@test compare(reshape, AT, rand(10), Ref((1,10)))
@test compare(reshape, AT, rand(Float32, 10), Ref((10,)))
@test compare(reshape, AT, rand(Float32, 10), Ref((10,1)))
@test compare(reshape, AT, rand(Float32, 10), Ref((1,10)))

@test_throws Exception reshape(AT(rand(10)), (10,2))
@test_throws Exception reshape(AT(rand(Float32, 10)), (10,2))
end

@testset "reinterpret" begin
Expand Down Expand Up @@ -158,7 +160,7 @@ end
AT <: AbstractGPUArray && @testset "cartesian iteration" begin
Ac = rand(Float32, 32, 32)
A = AT(Ac)
result = fill!(copy(A), 0.0)
result = fill!(copy(A), 0.0f0)
gpu_call(cartesian_iter, result, A, size(A))
Array(result) == Ac
end
Expand Down Expand Up @@ -188,10 +190,10 @@ end
end

@testset "permutedims" begin
@test compare(x->permutedims(x, [1, 2]), AT, rand(4, 4))
@test compare(x->permutedims(x, [1, 2]), AT, rand(Float32, 4, 4))

inds = rand(1:100, 150, 150)
@test compare(x->permutedims(view(x, inds, :), (3, 2, 1)), AT, rand(100, 100))
@test compare(x->permutedims(view(x, inds, :), (3, 2, 1)), AT, rand(Float32, 100, 100))
end

@testset "circshift" begin
Expand Down
67 changes: 34 additions & 33 deletions test/testsuite/broadcasting.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@testsuite "broadcasting" AT->begin
broadcasting(AT)
vec3(AT)
@testsuite "broadcasting" (AT, eltypes)->begin
broadcasting(AT, eltypes)
vec3(AT, eltypes)

@testset "type instabilities" begin
f(x) = x ? 1.0 : 0
Expand Down Expand Up @@ -37,8 +37,8 @@ function test_kernel(a::T, b) where T
return c
end

function broadcasting(AT)
for ET in supported_eltypes()
function broadcasting(AT, eltypes)
for ET in eltypes
N = 10
@testset "broadcast $ET" begin
@testset "RefValue" begin
Expand Down Expand Up @@ -91,7 +91,8 @@ function broadcasting(AT)
# since GPUArrays adds some arguments to the function, it becomes longer longer, hitting the 12
# so this wont fix for now
@test compare(AT, rand(ET, dim), rand(ET, dim), rand(ET, dim), rand(ET, dim), rand(ET, dim), rand(ET, dim)) do a1, a2, a3, a4, a5, a6
@. a1 = a2 + (1.2) *((1.3)*a3 + (1.4)*a4 + (1.5)*a5 + (1.6)*a6)
c1, c2, c3, c4, c5 = ET(1.2), ET(1.3), ET(1.4), ET(1.5), ET(1.6)
@. a1 = a2 + c1 * (c2 * a3 + c3 * a4 + c4 * a5 + c5 * a6)
end

@test compare(AT, rand(ET, dim), rand(ET, dim), rand(ET, dim), rand(ET, dim)) do u, uprev, duprev, ku
Expand All @@ -110,6 +111,14 @@ function broadcasting(AT)
dt = ET(1)
@. utilde = dt*(btilde1*k1 + btilde2*k2 + btilde3*k3 + btilde4*k4)
end

@testset "0D" begin
x = AT{ET}(undef)
x .= ET(1)
@test collect(x)[] == ET(1)
x /= ET(2)
@test collect(x)[] == ET(0.5)
end
end

@test compare((x) -> fill!(x, 1), AT, rand(ET, 3,3))
Expand All @@ -127,59 +136,51 @@ function broadcasting(AT)
end

@testset "map! $ET" begin
@test compare(AT, rand(2,2), rand(2,2)) do x,y
@test compare(AT, rand(ET, 2,2), rand(ET, 2,2)) do x,y
map!(+, x, y)
end
@test compare(AT, rand(2), rand(2,2)) do x,y
@test compare(AT, rand(ET, 2), rand(ET, 2,2)) do x,y
map!(+, x, y)
end
@test compare(AT, rand(2,2), rand(2)) do x,y
@test compare(AT, rand(ET, 2,2), rand(ET, 2)) do x,y
map!(+, x, y)
end
end

@testset "map $ET" begin
@test compare(AT, rand(2,2), rand(2,2)) do x,y
@test compare(AT, rand(ET, 2,2), rand(ET, 2,2)) do x,y
map(+, x, y)
end
@test compare(AT, rand(2), rand(2,2)) do x,y
@test compare(AT, rand(ET, 2), rand(ET, 2,2)) do x,y
map(+, x, y)
end
@test compare(AT, rand(2,2), rand(2)) do x,y
@test compare(AT, rand(ET, 2,2), rand(ET, 2)) do x,y
map(+, x, y)
end
end
end

@testset "0D" begin
x = AT{Float64}(undef)
x .= 1
@test collect(x)[] == 1
x /= 2
@test collect(x)[] == 0.5
end

@testset "Ref" begin
# as first arg, 0d broadcast
@test compare(x->getindex.(Ref(x),1), AT, [0])
@testset "Ref" begin
# as first arg, 0d broadcast
@test compare(x->getindex.(Ref(x), 1), AT, ET[0])

void_setindex!(args...) = (setindex!(args...); return)
@test compare(x->(void_setindex!.(Ref(x),1); x), AT, [0])
void_setindex!(args...) = (setindex!(args...); return)
@test compare(x->(void_setindex!.(Ref(x), ET(1)); x), AT, ET[0])

# regular broadcast
a = AT(rand(10))
b = AT(rand(10))
cpy(i,a,b) = (a[i] = b[i]; return)
cpy.(1:10, Ref(a), Ref(b))
@test Array(a) == Array(b)
# regular broadcast
a = AT(rand(ET, 10))
b = AT(rand(ET, 10))
cpy(i,a,b) = (a[i] = b[i]; return)
cpy.(1:10, Ref(a), Ref(b))
@test Array(a) == Array(b)
end
end

@testset "stackoverflow in copy(::Broadcast)" begin
copy(Base.broadcasted(identity, AT(Int[])))
end
end

function vec3(AT)
function vec3(AT, eltypes)
@testset "vec 3" begin
N = 20

Expand Down
28 changes: 17 additions & 11 deletions test/testsuite/construction.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@testsuite "construct/direct" AT->begin
for T in supported_eltypes()
@testsuite "construct/direct" (AT, eltypes)->begin
for T in eltypes
B = AT{T}(undef, 10)
@test B isa AT{T,1}
@test size(B) == (10,)
Expand Down Expand Up @@ -45,8 +45,8 @@
end
end

@testsuite "construct/similar" AT->begin
for T in supported_eltypes()
@testsuite "construct/similar" (AT, eltypes)->begin
for T in eltypes
B = AT{T}(undef, 10)

B = similar(B, Int32, 11, 15)
Expand Down Expand Up @@ -96,8 +96,8 @@ end
end
end

@testsuite "construct/convenience" AT->begin
for T in supported_eltypes()
@testsuite "construct/convenience" (AT, eltypes)->begin
for T in eltypes
A = AT(rand(T, 3))
b = rand(T)
fill!(A, b)
Expand Down Expand Up @@ -126,8 +126,8 @@ end
end
end

@testsuite "construct/conversions" AT->begin
for T in supported_eltypes()
@testsuite "construct/conversions" (AT, eltypes)->begin
for T in eltypes
Bc = round.(rand(10, 10) .* 10.0)
B = AT{T}(Bc)
@test size(B) == (10, 10)
Expand All @@ -146,16 +146,22 @@ end
@test eltype(B) == T
@test Array(B) Bc

Bc = rand(Int32, 3, 3, 3)
intervals = Dict(
Float16 => -2^11:2^11,
Float32 => -2^24:2^24,
Float64 => -2^53:2^53,
)

Bc = rand(Int8, 3, 3, 3)
B = convert(AT{T, 3}, Bc)
@test size(B) == (3, 3, 3)
@test eltype(B) == T
@test Array(B) Bc
end
end

@testsuite "construct/uniformscaling" AT->begin
for T in supported_eltypes()
@testsuite "construct/uniformscaling" (AT, eltypes)->begin
for T in eltypes
x = Matrix{T}(I, 4, 2)

x1 = AT{T, 2}(I, 4, 2)
Expand Down
2 changes: 1 addition & 1 deletion test/testsuite/gpuinterface.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@testsuite "interface" AT->begin
@testsuite "interface" (AT, eltypes)->begin
AT <: AbstractGPUArray || return

N = 10
Expand Down
Loading

0 comments on commit adb914e

Please sign in to comment.