31namespace shamrock::patch {
34 u64 seed,
u32 obj_cnt,
const std::shared_ptr<PatchDataLayerLayout> &pdl) {
35 PatchDataLayer pdat{pdl};
39 pdat.pdl().for_each_field_any([&](
auto &field) {
40 using f_t =
typename std::remove_reference<
decltype(field)>::type;
41 using base_t =
typename f_t::field_T;
43 pdat.fields.push_back(
44 var_t{PatchDataField<base_t>::mock_field(seed, obj_cnt, field.name, field.nvar)});
50 PatchDataLayer::PatchDataLayer(
const PatchDataLayer &other) : pdl_ptr(other.get_layout_ptr()) {
54 for (
auto &field_var : other.fields) {
56 field_var.visit([&](auto &field) {
57 using base_t = typename std::remove_reference<decltype(field)>::type::Field_type;
58 fields.emplace_back(PatchDataField<base_t>(field));
63 void PatchDataLayer::init_fields() {
65 pdl().for_each_field_any([&](
auto &field) {
66 using f_t =
typename std::remove_reference<
decltype(field)>::type;
67 using base_t =
typename f_t::field_T;
76 for (
u32 idx = 0; idx < fields.size(); idx++) {
79 [&](
auto &field,
auto &out_field) {
80 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
82 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
84 if constexpr (std::is_same<t1, t2>::value) {
85 field.extract_element(pidx, out_field);
91 out_pdat.fields[idx].value);
95 void PatchDataLayer::extract_elements(
99 for (
u32 idx = 0; idx < fields.size(); idx++) {
102 [&](
auto &field,
auto &out_field) {
103 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
105 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
107 if constexpr (std::is_same<t1, t2>::value) {
108 field.extract_elements(idxs, out_field);
114 out_pdat.fields[idx].value);
118 void PatchDataLayer::insert_elements(
const PatchDataLayer &pdat) {
122 for (
u32 idx = 0; idx < fields.size(); idx++) {
125 [&](
auto &field,
auto &out_field) {
126 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
128 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
130 if constexpr (std::is_same<t1, t2>::value) {
131 field.insert(out_field);
137 pdat.fields[idx].value);
141 void PatchDataLayer::overwrite(PatchDataLayer &pdat,
u32 obj_cnt) {
144 for (
u32 idx = 0; idx < fields.size(); idx++) {
147 [&](
auto &field,
auto &out_field) {
148 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
150 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
152 if constexpr (std::is_same<t1, t2>::value) {
153 field.overwrite(out_field, obj_cnt);
159 pdat.fields[idx].value);
163 void PatchDataLayer::resize(
u32 new_obj_cnt) {
165 for (
auto &field_var : fields) {
166 field_var.visit([&](
auto &field) {
167 field.resize(new_obj_cnt);
172 void PatchDataLayer::reserve(
u32 new_obj_cnt) {
174 for (
auto &field_var : fields) {
175 field_var.visit([&](
auto &field) {
176 field.reserve(new_obj_cnt);
181 void PatchDataLayer::expand(
u32 new_obj_cnt) {
183 for (
auto &field_var : fields) {
184 field_var.visit([&](
auto &field) {
185 field.expand(new_obj_cnt);
193 index_map, len, shamsys::instance::get_compute_scheduler_ptr());
195 for (
auto &field_var : fields) {
196 field_var.visit([&](
auto &field) {
197 field.index_remap(dev_index_map, len);
204 index_map, len, shamsys::instance::get_compute_scheduler_ptr());
206 for (
auto &field_var : fields) {
207 field_var.visit([&](
auto &field) {
208 field.index_remap_resize(dev_index_map, len);
214 for (
auto &field_var : fields) {
215 field_var.visit([&](
auto &field) {
216 field.index_remap_resize(index_map, len);
221 void PatchDataLayer::keep_ids(sycl::buffer<u32> &index_map,
u32 len) {
222 index_remap_resize(index_map, len);
230 for (
auto &field_var : fields) {
231 field_var.visit([&](
auto &field) {
232 field.remove_ids(indexes, len);
237 void PatchDataLayer::append_subset_to(
241 for (
u32 idx = 0; idx < fields.size(); idx++) {
244 [&](
auto &field,
auto &out_field) {
245 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
247 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
249 if constexpr (std::is_same<t1, t2>::value) {
250 field.append_subset_to(idxs_buf, sz, out_field);
256 pdat.fields[idx].value);
260 void PatchDataLayer::append_subset_to(
const std::vector<u32> &idxs, PatchDataLayer &pdat) {
263 for (
u32 idx = 0; idx < fields.size(); idx++) {
266 [&](
auto &field,
auto &out_field) {
267 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
269 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
271 if constexpr (std::is_same<t1, t2>::value) {
272 field.append_subset_to(idxs, out_field);
278 pdat.fields[idx].value);
282 void PatchDataLayer::append_subset_to(
283 const sham::DeviceBuffer<u32> &idxs_buf,
u32 sz, PatchDataLayer &pdat)
const {
286 for (
u32 idx = 0; idx < fields.size(); idx++) {
289 [&](
auto &field,
auto &out_field) {
290 using t1 =
typename std::remove_reference<
decltype(field)>::type::Field_type;
292 typename std::remove_reference<
decltype(out_field)>::type::Field_type;
294 if constexpr (std::is_same<t1, t2>::value) {
295 field.append_subset_to(idxs_buf, sz, out_field);
298 "Mismatch in layout\n source layout = {}\n dest layout = {}",
299 pdl().get_description_str(),
300 pdat.pdl().get_description_str()));
304 pdat.fields[idx].value);
308 void PatchDataLayer::serialize_buf(shamalgs::SerializeHelper &serializer) {
310 for_each_field_any([&](
auto &f) {
311 f.serialize_buf(serializer);
315 shamalgs::SerializeSize PatchDataLayer::serialize_buf_byte_size() {
316 shamalgs::SerializeSize sum{};
317 for_each_field_any([&](
auto &f) {
318 sum += f.serialize_buf_byte_size();
323 PatchDataLayer PatchDataLayer::deserialize_buf(
324 shamalgs::SerializeHelper &serializer,
const std::shared_ptr<PatchDataLayerLayout> &pdl) {
327 return PatchDataLayer{pdl, [&](
auto &pdat_fields) {
328 pdl->for_each_field_any([&](
auto &field) {
330 typename std::remove_reference<
decltype(field)>::type;
331 using base_t =
typename f_t::field_T;
333 pdat_fields.push_back(
335 serializer, field.name, field.nvar)});
340 void PatchDataLayer::fields_raz() {
341 for_each_field_any([&](
auto &f) {
348 bool is_empty = fields.empty();
351 return fields[0].visit_return([](
const auto &field) {
352 return field.get_obj_cnt();
357 "this PatchDataLayer does not contain any fields");
363 for (
auto &field_var : fields) {
365 field_var.visit([&](
auto &field) {
366 sum += field.memsize();
374 for (
auto &field_var : fields) {
375 field_var.visit([&](
auto &field) {
376 field.synchronize_buf();
383 for (
auto &field_var : fields) {
384 field_var.visit([&](
auto &field) {
385 if (field.get_obj_cnt() != cnt) {
397 for (
auto &field_var : fields) {
398 field_var.visit([&](
auto &field) {
399 if (field.has_nan()) {
412 for (
auto &field_var : fields) {
413 field_var.visit([&](
auto &field) {
414 if (field.has_inf()) {
427 for (
auto &field_var : fields) {
428 field_var.visit([&](
auto &field) {
429 if (field.has_nan_or_inf()) {
438 void PatchDataLayer::split_patchdata(
439 std::array<std::reference_wrapper<PatchDataLayer>, 8> pdats,
440 std::array<T, 8> min_box,
441 std::array<T, 8> max_box) {
456 auto get_vec_idx = [&](T vmin, T vmax) -> std::vector<u32> {
458 [&](
const auto &acc,
u32 idx, T vmin, T vmax) {
460 return Patch::is_in_patch_converted(val, vmin, vmax);
466 std::vector<u32> idx_p0 = get_vec_idx(min_box[0], max_box[0]);
467 std::vector<u32> idx_p1 = get_vec_idx(min_box[1], max_box[1]);
468 std::vector<u32> idx_p2 = get_vec_idx(min_box[2], max_box[2]);
469 std::vector<u32> idx_p3 = get_vec_idx(min_box[3], max_box[3]);
470 std::vector<u32> idx_p4 = get_vec_idx(min_box[4], max_box[4]);
471 std::vector<u32> idx_p5 = get_vec_idx(min_box[5], max_box[5]);
472 std::vector<u32> idx_p6 = get_vec_idx(min_box[6], max_box[6]);
473 std::vector<u32> idx_p7 = get_vec_idx(min_box[7], max_box[7]);
475 u32 el_cnt_new = idx_p0.size() + idx_p1.size() + idx_p2.size() + idx_p3.size()
476 + idx_p4.size() + idx_p5.size() + idx_p6.size() + idx_p7.size();
478 if (get_obj_cnt() != el_cnt_new) {
482 "error in patchdata split, the new element count doesn't match the old one");
484 logger::err_ln(
"PatchData", min_box[0], max_box[0]);
485 logger::err_ln(
"PatchData", min_box[1], max_box[1]);
486 logger::err_ln(
"PatchData", min_box[2], max_box[2]);
487 logger::err_ln(
"PatchData", min_box[3], max_box[3]);
488 logger::err_ln(
"PatchData", min_box[4], max_box[4]);
489 logger::err_ln(
"PatchData", min_box[5], max_box[5]);
490 logger::err_ln(
"PatchData", min_box[6], max_box[6]);
491 logger::err_ln(
"PatchData", min_box[7], max_box[7]);
493 T vmin = sham::min(min_box[0], min_box[1]);
494 vmin = sham::min(vmin, min_box[2]);
495 vmin = sham::min(vmin, min_box[3]);
496 vmin = sham::min(vmin, min_box[4]);
497 vmin = sham::min(vmin, min_box[5]);
498 vmin = sham::min(vmin, min_box[6]);
499 vmin = sham::min(vmin, min_box[7]);
501 T vmax = sham::max(max_box[0], max_box[1]);
502 vmax = sham::max(vmax, max_box[2]);
503 vmax = sham::max(vmax, max_box[3]);
504 vmax = sham::max(vmax, max_box[4]);
505 vmax = sham::max(vmax, max_box[5]);
506 vmax = sham::max(vmax, max_box[6]);
507 vmax = sham::max(vmax, max_box[7]);
509 main_field.check_err_range(
510 [&](T val, T vmin, T vmax) {
511 return Patch::is_in_patch_converted(val, vmin, vmax);
530 template void PatchDataLayer::split_patchdata(
531 std::array<std::reference_wrapper<PatchDataLayer>, 8> pdats,
532 std::array<f32_3, 8> min_box,
533 std::array<f32_3, 8> max_box);
534 template void PatchDataLayer::split_patchdata(
535 std::array<std::reference_wrapper<PatchDataLayer>, 8> pdats,
536 std::array<f64_3, 8> min_box,
537 std::array<f64_3, 8> max_box);
538 template void PatchDataLayer::split_patchdata(
539 std::array<std::reference_wrapper<PatchDataLayer>, 8> pdats,
540 std::array<u32_3, 8> min_box,
541 std::array<u32_3, 8> max_box);
542 template void PatchDataLayer::split_patchdata(
543 std::array<std::reference_wrapper<PatchDataLayer>, 8> pdats,
544 std::array<u64_3, 8> min_box,
545 std::array<u64_3, 8> max_box);
546 template void PatchDataLayer::split_patchdata(
547 std::array<std::reference_wrapper<PatchDataLayer>, 8> pdats,
548 std::array<i64_3, 8> min_box,
549 std::array<i64_3, 8> max_box);
555 if (p1.fields.size() != p2.fields.size()) {
559 for (
u32 idx = 0; idx < p1.fields.size(); idx++) {
560 bool ret = p1.fields[idx].visit_return([&](
auto &pf1) ->
bool {
561 using t1 =
typename std::remove_reference<
decltype(pf1)>::type::Field_type;
565 return pf1.check_field_match(*pf2);
571 check = check && ret;
Header file for the patch struct and related function.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
static PatchDataField deserialize_buf(shamalgs::SerializeHelper &serializer, std::string field_name, u32 nvar)
deserialize a field inverse of serialize_buf
std::vector< u32 > get_ids_vec_where(Lambdacd &&cd_true, Args &&...args)
Same function as.
A buffer allocated in USM (Unified Shared Memory).
PatchDataLayer container class, the layout is described in patchdata_layout.
void index_remap(sycl::buffer< u32 > &index_map, u32 len)
this function remaps the patchdatafield like so val[id] = val[index_map[id]] This function can be use...
bool has_inf()
check whether any field contains an infinite value
friend bool operator==(PatchDataLayer &p1, PatchDataLayer &p2)
Compare two layers field by field (defined in PatchDataLayer.cpp).
void check_field_obj_cnt_match()
check that all contained field have the same obj cnt
u32 get_obj_cnt() const
get the number of objects (particles) stored in this layer
void synchronize_buf()
synchronize the host/device buffers of all fields
void index_remap_resize(sycl::buffer< u32 > &index_map, u32 len)
this function remaps the patchdatafield like so val[id] = val[index_map[id]] This function can be use...
void remove_ids(const sham::DeviceBuffer< u32 > &indexes, u32 len)
remove some particles ids
bool has_nan()
check whether any field contains a NaN value
void extract_element(u32 pidx, PatchDataLayer &out_pdat)
extract particle at index pidx and insert it in the provided vectors
bool has_nan_or_inf()
check whether any field contains a NaN or infinite value
u64 memsize()
get the memory size in bytes used by all fields
This header file contains utility functions related to exception handling in the code.
void append_subset_to(const sham::DeviceBuffer< T > &buf, const sham::DeviceBuffer< u32 > &idxs_buf, u32 nvar, sham::DeviceBuffer< T > &buf_other, u32 start_enque)
Appends a subset of elements from one buffer to another.
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
This file contains the definition for the stacktrace related functionality.
shambase::details::NamedBasicStackEntry NamedStackEntry
Alias for shambase::details::NamedBasicStackEntry.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
header file to manage sycl