18 #include <flecsi-config.h> 20 #if !defined(__FLECSI_PRIVATE__) 21 #error Do not include this file directly! 36 #include <type_traits> 38 #if !defined(FLECSI_ENABLE_LEGION) 39 #error FLECSI_ENABLE_LEGION not defined! This file depends on Legion! 46 inline log::devel_tag execution_tag(
"execution");
63 using nonconst_ref_t =
typename nonconst_ref<T>::type;
69 template<
class... PP,
class... AA>
71 serial_arguments(std::tuple<PP...> * , AA &&... aa) {
72 static_assert((std::is_const_v<std::remove_reference_t<const PP>> && ...),
73 "Tasks cannot accept non-const references");
74 return util::serial_put<std::tuple<std::conditional_t<
75 std::is_constructible_v<nonconst_ref_t<PP> &, nonconst_ref_t<AA>>,
77 std::decay_t<PP>>...>>(
78 {exec::replace_argument<PP>(std::forward<AA>(aa))...});
91 using namespace Legion;
95 using RETURN =
typename traits_t::return_type;
96 using param_tuple =
typename traits_t::arguments_type;
102 auto & flecsi_context = run::context::instance();
105 constexpr
auto processor_type = mask_to_processor_type(ATTRIBUTES);
108 auto legion_runtime = Legion::Runtime::get_runtime();
109 auto legion_context = Legion::Runtime::get_context();
111 #if defined(FLECSI_ENABLE_FLOG) 112 const size_t tasks_executed = flecsi_context.tasks_executed();
113 if((tasks_executed > 0) &&
114 (tasks_executed % FLOG_SERIALIZATION_INTERVAL == 0)) {
116 size_t processes = flecsi_context.processes();
117 LegionRuntime::Arrays::Rect<1> launch_bounds(
118 LegionRuntime::Arrays::Point<1>(0),
119 LegionRuntime::Arrays::Point<1>(processes - 1));
120 Domain launch_domain = Domain::from_rect<1>(launch_bounds);
122 constexpr
auto red = [] {
125 Legion::ArgumentMap arg_map;
126 Legion::IndexLauncher reduction_launcher(leg::task_id<leg::verb<*red>>,
128 Legion::TaskArgument(NULL, 0),
131 Legion::Future
future = legion_runtime->execute_index_space(
132 legion_context, reduction_launcher, reduction_op<fold::max<std::size_t>>);
134 if(future.get_result<
size_t>() > FLOG_SERIALIZATION_THRESHOLD) {
135 constexpr
auto send = [] {
136 run::context::instance().set_mpi_task(log::send_to_one);
138 Legion::IndexLauncher flog_mpi_launcher(leg::task_id<leg::verb<*send>>,
140 Legion::TaskArgument(NULL, 0),
143 flog_mpi_launcher.tag = run::FLECSI_MAPPER_FORCE_RANK_MATCH;
147 legion_runtime->execute_index_space(legion_context, flog_mpi_launcher);
150 future_mpi.wait_all_results(
true);
153 flecsi_context.handoff_to_mpi(legion_context, legion_runtime);
156 flecsi_context.wait_on_mpi(legion_context, legion_runtime);
159 #endif // FLECSI_ENABLE_FLOG 161 size_t domain_size = LAUNCH_DOMAIN.size();
162 domain_size = domain_size == 0 ? flecsi_context.processes() : domain_size;
164 ++flecsi_context.tasks_executed();
166 leg::task_prologue_t pro(domain_size);
167 pro.walk<param_tuple>(args...);
169 std::optional<param_tuple> mpi_args;
170 std::vector<std::byte> buf;
171 if constexpr(processor_type == task_processor_type_t::mpi) {
175 mpi_args.emplace(std::forward<ARGS>(args)...);
176 const auto p = &*mpi_args;
177 buf.resize(
sizeof p);
178 std::memcpy(buf.data(), &p,
sizeof p);
181 buf = detail::serial_arguments(
182 static_cast<param_tuple *>(
nullptr), std::forward<ARGS>(args)...);
189 using wrap = leg::task_wrapper<F, processor_type>;
191 (ATTRIBUTES & ~mpi) | 1 << static_cast<std::size_t>(wrap::LegionProcessor)>;
193 if constexpr(LAUNCH_DOMAIN == single) {
195 static_assert(std::is_void_v<REDUCTION>,
196 "reductions are not supported for single tasks");
200 flog_devel(info) <<
"Executing single task" << std::endl;
203 TaskLauncher launcher(task, TaskArgument(buf.data(), buf.size()));
206 for(
auto & req : pro.region_requirements()) {
207 launcher.add_region_requirement(req);
211 launcher.futures = std::move(pro).futures();
213 static_assert(!(is_index_future<std::decay_t<ARGS>> || ...),
214 "can't use index future with single task");
216 if constexpr(processor_type == task_processor_type_t::toc ||
217 processor_type == task_processor_type_t::loc) {
219 legion_runtime->execute_task(legion_context, launcher)};
223 processor_type == task_processor_type_t::mpi,
"Unknown launch type");
226 <<
"Legion backend does not support 'single' launch" 227 <<
" for MPI tasks yet");
239 flog_devel(info) <<
"Executing index task" << std::endl;
242 LegionRuntime::Arrays::Rect<1> launch_bounds(
243 LegionRuntime::Arrays::Point<1>(0),
244 LegionRuntime::Arrays::Point<1>(domain_size - 1));
245 Domain launch_domain = Domain::from_rect<1>(launch_bounds);
247 Legion::ArgumentMap arg_map;
248 Legion::IndexLauncher launcher(
249 task, launch_domain, TaskArgument(buf.data(), buf.size()), arg_map);
252 for(
auto & req : pro.region_requirements()) {
253 launcher.add_region_requirement(req);
257 launcher.futures = std::move(pro).futures();
258 launcher.point_futures.assign(
259 pro.future_maps().begin(), pro.future_maps().end());
261 if constexpr(processor_type == task_processor_type_t::toc ||
262 processor_type == task_processor_type_t::loc) {
263 flog_devel(info) <<
"Executing index launch on loc" << std::endl;
265 if constexpr(!std::is_void_v<REDUCTION>) {
266 flog_devel(info) <<
"executing reduction logic for " 267 << util::type<REDUCTION>() << std::endl;
270 legion_context, launcher, reduction_op<REDUCTION>)};
274 Legion::FutureMap future_map =
275 legion_runtime->execute_index_space(legion_context, launcher);
282 processor_type == task_processor_type_t::mpi,
"Unknown launch type");
283 launcher.tag = run::FLECSI_MAPPER_FORCE_RANK_MATCH;
287 legion_runtime->execute_index_space(legion_context, launcher)};
292 flecsi_context.handoff_to_mpi(legion_context, legion_runtime);
296 flecsi_context.wait_on_mpi(legion_context, legion_runtime);
298 if constexpr(!std::is_void_v<REDUCTION>) {
300 flog_fatal(
"there is no implementation for the mpi"
decltype(auto) execute(ARGS &&... args)
Definition: execution.hh:382
decltype(auto) reduce(ARGS &&... args)
Definition: policy.hh:90
Definition: function_traits.hh:29
#define flog_fatal(message)
Definition: flog.hh:358
static flog_t & instance()
Definition: state.hh:73
size_t processes()
Definition: execution.hh:294
A launch domain with a static identity but a runtime size.
Definition: launch.hh:62
Definition: control.hh:31