diff --git a/test/testsuite.jl b/test/testsuite.jl index 9c285af8..54f90355 100644 --- a/test/testsuite.jl +++ b/test/testsuite.jl @@ -74,7 +74,6 @@ end include("testsuite/construction.jl") include("testsuite/gpuinterface.jl") include("testsuite/indexing.jl") -include("testsuite/io.jl") include("testsuite/base.jl") #include("testsuite/vector.jl") include("testsuite/reductions.jl") diff --git a/test/testsuite/base.jl b/test/testsuite/base.jl index b7ab3214..7e8fe7d5 100644 --- a/test/testsuite/base.jl +++ b/test/testsuite/base.jl @@ -207,4 +207,38 @@ end @test Array(b) == [0] @test Array(a) == [1] end + + @testset "input output" begin + # compact=false to avoid type aliases + replstr(x, kv::Pair...) = sprint((io,x) -> show(IOContext(io, :compact => false, :limit => true, :displaysize => (24, 80), kv...), MIME("text/plain"), x), x) + showstr(x, kv::Pair...) = sprint((io,x) -> show(IOContext(io, :limit => true, :displaysize => (24, 80), kv...), x), x) + + @testset "showing" begin + # vectors and non-vector arrays showing + # are handled differently in base/arrayshow.jl + A = AT(Int64[1]) + B = AT(Int64[1 2;3 4]) + + msg = replstr(A) + @test occursin(Regex("^1-element $AT{Int64,\\s?1.*}:\n 1\$"), msg) + + # # result of e.g. `print` differs on 32bit and 64bit machines + # due to different definition of `Int` type + # print([1]) shows as [1] on 64bit but Int64[1] on 32bit + msg = showstr(A) + @test msg == "[1]" || msg == "Int64[1]" + + msg = replstr(B) + @test occursin(Regex("^2×2 $AT{Int64,\\s?2.*}:\n 1 2\n 3 4\$"), msg) + + msg = showstr(B) + @test msg == "[1 2; 3 4]" || msg == "Int64[1 2; 3 4]" + + # the printing of Adjoint depends on global state + msg = replstr(A') + @test occursin(Regex("^1×1 Adjoint{Int64,\\s?$AT{Int64,\\s?1.*}}:\n 1\$"), msg) || + occursin(Regex("^1×1 LinearAlgebra.Adjoint{Int64,\\s?$AT{Int64,\\s?1.*}}:\n 1\$"), msg) || + occursin(Regex("^1×1 adjoint\\(::$AT{Int64,\\s?1.*}\\) with eltype Int64:\n 1\$"), msg) + end + end end diff --git a/test/testsuite/construction.jl b/test/testsuite/construction.jl index 676995c7..56cb54aa 100644 --- a/test/testsuite/construction.jl +++ b/test/testsuite/construction.jl @@ -1,180 +1,182 @@ -@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,) - @test eltype(B) == T - - B = AT{T}(undef, 10, 10) - @test B isa AT{T,2} - @test size(B) == (10, 10) - @test eltype(B) == T - - B = AT{T}(undef, (10, 10)) - @test B isa AT{T,2} - @test size(B) == (10, 10) - @test eltype(B) == T - end - - # compare against Array - for typs in [(), (Int,), (Int,1), (Int,2), (Float32,), (Float32,1), (Float32,2)], - args in [(), (1,), (1,2), ((1,),), ((1,2),), - (undef,), (undef, 1,), (undef, 1,2), (undef, (1,),), (undef, (1,2),), - (Int,), (Int, 1,), (Int, 1,2), (Int, (1,),), (Int, (1,2),), - ([1,2],), ([1 2],)] - cpu = try - Array{typs...}(args...) - catch ex - isa(ex, MethodError) || rethrow() - nothing - end - - gpu = try - AT{typs...}(args...) - catch ex - isa(ex, MethodError) || rethrow() - cpu == nothing || rethrow() - nothing +@testsuite "constructors" (AT, eltypes)->begin + @testset "direct" begin + for T in eltypes + B = AT{T}(undef, 10) + @test B isa AT{T,1} + @test size(B) == (10,) + @test eltype(B) == T + + B = AT{T}(undef, 10, 10) + @test B isa AT{T,2} + @test size(B) == (10, 10) + @test eltype(B) == T + + B = AT{T}(undef, (10, 10)) + @test B isa AT{T,2} + @test size(B) == (10, 10) + @test eltype(B) == T end - if cpu == nothing - @test gpu == nothing - else - @test typeof(cpu) == typeof(convert(Array, gpu)) + # compare against Array + for typs in [(), (Int,), (Int,1), (Int,2), (Float32,), (Float32,1), (Float32,2)], + args in [(), (1,), (1,2), ((1,),), ((1,2),), + (undef,), (undef, 1,), (undef, 1,2), (undef, (1,),), (undef, (1,2),), + (Int,), (Int, 1,), (Int, 1,2), (Int, (1,),), (Int, (1,2),), + ([1,2],), ([1 2],)] + cpu = try + Array{typs...}(args...) + catch ex + isa(ex, MethodError) || rethrow() + nothing + end + + gpu = try + AT{typs...}(args...) + catch ex + isa(ex, MethodError) || rethrow() + cpu == nothing || rethrow() + nothing + end + + if cpu == nothing + @test gpu == nothing + else + @test typeof(cpu) == typeof(convert(Array, gpu)) + end end end -end -@testsuite "construct/similar" (AT, eltypes)->begin - for T in eltypes - B = AT{T}(undef, 10) - - B = similar(B, Int32, 11, 15) - @test B isa AT{Int32,2} - @test size(B) == (11, 15) - @test eltype(B) == Int32 - - B = similar(B, T) - @test B isa AT{T,2} - @test size(B) == (11, 15) - @test eltype(B) == T - - B = similar(B, (5,)) - @test B isa AT{T,1} - @test size(B) == (5,) - @test eltype(B) == T - - B = similar(B, 7) - @test B isa AT{T,1} - @test size(B) == (7,) - @test eltype(B) == T - - B = similar(AT{Int32}, (11, 15)) - @test B isa AT{Int32,2} - @test size(B) == (11, 15) - @test eltype(B) == Int32 - - B = similar(AT{T}, (5,)) - @test B isa AT{T,1} - @test size(B) == (5,) - @test eltype(B) == T - - B = similar(AT{T}, 7) - @test B isa AT{T,1} - @test size(B) == (7,) - @test eltype(B) == T - - B = similar(Broadcast.Broadcasted(*, (B, B)), T) - @test B isa AT{T,1} - @test size(B) == (7,) - @test eltype(B) == T - - B = similar(Broadcast.Broadcasted(*, (B, B)), Int32, (11, 15)) - @test B isa AT{Int32,2} - @test size(B) == (11, 15) - @test eltype(B) == Int32 + @testset "similar" begin + for T in eltypes + B = AT{T}(undef, 10) + + B = similar(B, Int32, 11, 15) + @test B isa AT{Int32,2} + @test size(B) == (11, 15) + @test eltype(B) == Int32 + + B = similar(B, T) + @test B isa AT{T,2} + @test size(B) == (11, 15) + @test eltype(B) == T + + B = similar(B, (5,)) + @test B isa AT{T,1} + @test size(B) == (5,) + @test eltype(B) == T + + B = similar(B, 7) + @test B isa AT{T,1} + @test size(B) == (7,) + @test eltype(B) == T + + B = similar(AT{Int32}, (11, 15)) + @test B isa AT{Int32,2} + @test size(B) == (11, 15) + @test eltype(B) == Int32 + + B = similar(AT{T}, (5,)) + @test B isa AT{T,1} + @test size(B) == (5,) + @test eltype(B) == T + + B = similar(AT{T}, 7) + @test B isa AT{T,1} + @test size(B) == (7,) + @test eltype(B) == T + + B = similar(Broadcast.Broadcasted(*, (B, B)), T) + @test B isa AT{T,1} + @test size(B) == (7,) + @test eltype(B) == T + + B = similar(Broadcast.Broadcasted(*, (B, B)), Int32, (11, 15)) + @test B isa AT{Int32,2} + @test size(B) == (11, 15) + @test eltype(B) == Int32 + end end -end -@testsuite "construct/convenience" (AT, eltypes)->begin - for T in eltypes - A = AT(rand(T, 3)) - b = rand(T) - fill!(A, b) - @test A isa AT{T,1} - @test Array(A) == fill(b, 3) - - A = zero(AT(rand(T, 2))) - @test A isa AT{T,1} - @test Array(A) == zero(rand(T, 2)) - - A = zero(AT(rand(T, 2, 2))) - @test A isa AT{T,2} - @test Array(A) == zero(rand(T, 2, 2)) - - A = zero(AT(rand(T, 2, 2, 2))) - @test A isa AT{T,3} - @test Array(A) == zero(rand(T, 2, 2, 2)) - - A = one(AT(rand(T, 2, 2))) - @test A isa AT{T,2} - @test Array(A) == one(rand(T, 2, 2)) - - A = oneunit(AT(rand(T, 2, 2))) - @test A isa AT{T,2} - @test Array(A) == oneunit(rand(T, 2, 2)) + @testset "convenience" begin + for T in eltypes + A = AT(rand(T, 3)) + b = rand(T) + fill!(A, b) + @test A isa AT{T,1} + @test Array(A) == fill(b, 3) + + A = zero(AT(rand(T, 2))) + @test A isa AT{T,1} + @test Array(A) == zero(rand(T, 2)) + + A = zero(AT(rand(T, 2, 2))) + @test A isa AT{T,2} + @test Array(A) == zero(rand(T, 2, 2)) + + A = zero(AT(rand(T, 2, 2, 2))) + @test A isa AT{T,3} + @test Array(A) == zero(rand(T, 2, 2, 2)) + + A = one(AT(rand(T, 2, 2))) + @test A isa AT{T,2} + @test Array(A) == one(rand(T, 2, 2)) + + A = oneunit(AT(rand(T, 2, 2))) + @test A isa AT{T,2} + @test Array(A) == oneunit(rand(T, 2, 2)) + end end -end -@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) - @test eltype(B) == T - @test Array(B) ≈ Bc - - Bc = rand(T, 10) - B = AT(Bc) - @test size(B) == (10,) - @test eltype(B) == T - @test Array(B) ≈ Bc - - Bc = rand(T, 10, 10) - B = AT{T, 2}(Bc) - @test size(B) == (10, 10) - @test eltype(B) == T - @test Array(B) ≈ Bc - - 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 + @testset "conversions" begin + for T in eltypes + Bc = round.(rand(10, 10) .* 10.0) + B = AT{T}(Bc) + @test size(B) == (10, 10) + @test eltype(B) == T + @test Array(B) ≈ Bc + + Bc = rand(T, 10) + B = AT(Bc) + @test size(B) == (10,) + @test eltype(B) == T + @test Array(B) ≈ Bc + + Bc = rand(T, 10, 10) + B = AT{T, 2}(Bc) + @test size(B) == (10, 10) + @test eltype(B) == T + @test Array(B) ≈ Bc + + 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 -end -@testsuite "construct/uniformscaling" (AT, eltypes)->begin - for T in eltypes - x = Matrix{T}(I, 4, 2) + @testset "uniformscaling" begin + for T in eltypes + x = Matrix{T}(I, 4, 2) - x1 = AT{T, 2}(I, 4, 2) - x2 = AT{T}(I, (4, 2)) - x3 = AT{T, 2}(I, (4, 2)) + x1 = AT{T, 2}(I, 4, 2) + x2 = AT{T}(I, (4, 2)) + x3 = AT{T, 2}(I, (4, 2)) - @test Array(x1) ≈ x - @test Array(x2) ≈ x - @test Array(x3) ≈ x + @test Array(x1) ≈ x + @test Array(x2) ≈ x + @test Array(x3) ≈ x - x = Matrix(T(3) * I, 2, 4) - x1 = AT(T(3) * I, 2, 4) - @test eltype(x1) == T - @test Array(x1) ≈ x + x = Matrix(T(3) * I, 2, 4) + x1 = AT(T(3) * I, 2, 4) + @test eltype(x1) == T + @test Array(x1) ≈ x + end end end diff --git a/test/testsuite/io.jl b/test/testsuite/io.jl deleted file mode 100644 index fc871154..00000000 --- a/test/testsuite/io.jl +++ /dev/null @@ -1,34 +0,0 @@ -@testsuite "input output" (AT, eltypes)->begin - - # compact=false to avoid type aliases - replstr(x, kv::Pair...) = sprint((io,x) -> show(IOContext(io, :compact => false, :limit => true, :displaysize => (24, 80), kv...), MIME("text/plain"), x), x) - showstr(x, kv::Pair...) = sprint((io,x) -> show(IOContext(io, :limit => true, :displaysize => (24, 80), kv...), x), x) - - @testset "showing" begin - # vectors and non-vector arrays showing - # are handled differently in base/arrayshow.jl - A = AT(Int64[1]) - B = AT(Int64[1 2;3 4]) - - msg = replstr(A) - @test occursin(Regex("^1-element $AT{Int64,\\s?1.*}:\n 1\$"), msg) - - # # result of e.g. `print` differs on 32bit and 64bit machines - # due to different definition of `Int` type - # print([1]) shows as [1] on 64bit but Int64[1] on 32bit - msg = showstr(A) - @test msg == "[1]" || msg == "Int64[1]" - - msg = replstr(B) - @test occursin(Regex("^2×2 $AT{Int64,\\s?2.*}:\n 1 2\n 3 4\$"), msg) - - msg = showstr(B) - @test msg == "[1 2; 3 4]" || msg == "Int64[1 2; 3 4]" - - # the printing of Adjoint depends on global state - msg = replstr(A') - @test occursin(Regex("^1×1 Adjoint{Int64,\\s?$AT{Int64,\\s?1.*}}:\n 1\$"), msg) || - occursin(Regex("^1×1 LinearAlgebra.Adjoint{Int64,\\s?$AT{Int64,\\s?1.*}}:\n 1\$"), msg) || - occursin(Regex("^1×1 adjoint\\(::$AT{Int64,\\s?1.*}\\) with eltype Int64:\n 1\$"), msg) - end -end diff --git a/test/testsuite/linalg.jl b/test/testsuite/linalg.jl index 0bc399d0..8dc9c58a 100644 --- a/test/testsuite/linalg.jl +++ b/test/testsuite/linalg.jl @@ -17,88 +17,102 @@ @test compare(x -> permutedims(x, [2,1,4,3]), AT, randn(ComplexF32,3,4,5,1)) end - @testset "issymmetric/ishermitian" begin - n = 128 - areal = randn(n,n)/2 - aimg = randn(n,n)/2 - - @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64) - if !(eltya in eltypes) - continue + @testset "symmetric" begin + @testset "Hermitian" begin + A = rand(Float32,2,2) + A = A*A'+I #posdef + d_A = AT(A) + similar(Hermitian(d_A, :L), Float32) + end + + @testset "issymmetric/ishermitian" begin + n = 128 + areal = randn(n,n)/2 + aimg = randn(n,n)/2 + + @testset for eltya in (Float32, Float64, ComplexF32, ComplexF64) + if !(eltya in eltypes) + continue + end + a = convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) + asym = transpose(a) + a # symmetric indefinite + aherm = a' + a # Hermitian indefinite + @test issymmetric(asym) + @test ishermitian(aherm) end - a = convert(Matrix{eltya}, eltya <: Complex ? complex.(areal, aimg) : areal) - asym = transpose(a) + a # symmetric indefinite - aherm = a' + a # Hermitian indefinite - @test issymmetric(asym) - @test ishermitian(aherm) end end -end -@testsuite "linalg/triangular" (AT, eltypes)->begin - @testset "copytri!" begin - @testset for uplo in ('U', 'L') - @test compare(x -> LinearAlgebra.copytri!(x, uplo), AT, rand(Float32, 128, 128)) + @testset "triangular" begin + @testset "copytri!" begin + @testset for uplo in ('U', 'L') + @test compare(x -> LinearAlgebra.copytri!(x, uplo), AT, rand(Float32, 128, 128)) + end end - end - @testset "copyto! for triangular" begin - for TR in (UpperTriangular, LowerTriangular) - @test compare(transpose!, AT, Array{Float32}(undef, 128, 32), rand(Float32, 32, 128)) + @testset "copyto! for triangular" begin + for TR in (UpperTriangular, LowerTriangular) + @test compare(transpose!, AT, Array{Float32}(undef, 128, 32), rand(Float32, 32, 128)) - cpu_a = Array{Float32}(undef, 128, 128) - gpu_a = AT{Float32}(undef, 128, 128) - gpu_b = AT{Float32}(undef, 128, 128) + cpu_a = Array{Float32}(undef, 128, 128) + gpu_a = AT{Float32}(undef, 128, 128) + gpu_b = AT{Float32}(undef, 128, 128) - copyto!(gpu_a, rand(Float32, (128,128))) - copyto!(cpu_a, TR(gpu_a)) - @test cpu_a == Array(collect(TR(gpu_a))) + copyto!(gpu_a, rand(Float32, (128,128))) + copyto!(cpu_a, TR(gpu_a)) + @test cpu_a == Array(collect(TR(gpu_a))) - copyto!(gpu_a, rand(Float32, (128,128))) - gpu_c = copyto!(gpu_b, TR(gpu_a)) - @test all(Array(gpu_b) .== TR(Array(gpu_a))) - @test gpu_c isa AT - end + copyto!(gpu_a, rand(Float32, (128,128))) + gpu_c = copyto!(gpu_b, TR(gpu_a)) + @test all(Array(gpu_b) .== TR(Array(gpu_a))) + @test gpu_c isa AT + end - for TR in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriangular) - gpu_a = AT(rand(Float32, (128,128))) |> TR - gpu_b = AT{Float32}(undef, 128, 128) |> TR + for TR in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriangular) + gpu_a = AT(rand(Float32, (128,128))) |> TR + gpu_b = AT{Float32}(undef, 128, 128) |> TR - gpu_c = copyto!(gpu_b, gpu_a) - @test all(Array(gpu_b) .== Array(gpu_a)) - @test all(Array(gpu_c) .== Array(gpu_a)) - @test gpu_c isa TR + gpu_c = copyto!(gpu_b, gpu_a) + @test all(Array(gpu_b) .== Array(gpu_a)) + @test all(Array(gpu_c) .== Array(gpu_a)) + @test gpu_c isa TR + end end end -end -@testsuite "linalg/diagonal" (AT, eltypes)->begin - @testset "Array + Diagonal" begin - n = 128 - A = AT(rand(Float32, (n,n))) - d = AT(rand(Float32, n)) - D = Diagonal(d) - B = A + D - @test collect(B) ≈ collect(A) + collect(D) - end + @testset "diagonal" begin + @testset "Array + Diagonal" begin + n = 128 + A = AT(rand(Float32, (n,n))) + d = AT(rand(Float32, n)) + D = Diagonal(d) + B = A + D + @test collect(B) ≈ collect(A) + collect(D) + end - @testset "copy diagonal" begin - a = AT(rand(Float32, 10)) - D = Diagonal(a) - C = copy(D) - @test C isa Diagonal - @test C.diag isa AT - @test collect(D) == collect(C) + @testset "copy diagonal" begin + a = AT(rand(Float32, 10)) + D = Diagonal(a) + C = copy(D) + @test C isa Diagonal + @test C.diag isa AT + @test collect(D) == collect(C) + end + + @testset "$f! with diagonal $d" for (f, f!) in ((triu, triu!), (tril, tril!)), + d in -2:2 + A = randn(Float32, 10, 10) + @test f(A, d) == Array(f!(AT(A), d)) + end end - @testset "$f! with diagonal $d" for (f, f!) in ((triu, triu!), (tril, tril!)), - d in -2:2 - A = randn(Float32, 10, 10) - @test f(A, d) == Array(f!(AT(A), d)) + @testset "lmul! and rmul!" for (a,b) in [((3,4),(4,3)), ((3,), (1,3)), ((1,3), (3))], T in eltypes + @test compare(rmul!, AT, rand(T, a), Ref(rand(T))) + @test compare(lmul!, AT, Ref(rand(T)), rand(T, b)) end end -@testsuite "linalg/mul!" (AT, eltypes)->begin +@testsuite "linalg/mul!/vector-matrix" (AT, eltypes)->begin @testset "$T gemv y := $f(A) * x * a + y * b" for f in (identity, transpose, adjoint), T in eltypes y, A, x = rand(T, 4), rand(T, 4, 4), rand(T, 4) @@ -114,7 +128,9 @@ end @test compare(mul!, AT, rand(T, 2,2), rand(T, 2,1), f(rand(T, 2))) end end +end +@testsuite "linalg/mul!/matrix-matrix" (AT, eltypes)->begin @testset "$T gemm C := $f(A) * $g(B) * a + C * b" for f in (identity, transpose, adjoint), g in (identity, transpose, adjoint), T in eltypes A, B, C = rand(T, 4, 4), rand(T, 4, 4), rand(T, 4, 4) @@ -126,12 +142,9 @@ end @test compare(mul!, AT, C, f(A), g(B), Ref(T(4)), Ref(T(5))) @test typeof(AT(rand(T, 3, 3)) * AT(rand(T, 3, 3))) <: AbstractMatrix end +end - @testset "lmul! and rmul!" for (a,b) in [((3,4),(4,3)), ((3,), (1,3)), ((1,3), (3))], T in eltypes - @test compare(rmul!, AT, rand(T, a), Ref(rand(T))) - @test compare(lmul!, AT, Ref(rand(T)), rand(T, b)) - end - +@testsuite "linalg/norm" (AT, eltypes)->begin @testset "$p-norm($sz x $T)" for sz in [(2,), (2,2), (2,2,2)], p in Any[1, 2, 3, Inf, -Inf], T in eltypes @@ -142,12 +155,3 @@ end @test compare(norm, AT, rand(range, sz), Ref(p)) end end - -@testsuite "linalg/symmetric" (AT, eltypes)->begin - @testset "Hermitian" begin - A = rand(Float32,2,2) - A = A*A'+I #posdef - d_A = AT(A) - similar(Hermitian(d_A, :L), Float32) - end -end