Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
AMRGridRefinementHandler.cpp
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
19#include "shamcomm/logs.hpp"
21#include <stdexcept>
22
23template<class Tvec, class TgridVec>
24template<class UserAcc, class... T>
29 T &&...args) {
30
31 using namespace shamrock::patch;
32
33 u64 tot_refine = 0;
34 u64 tot_derefine = 0;
35
36 sham::DeviceQueue &q = shamsys::instance::get_compute_scheduler().get_queue();
37 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
38
39 scheduler().for_each_patchdata_nonempty([&](Patch cur_p, PatchDataLayer &pdat) {
40 u64 id_patch = cur_p.id_patch;
41
42 // create the refine and derefine flags buffers
43 u32 obj_cnt = pdat.get_obj_cnt();
44
45 sham::DeviceBuffer<u32> refine_flags(obj_cnt, dev_sched);
46 sham::DeviceBuffer<u32> derefine_flags(obj_cnt, dev_sched);
47
48 {
49 sham::EventList depends_list;
50
51 UserAcc uacc(depends_list, id_patch, cur_p, pdat, args...);
52
53 auto refine_acc = refine_flags.get_write_access(depends_list);
54 auto derefine_acc = derefine_flags.get_write_access(depends_list);
55
56 // fill in the flags
57 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
58 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
59 bool flag_refine = false;
60 bool flag_derefine = false;
61 uacc.refine_criterion(gid.get_linear_id(), uacc, flag_refine, flag_derefine);
62
63 // This is just a safe guard to avoid this nonsensicall case
64 if (flag_refine && flag_derefine) {
65 flag_derefine = false;
66 }
67
68 refine_acc[gid] = (flag_refine) ? 1 : 0;
69 derefine_acc[gid] = (flag_derefine) ? 1 : 0;
70 });
71 });
72
73 sham::EventList resulting_events;
74 resulting_events.add_event(e);
75
76 refine_flags.complete_event_state(resulting_events);
77 derefine_flags.complete_event_state(resulting_events);
78
79 uacc.finalize(resulting_events, id_patch, cur_p, pdat, args...);
80 }
81
82 sham::DeviceBuffer<TgridVec> &buf_cell_min = pdat.get_field_buf_ref<TgridVec>(0);
83 sham::DeviceBuffer<TgridVec> &buf_cell_max = pdat.get_field_buf_ref<TgridVec>(1);
84
85 sham::EventList depends_list;
86 auto acc_min = buf_cell_min.get_read_access(depends_list);
87 auto acc_max = buf_cell_max.get_read_access(depends_list);
88 auto acc_merge_flag = derefine_flags.get_write_access(depends_list);
89
90 // keep only derefine flags on only if the eight cells want to merge and if they can
91 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
92 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
93 u32 id = gid.get_linear_id();
94
95 std::array<BlockCoord, split_count> blocks;
96 bool do_merge = true;
97
98 // This avoid the case where we are in the last block of the buffer to avoid the
99 // out-of-bound read
100 if (id + split_count <= obj_cnt) {
101 bool all_want_to_merge = true;
102
103 for (u32 lid = 0; lid < split_count; lid++) {
104 blocks[lid] = BlockCoord{acc_min[gid + lid], acc_max[gid + lid]};
105 all_want_to_merge = all_want_to_merge && acc_merge_flag[gid + lid];
106 }
107
108 do_merge = all_want_to_merge && BlockCoord::are_mergeable(blocks);
109
110 } else {
111 do_merge = false;
112 }
113
114 acc_merge_flag[gid] = do_merge;
115 });
116 });
117
118 buf_cell_min.complete_event_state(e);
119 buf_cell_max.complete_event_state(e);
120 derefine_flags.complete_event_state(e);
121
123 // refinement
125
126 // perform stream compactions on the refinement flags
127 auto buf_refine = shamalgs::numeric::stream_compact(dev_sched, refine_flags, obj_cnt);
128
129 shamlog_debug_ln(
130 "AMRGrid", "patch ", id_patch, "refine block count = ", buf_refine.get_size());
131
132 tot_refine += buf_refine.get_size();
133
134 // add the results to the map
135 dd_refine_list.add_obj(id_patch, std::move(buf_refine));
136
138 // derefinement
140
141 // perform stream compactions on the derefinement flags
142 auto buf_derefine = shamalgs::numeric::stream_compact(dev_sched, derefine_flags, obj_cnt);
143
144 shamlog_debug_ln(
145 "AMRGrid", "patch ", id_patch, "merge block count = ", buf_derefine.get_size());
146
147 tot_derefine += buf_derefine.get_size();
148
149 // add the results to the map
150 dd_derefine_list.add_obj(id_patch, std::move(buf_derefine));
151 });
152
153 logger::info_ln("AMRGrid", "on this process", tot_refine, "blocks were refined");
154 logger::info_ln(
155 "AMRGrid", "on this process", tot_derefine * split_count, "blocks were derefined");
156}
157template<class Tvec, class TgridVec>
158template<class UserAcc>
161
162 using namespace shamrock::patch;
163
164 u64 sum_block_count = 0;
165
166 bool new_cell_were_added = false;
167
168 scheduler().for_each_patch_data([&](u64 id_patch, Patch cur_p, PatchDataLayer &pdat) {
169 sham::DeviceQueue &q = shamsys::instance::get_compute_scheduler().get_queue();
170
171 u32 old_obj_cnt = pdat.get_obj_cnt();
172
173 sham::DeviceBuffer<u32> &refine_flags = dd_refine_list.get(id_patch);
174
175 if (refine_flags.get_size() > 0) {
176
177 // alloc memory for the new blocks to be created
178 pdat.expand(refine_flags.get_size() * (split_count - 1));
179
180 sham::DeviceBuffer<TgridVec> &buf_cell_min = pdat.get_field_buf_ref<TgridVec>(0);
181 sham::DeviceBuffer<TgridVec> &buf_cell_max = pdat.get_field_buf_ref<TgridVec>(1);
182
183 sham::EventList depends_list;
184 auto block_bound_low = buf_cell_min.get_write_access(depends_list);
185 auto block_bound_high = buf_cell_max.get_write_access(depends_list);
186 UserAcc uacc(depends_list, pdat);
187 auto index_to_ref = refine_flags.get_read_access(depends_list);
188
189 // Refine the block (set the positions) and fill the corresponding fields
190 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
191 u32 start_index_push = old_obj_cnt;
192
193 constexpr u32 new_splits = split_count - 1;
194
195 cgh.parallel_for(sycl::range<1>(refine_flags.get_size()), [=](sycl::item<1> gid) {
196 u32 tid = gid.get_linear_id();
197
198 u32 idx_to_refine = index_to_ref[tid];
199
200 // gen splits coordinates
201 BlockCoord cur_block{
202 block_bound_low[idx_to_refine], block_bound_high[idx_to_refine]};
203
204 std::array<BlockCoord, split_count> block_coords
205 = BlockCoord::get_split(cur_block.bmin, cur_block.bmax);
206
207 // generate index for the refined blocks
208 std::array<u32, split_count> blocks_ids;
209 blocks_ids[0] = idx_to_refine;
210
211 // generate index for the new blocks (the current index is reused for the first
212 // new block, the others are pushed at the end of the patchdata)
213#pragma unroll
214 for (u32 pid = 0; pid < new_splits; pid++) {
215 blocks_ids[pid + 1] = start_index_push + tid * new_splits + pid;
216 }
217
218 // write coordinates
219
220#pragma unroll
221 for (u32 pid = 0; pid < split_count; pid++) {
222 block_bound_low[blocks_ids[pid]] = block_coords[pid].bmin;
223 block_bound_high[blocks_ids[pid]] = block_coords[pid].bmax;
224 }
225
226 // user lambda to fill the fields
227 uacc.apply_refine(idx_to_refine, cur_block, blocks_ids, block_coords, uacc);
228 });
229 });
230
231 sham::EventList resulting_events{e};
232
233 buf_cell_min.complete_event_state(resulting_events);
234 buf_cell_max.complete_event_state(resulting_events);
235
236 uacc.finalize(resulting_events, pdat);
237
238 refine_flags.complete_event_state(resulting_events);
239 }
240
241 sum_block_count += pdat.get_obj_cnt();
242 new_cell_were_added = new_cell_were_added || refine_flags.get_size() > 0;
243 });
244
245 logger::info_ln("AMRGrid", "process block count =", sum_block_count);
246
247 return new_cell_were_added;
248}
249
250template<class Tvec, class TgridVec>
251template<class UserAcc>
254
255 using namespace shamrock::patch;
256
257 bool cell_were_removed = false;
258
259 sham::DeviceQueue &q = shamsys::instance::get_compute_scheduler().get_queue();
260 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
261
262 scheduler().for_each_patch_data([&](u64 id_patch, Patch cur_p, PatchDataLayer &pdat) {
263 u32 old_obj_cnt = pdat.get_obj_cnt();
264
265 sham::DeviceBuffer<u32> &derefine_flags = dd_derefine_list.get(id_patch);
266
267 if (derefine_flags.get_size() > 0) {
268
269 // init flag table
270 sham::DeviceBuffer<u32> keep_block_flag(old_obj_cnt, dev_sched);
271 keep_block_flag.fill(1);
272
273 sham::DeviceBuffer<TgridVec> &buf_cell_min = pdat.get_field_buf_ref<TgridVec>(0);
274 sham::DeviceBuffer<TgridVec> &buf_cell_max = pdat.get_field_buf_ref<TgridVec>(1);
275
276 sham::EventList depends_list;
277 auto block_bound_low = buf_cell_min.get_write_access(depends_list);
278 auto block_bound_high = buf_cell_max.get_write_access(depends_list);
279 UserAcc uacc(depends_list, pdat);
280 auto index_to_deref = derefine_flags.get_read_access(depends_list);
281 auto flag_keep = keep_block_flag.get_write_access(depends_list);
282
283 // edit block content + make flag of blocks to keep
284 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
285 cgh.parallel_for(sycl::range<1>(derefine_flags.get_size()), [=](sycl::item<1> gid) {
286 u32 tid = gid.get_linear_id();
287
288 u32 idx_to_derefine = index_to_deref[gid];
289
290 // compute old block indexes
291 std::array<u32, split_count> old_indexes;
292#pragma unroll
293 for (u32 pid = 0; pid < split_count; pid++) {
294 old_indexes[pid] = idx_to_derefine + pid;
295 }
296
297 // load block coords
298 std::array<BlockCoord, split_count> block_coords;
299#pragma unroll
300 for (u32 pid = 0; pid < split_count; pid++) {
301 block_coords[pid] = BlockCoord{
302 block_bound_low[old_indexes[pid]], block_bound_high[old_indexes[pid]]};
303 }
304
305 // make new block coord
306 BlockCoord merged_block_coord = BlockCoord::get_merge(block_coords);
307
308 // write new coord
309 block_bound_low[idx_to_derefine] = merged_block_coord.bmin;
310 block_bound_high[idx_to_derefine] = merged_block_coord.bmax;
311
312// flag the old blocks for removal
313#pragma unroll
314 for (u32 pid = 1; pid < split_count; pid++) {
315 flag_keep[idx_to_derefine + pid] = 0;
316 }
317
318 // user lambda to fill the fields
319 uacc.apply_derefine(
320 old_indexes, block_coords, idx_to_derefine, merged_block_coord, uacc);
321 });
322 });
323
324 sham::EventList resulting_events{e};
325
326 buf_cell_min.complete_event_state(resulting_events);
327 buf_cell_max.complete_event_state(resulting_events);
328
329 uacc.finalize(resulting_events, pdat);
330
331 keep_block_flag.complete_event_state(resulting_events);
332 derefine_flags.complete_event_state(resulting_events);
333
334 // stream compact the flags
335 auto buf_keep
336 = shamalgs::numeric::stream_compact(dev_sched, keep_block_flag, old_obj_cnt);
337
338 shamlog_debug_ln(
339 "AMR Grid",
340 "patch",
341 id_patch,
342 "derefine block count ",
343 old_obj_cnt,
344 "->",
345 buf_keep.get_size());
346
347 if (buf_keep.get_size() == 0) {
348 throw std::runtime_error("buf keep must contain something at this point");
349 }
350
351 // remap pdat according to stream compact
352 pdat.index_remap_resize(buf_keep, buf_keep.get_size());
353
354 cell_were_removed = cell_were_removed || derefine_flags.get_size() > 0;
355 }
356 });
357
358 return cell_were_removed;
359}
360
361template<class Tvec, class TgridVec>
362template<class UserAccCrit, class UserAccSplit, class UserAccMerge>
365
366 // Ensure that the blocks are sorted before refinement
367 AMRSortBlocks block_sorter(context, solver_config, storage);
368 block_sorter.reorder_amr_blocks();
369
370 // get refine and derefine list
373
374 gen_refine_block_changes<UserAccCrit>(dd_refine_list, dd_derefine_list);
375
377 // Note that this only add new blocks at the end of the patchdata
378 internal_refine_grid<UserAccSplit>(std::move(dd_refine_list));
379
381 // Note that this will perform the merge then remove the old blocks
382 // This is ok to call straight after the refine without edditing the index list in derefine_list
383 // since no permutations were applied in internal_refine_grid and no cells can be both refined
384 // and derefined in the same pass
385 internal_derefine_grid<UserAccMerge>(std::move(dd_derefine_list));
386}
387
388template<class Tvec, class TgridVec>
391
392 class RefineCritBlock {
393 public:
394 const TgridVec *block_low_bound;
395 const TgridVec *block_high_bound;
396 const Tscal *block_density_field;
397
398 Tscal one_over_Nside = 1. / AMRBlock::Nside;
399
400 Tscal dxfact;
401 Tscal wanted_mass;
402
403 RefineCritBlock(
404 sham::EventList &depends_list,
405 u64 id_patch,
408 Tscal dxfact,
409 Tscal wanted_mass)
410 : dxfact(dxfact), wanted_mass(wanted_mass) {
411
412 block_low_bound = pdat.get_field<TgridVec>(0).get_buf().get_read_access(depends_list);
413 block_high_bound = pdat.get_field<TgridVec>(1).get_buf().get_read_access(depends_list);
414 block_density_field = pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>("rho"))
415 .get_buf()
416 .get_read_access(depends_list);
417 }
418
419 void finalize(
420 sham::EventList &resulting_events,
421 u64 id_patch,
424 Tscal dxfact,
425 Tscal wanted_mass) {
426
427 sham::DeviceBuffer<i64_3> &buf_cell_low_bound = pdat.get_field<i64_3>(0).get_buf();
428 sham::DeviceBuffer<i64_3> &buf_cell_high_bound = pdat.get_field<i64_3>(1).get_buf();
429
430 buf_cell_low_bound.complete_event_state(resulting_events);
431 buf_cell_high_bound.complete_event_state(resulting_events);
432 pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>("rho"))
433 .get_buf()
434 .complete_event_state(resulting_events);
435 }
436
437 void refine_criterion(
438 u32 block_id, RefineCritBlock acc, bool &should_refine, bool &should_derefine) const {
439
440 TgridVec low_bound = acc.block_low_bound[block_id];
441 TgridVec high_bound = acc.block_high_bound[block_id];
442
443 Tvec lower_flt = low_bound.template convert<Tscal>() * dxfact;
444 Tvec upper_flt = high_bound.template convert<Tscal>() * dxfact;
445
446 Tvec block_cell_size = (upper_flt - lower_flt) * one_over_Nside;
447
448 Tscal sum_mass = 0;
449 for (u32 i = 0; i < AMRBlock::block_size; i++) {
450 sum_mass += acc.block_density_field[i + block_id * AMRBlock::block_size];
451 }
452 sum_mass *= block_cell_size.x() * block_cell_size.y() * block_cell_size.z();
453
454 if (sum_mass > wanted_mass * 8) {
455 should_refine = true;
456 should_derefine = false;
457 } else if (sum_mass < wanted_mass) {
458 should_refine = false;
459 should_derefine = true;
460 } else {
461 should_refine = false;
462 should_derefine = false;
463 }
464
465 should_refine = should_refine && (high_bound.x() - low_bound.x() > AMRBlock::Nside);
466 should_refine = should_refine && (high_bound.y() - low_bound.y() > AMRBlock::Nside);
467 should_refine = should_refine && (high_bound.z() - low_bound.z() > AMRBlock::Nside);
468 }
469 };
470
471 class RefineCellAccessor {
472 public:
473 f64 *rho;
474 f64_3 *rho_vel;
475 f64 *rhoE;
476
477 RefineCellAccessor(sham::EventList &depends_list, shamrock::patch::PatchDataLayer &pdat) {
478
479 rho = pdat.get_field<f64>(2).get_buf().get_write_access(depends_list);
480 rho_vel = pdat.get_field<f64_3>(3).get_buf().get_write_access(depends_list);
481 rhoE = pdat.get_field<f64>(4).get_buf().get_write_access(depends_list);
482 }
483
484 void finalize(sham::EventList &resulting_events, shamrock::patch::PatchDataLayer &pdat) {
485 pdat.get_field<f64>(2).get_buf().complete_event_state(resulting_events);
486 pdat.get_field<f64_3>(3).get_buf().complete_event_state(resulting_events);
487 pdat.get_field<f64>(4).get_buf().complete_event_state(resulting_events);
488 }
489
490 void apply_refine(
491 u32 cur_idx,
492 BlockCoord cur_coords,
493 std::array<u32, 8> new_blocks,
494 std::array<BlockCoord, 8> new_block_coords,
495 RefineCellAccessor acc) const {
496
497 auto get_coord_ref = [](u32 i) -> std::array<u32, dim> {
498 constexpr u32 NsideBlockPow = 1;
499 constexpr u32 Nside = 1U << NsideBlockPow;
500
501 if constexpr (dim == 3) {
502 const u32 tmp = i >> NsideBlockPow;
503 return {i % Nside, (tmp) % Nside, (tmp) >> NsideBlockPow};
504 }
505 };
506
507 auto get_index_block = [](std::array<u32, dim> coord) -> u32 {
508 constexpr u32 NsideBlockPow = 1;
509 constexpr u32 Nside = 1U << NsideBlockPow;
510
511 if constexpr (dim == 3) {
512 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2];
513 }
514 };
515
516 auto get_gid_write = [&](std::array<u32, dim> &glid) -> u32 {
517 std::array<u32, dim> bid
518 = {glid[0] >> AMRBlock::NsideBlockPow,
519 glid[1] >> AMRBlock::NsideBlockPow,
520 glid[2] >> AMRBlock::NsideBlockPow};
521
522 // logger::raw_ln(glid,bid);
523 return new_blocks[get_index_block(bid)] * AMRBlock::block_size
524 + AMRBlock::get_index(
525 {glid[0] % AMRBlock::Nside,
526 glid[1] % AMRBlock::Nside,
527 glid[2] % AMRBlock::Nside});
528 };
529
530 std::array<f64, AMRBlock::block_size> old_rho_block;
531 std::array<f64_3, AMRBlock::block_size> old_rho_vel_block;
532 std::array<f64, AMRBlock::block_size> old_rhoE_block;
533
534 // save old block
535 for (u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
536
537 auto [lx, ly, lz] = get_coord_ref(loc_id);
538 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
539 old_rho_block[loc_id] = acc.rho[old_cell_idx];
540 old_rho_vel_block[loc_id] = acc.rho_vel[old_cell_idx];
541 old_rhoE_block[loc_id] = acc.rhoE[old_cell_idx];
542 }
543
544 for (u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
545
546 auto [lx, ly, lz] = get_coord_ref(loc_id);
547 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
548
549 Tscal rho_block = old_rho_block[loc_id];
550 Tvec rho_vel_block = old_rho_vel_block[loc_id];
551 Tscal rhoE_block = old_rhoE_block[loc_id];
552 for (u32 subdiv_lid = 0; subdiv_lid < 8; subdiv_lid++) {
553
554 auto [sx, sy, sz] = get_coord_ref(subdiv_lid);
555
556 std::array<u32, 3> glid = {lx * 2 + sx, ly * 2 + sy, lz * 2 + sz};
557
558 u32 new_cell_idx = get_gid_write(glid);
559 /*
560 if (1627 == cur_idx) {
561 logger::raw_ln(
562 cur_idx,
563 "set cell ",
564 new_cell_idx,
565 " from cell",
566 old_cell_idx,
567 "old",
568 rho_block,
569 rho_vel_block,
570 rhoE_block);
571 }
572 */
573 acc.rho[new_cell_idx] = rho_block;
574 acc.rho_vel[new_cell_idx] = rho_vel_block;
575 acc.rhoE[new_cell_idx] = rhoE_block;
576 }
577 }
578 }
579
580 void apply_derefine(
581 std::array<u32, 8> old_blocks,
582 std::array<BlockCoord, 8> old_coords,
583 u32 new_cell,
584 BlockCoord new_coord,
585
586 RefineCellAccessor acc) const {
587
588 std::array<f64, AMRBlock::block_size> rho_block;
589 std::array<f64_3, AMRBlock::block_size> rho_vel_block;
590 std::array<f64, AMRBlock::block_size> rhoE_block;
591
592 for (u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
593 rho_block[cell_id] = {};
594 rho_vel_block[cell_id] = {};
595 rhoE_block[cell_id] = {};
596 }
597
598 for (u32 pid = 0; pid < 8; pid++) {
599 for (u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
600 rho_block[cell_id] += acc.rho[old_blocks[pid] * AMRBlock::block_size + cell_id];
601 rho_vel_block[cell_id]
602 += acc.rho_vel[old_blocks[pid] * AMRBlock::block_size + cell_id];
603 rhoE_block[cell_id]
604 += acc.rhoE[old_blocks[pid] * AMRBlock::block_size + cell_id];
605 }
606 }
607
608 for (u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
609 rho_block[cell_id] /= 8;
610 rho_vel_block[cell_id] /= 8;
611 rhoE_block[cell_id] /= 8;
612 }
613
614 for (u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
615 u32 newcell_idx = new_cell * AMRBlock::block_size + cell_id;
616 acc.rho[newcell_idx] = rho_block[cell_id];
617 acc.rho_vel[newcell_idx] = rho_vel_block[cell_id];
618 acc.rhoE[newcell_idx] = rhoE_block[cell_id];
619 }
620 }
621 };
622
623 using AMRmode_None = typename AMRMode<Tvec, TgridVec>::None;
624 using AMRmode_DensityBased = typename AMRMode<Tvec, TgridVec>::DensityBased;
625
626 bool has_cell_order_changed = false;
627
628 if (AMRmode_None *cfg = std::get_if<AMRmode_None>(&solver_config.amr_mode.config)) {
629 // no refinment here turn around there is nothing to see
630 } else if (
631 AMRmode_DensityBased *cfg
632 = std::get_if<AMRmode_DensityBased>(&solver_config.amr_mode.config)) {
633 Tscal dxfact(solver_config.grid_coord_to_pos_fact);
634
635 // get refine and derefine list
638
639 gen_refine_block_changes<RefineCritBlock>(
640 refine_list, derefine_list, dxfact, cfg->crit_mass);
641
643 // Note that this only add new blocks at the end of the patchdata
644 bool change_refine = internal_refine_grid<RefineCellAccessor>(std::move(refine_list));
645
647 // Note that this will perform the merge then remove the old blocks
648 // This is ok to call straight after the refine without edditing the index list in
649 // derefine_list since no permutations were applied in internal_refine_grid and no cells can
650 // be both refined and derefined in the same pass
651 bool change_derefine = internal_derefine_grid<RefineCellAccessor>(std::move(derefine_list));
652
653 has_cell_order_changed = has_cell_order_changed || (change_refine || change_derefine);
654 }
655
656 if (has_cell_order_changed) {
657 // Ensure that the blocks are sorted before refinement
658 AMRSortBlocks block_sorter(context, solver_config, storage);
659 block_sorter.reorder_amr_blocks();
660 }
661}
662
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory)
void complete_event_state(sycl::event e) const
Complete the event state of the buffer.
T * get_write_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{})
Get a read-write pointer to the buffer's data.
size_t get_size() const
Gets the number of elements in the buffer.
const T * get_read_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{}) const
Get a read-only pointer to the buffer's data.
A SYCL queue associated with a device and a context.
sycl::event submit(Fct &&fct)
Submits a kernel to the SYCL queue.
DeviceQueue & get_queue(u32 id=0)
Get a reference to a DeviceQueue.
Class to manage a list of SYCL events.
Definition EventList.hpp:31
void add_event(sycl::event e)
Add an event to the list of events.
Definition EventList.hpp:87
Represents a collection of objects distributed across patches identified by a u64 id.
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
PatchDataLayer container class, the layout is described in patchdata_layout.
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...
main include file for the shamalgs algorithms
std::tuple< std::optional< sycl::buffer< u32 > >, u32 > stream_compact(sycl::queue &q, sycl::buffer< u32 > &buf_flags, u32 len)
Stream compaction algorithm.
Definition numeric.cpp:84
std::vector< std::string_view > args
Executable argument list (mapped from argv)
Definition cmdopt.cpp:63
Patch object that contain generic patch information.
Definition Patch.hpp:33
u64 id_patch
unique key that identify the patch
Definition Patch.hpp:86