Skip to content

Commit 7791faa

Browse files
authored
Some multi-threading improvements (#1630)
* fix multi-threaded parabolic terms on ARM On ARM, the previous versions resulted in cfunction: closures are not supported on this platform With this change, everything seems to work fine locally. At least test/test_threaded.jl runs fine with two threads. * reduce alloactions of multi-threaded parabolic terms a bit Polyester.jl passes arrays as pointer arrays to the closures without requiring allocations. More complicated structs may still require allocations, so unpacking some arrays before entering a threaded loop can reduce allocations. * format
1 parent 953f88a commit 7791faa

File tree

4 files changed

+86
-69
lines changed

4 files changed

+86
-69
lines changed

src/solvers/dgmulti/dg_parabolic.jl

+3-2
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ end
6262
function transform_variables!(u_transformed, u, mesh,
6363
equations_parabolic::AbstractEquationsParabolic,
6464
dg::DGMulti, parabolic_scheme, cache, cache_parabolic)
65+
transformation = gradient_variable_transformation(equations_parabolic)
66+
6567
@threaded for i in eachindex(u)
66-
u_transformed[i] = gradient_variable_transformation(equations_parabolic)(u[i],
67-
equations_parabolic)
68+
u_transformed[i] = transformation(u[i], equations_parabolic)
6869
end
6970
end
7071

src/solvers/dgsem_tree/dg_1d_parabolic.jl

+20-14
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,13 @@ end
105105
function transform_variables!(u_transformed, u, mesh::TreeMesh{1},
106106
equations_parabolic::AbstractEquationsParabolic,
107107
dg::DG, parabolic_scheme, cache, cache_parabolic)
108+
transformation = gradient_variable_transformation(equations_parabolic)
109+
108110
@threaded for element in eachelement(dg, cache)
109111
# Calculate volume terms in one element
110112
for i in eachnode(dg)
111113
u_node = get_node_vars(u, equations_parabolic, dg, i, element)
112-
u_transformed_node = gradient_variable_transformation(equations_parabolic)(u_node,
113-
equations_parabolic)
114+
u_transformed_node = transformation(u_node, equations_parabolic)
114115
set_node_vars!(u_transformed, u_transformed_node, equations_parabolic, dg,
115116
i, element)
116117
end
@@ -147,16 +148,18 @@ function prolong2interfaces!(cache_parabolic, flux_viscous,
147148
equations_parabolic::AbstractEquationsParabolic,
148149
surface_integral, dg::DG, cache)
149150
@unpack interfaces = cache_parabolic
151+
@unpack neighbor_ids = interfaces
152+
interfaces_u = interfaces.u
150153

151154
@threaded for interface in eachinterface(dg, cache)
152-
left_element = interfaces.neighbor_ids[1, interface]
153-
right_element = interfaces.neighbor_ids[2, interface]
155+
left_element = neighbor_ids[1, interface]
156+
right_element = neighbor_ids[2, interface]
154157

155158
# interface in x-direction
156159
for v in eachvariable(equations_parabolic)
157-
# OBS! `interfaces.u` stores the interpolated *fluxes* and *not the solution*!
158-
interfaces.u[1, v, interface] = flux_viscous[v, nnodes(dg), left_element]
159-
interfaces.u[2, v, interface] = flux_viscous[v, 1, right_element]
160+
# OBS! `interfaces_u` stores the interpolated *fluxes* and *not the solution*!
161+
interfaces_u[1, v, interface] = flux_viscous[v, nnodes(dg), left_element]
162+
interfaces_u[2, v, interface] = flux_viscous[v, 1, right_element]
160163
end
161164
end
162165

@@ -204,21 +207,22 @@ function prolong2boundaries!(cache_parabolic, flux_viscous,
204207
equations_parabolic::AbstractEquationsParabolic,
205208
surface_integral, dg::DG, cache)
206209
@unpack boundaries = cache_parabolic
207-
@unpack neighbor_sides = boundaries
210+
@unpack neighbor_sides, neighbor_ids = boundaries
211+
boundaries_u = boundaries.u
208212

209213
@threaded for boundary in eachboundary(dg, cache_parabolic)
210-
element = boundaries.neighbor_ids[boundary]
214+
element = neighbor_ids[boundary]
211215

212216
if neighbor_sides[boundary] == 1
213217
# element in -x direction of boundary
214218
for v in eachvariable(equations_parabolic)
215-
# OBS! `boundaries.u` stores the interpolated *fluxes* and *not the solution*!
216-
boundaries.u[1, v, boundary] = flux_viscous[v, nnodes(dg), element]
219+
# OBS! `boundaries_u` stores the interpolated *fluxes* and *not the solution*!
220+
boundaries_u[1, v, boundary] = flux_viscous[v, nnodes(dg), element]
217221
end
218222
else # Element in +x direction of boundary
219223
for v in eachvariable(equations_parabolic)
220-
# OBS! `boundaries.u` stores the interpolated *fluxes* and *not the solution*!
221-
boundaries.u[2, v, boundary] = flux_viscous[v, 1, element]
224+
# OBS! `boundaries_u` stores the interpolated *fluxes* and *not the solution*!
225+
boundaries_u[2, v, boundary] = flux_viscous[v, 1, element]
222226
end
223227
end
224228
end
@@ -552,8 +556,10 @@ end
552556
# where f(u) is the inviscid flux and g(u) is the viscous flux.
553557
function apply_jacobian_parabolic!(du, mesh::TreeMesh{1},
554558
equations::AbstractEquationsParabolic, dg::DG, cache)
559+
@unpack inverse_jacobian = cache.elements
560+
555561
@threaded for element in eachelement(dg, cache)
556-
factor = cache.elements.inverse_jacobian[element]
562+
factor = inverse_jacobian[element]
557563

558564
for i in eachnode(dg)
559565
for v in eachvariable(equations)

src/solvers/dgsem_tree/dg_2d_parabolic.jl

+28-23
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,13 @@ end
118118
function transform_variables!(u_transformed, u, mesh::Union{TreeMesh{2}, P4estMesh{2}},
119119
equations_parabolic::AbstractEquationsParabolic,
120120
dg::DG, parabolic_scheme, cache, cache_parabolic)
121+
transformation = gradient_variable_transformation(equations_parabolic)
122+
121123
@threaded for element in eachelement(dg, cache)
122124
# Calculate volume terms in one element
123125
for j in eachnode(dg), i in eachnode(dg)
124126
u_node = get_node_vars(u, equations_parabolic, dg, i, j, element)
125-
u_transformed_node = gradient_variable_transformation(equations_parabolic)(u_node,
126-
equations_parabolic)
127+
u_transformed_node = transformation(u_node, equations_parabolic)
127128
set_node_vars!(u_transformed, u_transformed_node, equations_parabolic, dg,
128129
i, j, element)
129130
end
@@ -168,30 +169,31 @@ function prolong2interfaces!(cache_parabolic, flux_viscous,
168169
equations_parabolic::AbstractEquationsParabolic,
169170
surface_integral, dg::DG, cache)
170171
@unpack interfaces = cache_parabolic
171-
@unpack orientations = interfaces
172+
@unpack orientations, neighbor_ids = interfaces
173+
interfaces_u = interfaces.u
172174

173175
flux_viscous_x, flux_viscous_y = flux_viscous
174176

175177
@threaded for interface in eachinterface(dg, cache)
176-
left_element = interfaces.neighbor_ids[1, interface]
177-
right_element = interfaces.neighbor_ids[2, interface]
178+
left_element = neighbor_ids[1, interface]
179+
right_element = neighbor_ids[2, interface]
178180

179181
if orientations[interface] == 1
180182
# interface in x-direction
181183
for j in eachnode(dg), v in eachvariable(equations_parabolic)
182-
# OBS! `interfaces.u` stores the interpolated *fluxes* and *not the solution*!
183-
interfaces.u[1, v, j, interface] = flux_viscous_x[v, nnodes(dg), j,
184+
# OBS! `interfaces_u` stores the interpolated *fluxes* and *not the solution*!
185+
interfaces_u[1, v, j, interface] = flux_viscous_x[v, nnodes(dg), j,
184186
left_element]
185-
interfaces.u[2, v, j, interface] = flux_viscous_x[v, 1, j,
187+
interfaces_u[2, v, j, interface] = flux_viscous_x[v, 1, j,
186188
right_element]
187189
end
188190
else # if orientations[interface] == 2
189191
# interface in y-direction
190192
for i in eachnode(dg), v in eachvariable(equations_parabolic)
191-
# OBS! `interfaces.u` stores the interpolated *fluxes* and *not the solution*!
192-
interfaces.u[1, v, i, interface] = flux_viscous_y[v, i, nnodes(dg),
193+
# OBS! `interfaces_u` stores the interpolated *fluxes* and *not the solution*!
194+
interfaces_u[1, v, i, interface] = flux_viscous_y[v, i, nnodes(dg),
193195
left_element]
194-
interfaces.u[2, v, i, interface] = flux_viscous_y[v, i, 1,
196+
interfaces_u[2, v, i, interface] = flux_viscous_y[v, i, 1,
195197
right_element]
196198
end
197199
end
@@ -244,41 +246,42 @@ function prolong2boundaries!(cache_parabolic, flux_viscous,
244246
equations_parabolic::AbstractEquationsParabolic,
245247
surface_integral, dg::DG, cache)
246248
@unpack boundaries = cache_parabolic
247-
@unpack orientations, neighbor_sides = boundaries
249+
@unpack orientations, neighbor_sides, neighbor_ids = boundaries
250+
boundaries_u = boundaries.u
248251
flux_viscous_x, flux_viscous_y = flux_viscous
249252

250253
@threaded for boundary in eachboundary(dg, cache_parabolic)
251-
element = boundaries.neighbor_ids[boundary]
254+
element = neighbor_ids[boundary]
252255

253256
if orientations[boundary] == 1
254257
# boundary in x-direction
255258
if neighbor_sides[boundary] == 1
256259
# element in -x direction of boundary
257260
for l in eachnode(dg), v in eachvariable(equations_parabolic)
258-
# OBS! `boundaries.u` stores the interpolated *fluxes* and *not the solution*!
259-
boundaries.u[1, v, l, boundary] = flux_viscous_x[v, nnodes(dg), l,
261+
# OBS! `boundaries_u` stores the interpolated *fluxes* and *not the solution*!
262+
boundaries_u[1, v, l, boundary] = flux_viscous_x[v, nnodes(dg), l,
260263
element]
261264
end
262265
else # Element in +x direction of boundary
263266
for l in eachnode(dg), v in eachvariable(equations_parabolic)
264-
# OBS! `boundaries.u` stores the interpolated *fluxes* and *not the solution*!
265-
boundaries.u[2, v, l, boundary] = flux_viscous_x[v, 1, l, element]
267+
# OBS! `boundaries_u` stores the interpolated *fluxes* and *not the solution*!
268+
boundaries_u[2, v, l, boundary] = flux_viscous_x[v, 1, l, element]
266269
end
267270
end
268271
else # if orientations[boundary] == 2
269272
# boundary in y-direction
270273
if neighbor_sides[boundary] == 1
271274
# element in -y direction of boundary
272275
for l in eachnode(dg), v in eachvariable(equations_parabolic)
273-
# OBS! `boundaries.u` stores the interpolated *fluxes* and *not the solution*!
274-
boundaries.u[1, v, l, boundary] = flux_viscous_y[v, l, nnodes(dg),
276+
# OBS! `boundaries_u` stores the interpolated *fluxes* and *not the solution*!
277+
boundaries_u[1, v, l, boundary] = flux_viscous_y[v, l, nnodes(dg),
275278
element]
276279
end
277280
else
278281
# element in +y direction of boundary
279282
for l in eachnode(dg), v in eachvariable(equations_parabolic)
280-
# OBS! `boundaries.u` stores the interpolated *fluxes* and *not the solution*!
281-
boundaries.u[2, v, l, boundary] = flux_viscous_y[v, l, 1, element]
283+
# OBS! `boundaries_u` stores the interpolated *fluxes* and *not the solution*!
284+
boundaries_u[2, v, l, boundary] = flux_viscous_y[v, l, 1, element]
282285
end
283286
end
284287
end
@@ -608,7 +611,7 @@ function prolong2mortars!(cache, flux_viscous::Tuple{AbstractArray, AbstractArra
608611
end
609612

610613
# NOTE: Use analogy to "calc_mortar_flux!" for hyperbolic eqs with no nonconservative terms.
611-
# Reasoning: "calc_interface_flux!" for parabolic part is implemented as the version for
614+
# Reasoning: "calc_interface_flux!" for parabolic part is implemented as the version for
612615
# hyperbolic terms with conserved terms only, i.e., no nonconservative terms.
613616
function calc_mortar_flux!(surface_flux_values,
614617
mesh::TreeMesh{2},
@@ -934,8 +937,10 @@ end
934937
# where f(u) is the inviscid flux and g(u) is the viscous flux.
935938
function apply_jacobian_parabolic!(du, mesh::Union{TreeMesh{2}, P4estMesh{2}},
936939
equations::AbstractEquationsParabolic, dg::DG, cache)
940+
@unpack inverse_jacobian = cache.elements
941+
937942
@threaded for element in eachelement(dg, cache)
938-
factor = cache.elements.inverse_jacobian[element]
943+
factor = inverse_jacobian[element]
939944

940945
for j in eachnode(dg), i in eachnode(dg)
941946
for v in eachvariable(equations)

0 commit comments

Comments
 (0)