Skip to content

Commit 63459e5

Browse files
authored
Reduce allocation of dense arrays on-the-fly in linalg tests (#485)
1 parent c73d6e3 commit 63459e5

File tree

2 files changed

+111
-99
lines changed

2 files changed

+111
-99
lines changed

test/linalg.jl

+104-93
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,15 @@ end
8383

8484
@testset "Sparse promotion in sparse matmul" begin
8585
A = SparseMatrixCSC{Float32, Int8}(2, 2, Int8[1, 2, 3], Int8[1, 2], Float32[1., 2.])
86+
MA = Array(A)
8687
B = SparseMatrixCSC{ComplexF32, Int32}(2, 2, Int32[1, 2, 3], Int32[1, 2], ComplexF32[1. + im, 2. - im])
87-
@test A*transpose(B) Array(A) * transpose(Array(B))
88-
@test A*adjoint(B) Array(A) * adjoint(Array(B))
89-
@test transpose(A)*B transpose(Array(A)) * Array(B)
90-
@test transpose(A)*transpose(B) transpose(Array(A)) * transpose(Array(B))
91-
@test adjoint(B)*A adjoint(Array(B)) * Array(A)
92-
@test adjoint(B)*adjoint(complex.(A)) adjoint(Array(B)) * adjoint(Array(complex.(A)))
88+
MB = Array(B)
89+
@test A*transpose(B) MA * transpose(MB)
90+
@test A*adjoint(B) MA * adjoint(MB)
91+
@test transpose(A)*B transpose(MA) * MB
92+
@test transpose(A)*transpose(B) transpose(MA) * transpose(MB)
93+
@test adjoint(B)*A adjoint(MB) * MA
94+
@test adjoint(B)*adjoint(complex.(A)) adjoint(MB) * adjoint(Array(complex.(A)))
9395
end
9496

9597
@testset "multiplication of triangular sparse and dense matrices" begin
@@ -226,10 +228,11 @@ end
226228

227229
@testset "UniformScaling" begin
228230
local A = sprandn(10, 10, 0.5)
229-
@test A + I == Array(A) + I
230-
@test I + A == I + Array(A)
231-
@test A - I == Array(A) - I
232-
@test I - A == I - Array(A)
231+
MA = Array(A)
232+
@test A + I == MA + I
233+
@test I + A == I + MA
234+
@test A - I == MA - I
235+
@test I - A == I - MA
233236
end
234237

235238
@testset "unary minus for SparseMatrixCSC{Bool}" begin
@@ -240,25 +243,30 @@ end
240243

241244
@testset "sparse matrix norms" begin
242245
Ac = sprandn(10,10,.1) + im* sprandn(10,10,.1)
246+
MAc = Array(Ac)
243247
Ar = sprandn(10,10,.1)
244-
Ai = ceil.(Int,Ar*100)
245-
@test opnorm(Ac,1) opnorm(Array(Ac),1)
246-
@test opnorm(Ac,Inf) opnorm(Array(Ac),Inf)
247-
@test norm(Ac) norm(Array(Ac))
248-
@test opnorm(Ar,1) opnorm(Array(Ar),1)
249-
@test opnorm(Ar,Inf) opnorm(Array(Ar),Inf)
250-
@test norm(Ar) norm(Array(Ar))
251-
@test opnorm(Ai,1) opnorm(Array(Ai),1)
252-
@test opnorm(Ai,Inf) opnorm(Array(Ai),Inf)
253-
@test norm(Ai) norm(Array(Ai))
248+
MAr = Array(Ar)
249+
Ai = ceil.(Int, Ar*100)
250+
MAi = Array(Ai)
251+
@test opnorm(Ac,1) opnorm(MAc,1)
252+
@test opnorm(Ac,Inf) opnorm(MAc,Inf)
253+
@test norm(Ac) norm(MAc)
254+
@test opnorm(Ar,1) opnorm(MAr,1)
255+
@test opnorm(Ar,Inf) opnorm(MAr,Inf)
256+
@test norm(Ar) norm(MAr)
257+
@test opnorm(Ai,1) opnorm(MAi,1)
258+
@test opnorm(Ai,Inf) opnorm(MAi,Inf)
259+
@test norm(Ai) norm(MAi)
254260
Ai = trunc.(Int, Ar*100)
255-
@test opnorm(Ai,1) opnorm(Array(Ai),1)
256-
@test opnorm(Ai,Inf) opnorm(Array(Ai),Inf)
257-
@test norm(Ai) norm(Array(Ai))
261+
MAi = Array(Ai)
262+
@test opnorm(Ai,1) opnorm(MAi,1)
263+
@test opnorm(Ai,Inf) opnorm(MAi,Inf)
264+
@test norm(Ai) norm(MAi)
258265
Ai = round.(Int, Ar*100)
259-
@test opnorm(Ai,1) opnorm(Array(Ai),1)
260-
@test opnorm(Ai,Inf) opnorm(Array(Ai),Inf)
261-
@test norm(Ai) norm(Array(Ai))
266+
MAi = Array(Ai)
267+
@test opnorm(Ai,1) opnorm(MAi,1)
268+
@test opnorm(Ai,Inf) opnorm(MAi,Inf)
269+
@test norm(Ai) norm(MAi)
262270
# make certain entries in nzval beyond
263271
# the range specified in colptr do not
264272
# impact norm of a sparse matrix
@@ -269,16 +277,18 @@ end
269277

270278
# Test (m x 1) sparse matrix
271279
colM = sprandn(10, 1, 0.6)
272-
@test opnorm(colM, 1) opnorm(Array(colM), 1)
273-
@test opnorm(colM) opnorm(Array(colM))
274-
@test opnorm(colM, Inf) opnorm(Array(colM), Inf)
280+
McolM = Array(colM)
281+
@test opnorm(colM, 1) opnorm(McolM, 1)
282+
@test opnorm(colM) opnorm(McolM)
283+
@test opnorm(colM, Inf) opnorm(McolM, Inf)
275284
@test_throws ArgumentError opnorm(colM, 3)
276285

277286
# Test (1 x n) sparse matrix
278287
rowM = sprandn(1, 10, 0.6)
279-
@test opnorm(rowM, 1) opnorm(Array(rowM), 1)
280-
@test opnorm(rowM) opnorm(Array(rowM))
281-
@test opnorm(rowM, Inf) opnorm(Array(rowM), Inf)
288+
MrowM = Array(rowM)
289+
@test opnorm(rowM, 1) opnorm(MrowM, 1)
290+
@test opnorm(rowM) opnorm(MrowM)
291+
@test opnorm(rowM, Inf) opnorm(MrowM, Inf)
282292
@test_throws ArgumentError opnorm(rowM, 3)
283293
end
284294

@@ -293,20 +303,21 @@ end
293303
if elty <: Complex
294304
dd+=im*convert(Vector{elty}, randn(n))
295305
end
296-
D = Diagonal(dd)
297-
b = rand(elty, n, n)
298-
b = sparse(b)
299-
@test ldiv!(D, copy(b)) Array(D)\Array(b)
306+
D = Diagonal(dd); MD = Array(D)
307+
bd = rand(elty, n, n)
308+
b = sparse(bd)
309+
@test ldiv!(D, copy(b)) MD\bd
300310
@test_throws SingularException ldiv!(Diagonal(zeros(elty, n)), copy(b))
301311
b = rand(elty, n+1, n+1)
302312
b = sparse(b)
303313
@test_throws DimensionMismatch ldiv!(D, copy(b))
304314
b = view(rand(elty, n+1), Vector(1:n+1))
305315
@test_throws DimensionMismatch ldiv!(D, b)
306316
for b in (sparse(rand(elty,n,n)), sparse(rand(elty,n)))
307-
@test lmul!(copy(D), copy(b)) Array(D)*Array(b)
308-
@test lmul!(transpose(copy(D)), copy(b)) transpose(Array(D))*Array(b)
309-
@test lmul!(adjoint(copy(D)), copy(b)) Array(D)'*Array(b)
317+
bd = Array(b)
318+
@test lmul!(copy(D), copy(b)) MD*bd
319+
@test lmul!(transpose(copy(D)), copy(b)) transpose(MD)*bd
320+
@test lmul!(adjoint(copy(D)), copy(b)) MD'*bd
310321
end
311322
end
312323
end
@@ -662,29 +673,29 @@ end
662673
(100, 0.01, 100, 0.01, 20),
663674
(100, 0.1, 100, 0.2, 100),
664675
)
665-
a = sprand(m, n, p)
666-
b = sprand(n, k, q)
676+
a = sprand(m, n, p); ad = Array(a)
677+
b = sprand(n, k, q); bd = Array(b)
667678
as = sparse(a')
668679
bs = sparse(b')
669680
ab = a * b
670-
aab = Array(a) * Array(b)
681+
aab = ad * bd
671682
@test maximum(abs.(ab - aab)) < 100*eps()
672683
@test a*bs' == ab
673684
@test as'*b == ab
674685
@test as'*bs' == ab
675686
f = Diagonal(rand(n))
676-
@test Array(a*f) == Array(a)*f
677-
@test Array(f*b) == f*Array(b)
687+
@test Array(a*f) == ad*f
688+
@test Array(f*b) == f*bd
678689
A = rand(2n, 2n)
679-
sA = view(A, 1:2:2n, 1:2:2n)
680-
@test Array((sA*b)::Matrix) Array(sA)*Array(b)
681-
@test Array((a*sA)::Matrix) Array(a)*Array(sA)
682-
@test Array((sA'b)::Matrix) Array(sA')*Array(b)
683-
c = sprandn(ComplexF32, n, n, q)
684-
@test Array((sA*c')::Matrix) Array(sA)*Array(c)'
685-
@test Array((c'*sA)::Matrix) Array(c)'*Array(sA)
686-
@test Array((sA'c)::Matrix) Array(sA')*Array(c)
687-
@test Array((sA'c')::Matrix) Array(sA')*Array(c)'
690+
sA = view(A, 1:2:2n, 1:2:2n); dA = Array(sA)
691+
@test (sA*b)::Matrix dA*bd
692+
@test (a*sA)::Matrix ad*dA
693+
@test (sA'b)::Matrix dA'*bd
694+
c = sprandn(ComplexF32, n, n, q); cd = Array(c)
695+
@test (sA*c')::Matrix dA*cd'
696+
@test (c'*sA)::Matrix cd'*dA
697+
@test (sA'c)::Matrix dA'*cd
698+
@test (sA'c')::Matrix dA'*cd'
688699
end
689700
end
690701

@@ -746,16 +757,16 @@ end
746757
d = sparse(d_di); d_d = Array(d_di)
747758
# mat ⊗ mat
748759
for t in (identity, adjoint, transpose)
749-
@test Array(kron(t(a), b)::SparseMatrixCSC) == kron(t(a_d), b_d)
750-
@test Array(kron(a, t(b))::SparseMatrixCSC) == kron(a_d, t(b_d))
751-
@test Array(kron(t(a), t(b))::SparseMatrixCSC) == kron(t(a_d), t(b_d))
752-
@test Array(kron(t(a), b_d)::SparseMatrixCSC) == kron(t(a_d), b_d)
753-
@test Array(kron(a_d, t(b))::SparseMatrixCSC) == kron(a_d, t(b_d))
754-
@test Array(kron(t(a), c_di)::SparseMatrixCSC) == kron(t(a_d), c_d)
755-
@test Array(kron(a, t(c_di))::SparseMatrixCSC) == kron(a_d, t(c_d))
756-
@test Array(kron(t(a), t(c_di))::SparseMatrixCSC) == kron(t(a_d), t(c_d))
757-
@test Array(kron(c_di, y)::SparseMatrixCSC) == kron(c_di, y_d)
758-
@test Array(kron(x, d_di)::SparseMatrixCSC) == kron(x_d, d_di)
760+
@test kron(t(a), b)::SparseMatrixCSC == kron(t(a_d), b_d)
761+
@test kron(a, t(b))::SparseMatrixCSC == kron(a_d, t(b_d))
762+
@test kron(t(a), t(b))::SparseMatrixCSC == kron(t(a_d), t(b_d))
763+
@test kron(t(a), b_d)::SparseMatrixCSC == kron(t(a_d), b_d)
764+
@test kron(a_d, t(b))::SparseMatrixCSC == kron(a_d, t(b_d))
765+
@test kron(t(a), c_di)::SparseMatrixCSC == kron(t(a_d), c_d)
766+
@test kron(a, t(c_di))::SparseMatrixCSC == kron(a_d, t(c_d))
767+
@test kron(t(a), t(c_di))::SparseMatrixCSC == kron(t(a_d), t(c_d))
768+
@test kron(c_di, y)::SparseMatrixCSC == kron(c_di, y_d)
769+
@test kron(x, d_di)::SparseMatrixCSC == kron(x_d, d_di)
759770
end
760771
end
761772
# vec ⊗ vec
@@ -764,22 +775,22 @@ end
764775
@test Vector(kron(x, y_d)::SparseVector) == kron(x_d, y_d)
765776
for t in (identity, adjoint, transpose)
766777
# mat ⊗ vec
767-
@test Array(kron(t(a), y)::SparseMatrixCSC) == kron(t(a_d), y_d)
768-
@test Array(kron(t(a_d), y)::SparseMatrixCSC) == kron(t(a_d), y_d)
769-
@test Array(kron(t(a), y_d)::SparseMatrixCSC) == kron(t(a_d), y_d)
778+
@test kron(t(a), y)::SparseMatrixCSC == kron(t(a_d), y_d)
779+
@test kron(t(a_d), y)::SparseMatrixCSC == kron(t(a_d), y_d)
780+
@test kron(t(a), y_d)::SparseMatrixCSC == kron(t(a_d), y_d)
770781
# vec ⊗ mat
771-
@test Array(kron(x, t(b))::SparseMatrixCSC) == kron(x_d, t(b_d))
772-
@test Array(kron(x_d, t(b))::SparseMatrixCSC) == kron(x_d, t(b_d))
773-
@test Array(kron(x, t(b_d))::SparseMatrixCSC) == kron(x_d, t(b_d))
782+
@test kron(x, t(b))::SparseMatrixCSC == kron(x_d, t(b_d))
783+
@test kron(x_d, t(b))::SparseMatrixCSC == kron(x_d, t(b_d))
784+
@test kron(x, t(b_d))::SparseMatrixCSC == kron(x_d, t(b_d))
774785
end
775786
# vec ⊗ vec'
776-
@test Array(kron(v, y')::SparseMatrixCSC) == kron(v_d, y_d')
777-
@test Array(kron(x, y')::SparseMatrixCSC) == kron(x_d, y_d')
787+
@test kron(v, y')::SparseMatrixCSC == kron(v_d, y_d')
788+
@test kron(x, y')::SparseMatrixCSC == kron(x_d, y_d')
778789
# test different types
779790
z = convert(SparseVector{Float16, Int8}, y); z_d = Vector(z)
780791
@test Vector(kron(x, z)) == kron(x_d, z_d)
781-
@test Array(kron(a, z)) == kron(a_d, z_d)
782-
@test Array(kron(z, b)) == kron(z_d, b_d)
792+
@test kron(a, z) == kron(a_d, z_d)
793+
@test kron(z, b) == kron(z_d, b_d)
783794
# test bounds checks
784795
@test_throws DimensionMismatch kron!(copy(a), a, b)
785796
@test_throws DimensionMismatch kron!(copy(x), x, y)
@@ -790,30 +801,30 @@ end
790801
@testset "sparse Frobenius dot/inner product" begin
791802
full_view = M -> view(M, :, :)
792803
for i = 1:5
793-
A = sprand(ComplexF64,10,15,0.4)
794-
B = sprand(ComplexF64,10,15,0.5)
795-
C = rand(10,15) .> 0.3
796-
@test dot(A,B) dot(Matrix(A), Matrix(B))
797-
@test dot(A,B) dot(A, Matrix(B))
798-
@test dot(A,B) dot(Matrix(A), B)
799-
@test dot(A,C) dot(Matrix(A), C)
800-
@test dot(C,A) dot(C, Matrix(A))
804+
A = sprand(ComplexF64,10,15,0.4); MA = Matrix(A)
805+
B = sprand(ComplexF64,10,15,0.5); MB = Matrix(B)
806+
C = rand(10,15) .> 0.3; MC = Matrix(C)
807+
@test dot(A,B) dot(MA, MB)
808+
@test dot(A,B) dot(A, MB)
809+
@test dot(A,B) dot(MA, B)
810+
@test dot(A,C) dot(MA, C)
811+
@test dot(C,A) dot(C, MA)
801812
# square matrices required by most linear algebra wrappers
802-
SA = A * A'
803-
SB = B * B'
804-
SC = C * C'
813+
SA = A * A'; MSA = Matrix(SA)
814+
SB = B * B'; MSB = Matrix(SB)
815+
SC = C * C'; MSC = Matrix(SC)
805816
for W in (full_view, LowerTriangular, UpperTriangular, UpperHessenberg, Symmetric, Hermitian)
806-
WA = W(Matrix(SA))
807-
WB = W(Matrix(SB))
808-
WC = W(Matrix(SC))
809-
@test dot(WA,SB) dot(WA, Matrix(SB))
810-
@test dot(SA,WB) dot(Matrix(SA), WB)
811-
@test dot(SA,WC) dot(Matrix(SA), WC)
817+
WA = W(MSA)
818+
WB = W(MSB)
819+
WC = W(MSC)
820+
@test dot(WA,SB) dot(WA, MSB)
821+
@test dot(SA,WB) dot(MSA, WB)
822+
@test dot(SA,WC) dot(MSA, WC)
812823
end
813824
for W in (transpose, adjoint)
814-
WA = W(Matrix(A))
815-
WB = W(Matrix(B))
816-
WC = W(Matrix(C))
825+
WA = W(MA)
826+
WB = W(MB)
827+
WC = W(MC)
817828
TA = copy(W(A))
818829
TB = copy(W(B))
819830
@test dot(WA,TB) dot(WA, Matrix(TB))

test/sparsematrix_ops.jl

+7-6
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,13 @@ do33 = fill(1.,3)
101101
end
102102
@testset "binary operations on sparse matrices with union eltype" begin
103103
A = sparse([1,2,1], [1,1,2], Union{Int, Missing}[1, missing, 0])
104+
MA = Array(A)
104105
for fun in (+, -, *, min, max)
105106
if fun in (+, -)
106-
@test collect(skipmissing(Array(fun(A, A)))) == collect(skipmissing(Array(fun(Array(A), Array(A)))))
107+
@test collect(skipmissing(Array(fun(A, A)))) == collect(skipmissing(Array(fun(MA, MA))))
107108
end
108-
@test collect(skipmissing(Array(map(fun, A, A)))) == collect(skipmissing(map(fun, Array(A), Array(A))))
109-
@test collect(skipmissing(Array(broadcast(fun, A, A)))) == collect(skipmissing(broadcast(fun, Array(A), Array(A))))
109+
@test collect(skipmissing(Array(map(fun, A, A)))) == collect(skipmissing(map(fun, MA, MA)))
110+
@test collect(skipmissing(Array(broadcast(fun, A, A)))) == collect(skipmissing(broadcast(fun, MA, MA)))
110111
end
111112
b = convert(SparseMatrixCSC{Union{Float64, Missing}}, sprandn(Float64, 20, 10, 0.2)); b[rand(1:200, 3)] .= missing
112113
C = convert(SparseMatrixCSC{Union{Float64, Missing}}, sprandn(Float64, 20, 10, 0.9)); C[rand(1:200, 3)] .= missing
@@ -263,10 +264,10 @@ end
263264

264265
@testset "findall" begin
265266
# issue described in https://groups.google.com/d/msg/julia-users/Yq4dh8NOWBQ/GU57L90FZ3EJ
266-
A = sparse(I, 5, 5)
267-
@test findall(A) == findall(x -> x == true, A) == findall(Array(A))
267+
A = sparse(I, 5, 5); MA = Array(A)
268+
@test findall(A) == findall(x -> x == true, A) == findall(MA)
268269
# Non-stored entries are true
269-
@test findall(x -> x == false, A) == findall(x -> x == false, Array(A))
270+
@test findall(x -> x == false, A) == findall(x -> x == false, MA)
270271

271272
# Not all stored entries are true
272273
@test findall(sparse([true false])) == [CartesianIndex(1, 1)]

0 commit comments

Comments
 (0)