ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
particle_reduction.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2025-2026 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <config/config.hpp>
23
24#include "Particle.hpp"
26
27#include <Kokkos_Core.hpp>
28
29#include <concepts>
30#include <utility>
31
32namespace Reduction {
33
34/** @brief Custom reduction in the form required by Kokkos */
35template <typename ResultType, class Kernel, class Reduction>
37public:
38 // Kokkos reduction functors need the value_type typedef.
39 // This is the type of the result of the reduction.
41
42 // Just like with parallel_for functors, you may specify
43 // an execution_space typedef. If not provided, Kokkos
44 // will use the default execution space by default.
45
46 // kernels to wrap
51
52 inline void operator()(std::integral auto const i, value_type &update) const {
53 kernel(i, update);
54 }
55
56 // "Join" intermediate results from different threads.
57 // This should normally implement the same reduction
58 // operation as operator() above.
59 inline void join(value_type &dst, value_type const &src) const {
61 }
62};
63
64template <typename ResultType, class Kernel, class Reduction>
69
70} // namespace Reduction
71
72/** @brief Run a reduction over all particles.
73 *
74 * @param cs cell structure to iterate over
75 * @param add_partial function that accumulates a result from a single particle
76 * @param reduce_op function that joins two reduction results
77 *
78 * both functions have to implement the same reduction.
79 */
80template <typename ResultType>
82 CellStructure const &cs,
83 std::invocable<ResultType &, Particle const &> auto add_partial,
84 [[maybe_unused]] std::invocable<ResultType &, ResultType const &> auto
85 reduce_op) {
86
87 static_assert(std::is_invocable_r_v<void, decltype(add_partial), ResultType &,
88 Particle const &>);
89 static_assert(std::is_invocable_r_v<void, decltype(reduce_op), ResultType &,
90 ResultType const &>);
91 ResultType result{};
92
93 auto const &cells = cs.decomposition().local_cells();
94 if (cells.size() > 1) { // parallel loop over cells
95 auto reducer = Reduction::make_kokkos_reducer<ResultType>(
96 [&cells, add_partial](std::size_t const c_index, ResultType &res) {
97 for (auto const &p : cells[c_index]->particles()) {
98 add_partial(res, p);
99 }
100 },
101 reduce_op);
102 Kokkos::parallel_reduce( // loop over cells
103 "reduce_on_local_particle",
104 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(std::size_t{0},
105 cells.size()),
106 reducer, result);
107 return result;
108 }
109 // single cell case
110 auto const &particles = cells.front()->particles();
111 auto reducer = Reduction::make_kokkos_reducer<ResultType>(
112 [&particles, add_partial](std::size_t const p_index, ResultType &res) {
113 add_partial(res, std::as_const(*(particles.begin() + p_index)));
114 },
115 reduce_op);
116 Kokkos::parallel_reduce( // loop over particles
117 "reduce_on_local_particle",
118 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(std::size_t{0},
119 particles.size()),
120 reducer, result);
121 return result;
122}
Describes a cell structure / cell system.
ParticleDecomposition const & decomposition() const
Get the underlying particle decomposition.
virtual std::span< Cell *const > local_cells() const =0
Get pointer to local cells.
base_type::size_type size() const
Custom reduction in the form required by Kokkos.
void join(value_type &dst, value_type const &src) const
KokkosReducer(Kernel kernel, Reduction reduction_op)
void operator()(std::integral auto const i, value_type &update) const
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
KokkosReducer< ResultType, Kernel, Reduction > make_kokkos_reducer(Kernel k, Reduction reduce_op)
STL namespace.
ResultType reduce_over_local_particles(CellStructure const &cs, std::invocable< ResultType &, Particle const & > auto add_partial, std::invocable< ResultType &, ResultType const & > auto reduce_op)
Run a reduction over all particles.
Struct holding all information for one particle.
Definition Particle.hpp:436