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
endScattering (@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
endSame 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)
endReordering 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]
endTesserae.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