Skip to content

Commit ca0e655

Browse files
committed
Update blas.jl
Update blas.jl 1. test negative stride more thoroughly 2. add missing test to `trmv` and `trsv` and put them together 3. add missing test to `symv` and `hemv`
1 parent 59d1c79 commit ca0e655

File tree

1 file changed

+130
-125
lines changed

1 file changed

+130
-125
lines changed

stdlib/LinearAlgebra/test/blas.jl

Lines changed: 130 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -88,50 +88,38 @@ end
8888
x2 = randn(elty, n)
8989
α = rand(elty)
9090
β = rand(elty)
91-
@test BLAS.axpy!(α,copy(x1),copy(x2)) α*x1 + x2
92-
@test BLAS.axpby!(α,copy(x1),β,copy(x2)) α*x1 + β*x2
91+
for X1 in (x1, view(x1,n:-1:1)), X2 in (x2, view(x2, n:-1:1))
92+
@test BLAS.axpy!(α,deepcopy(X1),deepcopy(X2)) α*X1 + X2
93+
@test BLAS.axpby!(α,deepcopy(X1),β,deepcopy(X2)) α*X1 + β*X2
94+
end
95+
for ind1 in (1:n, n:-1:1), ind2 in (1:n, n:-1:1)
96+
@test BLAS.axpy!(α,copy(x1),ind1,copy(x2),ind2) x2 + α*(ind1 == ind2 ? x1 : reverse(x1))
97+
end
9398
@test_throws DimensionMismatch BLAS.axpy!(α, copy(x1), rand(elty, n + 1))
9499
@test_throws DimensionMismatch BLAS.axpby!(α, copy(x1), β, rand(elty, n + 1))
95100
@test_throws DimensionMismatch BLAS.axpy!(α, copy(x1), 1:div(n,2), copy(x2), 1:n)
96101
@test_throws ArgumentError BLAS.axpy!(α, copy(x1), 0:div(n,2), copy(x2), 1:(div(n, 2) + 1))
97102
@test_throws ArgumentError BLAS.axpy!(α, copy(x1), 1:div(n,2), copy(x2), 0:(div(n, 2) - 1))
98-
@test BLAS.axpy!(α,copy(x1),1:n,copy(x2),1:n) x2 + α*x1
99-
# negative stride test
100-
@test BLAS.axpy!(α,copy(x1),n:-1:1,copy(x2),n:-1:1) x2 + α*x1
101-
x1′, x2′ = @views x1[end:-1:1], x2[end:-1:1]
102-
@test BLAS.axpy!(α, deepcopy(x1′), deepcopy(x2′)) α*x1′ + x2′
103-
@test BLAS.axpy!(α, deepcopy(x1), deepcopy(x2′)) α*x1 + x2′
104-
@test BLAS.axpy!(α, deepcopy(x1′), deepcopy(x2)) α*x1′ + x2
105-
@test BLAS.axpby!(α, deepcopy(x1′), β, deepcopy(x2)) α*x1′ + β*x2
106103
end
107104
@testset "nrm2, iamax, and asum for StridedVectors" begin
108105
a = rand(elty,n)
109-
b = view(a,2:2:n,1)
110-
@test BLAS.nrm2(b) norm(b)
111-
@test BLAS.asum(b) sum(fabs, b)
112-
@test BLAS.iamax(b) == findmax(fabs, b)[2]
113-
# negative stride test
114-
c = view(a,n:-2:2)
115-
@test BLAS.nrm2(c) norm(c)
116-
@test BLAS.asum(c) sum(fabs, c)
117-
@test BLAS.iamax(c) == 0
106+
for ind in (2:2:n, n:-2:2)
107+
b = view(a, ind, 1)
108+
@test BLAS.nrm2(b) sqrt(sum(abs2, b))
109+
@test BLAS.asum(b) sum(fabs, b)
110+
@test BLAS.iamax(b) == findmax(fabs, b)[2] * (step(ind) >= 0)
111+
end
118112
end
119-
# scal
120-
α = rand(elty)
121-
a = rand(elty,n)
122-
@test BLAS.scal(n,α,a,1) α * a
123-
# negative stride test
124-
@test BLAS.scal!(α, view(copy(a), n:-1:1)) α * reverse(a)
125-
126-
@testset "trsv" begin
127-
A = triu(rand(elty,n,n))
128-
@testset "Vector and SubVector" for x in (rand(elty, n), view(rand(elty,2n),1:2:2n), view(rand(elty,n),n:-1:1))
129-
@test A\x BLAS.trsv('U','N','N', A, x) BLAS.trsv!('U','N','N', A, deepcopy(x))
130-
@test_throws DimensionMismatch BLAS.trsv('U','N','N',A,Vector{elty}(undef,n+1))
113+
@testset "scal" begin
114+
α = rand(elty)
115+
a = rand(elty,n)
116+
@test BLAS.scal(n,α,a,1) α * a
117+
for v in (a, view(a, n:-1:1))
118+
@test BLAS.scal!(α, deepcopy(v)) α * v
131119
end
132120
end
133-
@testset "ger, her, syr" for x in (rand(elty, n), view(rand(elty,2n), 1:2:2n), view(rand(elty,2n), 2n:-2:1)),
134-
y in (rand(elty,n), view(rand(elty,3n), 1:3:3n), view(rand(elty,3n), 3n:-3:1))
121+
@testset "ger, her, syr" for x in (rand(elty, n), view(rand(elty,2n), 1:2:2n), view(rand(elty,n), n:-1:1)),
122+
y in (rand(elty,n), view(rand(elty,3n), 1:3:3n), view(rand(elty,2n), 2n:-2:2))
135123

136124
A = rand(elty,n,n)
137125
α = rand(elty)
@@ -156,35 +144,63 @@ end
156144
@testset "copy" begin
157145
x1 = randn(elty, n)
158146
x2 = randn(elty, n)
159-
@test x2 === BLAS.copyto!(x2, 1:n, x1, 1:n) == x1
147+
for ind1 in (1:n, n:-1:1), ind2 in (1:n, n:-1:1)
148+
@test x2 === BLAS.copyto!(x2, ind1, x1, ind2) == (ind1 == ind2 ? x1 : reverse(x1))
149+
end
160150
@test_throws DimensionMismatch BLAS.copyto!(x2, 1:n, x1, 1:(n - 1))
161151
@test_throws ArgumentError BLAS.copyto!(x1, 0:div(n, 2), x2, 1:(div(n, 2) + 1))
162152
@test_throws ArgumentError BLAS.copyto!(x1, 1:(div(n, 2) + 1), x2, 0:div(n, 2))
163-
@test x2 === BLAS.copyto!(x2, 1:n, x1, n:-1:1) == reverse(x1)
164153
end
165-
# trmv
166-
A = triu(rand(elty,n,n))
167-
x = rand(elty,n)
168-
@test BLAS.trmv('U','N','N',A,x) A*x
169-
@test BLAS.trmv!('U','N','N',A,view(copy(x),n:-1:1)) A*x[n:-1:1]
154+
@testset "trmv and trsv" begin
155+
A = rand(elty,n,n)
156+
x = rand(elty,n)
157+
xerr = Vector{elty}(undef,n+1)
158+
for uplo in ('U', 'L'), diag in ('U','N'), trans in ('N', 'T', 'C')
159+
Wrapper = if uplo == 'U'
160+
diag == 'U' ? UnitUpperTriangular : UpperTriangular
161+
else
162+
diag == 'U' ? UnitLowerTriangular : LowerTriangular
163+
end
164+
fun = trans == 'N' ? identity : trans == 'T' ? transpose : adjoint
165+
fullA = collect(fun(Wrapper(A)))
166+
@testset "trmv" begin
167+
@test BLAS.trmv(uplo,trans,diag,A,x) fullA * x
168+
@test_throws DimensionMismatch BLAS.trmv(uplo,trans,diag,A,xerr)
169+
for xx in (x, view(x, n:-1:1))
170+
@test BLAS.trmv!(uplo,trans,diag,A,deepcopy(xx)) fullA * xx
171+
end
172+
end
173+
@testset "trsv" begin
174+
@test BLAS.trsv(uplo,trans,diag,A,x) fullA \ x
175+
@test_throws DimensionMismatch BLAS.trsv(uplo,trans,diag,A,xerr)
176+
for xx in (x, view(x, n:-1:1))
177+
@test BLAS.trsv!(uplo,trans,diag,A,deepcopy(xx)) fullA \ xx
178+
end
179+
end
180+
end
181+
end
170182
@testset "symmetric/Hermitian multiplication" begin
171183
x = rand(elty,n)
172184
A = rand(elty,n,n)
185+
y = rand(elty, n)
186+
α = randn(elty)
187+
β = randn(elty)
173188
Aherm = A + A'
174189
Asymm = A + transpose(A)
175-
@testset "symv and hemv" begin
176-
@test BLAS.symv('U',Asymm,x) Asymm*x
177-
@test BLAS.symv('U',Asymm,view(x,n:-1:1)) Asymm*x[n:-1:1]
178-
@test BLAS.symv!('U',one(elty),Asymm,x,zero(elty),view(similar(x),n:-1:1)) Asymm*x
179-
offsizevec, offsizemat = Array{elty}.(undef,(n+1, (n,n+1)))
180-
@test_throws DimensionMismatch BLAS.symv!('U',one(elty),Asymm,x,one(elty),offsizevec)
181-
@test_throws DimensionMismatch BLAS.symv('U',offsizemat,x)
190+
offsizevec, offsizemat = Array{elty}.(undef,(n+1, (n,n+1)))
191+
@testset "symv and hemv" for uplo in ('U', 'L')
192+
@test BLAS.symv(uplo,Asymm,x) Asymm*x
193+
for xx in (x, view(x, n:-1:1)), yy in (y, view(y, n:-1:1))
194+
@test BLAS.symv!(uplo,α,Asymm,xx,β,deepcopy(yy)) α * Asymm * xx + β * yy
195+
end
196+
@test_throws DimensionMismatch BLAS.symv!(uplo,α,Asymm,x,β,offsizevec)
197+
@test_throws DimensionMismatch BLAS.symv(uplo,offsizemat,x)
182198
if elty <: BlasComplex
183-
@test BLAS.hemv('U',Aherm,x) Aherm*x
184-
@test BLAS.hemv('U',Aherm,view(x,n:-1:1)) Aherm*x[n:-1:1]
185-
@test BLAS.hemv!('U',one(elty),Aherm,x,zero(elty),view(similar(x),n:-1:1)) Aherm*x
186-
@test_throws DimensionMismatch BLAS.hemv('U',offsizemat,x)
187-
@test_throws DimensionMismatch BLAS.hemv!('U',one(elty),Aherm,x,one(elty),offsizevec)
199+
@test BLAS.hemv(uplo,Aherm,x) Aherm*x
200+
for xx in (x, view(x, n:-1:1)), yy in (y, view(y, n:-1:1))
201+
@test BLAS.hemv!(uplo,α,Aherm,xx,β,deepcopy(yy)) α * Aherm * xx + β * yy end
202+
@test_throws DimensionMismatch BLAS.hemv(uplo,offsizemat,x)
203+
@test_throws DimensionMismatch BLAS.hemv!(uplo,one(elty),Aherm,x,one(elty),offsizevec)
188204
end
189205
end
190206

@@ -214,37 +230,27 @@ end
214230
# Both matrix dimensions n coincide, as we have Hermitian matrices.
215231
# Define the inputs and outputs of hpmv!, y = α*A*x+β*y
216232
α = rand(elty)
217-
M = rand(elty, n, n)
218-
AL = Hermitian(M, :L)
219-
AU = Hermitian(M, :U)
233+
A = rand(elty, n, n)
220234
x = rand(elty, n)
221235
β = rand(elty)
222236
y = rand(elty, n)
223-
224-
# Create lower triangular packing of AL
225-
AP = elty[]
226-
for j in 1:n, i in j:n
227-
push!(AP, AL[i,j])
237+
for uplo in (:L, :U)
238+
Cuplo = String(uplo)[1]
239+
AH = Hermitian(A, uplo)
240+
# Create lower/upper triangular packing of AL
241+
AP = elty[]
242+
for j in 1:n, i in (uplo == :L ? (j:n) : (1:j))
243+
push!(AP, AH[i,j])
244+
end
245+
for xx in (x, view(x,n:-1:1)), yy in (y, view(y,n:-1:1))
246+
@test BLAS.hpmv!(Cuplo, α, AP, xx, β, deepcopy(yy)) α*AH*xx + β*yy
247+
end
248+
AP′ = view(zeros(elty, n*(n+1)),1:2:n*(n+1))
249+
@test_throws ArgumentError BLAS.hpmv!(Cuplo, α, AP′, x, β, y)
250+
AP′ = view(AP, 1:length(AP′) - 1)
251+
@test_throws DimensionMismatch BLAS.hpmv!(Cuplo, α, AP′, x, β, y)
252+
@test_throws DimensionMismatch BLAS.hpmv!(Cuplo, α, AP′, x, β, view(y,1:n-1))
228253
end
229-
@test BLAS.hpmv!('L', α, AP, x, β, copy(y)) α*AL*x + β*y
230-
@test BLAS.hpmv!('L', α, AP, view(x,n:-1:1), β, copy(y))
231-
BLAS.hpmv!('L', α, AP, x[n:-1:1], β, copy(y))
232-
233-
# Create upper triangular packing of AU
234-
AP = elty[]
235-
for j in 1:n, i in 1:j
236-
push!(AP, AU[i,j])
237-
end
238-
@test BLAS.hpmv!('U', α, AP, x, β, copy(y)) α*AU*x + β*y
239-
@test BLAS.hpmv!('U', α, AP, view(x,n:-1:1), β, copy(y))
240-
BLAS.hpmv!('U', α, AP, x[n:-1:1], β, copy(y))
241-
242-
# inputs check
243-
AP′ = view(zeros(elty, n*(n+1)),1:2:n*(n+1))
244-
@test_throws ArgumentError BLAS.hpmv!('L', α, AP′, x, β, y)
245-
AP′ = view(AP, 1:length(AP′) - 1)
246-
@test_throws DimensionMismatch BLAS.hpmv!('L', α, AP′, x, β, y)
247-
@test_throws DimensionMismatch BLAS.hpmv!('L', α, AP′, x, β, view(y,1:n-1))
248254
end
249255
end
250256

@@ -254,83 +260,82 @@ end
254260
# Both matrix dimensions n coincide, as we have symmetric matrices.
255261
# Define the inputs and outputs of spmv!, y = α*A*x+β*y
256262
α = rand(elty)
257-
M = rand(elty, n, n)
258-
AL = Symmetric(M, :L)
259-
AU = Symmetric(M, :U)
263+
A = rand(elty, n, n)
260264
x = rand(elty, n)
261265
β = rand(elty)
262266
y = rand(elty, n)
263-
264-
# Create lower triangular packing of AL
265-
AP = elty[]
266-
for j in 1:n, i in j:n
267-
push!(AP, AL[i,j])
267+
for uplo in (:L, :U)
268+
Cuplo = String(uplo)[1]
269+
AS = Symmetric(A, uplo)
270+
# Create lower/upper triangular packing of AL
271+
AP = elty[]
272+
for j in 1:n, i in (uplo == :L ? (j:n) : (1:j))
273+
push!(AP, AS[i,j])
274+
end
275+
for xx in (x, view(x,n:-1:1)), yy in (y, view(y,n:-1:1))
276+
@test BLAS.spmv!(Cuplo, α, AP, xx, β, deepcopy(yy)) α*AS*xx + β*yy
277+
end
278+
AP′ = view(zeros(elty, n*(n+1)),1:2:n*(n+1))
279+
@test_throws ArgumentError BLAS.spmv!(Cuplo, α, AP′, x, β, y)
280+
AP′ = view(AP, 1:length(AP′) - 1)
281+
@test_throws DimensionMismatch BLAS.spmv!(Cuplo, α, AP′, x, β, y)
282+
@test_throws DimensionMismatch BLAS.spmv!(Cuplo, α, AP′, x, β, view(y,1:n-1))
268283
end
269-
@test BLAS.spmv!('L', α, AP, x, β, copy(y)) α*AL*x + β*y
270-
@test BLAS.spmv!('L', α, AP, view(x,n:-1:1), β, copy(y))
271-
BLAS.spmv!('L', α, AP, x[n:-1:1], β, copy(y))
272-
273-
y_result_julia_upper = α*AU*x + β*y
274-
275-
# Create upper triangular packing of AU
276-
AP = elty[]
277-
for j in 1:n, i in 1:j
278-
push!(AP, AU[i,j])
279-
end
280-
@test BLAS.spmv!('U', α, AP, x, β, copy(y)) α*AU*x + β*y
281-
@test BLAS.spmv!('U', α, AP, view(x,n:-1:1), β, copy(y))
282-
BLAS.spmv!('U', α, AP, x[n:-1:1], β, copy(y))
283-
284-
# inputs check
285-
AP′ = view(zeros(elty, n*(n+1)),1:2:n*(n+1))
286-
@test_throws ArgumentError BLAS.spmv!('L', α, AP′, x, β, y)
287-
AP′ = view(AP, 1:length(AP′) - 1)
288-
@test_throws DimensionMismatch BLAS.spmv!('L', α, AP′, x, β, y)
289-
@test_throws DimensionMismatch BLAS.spmv!('L', α, AP′, x, β, view(y,1:n-1))
290284
end
291285
end
292-
293-
#trsm
294-
A = triu(rand(elty,n,n))
295-
B = rand(elty,(n,n))
296-
@test BLAS.trsm('L','U','N','N',one(elty),A,B) A\B
297-
286+
@testset "trsm" begin
287+
A = triu(rand(elty,n,n))
288+
B = rand(elty,(n,n))
289+
@test BLAS.trsm('L','U','N','N',one(elty),A,B) A\B
290+
end
298291
#will work for SymTridiagonal,Tridiagonal,Bidiagonal!
299292
@testset "banded matrix mv" begin
300293
@testset "gbmv" begin
301-
TD = Tridiagonal(rand(elty,n-1),rand(elty,n),rand(elty,n-1))
302-
x = rand(elty,n)
294+
TD = Tridiagonal(rand(elty,n-1),rand(elty,n),rand(elty,n-1))
295+
x = rand(elty, n)
303296
#put TD into the BLAS format!
304297
fTD = zeros(elty,3,n)
305298
fTD[1,2:n] = TD.du
306299
fTD[2,:] = TD.d
307300
fTD[3,1:n-1] = TD.dl
308301
@test BLAS.gbmv('N',n,1,1,fTD,x) TD*x
309-
@test BLAS.gbmv('N',n,1,1,fTD,view(x,n:-1:1)) TD*x[n:-1:1]
310-
@test BLAS.gbmv!('N',n,1,1,one(elty),fTD,x,zero(elty),view(similar(x),n:-1:1)) TD*x
302+
y = rand(elty, n)
303+
α = randn(elty)
304+
β = randn(elty)
305+
for xx in (x, view(x, n:-1:1)), yy in (y, view(y, n:-1:1))
306+
@test BLAS.gbmv!('N',n,1,1,α,fTD,xx,β,deepcopy(yy)) α * TD * xx + β * yy
307+
end
311308
end
312309
#will work for SymTridiagonal only!
313-
@testset "sbmv" begin
310+
@testset "sbmv and hbmv" begin
311+
x = rand(elty,n)
314312
if elty <: BlasReal
315313
ST = SymTridiagonal(rand(elty,n),rand(elty,n-1))
316-
x = rand(elty,n)
317314
#put TD into the BLAS format!
318315
fST = zeros(elty,2,n)
319316
fST[1,2:n] = ST.ev
320317
fST[2,:] = ST.dv
321318
@test BLAS.sbmv('U',1,fST,x) ST*x
322-
@test BLAS.sbmv('U',1,fST,view(x, n:-1:1)) ST*x[n:-1:1]
323-
@test BLAS.sbmv!('U',1, one(elty), fST, x, zero(elty), view(similar(x),n:-1:1)) ST*x
319+
y = rand(elty, n)
320+
α = randn(elty)
321+
β = randn(elty)
322+
for xx in (x, view(x, n:-1:1)), yy in (y, view(y, n:-1:1))
323+
@test BLAS.sbmv!('U',1,α,fST,xx,β,deepcopy(yy)) α * ST * xx + β * yy
324+
end
324325
else
325-
dv = real(rand(elty,n))
326+
dv = rand(real(elty),n)
326327
ev = rand(elty,n-1)
327328
bH = zeros(elty,2,n)
328329
bH[1,2:n] = ev
329330
bH[2,:] = dv
330331
fullH = diagm(0 => dv, -1 => conj(ev), 1 => ev)
331332
@test BLAS.hbmv('U',1,bH,x) fullH*x
332-
@test BLAS.hbmv('U',1,bH,view(x,n:-1:1)) fullH*x[n:-1:1]
333-
@test BLAS.hbmv!('U',1, one(elty), bH, x, zero(elty), view(similar(x),n:-1:1)) fullH*x
333+
y = rand(elty, n)
334+
α = randn(elty)
335+
β = randn(elty)
336+
for xx in (x, view(x, n:-1:1)), yy in (y, view(y, n:-1:1))
337+
@test BLAS.hbmv!('U',1,α,bH,xx,β,deepcopy(yy)) α * fullH * xx + β * yy
338+
end
334339
end
335340
end
336341
end

0 commit comments

Comments
 (0)