Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid unwrapping-wrapping combination in LinearAlgebra #41252

Merged
merged 4 commits into from
Jun 19, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -745,32 +745,30 @@ function ldiv!(A::Union{Bidiagonal,AbstractTriangular}, B::AbstractMatrix)
end
function ldiv!(adjA::Adjoint{<:Any,<:Union{Bidiagonal,AbstractTriangular}}, B::AbstractMatrix)
require_one_based_indexing(adjA, B)
A = adjA.parent
nA,mA = size(A)
tmp = similar(B,size(B,1))
mA, nA = size(adjA)
n = size(B, 1)
tmp = similar(B, n)
if mA != n
throw(DimensionMismatch("size of adjoint of A is ($mA,$nA), corresponding dimension of B is $n"))
end
for i = 1:size(B,2)
copyto!(tmp, 1, B, (i - 1)*n + 1, n)
ldiv!(adjoint(A), tmp)
ldiv!(adjA, tmp)
copyto!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented.
end
B
end
function ldiv!(transA::Transpose{<:Any,<:Union{Bidiagonal,AbstractTriangular}}, B::AbstractMatrix)
require_one_based_indexing(transA, B)
A = transA.parent
nA,mA = size(A)
tmp = similar(B,size(B,1))
mA, nA = size(transA)
n = size(B, 1)
tmp = similar(B, n)
if mA != n
throw(DimensionMismatch("size of transpose of A is ($mA,$nA), corresponding dimension of B is $n"))
end
for i = 1:size(B,2)
copyto!(tmp, 1, B, (i - 1)*n + 1, n)
ldiv!(transpose(A), tmp)
ldiv!(transA, tmp)
copyto!(B, (i - 1)*n + 1, tmp, 1, n) # Modify this when array view are implemented.
end
B
Expand Down Expand Up @@ -830,14 +828,14 @@ function \(transA::Transpose{<:Number,<:Bidiagonal{<:Number}}, B::AbstractVecOrM
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
ldiv!(transpose(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB))
end
\(transA::Transpose{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(transpose(transA.parent), copy(B))
\(transA::Transpose{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(transA, copy(B))
function \(adjA::Adjoint{<:Number,<:Bidiagonal{<:Number}}, B::AbstractVecOrMat{<:Number})
A = adjA.parent
TA, TB = eltype(A), eltype(B)
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
ldiv!(adjoint(convert(AbstractArray{TAB}, A)), copy_oftype(B, TAB))
end
\(adjA::Adjoint{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(adjoint(adjA.parent), copy(B))
\(adjA::Adjoint{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = ldiv!(adjA, copy(B))

factorize(A::Bidiagonal) = A

Expand Down
3 changes: 2 additions & 1 deletion stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ function *(transA::Transpose{<:Any,<:AbstractMatrix}, D::Diagonal)
rmul!(At, D)
end

*(D::Diagonal, adjQ::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = (Q = adjQ.parent; rmul!(Array(D), adjoint(Q)))
*(D::Diagonal, adjQ::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) =
rmul!(Array{promote_type(eltype(D), eltype(adjQ))}(D), adjQ)
function *(D::Diagonal, adjA::Adjoint{<:Any,<:AbstractMatrix})
A = adjA.parent
Ac = similar(A, promote_op(*, eltype(A), eltype(D.diag)), (size(A, 2), size(A, 1)))
Expand Down
10 changes: 5 additions & 5 deletions stdlib/LinearAlgebra/src/lq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ end

### QcB
lmul!(adjA::Adjoint{<:Any,<:LQPackedQ{T}}, B::StridedVecOrMat{T}) where {T<:BlasReal} =
(A = adjA.parent; LAPACK.ormlq!('L','T',A.factors,A.τ,B))
(A = adjA.parent; LAPACK.ormlq!('L', 'T', A.factors, A.τ, B))
lmul!(adjA::Adjoint{<:Any,<:LQPackedQ{T}}, B::StridedVecOrMat{T}) where {T<:BlasComplex} =
(A = adjA.parent; LAPACK.ormlq!('L','C',A.factors,A.τ,B))
(A = adjA.parent; LAPACK.ormlq!('L', 'C', A.factors, A.τ, B))

function *(adjA::Adjoint{<:Any,<:LQPackedQ}, B::StridedVecOrMat)
A = adjA.parent
Expand All @@ -232,11 +232,11 @@ function *(A::LQPackedQ, adjB::Adjoint{<:Any,<:StridedVecOrMat})
return lmul!(A, BB)
end
function *(adjA::Adjoint{<:Any,<:LQPackedQ}, adjB::Adjoint{<:Any,<:StridedVecOrMat})
A, B = adjA.parent, adjB.parent
TAB = promote_type(eltype(A), eltype(B))
B = adjB.parent
TAB = promote_type(eltype(adjA.parent), eltype(B))
BB = similar(B, TAB, (size(B, 2), size(B, 1)))
adjoint!(BB, B)
return lmul!(adjoint(A), BB)
return lmul!(adjA, BB)
end

# in-place right-application of LQPackedQs
Expand Down
213 changes: 80 additions & 133 deletions stdlib/LinearAlgebra/src/matmul.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,9 @@ function (*)(A::AbstractMatrix{T}, x::AbstractVector{S}) where {T,S}
end

# these will throw a DimensionMismatch unless B has 1 row (or 1 col for transposed case):
function *(a::AbstractVector, transB::Transpose{<:Any,<:AbstractMatrix})
B = transB.parent
reshape(a,length(a),1)*transpose(B)
end
function *(a::AbstractVector, adjB::Adjoint{<:Any,<:AbstractMatrix})
B = adjB.parent
reshape(a,length(a),1)*adjoint(B)
end
(*)(a::AbstractVector, B::AbstractMatrix) = reshape(a,length(a),1)*B
(*)(a::AbstractVector, tB::Transpose{<:Any,<:AbstractMatrix}) = reshape(a, length(a), 1) * tB
(*)(a::AbstractVector, adjB::Adjoint{<:Any,<:AbstractMatrix}) = reshape(a, length(a), 1) * adjB
(*)(a::AbstractVector, B::AbstractMatrix) = reshape(a, length(a), 1) * B

@inline mul!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasFloat} =
Expand All @@ -81,53 +75,39 @@ end
alpha::Number, beta::Number) =
generic_matvecmul!(y, 'N', A, x, MulAddMul(alpha, beta))

function *(transA::Transpose{<:Any,<:StridedMatrix{T}}, x::StridedVector{S}) where {T<:BlasFloat,S}
A = transA.parent
function *(tA::Transpose{<:Any,<:StridedMatrix{T}}, x::StridedVector{S}) where {T<:BlasFloat,S}
TS = promote_op(matprod, T, S)
mul!(similar(x,TS,size(A,2)), transpose(A), convert(AbstractVector{TS}, x))
mul!(similar(x, TS, size(tA, 1)), tA, convert(AbstractVector{TS}, x))
end
function *(transA::Transpose{<:Any,<:AbstractMatrix{T}}, x::AbstractVector{S}) where {T,S}
A = transA.parent
function *(tA::Transpose{<:Any,<:AbstractMatrix{T}}, x::AbstractVector{S}) where {T,S}
TS = promote_op(matprod, T, S)
mul!(similar(x,TS,size(A,2)), transpose(A), x)
end
@inline function mul!(y::StridedVector{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasFloat}
A = transA.parent
return gemv!(y, 'T', A, x, alpha, beta)
end
@inline function mul!(y::AbstractVector, transA::Transpose{<:Any,<:AbstractVecOrMat}, x::AbstractVector,
alpha::Number, beta::Number)
A = transA.parent
return generic_matvecmul!(y, 'T', A, x, MulAddMul(alpha, beta))
mul!(similar(x, TS, size(tA, 1)), tA, x)
end
@inline mul!(y::StridedVector{T}, tA::Transpose{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasFloat} =
gemv!(y, 'T', tA.parent, x, alpha, beta)
@inline mul!(y::AbstractVector, tA::Transpose{<:Any,<:AbstractVecOrMat}, x::AbstractVector,
alpha::Number, beta::Number) =
generic_matvecmul!(y, 'T', tA.parent, x, MulAddMul(alpha, beta))

function *(adjA::Adjoint{<:Any,<:StridedMatrix{T}}, x::StridedVector{S}) where {T<:BlasFloat,S}
A = adjA.parent
TS = promote_op(matprod, T, S)
mul!(similar(x,TS,size(A,2)), adjoint(A) ,convert(AbstractVector{TS},x))
mul!(similar(x, TS, size(adjA, 1)), adjA, convert(AbstractVector{TS}, x))
end
function *(adjA::Adjoint{<:Any,<:AbstractMatrix{T}}, x::AbstractVector{S}) where {T,S}
A = adjA.parent
TS = promote_op(matprod, T, S)
mul!(similar(x,TS,size(A,2)), adjoint(A), x)
mul!(similar(x, TS, size(adjA, 1)), adjA, x)
end

@inline function mul!(y::StridedVector{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasReal}
A = adjA.parent
return mul!(y, transpose(A), x, alpha, beta)
end
@inline function mul!(y::StridedVector{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasComplex}
A = adjA.parent
return gemv!(y, 'C', A, x, alpha, beta)
end
@inline function mul!(y::AbstractVector, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, x::AbstractVector,
alpha::Number, beta::Number)
A = adjA.parent
return generic_matvecmul!(y, 'C', A, x, MulAddMul(alpha, beta))
end
@inline mul!(y::StridedVector{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasReal} =
mul!(y, transpose(adjA.parent), x, alpha, beta)
@inline mul!(y::StridedVector{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, x::StridedVector{T},
alpha::Number, beta::Number) where {T<:BlasComplex} =
gemv!(y, 'C', adjA.parent, x, alpha, beta)
@inline mul!(y::AbstractVector, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, x::AbstractVector,
alpha::Number, beta::Number) =
generic_matvecmul!(y, 'C', adjA.parent, x, MulAddMul(alpha, beta))

# Vector-Matrix multiplication
(*)(x::AdjointAbsVec, A::AbstractMatrix) = (A'*x')'
Expand Down Expand Up @@ -368,25 +348,23 @@ julia> lmul!(F.Q, B)
"""
lmul!(A, B)

@inline function mul!(C::StridedMatrix{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T},
@inline function mul!(C::StridedMatrix{T}, tA::Transpose{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T},
alpha::Number, beta::Number) where {T<:BlasFloat}
A = transA.parent
if A===B
A = tA.parent
if A === B
return syrk_wrapper!(C, 'T', A, MulAddMul(alpha, beta))
else
return gemm_wrapper!(C, 'T', 'N', A, B, MulAddMul(alpha, beta))
end
end
@inline function mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:AbstractVecOrMat}, B::AbstractVecOrMat,
alpha::Number, beta::Number)
A = transA.parent
return generic_matmatmul!(C, 'T', 'N', A, B, MulAddMul(alpha, beta))
end
@inline mul!(C::AbstractMatrix, tA::Transpose{<:Any,<:AbstractVecOrMat}, B::AbstractVecOrMat,
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'T', 'N', tA.parent, B, MulAddMul(alpha, beta))

@inline function mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, transB::Transpose{<:Any,<:StridedVecOrMat{T}},
@inline function mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, tB::Transpose{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat}
B = transB.parent
if A===B
B = tB.parent
if A === B
return syrk_wrapper!(C, 'N', A, MulAddMul(alpha, beta))
else
return gemm_wrapper!(C, 'N', 'T', A, B, MulAddMul(alpha, beta))
Expand All @@ -395,74 +373,56 @@ end
# Complex matrix times transposed real matrix. Reinterpret the first matrix to real for efficiency.
for elty in (Float32,Float64)
@eval begin
@inline function mul!(C::StridedMatrix{Complex{$elty}}, A::StridedVecOrMat{Complex{$elty}}, transB::Transpose{<:Any,<:StridedVecOrMat{$elty}},
@inline function mul!(C::StridedMatrix{Complex{$elty}}, A::StridedVecOrMat{Complex{$elty}}, tB::Transpose{<:Any,<:StridedVecOrMat{$elty}},
alpha::Real, beta::Real)
Afl = reinterpret($elty, A)
Cfl = reinterpret($elty, C)
mul!(Cfl, Afl, transB, alpha, beta)
mul!(Cfl, Afl, tB, alpha, beta)
return C
end
end
end
# collapsing the following two defs with C::AbstractVecOrMat yields ambiguities
@inline mul!(C::AbstractVector, A::AbstractVecOrMat, transB::Transpose{<:Any,<:AbstractVecOrMat},
@inline mul!(C::AbstractVector, A::AbstractVecOrMat, tB::Transpose{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'N', 'T', A, transB.parent, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::AbstractVecOrMat, transB::Transpose{<:Any,<:AbstractVecOrMat},
generic_matmatmul!(C, 'N', 'T', A, tB.parent, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::AbstractVecOrMat, tB::Transpose{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'N', 'T', A, transB.parent, MulAddMul(alpha, beta))

@inline function mul!(C::StridedMatrix{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, transB::Transpose{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat}
A = transA.parent
B = transB.parent
return gemm_wrapper!(C, 'T', 'T', A, B, MulAddMul(alpha, beta))
end
@inline function mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:AbstractVecOrMat}, transB::Transpose{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number)
A = transA.parent
B = transB.parent
return generic_matmatmul!(C, 'T', 'T', A, B, MulAddMul(alpha, beta))
end

@inline function mul!(C::StridedMatrix{T}, transA::Transpose{<:Any,<:StridedVecOrMat{T}}, transB::Adjoint{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat}
A = transA.parent
B = transB.parent
return gemm_wrapper!(C, 'T', 'C', A, B, MulAddMul(alpha, beta))
end
@inline function mul!(C::AbstractMatrix, transA::Transpose{<:Any,<:AbstractVecOrMat}, transB::Adjoint{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number)
A = transA.parent
B = transB.parent
return generic_matmatmul!(C, 'T', 'C', A, B, MulAddMul(alpha, beta))
end

@inline function mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T},
alpha::Real, beta::Real) where {T<:BlasReal}
A = adjA.parent
return mul!(C, transpose(A), B, alpha, beta)
end
generic_matmatmul!(C, 'N', 'T', A, tB.parent, MulAddMul(alpha, beta))

@inline mul!(C::StridedMatrix{T}, tA::Transpose{<:Any,<:StridedVecOrMat{T}}, tB::Transpose{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat} =
gemm_wrapper!(C, 'T', 'T', tA.parent, tB.parent, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, tA::Transpose{<:Any,<:AbstractVecOrMat}, tB::Transpose{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'T', 'T', tA.parent, tB.parent, MulAddMul(alpha, beta))

@inline mul!(C::StridedMatrix{T}, tA::Transpose{<:Any,<:StridedVecOrMat{T}}, adjB::Adjoint{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat} =
gemm_wrapper!(C, 'T', 'C', tA.parent, adjB.parent, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, tA::Transpose{<:Any,<:AbstractVecOrMat}, tB::Adjoint{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'T', 'C', tA.parent, tB.parent, MulAddMul(alpha, beta))

@inline mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T},
alpha::Real, beta::Real) where {T<:BlasReal} =
mul!(C, transpose(adjA.parent), B, alpha, beta)
@inline function mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, B::StridedVecOrMat{T},
alpha::Number, beta::Number) where {T<:BlasComplex}
A = adjA.parent
if A===B
if A === B
return herk_wrapper!(C, 'C', A, MulAddMul(alpha, beta))
else
return gemm_wrapper!(C, 'C', 'N', A, B, MulAddMul(alpha, beta))
end
end
@inline function mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, B::AbstractVecOrMat,
alpha::Number, beta::Number)
A = adjA.parent
return generic_matmatmul!(C, 'C', 'N', A, B, MulAddMul(alpha, beta))
end
@inline mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, B::AbstractVecOrMat,
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'C', 'N', adjA.parent, B, MulAddMul(alpha, beta))

@inline function mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:StridedVecOrMat{<:BlasReal}},
alpha::Number, beta::Number) where {T<:BlasFloat}
B = adjB.parent
return mul!(C, A, transpose(B), alpha, beta)
end
@inline mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:StridedVecOrMat{<:BlasReal}},
alpha::Number, beta::Number) where {T<:BlasFloat} =
mul!(C, A, transpose(adjB.parent), alpha, beta)
@inline function mul!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, adjB::Adjoint{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasComplex}
B = adjB.parent
Expand All @@ -472,37 +432,24 @@ end
return gemm_wrapper!(C, 'N', 'C', A, B, MulAddMul(alpha, beta))
end
end
@inline function mul!(C::AbstractMatrix, A::AbstractVecOrMat, adjB::Adjoint{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number)
B = adjB.parent
return generic_matmatmul!(C, 'N', 'C', A, B, MulAddMul(alpha, beta))
end
@inline mul!(C::AbstractMatrix, A::AbstractVecOrMat, adjB::Adjoint{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'N', 'C', A, adjB.parent, MulAddMul(alpha, beta))

@inline function mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, adjB::Adjoint{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat}
A = adjA.parent
B = adjB.parent
return gemm_wrapper!(C, 'C', 'C', A, B, MulAddMul(alpha, beta))
end
@inline function mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, adjB::Adjoint{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number)
A = adjA.parent
B = adjB.parent
return generic_matmatmul!(C, 'C', 'C', A, B, MulAddMul(alpha, beta))
end
@inline mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, adjB::Adjoint{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat} =
gemm_wrapper!(C, 'C', 'C', adjA.parent, adjB.parent, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, adjB::Adjoint{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'C', 'C', adjA.parent, adjB.parent, MulAddMul(alpha, beta))

@inline mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, tB::Transpose{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat} =
gemm_wrapper!(C, 'C', 'T', adjA.parent, tB.parent, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, tB::Transpose{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number) =
generic_matmatmul!(C, 'C', 'T', adjA.parent, tB.parent, MulAddMul(alpha, beta))

@inline function mul!(C::StridedMatrix{T}, adjA::Adjoint{<:Any,<:StridedVecOrMat{T}}, transB::Transpose{<:Any,<:StridedVecOrMat{T}},
alpha::Number, beta::Number) where {T<:BlasFloat}
A = adjA.parent
B = transB.parent
return gemm_wrapper!(C, 'C', 'T', A, B, MulAddMul(alpha, beta))
end
@inline function mul!(C::AbstractMatrix, adjA::Adjoint{<:Any,<:AbstractVecOrMat}, transB::Transpose{<:Any,<:AbstractVecOrMat},
alpha::Number, beta::Number)
A = adjA.parent
B = transB.parent
return generic_matmatmul!(C, 'C', 'T', A, B, MulAddMul(alpha, beta))
end
# Supporting functions for matrix multiplication

# copy transposed(adjoint) of upper(lower) side-digonals. Optionally include diagonal.
Expand Down
Loading