Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
ComputeField.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
20#include "shambase/memory.hpp"
21#include "shambackends/sycl.hpp"
22#include "shambackends/vec.hpp"
27
28namespace shamrock {
29
30 template<class T>
32
33 public:
35
36 inline void generate(PatchScheduler &sched, std::string name, u32 nvar = 1) {
37 StackEntry stack_loc{};
38
39 using namespace shamrock::patch;
40
41 sched.for_each_patch_data([&](u64 id_patch, Patch cur_p, PatchDataLayer &pdat) {
42 field_data.add_obj(id_patch, PatchDataField<T>(name, nvar));
43 field_data.get(id_patch).resize(pdat.get_obj_cnt());
44 });
45 }
46
47 inline sham::DeviceBuffer<T> &get_buf(u64 id_patch) {
48 return field_data.get(id_patch).get_buf();
49 }
50
51 inline shambase::DistributedData<u32> get_obj_cnts() const {
52 return field_data.template map<u32>([](u64 id, const PatchDataField<T> &cfield) {
53 return cfield.get_obj_cnt();
54 });
55 }
56
57 inline PatchDataField<T> &get_field(u64 id_patch) { return field_data.get(id_patch); }
58
59 inline sham::DeviceBuffer<T> &get_buf_check(u64 id) { return get_buf(id); }
60
61 template<u32 nvar>
63 return field_data.template map<PatchDataFieldSpan<T, nvar>>(
64 [&](u64 id, PatchDataField<T> &cfield) {
65 return cfield.template get_span<nvar>();
66 });
67 }
68
70 get_field_span_nvar_dynamic() {
71 return field_data.template map<PatchDataFieldSpan<T, shamrock::dynamic_nvar>>(
72 [&](u64 id, PatchDataField<T> &cfield) {
73 return cfield.get_field_span_nvar_dynamic();
74 });
75 }
76
77 inline T compute_rank_max() {
78 StackEntry stack_loc{};
80 field_data.for_each([&](u64 id, PatchDataField<T> &cfield) {
81 if (!cfield.is_empty()) {
82 ret = sham::max(ret, cfield.compute_max());
83 }
84 });
85
86 return ret;
87 }
88
89 inline T compute_rank_min() {
90 StackEntry stack_loc{};
92 field_data.for_each([&](u64 id, PatchDataField<T> &cfield) {
93 if (!cfield.is_empty()) {
94 ret = sham::min(ret, cfield.compute_min());
95 }
96 });
97
98 return ret;
99 }
100
101 inline T compute_rank_sum() {
102 StackEntry stack_loc{};
104 field_data.for_each([&](u64 id, PatchDataField<T> &cfield) {
105 if (!cfield.is_empty()) {
106 ret += cfield.compute_sum();
107 }
108 });
109
110 return ret;
111 }
112
113 inline T compute_rank_dot_sum() {
114 StackEntry stack_loc{};
116 field_data.for_each([&](u64 id, PatchDataField<T> &cfield) {
117 if (!cfield.is_empty()) {
118 ret += cfield.compute_dot_sum();
119 }
120 });
121
122 return ret;
123 }
124
125 inline u32 get_nvar() {
126
127 std::optional<u32> nvar = std::nullopt;
128
129 field_data.for_each([&](u64 id, PatchDataField<T> &cfield) {
130 u32 loc_nvar = cfield.get_nvar();
131 if (!bool(nvar)) {
132 nvar = loc_nvar;
133 }
134
135 if (nvar != loc_nvar) {
137 shambase::format("mismatch in nvar excepted={} found={}", *nvar, loc_nvar));
138 }
139 });
140
141 if (!bool(nvar)) {
143 "you cannot query this function when you have no fields");
144 }
145
146 return *nvar;
147 }
148
149 inline std::unique_ptr<sycl::buffer<T>> rankgather_computefield(PatchScheduler &sched) {
150 StackEntry stack_loc{};
151
152 std::unique_ptr<sycl::buffer<T>> ret;
153
154 u64 num_obj = sched.get_rank_count();
155 u64 nvar = get_nvar();
156
157 if (num_obj > 0) {
158 ret = std::make_unique<sycl::buffer<T>>(num_obj * nvar);
159
160 using namespace shamrock::patch;
161
162 u64 ptr = 0; // TODO accumulate_field() in scheduler ?
163 sched.for_each_patch_data([&](u64 id_patch, Patch cur_p, PatchDataLayer &pdat) {
164 using namespace shamalgs::memory;
165 using namespace shambase;
166
167 if (pdat.get_obj_cnt() > 0) {
168 write_with_offset_into(
169 shamsys::instance::get_compute_scheduler().get_queue(),
170 get_check_ref(ret),
171 get_buf(id_patch),
172 ptr,
173 pdat.get_obj_cnt() * nvar);
174
175 ptr += pdat.get_obj_cnt() * nvar;
176 }
177 });
178 }
179
180 return ret;
181 }
182
183 inline void reset() { field_data.reset(); }
184 };
185} // namespace shamrock
Header file describing a Node Instance.
MPI scheduler.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
The MPI scheduler.
void for_each_patch_data(Function &&fct)
for each macro for patchadata example usage
A buffer allocated in USM (Unified Shared Memory)
Represents a collection of objects distributed across patches identified by a u64 id.
iterator add_obj(u64 id, T &&obj)
Adds a new object to the collection.
void for_each(std::function< void(u64, T &)> &&f)
Applies a function to each object in the collection.
T & get(u64 id)
Returns a reference to an object in the collection.
void reset()
Reset the collection to its initial state.
PatchDataLayer container class, the layout is described in patchdata_layout.
memory manipulation algorithms
namespace for basic c++ utilities
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
namespace for the main framework
Definition __init__.py:1
Patch object that contain generic patch information.
Definition Patch.hpp:33