Skip to content

Commit c9500cf

Browse files
authored
Use LazyStrings in error messages (#234)
* Use LazyStrings in error messages * Use string function instead of String constructor * LazyString in DimensionMismatch messages * Add tests * Use ColumnNorm only on Julia v1.10+ * Fix tests * Reinstate missing variable * Add tests for throw_mul_axes_err with custom axes
1 parent fbc7d72 commit c9500cf

10 files changed

+86
-45
lines changed

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Quaternions = "0.7"
2323
Random = "1.6"
2424
SparseArrays = "1.6"
2525
StableRNGs = "1"
26+
StaticArrays = "1"
2627
Test = "1.6"
2728
julia = "1.6"
2829

@@ -33,7 +34,8 @@ Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
3334
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3435
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
3536
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
37+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
3638
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3739

3840
[targets]
39-
test = ["Aqua", "Infinities", "Quaternions", "Random", "StableRNGs", "SparseArrays", "Test"]
41+
test = ["Aqua", "Infinities", "Quaternions", "Random", "StableRNGs", "SparseArrays", "StaticArrays", "Test"]

src/ArrayLayouts.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ else
5959
LinearAlgebra.UnitLowerTriangular{T,S}}
6060
end
6161

62+
@static if VERSION v"1.8.0"
63+
import Base: LazyString
64+
else
65+
const LazyString = string
66+
end
67+
6268
# Originally defined in FillArrays
6369
_copy_oftype(A::AbstractArray, ::Type{S}) where {S} = eltype(A) == S ? copy(A) : AbstractArray{S}(A)
6470
_copy_oftype(A::AbstractRange, ::Type{S}) where {S} = eltype(A) == S ? copy(A) : map(S, A)
@@ -205,7 +211,7 @@ getindex(A::AdjOrTrans{<:Any,<:LayoutVector}, kr::Integer, jr::AbstractVector) =
205211
function *(a::Transpose{T, <:LayoutVector{T}}, b::Zeros{T, 1}) where T<:Real
206212
la, lb = length(a), length(b)
207213
if la lb
208-
throw(DimensionMismatch("dot product arguments have lengths $la and $lb"))
214+
throw(DimensionMismatch(LazyString("dot product arguments have lengths ", la, " and ", lb)))
209215
end
210216
return zero(T)
211217
end
@@ -334,7 +340,7 @@ end
334340
@inline function reflectorApply!(x::AbstractVector, τ::Number, A::AbstractVecOrMat)
335341
m,n = size(A,1),size(A,2)
336342
if length(x) != m
337-
throw(DimensionMismatch("reflector has length $(length(x)), which must match the first dimension of matrix A, $m"))
343+
throw(DimensionMismatch(LazyString("reflector has length ", length(x), ", which must match the first dimension of matrix A, ", m)))
338344
end
339345
m == 0 && return A
340346
@inbounds begin

src/factorizations.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ function copyto!(dest::AbstractArray, M::Ldiv{<:AbstractQLayout})
152152
ldiv!(A,dest)
153153
end
154154

155-
materialize!(M::Lmul{LAY}) where LAY<:AbstractQLayout = error("Overload materialize!(::Lmul{$(LAY)})")
156-
materialize!(M::Rmul{LAY}) where LAY<:AbstractQLayout = error("Overload materialize!(::Rmul{$(LAY)})")
155+
materialize!(M::Lmul{LAY}) where LAY<:AbstractQLayout = error(LazyString("Overload materialize!(::Lmul{", LAY, "})"))
156+
materialize!(M::Rmul{LAY}) where LAY<:AbstractQLayout = error(LazyString("Overload materialize!(::Rmul{", LAY, "})"))
157157

158158
materialize!(M::Ldiv{<:AbstractQLayout}) = materialize!(Lmul(M.A',M.B))
159159

@@ -179,7 +179,7 @@ function materialize!(M::Lmul{<:QRPackedQLayout})
179179
mA, nA = size(A.factors)
180180
mB, nB = size(B,1), size(B,2)
181181
if mA != mB
182-
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA) but B has dimensions ($mB, $nB)"))
182+
throw(DimensionMismatch(LazyString("matrix A has dimensions (", mA, ",", nA, ") but B has dimensions (", mB, ", ", nB, ")")))
183183
end
184184
Afactors = A.factors
185185
@inbounds begin
@@ -217,7 +217,7 @@ function materialize!(M::Lmul{<:AdjQRPackedQLayout})
217217
mA, nA = size(A.factors)
218218
mB, nB = size(B,1), size(B,2)
219219
if mA != mB
220-
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA) but B has dimensions ($mB, $nB)"))
220+
throw(DimensionMismatch(LazyString("matrix A has dimensions (", mA, ",", nA, ") but B has dimensions (", mB, ", ", nB, ")")))
221221
end
222222
Afactors = A.factors
223223
@inbounds begin
@@ -248,7 +248,7 @@ function materialize!(M::Rmul{<:Any,<:QRPackedQLayout})
248248
mQ, nQ = size(Q.factors)
249249
mA, nA = size(A,1), size(A,2)
250250
if nA != mQ
251-
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA) but matrix Q has dimensions ($mQ, $nQ)"))
251+
throw(DimensionMismatch(LazyString("matrix A has dimensions (", mA, ",", nA, ") but matrix Q has dimensions (", mQ, ", ", nQ, ")")))
252252
end
253253
Qfactors = Q.factors
254254
@inbounds begin
@@ -284,7 +284,7 @@ function materialize!(M::Rmul{<:Any,<:AdjQRPackedQLayout})
284284
mQ, nQ = size(Q.factors)
285285
mA, nA = size(A,1), size(A,2)
286286
if nA != mQ
287-
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA) but matrix Q has dimensions ($mQ, $nQ)"))
287+
throw(DimensionMismatch(LazyString("matrix A has dimensions (", mA, ",", nA, ") but matrix Q has dimensions (", mQ, ", ", nQ, ")")))
288288
end
289289
Qfactors = Q.factors
290290
@inbounds begin
@@ -309,10 +309,10 @@ end
309309
__qr(layout, lengths, A; kwds...) = invoke(qr, Tuple{AbstractMatrix{eltype(A)}}, A; kwds...)
310310
_qr(layout, axes, A; kwds...) = __qr(layout, map(length, axes), A; kwds...)
311311
_qr(layout, axes, A, pivot::P; kwds...) where P = invoke(qr, Tuple{AbstractMatrix{eltype(A)},P}, A, pivot; kwds...)
312-
_qr!(layout, axes, A, args...; kwds...) = error("Overload _qr!(::$(typeof(layout)), axes, A)")
312+
_qr!(layout, axes, A, args...; kwds...) = error(LazyString("Overload _qr!(::", typeof(layout), ", axes, A)"))
313313
_lu(layout, axes, A; kwds...) = invoke(lu, Tuple{AbstractMatrix{eltype(A)}}, A; kwds...)
314314
_lu(layout, axes, A, pivot::P; kwds...) where P = invoke(lu, Tuple{AbstractMatrix{eltype(A)},P}, A, pivot; kwds...)
315-
_lu!(layout, axes, A, args...; kwds...) = error("Overload _lu!(::$(typeof(layout)), axes, A)")
315+
_lu!(layout, axes, A, args...; kwds...) = error(LazyString("Overload _lu!(::", typeof(layout), ", axes, A)"))
316316
_cholesky(layout, axes, A, ::CNoPivot=CNoPivot(); check::Bool = true) = cholesky!(cholcopy(A); check = check)
317317
_cholesky(layout, axes, A, ::CRowMaximum; tol = 0.0, check::Bool = true) = cholesky!(cholcopy(A), CRowMaximum(); tol = tol, check = check)
318318
_factorize(layout, axes, A) = qr(A) # Default to QR

src/ldiv.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ _getindex(::Type{Tuple{I,J}}, L::Ldiv, (k,j)::Tuple{Colon,J}) where {I,J} = Ldiv
5656
_getindex(::Type{Tuple{I,J}}, L::Ldiv, (k,j)::Tuple{I,J}) where {I,J} = L[:,j][k]
5757

5858
check_ldiv_axes(A, B) =
59-
axes(A,1) == axes(B,1) || throw(DimensionMismatch("First axis of A, $(axes(A,1)), and first axis of B, $(axes(B,1)) must match"))
59+
axes(A,1) == axes(B,1) || throw(DimensionMismatch(LazyString("First axis of A, ", axes(A,1), ", and first axis of B, ", axes(B,1), " must match")))
6060

6161
check_rdiv_axes(A, B) =
62-
axes(A,2) == axes(B,2) || throw(DimensionMismatch("Second axis of A, $(axes(A,2)), and second axis of B, $(axes(B,2)) must match"))
62+
axes(A,2) == axes(B,2) || throw(DimensionMismatch(LazyString("Second axis of A, ", axes(A,2), ", and second axis of B, ", axes(B,2), " must match")))
6363

6464

6565

@@ -73,12 +73,12 @@ end
7373
Rdiv(instantiate(L.A), instantiate(L.B))
7474
end
7575

76-
__ldiv!(::Mat, ::Mat, B) where Mat = error("Overload materialize!(::Ldiv{$(typeof(MemoryLayout(Mat))),$(typeof(MemoryLayout(B)))})")
77-
__ldiv!(::Mat, ::Mat, B::LayoutArray) where Mat = error("Overload materialize!(::Ldiv{$(typeof(MemoryLayout(Mat))),$(typeof(MemoryLayout(B)))})")
76+
__ldiv!(::Mat, ::Mat, B) where Mat = error(LazyString("Overload materialize!(::Ldiv{", typeof(MemoryLayout(Mat)), ",", typeof(MemoryLayout(B)), "})"))
77+
__ldiv!(::Mat, ::Mat, B::LayoutArray) where Mat = error(LazyString("Overload materialize!(::Ldiv{", typeof(MemoryLayout(Mat)), ",", typeof(MemoryLayout(B)), "})"))
7878
__ldiv!(_, F, B) = LinearAlgebra.ldiv!(F, B)
7979
@inline _ldiv!(A, B) = __ldiv!(A, factorize(A), B)
8080
@inline _ldiv!(A::Factorization, B) = LinearAlgebra.ldiv!(A, B)
81-
@inline _ldiv!(A::Factorization, B::LayoutArray) = error("Overload materialize!(::Ldiv{$(typeof(MemoryLayout(A))),$(typeof(MemoryLayout(B)))})")
81+
@inline _ldiv!(A::Factorization, B::LayoutArray) = error(LazyString("Overload materialize!(::Ldiv{", typeof(MemoryLayout(A)), ",", typeof(MemoryLayout(B)), "})"))
8282

8383
@inline _ldiv!(dest, A, B; kwds...) = ldiv!(dest, factorize(A), B; kwds...)
8484
@inline _ldiv!(dest, A::Factorization, B; kwds...) = LinearAlgebra.ldiv!(dest, A, B; kwds...)

src/memorylayout.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,8 @@ diagonaldata(D::Bidiagonal) = D.dv
585585
diagonaldata(D::SymTridiagonal) = D.dv
586586
diagonaldata(D::Tridiagonal) = D.d
587587

588-
supdiagonaldata(D::Bidiagonal) = D.uplo == 'U' ? D.ev : throw(ArgumentError("$D is lower-bidiagonal"))
589-
subdiagonaldata(D::Bidiagonal) = D.uplo == 'L' ? D.ev : throw(ArgumentError("$D is upper-bidiagonal"))
588+
supdiagonaldata(D::Bidiagonal) = D.uplo == 'U' ? D.ev : throw(ArgumentError(LazyString(D, " is lower-bidiagonal")))
589+
subdiagonaldata(D::Bidiagonal) = D.uplo == 'L' ? D.ev : throw(ArgumentError(LazyString(D, " is upper-bidiagonal")))
590590

591591
supdiagonaldata(D::SymTridiagonal) = D.ev
592592
subdiagonaldata(D::SymTridiagonal) = D.ev

src/mul.jl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,28 @@ check_mul_axes(A) = nothing
9292
_check_mul_axes(::Number, ::Number) = nothing
9393
_check_mul_axes(::Number, _) = nothing
9494
_check_mul_axes(_, ::Number) = nothing
95-
_check_mul_axes(A, B) = axes(A, 2) == axes(B, 1) || throw(DimensionMismatch("Second axis of A, $(axes(A,2)), and first axis of B, $(axes(B,1)) must match"))
95+
_check_mul_axes(A, B) = axes(A, 2) == axes(B, 1) || throw_mul_axes_err(axes(A,2), axes(B,1))
96+
@noinline function throw_mul_axes_err(axA2, axB1)
97+
throw(
98+
DimensionMismatch(
99+
LazyString("second axis of A, ", axA2, ", and first axis of B, ", axB1, ", must match")))
100+
end
101+
@noinline function throw_mul_axes_err(axA2::Base.OneTo, axB1::Base.OneTo)
102+
throw(
103+
DimensionMismatch(
104+
LazyString("second dimension of A, ", length(axA2), ", does not match length of x, ", length(axB1))))
105+
end
96106
# we need to special case AbstractQ as it allows non-compatiple multiplication
97107
const FlexibleLeftQs = Union{QRCompactWYQ,QRPackedQ,HessenbergQ}
98108
_check_mul_axes(::FlexibleLeftQs, ::Number) = nothing
99109
_check_mul_axes(Q::FlexibleLeftQs, B) =
100110
axes(Q.factors, 1) == axes(B, 1) || axes(Q.factors, 2) == axes(B, 1) ||
101-
throw(DimensionMismatch("First axis of B, $(axes(B,1)) must match either axes of A, $(axes(Q.factors))"))
111+
throw(DimensionMismatch(LazyString("First axis of B, ", axes(B,1), " must match either axes of A, ", axes(Q.factors))))
102112
_check_mul_axes(::Number, ::AdjointQtype{<:Any,<:FlexibleLeftQs}) = nothing
103113
function _check_mul_axes(A, adjQ::AdjointQtype{<:Any,<:FlexibleLeftQs})
104114
Q = parent(adjQ)
105115
axes(A, 2) == axes(Q.factors, 1) || axes(A, 2) == axes(Q.factors, 2) ||
106-
throw(DimensionMismatch("Second axis of A, $(axes(A,2)) must match either axes of B, $(axes(Q.factors))"))
116+
throw(DimensionMismatch(LazyString("Second axis of A, ", axes(A,2), " must match either axes of B, ", axes(Q.factors))))
107117
end
108118
_check_mul_axes(Q::FlexibleLeftQs, adjQ::AdjointQtype{<:Any,<:FlexibleLeftQs}) =
109119
invoke(_check_mul_axes, Tuple{Any,Any}, Q, adjQ)
@@ -115,7 +125,7 @@ end
115125
# we need to special case AbstractQ as it allows non-compatiple multiplication
116126
function check_mul_axes(A::Union{QRCompactWYQ,QRPackedQ}, B, C...)
117127
axes(A.factors, 1) == axes(B, 1) || axes(A.factors, 2) == axes(B, 1) ||
118-
throw(DimensionMismatch("First axis of B, $(axes(B,1)) must match either axes of A, $(axes(A))"))
128+
throw(DimensionMismatch(LazyString("First axis of B, ", axes(B,1), " must match either axes of A, ", axes(A))))
119129
check_mul_axes(B, C...)
120130
end
121131

src/muladd.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ similar(M::MulAdd) = similar(M, eltype(M))
5252
function checkdimensions(M::MulAdd)
5353
@boundscheck check_mul_axes(M.α, M.A, M.B)
5454
@boundscheck check_mul_axes(M.β, M.C)
55-
@boundscheck axes(M.A,1) == axes(M.C,1) || throw(DimensionMismatch("First axis of A, $(axes(M.A,1)), and first axis of C, $(axes(M.C,1)) must match"))
56-
@boundscheck axes(M.B,2) == axes(M.C,2) || throw(DimensionMismatch("Second axis of B, $(axes(M.B,2)), and second axis of C, $(axes(M.C,2)) must match"))
55+
@boundscheck axes(M.A,1) == axes(M.C,1) || throw(DimensionMismatch(LazyString("First axis of A, ", axes(M.A,1), ", and first axis of C, ", axes(M.C,1), " must match")))
56+
@boundscheck axes(M.B,2) == axes(M.C,2) || throw(DimensionMismatch(LazyString("Second axis of B, ", axes(M.B,2), ", and second axis of C, ", axes(M.C,2), " must match")))
5757
end
5858
@propagate_inbounds function instantiate(M::MulAdd)
5959
checkdimensions(M)

src/triangular.jl

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function materialize!(M::Lmul{<:TriangularLayout{'U','N'}})
2626
A,B = M.A,M.B
2727
m, n = size(B, 1), size(B, 2)
2828
if m != size(A, 1)
29-
throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m"))
29+
throw(DimensionMismatch(LazyString("right hand side B needs first dimension of size ", size(A,1), ", has size ", m)))
3030
end
3131
Adata = triangulardata(A)
3232
for j = rowsupport(B)
@@ -46,7 +46,7 @@ function materialize!(M::Lmul{<:TriangularLayout{'U','U'}})
4646
A,B = M.A,M.B
4747
m, n = size(B, 1), size(B, 2)
4848
if m != size(A, 1)
49-
throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m"))
49+
throw(DimensionMismatch(LazyString("right hand side B needs first dimension of size ", size(A,1), ", has size ", m)))
5050
end
5151
Adata = triangulardata(A)
5252
for j = rowsupport(B)
@@ -66,7 +66,7 @@ function materialize!(M::Lmul{<:TriangularLayout{'L','N'}})
6666
A,B = M.A,M.B
6767
m, n = size(B, 1), size(B, 2)
6868
if m != size(A, 1)
69-
throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m"))
69+
throw(DimensionMismatch(LazyString("right hand side B needs first dimension of size ", size(A,1), ", has size ", m)))
7070
end
7171
Adata = triangulardata(A)
7272
for j = 1:n
@@ -84,7 +84,7 @@ function materialize!(M::Lmul{<:TriangularLayout{'L','U'}})
8484
A,B = M.A,M.B
8585
m, n = size(B, 1), size(B, 2)
8686
if m != size(A, 1)
87-
throw(DimensionMismatch("right hand side B needs first dimension of size $(size(A,1)), has size $m"))
87+
throw(DimensionMismatch(LazyString("right hand side B needs first dimension of size ", size(A,1), ", has size ", m)))
8888
end
8989
Adata = triangulardata(A)
9090
for j = 1:n
@@ -264,10 +264,7 @@ end
264264
function materialize!(M::MatLdivVec{<:TriangularLayout{'U','N'}})
265265
A,b = M.A,M.B
266266
require_one_based_indexing(A, b)
267-
n = size(A, 2)
268-
if !(n == length(b))
269-
throw(DimensionMismatch("second dimension of left hand side A, $n, and length of right hand side b, $(length(b)), must be equal"))
270-
end
267+
check_mul_axes(A, b)
271268
data = triangulardata(A)
272269
@inbounds for j in reverse(colsupport(b,1))
273270
iszero(data[j,j]) && throw(SingularException(j))
@@ -282,10 +279,7 @@ end
282279
function materialize!(M::MatLdivVec{<:TriangularLayout{'U','U'}})
283280
A,b = M.A,M.B
284281
require_one_based_indexing(A, b)
285-
n = size(A, 2)
286-
if !(n == length(b))
287-
throw(DimensionMismatch("second dimension of left hand side A, $n, and length of right hand side b, $(length(b)), must be equal"))
288-
end
282+
check_mul_axes(A, b)
289283
data = triangulardata(A)
290284
@inbounds for j in reverse(colsupport(b,1))
291285
iszero(data[j,j]) && throw(SingularException(j))
@@ -300,11 +294,9 @@ end
300294
function materialize!(M::MatLdivVec{<:TriangularLayout{'L','N'}})
301295
A,b = M.A,M.B
302296
require_one_based_indexing(A, b)
303-
n = size(A, 2)
304-
if !(n == length(b))
305-
throw(DimensionMismatch("second dimension of left hand side A, $n, and length of right hand side b, $(length(b)), must be equal"))
306-
end
297+
check_mul_axes(A, b)
307298
data = triangulardata(A)
299+
n = size(A, 2)
308300
@inbounds for j in 1:n
309301
iszero(data[j,j]) && throw(SingularException(j))
310302
bj = b[j] = data[j,j] \ b[j]
@@ -318,11 +310,9 @@ end
318310
function materialize!(M::MatLdivVec{<:TriangularLayout{'L','U'}})
319311
A,b = M.A,M.B
320312
require_one_based_indexing(A, b)
321-
n = size(A, 2)
322-
if !(n == length(b))
323-
throw(DimensionMismatch("second dimension of left hand side A, $n, and length of right hand side b, $(length(b)), must be equal"))
324-
end
313+
check_mul_axes(A, b)
325314
data = triangulardata(A)
315+
n = size(A, 2)
326316
@inbounds for j in 1:n
327317
iszero(data[j,j]) && throw(SingularException(j))
328318
bj = b[j]
@@ -379,7 +369,7 @@ function materialize!(M::MatLdivVec{<:BidiagonalLayout})
379369
require_one_based_indexing(A, b)
380370
N = size(A, 2)
381371
if N != length(b)
382-
throw(DimensionMismatch("second dimension of A, $N, does not match one of the length of b, $(length(b))"))
372+
throw(DimensionMismatch(LazyString("second dimension of A, ", N, ", does not match one of the length of b, ", length(b))))
383373
end
384374

385375
if N == 0

test/test_ldiv.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module TestLdiv
22

33
using ArrayLayouts, LinearAlgebra, FillArrays, Test
44
import ArrayLayouts: ApplyBroadcastStyle, QRCompactWYQLayout, QRCompactWYLayout, QRPackedQLayout, QRPackedLayout
5+
using StaticArrays
56

67
@testset "Ldiv" begin
78
@testset "Float64 \\ *" begin
@@ -295,6 +296,25 @@ import ArrayLayouts: ApplyBroadcastStyle, QRCompactWYQLayout, QRCompactWYLayout,
295296
@test ArrayLayouts.rdiv!(similar(B), B, D) == B / D
296297
@test_broken ArrayLayouts.rdiv!(similar(B), D, B) == D / B
297298
end
299+
300+
@testset "error paths" begin
301+
v = rand(Int,3)
302+
A = rand(2,2)
303+
S = SMatrix{2,2}(A)
304+
errA(U) = DimensionMismatch("second dimension of A, $(size(U,2)), does not match length of x, $(length(v))")
305+
errS(U) = DimensionMismatch("second axis of A, $(axes(U,2)), and first axis of B, $(axes(v,1)), must match")
306+
for (M, errf) in ((A, errA), (S, errS))
307+
U = UpperTriangular(M)
308+
err = errf(U)
309+
@test_throws err ArrayLayouts.materialize!(ArrayLayouts.Ldiv(U, v))
310+
UU = UnitUpperTriangular(M)
311+
@test_throws err ArrayLayouts.materialize!(ArrayLayouts.Ldiv(UU, v))
312+
L = LowerTriangular(M)
313+
@test_throws err ArrayLayouts.materialize!(ArrayLayouts.Ldiv(L, v))
314+
UL = UnitLowerTriangular(M)
315+
@test_throws err ArrayLayouts.materialize!(ArrayLayouts.Ldiv(UL, v))
316+
end
317+
end
298318
end
299319

300320
end

test/test_muladd.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,19 @@ Random.seed!(0)
845845
end
846846
end
847847

848+
@testset "Error paths" begin
849+
if VERSION >= v"1.10.0"
850+
Q = qr(rand(2,2), ColumnNorm()).Q
851+
else
852+
Q = qr(rand(2,2), Val(true)).Q
853+
end
854+
v = rand(Float32, 3)
855+
@test_throws DimensionMismatch ArrayLayouts.materialize!(ArrayLayouts.Rmul(v, Q))
856+
@test_throws DimensionMismatch ArrayLayouts.materialize!(ArrayLayouts.Rmul(v, Q'))
857+
@test_throws DimensionMismatch ArrayLayouts.materialize!(ArrayLayouts.Lmul(Q, v))
858+
@test_throws DimensionMismatch ArrayLayouts.materialize!(ArrayLayouts.Lmul(Q', v))
859+
end
860+
848861
@testset "dual" begin
849862
a = randn(5)
850863
X = randn(5,6)

0 commit comments

Comments
 (0)