21#include "nlohmann/json.hpp"
40void PatchScheduler::init_mpi_required_types() {
47void PatchScheduler::free_mpi_required_types() {
55void PatchScheduler::make_patch_base_grid(std::array<u32, dim> patch_count) {
57 static_assert(dim == 3,
"this is not implemented for dim != 3");
59 u32 max_lin_patch_count = 0;
60 for (
u32 i = 0; i < dim; i++) {
61 max_lin_patch_count = sycl::max(max_lin_patch_count, patch_count[i]);
66 u64 sz_root_patch = PatchScheduler::max_axis_patch_coord_length / coord_div_fact;
68 std::vector<shamrock::patch::PatchCoord<3>> coords;
69 for (
u32 x = 0; x < patch_count[0]; x++) {
70 for (
u32 y = 0; y < patch_count[1]; y++) {
71 for (
u32 z = 0; z < patch_count[2]; z++) {
72 shamrock::patch::PatchCoord coord;
74 coord.coord_min[0] = sz_root_patch * (x);
75 coord.coord_min[1] = sz_root_patch * (y);
76 coord.coord_min[2] = sz_root_patch * (z);
77 coord.coord_max[0] = sz_root_patch * (x + 1) - 1;
78 coord.coord_max[1] = sz_root_patch * (y + 1) - 1;
79 coord.coord_max[2] = sz_root_patch * (z + 1) - 1;
81 coords.push_back(coord);
86 shamrock::patch::PatchCoord bounds;
87 bounds.coord_min[0] = 0;
88 bounds.coord_min[1] = 0;
89 bounds.coord_min[2] = 0;
90 bounds.coord_max[0] = sz_root_patch * patch_count[0] - 1;
91 bounds.coord_max[1] = sz_root_patch * patch_count[1] - 1;
92 bounds.coord_max[2] = sz_root_patch * patch_count[2] - 1;
94 get_sim_box().set_patch_coord_bounding_box(bounds);
99template void PatchScheduler::make_patch_base_grid<3>(std::array<u32, 3> patch_count);
104 using namespace shamrock::patch;
106 std::vector<u64> ret;
108 for (
auto coord : coords) {
110 u32 node_owner_id = 0;
116 root.coord_min[0] = coord.coord_min[0];
117 root.coord_min[1] = coord.coord_min[1];
118 root.coord_min[2] = coord.coord_min[2];
119 root.coord_max[0] = coord.coord_max[0];
120 root.coord_max[1] = coord.coord_max[1];
121 root.coord_max[2] = coord.coord_max[2];
129 shamlog_debug_sycl_ln(
"Scheduler",
"adding patch data");
131 shamlog_debug_sycl_ln(
133 "patch data wasn't added rank =",
169 shamlog_debug_ln(
"Scheduler",
"pushing data obj cnt =", pdat.get_obj_cnt());
174 auto variant_main = pdl_old().get_main_field_any();
176 variant_main.visit([&](
auto &arg) {
177 using base_t =
typename std::remove_reference<
decltype(arg)>::type::field_T;
179 if constexpr (shambase::VectorProperties<base_t>::dimension == 3) {
180 auto [bmin, bmax] = get_sim_box().patch_coord_to_domain<base_t>(cur_p);
182 shamlog_debug_sycl_ln(
183 "Scheduler",
"pushing data in patch ", id_patch,
"search range :", bmin, bmax);
187 throw std::runtime_error(
"this does not yet work with dimension different from 3");
194 using namespace shamrock::patch;
197 coord.coord_min[0] = 0;
198 coord.coord_min[1] = 0;
199 coord.coord_min[2] = 0;
200 coord.coord_max[0] = max_axis_patch_coord;
201 coord.coord_max[1] = max_axis_patch_coord;
202 coord.coord_max[2] = max_axis_patch_coord;
209PatchScheduler::PatchScheduler(
210 const std::shared_ptr<shamrock::patch::PatchDataLayerLayout> &pdl_ptr,
215 pdl_ptr, {{0, 0, 0}, {max_axis_patch_coord, max_axis_patch_coord, max_axis_patch_coord}}),
216 synchronized_data() {
218 crit_patch_split = crit_split;
219 crit_patch_merge = crit_merge;
222PatchScheduler::~PatchScheduler() {}
224bool PatchScheduler::should_resize_box(
bool node_in) {
232void PatchScheduler::sync_build_LB(
bool global_patch_sync,
bool balance_load) {
236 if (global_patch_sync)
241 shamrock::scheduler::LoadBalancingChangeList change_list
253std::tuple<f32_3, f32_3> PatchScheduler::get_box_tranform() {
254 if (!pdl_old().check_main_field_type<f32_3>())
256 "cannot query single precision box the main field is not of f32_3 type");
258 auto [bmin, bmax] =
patch_data.sim_box.get_bounding_box<f32_3>();
260 f32_3 translate_factor = bmin;
263 return {translate_factor, scale_factor};
267std::tuple<f64_3, f64_3> PatchScheduler::get_box_tranform() {
268 if (!pdl_old().check_main_field_type<f64_3>())
270 "cannot query single precision box the main field is not of f64_3 type");
272 auto [bmin, bmax] =
patch_data.sim_box.get_bounding_box<f64_3>();
274 f64_3 translate_factor = bmin;
277 return {translate_factor, scale_factor};
281std::tuple<f32_3, f32_3> PatchScheduler::get_box_volume() {
282 if (!pdl_old().check_main_field_type<f32_3>())
284 "cannot query single precision box the main field is not of f32_3 type");
286 return patch_data.sim_box.get_bounding_box<f32_3>();
290std::tuple<f64_3, f64_3> PatchScheduler::get_box_volume() {
291 if (!pdl_old().check_main_field_type<f64_3>())
293 "cannot query single precision box the main field is not of f64_3 type");
295 return patch_data.sim_box.get_bounding_box<f64_3>();
299std::tuple<i64_3, i64_3> PatchScheduler::get_box_volume() {
300 if (!pdl_old().check_main_field_type<i64_3>())
302 "cannot query single precision box the main field is not of i64_3 type");
304 return patch_data.sim_box.get_bounding_box<i64_3>();
313 if (!is_mpi_sycl_interop_active())
315 "sycl mpi interop not initialized");
318 shamlog_debug_ln(
"Scheduler",
"running scheduler step");
320 struct SchedulerStepTimers {
323 std::optional<shambase::Timer> global_idx_map_build = {};
324 std::optional<shambase::Timer> patch_tree_count_reduce = {};
325 std::optional<shambase::Timer> gen_merge_split_rq = {};
326 std::optional<u32_2> split_merge_cnt = {};
327 std::optional<shambase::Timer> apply_splits = {};
328 std::optional<shambase::Timer> load_balance_compute = {};
329 std::optional<u32> load_balance_move_op_cnt = {};
330 std::optional<shambase::Timer> load_balance_apply = {};
335 std::string str =
"";
336 str +=
"Scheduler step timings : ";
337 str += shambase::format(
338 "\n metadata sync : {:<10} ({:2.1f}%)",
341 if (patch_tree_count_reduce) {
342 str += shambase::format(
343 "\n patch tree reduce : {:<10} ({:2.1f}%)",
344 patch_tree_count_reduce->get_time_str(),
345 100 * (patch_tree_count_reduce->nanosec / total));
347 if (gen_merge_split_rq) {
348 str += shambase::format(
349 "\n gen split merge : {:<10} ({:2.1f}%)",
350 gen_merge_split_rq->get_time_str(),
351 100 * (gen_merge_split_rq->nanosec / total));
353 if (split_merge_cnt) {
354 str += shambase::format(
355 "\n split / merge op : {}/{}",
356 split_merge_cnt->x(),
357 split_merge_cnt->y());
360 str += shambase::format(
361 "\n apply split merge : {:<10} ({:2.1f}%)",
362 apply_splits->get_time_str(),
363 100 * (apply_splits->nanosec / total));
365 if (load_balance_compute) {
366 str += shambase::format(
367 "\n LB compute : {:<10} ({:2.1f}%)",
368 load_balance_compute->get_time_str(),
369 100 * (load_balance_compute->nanosec / total));
371 if (load_balance_move_op_cnt) {
372 str += shambase::format(
373 "\n LB move op cnt : {}", *load_balance_move_op_cnt);
375 if (load_balance_apply) {
376 str += shambase::format(
377 "\n LB apply : {:<10} ({:2.1f}%)",
378 load_balance_apply->get_time_str(),
379 100 * (load_balance_apply->nanosec / total));
386 timers.global_timer.
start();
390 timers.metadata_sync.start();
392 timers.metadata_sync.stop();
396 std::unordered_set<u64> split_rq;
397 std::unordered_set<u64> merge_rq;
399 if (do_split_merge) {
404 timers.global_idx_map_build->
start();
407 timers.global_idx_map_build->stop();
413 timers.patch_tree_count_reduce->
start();
415 timers.patch_tree_count_reduce->stop();
421 timers.gen_merge_split_rq->
start();
424 timers.gen_merge_split_rq->stop();
426 timers.split_merge_cnt = u32_2{split_rq.size(), merge_rq.size()};
445 timers.apply_splits->
start();
446 split_patches(split_rq);
447 timers.apply_splits->stop();
454 set_patch_pack_values(merge_rq);
457 if (do_load_balancing) {
460 timers.load_balance_compute->
start();
464 timers.load_balance_compute->stop();
466 timers.load_balance_move_op_cnt = change_list.change_ops.size();
469 timers.load_balance_apply->
start();
472 timers.load_balance_apply->stop();
477 if (do_split_merge) {
479 merge_patches(merge_rq);
492 if (split_rq.size() > 0 || merge_rq.size() > 0) {
498 timers.global_timer.stop();
499 timers.print_stats();
569std::string PatchScheduler::dump_status() {
571 using namespace shamrock::patch;
573 std::stringstream ss;
575 ss <<
"----- MPI Scheduler dump -----\n\n";
576 ss <<
" -> SchedulerPatchList\n";
581 ss <<
" global content : \n";
584 ss <<
" -> " << p.id_patch <<
" : " << p.load_value <<
" " << p.node_owner_id <<
" "
585 << p.pack_node_index <<
" "
586 <<
"( [" << p.coord_min[0] <<
"," << p.coord_max[0] <<
"] "
587 <<
" [" << p.coord_min[1] <<
"," << p.coord_max[1] <<
"] "
588 <<
" [" << p.coord_min[2] <<
"," << p.coord_max[2] <<
"] )\n";
590 ss <<
" local content : \n";
593 ss <<
" -> id : " << p.id_patch <<
" : " << p.load_value <<
" " << p.node_owner_id
594 <<
" " << p.pack_node_index <<
" "
595 <<
"( [" << p.coord_min[0] <<
"," << p.coord_max[0] <<
"] "
596 <<
" [" << p.coord_min[1] <<
"," << p.coord_max[1] <<
"] "
597 <<
" [" << p.coord_min[2] <<
"," << p.coord_max[2] <<
"] )\n";
600 ss << shambase::format(
601 "patch_list.id_patch_to_global_idx :\n{}\n",
patch_list.id_patch_to_global_idx);
602 ss << shambase::format(
603 "patch_list.id_patch_to_local_idx :\n{}\n",
patch_list.id_patch_to_local_idx);
605 ss <<
" -> SchedulerPatchData\n";
606 ss <<
" owned data : \n";
608 patch_data.for_each_patchdata([&](
u64 patch_id, shamrock::patch::PatchDataLayer &pdat) {
609 ss <<
"patch id : " << patch_id <<
" len = " << pdat.get_obj_cnt() <<
"\n";
622 ss <<
" -> SchedulerPatchTree\n";
625 ss << shambase::format(
626 " -> id : {} -> ({}) <=> {} [{}, {}] (cl={} il={} l={} pid={})\n",
628 pnode.tree_node.childs_nid,
629 pnode.linked_patchid,
630 pnode.patch_coord.coord_min,
631 pnode.patch_coord.coord_max,
632 pnode.tree_node.child_are_all_leafs,
633 pnode.tree_node.is_leaf,
634 pnode.tree_node.level,
635 pnode.tree_node.parent_nid);
643 if (pdl_old().check_main_field_type<f32_3>()) {
644 auto [bmin, bmax] =
patch_data.sim_box.patch_coord_to_domain<f32_3>(p);
645 ret = shambase::format(
"coord = {} {}", bmin, bmax);
646 }
else if (pdl_old().check_main_field_type<f64_3>()) {
647 auto [bmin, bmax] =
patch_data.sim_box.patch_coord_to_domain<f64_3>(p);
648 ret = shambase::format(
"coord = {} {}", bmin, bmax);
649 }
else if (pdl_old().check_main_field_type<u32_3>()) {
650 auto [bmin, bmax] =
patch_data.sim_box.patch_coord_to_domain<u32_3>(p);
651 ret = shambase::format(
"coord = {} {}", bmin, bmax);
652 }
else if (pdl_old().check_main_field_type<u64_3>()) {
653 auto [bmin, bmax] =
patch_data.sim_box.patch_coord_to_domain<u64_3>(p);
654 ret = shambase::format(
"coord = {} {}", bmin, bmax);
657 "the main field does not match any");
667 using namespace shamrock::patch;
672 main_field.check_err_range(
673 [&](vec val, vec vmin, vec vmax) {
678 shambase::format(
"patch id = {}", pid));
682void PatchScheduler::check_patchdata_locality_correctness() {
686 if (pdl_old().check_main_field_type<f32_3>()) {
687 check_locality_t<f32_3>(*
this);
688 }
else if (pdl_old().check_main_field_type<f64_3>()) {
689 check_locality_t<f64_3>(*
this);
690 }
else if (pdl_old().check_main_field_type<u32_3>()) {
691 check_locality_t<u32_3>(*
this);
692 }
else if (pdl_old().check_main_field_type<u64_3>()) {
693 check_locality_t<u64_3>(*
this);
694 }
else if (pdl_old().check_main_field_type<i64_3>()) {
695 check_locality_t<i64_3>(*
this);
698 "the main field does not match any");
702void PatchScheduler::split_patches(std::unordered_set<u64> split_rq) {
704 for (
u64 tree_id : split_rq) {
707 PatchTree::Node &splitted_node =
patch_tree.tree[tree_id];
709 shamrock::patch::Patch old_patch
712 auto [idx_p0, idx_p1, idx_p2, idx_p3, idx_p4, idx_p5, idx_p6, idx_p7]
713 =
patch_list.split_patch(splitted_node.linked_patchid);
715 u64 old_patch_id = splitted_node.linked_patchid;
717 splitted_node.linked_patchid =
u64_max;
746 }
catch (
const PatchDataRangeCheckError &e) {
747 logger::err_ln(
"SchedulerPatchData",
"catched range issue with patchdata split");
749 logger::raw_ln(
" old patch", old_patch.
id_patch, format_patch_coord(old_patch));
751 logger::err_ln(
"Scheduler",
"global patch list :");
752 for (shamrock::patch::Patch &p :
patch_list.global) {
753 logger::raw_ln(
" patch", p.id_patch, format_patch_coord(p));
757 "\n Initial error : "
763inline void PatchScheduler::merge_patches(std::unordered_set<u64> merge_rq) {
765 for (
u64 tree_id : merge_rq) {
767 PatchTree::Node &to_merge_node =
patch_tree.tree[tree_id];
806 patch_list.id_patch_to_global_idx[patch_id7]);
810 to_merge_node.linked_patchid = patch_id0;
814inline void PatchScheduler::set_patch_pack_values(std::unordered_set<u64> merge_rq) {
816 for (
u64 tree_id : merge_rq) {
818 PatchTree::Node &to_merge_node =
patch_tree.tree[tree_id];
827 for (
u8 i = 1; i < 8; i++) {
831 [
patch_tree.tree[to_merge_node.get_child_nid(i)].linked_patchid]]
832 .pack_node_index = idx_pack;
837void PatchScheduler::dump_local_patches(std::string filename) {
839 using namespace shamrock::patch;
841 std::ofstream fout(filename);
843 if (pdl_old().check_main_field_type<f32_3>()) {
845 std::tuple<f32_3, f32_3> box_transform = get_box_tranform<f32_3>();
850 = f32_3{p.coord_min[0], p.coord_min[1], p.coord_min[2]} * std::get<1>(box_transform)
851 + std::get<0>(box_transform);
852 f32_3 box_max = (f32_3{p.coord_max[0], p.coord_max[1], p.coord_max[2]} + 1)
853 * std::get<1>(box_transform)
854 + std::get<0>(box_transform);
856 fout << p.id_patch <<
"|" << p.load_value <<
"|" << p.node_owner_id <<
"|"
857 << p.pack_node_index <<
"|" << box_min.x() <<
"|" << box_max.x() <<
"|"
858 << box_min.y() <<
"|" << box_max.y() <<
"|" << box_min.z() <<
"|" << box_max.z()
864 }
else if (pdl_old().check_main_field_type<f64_3>()) {
866 std::tuple<f64_3, f64_3> box_transform = get_box_tranform<f64_3>();
871 = f64_3{p.coord_min[0], p.coord_min[1], p.coord_min[2]} * std::get<1>(box_transform)
872 + std::get<0>(box_transform);
873 f64_3 box_max = (f64_3{p.coord_max[0], p.coord_max[1], p.coord_max[3]} + 1)
874 * std::get<1>(box_transform)
875 + std::get<0>(box_transform);
877 fout << p.id_patch <<
"|" << p.load_value <<
"|" << p.node_owner_id <<
"|"
878 << p.pack_node_index <<
"|" << box_min.x() <<
"|" << box_max.x() <<
"|"
879 << box_min.y() <<
"|" << box_max.y() <<
"|" << box_min.z() <<
"|" << box_max.z()
887 "the chosen type for the main field is not handled");
892 std::unique_ptr<shamcomm::CommunicationBuffer> buf;
897void send_messages(std::vector<Message> &msgs, std::vector<MPI_Request> &rqs) {
898 for (
auto &msg : msgs) {
899 rqs.push_back(MPI_Request{});
900 u32 rq_index = rqs.size() - 1;
901 auto &rq = rqs[rq_index];
903 u64 bsize = msg.buf->get_size();
904 if (bsize % 8 != 0) {
906 "the following mpi comm assume that we can send longs to pack 8byte");
908 u64 lcount = bsize / 8;
924void recv_probe_messages(std::vector<Message> &msgs, std::vector<MPI_Request> &rqs) {
926 for (
auto &msg : msgs) {
927 rqs.push_back(MPI_Request{});
928 u32 rq_index = rqs.size() - 1;
929 auto &rq = rqs[rq_index];
936 msg.buf = std::make_unique<shamcomm::CommunicationBuffer>(
937 cnt * 8, shamsys::instance::get_compute_scheduler_ptr());
940 msg.buf->get_ptr(), cnt, get_mpi_type<u64>(), msg.rank, msg.tag, MPI_COMM_WORLD, &rq);
944std::vector<std::unique_ptr<shamrock::patch::PatchDataLayer>> PatchScheduler::gather_data(
947 using namespace shamrock::patch;
952 auto serializer = [](shamrock::patch::PatchDataLayer &pdat) {
953 shamalgs::SerializeHelper ser(shamsys::instance::get_compute_scheduler_ptr());
954 ser.allocate(pdat.serialize_buf_byte_size());
955 pdat.serialize_buf(ser);
956 return ser.finalize();
959 auto deserializer = [&](sham::DeviceBuffer<u8> &&buf) {
961 shamalgs::SerializeHelper ser(
962 shamsys::instance::get_compute_scheduler_ptr(),
963 std::forward<sham::DeviceBuffer<u8>>(buf));
964 return shamrock::patch::PatchDataLayer::deserialize_buf(ser, get_layout_ptr_old());
967 std::vector<Message> send_payloads;
969 for (
u32 i = 0; i < plist.size(); i++) {
970 auto &cpatch = plist[i];
972 auto &patchdata = pdata.get(cpatch.id_patch);
974 sham::DeviceBuffer<u8> tmp = serializer(patchdata);
976 send_payloads.push_back(
978 .buf = std::make_unique<shamcomm::CommunicationBuffer>(
979 std::move(tmp), shamsys::instance::get_compute_scheduler_ptr()),
985 std::vector<MPI_Request> rqs;
986 send_messages(send_payloads, rqs);
988 std::vector<Message> recv_payloads;
991 for (
u32 i = 0; i < plist.size(); i++) {
992 recv_payloads.push_back(
994 .buf = std::unique_ptr<shamcomm::CommunicationBuffer>{},
995 .rank =
i32(plist[i].node_owner_id),
1001 recv_probe_messages(recv_payloads, rqs);
1003 std::vector<MPI_Status> st_lst(rqs.size());
1006 std::vector<std::unique_ptr<PatchDataLayer>> ret;
1007 for (
auto &recv_msg : recv_payloads) {
1010 sham::DeviceBuffer<u8> buf
1013 ret.push_back(std::make_unique<PatchDataLayer>(deserializer(std::move(buf))));
1019nlohmann::json PatchScheduler::serialize_patch_metadata() {
1021 nlohmann::json jsim_box;
1027 {
"patchdata_layout", pdl_old()},
1028 {
"sim_box", jsim_box},
function to run load balancing with the hilbert curve
Header file describing a Node Instance.
double f64
Alias for double.
std::uint8_t u8
8 bit unsigned integer
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
std::uint16_t u16
16 bit unsigned integer
std::int32_t i32
32 bit integer
void for_each_patch_data(Function &&fct)
for each macro for patchadata example usage
SchedulerPatchData patch_data
handle the data of the patches of the scheduler
u64 crit_patch_split
splitting limit (if load value > crit_patch_split => patch split)
PatchTree patch_tree
handle the tree structure of the patches
void scheduler_step(bool do_split_merge, bool do_load_balancing)
scheduler step
SynchronizedData synchronized_data
data that is synchroneous across all ranks
SchedulerPatchList patch_list
handle the list of the patches of the scheduler
std::unordered_set< u64 > owned_patch_id
(owned_patch_id = patch_list.build_local())
std::vector< u64 > add_root_patches(std::vector< shamrock::patch::PatchCoord< 3 > > coords)
add a root patch to the scheduler
u64 crit_patch_merge
merging limit (if load value < crit_patch_merge => patch merge)
void allpush_data(shamrock::patch::PatchDataLayer &pdat)
push data in the scheduler The content of pdat as to be the same for each node
void add_root_patch()
add patch to the scheduler
std::vector< shamrock::patch::Patch > local
contain the list of patch owned by the current node
std::vector< shamrock::patch::Patch > global
contain the list of all patches in the simulation
Class Timer measures the time elapsed since the timer was started.
std::string get_time_str() const
Converts the stored nanosecond time to a string representation.
void start()
Starts the timer.
f64 nanosec
Time in nanoseconds.
static sham::DeviceBuffer< u8 > convert_usm(CommunicationBuffer &&buf)
destroy the buffer and recover the held object
PatchDataLayer container class, the layout is described in patchdata_layout.
void insert_elements_in_range(PatchDataLayer &pdat, T bmin, T bmax)
insert elements of pdat only if they are within the range
std::tuple< T, T > patch_coord_to_domain(const Patch &p) const
get the patch coordinates on the domain
static LoadBalancingChangeList make_change_list(std::vector< shamrock::patch::Patch > &global_patch_list)
static constexpr u64 max_box_sz
std::array< u64, 8 > childs_nid
Array of childs node ids.
shamrock::patch::SimulationBoxInfo sim_box
simulation box geometry info
This header file contains utility functions related to exception handling in the code.
constexpr T roundup_pow2_clz(T v) noexcept
round up to the next power of two 0 is rounded up to 1 as it is not a pow of 2 every input above the ...
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
std::string increase_indent(std::string in, std::string delim="\n ")
Increase indentation of a string.
auto extract_pointer(std::unique_ptr< T > &o, SourceLocation loc=SourceLocation()) -> T
extract content out of unique_ptr
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
constexpr u64 u64_max
u64 max value
constexpr i32 i32_max
i32 max value
header for PatchData related function and declaration
void info_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
This file contains the definition for the stacktrace related functionality.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
Patch object that contain generic patch information.
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
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...
u32 node_owner_id
node rank owner of this patch
u64 load_value
if synchronized contain the load value of the patch
u64 id_patch
unique key that identify the patch
header file to manage sycl
void Get_count(const MPI_Status *status, MPI_Datatype datatype, int *count)
MPI wrapper for MPI_Get_count.
void Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request)
MPI wrapper for MPI_Irecv.
void Probe(int source, int tag, MPI_Comm comm, MPI_Status *status)
MPI wrapper for MPI_Probe.
void Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
MPI wrapper for MPI_Allreduce.
void Waitall(int count, MPI_Request array_of_requests[], MPI_Status *array_of_statuses)
MPI wrapper for MPI_Waitall.
void Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
MPI wrapper for MPI_Isend.