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

add special type for views of Band, macro to implement banded linear algebra #37

Merged
merged 29 commits into from
Feb 23, 2018

Conversation

dlfivefifty
Copy link
Member

Now view(A, band(0)) returns a view of A, not A.data.

This enables faster implementations of, for example, Vector{Float64}(view(A, band(0))).

Copy link
Contributor

@randy3k randy3k left a 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).

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)
Copy link
Contributor

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?


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} =
Copy link
Contributor

@randy3k randy3k Oct 31, 2017

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.

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} =
Copy link
Contributor

@randy3k randy3k Oct 31, 2017

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


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} =
Copy link
Contributor

@randy3k randy3k Oct 31, 2017

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

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} =
Copy link
Contributor

@randy3k randy3k Oct 31, 2017

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

@dlfivefifty
Copy link
Member Author

I think we should turn BLAS compatible into a trait, a la Base.HasLength, and get rid of BLASBandedMatrix (see JuliaLang/julia#24383 (comment) for one reason to get rid of Union types). For example:

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 StridedMatrix in Base becomes a trait.

@randy3k
Copy link
Contributor

randy3k commented Nov 3, 2017

Cf: JuliaLang/julia#2345 (comment)

@dlfivefifty dlfivefifty changed the title add special type for views of Band add special type for views of Band, macro to implement banded linear algebra Nov 4, 2017
@dlfivefifty
Copy link
Member Author

I just pushed an update that implements the proposed trait solution. It has simplified the @banded_linalg macros.

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 A_*_B! overloads (and remove the need for the @banded_linalg macros completely.

@dlfivefifty dlfivefifty merged commit cc4e07c into master Feb 23, 2018
@dlfivefifty dlfivefifty deleted the feat-bandslice branch February 23, 2018 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants