Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
Patch.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 "PatchCoord.hpp"
23
24namespace shamrock::patch {
25
26 template<u32 dim>
27 MPI_Datatype get_patch_mpi_type();
28
33 struct Patch {
34
36 // Constexpr defs
38
50 static constexpr u32 dim = 3U;
51
52 static_assert(dim < 4, "the patch object is implemented only up to dim 3");
53
54 static constexpr u32 splts_count = 1U << dim;
55
56 static constexpr u32 err_node_flag = u32_max;
57
59 // Members
61
89
90 std::array<u64, dim> coord_min;
91 std::array<u64, dim> coord_max;
92
94
96 // functions
98
106 bool operator==(const Patch &rhs) const;
107
112
119 [[nodiscard]] inline bool is_err_mode() const { return node_owner_id == err_node_flag; }
120
121 [[nodiscard]] std::array<u64, dim> get_split_coord() const;
122
123 [[nodiscard]] std::array<Patch, splts_count> get_split() const;
124
125 [[nodiscard]] static Patch merge_patch(std::array<Patch, splts_count> patches);
126
136 template<class T>
137 std::tuple<sycl::vec<T, 3>, sycl::vec<T, 3>> convert_coord(
138 sycl::vec<u64, 3> src_offset, sycl::vec<T, 3> divfact, sycl::vec<T, 3> offset) const;
139
150 template<class T>
151 inline static bool is_in_patch_converted(
152 sycl::vec<T, 3> val, sycl::vec<T, 3> min_val, sycl::vec<T, 3> max_val);
153
154 inline void override_from_coord(PatchCoord<dim> pc) {
155 coord_min[0] = pc.coord_min[0];
156 coord_min[1] = pc.coord_min[1];
157 coord_min[2] = pc.coord_min[2];
158 coord_max[0] = pc.coord_max[0];
159 coord_max[1] = pc.coord_max[1];
160 coord_max[2] = pc.coord_max[2];
161 }
162
163 [[nodiscard]] inline PatchCoord<dim> get_coords() const { return {coord_min, coord_max}; }
164
165 inline shammath::CoordRange<u64_3> get_patch_range() {
166 return get_coords().get_patch_range();
167 }
168 };
169
171 // out of line implementation
173
174 inline bool Patch::operator==(const Patch &rhs) const {
175
176 bool ret_val = true;
177
178 ret_val = ret_val && (id_patch == rhs.id_patch);
179
180 ret_val = ret_val && (pack_node_index == rhs.pack_node_index);
181 ret_val = ret_val && (load_value == rhs.load_value);
182
183#pragma unroll
184 for (u32 i = 0; i < dim; i++) {
185 ret_val = ret_val && (coord_min[i] == rhs.coord_min[i]);
186 }
187
188#pragma unroll
189 for (u32 i = 0; i < dim; i++) {
190 ret_val = ret_val && (coord_max[i] == rhs.coord_max[i]);
191 }
192
193 ret_val = ret_val && (node_owner_id == rhs.node_owner_id);
194
195 return ret_val;
196 }
197
198 template<class T>
199 inline std::tuple<sycl::vec<T, 3>, sycl::vec<T, 3>> Patch::convert_coord(
200 sycl::vec<u64, 3> src_offset, sycl::vec<T, 3> divfact, sycl::vec<T, 3> offset) const {
202 coord_min,
203 coord_max,
204 {src_offset.x(), src_offset.y(), src_offset.z()},
205 divfact,
206 offset);
207 }
208
209 template<class T>
211 sycl::vec<T, 3> val, sycl::vec<T, 3> min_val, sycl::vec<T, 3> max_val) {
212 return (
213 (min_val.x() <= val.x()) && (val.x() < max_val.x()) && (min_val.y() <= val.y())
214 && (val.y() < max_val.y()) && (min_val.z() <= val.z()) && (val.z() < max_val.z()));
215 }
216
217 [[nodiscard]] inline auto Patch::get_split_coord() const -> std::array<u64, dim> {
218 return PatchCoord<dim>::get_split_coord(coord_min, coord_max);
219 }
220
221 [[nodiscard]] inline auto Patch::get_split() const -> std::array<Patch, splts_count> {
222
223 // init vars
224 Patch p0, p1, p2, p3, p4, p5, p6, p7;
225
226 // setup internal fields
227 p0 = *this; // copy of the current state
228 p0.load_value /= 8;
229
230 p1 = p0;
231 p2 = p0;
232 p3 = p0;
233 p4 = p0;
234 p5 = p0;
235 p6 = p0;
236 p7 = p0;
237
238 std::array<PatchCoord<dim>, splts_count> splts_c
239 = PatchCoord<dim>::get_split(coord_min, coord_max);
240
241 p0.override_from_coord(splts_c[0]);
242 p1.override_from_coord(splts_c[1]);
243 p2.override_from_coord(splts_c[2]);
244 p3.override_from_coord(splts_c[3]);
245 p4.override_from_coord(splts_c[4]);
246 p5.override_from_coord(splts_c[5]);
247 p6.override_from_coord(splts_c[6]);
248 p7.override_from_coord(splts_c[7]);
249
250 return {p0, p1, p2, p3, p4, p5, p6, p7};
251 }
252
253 [[nodiscard]] inline Patch Patch::merge_patch(std::array<Patch, splts_count> patches) {
254
255 PatchCoord merged_c = PatchCoord<dim>::merge(
256 {patches[0].get_coords(),
257 patches[1].get_coords(),
258 patches[2].get_coords(),
259 patches[3].get_coords(),
260 patches[4].get_coords(),
261 patches[5].get_coords(),
262 patches[6].get_coords(),
263 patches[7].get_coords()});
264
265 Patch ret{};
266 ret = patches[0];
267
268 ret.coord_min[0] = merged_c.coord_min[0];
269 ret.coord_min[1] = merged_c.coord_min[1];
270 ret.coord_min[2] = merged_c.coord_min[2];
271 ret.coord_max[0] = merged_c.coord_max[0];
272 ret.coord_max[1] = merged_c.coord_max[1];
273 ret.coord_max[2] = merged_c.coord_max[2];
274
275 ret.pack_node_index = u64_max;
276
277 ret.load_value += patches[1].load_value;
278 ret.load_value += patches[2].load_value;
279 ret.load_value += patches[3].load_value;
280 ret.load_value += patches[4].load_value;
281 ret.load_value += patches[5].load_value;
282 ret.load_value += patches[6].load_value;
283 ret.load_value += patches[7].load_value;
284
285 return ret;
286 }
287
288} // namespace shamrock::patch
This header does the MPI include and wrap MPI calls.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
STL namespace.
constexpr u64 u64_max
u64 max value
constexpr u32 u32_max
u32 max value
Patch object that contain generic patch information.
Definition Patch.hpp:33
static constexpr u32 dim
dimension of the patch (only 3 so far)
Definition Patch.hpp:50
bool is_err_mode() const
check if a patch is in error mode
Definition Patch.hpp:119
u64 pack_node_index
this value mean "to pack with index xxx in the global patch table" and not "to pack with id_pach == x...
Definition Patch.hpp:87
static bool is_in_patch_converted(sycl::vec< T, 3 > val, sycl::vec< T, 3 > min_val, sycl::vec< T, 3 > max_val)
check if particle is in the asked range, given the output of @convert_coord
Definition Patch.hpp:210
static constexpr u32 splts_count
if a patch splits, this gives the number of childs
Definition Patch.hpp:54
void set_err_mode()
Make the patch in error mode (patch struct that will be flushed on sync)
Definition Patch.hpp:111
bool operator==(const Patch &rhs) const
check if patch equals
Definition Patch.hpp:174
u32 node_owner_id
node rank owner of this patch
Definition Patch.hpp:93
std::tuple< sycl::vec< T, 3 >, sycl::vec< T, 3 > > convert_coord(sycl::vec< u64, 3 > src_offset, sycl::vec< T, 3 > divfact, sycl::vec< T, 3 > offset) const
return an open interval of the corresponding patch coordinates given the div & offset
Definition Patch.hpp:199
u64 load_value
if synchronized contain the load value of the patch
Definition Patch.hpp:88
static constexpr u32 err_node_flag
value of node_owner_id if the patch is invalid
Definition Patch.hpp:56
u64 id_patch
unique key that identify the patch
Definition Patch.hpp:86