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

Implement multiply-add interface in LinearAlgebra #29634

Merged
merged 46 commits into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9cef41a
Multiply-add interface for BLAS.gemm!
tkf Oct 13, 2018
4013d8d
Multiply-add interface for BLAS.syrk!
tkf Oct 13, 2018
93aa9b6
Multiply-add interface for BLAS.herk!
tkf Oct 13, 2018
95deaaf
Multiply-add interface for gemv!
tkf Oct 13, 2018
302396b
Fix UndefRefError from C[i,j]
tkf Oct 13, 2018
3b72e3b
Do not assume *(::Bool, ::eltype(C)) exists
tkf Oct 13, 2018
a27f5f5
Implement mul! in terms of addmul!
tkf Nov 18, 2018
04333aa
Test multiply-add interface
tkf Nov 18, 2018
ae38931
Document addmul!
tkf Nov 19, 2018
87b41b8
Use lmul! for beta * C; eltype may not be commutative
tkf Nov 19, 2018
8f41412
Add _lmul_or_fill!
tkf Nov 19, 2018
b97af31
Add multiply-add interface for symmetric matrices
tkf Nov 19, 2018
cd169b3
Add multiply-add interface for Number and UniformScaling
tkf Nov 19, 2018
a655ff8
Add multiply-add interface for diagonal matrices
tkf Nov 19, 2018
84f009b
Add multiply-add interface for bi- and tri-diagonal matrices
tkf Nov 19, 2018
b0ab7b2
Add multiply-add interface for triangular matrices
tkf Nov 19, 2018
92a7e86
Test multiply-add interface in test/generic.jl
tkf Nov 19, 2018
00cfc91
Fix addmul!(C, s::Number, X, alpha, beta)
tkf Nov 19, 2018
ed6821f
Special-case alpha=1 beta=0 using type parameter
tkf Nov 20, 2018
602fb7b
Test multiply-add interface in test/uniformscaling.jl
tkf Nov 20, 2018
c33767b
Test multiply-add interface in test/diagonal.jl
tkf Nov 20, 2018
1309cc7
Use addmul! in SparseArrays
tkf Nov 20, 2018
4d61edf
Systematically test addmul!
tkf Nov 20, 2018
d88a182
Make MulAddMul benchmark-friendly
tkf Nov 20, 2018
8957d0b
Fix _modify! docstring
tkf Nov 20, 2018
66e04c7
Use MulAddMul in A_mul_B_td!
tkf Nov 20, 2018
d0a7672
Comment out broken test_broken
tkf Nov 20, 2018
96c5550
Relax rtol based on eltype of matrices A, B, C
tkf Nov 20, 2018
57a6077
Pass around MulAddMul instead of alpha and beta for type stability
tkf Nov 21, 2018
46d6614
Inline functions between *(::Matrix, ::Matrix) and gemm_wrapper!
tkf Nov 21, 2018
b0642c5
Annotate argument type MulAddMul
tkf Nov 21, 2018
eb1e87f
Inline all addmul!
tkf Nov 21, 2018
ce7b862
Construct MulAddMul outside A_mul_B_td!
tkf Nov 21, 2018
0a09ec1
Add multiply-add interface in test/tridiag.jl
tkf Nov 21, 2018
474c9f7
Mention combined multiply-add in NEWS.md [ci skip]
tkf Nov 22, 2018
82c5749
Mention that mul!(C, A, B, α, β) is deprecated [ci skip]
tkf Nov 22, 2018
29683db
Change API definition to C = ABα + Cβ
tkf Nov 30, 2018
07058ba
Fix indentation
tkf Dec 1, 2018
fae1a7a
Merge branch 'master' into matmuladd
tkf Dec 1, 2018
84b3be7
Merge branch 'master' into matmuladd
tkf Aug 13, 2019
49fed2a
Fix triangular.jl
tkf Aug 13, 2019
32853b9
Fix UndefRefError in multiplication with Diagonal
tkf Aug 13, 2019
ae925c2
Define Base.convert(::Type{Quaternion{T}}, s::Real)
tkf Aug 13, 2019
7be001f
Rename: addmul! -> mul!
tkf Aug 13, 2019
22121d0
Fix doctest
tkf Aug 13, 2019
c7e3efd
Workaround broadcast error with e.g., triangular matrix of BigFloat
tkf Aug 13, 2019
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
2 changes: 1 addition & 1 deletion stdlib/LinearAlgebra/src/LinearAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import Base: USE_BLAS64, abs, acos, acosh, acot, acoth, acsc, acsch, adjoint, as
strides, stride, tan, tanh, transpose, trunc, typed_hcat, vec
using Base: hvcat_fill, IndexLinear, promote_op, promote_typeof,
@propagate_inbounds, @pure, reduce, typed_vcat, require_one_based_indexing
using Base.Broadcast: Broadcasted
using Base.Broadcast: Broadcasted, broadcasted

export
# Modules
Expand Down
133 changes: 70 additions & 63 deletions stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,23 +338,23 @@ end

const BiTriSym = Union{Bidiagonal,Tridiagonal,SymTridiagonal}
const BiTri = Union{Bidiagonal,Tridiagonal}
mul!(C::AbstractMatrix, A::SymTridiagonal, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::AbstractTriangular, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Diagonal, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractVecOrMat}, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractVecOrMat}, B::BiTriSym) = A_mul_B_td!(C, A, B)
mul!(C::AbstractVector, A::BiTriSym, B::AbstractVector) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::BiTriSym, B::AbstractVecOrMat) = A_mul_B_td!(C, A, B)
mul!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat) = A_mul_B_td!(C, A, B)
mul!(C::AbstractMatrix, A::BiTriSym, B::Transpose{<:Any,<:AbstractVecOrMat}) = A_mul_B_td!(C, A, B) # around bidiag line 330
mul!(C::AbstractMatrix, A::BiTriSym, B::Adjoint{<:Any,<:AbstractVecOrMat}) = A_mul_B_td!(C, A, B)
mul!(C::AbstractVector, A::BiTriSym, B::Transpose{<:Any,<:AbstractVecOrMat}) = throw(MethodError(mul!, (C, A, B)))
@inline mul!(C::AbstractMatrix, A::SymTridiagonal, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::AbstractTriangular, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Diagonal, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractTriangular}, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractTriangular}, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:AbstractVecOrMat}, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::Transpose{<:Any,<:AbstractVecOrMat}, B::BiTriSym, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractVector, A::BiTriSym, B::AbstractVector, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::BiTriSym, B::AbstractVecOrMat, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractMatrix, A::BiTriSym, B::Transpose{<:Any,<:AbstractVecOrMat}, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta)) # around bidiag line 330
@inline mul!(C::AbstractMatrix, A::BiTriSym, B::Adjoint{<:Any,<:AbstractVecOrMat}, alpha::Number, beta::Number) = A_mul_B_td!(C, A, B, MulAddMul(alpha, beta))
@inline mul!(C::AbstractVector, A::BiTriSym, B::Transpose{<:Any,<:AbstractVecOrMat}, alpha::Number, beta::Number) = throw(MethodError(mul!, (C, A, B)), MulAddMul(alpha, beta))

function check_A_mul_B!_sizes(C, A, B)
require_one_based_indexing(C)
Expand Down Expand Up @@ -386,11 +386,15 @@ function _diag(A::Bidiagonal, k)
end
end

function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym)
function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym,
_add::MulAddMul = MulAddMul())
check_A_mul_B!_sizes(C, A, B)
n = size(A,1)
n <= 3 && return mul!(C, Array(A), Array(B))
fill!(C, zero(eltype(C)))
n <= 3 && return mul!(C, Array(A), Array(B), _add.alpha, _add.beta)
# We use `_rmul_or_fill!` instead of `_modify!` here since using
# `_modify!` in the following loop will not update the
# off-diagonal elements for non-zero beta.
_rmul_or_fill!(C, _add.beta)
Al = _diag(A, -1)
Ad = _diag(A, 0)
Au = _diag(A, 1)
Expand All @@ -399,14 +403,14 @@ function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym)
Bu = _diag(B, 1)
@inbounds begin
# first row of C
C[1,1] = A[1,1]*B[1,1] + A[1, 2]*B[2, 1]
C[1,2] = A[1,1]*B[1,2] + A[1,2]*B[2,2]
C[1,3] = A[1,2]*B[2,3]
C[1,1] += _add(A[1,1]*B[1,1] + A[1, 2]*B[2, 1])
C[1,2] += _add(A[1,1]*B[1,2] + A[1,2]*B[2,2])
C[1,3] += _add(A[1,2]*B[2,3])
# second row of C
C[2,1] = A[2,1]*B[1,1] + A[2,2]*B[2,1]
C[2,2] = A[2,1]*B[1,2] + A[2,2]*B[2,2] + A[2,3]*B[3,2]
C[2,3] = A[2,2]*B[2,3] + A[2,3]*B[3,3]
C[2,4] = A[2,3]*B[3,4]
C[2,1] += _add(A[2,1]*B[1,1] + A[2,2]*B[2,1])
C[2,2] += _add(A[2,1]*B[1,2] + A[2,2]*B[2,2] + A[2,3]*B[3,2])
C[2,3] += _add(A[2,2]*B[2,3] + A[2,3]*B[3,3])
C[2,4] += _add(A[2,3]*B[3,4])
for j in 3:n-2
Ajj₋1 = Al[j-1]
Ajj = Ad[j]
Expand All @@ -420,26 +424,27 @@ function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::BiTriSym)
Bj₊1j = Bl[j]
Bj₊1j₊1 = Bd[j+1]
Bj₊1j₊2 = Bu[j+1]
C[j,j-2] = Ajj₋1*Bj₋1j₋2
C[j, j-1] = Ajj₋1*Bj₋1j₋1 + Ajj*Bjj₋1
C[j, j ] = Ajj₋1*Bj₋1j + Ajj*Bjj + Ajj₊1*Bj₊1j
C[j, j+1] = Ajj *Bjj₊1 + Ajj₊1*Bj₊1j₊1
C[j, j+2] = Ajj₊1*Bj₊1j₊2
C[j,j-2] += _add( Ajj₋1*Bj₋1j₋2)
C[j, j-1] += _add(Ajj₋1*Bj₋1j₋1 + Ajj*Bjj₋1)
C[j, j ] += _add(Ajj₋1*Bj₋1j + Ajj*Bjj + Ajj₊1*Bj₊1j)
C[j, j+1] += _add(Ajj *Bjj₊1 + Ajj₊1*Bj₊1j₊1)
C[j, j+2] += _add(Ajj₊1*Bj₊1j₊2)
end
# row before last of C
C[n-1,n-3] = A[n-1,n-2]*B[n-2,n-3]
C[n-1,n-2] = A[n-1,n-1]*B[n-1,n-2] + A[n-1,n-2]*B[n-2,n-2]
C[n-1,n-1] = A[n-1,n-2]*B[n-2,n-1] + A[n-1,n-1]*B[n-1,n-1] + A[n-1,n]*B[n,n-1]
C[n-1,n ] = A[n-1,n-1]*B[n-1,n ] + A[n-1, n]*B[n ,n ]
C[n-1,n-3] += _add(A[n-1,n-2]*B[n-2,n-3])
C[n-1,n-2] += _add(A[n-1,n-1]*B[n-1,n-2] + A[n-1,n-2]*B[n-2,n-2])
C[n-1,n-1] += _add(A[n-1,n-2]*B[n-2,n-1] + A[n-1,n-1]*B[n-1,n-1] + A[n-1,n]*B[n,n-1])
C[n-1,n ] += _add(A[n-1,n-1]*B[n-1,n ] + A[n-1, n]*B[n ,n ])
# last row of C
C[n,n-2] = A[n,n-1]*B[n-1,n-2]
C[n,n-1] = A[n,n-1]*B[n-1,n-1] + A[n,n]*B[n,n-1]
C[n,n ] = A[n,n-1]*B[n-1,n ] + A[n,n]*B[n,n ]
C[n,n-2] += _add(A[n,n-1]*B[n-1,n-2])
C[n,n-1] += _add(A[n,n-1]*B[n-1,n-1] + A[n,n]*B[n,n-1])
C[n,n ] += _add(A[n,n-1]*B[n-1,n ] + A[n,n]*B[n,n ])
end # inbounds
C
end

function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::Diagonal)
function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::Diagonal,
_add::MulAddMul = MulAddMul())
check_A_mul_B!_sizes(C, A, B)
n = size(A,1)
n <= 3 && return mul!(C, Array(A), Array(B))
Expand All @@ -450,29 +455,30 @@ function A_mul_B_td!(C::AbstractMatrix, A::BiTriSym, B::Diagonal)
Bd = B.diag
@inbounds begin
# first row of C
C[1,1] = A[1,1]*B[1,1]
C[1,2] = A[1,2]*B[2,2]
_modify!(_add, A[1,1]*B[1,1], C, (1,1))
_modify!(_add, A[1,2]*B[2,2], C, (1,2))
# second row of C
C[2,1] = A[2,1]*B[1,1]
C[2,2] = A[2,2]*B[2,2]
C[2,3] = A[2,3]*B[3,3]
_modify!(_add, A[2,1]*B[1,1], C, (2,1))
_modify!(_add, A[2,2]*B[2,2], C, (2,2))
_modify!(_add, A[2,3]*B[3,3], C, (2,3))
for j in 3:n-2
C[j, j-1] = Al[j-1]*Bd[j-1]
C[j, j ] = Ad[j ]*Bd[j ]
C[j, j+1] = Au[j ]*Bd[j+1]
_modify!(_add, Al[j-1]*Bd[j-1], C, (j, j-1))
_modify!(_add, Ad[j ]*Bd[j ], C, (j, j ))
_modify!(_add, Au[j ]*Bd[j+1], C, (j, j+1))
end
# row before last of C
C[n-1,n-2] = A[n-1,n-2]*B[n-2,n-2]
C[n-1,n-1] = A[n-1,n-1]*B[n-1,n-1]
C[n-1,n ] = A[n-1, n]*B[n ,n ]
_modify!(_add, A[n-1,n-2]*B[n-2,n-2], C, (n-1,n-2))
_modify!(_add, A[n-1,n-1]*B[n-1,n-1], C, (n-1,n-1))
_modify!(_add, A[n-1, n]*B[n ,n ], C, (n-1,n ))
# last row of C
C[n,n-1] = A[n,n-1]*B[n-1,n-1]
C[n,n ] = A[n,n ]*B[n, n ]
_modify!(_add, A[n,n-1]*B[n-1,n-1], C, (n,n-1))
_modify!(_add, A[n,n ]*B[n, n ], C, (n,n ))
end # inbounds
C
end

function A_mul_B_td!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat)
function A_mul_B_td!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat,
_add::MulAddMul = MulAddMul())
require_one_based_indexing(C)
require_one_based_indexing(B)
nA = size(A,1)
Expand All @@ -483,28 +489,29 @@ function A_mul_B_td!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat)
if size(C,2) != nB
throw(DimensionMismatch("A has second dimension $nA, B has $(size(B,2)), C has $(size(C,2)) but all must match"))
end
nA <= 3 && return mul!(C, Array(A), Array(B))
nA <= 3 && return mul!(C, Array(A), Array(B), _add.alpha, _add.beta)
l = _diag(A, -1)
d = _diag(A, 0)
u = _diag(A, 1)
@inbounds begin
for j = 1:nB
b₀, b₊ = B[1, j], B[2, j]
C[1, j] = d[1]*b₀ + u[1]*b₊
_modify!(_add, d[1]*b₀ + u[1]*b₊, C, (1, j))
for i = 2:nA - 1
b₋, b₀, b₊ = b₀, b₊, B[i + 1, j]
C[i, j] = l[i - 1]*b₋ + d[i]*b₀ + u[i]*b₊
_modify!(_add, l[i - 1]*b₋ + d[i]*b₀ + u[i]*b₊, C, (i, j))
end
C[nA, j] = l[nA - 1]*b₀ + d[nA]*b₊
_modify!(_add, l[nA - 1]*b₀ + d[nA]*b₊, C, (nA, j))
end
end
C
end

function A_mul_B_td!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym)
function A_mul_B_td!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym,
_add::MulAddMul = MulAddMul())
check_A_mul_B!_sizes(C, A, B)
n = size(A,1)
n <= 3 && return mul!(C, Array(A), Array(B))
n <= 3 && return mul!(C, Array(A), Array(B), _add.alpha, _add.beta)
m = size(B,2)
Bl = _diag(B, -1)
Bd = _diag(B, 0)
Expand All @@ -516,16 +523,16 @@ function A_mul_B_td!(C::AbstractMatrix, A::AbstractMatrix, B::BiTriSym)
Bmm = Bd[m]
Bm₋1m = Bu[m-1]
for i in 1:n
C[i, 1] = A[i,1] * B11 + A[i, 2] * B21
C[i, m] = A[i, m-1] * Bm₋1m + A[i, m] * Bmm
_modify!(_add, A[i,1] * B11 + A[i, 2] * B21, C, (i, 1))
_modify!(_add, A[i, m-1] * Bm₋1m + A[i, m] * Bmm, C, (i, m))
end
# middle columns of C
for j = 2:m-1
Bj₋1j = Bu[j-1]
Bjj = Bd[j]
Bj₊1j = Bl[j]
for i = 1:n
C[i, j] = A[i, j-1] * Bj₋1j + A[i, j]*Bjj + A[i, j+1] * Bj₊1j
_modify!(_add, A[i, j-1] * Bj₋1j + A[i, j]*Bjj + A[i, j+1] * Bj₊1j, C, (i, j))
end
end
end # inbounds
Expand Down
38 changes: 27 additions & 11 deletions stdlib/LinearAlgebra/src/blas.jl
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,9 @@ for (fname, elty) in ((:dgemv_,:Float64),
# CHARACTER TRANS
#* .. Array Arguments ..
# DOUBLE PRECISION A(LDA,*),X(*),Y(*)
function gemv!(trans::AbstractChar, alpha::($elty), A::AbstractVecOrMat{$elty}, X::AbstractVector{$elty}, beta::($elty), Y::AbstractVector{$elty})
function gemv!(trans::AbstractChar, alpha::Union{($elty), Bool},
A::AbstractVecOrMat{$elty}, X::AbstractVector{$elty},
beta::Union{($elty), Bool}, Y::AbstractVector{$elty})
require_one_based_indexing(A, X, Y)
m,n = size(A,1),size(A,2)
if trans == 'N' && (length(X) != n || length(Y) != m)
Expand Down Expand Up @@ -656,7 +658,10 @@ for (fname, elty) in ((:dgbmv_,:Float64),
# CHARACTER TRANS
# * .. Array Arguments ..
# DOUBLE PRECISION A(LDA,*),X(*),Y(*)
function gbmv!(trans::AbstractChar, m::Integer, kl::Integer, ku::Integer, alpha::($elty), A::AbstractMatrix{$elty}, x::AbstractVector{$elty}, beta::($elty), y::AbstractVector{$elty})
function gbmv!(trans::AbstractChar, m::Integer, kl::Integer, ku::Integer,
alpha::Union{($elty), Bool}, A::AbstractMatrix{$elty},
x::AbstractVector{$elty}, beta::Union{($elty), Bool},
y::AbstractVector{$elty})
require_one_based_indexing(A, x, y)
chkstride1(A)
ccall((@blasfunc($fname), libblas), Cvoid,
Expand Down Expand Up @@ -704,7 +709,9 @@ for (fname, elty, lib) in ((:dsymv_,:Float64,libblas),
# CHARACTER UPLO
# .. Array Arguments ..
# DOUBLE PRECISION A(LDA,*),X(*),Y(*)
function symv!(uplo::AbstractChar, alpha::($elty), A::AbstractMatrix{$elty}, x::AbstractVector{$elty}, beta::($elty), y::AbstractVector{$elty})
function symv!(uplo::AbstractChar, alpha::Union{($elty), Bool},
A::AbstractMatrix{$elty}, x::AbstractVector{$elty},
beta::Union{($elty), Bool}, y::AbstractVector{$elty})
require_one_based_indexing(A, x, y)
m, n = size(A)
if m != n
Expand Down Expand Up @@ -756,7 +763,7 @@ symv(ul, A, x)
for (fname, elty) in ((:zhemv_,:ComplexF64),
(:chemv_,:ComplexF32))
@eval begin
function hemv!(uplo::AbstractChar, α::$elty, A::AbstractMatrix{$elty}, x::AbstractVector{$elty}, β::$elty, y::AbstractVector{$elty})
function hemv!(uplo::AbstractChar, α::Union{$elty, Bool}, A::AbstractMatrix{$elty}, x::AbstractVector{$elty}, β::Union{$elty, Bool}, y::AbstractVector{$elty})
require_one_based_indexing(A, x, y)
m, n = size(A)
if m != n
Expand Down Expand Up @@ -1112,7 +1119,11 @@ for (gemm, elty) in
# CHARACTER TRANSA,TRANSB
# * .. Array Arguments ..
# DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
function gemm!(transA::AbstractChar, transB::AbstractChar, alpha::($elty), A::AbstractVecOrMat{$elty}, B::AbstractVecOrMat{$elty}, beta::($elty), C::AbstractVecOrMat{$elty})
function gemm!(transA::AbstractChar, transB::AbstractChar,
alpha::Union{($elty), Bool},
A::AbstractVecOrMat{$elty}, B::AbstractVecOrMat{$elty},
beta::Union{($elty), Bool},
C::AbstractVecOrMat{$elty})
# if any([stride(A,1), stride(B,1), stride(C,1)] .!= 1)
# error("gemm!: BLAS module requires contiguous matrix columns")
# end # should this be checked on every call?
Expand Down Expand Up @@ -1175,7 +1186,9 @@ for (mfname, elty) in ((:dsymm_,:Float64),
# CHARACTER SIDE,UPLO
# .. Array Arguments ..
# DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
function symm!(side::AbstractChar, uplo::AbstractChar, alpha::($elty), A::AbstractMatrix{$elty}, B::AbstractMatrix{$elty}, beta::($elty), C::AbstractMatrix{$elty})
function symm!(side::AbstractChar, uplo::AbstractChar, alpha::Union{($elty), Bool},
A::AbstractMatrix{$elty}, B::AbstractMatrix{$elty},
beta::Union{($elty), Bool}, C::AbstractMatrix{$elty})
require_one_based_indexing(A, B, C)
m, n = size(C)
j = checksquare(A)
Expand Down Expand Up @@ -1244,7 +1257,9 @@ for (mfname, elty) in ((:zhemm_,:ComplexF64),
# CHARACTER SIDE,UPLO
# .. Array Arguments ..
# DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
function hemm!(side::AbstractChar, uplo::AbstractChar, alpha::($elty), A::AbstractMatrix{$elty}, B::AbstractMatrix{$elty}, beta::($elty), C::AbstractMatrix{$elty})
function hemm!(side::AbstractChar, uplo::AbstractChar, alpha::Union{($elty), Bool},
A::AbstractMatrix{$elty}, B::AbstractMatrix{$elty},
beta::Union{($elty), Bool}, C::AbstractMatrix{$elty})
require_one_based_indexing(A, B, C)
m, n = size(C)
j = checksquare(A)
Expand Down Expand Up @@ -1309,8 +1324,8 @@ for (fname, elty) in ((:dsyrk_,:Float64),
# * .. Array Arguments ..
# REAL A(LDA,*),C(LDC,*)
function syrk!(uplo::AbstractChar, trans::AbstractChar,
alpha::($elty), A::AbstractVecOrMat{$elty},
beta::($elty), C::AbstractMatrix{$elty})
alpha::Union{($elty), Bool}, A::AbstractVecOrMat{$elty},
beta::Union{($elty), Bool}, C::AbstractMatrix{$elty})
require_one_based_indexing(A, C)
n = checksquare(C)
nn = size(A, trans == 'N' ? 1 : 2)
Expand Down Expand Up @@ -1366,8 +1381,9 @@ for (fname, elty, relty) in ((:zherk_, :ComplexF64, :Float64),
# * ..
# * .. Array Arguments ..
# COMPLEX A(LDA,*),C(LDC,*)
function herk!(uplo::AbstractChar, trans::AbstractChar, α::$relty, A::AbstractVecOrMat{$elty},
β::$relty, C::AbstractMatrix{$elty})
function herk!(uplo::AbstractChar, trans::AbstractChar,
α::Union{$relty, Bool}, A::AbstractVecOrMat{$elty},
β::Union{$relty, Bool}, C::AbstractMatrix{$elty})
require_one_based_indexing(A, C)
n = checksquare(C)
nn = size(A, trans == 'N' ? 1 : 2)
Expand Down
Loading