Orrery
A GPU-accelerated N-body gravitational simulator
Loading...
Searching...
No Matches
sycl_tree_solver.hpp
Go to the documentation of this file.
1#pragma once
2
95
96#include <cstdint>
97#include <memory>
98#include <span>
99#include <string_view>
100
105#include "orrery/core/types.hpp"
110
111#ifdef ORRERY_ENABLE_SYCL
112
113namespace orrery::solvers {
114
123enum class TreeTraversal : std::uint8_t {
130
133};
134
135[[nodiscard]] constexpr std::string_view to_string(TreeTraversal traversal) noexcept {
136 return traversal == TreeTraversal::kCoherent ? "coherent" : "independent";
137}
138
177
183class SyclTreeSolver final : public ForceSolver {
184public:
196 [[nodiscard]] static std::unique_ptr<SyclTreeSolver>
198 backend::Executor* executor = nullptr);
199
200 ~SyclTreeSolver() override;
201
202 SyclTreeSolver(const SyclTreeSolver&) = delete;
203 SyclTreeSolver& operator=(const SyclTreeSolver&) = delete;
204 SyclTreeSolver(SyclTreeSolver&&) noexcept;
205 SyclTreeSolver& operator=(SyclTreeSolver&&) noexcept;
206
216 void evaluate(core::Vec3Span<const core::Real> positions, std::span<const core::Real> masses,
217 core::Vec3Span<core::Real> accelerations) override;
218
219 [[nodiscard]] std::string_view name() const noexcept override { return "sycl-tree"; }
220
221 [[nodiscard]] core::Softening softening() const noexcept override;
222
223 [[nodiscard]] InteractionCount interaction_count() const noexcept override;
224
225 void reset_interaction_count() noexcept override;
226
229 [[nodiscard]] const TreeParameters& parameters() const noexcept;
230
237 [[nodiscard]] const Octree& tree() const noexcept;
238
240 [[nodiscard]] TreeTraversal traversal() const noexcept;
241
242 void select_traversal(TreeTraversal traversal) noexcept;
243
257 void select_sub_group_width(unsigned width) noexcept;
258
260 [[nodiscard]] unsigned sub_group_width() const noexcept;
261
263 [[nodiscard]] std::span<const unsigned> supported_sub_group_widths() const noexcept;
264
269 [[nodiscard]] core::Index work_group_size() const noexcept;
270
283 [[nodiscard]] std::uint64_t node_visits() const noexcept;
284
286 [[nodiscard]] const backend::DeviceDescription& device() const noexcept;
287
289 [[nodiscard]] const SyclTreeTimings& timings() const noexcept;
290
297 [[nodiscard]] bool uses_shared_memory() const noexcept;
298
299private:
303 struct Impl;
304
305 explicit SyclTreeSolver(std::unique_ptr<Impl> impl) noexcept;
306
307 std::unique_ptr<Impl> impl_;
308};
309
310} // namespace orrery::solvers
311
312#endif // ORRERY_ENABLE_SYCL
Something that can run a loop body over a range, possibly in parallel.
Definition executor.hpp:52
The softening length of the Plummer kernel above.
Definition softening.hpp:49
The octree of one configuration, built from Morton-sorted particles.
Definition octree.hpp:208
const TreeParameters & parameters() const noexcept
The tree parameters in force, after the corrections TreeParameters documents.
const backend::DeviceDescription & device() const noexcept
What the runtime says about the device this solver runs on.
InteractionCount interaction_count() const noexcept override
The work done since construction or since the last reset.
TreeTraversal traversal() const noexcept
Which traversal the next evaluation will run.
core::Softening softening() const noexcept override
The softening this solver applies.
std::uint64_t node_visits() const noexcept
How many nodes the traversal visited, summed over work-items, since the count was last reset.
void select_sub_group_width(unsigned width) noexcept
Ask for a particular sub-group width, and settle for the device's own choice if it cannot provide tha...
void evaluate(core::Vec3Span< const core::Real > positions, std::span< const core::Real > masses, core::Vec3Span< core::Real > accelerations) override
Write the acceleration at each position into accelerations.
std::span< const unsigned > supported_sub_group_widths() const noexcept
The widths this device will compile a kernel for, ascending.
core::Index work_group_size() const noexcept
The work-group size the traversal launches with.
void reset_interaction_count() noexcept override
Set every counter back to zero.
bool uses_shared_memory() const noexcept
Whether the arrays the traversal reads are shared unified memory, asked of the runtime rather than as...
const SyclTreeTimings & timings() const noexcept
Where the last evaluation spent its time.
unsigned sub_group_width() const noexcept
The width asked for, which is zero when the compiler is choosing.
std::string_view name() const noexcept override
The solver's name, for benchmark tables and test messages.
Definition sycl_tree_solver.hpp:219
const Octree & tree() const noexcept
The tree the last evaluation built, empty before the first.
static std::unique_ptr< SyclTreeSolver > try_create(TreeParameters parameters={}, core::Softening softening={}, backend::Executor *executor=nullptr)
A solver on this machine's GPU, or nothing.
How a kernel asks for a loop to be run in parallel.
What every gravitational force solver in this project provides.
The unit in which the cost of a force evaluation is reported.
The tree the Barnes-Hut solver walks, and the moments it carries.
Plummer softening, defined once for everything that needs it.
What a solver has done since the count was last reset.
Definition interaction_count.hpp:37
Where one force evaluation spent its time.
Definition sycl_tree_solver.hpp:150
backend::Duration kernel
Submitting the traversal and waiting for the device.
Definition sycl_tree_solver.hpp:171
backend::Duration construction
Building the octree over the sorted order, on the host.
Definition sycl_tree_solver.hpp:160
backend::Duration gathering
Gathering the positions and masses into the tree's order, writing straight into shared memory.
Definition sycl_tree_solver.hpp:157
backend::Duration ordering
Computing and sorting the Morton codes, on the host.
Definition sycl_tree_solver.hpp:152
backend::Duration node_staging
Converting the host node array into the device layout.
Definition sycl_tree_solver.hpp:167
backend::Duration scatter
Scattering the accelerations back to the caller's order out of shared memory.
Definition sycl_tree_solver.hpp:175
The choices that decide what the tree costs and how accurate it is.
Definition octree.hpp:147
Finding the GPU, and reporting what was found.
TreeTraversal
Which of the two traversals the device runs.
Definition sycl_tree_solver.hpp:123
@ kIndependent
One work-item per target, each following its own node index.
Definition sycl_tree_solver.hpp:129
@ kCoherent
One node index per sub-group, advanced by agreement.
Definition sycl_tree_solver.hpp:132
The scalar and index types that every layer of the project agrees on.
Three parallel component arrays, viewed as one sequence of 3-vectors.
What each worker thread did, and how long it spent doing nothing.
std::chrono::nanoseconds Duration
Durations are stored in nanoseconds so that they add without conversion and mean the same thing on ev...
Definition worker_statistics.hpp:53