7#include <Kokkos_Core.hpp>
16#define NEON_LAMBDA KOKKOS_LAMBDA
17#define NEON_INLINE_FUNCTION KOKKOS_INLINE_FUNCTION
21using Kokkos::atomic_add;
22using Kokkos::atomic_sub;
25#define NEON_LAMBDA [&]
37template<
typename ValueType>
42template<
typename Kernel>
46 } -> std::same_as<void>;
63 if (
const auto* serial = std::get_if<SerialExecutor>(&exec))
67 else if (
const auto* cpu = std::get_if<CPUExecutor>(&exec))
73 f(std::get<GPUExecutor>(exec));
79template<
typename ExecutorType>
83 if (logger !=
nullptr)
90template<
typename ExecutorType, parallelForKernel Kernel>
92 const ExecutorType&, std::pair<localIdx, localIdx> range,
const Kernel& kernel, std::string
name
95 auto [start, end] = range;
97 if constexpr (std::is_same<std::remove_reference_t<ExecutorType>,
SerialExecutor>::value)
99 for (
localIdx i = start; i < end; i++)
106 using runOn =
typename ExecutorType::exec;
113 Kokkos::parallel_for(
114 name, Kokkos::RangePolicy<runOn, Kokkos::IndexType<localIdx>>(start, end), kernel
121template<parallelForKernel Kernel>
124 std::pair<localIdx, localIdx> range,
125 const Kernel& kernel,
126 std::string
name =
"parallelFor"
133template<
typename Kernel,
typename ValueType>
137 } -> std::same_as<ValueType>;
148 ContType<ValueType>& container,
149 const Kernel& kernel,
150 std::string
name =
"parallelFor"
153 auto view = container.view();
154 const auto viewSize =
toLocalIdx(view.size());
155 if constexpr (std::is_same<std::remove_reference_t<Executor>,
SerialExecutor>::value)
157 for (
localIdx i = 0; i < viewSize; i++)
164 using runOn =
typename Executor::exec;
165 Kokkos::parallel_for(
167 Kokkos::RangePolicy<runOn>(0, viewSize),
177 parallelForContainerKernel<ValueType> Kernel>
178void parallelFor(ContType<ValueType>& cont,
const Kernel& kernel, std::string
name =
"parallelFor")
183template<
typename Executor,
typename Kernel,
typename T>
185 [[maybe_unused]]
const Executor& exec,
186 std::pair<localIdx, localIdx> range,
187 const Kernel& kernel,
191 auto [start, end] = range;
192 if constexpr (std::is_same<std::remove_reference_t<Executor>,
SerialExecutor>::value)
194 for (
localIdx i = start; i < end; i++)
196 if constexpr (Kokkos::is_reducer<T>::value)
198 kernel(i, value.reference());
208 using runOn =
typename Executor::exec;
209 Kokkos::parallel_reduce(
210 "parallelReduce", Kokkos::RangePolicy<runOn>(start, end), kernel, value
215template<
typename Kernel,
typename T>
217 const NeoN::Executor& exec, std::pair<localIdx, localIdx> range,
const Kernel& kernel, T& value
224template<
typename Executor,
typename ValueType,
typename Kernel,
typename T>
229 if constexpr (std::is_same<std::remove_reference_t<Executor>,
SerialExecutor>::value)
232 for (
localIdx i = 0; i < fieldSize; i++)
234 if constexpr (Kokkos::is_reducer<T>::value)
236 kernel(i, value.reference());
246 using runOn =
typename Executor::exec;
247 Kokkos::parallel_reduce(
248 "parallelReduce", Kokkos::RangePolicy<runOn>(0, field.
size()), kernel, value
253template<
typename ValueType,
typename Kernel,
typename T>
257 field.
exec(), [&](
const auto& e) { parallelReduce(e, field, kernel, value); }
261template<
typename Executor,
typename Kernel>
263 [[maybe_unused]]
const Executor& exec, std::pair<localIdx, localIdx> range,
const Kernel& kernel
266 auto [start, end] = range;
267 using runOn =
typename Executor::exec;
268 Kokkos::parallel_scan(
"parallelScan", Kokkos::RangePolicy<runOn>(start, end), kernel);
271template<
typename Kernel>
273 const NeoN::Executor& exec, std::pair<localIdx, localIdx> range,
const Kernel& kernel
279template<
typename Executor,
typename Kernel,
typename ReturnType>
281 [[maybe_unused]]
const Executor& exec,
282 std::pair<localIdx, localIdx> range,
283 const Kernel& kernel,
284 ReturnType& returnValue
287 auto [start, end] = range;
288 using runOn =
typename Executor::exec;
289 Kokkos::parallel_scan(
290 "parallelScan", Kokkos::RangePolicy<runOn>(start, end), kernel, returnValue
294template<
typename Kernel,
typename ReturnType>
297 std::pair<localIdx, localIdx> range,
298 const Kernel& kernel,
299 ReturnType& returnValue
303 exec, [&](
const auto& e) {
parallelScan(e, range, kernel, returnValue); }
Reference executor for serial CPU execution.
An executor-aware contiguous container for numerical data with vector-style arithmetic semantics.
sizeType size() const
Returns the number of elements in the Vector.
const Executor & exec() const
Returns the executor associated with the Vector.
void visitExecutor(const Executor &exec, F &&f)
Integer types used throughout NeoN.
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
void fenceIfLogger(const ExecutorType &exec)
void fence(const Executor &exec)
localIdx toLocalIdx(sizeType value)
std::shared_ptr< const Logging::BaseLogger > getLogger(const Executor &exec)
void parallelScan(const Executor &exec, std::pair< localIdx, localIdx > range, const Kernel &kernel)
void parallelFor(const ExecutorType &, std::pair< localIdx, localIdx > range, const Kernel &kernel, std::string name)
const std::string & name(const NeoN::Document &doc)
Retrieves the name of a Document.
void parallelReduce(const Executor &exec, std::pair< localIdx, localIdx > range, const Kernel &kernel, T &value)