Interface Documentation
Version: invalid
policy.hh
Go to the documentation of this file.
1 /*
2  @@@@@@@@ @@ @@@@@@ @@@@@@@@ @@
3  /@@///// /@@ @@////@@ @@////// /@@
4  /@@ /@@ @@@@@ @@ // /@@ /@@
5  /@@@@@@@ /@@ @@///@@/@@ /@@@@@@@@@/@@
6  /@@//// /@@/@@@@@@@/@@ ////////@@/@@
7  /@@ /@@/@@//// //@@ @@ /@@/@@
8  /@@ @@@//@@@@@@ //@@@@@@ @@@@@@@@ /@@
9  // /// ////// ////// //////// //
10 
11  Copyright (c) 2016, Triad National Security, LLC
12  All rights reserved.
13  */
14 #pragma once
15 
18 #include <flecsi-config.h>
19 
20 #if !defined(FLECSI_ENABLE_LEGION)
21 #error FLECSI_ENABLE_LEGION not defined! This file depends on Legion!
22 #endif
23 
24 #include <flecsi/data/field.hh>
25 
26 #include <hdf5.h>
27 #include <legion.h>
28 
29 namespace flecsi {
30 
31 inline log::devel_tag io_tag("io");
32 
33 namespace io {
34 
35 inline void checkpoint_with_attach_task(const Legion::Task * task,
36  const std::vector<Legion::PhysicalRegion> & regions,
37  Legion::Context ctx,
38  Legion::Runtime * runtime);
39 
40 inline void checkpoint_without_attach_task(const Legion::Task * task,
41  const std::vector<Legion::PhysicalRegion> & regions,
42  Legion::Context ctx,
43  Legion::Runtime * runtime);
44 
45 inline void recover_with_attach_task(const Legion::Task * task,
46  const std::vector<Legion::PhysicalRegion> & regions,
47  Legion::Context ctx,
48  Legion::Runtime * runtime);
49 
50 inline void recover_without_attach_task(const Legion::Task * task,
51  const std::vector<Legion::PhysicalRegion> & regions,
52  Legion::Context ctx,
53  Legion::Runtime * runtime);
54 
55 /*----------------------------------------------------------------------------*
56  HDF5 descriptor of one logical region, not called by users.
57  *----------------------------------------------------------------------------*/
59  legion_hdf5_region_t(Legion::LogicalRegion lr,
60  Legion::LogicalPartition lp,
61  std::string lr_name,
62  std::map<Legion::FieldID, std::string> & field_string_map)
63  : logical_region(lr), logical_partition(lp), logical_region_name(lr_name),
64  field_string_map(field_string_map) {
65  Legion::Runtime * runtime = Legion::Runtime::get_runtime();
66  Legion::Context ctx = Legion::Runtime::get_context();
67  if(lr.get_dim() == 1) {
68  Legion::Domain domain =
69  runtime->get_index_space_domain(ctx, lr.get_index_space());
70  dim_size[0] = domain.get_volume();
71  {
72  log::devel_guard guard(io_tag);
73  flog_devel(info) << "ID logical region size " << dim_size[0]
74  << std::endl;
75  }
76  }
77  else {
78  Legion::Domain domain =
79  runtime->get_index_space_domain(ctx, lr.get_index_space());
80  dim_size[0] = domain.get_volume();
81  {
82  log::devel_guard guard(io_tag);
83  flog_devel(info) << "ID logical region size " << dim_size[0]
84  << std::endl;
85  }
86  }
87  }
88 
89  legion_hdf5_region_t(Legion::LogicalRegion lr,
90  Legion::LogicalPartition lp,
91  std::string lr_name)
92  : logical_region(lr), logical_partition(lp), logical_region_name(lr_name) {}
93 
94  Legion::LogicalRegion logical_region;
95  Legion::LogicalPartition logical_partition;
96  std::string logical_region_name;
97  std::map<Legion::FieldID, std::string> field_string_map;
98  size_t dim_size[3];
99 };
100 
101 /*----------------------------------------------------------------------------*
102  HDF5 file, not called by users.
103  *----------------------------------------------------------------------------*/
105 
106  //----------------------------------------------------------------------------//
107  // Implementation of legion_hdf5_t::legion_hdf5_t.
108  //----------------------------------------------------------------------------//
109  legion_hdf5_t(std::string file_name, int num_files)
110  : hdf5_file_id(-1), file_name(file_name), num_files(num_files) {
111  hdf5_region_vector.clear();
112  hdf5_group_map.clear();
113  {
114  log::devel_guard guard(io_tag);
115  flog_devel(info) << "Init HDF5 file " << file_name << " num_files "
116  << num_files << std::endl;
117  }
118  }
119 
120  //----------------------------------------------------------------------------//
121  // Implementation of legion_hdf5_t::legion_hdf5_t.
122  //----------------------------------------------------------------------------//
123  legion_hdf5_t(const char * file_name, int num_files)
124  : legion_hdf5_t(std::string(file_name), num_files) {}
125 
126  //----------------------------------------------------------------------------//
127  // Implementation of legion_hdf5_t::create_hdf5_file.
128  //----------------------------------------------------------------------------//
129  bool create_hdf5_file(int file_idx) {
130  assert(hdf5_file_id == -1);
131  std::string fname = file_name + std::to_string(file_idx);
132  hdf5_file_id =
133  H5Fcreate(fname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
134  if(hdf5_file_id < 0) {
135  flog(error) << "H5Fcreate failed: " << hdf5_file_id << std::endl;
136  return false;
137  }
138  {
139  log::devel_guard guard(io_tag);
140  flog_devel(info) << "Create HDF5 file " << fname << " file_id "
141  << hdf5_file_id << std::endl;
142  }
143  return true;
144  }
145 
146  //----------------------------------------------------------------------------//
147  // Implementation of legion_hdf5_t:open_hdf5_file.
148  //----------------------------------------------------------------------------//
149  bool open_hdf5_file(int file_idx) {
150  assert(hdf5_file_id == -1);
151  std::string fname = file_name + std::to_string(file_idx);
152  hdf5_file_id = H5Fopen(fname.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
153  if(hdf5_file_id < 0) {
154  flog(error) << "H5Fopen failed: " << hdf5_file_id << std::endl;
155  return false;
156  }
157  {
158  log::devel_guard guard(io_tag);
159  flog_devel(info) << "Open HDF5 file " << fname << " file_id "
160  << hdf5_file_id << std::endl;
161  }
162  return true;
163  }
164 
165  //----------------------------------------------------------------------------//
166  // Implementation of legion_hdf5_t:close_hdf5_file.
167  //----------------------------------------------------------------------------//
168  bool close_hdf5_file() {
169  assert(hdf5_file_id >= 0);
170  H5Fflush(hdf5_file_id, H5F_SCOPE_LOCAL);
171  H5Fclose(hdf5_file_id);
172  {
173  log::devel_guard guard(io_tag);
174  flog_devel(info) << "Close HDF5 file_id " << hdf5_file_id << std::endl;
175  }
176  hdf5_file_id = -1;
177  return true;
178  }
179 
180  //----------------------------------------------------------------------------//
181  // Implementation of legion_hdf5_t::write_string_to_hdf5_file.
182  //----------------------------------------------------------------------------//
183  bool write_string_to_hdf5_file(const char * group_name,
184  const char * dataset_name,
185  const std::string & str,
186  size_t) {
187 
188  assert(hdf5_file_id >= 0);
189 
190  const char * cstr = str.c_str();
191  [[maybe_unused]] herr_t status; // FIXME: report errors
192  // TODO:FIXME
193  // status = H5Eset_auto(NULL, NULL);
194  // status = H5Gget_objinfo (hdf5_file_id, group_name, 0, NULL);
195 
196  hid_t group_id;
197  std::map<std::string, hid_t>::iterator it;
198  it = hdf5_group_map.find(std::string(group_name));
199  if(it != hdf5_group_map.end()) {
200  group_id = H5Gopen2(hdf5_file_id, group_name, H5P_DEFAULT);
201  }
202  else {
203  group_id = H5Gcreate2(
204  hdf5_file_id, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
205  hdf5_group_map[std::string(group_name)] = group_id;
206  }
207  if(group_id < 0) {
208  flog(error) << "H5Gcreate2 failed: " << group_id << std::endl;
209  H5Fclose(hdf5_file_id);
210  return false;
211  }
212 
213  hid_t filetype = H5Tcopy(H5T_C_S1);
214  status = H5Tset_size(filetype, H5T_VARIABLE);
215  hid_t memtype = H5Tcopy(H5T_C_S1);
216  status = H5Tset_size(memtype, H5T_VARIABLE);
217 
218  hsize_t dims[1];
219  dims[0] = 1;
220  hid_t dataspace_id = H5Screate_simple(1, dims, NULL);
221 
222  const char * data[1];
223  data[0] = cstr;
224  hid_t dset = H5Dcreate2(group_id,
225  dataset_name,
226  filetype,
227  dataspace_id,
228  H5P_DEFAULT,
229  H5P_DEFAULT,
230  H5P_DEFAULT);
231  status = H5Dwrite(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
232 
233  H5Fflush(hdf5_file_id, H5F_SCOPE_LOCAL);
234  status = H5Dclose(dset);
235  status = H5Sclose(dataspace_id);
236  status = H5Tclose(filetype);
237  status = H5Tclose(memtype);
238  status = H5Gclose(group_id);
239  return true;
240  }
241 
242  //----------------------------------------------------------------------------//
243  // Implementation of legion_hdf5_t::read_string_from_hdf5_file.
244  //----------------------------------------------------------------------------//
245  bool read_string_from_hdf5_file(const char * group_name,
246  const char * dataset_name,
247  std::string & str) {
248 
249  assert(hdf5_file_id >= 0);
250 
251  [[maybe_unused]] herr_t status; // FIXME: report errors
252  // TODO:FIXME
253  // status = H5Eset_auto(NULL, NULL);
254  // status = H5Gget_objinfo (hdf5_file_id, group_name, 0, NULL);
255 
256  hid_t group_id;
257  group_id = H5Gopen2(hdf5_file_id, group_name, H5P_DEFAULT);
258 
259  if(group_id < 0) {
260  flog(error) << "H5Gcreate2 failed: " << group_id << std::endl;
261  H5Fclose(hdf5_file_id);
262  return false;
263  }
264 
265  hid_t dset = H5Dopen2(group_id, dataset_name, H5P_DEFAULT);
266 
267  hid_t filetype = H5Dget_type(dset);
268  hid_t memtype = H5Tcopy(H5T_C_S1);
269  status = H5Tset_size(memtype, H5T_VARIABLE);
270 
271  char * data[1];
272  status = H5Dread(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
273 
274  str = str + std::string(data[0]);
275  H5Fflush(hdf5_file_id, H5F_SCOPE_LOCAL);
276 
277  hid_t space = H5Dget_space(dset);
278  status = H5Dvlen_reclaim(memtype, space, H5P_DEFAULT, data);
279  status = H5Dclose(dset);
280  status = H5Tclose(filetype);
281  status = H5Tclose(memtype);
282  status = H5Gclose(group_id);
283  return true;
284  }
285 
286  //----------------------------------------------------------------------------//
287  // Implementation of legion_hdf5_t::add_logical_region.
288  //----------------------------------------------------------------------------//
289  void add_logical_region(Legion::LogicalRegion lr,
290  Legion::LogicalPartition lp,
291  std::string lr_name,
292  std::map<Legion::FieldID, std::string> field_string_map) {
293  legion_hdf5_region_t h5_lr(lr, lp, lr_name, field_string_map);
294  hdf5_region_vector.push_back(h5_lr);
295  }
296 
297  //----------------------------------------------------------------------------//
298  // Implementation of legion_hdf5_t::add_hdf5_region.
299  //----------------------------------------------------------------------------//
300  void add_hdf5_region(const legion_hdf5_region_t & hdf5_region) {
301  hdf5_region_vector.push_back(hdf5_region);
302  }
303 
304  //----------------------------------------------------------------------------//
305  // Implementation of legion_hdf5_t::create_datasets_for_regions.
306  //----------------------------------------------------------------------------//
307  bool create_datasets_for_regions(int file_idx) {
308  assert(hdf5_region_vector.size() > 0);
309  assert(hdf5_file_id >= 0);
310 
311  Legion::Runtime * runtime = Legion::Runtime::get_runtime();
312  Legion::Context ctx = Legion::Runtime::get_context();
313 
314  {
315  log::devel_guard guard(io_tag);
316  flog_devel(info) << "Create HDF5 datasets file_id " << hdf5_file_id
317  << " regions size " << hdf5_region_vector.size()
318  << std::endl;
319  }
320 
321  for(legion_hdf5_region_t & lr_it : hdf5_region_vector) {
322 
323  hid_t dataspace_id = -1;
324  if(lr_it.logical_region.get_index_space().get_dim() == 1) {
325  Legion::LogicalRegion sub_lr = runtime->get_logical_subregion_by_color(
326  ctx, lr_it.logical_partition, file_idx);
327  Legion::Domain domain =
328  runtime->get_index_space_domain(ctx, sub_lr.get_index_space());
329  hsize_t dims[1];
330  dims[0] = domain.get_volume();
331  dataspace_id = H5Screate_simple(1, dims, NULL);
332  }
333  else {
334  Legion::LogicalRegion sub_lr = runtime->get_logical_subregion_by_color(
335  ctx, lr_it.logical_partition, file_idx);
336  Legion::Domain domain =
337  runtime->get_index_space_domain(ctx, sub_lr.get_index_space());
338  hsize_t dims[1];
339  dims[0] = domain.get_volume();
340  dataspace_id = H5Screate_simple(1, dims, NULL);
341  }
342  if(dataspace_id < 0) {
343  flog(error) << "H5Screate_simple failed: " << dataspace_id << std::endl;
344  H5Fclose(hdf5_file_id);
345  return false;
346  }
347 #if 0
348  hid_t group_id = H5Gcreate2(file_id, (*lr_it).logical_region_name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
349  if (group_id < 0) {
350  printf("H5Gcreate2 failed: %lld\n", (long long)group_id);
351  H5Sclose(dataspace_id);
352  H5Fclose(hdf5_file_id);
353  return false;
354  }
355 #endif
356  for(std::pair<const Legion::FieldID, std::string> & it :
357  lr_it.field_string_map) {
358  const char * dataset_name = (it.second).c_str();
359  hid_t dataset = H5Dcreate2(hdf5_file_id,
360  dataset_name,
361  H5T_IEEE_F64LE,
362  dataspace_id,
363  H5P_DEFAULT,
364  H5P_DEFAULT,
365  H5P_DEFAULT);
366  if(dataset < 0) {
367  flog(error) << "H5Dcreate2 failed: " << dataset << std::endl;
368  // H5Gclose(group_id);
369  H5Sclose(dataspace_id);
370  H5Fclose(hdf5_file_id);
371  return false;
372  }
373  H5Dclose(dataset);
374  }
375  // H5Gclose(group_id);
376  H5Sclose(dataspace_id);
377  }
378  H5Fflush(hdf5_file_id, H5F_SCOPE_LOCAL);
379  return true;
380  }
381 
382  hid_t hdf5_file_id;
383  std::string file_name;
384  int num_files;
385  std::vector<legion_hdf5_region_t> hdf5_region_vector;
386  std::map<std::string, hid_t> hdf5_group_map;
387 };
388 
389 /*----------------------------------------------------------------------------*
390  Legion HDF5 checkpoint interface.
391  *----------------------------------------------------------------------------*/
392 using hdf5_t = legion_hdf5_t;
394 using launch_space_t = Legion::IndexSpace;
395 
396 inline legion_hdf5_t
397 init_hdf5_file(const char * file_name, int num_files) {
398  return legion_hdf5_t(file_name, num_files);
399 } // init_hdf5_file
400 
401 inline bool
402 create_hdf5_file(legion_hdf5_t & hdf5_file, int file_idx) {
403  return hdf5_file.create_hdf5_file(file_idx);
404 } // create_hdf5_file
405 
406 inline bool
407 open_hdf5_file(legion_hdf5_t & hdf5_file, int file_idx) {
408  return hdf5_file.open_hdf5_file(file_idx);
409 } // open_hdf5_file
410 
411 inline bool
412 close_hdf5_file(legion_hdf5_t & hdf5_file) {
413  return hdf5_file.close_hdf5_file();
414 } // close_hdf5_file
415 
416 inline bool
417 create_datasets_for_regions(legion_hdf5_t & hdf5_file, int file_idx) {
418  return hdf5_file.create_datasets_for_regions(file_idx);
419 } // create_datasets_for_regions
420 
421 inline bool
422 write_string_to_hdf5_file(legion_hdf5_t & hdf5_file,
423  int,
424  const char * group_name,
425  const char * dataset_name,
426  const std::string & str,
427  size_t size) {
428  return hdf5_file.write_string_to_hdf5_file(
429  group_name, dataset_name, str, size);
430 } // write_string_to_hdf5_file
431 
432 inline bool
433 read_string_from_hdf5_file(legion_hdf5_t & hdf5_file,
434  int,
435  const char * group_name,
436  const char * dataset_name,
437  std::string & str) {
438  return hdf5_file.read_string_from_hdf5_file(group_name, dataset_name, str);
439 } // read_string_from_hdf5_file
440 
441 inline void
442 add_regions(legion_hdf5_t & hdf5_file,
443  std::vector<legion_hdf5_region_t> & hdf5_region_vector) {
444  for(auto & r : hdf5_region_vector)
445  hdf5_file.add_hdf5_region(r);
446 } // add_regions
447 
448 inline void
449 generate_hdf5_files(legion_hdf5_t & hdf5_file) {
450  for(int i = 0; i < hdf5_file.num_files; i++) {
451  hdf5_file.create_hdf5_file(i);
452  hdf5_file.create_datasets_for_regions(i);
453  hdf5_file.close_hdf5_file();
454  }
455 } // generate_hdf5_files
456 
457 inline void
458 checkpoint_data(legion_hdf5_t & hdf5_file,
459  Legion::IndexSpace launch_space,
460  std::vector<legion_hdf5_region_t> & hdf5_region_vector,
461  bool attach_flag) {
462  std::string file_name = hdf5_file.file_name;
463 
464  Legion::Runtime * runtime = Legion::Runtime::get_runtime();
465  Legion::Context ctx = Legion::Runtime::get_context();
466 
467  std::vector<std::map<Legion::FieldID, std::string>> field_string_map_vector;
468  for(legion_hdf5_region_t & it : hdf5_region_vector) {
469  field_string_map_vector.push_back(it.field_string_map);
470  }
471 
472  std::vector<std::byte> task_args;
473  task_args = util::serial_put(std::tie(field_string_map_vector, file_name));
474 
475  auto task_id =
476  attach_flag
477  ? exec::leg::task_id<checkpoint_with_attach_task, loc | inner>
478  : exec::leg::task_id<checkpoint_without_attach_task, loc | leaf>;
479 
480  Legion::IndexLauncher checkpoint_launcher(task_id,
481  launch_space,
482  Legion::TaskArgument((void *)(task_args.data()), task_args.size()),
483  Legion::ArgumentMap());
484 
485  int idx = 0;
486  for(legion_hdf5_region_t & it : hdf5_region_vector) {
487  checkpoint_launcher.add_region_requirement(
488  Legion::RegionRequirement(it.logical_partition,
489  0 /*projection ID*/,
490  READ_ONLY,
491  EXCLUSIVE,
492  it.logical_region));
493 
494  std::map<Legion::FieldID, std::string> & field_string_map =
495  it.field_string_map;
496  for(std::pair<const Legion::FieldID, std::string> & it : field_string_map) {
497  checkpoint_launcher.region_requirements[idx].add_field(it.first);
498  }
499  idx++;
500  }
501 
502  {
503  log::devel_guard guard(io_tag);
504  flog_devel(info) << "Start checkpoint file " << file_name
505  << " regions size " << hdf5_region_vector.size()
506  << std::endl;
507  }
508 
509  Legion::FutureMap fumap =
510  runtime->execute_index_space(ctx, checkpoint_launcher);
511  fumap.wait_all_results();
512 } // checkpoint_data
513 
514 inline void
515 recover_data(legion_hdf5_t & hdf5_file,
516  Legion::IndexSpace launch_space,
517  std::vector<legion_hdf5_region_t> & hdf5_region_vector,
518  bool attach_flag) {
519  std::string file_name = hdf5_file.file_name;
520 
521  Legion::Runtime * runtime = Legion::Runtime::get_runtime();
522  Legion::Context ctx = Legion::Runtime::get_context();
523 
524  std::vector<std::map<Legion::FieldID, std::string>> field_string_map_vector;
525  for(legion_hdf5_region_t & it : hdf5_region_vector) {
526  field_string_map_vector.push_back(it.field_string_map);
527  }
528 
529  std::vector<std::byte> task_args;
530  task_args = util::serial_put(std::tie(field_string_map_vector, file_name));
531 
532  auto task_id =
533  attach_flag ? exec::leg::task_id<recover_with_attach_task, loc | inner>
534  : exec::leg::task_id<recover_without_attach_task, loc | leaf>;
535 
536  Legion::IndexLauncher recover_launcher(task_id,
537  launch_space,
538  Legion::TaskArgument((void *)(task_args.data()), task_args.size()),
539  Legion::ArgumentMap());
540  int idx = 0;
541  for(legion_hdf5_region_t & it : hdf5_region_vector) {
542  recover_launcher.add_region_requirement(
543  Legion::RegionRequirement(it.logical_partition,
544  0 /*projection ID*/,
545  WRITE_DISCARD,
546  EXCLUSIVE,
547  it.logical_region));
548 
549  std::map<Legion::FieldID, std::string> & field_string_map =
550  it.field_string_map;
551  for(std::pair<const Legion::FieldID, std::string> & it : field_string_map) {
552  recover_launcher.region_requirements[idx].add_field(it.first);
553  }
554  idx++;
555  }
556 
557  {
558  log::devel_guard guard(io_tag);
559  flog_devel(info) << "Start recover file " << file_name << " regions size "
560  << hdf5_region_vector.size() << std::endl;
561  }
562 
563  Legion::FutureMap fumap = runtime->execute_index_space(ctx, recover_launcher);
564  fumap.wait_all_results();
565 } // recover_data
566 
568  void add_process_topology(legion_hdf5_t & hdf5_file) {
569  auto & index_runtime_data = process_topology.get();
570 
571  std::map<Legion::FieldID, std::string> field_string_map;
572 
573  for(const auto p :
574  run::context::instance().get_field_info_store<topo::index>()) {
575  field_string_map[p->fid] = std::to_string(p->fid);
576  }
577 
578  Legion::Runtime * runtime = Legion::Runtime::get_runtime();
579  Legion::Context ctx = Legion::Runtime::get_context();
580  Legion::Rect<1> file_color_bounds(0, hdf5_file.num_files - 1);
581  data::leg::unique_index_space process_topology_file_is =
582  runtime->create_index_space(ctx, file_color_bounds);
583 #if 0
584  process_topology_file_ip = runtime->create_pending_partition(ctx, index_runtime_data.index_space, process_topology_file_is);
585  int idx = 0;
586  int num_subregions = index_runtime_data.colors;
587  for (int point = 0; point < hdf5_file.num_files; point++) {
588  std::vector<IndexSpace> subspaces;
589  for (int i = 0; i < num_subregions/hdf5_file.num_files; i++) {
590  subspaces.push_back(runtime->get_index_subspace(ctx, index_runtime_data.color_partition.get_index_partition(), idx));
591  idx ++;
592  }
593  runtime->create_index_space_union(ctx, process_topology_file_ip, point, subspaces);
594  }
595 #else
596  data::leg::unique_index_partition process_topology_file_ip =
597  runtime->create_equal_partition(
598  ctx, index_runtime_data.index_space, process_topology_file_is);
599 #endif
600  data::leg::unique_logical_partition process_topology_file_lp =
601  runtime->get_logical_partition(
602  ctx, index_runtime_data.logical_region, process_topology_file_ip);
603  hdf5_file.add_logical_region(index_runtime_data.logical_region,
604  process_topology_file_lp,
605  "null",
606  field_string_map);
607 
608  file_map[&index_runtime_data] = {std::move(process_topology_file_is),
609  std::move(process_topology_file_ip),
610  std::move(process_topology_file_lp)};
611  } // add_process_topology
612 
613  void checkpoint_process_topology(legion_hdf5_t & hdf5_file) {
614  auto const & fid_vector =
615  run::context::instance().get_field_info_store<topo::index>();
616 
617  auto & index_runtime_data = process_topology.get();
618  {
619  log::devel_guard guard(io_tag);
620  flog_devel(info) << "Checkpoint default index topology, fields size "
621  << fid_vector.size() << std::endl;
622  }
623 
624  const auto & file = file_map[&index_runtime_data];
625  legion_hdf5_region_t checkpoint_region(index_runtime_data.logical_region,
626  file.logical_partition,
627  "process_topology");
628  for(const auto p : fid_vector) {
629  checkpoint_region.field_string_map[p->fid] = std::to_string(p->fid);
630  }
631 
632  std::vector<legion_hdf5_region_t> hdf5_region_vector;
633  hdf5_region_vector.push_back(checkpoint_region);
634  checkpoint_data(hdf5_file, file.index_space, hdf5_region_vector, true);
635  } // checkpoint_process_topology
636 
637  // void checkpoint_index_topology(legion_hdf5_t & hdf5_file, const
638  // flecsi::util::const_string_t &index_topology_name);
639 
640  void checkpoint_index_topology_field(hdf5_t & hdf5_file,
641  const field_reference_t & fh) {
642  const size_t fid = fh.fid();
643  auto & index_runtime_data = fh.topology().get();
644 
645  {
646  log::devel_guard guard(io_tag);
647  flog_devel(info) << "Checkpoint index topology, field " << fid
648  << std::endl;
649  }
650 
651  const auto & file = file_map[&index_runtime_data];
652  legion_hdf5_region_t checkpoint_region(index_runtime_data.logical_region,
653  file.logical_partition,
654  "process_topology");
655  checkpoint_region.field_string_map[fid] = std::to_string(fid);
656 
657  std::vector<legion_hdf5_region_t> hdf5_region_vector;
658  hdf5_region_vector.push_back(checkpoint_region);
659  checkpoint_data(hdf5_file, file.index_space, hdf5_region_vector, true);
660  } // checkpoint_index_topology_field
661 
662  void recover_process_topology(legion_hdf5_t & hdf5_file) {
663  auto const & fid_vector =
664  run::context::instance().get_field_info_store<topo::index>();
665 
666  auto & index_runtime_data = process_topology.get();
667 
668  {
669  log::devel_guard guard(io_tag);
670  flog_devel(info) << "Recover default index topology, fields size "
671  << fid_vector.size() << std::endl;
672  }
673 
674  const auto & file = file_map[&index_runtime_data];
675  legion_hdf5_region_t recover_region(index_runtime_data.logical_region,
676  file.logical_partition,
677  "process_topology");
678  for(const auto p : fid_vector) {
679  recover_region.field_string_map[p->fid] = std::to_string(p->fid);
680  }
681 
682  std::vector<legion_hdf5_region_t> hdf5_region_vector;
683  hdf5_region_vector.push_back(recover_region);
684  recover_data(hdf5_file, file.index_space, hdf5_region_vector, true);
685  } // recover_process_topology
686 
687  void recover_index_topology_field(hdf5_t & hdf5_file,
688  const field_reference_t & fh) {
689  const size_t fid = fh.fid();
690  auto & index_runtime_data = fh.topology().get();
691 
692  {
693  log::devel_guard guard(io_tag);
694  flog_devel(info) << "Recover index topology, field " << fid << std::endl;
695  }
696 
697  const auto & file = file_map[&index_runtime_data];
698  legion_hdf5_region_t recover_region(index_runtime_data.logical_region,
699  file.logical_partition,
700  "index_topology");
701  recover_region.field_string_map[fid] = std::to_string(fid);
702 
703  std::vector<legion_hdf5_region_t> hdf5_region_vector;
704  hdf5_region_vector.push_back(recover_region);
705  recover_data(hdf5_file, file.index_space, hdf5_region_vector, true);
706  } // recover_index_topology_field
707 
708 private:
709  struct topology_data {
710  data::leg::unique_index_space index_space;
711  data::leg::unique_index_partition index_partition;
712  data::leg::unique_logical_partition logical_partition;
713  };
714  std::map<const topo::index::core *, topology_data> file_map;
715 };
716 
717 inline void
718 checkpoint_with_attach_task(const Legion::Task * task,
719  const std::vector<Legion::PhysicalRegion> & regions,
720  Legion::Context ctx,
721  Legion::Runtime * runtime) {
722 
723  const int point = task->index_point.point_data[0];
724 
725  const std::byte * task_args = (const std::byte *)task->args;
726 
727  std::vector<std::map<Legion::FieldID, std::string>> field_string_map_vector;
728 
729  field_string_map_vector =
730  util::serial_get<std::vector<std::map<Legion::FieldID, std::string>>>(
731  task_args);
732 
733  std::string fname = util::serial_get<std::string>(task_args);
734 
735  fname = fname + std::to_string(point);
736  char * file_name = const_cast<char *>(fname.c_str());
737 
738  for(unsigned int rid = 0; rid < regions.size(); rid++) {
739  Legion::PhysicalRegion attach_dst_pr;
740  Legion::LogicalRegion input_lr = regions[rid].get_logical_region();
741  Legion::LogicalRegion attach_dst_lr = runtime->create_logical_region(
742  ctx, input_lr.get_index_space(), input_lr.get_field_space());
743 
744  Legion::AttachLauncher hdf5_attach_launcher(
745  EXTERNAL_HDF5_FILE, attach_dst_lr, attach_dst_lr);
746  std::map<Legion::FieldID, const char *> field_map;
747  std::set<Legion::FieldID> field_set = task->regions[rid].privilege_fields;
748  std::map<Legion::FieldID, std::string>::iterator map_it;
749  for(Legion::FieldID it : field_set) {
750  map_it = field_string_map_vector[rid].find(it);
751  if(map_it != field_string_map_vector[rid].end()) {
752  field_map.insert(std::make_pair(it, (map_it->second).c_str()));
753  }
754  else {
755  assert(0);
756  }
757  }
758 
759  {
760  log::devel_guard guard(io_tag);
761  flog_devel(info) << "Checkpoint data to HDF5 file attach " << file_name
762  << " region_id " << rid
763  << " (dataset(fid) size= " << field_map.size() << ")"
764  << " field_string_map_vector(regions) size "
765  << field_string_map_vector.size() << std::endl;
766  }
767 
768  hdf5_attach_launcher.attach_hdf5(
769  file_name, field_map, LEGION_FILE_READ_WRITE);
770  attach_dst_pr =
771  runtime->attach_external_resource(ctx, hdf5_attach_launcher);
772  // cp_pr.wait_until_valid();
773 
774  Legion::CopyLauncher copy_launcher1;
775  copy_launcher1.add_copy_requirements(
776  Legion::RegionRequirement(input_lr, READ_ONLY, EXCLUSIVE, input_lr),
777  Legion::RegionRequirement(
778  attach_dst_lr, WRITE_DISCARD, EXCLUSIVE, attach_dst_lr));
779  for(Legion::FieldID it : field_set) {
780  copy_launcher1.add_src_field(0, it);
781  copy_launcher1.add_dst_field(0, it);
782  }
783  runtime->issue_copy_operation(ctx, copy_launcher1);
784 
785  Legion::Future fu =
786  runtime->detach_external_resource(ctx, attach_dst_pr, true);
787  fu.wait();
788  runtime->destroy_logical_region(ctx, attach_dst_lr);
789  }
790 } // checkpoint_with_attach_task
791 
792 inline void
793 checkpoint_without_attach_task(const Legion::Task * task,
794  const std::vector<Legion::PhysicalRegion> & regions,
795  Legion::Context ctx,
796  Legion::Runtime * runtime) {
797 
798  const int point = task->index_point.point_data[0];
799 
800  const std::byte * task_args = (const std::byte *)task->args;
801 
802  std::vector<std::map<Legion::FieldID, std::string>> field_string_map_vector;
803 
804  field_string_map_vector =
805  util::serial_get<std::vector<std::map<Legion::FieldID, std::string>>>(
806  task_args);
807 
808  std::string fname = util::serial_get<std::string>(task_args);
809 
810  fname = fname + std::to_string(point);
811  char * file_name = const_cast<char *>(fname.c_str());
812 
813  hid_t file_id;
814  file_id = H5Fopen(file_name, H5F_ACC_RDWR, H5P_DEFAULT);
815  if(file_id < 0) {
816  flog(error) << "H5Fopen failed: " << file_id << std::endl;
817  assert(0);
818  }
819 
820  for(unsigned int rid = 0; rid < regions.size(); rid++) {
821  std::set<Legion::FieldID> field_set = task->regions[rid].privilege_fields;
822  std::map<Legion::FieldID, std::string>::iterator map_it;
823  for(Legion::FieldID it : field_set) {
824  map_it = field_string_map_vector[rid].find(it);
825  if(map_it != field_string_map_vector[rid].end()) {
826  const Legion::FieldAccessor<READ_ONLY,
827  double,
828  1,
829  Legion::coord_t,
830  Realm::AffineAccessor<double, 1, Legion::coord_t>>
831  acc_fid(regions[rid], it);
832  Legion::Rect<1> rect = runtime->get_index_space_domain(
833  ctx, task->regions[rid].region.get_index_space());
834  const double * dset_data = acc_fid.ptr(rect.lo);
835  hid_t dataset_id =
836  H5Dopen2(file_id, (map_it->second).c_str(), H5P_DEFAULT);
837  if(dataset_id < 0) {
838  flog(error) << "H5Dopen2 failed: " << dataset_id << std::endl;
839  H5Fclose(file_id);
840  assert(0);
841  }
842  H5Dwrite(
843  dataset_id, H5T_IEEE_F64LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_data);
844  H5Dclose(dataset_id);
845  }
846  else {
847  assert(0);
848  }
849  }
850 
851  {
852  log::devel_guard guard(io_tag);
853  flog_devel(info) << "Checkpoint data to HDF5 file no attach " << file_name
854  << " region_id " << rid
855  << " (dataset(fid) size= " << field_set.size() << ")"
856  << " field_string_map_vector(regions) size "
857  << field_string_map_vector.size() << std::endl;
858  }
859  }
860 
861  H5Fflush(file_id, H5F_SCOPE_LOCAL);
862  H5Fclose(file_id);
863 } // checkpoint_without_attach_task
864 
865 inline void
866 recover_with_attach_task(const Legion::Task * task,
867  const std::vector<Legion::PhysicalRegion> & regions,
868  Legion::Context ctx,
869  Legion::Runtime * runtime) {
870  const int point = task->index_point.point_data[0];
871 
872  const std::byte * task_args = (const std::byte *)task->args;
873 
874  std::vector<std::map<Legion::FieldID, std::string>> field_string_map_vector;
875 
876  field_string_map_vector =
877  util::serial_get<std::vector<std::map<Legion::FieldID, std::string>>>(
878  task_args);
879 
880  std::string fname = util::serial_get<std::string>(task_args);
881 
882  fname = fname + std::to_string(point);
883  char * file_name = const_cast<char *>(fname.c_str());
884 
885  for(unsigned int rid = 0; rid < regions.size(); rid++) {
886  Legion::PhysicalRegion attach_src_pr;
887  Legion::LogicalRegion output_lr = regions[rid].get_logical_region();
888  Legion::LogicalRegion attach_src_lr = runtime->create_logical_region(
889  ctx, output_lr.get_index_space(), output_lr.get_field_space());
890 
891  Legion::AttachLauncher hdf5_attach_launcher(
892  EXTERNAL_HDF5_FILE, attach_src_lr, attach_src_lr);
893  std::map<Legion::FieldID, const char *> field_map;
894  std::set<Legion::FieldID> field_set = task->regions[rid].privilege_fields;
895  std::map<Legion::FieldID, std::string>::iterator map_it;
896  for(Legion::FieldID it : field_set) {
897  map_it = field_string_map_vector[rid].find(it);
898  if(map_it != field_string_map_vector[rid].end()) {
899  field_map.insert(std::make_pair(it, (map_it->second).c_str()));
900  }
901  else {
902  assert(0);
903  }
904  }
905 
906  {
907  log::devel_guard guard(io_tag);
908  flog_devel(info) << "Recorver data to HDF5 file attach " << file_name
909  << " region_id " << rid
910  << " (dataset(fid) size= " << field_map.size() << ")"
911  << " field_string_map_vector(regions) size "
912  << field_string_map_vector.size() << std::endl;
913  }
914 
915  hdf5_attach_launcher.attach_hdf5(
916  file_name, field_map, LEGION_FILE_READ_WRITE);
917  attach_src_pr =
918  runtime->attach_external_resource(ctx, hdf5_attach_launcher);
919 
920  Legion::CopyLauncher copy_launcher2;
921  copy_launcher2.add_copy_requirements(
922  Legion::RegionRequirement(
923  attach_src_lr, READ_ONLY, EXCLUSIVE, attach_src_lr),
924  Legion::RegionRequirement(
925  output_lr, WRITE_DISCARD, EXCLUSIVE, output_lr));
926  for(Legion::FieldID it : field_set) {
927  copy_launcher2.add_src_field(0, it);
928  copy_launcher2.add_dst_field(0, it);
929  }
930  runtime->issue_copy_operation(ctx, copy_launcher2);
931 
932  Legion::Future fu =
933  runtime->detach_external_resource(ctx, attach_src_pr, true);
934  fu.wait();
935  runtime->destroy_logical_region(ctx, attach_src_lr);
936  }
937 } // recover_with_attach_task
938 
939 inline void
940 recover_without_attach_task(const Legion::Task * task,
941  const std::vector<Legion::PhysicalRegion> & regions,
942  Legion::Context ctx,
943  Legion::Runtime * runtime) {
944  const int point = task->index_point.point_data[0];
945 
946  const std::byte * task_args = (const std::byte *)task->args;
947 
948  std::vector<std::map<Legion::FieldID, std::string>> field_string_map_vector;
949 
950  field_string_map_vector =
951  util::serial_get<std::vector<std::map<Legion::FieldID, std::string>>>(
952  task_args);
953 
954  std::string fname = util::serial_get<std::string>(task_args);
955 
956  fname = fname + std::to_string(point);
957  char * file_name = const_cast<char *>(fname.c_str());
958 
959  hid_t file_id;
960  file_id = H5Fopen(file_name, H5F_ACC_RDWR, H5P_DEFAULT);
961  if(file_id < 0) {
962  flog(error) << "H5Fopen failed: " << file_id << std::endl;
963  assert(0);
964  }
965 
966  for(unsigned int rid = 0; rid < regions.size(); rid++) {
967  std::set<Legion::FieldID> field_set = task->regions[rid].privilege_fields;
968  std::map<Legion::FieldID, std::string>::iterator map_it;
969  for(Legion::FieldID it : field_set) {
970  map_it = field_string_map_vector[rid].find(it);
971  if(map_it != field_string_map_vector[rid].end()) {
972  const Legion::FieldAccessor<WRITE_DISCARD,
973  double,
974  1,
975  Legion::coord_t,
976  Realm::AffineAccessor<double, 1, Legion::coord_t>>
977  acc_fid(regions[rid], it);
978  Legion::Rect<1> rect = runtime->get_index_space_domain(
979  ctx, task->regions[rid].region.get_index_space());
980  double * dset_data = acc_fid.ptr(rect.lo);
981  hid_t dataset_id =
982  H5Dopen2(file_id, (map_it->second).c_str(), H5P_DEFAULT);
983  if(dataset_id < 0) {
984  flog(error) << "H5Dopen2 failed: " << dataset_id << std::endl;
985  H5Fclose(file_id);
986  assert(0);
987  }
988  H5Dread(
989  dataset_id, H5T_IEEE_F64LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset_data);
990  H5Dclose(dataset_id);
991  }
992  else {
993  assert(0);
994  }
995  }
996 
997  {
998  log::devel_guard guard(io_tag);
999  flog_devel(info) << "Checkpoint data to HDF5 file no attach " << file_name
1000  << " region_id " << rid
1001  << " (dataset(fid) size= " << field_set.size() << ")"
1002  << " field_string_map_vector(regions) size "
1003  << field_string_map_vector.size() << std::endl;
1004  }
1005  }
1006 } // recover_without_attach_task
1007 
1008 } // namespace io
1009 } // namespace flecsi
#define flog(severity)
Definition: flog.hh:136
Definition: policy.hh:567
Definition: policy.hh:58
Definition: flog.hh:82
Definition: index.hh:64
Definition: field.hh:57
Definition: policy.hh:104
Definition: control.hh:31