Interface Documentation
Version: invalid
task_prologue.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_PRIVATE__)
21 #error Do not include this file directly!
22 #endif
23 
24 #include "flecsi/data/accessor.hh"
25 #include "flecsi/data/privilege.hh"
28 #include "flecsi/run/backend.hh"
29 #include "flecsi/topo/global.hh"
33 //#include "flecsi/topo/unstructured/interface.hh"
34 #include "flecsi/util/demangle.hh"
36 
37 #if !defined(FLECSI_ENABLE_LEGION)
38 #error FLECSI_ENABLE_LEGION not defined! This file depends on Legion!
39 #endif
40 
41 #include <legion.h>
42 
43 namespace flecsi {
44 
45 inline log::devel_tag task_prologue_tag("task_prologue");
46 
47 namespace exec::leg {
48 
59 
67  task_prologue_t(const size_t & domain) : domain_(domain) {}
68 
69  std::vector<Legion::RegionRequirement> const & region_requirements() const {
70  return region_reqs_;
71  } // region_requirements
72 
73  std::vector<Legion::Future> && futures() && {
74  return std::move(futures_);
75  } // futures
76 
77  std::vector<Legion::FutureMap> const & future_maps() const {
78  return future_maps_;
79  } // future_maps
80 
87  static Legion::PrivilegeMode privilege_mode(size_t mode) {
88  switch(mode) {
89  case size_t(nu):
90  return WRITE_DISCARD;
91  case size_t(ro):
92  return READ_ONLY;
93  case size_t(wo):
94  return WRITE_DISCARD;
95  case size_t(rw):
96  return READ_WRITE;
97  default:
98  flog_fatal("invalid privilege mode");
99  } // switch
100 
101  return NO_ACCESS;
102  } // privilege_mode
103 
104  template<class P, class... AA>
105  void walk(const AA &... aa) {
106  walk(static_cast<P *>(nullptr), aa...);
107  }
108 
109  /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*
110  The following methods are specializations on layout and client
111  type, potentially for every permutation thereof.
112  *^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
113 
114  template<class T,
115  std::size_t Priv,
116  class Topo,
117  topo::index_space_t<Topo> Space>
118  void visit(data::accessor<data::singular, T, Priv> * null_p,
120  visit(get_null_base(null_p), ref.template cast<data::dense>());
121  }
122 
123  /*--------------------------------------------------------------------------*
124  Global Topology
125  *--------------------------------------------------------------------------*/
126 
127  template<typename DATA_TYPE, size_t PRIVILEGES>
128  void visit(
130  const data::
131  field_reference<DATA_TYPE, data::dense, topo::global, topo::elements> &
132  ref) {
133  Legion::LogicalRegion region = ref.topology().get().logical_region;
134 
135  static_assert(privilege_count(PRIVILEGES) == 1,
136  "global topology accessor type only takes one privilege");
137 
138  constexpr auto priv = get_privilege(0, PRIVILEGES);
139 
140  if(priv > partition_privilege_t::ro)
141  flog_assert(domain_ == 1,
142  "global can only be modified from within single launch task");
143 
144  Legion::RegionRequirement rr(region,
145  priv > partition_privilege_t::ro ? privilege_mode(priv) : READ_ONLY,
146  EXCLUSIVE,
147  region);
148 
149  rr.add_field(ref.fid());
150  region_reqs_.push_back(rr);
151  } // visit
152 
153  template<typename DATA_TYPE,
154  size_t PRIVILEGES,
155  class Topo,
156  topo::index_space_t<Topo> Space,
157  class = std::enable_if_t<topo::privilege_count<Topo, Space> == 1>>
158  void visit(
161  auto & instance_data = ref.topology().get().template get_partition<Space>();
162 
163  flog_assert(instance_data.colors() == domain_,
164  "attempting to pass field with "
165  << instance_data.colors()
166  << " partitions into task with launch domain of size " << domain_);
167 
168  static_assert(privilege_count(PRIVILEGES) == 1,
169  "accessors for this topology type take only one privilege");
170 
171  Legion::RegionRequirement rr(instance_data.logical_partition,
172  0,
173  privilege_mode(get_privilege(0, PRIVILEGES)),
174  EXCLUSIVE,
175  Legion::Runtime::get_runtime()->get_parent_logical_region(
176  instance_data.logical_partition));
177 
178  rr.add_field(ref.fid());
179  region_reqs_.push_back(rr);
180  } // visit
181 
182  template<class Topo, std::size_t Priv>
183  void visit(data::topology_accessor<Topo, Priv> * /* parameter */,
184  const data::topology_slot<Topo> & slot) {
185  Topo::core::fields([&](auto & f) {
186  visit(static_cast<data::field_accessor<decltype(f), Priv> *>(nullptr),
187  f(slot));
188  });
189  }
190 
191  /*--------------------------------------------------------------------------*
192  Futures
193  *--------------------------------------------------------------------------*/
194  template<typename DATA_TYPE>
195  void visit(const future<DATA_TYPE> & f) {
196  futures_.push_back(f.legion_future_);
197  }
198 
199  template<typename DATA_TYPE>
200  void visit(const future<DATA_TYPE, exec::launch_type_t::index> & f) {
201  future_maps_.push_back(f.legion_future_);
202  }
203 
204  /*--------------------------------------------------------------------------*
205  Non-FleCSI Data Types
206  *--------------------------------------------------------------------------*/
207 
208  template<typename DATA_TYPE>
209  static void visit(DATA_TYPE &) {
210  static_assert(!std::is_base_of_v<data::convert_tag, DATA_TYPE>,
211  "Unknown task argument type");
212  {
213  log::devel_guard guard(task_prologue_tag);
214  flog_devel(info) << "Skipping argument with type "
215  << util::type<DATA_TYPE>() << std::endl;
216  }
217  } // visit
218 
219 private:
220  // Argument types for which we don't also need the type of the parameter:
221  template<class P, typename DATA_TYPE>
222  void visit(P *, DATA_TYPE & x) {
223  visit(x);
224  } // visit
225 
226  template<class... PP, class... AA>
227  void walk(std::tuple<PP...> * /* to deduce PP */, const AA &... aa) {
228  (visit(static_cast<std::decay_t<PP> *>(nullptr), aa), ...);
229  }
230 
231  size_t domain_;
232 
233  std::vector<Legion::RegionRequirement> region_reqs_;
234  std::vector<Legion::Future> futures_;
235  std::vector<Legion::FutureMap> future_maps_;
236 }; // task_prologue_t
237 
238 } // namespace exec::leg
239 } // namespace flecsi
static Legion::PrivilegeMode privilege_mode(size_t mode)
Definition: task_prologue.hh:87
Definition: topology_accessor.hh:39
Definition: field.hh:83
task_prologue_t(const size_t &domain)
Definition: task_prologue.hh:67
#define flog_assert(test, message)
Definition: flog.hh:411
constexpr partition_privilege_t get_privilege(std::size_t i, std::size_t pack)
Definition: privilege.hh:88
Definition: flog.hh:82
Definition: topology_slot.hh:30
#define flog_fatal(message)
Definition: flog.hh:358
Definition: launch.hh:95
Definition: task_prologue.hh:58
Definition: field.hh:32
constexpr size_t privilege_count(std::size_t PACK)
Definition: privilege.hh:76
Definition: control.hh:31