Skip to content

Commit c3cee00

Browse files
vchuravyafilogoranocha
authored
Support serial execution and introduce backend preference (#2476)
* Support serial backend Co-authored-by: Valentin Churavy <[email protected]> * Rebase post 2212 and KernelAbstraction support * Update src/auxiliary/containers.jl * Apply suggestions from code review Co-authored-by: Hendrik Ranocha <[email protected]> * add news and bump version * Update NEWS.md * Improve summary for threading backend --------- Co-authored-by: afilogo <[email protected]> Co-authored-by: Hendrik Ranocha <[email protected]>
1 parent dbf254b commit c3cee00

File tree

8 files changed

+48
-24
lines changed

8 files changed

+48
-24
lines changed

NEWS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ Trixi.jl follows the interpretation of
55
used in the Julia ecosystem. Notable changes will be documented in this file
66
for human readability.
77

8+
9+
## Changes when updating to v0.13 from v0.12.x
10+
11+
#### Changed
12+
13+
- The `polyester` preference got merged with the `native_threading` preference and the `Trixi.set_polyester!` function got renamed to `Trixi.set_threading_backend!` ([#2476]).
14+
15+
#### Deprecated
16+
17+
#### Removed
18+
819
## Changes in the v0.12 lifecycle
920

1021
#### Added

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Trixi"
22
uuid = "a7f1ee26-1774-49b1-8366-f1abc58fbfcb"
33
authors = ["Michael Schlottke-Lakemper <[email protected]>", "Gregor Gassner <[email protected]>", "Hendrik Ranocha <[email protected]>", "Andrew R. Winters <[email protected]>", "Jesse Chan <[email protected]>", "Andrés Rueda-Ramírez <[email protected]>"]
4-
version = "0.12.8-DEV"
4+
version = "0.13.0-DEV"
55

66
[deps]
77
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"

src/Trixi.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ module Trixi
1818
using Preferences: @load_preference, set_preferences!
1919
const _PREFERENCE_SQRT = @load_preference("sqrt", "sqrt_Trixi_NaN")
2020
const _PREFERENCE_LOG = @load_preference("log", "log_Trixi_NaN")
21-
const _PREFERENCE_POLYESTER = @load_preference("polyester", true)
21+
const _PREFERENCE_THREADING = @load_preference("backend", :polyester)
2222
const _PREFERENCE_LOOPVECTORIZATION = @load_preference("loop_vectorization", true)
23-
const _PREFERENCE_USE_NATIVE_THREADING = @load_preference("native_threading", true)
2423

2524
# Include other packages that are used in Trixi.jl
2625
# (standard library packages first, other packages next, all of them sorted alphabetically)

src/auxiliary/auxiliary.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,16 +206,19 @@ and [https://discourse.julialang.org/t/threads-threads-with-one-thread-how-to-re
206206
macro threaded(expr)
207207
# !!! danger "Heisenbug"
208208
# Look at the comments for `wrap_array` when considering to change this macro.
209-
expr = if _PREFERENCE_POLYESTER
209+
expr = @static if _PREFERENCE_THREADING === :polyester
210210
# Currently using `@batch` from Polyester.jl is more efficient,
211211
# bypasses the Julia task scheduler and provides parallelization with less overhead.
212212
quote
213213
$Trixi.@batch $(expr)
214214
end
215-
else
215+
elseif _PREFERENCE_THREADING === :static ||
216+
_PREFERENCE_THREADING === :kernelabstractions
216217
# The following code is a simple version using only `Threads.@threads` from the
217218
# standard library with an additional check whether only a single thread is used
218219
# to reduce some overhead (and allocations) for serial execution.
220+
# If we want to execute on KernelAbstractions, we use the static backend here to fallback on,
221+
# for loops that do not yet support GPU execution.
219222
quote
220223
let
221224
if $Threads.nthreads() == 1
@@ -225,6 +228,10 @@ macro threaded(expr)
225228
end
226229
end
227230
end
231+
elseif _PREFERENCE_THREADING === :serial
232+
quote
233+
$(expr)
234+
end
228235
end
229236
# Use `esc(quote ... end)` for nested macro calls as suggested in
230237
# https://github.com/JuliaLang/julia/issues/23221

src/auxiliary/containers.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,9 @@ Return the computational backend for `x`, which is either a KernelAbstractions b
358358
If the backend is `nothing`, the default multi-threaded CPU backend is used.
359359
"""
360360
function trixi_backend(x)
361-
# TODO: https://github.com/trixi-framework/Trixi.jl/pull/2417
362-
if (_PREFERENCE_POLYESTER && LoopVectorization.check_args(x)) ||
363-
(_PREFERENCE_USE_NATIVE_THREADING && get_backend(x) isa KernelAbstractions.CPU)
361+
if (_PREFERENCE_THREADING === :polyester && LoopVectorization.check_args(x)) ||
362+
(_PREFERENCE_THREADING !== :kernelabstractions &&
363+
get_backend(x) isa KernelAbstractions.CPU)
364364
return nothing
365365
end
366366
return get_backend(x)

src/auxiliary/math.jl

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,27 @@
88
const TRIXI_UUID = UUID("a7f1ee26-1774-49b1-8366-f1abc58fbfcb")
99

1010
"""
11-
Trixi.set_polyester!(toggle::Bool; force = true)
12-
13-
Toggle the usage of [Polyester.jl](https://github.com/JuliaSIMD/Polyester.jl) for multithreading.
14-
By default, Polyester.jl is enabled, but it can
15-
be useful for performance comparisons to switch to the Julia core backend.
16-
17-
This does not fully disable Polyester.jl,
18-
but only its use as part of Trixi.jl's [`@threaded`](@ref) macro.
11+
Trixi.set_threading_backend!(backend::Symbol; force = true)
12+
13+
Toggle and/or switch backend behavior used in multithreaded loops inside Trixi.jl.
14+
The selected backend affects the behavior of Trixi.jl's [`@threaded`](@ref) macro, which is used
15+
throughout the codebase for parallel loops. By default, Polyester.jl is enabled for
16+
optimal performance, but switching backends can be useful for comparisons or debugging.
17+
18+
# Available backends
19+
- `:polyester`: Uses the default [Polyester.jl](https://github.com/JuliaSIMD/Polyester.jl)
20+
- `:static`: Uses Julia's built-in static thread scheduling via `Threads.@threads :static`
21+
- `:serial`: Disables threading, executing loops serially
22+
- `:kernelabstractions`: Preferentially use the [KernelAbstractions.jl](https://github.com/JuliaGPU/KernelAbstractions.jl)
23+
kernels written in Trixi.jl, falling back to `:static` execution.
1924
"""
20-
function set_polyester!(toggle::Bool; force = true)
21-
set_preferences!(TRIXI_UUID, "polyester" => toggle, force = force)
22-
@info "Please restart Julia and reload Trixi.jl for the `polyester` change to take effect"
25+
function set_threading_backend!(backend::Symbol = :polyester; force = true)
26+
valid_backends = (:polyester, :static, :serial, :kernelabstractions)
27+
if !(backend in valid_backends)
28+
throw(ArgumentError("Invalid threading backend: $(backend). Current options are: $(join(valid_backends, ", "))"))
29+
end
30+
set_preferences!(TRIXI_UUID, "backend" => backend, force = force)
31+
@info "Please restart Julia and reload Trixi.jl for the `backend` change to take effect"
2332
end
2433

2534
"""

src/callbacks_step/summary.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,7 @@ function initialize_summary_callback(cb::DiscreteCallback, u, t, integrator;
209209

210210
# technical details
211211
setup = Pair{String, Any}["#threads" => Threads.nthreads()]
212-
if !_PREFERENCE_POLYESTER
213-
push!(setup, "Polyester" => "disabled")
214-
end
212+
push!(setup, "threading backend" => string(_PREFERENCE_THREADING))
215213
if !_PREFERENCE_LOOPVECTORIZATION
216214
push!(setup, "LoopVectorization" => "disabled")
217215
end

src/solvers/dg.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ end
669669
# since LoopVectorization does not support `ForwardDiff.Dual`s. Hence, we use
670670
# optimized `PtrArray`s whenever possible and fall back to plain `Array`s
671671
# otherwise.
672-
if _PREFERENCE_POLYESTER && LoopVectorization.check_args(u_ode)
672+
if _PREFERENCE_THREADING === :polyester && LoopVectorization.check_args(u_ode)
673673
# This version using `PtrArray`s from StrideArrays.jl is very fast and
674674
# does not result in allocations.
675675
#
@@ -704,7 +704,7 @@ end
704704
nvariables(equations) * nnodes(dg)^ndims(mesh) * nelements(dg, cache)
705705
end
706706
# See comments on the DGSEM version above
707-
if _PREFERENCE_POLYESTER && LoopVectorization.check_args(u_ode)
707+
if _PREFERENCE_THREADING === :polyester && LoopVectorization.check_args(u_ode)
708708
# Here, we do not specialize on the number of nodes using `StaticInt` since
709709
# - it will not be type stable (SBP operators just store it as a runtime value)
710710
# - FD methods tend to use high node counts

0 commit comments

Comments
 (0)