Skip to content

Commit 7ed4c68

Browse files
committed
block smoothing, remove branches, and parallel Jacobi
1 parent e15ef16 commit 7ed4c68

File tree

1 file changed

+81
-28
lines changed

1 file changed

+81
-28
lines changed

src/smoother.jl

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,17 @@ end
2929
function gs!(A, b, x, start, step, stop)
3030
n = size(A, 1)
3131
z = zero(eltype(A))
32-
for i = start:step:stop
33-
rsum = z
34-
d = z
35-
for j in nzrange(A, i)
36-
row = A.rowval[j]
37-
val = A.nzval[j]
38-
if i == row
39-
d = val
40-
else
41-
rsum += val * x[row]
32+
@inbounds for col = 1:size(x, 2)
33+
for i = start:step:stop
34+
rsum = z
35+
d = z
36+
for j in nzrange(A, i)
37+
row = A.rowval[j]
38+
val = A.nzval[j]
39+
d = ifelse(i == row, val, d)
40+
rsum += ifelse(i == row, 0, val * x[row, col])
4241
end
43-
end
44-
45-
if d != 0
46-
x[i] = (b[i] - rsum) / d
42+
x[i, col] = ifelse(d == 0, x[i, col], (b[i, col] - rsum) / d)
4743
end
4844
end
4945
end
@@ -52,40 +48,97 @@ struct Jacobi{T,TX} <: Smoother
5248
ω::T
5349
temp::TX
5450
end
55-
Jacobi=0.5, x) = Jacobi{T,TX}(ω, similar(x))
51+
Jacobi(ω, x::TX) where {T, TX<:AbstractVector{T}} = Jacobi{T,TX}(ω, similar(x))
52+
Jacobi(x::TX, ω = 0.5) where {T, TX<:AbstractVector{T}} = Jacobi{T,TX}(ω, similar(x))
5653

57-
function (jacobi::Jacobi)(A, x, b, ω, start, step, stop)
54+
function (jacobi::Jacobi)(A, x, b)
5855

59-
one = one(eltype(A))
56+
ω = jacobi.ω
57+
one = Base.one(eltype(A))
6058
temp = jacobi.temp
6159

62-
@inbounds for col in 1:size(x, 2)
63-
for i = start:step:stop
60+
@inbounds for col = 1:size(x, 2)
61+
for i = 1:size(A, 1)
6462
temp[i, col] = x[i, col]
6563
end
6664

67-
for i = start:step:stop
65+
for i = 1:size(A, 1)
6866
rsum = zero(eltype(A))
6967
diag = zero(eltype(A))
7068

7169
for j in nzrange(A, i)
7270
row = A.rowval[j]
7371
val = A.nzval[j]
7472

75-
if row == i
76-
diag = val
77-
else
78-
rsum += val * temp[row, col]
79-
end
73+
diag = ifelse(row == i, val, diag)
74+
rsum += ifelse(row == i, 0, val * temp[row, col])
8075
end
8176

82-
if diag != 0
83-
x[i, col] = (one - ω) * temp[i, col] + ω * ((b[i, col] - rsum) / diag)
84-
end
77+
xcand = (one - ω) * temp[i, col] + ω * ((b[i, col] - rsum) / diag)
78+
x[i, col] = ifelse(diag == 0, x[i, col], xcand)
8579
end
8680
end
8781
end
8882

83+
#=
84+
using KissThreading: tmap!
85+
86+
struct ParallelJacobi{T,TX} <: Smoother
87+
ω::T
88+
temp::TX
89+
end
90+
ParallelJacobi(ω, x::TX) where {T, TX<:AbstractVector{T}} = ParallelJacobi{T,TX}(ω, similar(x))
91+
ParallelJacobi(x::TX, ω = 0.5) where {T, TX<:AbstractVector{T}} = ParallelJacobi{T,TX}(ω, similar(x))
92+
93+
struct ParallelTemp{TX, TI}
94+
temp::TX
95+
col::TI
96+
end
97+
(ptemp::ParallelTemp)(i) = ptemp.temp[i, ptemp.col]
98+
99+
struct ParallelJacobiMapper{TA, TX, TB, TTemp, TF, TI}
100+
A::TA
101+
x::TX
102+
b::TB
103+
temp::TTemp
104+
ω::TF
105+
col::TI
106+
end
107+
function (pjacobmapper::ParallelJacobiMapper)(i)
108+
A = pjacobmapper.A
109+
x = pjacobmapper.x
110+
b = pjacobmapper.b
111+
temp = pjacobmapper.temp
112+
ω = pjacobmapper.ω
113+
col = pjacobmapper.col
114+
115+
one = Base.one(eltype(A))
116+
rsum = zero(eltype(A))
117+
diag = zero(eltype(A))
118+
119+
for j in nzrange(A, i)
120+
row = A.rowval[j]
121+
val = A.nzval[j]
122+
123+
diag = ifelse(row == i, val, diag)
124+
rsum += ifelse(row == i, 0, val * temp[row, col])
125+
end
126+
xcand = (one - ω) * temp[i, col] + ω * ((b[i, col] - rsum) / diag)
127+
128+
return ifelse(diag == 0, x[i, col], xcand)
129+
end
130+
131+
function (jacobi::ParallelJacobi)(A, x, b)
132+
ω = jacobi.ω
133+
temp = jacobi.temp
134+
for col = 1:size(x, 2)
135+
@views tmap!(ParallelTemp(temp, col), x[1:size(A, 1), col], 1:size(A, 1))
136+
@views tmap!(ParallelJacobiMapper(A, x, b, temp, ω, col),
137+
x[1:size(A, 1), col], 1:size(A, 1))
138+
end
139+
end
140+
=#
141+
89142
struct JacobiProlongation{T}
90143
ω::T
91144
end

0 commit comments

Comments
 (0)