Skip to content

Commit e7b2a8a

Browse files
jishnubdkarrasch
andcommitted
Specialize Diagonal * Adjoint (#1207)
This reinstates slightly altered versions of the methods that were removed in JuliaLang/julia#52389. Sort of fixes #1205, although this doesn't recover the full performance. However, this version is more general, and works with the example presented in JuliaLang/julia#52389. There's still a performance regression, but the full performance may only be obtained for mutable matrices, and we may not assume mutability in general. Performance: v1.10: ```julia julia> n = 100 100 julia> A = adjoint(sparse(Float64, I, n, n)); julia> B = Diagonal(ones(n)); julia> @Btime $A * $B; 837.119 ns (5 allocations: 2.59 KiB) ``` This PR ```julia julia> @Btime $A * $B; 1.106 μs (15 allocations: 5.56 KiB) ``` We need double the allocations here compared to earlier, as we firstly materialize `D' * A'`, and then we again copy the adjoint of this result. I wonder if this may be reduced. --------- Co-authored-by: Daniel Karrasch <daniel.karrasch@posteo.de>
1 parent e7da19f commit e7b2a8a

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/adjtrans.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ const AdjointAbsVec{T} = Adjoint{T,<:AbstractVector}
319319
const AdjointAbsMat{T} = Adjoint{T,<:AbstractMatrix}
320320
const TransposeAbsVec{T} = Transpose{T,<:AbstractVector}
321321
const TransposeAbsMat{T} = Transpose{T,<:AbstractMatrix}
322-
const AdjOrTransAbsVec{T} = AdjOrTrans{T,<:AbstractVector}
323-
const AdjOrTransAbsMat{T} = AdjOrTrans{T,<:AbstractMatrix}
322+
const AdjOrTransAbsVec{T,V<:AbstractVector} = AdjOrTrans{T,V}
323+
const AdjOrTransAbsMat{T,M<:AbstractMatrix} = AdjOrTrans{T,M}
324324

325325
# for internal use below
326326
wrapperop(_) = identity

src/diagonal.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,28 @@ function (*)(D::Diagonal, V::AbstractVector)
332332
return D.diag .* V
333333
end
334334

335+
function _diag_adj_mul(A::AdjOrTransAbsMat, D::Diagonal)
336+
adj = wrapperop(A)
337+
copy(adj(adj(D) * adj(A)))
338+
end
339+
function _diag_adj_mul(A::AdjOrTransAbsMat{<:Number, <:StridedMatrix}, D::Diagonal{<:Number})
340+
@invoke *(A::AbstractMatrix, D::AbstractMatrix)
341+
end
342+
function _diag_adj_mul(D::Diagonal, A::AdjOrTransAbsMat)
343+
adj = wrapperop(A)
344+
copy(adj(adj(A) * adj(D)))
345+
end
346+
function _diag_adj_mul(D::Diagonal{<:Number}, A::AdjOrTransAbsMat{<:Number, <:StridedMatrix})
347+
@invoke *(D::AbstractMatrix, A::AbstractMatrix)
348+
end
349+
350+
function (*)(A::AdjOrTransAbsMat, D::Diagonal)
351+
_diag_adj_mul(A, D)
352+
end
353+
function (*)(D::Diagonal, A::AdjOrTransAbsMat)
354+
_diag_adj_mul(D, A)
355+
end
356+
335357
function rmul!(A::AbstractMatrix, D::Diagonal)
336358
matmul_size_check(size(A), size(D))
337359
for I in CartesianIndices(A)

0 commit comments

Comments
 (0)