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

Cleanup Wrappers and Tests #37

Merged
merged 20 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
31 changes: 17 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
name: ci
on:
- push
- pull_request
pull_request:
branches:
- master
push:
branches:
- master
- release-*
- runci/*
tags: ['*']
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.version == 'nightly' }}
strategy:
fail-fast: false
matrix:
Expand All @@ -24,16 +32,11 @@ jobs:
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- name: Cache artifacts
uses: actions/cache@v4
env:
cache-name: cache-artifacts
show-versioninfo: true
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v4
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@latest
- uses: julia-actions/julia-runtest@latest
file: lcov.info
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ julia = "1.6"
MKL_jll = "2024.2.0"

[extras]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["Test", "Random"]
10 changes: 8 additions & 2 deletions src/MKLSparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ using LinearAlgebra, SparseArrays
using LinearAlgebra: BlasInt, BlasFloat, checksquare
using MKL_jll: libmkl_rt

# For testing purposes:
global const __counter = Ref(0)
# counts total MKL Sparse API calls (for testing purposes)
global const __mklsparse_calls_count = Ref(0)

# increments to the `__mklsparse_calls_count` variable
function _log_mklsparse_call(fname)
#@debug "$fname called"
__mklsparse_calls_count[] += 1
end

@enum Threading begin
THREADING_INTEL
Expand Down
91 changes: 29 additions & 62 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,93 +5,60 @@ matdescra(A::UnitLowerTriangular) = "TLUF"
matdescra(A::UnitUpperTriangular) = "TUUF"
matdescra(A::Symmetric) = string('S', A.uplo, 'N', 'F')
matdescra(A::Hermitian) = string('H', A.uplo, 'N', 'F')
matdescra(A::SparseMatrixCSC) = "GUUF"
matdescra(A::SparseMatrixCSC) = "GFNF"
matdescra(A::Transpose) = matdescra(A.parent)
matdescra(A::Adjoint) = matdescra(A.parent)

# The increments to the `__counter` variable is for testing purposes

function _check_transa(t::Char)
if !(t in ('C', 'N', 'T'))
error("transa: is '$t', must be 'N', 'T', or 'C'")
end
end

mkl_size(t::Char, M::AbstractVecOrMat) = t == 'N' ? size(M) : reverse(size(M))


# Checks sizes for the multiplication C <- A * B
function _check_mat_mult_matvec(C, A, B, tA)
_size(v::AbstractMatrix) = size(v)
_size(v::AbstractVector) = (size(v,1), 1)
_str(v::AbstractMatrix) = string("[", size(v,1), ", ", size(v,2), "]")
_str(v::AbstractVector) = string("[", size(v,1), "]")
mA, nA = mkl_size(tA, A)
mB, nB = _size(B)
mC, nC = _size(C)
if nA != mB || mC != mA || nC != nB
t = ""
if tA == 'T'; t = ".\'"; end
if tA == 'C'; t = "\'"; end
str = string("arrays had inconsistent dimensions for C <- A", t, " * B: ", _str(C), " <- ", _str(A), t, " * ", _str(B))
throw(DimensionMismatch(str))
end
end

function cscmv!(transa::Char, α::T, matdescra::String,
A::SparseMatrixCSC{T, Int32}, x::StridedVector{T},
A::AbstractSparseMatrix{T}, x::StridedVector{T},
β::T, y::StridedVector{T}) where {T <: BlasFloat}
_check_transa(transa)
_check_mat_mult_matvec(y, A, x, transa)
__counter[] += 1
T == Float32 && (mkl_scscmv(transa, A.m, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, β, y))
T == Float64 && (mkl_dcscmv(transa, A.m, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, β, y))
T == ComplexF32 && (mkl_ccscmv(transa, A.m, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, β, y))
T == ComplexF64 && (mkl_zcscmv(transa, A.m, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, β, y))
check_transa(transa)
check_mat_op_sizes(y, A, transa, x, 'N')

mkl_call(Val{:mkl_TSmvI}(), typeof(A),
transa, A.m, A.n, α, matdescra,
A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, β, y)
return y
end

function cscmm!(transa::Char, α::T, matdescra::String,
A::SparseMatrixCSC{T, Int32}, B::StridedMatrix{T},
A::SparseMatrixCSC{T}, B::StridedMatrix{T},
β::T, C::StridedMatrix{T}) where {T <: BlasFloat}
_check_transa(transa)
_check_mat_mult_matvec(C, A, B, transa)
check_transa(transa)
check_mat_op_sizes(C, A, transa, B, 'N')
mB, nB = size(B)
mC, nC = size(C)
__counter[] += 1
T == Float32 && (mkl_scscmm(transa, A.m, nC, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, β, C, mC))
T == Float64 && (mkl_dcscmm(transa, A.m, nC, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, β, C, mC))
T == ComplexF32 && (mkl_ccscmm(transa, A.m, nC, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, β, C, mC))
T == ComplexF64 && (mkl_zcscmm(transa, A.m, nC, A.n, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, β, C, mC))

mkl_call(Val{:mkl_TSmmI}(), typeof(A),
transa, A.m, nC, A.n, α, matdescra,
A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, β, C, mC)
return C
end

function cscsv!(transa::Char, α::T, matdescra::String,
A::SparseMatrixCSC{T, Int32}, x::StridedVector{T},
A::SparseMatrixCSC{T}, x::StridedVector{T},
y::StridedVector{T}) where {T <: BlasFloat}
n = checksquare(A)
_check_transa(transa)
_check_mat_mult_matvec(y, A, x, transa)
__counter[] += 1
T == Float32 && (mkl_scscsv(transa, A.m, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, y))
T == Float64 && (mkl_dcscsv(transa, A.m, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, y))
T == ComplexF32 && (mkl_ccscsv(transa, A.m, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, y))
T == ComplexF64 && (mkl_zcscsv(transa, A.m, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, y))
check_transa(transa)
check_mat_op_sizes(y, A, transa, x, 'N')

mkl_call(Val{:mkl_TSsvI}(), typeof(A),
transa, A.m, α, matdescra,
A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), x, y)
return y
end

function cscsm!(transa::Char, α::T, matdescra::String,
A::SparseMatrixCSC{T, Int32}, B::StridedMatrix{T},
A::SparseMatrixCSC{T}, B::StridedMatrix{T},
C::StridedMatrix{T}) where {T <: BlasFloat}
mB, nB = size(B)
mC, nC = size(C)
n = checksquare(A)
_check_transa(transa)
_check_mat_mult_matvec(C, A, B, transa)
__counter[] += 1
T == Float32 && (mkl_scscsm(transa, A.n, nC, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, C, mC))
T == Float64 && (mkl_dcscsm(transa, A.n, nC, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, C, mC))
T == ComplexF32 && (mkl_ccscsm(transa, A.n, nC, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, C, mC))
T == ComplexF64 && (mkl_zcscsm(transa, A.n, nC, α, matdescra, A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, C, mC))
check_transa(transa)
check_mat_op_sizes(C, A, transa, B, 'N')

mkl_call(Val{:mkl_TSsmI}(), typeof(A),
transa, A.n, nC, α, matdescra,
A.nzval, A.rowval, A.colptr, pointer(A.colptr, 2), B, mB, C, mC)
return C
end
101 changes: 53 additions & 48 deletions src/generic.jl
Original file line number Diff line number Diff line change
@@ -1,54 +1,59 @@
for T in (:Float32, :Float64, :ComplexF32, :ComplexF64)
INT_TYPES = Base.USE_BLAS64 ? (:Int32, :Int64) : (:Int32,)
for INT in INT_TYPES
for SparseMatrix in (:(SparseMatrixCSC{$T,$INT}), :(MKLSparse.SparseMatrixCSR{$T,$INT}), :(MKLSparse.SparseMatrixCOO{$T,$INT}))
# generates the reference to the MKL function from the template
@inline @generated function mkl_function(
::Val{F}, ::Type{S}
) where S <: AbstractSparseMatrix{Tv, Ti} where {F, Tv, Ti}
mkl_function_name(F, S, Tv, Ti)
end

fname_mv = Symbol("mkl_sparse_", mkl_type_specifier(T), "_mv" , mkl_integer_specifier(INT))
fname_mm = Symbol("mkl_sparse_", mkl_type_specifier(T), "_mm" , mkl_integer_specifier(INT))
fname_trsv = Symbol("mkl_sparse_", mkl_type_specifier(T), "_trsv", mkl_integer_specifier(INT))
fname_trsm = Symbol("mkl_sparse_", mkl_type_specifier(T), "_trsm", mkl_integer_specifier(INT))
# calls MKL function with the name constructed from the template F (e.g. :mkl_Tcscmm)
# using the sparse matrix type S (e.g. SparseMatrixCSC{Float64, Int32}),
# see mkl_function_name()
@inline @generated function mkl_call(
::Val{F}, ::Type{S}, args...;
log::Val{L} = Val{true}()
) where {L, S <: AbstractSparseMatrix{Tv, Ti}} where {F, Tv, Ti}
fname = mkl_function_name(F, S, Tv, Ti)
body = Expr(:call, fname, (:(args[$i]) for i in eachindex(args))...)
L && (body = Expr(:block, :(_log_mklsparse_call($(QuoteNode(fname)))), body))
return body
end

@eval begin
function mv!(operation::Char, alpha::$T, A::$SparseMatrix, descr::matrix_descr, x::StridedVector{$T}, beta::$T, y::StridedVector{$T})
_check_transa(operation)
_check_mat_mult_matvec(y, A, x, operation)
__counter[] += 1
$fname_mv(operation, alpha, MKLSparseMatrix(A), descr, x, beta, y)
return y
end
function mv!(transa::Char, alpha::T, A::AbstractSparseMatrix{T}, descr::matrix_descr, x::StridedVector{T}, beta::T, y::StridedVector{T}) where T
check_transa(transa)
check_mat_op_sizes(y, A, transa, x, 'N')
mkl_call(Val{:mkl_sparse_T_mvI}(), typeof(A),
transa, alpha, MKLSparseMatrix(A), descr, x, beta, y)
return y
end

function mm!(operation::Char, alpha::$T, A::$SparseMatrix, descr::matrix_descr, x::StridedMatrix{$T}, beta::$T, y::StridedMatrix{$T})
_check_transa(operation)
_check_mat_mult_matvec(y, A, x, operation)
__counter[] += 1
columns = size(y, 2)
ldx = stride(x, 2)
ldy = stride(y, 2)
$fname_mm(operation, alpha, MKLSparseMatrix(A), descr, 'C', x, columns, ldx, beta, y, ldy)
return y
end
function mm!(transa::Char, alpha::T, A::AbstractSparseMatrix{T}, descr::matrix_descr, x::StridedMatrix{T}, beta::T, y::StridedMatrix{T}) where T
check_transa(transa)
check_mat_op_sizes(y, A, transa, x, 'N')
columns = size(y, 2)
ldx = stride(x, 2)
ldy = stride(y, 2)
mkl_call(Val{:mkl_sparse_T_mmI}(), typeof(A),
transa, alpha, MKLSparseMatrix(A), descr, 'C', x, columns, ldx, beta, y, ldy)
return y
end

function trsv!(operation::Char, alpha::$T, A::$SparseMatrix, descr::matrix_descr, x::StridedVector{$T}, y::StridedVector{$T})
checksquare(A)
_check_transa(operation)
_check_mat_mult_matvec(y, A, x, operation)
__counter[] += 1
$fname_trsv(operation, alpha, MKLSparseMatrix(A), descr, x, y)
return y
end
function trsv!(transa::Char, alpha::T, A::AbstractSparseMatrix{T}, descr::matrix_descr, x::StridedVector{T}, y::StridedVector{T}) where T
checksquare(A)
check_transa(transa)
check_mat_op_sizes(y, A, transa, x, 'N')
mkl_call(Val{:mkl_sparse_T_trsvI}(), typeof(A),
transa, alpha, MKLSparseMatrix(A), descr, x, y)
return y
end

function trsm!(operation::Char, alpha::$T, A::$SparseMatrix, descr::matrix_descr, x::StridedMatrix{$T}, y::StridedMatrix{$T})
checksquare(A)
_check_transa(operation)
_check_mat_mult_matvec(y, A, x, operation)
__counter[] += 1
columns = size(y, 2)
ldx = stride(x, 2)
ldy = stride(y, 2)
$fname_trsm(operation, alpha, MKLSparseMatrix(A), descr, 'C', x, columns, ldx, y, ldy)
return y
end
end
end
end
function trsm!(transa::Char, alpha::T, A::AbstractSparseMatrix{T}, descr::matrix_descr, x::StridedMatrix{T}, y::StridedMatrix{T}) where T
checksquare(A)
check_transa(transa)
check_mat_op_sizes(y, A, transa, x, 'N')
columns = size(y, 2)
ldx = stride(x, 2)
ldy = stride(y, 2)
mkl_call(Val{:mkl_sparse_T_trsmI}(), typeof(A),
transa, alpha, MKLSparseMatrix(A), descr, 'C', x, columns, ldx, y, ldy)
return y
end
Loading
Loading