@@ -15,33 +15,34 @@ include(joinpath("..", "utilities.jl"))
1515 k = min (m, n)
1616 algs = (CUSOLVER_QRIteration (), CUSOLVER_SVDPolar (), CUSOLVER_Jacobi ())
1717 @testset " algorithm $alg " for alg in algs
18- minmn = min (m, n)
19- A = CuArray (randn (rng, T, m, n))
18+ As = m == n ? (CuArray (randn (rng, T, m, n)), Diagonal (CuArray (randn (rng, T, m)))) : (CuArray (randn (rng, T, m, n)),)
19+ for A in As
20+ minmn = min (m, n)
21+ U, S, Vᴴ = svd_compact (A; alg)
22+ @test U isa CuMatrix{T} && size (U) == (m, minmn)
23+ @test S isa Diagonal{real (T), <: CuVector } && size (S) == (minmn, minmn)
24+ @test Vᴴ isa CuMatrix{T} && size (Vᴴ) == (minmn, n)
25+ @test U * S * Vᴴ ≈ A
26+ @test isapproxone (U' * U)
27+ @test isapproxone (Vᴴ * Vᴴ' )
28+ @test isposdef (S)
2029
21- U, S, Vᴴ = svd_compact (A; alg)
22- @test U isa CuMatrix{T} && size (U) == (m, minmn)
23- @test S isa Diagonal{real (T), <: CuVector } && size (S) == (minmn, minmn)
24- @test Vᴴ isa CuMatrix{T} && size (Vᴴ) == (minmn, n)
25- @test U * S * Vᴴ ≈ A
26- @test isapproxone (U' * U)
27- @test isapproxone (Vᴴ * Vᴴ' )
28- @test isposdef (S)
30+ Ac = similar (A)
31+ U2, S2, V2ᴴ = @constinferred svd_compact! (copy! (Ac, A), (U, S, Vᴴ), alg)
32+ @test U2 === U
33+ @test S2 === S
34+ @test V2ᴴ === Vᴴ
35+ @test U * S * Vᴴ ≈ A
36+ @test isapproxone (U' * U)
37+ @test isapproxone (Vᴴ * Vᴴ' )
38+ @test isposdef (S)
2939
30- Ac = similar (A)
31- U2, S2, V2ᴴ = @constinferred svd_compact! (copy! (Ac, A), (U, S, Vᴴ), alg)
32- @test U2 === U
33- @test S2 === S
34- @test V2ᴴ === Vᴴ
35- @test U * S * Vᴴ ≈ A
36- @test isapproxone (U' * U)
37- @test isapproxone (Vᴴ * Vᴴ' )
38- @test isposdef (S)
39-
40- Sd = svd_vals (A, alg)
41- @test CuArray (diagview (S)) ≈ Sd
42- # CuArray is necessary because norm of CuArray view with non-unit step is broken
43- if alg isa CUSOLVER_QRIteration
44- @test_warn " invalid keyword arguments for GPU_QRIteration" svd_compact! (copy! (Ac, A), (U, S, Vᴴ), CUSOLVER_QRIteration (; bad = " bad" ))
40+ Sd = svd_vals (A, alg)
41+ @test CuArray (diagview (S)) ≈ Sd
42+ # CuArray is necessary because norm of CuArray view with non-unit step is broken
43+ if alg isa CUSOLVER_QRIteration
44+ @test_warn " invalid keyword arguments for GPU_QRIteration" svd_compact! (copy! (Ac, A), (U, S, Vᴴ), CUSOLVER_QRIteration (; bad = " bad" ))
45+ end
4546 end
4647 end
4748 end
5354 @testset " size ($m , $n )" for n in (37 , m, 63 )
5455 algs = (CUSOLVER_QRIteration (), CUSOLVER_SVDPolar (), CUSOLVER_Jacobi ())
5556 @testset " algorithm $alg " for alg in algs
56- A = CuArray (randn (rng, T, m, n))
57- U, S, Vᴴ = svd_full (A; alg)
58- @test U isa CuMatrix{T} && size (U) == (m, m)
59- @test S isa CuMatrix{real (T)} && size (S) == (m, n)
60- @test Vᴴ isa CuMatrix{T} && size (Vᴴ) == (n, n)
61- @test U * S * Vᴴ ≈ A
62- @test isapproxone (U' * U)
63- @test isapproxone (U * U' )
64- @test isapproxone (Vᴴ * Vᴴ' )
65- @test isapproxone (Vᴴ' * Vᴴ)
66- @test all (isposdef, diagview (S))
57+ As = m == n ? (CuArray (randn (rng, T, m, n)), Diagonal (CuArray (randn (rng, T, m)))) : (CuArray (randn (rng, T, m, n)),)
58+ for A in As
59+ minmn = min (m, n)
60+ U, S, Vᴴ = svd_full (A; alg)
61+ @test U isa CuMatrix{T} && size (U) == (m, m)
62+ @test S isa CuMatrix{real (T)} && size (S) == (m, n)
63+ @test Vᴴ isa CuMatrix{T} && size (Vᴴ) == (n, n)
64+ @test U * S * Vᴴ ≈ A
65+ @test isapproxone (U' * U)
66+ @test isapproxone (U * U' )
67+ @test isapproxone (Vᴴ * Vᴴ' )
68+ @test isapproxone (Vᴴ' * Vᴴ)
69+ @test all (isposdef, diagview (S))
6770
68- Ac = similar (A)
69- U2, S2, V2ᴴ = @constinferred svd_full! (copy! (Ac, A), (U, S, Vᴴ), alg)
70- @test U2 === U
71- @test S2 === S
72- @test V2ᴴ === Vᴴ
73- @test U * S * Vᴴ ≈ A
74- @test isapproxone (U' * U)
75- @test isapproxone (U * U' )
76- @test isapproxone (Vᴴ * Vᴴ' )
77- @test isapproxone (Vᴴ' * Vᴴ)
78- @test all (isposdef, diagview (S))
71+ Ac = similar (A)
72+ U2, S2, V2ᴴ = @constinferred svd_full! (copy! (Ac, A), (U, S, Vᴴ), alg)
73+ @test U2 === U
74+ @test S2 === S
75+ @test V2ᴴ === Vᴴ
76+ @test U * S * Vᴴ ≈ A
77+ @test isapproxone (U' * U)
78+ @test isapproxone (U * U' )
79+ @test isapproxone (Vᴴ * Vᴴ' )
80+ @test isapproxone (Vᴴ' * Vᴴ)
81+ @test all (isposdef, diagview (S))
7982
80- minmn = min (m, n)
81- Sc = similar (A, real (T), minmn)
82- Sc2 = svd_vals! (copy! (Ac, A), Sc, alg)
83- @test Sc === Sc2
84- @test CuArray (diagview (S)) ≈ Sc
85- # CuArray is necessary because norm of CuArray view with non-unit step is broken
86- if alg isa CUSOLVER_QRIteration
87- @test_warn " invalid keyword arguments for GPU_QRIteration" svd_full! (copy! (Ac, A), (U, S, Vᴴ), CUSOLVER_QRIteration (; bad = " bad" ))
88- @test_warn " invalid keyword arguments for GPU_QRIteration" svd_vals! (copy! (Ac, A), Sc, CUSOLVER_QRIteration (; bad = " bad" ))
83+ Sc = similar (A, real (T), minmn)
84+ Sc2 = svd_vals! (copy! (Ac, A), Sc, alg)
85+ @test Sc === Sc2
86+ @test CuArray (diagview (S)) ≈ Sc
87+ # CuArray is necessary because norm of CuArray view with non-unit step is broken
88+ if alg isa CUSOLVER_QRIteration
89+ @test_warn " invalid keyword arguments for GPU_QRIteration" svd_full! (copy! (Ac, A), (U, S, Vᴴ), CUSOLVER_QRIteration (; bad = " bad" ))
90+ if ! isa (A, Diagonal)
91+ @test_warn " invalid keyword arguments for GPU_QRIteration" svd_vals! (copy! (Ac, A), Sc, CUSOLVER_QRIteration (; bad = " bad" ))
92+ end
93+ end
8994 end
9095 end
9196 end
9297 @testset " size (0, 0)" begin
9398 algs = (CUSOLVER_QRIteration (), CUSOLVER_SVDPolar (), CUSOLVER_Jacobi ())
9499 @testset " algorithm $alg " for alg in algs
95- A = CuArray (randn (rng, T, 0 , 0 ))
96- U, S, Vᴴ = svd_full (A; alg)
97- @test U isa CuMatrix{T} && size (U) == (0 , 0 )
98- @test S isa CuMatrix{real (T)} && size (S) == (0 , 0 )
99- @test Vᴴ isa CuMatrix{T} && size (Vᴴ) == (0 , 0 )
100- @test U * S * Vᴴ ≈ A
101- @test isapproxone (U' * U)
102- @test isapproxone (U * U' )
103- @test isapproxone (Vᴴ * Vᴴ' )
104- @test isapproxone (Vᴴ' * Vᴴ)
105- @test all (isposdef, diagview (S))
100+ for A in (CuArray (randn (rng, T, 0 , 0 )), Diagonal (CuArray (randn (rng, T, 0 ))))
101+ U, S, Vᴴ = svd_full (A; alg)
102+ @test U isa CuMatrix{T} && size (U) == (0 , 0 )
103+ @test S isa CuMatrix{real (T)} && size (S) == (0 , 0 )
104+ @test Vᴴ isa CuMatrix{T} && size (Vᴴ) == (0 , 0 )
105+ @test U * S * Vᴴ ≈ A
106+ @test isapproxone (U' * U)
107+ @test isapproxone (U * U' )
108+ @test isapproxone (Vᴴ * Vᴴ' )
109+ @test isapproxone (Vᴴ' * Vᴴ)
110+ @test all (isposdef, diagview (S))
111+ end
106112 end
107113 end
108114end
@@ -115,26 +121,28 @@ end
115121 p = min (m, n) - k - 1
116122 algs = (CUSOLVER_QRIteration (), CUSOLVER_SVDPolar (), CUSOLVER_Jacobi (), CUSOLVER_Randomized (; k = k, p = p, niters = 100 ))
117123 @testset " algorithm $alg " for alg in algs
118- hA = randn (rng, T, m, n)
119- S₀ = svd_vals (hA)
120- A = CuArray (hA)
121- minmn = min (m, n)
122- r = k
124+ hAs = m == n ? (randn (rng, T, m, n), Diagonal (randn (rng, T, m))) : (randn (rng, T, m, n),)
125+ for hA in hAs
126+ S₀ = svd_vals (hA)
127+ A = CuArray (hA)
128+ minmn = min (m, n)
129+ r = k
123130
124- U1, S1, V1ᴴ, ϵ1 = @constinferred svd_trunc (A; alg, trunc = truncrank (r))
125- @test length (S1. diag) == r
126- @test opnorm (A - U1 * S1 * V1ᴴ) ≈ S₀[r + 1 ]
127- @test norm (A - U1 * S1 * V1ᴴ) ≈ ϵ1
131+ U1, S1, V1ᴴ, ϵ1 = @constinferred svd_trunc (A; alg, trunc = truncrank (r))
132+ @test length (S1. diag) == r
133+ @test opnorm (A - U1 * S1 * V1ᴴ) ≈ S₀[r + 1 ]
134+ @test norm (A - U1 * S1 * V1ᴴ) ≈ ϵ1
128135
129- if ! (alg isa CUSOLVER_Randomized)
130- s = 1 + sqrt (eps (real (T)))
131- trunc2 = trunctol (; atol = s * S₀[r + 1 ])
136+ if ! (alg isa CUSOLVER_Randomized)
137+ s = 1 + sqrt (eps (real (T)))
138+ trunc2 = trunctol (; atol = s * S₀[r + 1 ])
132139
133- U2, S2, V2ᴴ, ϵ2 = @constinferred svd_trunc (A; alg, trunc = trunctol (; atol = s * S₀[r + 1 ]))
134- @test length (S2. diag) == r
135- @test U1 ≈ U2
136- @test parent (S1) ≈ parent (S2)
137- @test V1ᴴ ≈ V2ᴴ
140+ U2, S2, V2ᴴ, ϵ2 = @constinferred svd_trunc (A; alg, trunc = trunctol (; atol = s * S₀[r + 1 ]))
141+ @test length (S2. diag) == r
142+ @test U1 ≈ U2
143+ @test parent (S1) ≈ parent (S2)
144+ @test V1ᴴ ≈ V2ᴴ
145+ end
138146 end
139147 end
140148 end
0 commit comments