-
Notifications
You must be signed in to change notification settings - Fork 38
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
add special type for views of Band, macro to implement banded linear algebra #37
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, we need to check if the matrix type if BLAS compatible as well as the existence of the methods leadingdimension(::T)
and pointer(::T)
.
src/generic/linalg.jl
Outdated
BandedMatrices.@banded_banded_linalg($Typ, $Typ) | ||
# default is to use dense axpy! | ||
BandedMatrices.banded_axpy!(a::Number, X::$Typ, Y::AbstractMatrix) = | ||
BandedMatrices.banded_dense_axpy!(a, X, Y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps there is obvious, but why not using banded_generic_axpy
if the interface has been implemented?
src/generic/linalg.jl
Outdated
|
||
macro banded_banded_banded_linalg(Typ1, Typ2, Typ3) | ||
ret = quote | ||
BandedMatrices.positively_banded_matmatmul!(C::$Typ1{T}, tA::Char, tB::Char, A::$Typ2{T}, B::$Typ3{T}) where {T <: BlasFloat} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should only eval this when Type 1, 2, 3 are BLAS compatible. Also, unless bothleadingdimension(::T)
and pointer(::T)
exist, this function will dispatch gbmm
and produce an error.
src/generic/linalg.jl
Outdated
Base.:*(A::$Typ{U}, b::StridedVector{V}) where {U, V} = | ||
Base.LinAlg.A_mul_B!(Vector{promote_type(U, V)}(size(A, 1)), A, b) | ||
|
||
BandedMatrices.positively_banded_matmatmul!(C::StridedMatrix{T}, tA::Char, tB::Char, A::$Typ{T}, B::StridedMatrix{T}) where {T <: BlasFloat} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function should be only defined when the types are BLAS compatible
src/generic/linalg.jl
Outdated
|
||
BandedMatrices.positively_banded_matmatmul!(C::StridedMatrix{T}, tA::Char, tB::Char, A::$Typ{T}, B::StridedMatrix{T}) where {T <: BlasFloat} = | ||
BandedMatrices._positively_banded_matmatmul!(C, tA, tB, A, B) | ||
BandedMatrices.positively_banded_matmatmul!(C::StridedMatrix{T}, tA::Char, tB::Char, A::StridedMatrix{T}, B::$Typ{T}) where {T <: BlasFloat} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, this function should be only defined when the types are BLAS compatible
src/generic/linalg.jl
Outdated
end | ||
|
||
# use BLAS routine for positively banded BLASBandedMatrix | ||
BandedMatrices.positively_banded_matvecmul!(c::StridedVector{T}, tA::Char, A::$Typ{T}, b::StridedVector{T}) where {T <: BandedMatrices.BlasFloat} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function should be only defined when the types are BLAS compatible
I think we should turn BLAS compatible into a trait, a la struct NotBLAS end
struct IsBLASStridedArray{d} end
const IsBLASStridedMatrix = BLASStridedArray{2}
struct IsBLASBandedMatrix end
blasstructure(::Type{<:AbstractArray}) = NotBLAS()
blasstructure(::Type{SM}) where SM <: StridedMatrix{T} where T <: BlasFloat = IsBLASStridedMatrix()
blasstructure(::Type{BandedMatrix{<:BlasFloat}}) = IsBLASBandedMatrix()
blasstructure(::Type{BandedSubBandedMatrix{<:BlasFloat}}) = IsBLASBandedMatrix()
# if blasstructure returns IsBLASBandedMatrix(), then one is required to override `leadingdimension`
leadingdimension(A::BandedMatrix{<:BlasFloat}) = ...
banded_matmatmul!(C::AbstractMatrix{T}, tA::Char, tB::Char, A::AbstractMatrix{U}, B::AbstractMatrix{V}) where {T, U, V} = banded_matmatmul!(C, tA, tB, A, B, isblasbanded(A), isblasbanded(B))
banded_matmatmul!(C::AbstractMatrix{T}, tA::Char, tB::Char, A::AbstractMatrix{U}, B::AbstractMatrix{V}, blasA, blasB) where {T, U, V} = banded_generic_matmatmul!(C, tA, tB, A, B)
banded_matmatmul!(C::AbstractMatrix{T}, tA::Char, tB::Char, A::AbstractMatrix{U}, B::AbstractMatrix{V}, ::IsBLASBandedMatrix, :IsBLASBandedMatrix) where {T, U, V} = generally_banded_matmatmul!(C, tA, tB, A, B)
This does move away from the design of Base, but I would bet that eventually |
I just pushed an update that implements the proposed trait solution. It has simplified the If I find the time, I might make a similar change in Base and open a pull request, to at least start a discussion about it. I think if Base's design used traits instead of inheritance to determine BLAS structure, it would greatly simplify the |
…ces.jl into feat-bandslice
…es that are not <: AbstractBandedMatrix
• SymBandedMatrix{T}(data,...) -> _SymBandedMatrix(data,...) These changes avoid confusion between converting a matrix and specifying the data of a matrix.
… banded matrix interface for Base types
SymBandedMatrix{T}(n,m,a,b) -> SymBandedMatrix{T}(uninitialized,n,m,a,b)
• fix BlasStrided -> BandedLayout
Now
view(A, band(0))
returns a view ofA
, notA.data
.This enables faster implementations of, for example,
Vector{Float64}(view(A, band(0)))
.