Multi-threading
Tesserae.jl provides a @threaded
macro to enable multi-threading. It behaves similarly to Julia’s built-in Threads.@threads, but is specifically designed to work with particle-grid transfer macros such as @G2P
, @P2G
, @G2P2G
, and @P2G_Matrix
.
Usage guidelines
Gathering (@G2P
)
To parallelize @G2P
, simply prefix it with @threaded
.
@threaded @G2P grid=>i particles=>p weights=>ip begin
# your code here
end
Scattering (@P2G
, @G2P2G
and @P2G_Matrix
)
For scattering operations, prefix @P2G
with @threaded
and use ColorPartition
to avoid data races on the grid.
partition = ColorPartition(mesh)
update!(partition, particles.x)
@threaded @P2G grid=>i particles=>p weights=>ip partition begin
# your code here
end
Same applies to @G2P2G
and @P2G_Matrix
.
Updating interpolation values
To update interpolation values, either use the update!
function, or simply:
@threaded for p in eachindex(particles)
update!(weights[p], particles.x[p], mesh)
end
Reordering particles
For @P2G
and related scattering operations, using reorder_particles!
together with ColorPartition
can significantly improve cache efficiency and thread scaling:
partition = ColorPartition(mesh)
update!(partition, particles.x)
reorder_particles!(particles, partition)
Reordering ensures that particles within the same grid block are stored contiguously in memory, reducing random memory access during parallel execution.
reorder_particles!
can be expensive for large systems. It is usually sufficient to reorder particles only when their spatial distribution has changed significantly. Avoid calling it on every step.
Multi-threading API
Tesserae.@threaded
— Macro@threaded [scheduler] for ...
@threaded [scheduler] @P2G ...
@threaded @P2G ...
A macro similar to Threads.@threads
, but also works with @P2G
, @G2P
, @G2P2G
, and @P2G_Matrix
macros for particle-grid transfers.
The optional scheduler
can be :static
, :dynamic
, :greedy
, or :nothing
(sequential execution). The default is :dynamic
.
See also ColorPartition
.
If multi-threading is disabled or only one thread is available, this macro falls back to sequential execution.
Examples
# Parallel loop
@threaded for i in 1:100
println(i)
end
# Grid-to-particle transfer
@threaded @G2P grid=>i particles=>p weights=>ip begin
v[p] = @∑ w[ip] * v[i]
end
Tesserae.ColorPartition
— TypeColorPartition(::CartesianMesh)
ColorPartition
stores partitioning information used by the @P2G
, @G2P2G
and @P2G_Matrix
macros to avoid write conflicts during parallel particle-to-grid transfers.
The @threaded
macro must be placed before @P2G
, @G2P2G
and @P2G_Matrix
to enable parallel transfer.
Examples
# Construct ColorPartition
partition = ColorPartition(mesh)
# Update coloring using current particle positions
update!(partition, particles.x)
# P2G transfer
@threaded @P2G grid=>i particles=>p weights=>ip partition begin
m[i] = @∑ w[ip] * m[p]
mv[i] = @∑ w[ip] * m[p] * v[p]
end