Skip to content

Commit 7a37706

Browse files
authored
Merge pull request #37 from termi-official/do/polyester-mul
Add polyester for SpMV kernels
2 parents 7aab96d + b8d34e9 commit 7a37706

File tree

4 files changed

+112
-5
lines changed

4 files changed

+112
-5
lines changed

.github/workflows/ci.yml

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ jobs:
88
fail-fast: false
99
matrix:
1010
version:
11-
- '1.8'
12-
- '1.9'
13-
- '1.10'
11+
- 'lts'
12+
- '1.11'
13+
- '1'
1414
os:
1515
- ubuntu-latest
1616
- windows-latest
@@ -31,6 +31,37 @@ jobs:
3131
file: lcov.info
3232
verbose: true
3333

34+
threaded-test:
35+
name: Test Threaded ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
36+
runs-on: ${{ matrix.os }}
37+
env:
38+
JULIA_NUM_THREADS: 2
39+
strategy:
40+
fail-fast: false
41+
matrix:
42+
version:
43+
- 'lts'
44+
- '1.11'
45+
- '1'
46+
os:
47+
- ubuntu-latest
48+
arch:
49+
- x64
50+
steps:
51+
- uses: actions/checkout@v4
52+
- uses: julia-actions/setup-julia@v2
53+
with:
54+
version: ${{ matrix.version }}
55+
arch: ${{ matrix.arch }}
56+
- uses: julia-actions/cache@v2
57+
- uses: julia-actions/julia-buildpkg@v1
58+
- uses: julia-actions/julia-runtest@v1
59+
- uses: julia-actions/julia-processcoverage@v1
60+
- uses: codecov/codecov-action@v5
61+
with:
62+
file: lcov.info
63+
verbose: true
64+
3465
docs:
3566
name: Documentation
3667
permissions:

Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ authors = ["Víctor Sande <vsande@cimne.upc.edu>", "Francesc Verdugo <fverdugo@c
44
version = "0.6.10"
55

66
[deps]
7+
Atomix = "a9b6321e-bd34-4604-b9c9-b65b8de01458"
78
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
9+
Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588"
810
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
911
SuiteSparse = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
1012

1113
[compat]
14+
Atomix = "1.1.2"
15+
Polyester = "0.7.19"
1216
julia = "1"
1317

1418
[extras]

src/SparseMatricesCSR.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export SymSparseMatrixCSR
1414
export sparsecsr, symsparsecsr
1515
export colvals, getBi, getoffset
1616

17+
import Polyester: @batch
18+
import Atomix: @atomic
19+
1720
include("SparseMatrixCSR.jl")
1821

1922
include("SymSparseMatrixCSR.jl")

src/SparseMatrixCSR.jl

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,37 @@ count(pred, S::SparseMatrixCSR) = count(pred, nzvalview(S))
320320
count(S::SparseMatrixCSR) = count(i->true, nzvalview(S))
321321

322322
function mul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector, α::Number, β::Number)
323+
if Threads.nthreads() > 1
324+
tmul!(y, A, v, α, β)
325+
else
326+
smul!(y, A, v, α, β)
327+
end
328+
end
329+
330+
function smul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector, α::Number, β::Number)
323331
A.n == size(v, 1) || throw(DimensionMismatch())
324332
A.m == size(y, 1) || throw(DimensionMismatch())
325333
if β != 1
326334
β != 0 ? rmul!(y, β) : fill!(y, zero(eltype(y)))
327335
end
328336
o = getoffset(A)
329-
for row = 1:size(y, 1)
337+
@batch for row = 1:size(y, 1)
338+
@inbounds for nz in nzrange(A,row)
339+
col = A.colval[nz]+o
340+
y[row] += A.nzval[nz]*v[col]*α
341+
end
342+
end
343+
return y
344+
end
345+
346+
function tmul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector, α::Number, β::Number)
347+
A.n == size(v, 1) || throw(DimensionMismatch())
348+
A.m == size(y, 1) || throw(DimensionMismatch())
349+
if β != 1
350+
β != 0 ? rmul!(y, β) : fill!(y, zero(eltype(y)))
351+
end
352+
o = getoffset(A)
353+
@batch for row = 1:size(y, 1)
330354
@inbounds for nz in nzrange(A,row)
331355
col = A.colval[nz]+o
332356
y[row] += A.nzval[nz]*v[col]*α
@@ -336,6 +360,14 @@ function mul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector, α::Number
336360
end
337361

338362
function mul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector)
363+
if Threads.nthreads() > 1
364+
tmul!(y, A, v)
365+
else
366+
smul!(y, A, v)
367+
end
368+
end
369+
370+
function smul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector)
339371
A.n == size(v, 1) || throw(DimensionMismatch())
340372
A.m == size(y, 1) || throw(DimensionMismatch())
341373
fill!(y, zero(eltype(y)))
@@ -349,9 +381,31 @@ function mul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector)
349381
return y
350382
end
351383

384+
function tmul!(y::AbstractVector,A::SparseMatrixCSR,v::AbstractVector)
385+
A.n == size(v, 1) || throw(DimensionMismatch())
386+
A.m == size(y, 1) || throw(DimensionMismatch())
387+
fill!(y, zero(eltype(y)))
388+
o = getoffset(A)
389+
@batch for row = 1:size(y, 1)
390+
@inbounds for nz in nzrange(A,row)
391+
col = A.colval[nz]+o
392+
y[row] += A.nzval[nz]*v[col]
393+
end
394+
end
395+
return y
396+
end
397+
352398
*(A::SparseMatrixCSR, v::Vector) = (y = similar(v,size(A,1));mul!(y,A,v))
353399

354-
function mul!(y::AbstractVector,A::Adjoint{T, <:SparseMatrixCSR},v::AbstractVector) where T
400+
function mul!(y::AbstractVector,A::Adjoint{<:Any, <:SparseMatrixCSR},v::AbstractVector)
401+
if Threads.nthreads() > 1
402+
tmul!(y, A, v)
403+
else
404+
smul!(y, A, v)
405+
end
406+
end
407+
408+
function smul!(y::AbstractVector,A::Adjoint{<:Any, <:SparseMatrixCSR},v::AbstractVector)
355409
P = A.parent
356410
P.n == size(y, 1) || throw(DimensionMismatch())
357411
P.m == size(v, 1) || throw(DimensionMismatch())
@@ -366,6 +420,21 @@ function mul!(y::AbstractVector,A::Adjoint{T, <:SparseMatrixCSR},v::AbstractVect
366420
return y
367421
end
368422

423+
function tmul!(y::AbstractVector,A::Adjoint{<:Any, <:SparseMatrixCSR},v::AbstractVector)
424+
P = A.parent
425+
P.n == size(y, 1) || throw(DimensionMismatch())
426+
P.m == size(v, 1) || throw(DimensionMismatch())
427+
fill!(y,zero(eltype(y)))
428+
o = getoffset(P)
429+
@batch for row = 1:size(P, 1)
430+
for nz in nzrange(P,row)
431+
col = P.colval[nz]+o
432+
@atomic y[col] += P.nzval[nz]*v[row]
433+
end
434+
end
435+
return y
436+
end
437+
369438
*(A::Adjoint{T, <:SparseMatrixCSR}, v::AbstractVector) where T = (y = similar(v, promote_type(eltype(v),T), size(A,1)); mul!(y, A, v))
370439

371440
function show(io::IO, ::MIME"text/plain", S::SparseMatrixCSR)

0 commit comments

Comments
 (0)