Skip to content

Commit 997c4b7

Browse files
authored
Backports to v1.12.3 (#1490)
2 parents 5567504 + b17cd17 commit 997c4b7

File tree

13 files changed

+44
-51
lines changed

13 files changed

+44
-51
lines changed

src/bidiag.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ function dot(x::AbstractVector, B::Bidiagonal, y::AbstractVector)
12091209
nx, ny = length(x), length(y)
12101210
(nx == size(B, 1) == ny) || throw(DimensionMismatch())
12111211
if nx 1
1212-
nx == 0 && return dot(zero(eltype(x)), zero(eltype(B)), zero(eltype(y)))
1212+
nx == 0 && return zero(dot(zero(eltype(x)), zero(eltype(B)), zero(eltype(y))))
12131213
return dot(x[1], B.dv[1], y[1])
12141214
end
12151215
ev, dv = B.ev, B.dv

src/blas.jl

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ export
8484
trsm!,
8585
trsm
8686

87-
using ..LinearAlgebra: libblastrampoline, BlasReal, BlasComplex, BlasFloat, BlasInt,
88-
DimensionMismatch, checksquare, chkstride1, SingularException
87+
using ..LinearAlgebra: libblastrampoline, BlasReal, BlasComplex, BlasFloat, BlasInt, DimensionMismatch, checksquare, chkstride1
8988

9089
include("lbt.jl")
9190

@@ -1370,11 +1369,6 @@ for (fname, elty) in ((:dtrsv_,:Float64),
13701369
throw(DimensionMismatch(lazy"size of A is $n != length(x) = $(length(x))"))
13711370
end
13721371
chkstride1(A)
1373-
if diag == 'N'
1374-
for i in 1:n
1375-
iszero(A[i,i]) && throw(SingularException(i))
1376-
end
1377-
end
13781372
px, stx = vec_pointer_stride(x, ArgumentError("input vector with 0 stride is not allowed"))
13791373
GC.@preserve x ccall((@blasfunc($fname), libblastrampoline), Cvoid,
13801374
(Ref{UInt8}, Ref{UInt8}, Ref{UInt8}, Ref{BlasInt},
@@ -2098,7 +2092,7 @@ end
20982092
her2k!(uplo, trans, alpha, A, B, beta, C)
20992093
21002094
Rank-2k update of the Hermitian matrix `C` as
2101-
`alpha*A*B' + alpha*B*A' + beta*C` or `alpha*A'*B + alpha*B'*A + beta*C`
2095+
`alpha*A*B' + alpha'*B*A' + beta*C` or `alpha*A'*B + alpha'*B'*A + beta*C`
21022096
according to [`trans`](@ref stdlib-blas-trans). The scalar `beta` has to be real.
21032097
Only the [`uplo`](@ref stdlib-blas-uplo) triangle of `C` is used. Return `C`.
21042098
"""
@@ -2107,8 +2101,8 @@ function her2k! end
21072101
"""
21082102
her2k(uplo, trans, alpha, A, B)
21092103
2110-
Return the [`uplo`](@ref stdlib-blas-uplo) triangle of `alpha*A*B' + alpha*B*A'`
2111-
or `alpha*A'*B + alpha*B'*A`, according to [`trans`](@ref stdlib-blas-trans).
2104+
Return the [`uplo`](@ref stdlib-blas-uplo) triangle of `alpha*A*B' + alpha'*B*A'`
2105+
or `alpha*A'*B + alpha'*B'*A`, according to [`trans`](@ref stdlib-blas-trans).
21122106
"""
21132107
her2k(uplo, trans, alpha, A, B)
21142108

@@ -2223,11 +2217,6 @@ for (mmname, smname, elty) in
22232217
end
22242218
chkstride1(A)
22252219
chkstride1(B)
2226-
if diag == 'N'
2227-
for i in 1:k
2228-
iszero(A[i,i]) && throw(SingularException(i))
2229-
end
2230-
end
22312220
ccall((@blasfunc($smname), libblastrampoline), Cvoid,
22322221
(Ref{UInt8}, Ref{UInt8}, Ref{UInt8}, Ref{UInt8},
22332222
Ref{BlasInt}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty},

src/generic.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,8 @@ function dot(x::AbstractArray, y::AbstractArray)
986986
throw(DimensionMismatch(lazy"first array has length $(lx) which does not match the length of the second, $(length(y))."))
987987
end
988988
if lx == 0
989-
return dot(zero(eltype(x)), zero(eltype(y)))
989+
# make sure the returned result equals exactly the zero element
990+
return zero(dot(zero(eltype(x)), zero(eltype(y))))
990991
end
991992
s = zero(dot(first(x), first(y)))
992993
for (Ix, Iy) in zip(eachindex(x), eachindex(y))
@@ -1027,6 +1028,8 @@ dot(x, A, y) = dot(x, A*y) # generic fallback for cases that are not covered by
10271028

10281029
function dot(x::AbstractVector, A::AbstractMatrix, y::AbstractVector)
10291030
(axes(x)..., axes(y)...) == axes(A) || throw(DimensionMismatch())
1031+
# outermost zero call to avoid spurious sign ambiguity (like 0.0 - 0.0im)
1032+
any(isempty, (x, y)) && return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
10301033
T = typeof(dot(first(x), first(A), first(y)))
10311034
s = zero(T)
10321035
i₁ = first(eachindex(x))

src/hessenberg.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ function dot(x::AbstractVector, H::UpperHessenberg, y::AbstractVector)
360360
m = size(H, 1)
361361
(length(x) == m == length(y)) || throw(DimensionMismatch())
362362
if iszero(m)
363-
return dot(zero(eltype(x)), zero(eltype(H)), zero(eltype(y)))
363+
return zero(dot(zero(eltype(x)), zero(eltype(H)), zero(eltype(y))))
364364
end
365365
x₁ = x[1]
366366
r = dot(x₁, H[1,1], y[1])

src/matmul.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ end
460460
throw(DimensionMismatch(
461461
LazyString(
462462
"incompatible destination size: ",
463-
lazy"the destination $strC of $size_or_len_str_C $C_size_len is incomatible with the product of a $strA of size $sizeA and a $strB of $size_or_len_str_B $B_size_len. ",
463+
lazy"the destination $strC of $size_or_len_str_C $C_size_len is incompatible with the product of a $strA of size $sizeA and a $strB of $size_or_len_str_B $B_size_len. ",
464464
lazy"The destination must be of $size_or_len_str_dest $destsize."
465465
)
466466
)

src/symmetric.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ for (T, trans, real) in [(:Symmetric, :transpose, :identity), (:(Hermitian{<:Uni
520520
if n != size(B, 2)
521521
throw(DimensionMismatch(lazy"A has dimensions $(size(A)) but B has dimensions $(size(B))"))
522522
end
523-
523+
iszero(n) && return $real(zero(dot(zero(eltype(A)), zero(eltype(B)))))
524524
dotprod = $real(zero(dot(first(A), first(B))))
525525
@inbounds if A.uplo == 'U' && B.uplo == 'U'
526526
for j in 1:n
@@ -719,6 +719,7 @@ function dot(x::AbstractVector, A::RealHermSymComplexHerm, y::AbstractVector)
719719
require_one_based_indexing(x, y)
720720
n = length(x)
721721
(n == length(y) == size(A, 1)) || throw(DimensionMismatch())
722+
iszero(n) && return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
722723
data = A.data
723724
r = dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y)))
724725
iszero(n) && return r

src/triangular.jl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ function dot(x::AbstractVector, A::UpperTriangular, y::AbstractVector)
849849
m = size(A, 1)
850850
(length(x) == m == length(y)) || throw(DimensionMismatch())
851851
if iszero(m)
852-
return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y)))
852+
return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
853853
end
854854
x₁ = x[1]
855855
r = dot(x₁, A[1,1], y[1])
@@ -870,7 +870,7 @@ function dot(x::AbstractVector, A::UnitUpperTriangular, y::AbstractVector)
870870
m = size(A, 1)
871871
(length(x) == m == length(y)) || throw(DimensionMismatch())
872872
if iszero(m)
873-
return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y)))
873+
return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
874874
end
875875
x₁ = first(x)
876876
r = dot(x₁, y[1])
@@ -892,7 +892,7 @@ function dot(x::AbstractVector, A::LowerTriangular, y::AbstractVector)
892892
m = size(A, 1)
893893
(length(x) == m == length(y)) || throw(DimensionMismatch())
894894
if iszero(m)
895-
return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y)))
895+
return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
896896
end
897897
r = zero(typeof(dot(first(x), first(A), first(y))))
898898
@inbounds for j in axes(A, 2)
@@ -912,7 +912,7 @@ function dot(x::AbstractVector, A::UnitLowerTriangular, y::AbstractVector)
912912
m = size(A, 1)
913913
(length(x) == m == length(y)) || throw(DimensionMismatch())
914914
if iszero(m)
915-
return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y)))
915+
return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
916916
end
917917
r = zero(typeof(dot(first(x), first(y))))
918918
@inbounds for j in axes(A, 2)
@@ -1268,13 +1268,11 @@ function generic_mattrimul!(C::StridedMatrix{T}, uploc, isunitc, tfun::Function,
12681268
end
12691269
end
12701270
# division
1271-
generic_trimatdiv!(C::StridedVector{T}, uploc, isunitc, tfun::Function, A::StridedMatrix{T}, B::AbstractVector{T}) where {T<:BlasFloat} =
1272-
BLAS.trsv!(uploc, tfun === identity ? 'N' : tfun === transpose ? 'T' : 'C', isunitc, A, C === B ? C : copyto!(C, B))
1273-
function generic_trimatdiv!(C::StridedMatrix{T}, uploc, isunitc, tfun::Function, A::StridedMatrix{T}, B::AbstractMatrix{T}) where {T<:BlasFloat}
1271+
function generic_trimatdiv!(C::StridedVecOrMat{T}, uploc, isunitc, tfun::Function, A::StridedMatrix{T}, B::AbstractVecOrMat{T}) where {T<:BlasFloat}
12741272
if stride(C,1) == stride(A,1) == 1
1275-
BLAS.trsm!('L', uploc, tfun === identity ? 'N' : tfun === transpose ? 'T' : 'C', isunitc, one(T), A, C === B ? C : copyto!(C, B))
1273+
LAPACK.trtrs!(uploc, tfun === identity ? 'N' : tfun === transpose ? 'T' : 'C', isunitc, A, C === B ? C : copyto!(C, B))
12761274
else # incompatible with LAPACK
1277-
@invoke generic_trimatdiv!(C::AbstractVecOrMat, uploc, isunitc, tfun::Function, A::AbstractMatrix, B::AbstractMatrix)
1275+
@invoke generic_trimatdiv!(C::AbstractVecOrMat, uploc, isunitc, tfun::Function, A::AbstractMatrix, B::AbstractVecOrMat)
12781276
end
12791277
end
12801278
function generic_mattridiv!(C::StridedMatrix{T}, uploc, isunitc, tfun::Function, A::AbstractMatrix{T}, B::StridedMatrix{T}) where {T<:BlasFloat}

src/tridiag.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ function dot(x::AbstractVector, S::SymTridiagonal, y::AbstractVector)
246246
nx, ny = length(x), length(y)
247247
(nx == size(S, 1) == ny) || throw(DimensionMismatch("dot"))
248248
if nx 1
249-
nx == 0 && return dot(zero(eltype(x)), zero(eltype(S)), zero(eltype(y)))
249+
nx == 0 && return zero(dot(zero(eltype(x)), zero(eltype(S)), zero(eltype(y))))
250250
return dot(x[1], S.dv[1], y[1])
251251
end
252252
dv, ev = S.dv, S.ev
@@ -965,7 +965,7 @@ function dot(x::AbstractVector, A::Tridiagonal, y::AbstractVector)
965965
nx, ny = length(x), length(y)
966966
(nx == size(A, 1) == ny) || throw(DimensionMismatch())
967967
if nx 1
968-
nx == 0 && return dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y)))
968+
nx == 0 && return zero(dot(zero(eltype(x)), zero(eltype(A)), zero(eltype(y))))
969969
return dot(x[1], A.d[1], y[1])
970970
end
971971
@inbounds begin

test/generic.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,10 @@ end
733733
@test dot(x, B', y) dot(B*x, y)
734734
elty <: Real && @test dot(x, transpose(B), y) dot(x, transpose(B)*y)
735735
end
736+
for (m, n) in ((0, 0), (1, 0), (0, 1))
737+
v = zeros(ComplexF64, m); a = zeros(ComplexF64, m, n); w = zeros(Float64, n)
738+
@test dot(v, a, w) === zero(ComplexF64)
739+
end
736740
end
737741

738742
@testset "condskeel #34512" begin

test/matmul.jl

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -676,23 +676,24 @@ end
676676
@test dot(Z, Z) == convert(elty, 34.0)
677677
end
678678

679-
dot1(x, y) = invoke(dot, Tuple{Any,Any}, x, y)
680-
dot2(x, y) = invoke(dot, Tuple{AbstractArray,AbstractArray}, x, y)
681679
@testset "generic dot" begin
680+
dot1(x, y) = invoke(dot, Tuple{Any,Any}, x, y)
681+
dot2(x, y) = invoke(dot, Tuple{AbstractArray,AbstractArray}, x, y)
682682
AA = [1+2im 3+4im; 5+6im 7+8im]
683683
BB = [2+7im 4+1im; 3+8im 6+5im]
684684
for A in (copy(AA), view(AA, 1:2, 1:2)), B in (copy(BB), view(BB, 1:2, 1:2))
685685
@test dot(A, B) == dot(vec(A), vec(B)) == dot1(A, B) == dot2(A, B) == dot(float.(A), float.(B))
686-
@test dot(Int[], Int[]) == 0 == dot1(Int[], Int[]) == dot2(Int[], Int[])
687-
@test_throws MethodError dot(Any[], Any[])
688-
@test_throws MethodError dot1(Any[], Any[])
689-
@test_throws MethodError dot2(Any[], Any[])
690-
for n1 = 0:2, n2 = 0:2, d in (dot, dot1, dot2)
691-
if n1 != n2
692-
@test_throws DimensionMismatch d(1:n1, 1:n2)
693-
else
694-
@test d(1:n1, 1:n2) norm(1:n1)^2
695-
end
686+
end
687+
@test dot(Int[], Int[]) == 0 == dot1(Int[], Int[]) == dot2(Int[], Int[])
688+
@test dot(ComplexF64[], Float64[]) === dot(ComplexF64[;;], Float64[;;]) === zero(ComplexF64)
689+
@test_throws MethodError dot(Any[], Any[])
690+
@test_throws MethodError dot1(Any[], Any[])
691+
@test_throws MethodError dot2(Any[], Any[])
692+
for n1 = 0:2, n2 = 0:2, d in (dot, dot1, dot2)
693+
if n1 != n2
694+
@test_throws DimensionMismatch d(1:n1, 1:n2)
695+
else
696+
@test d(1:n1, 1:n2) norm(1:n1)^2
696697
end
697698
end
698699
end

0 commit comments

Comments
 (0)