diff --git a/examples/attach_file/Makefile b/examples/attach_file/Makefile index ce5827f128..69ae89f1db 100644 --- a/examples/attach_file/Makefile +++ b/examples/attach_file/Makefile @@ -23,7 +23,7 @@ DEBUG ?= 1 # Include debugging symbols OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level USE_CUDA ?= 0 # Include CUDA support (requires CUDA) USE_GASNET ?= 0 # Include GASNet support (requires GASNet) -USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +USE_HDF ?= 1 # Include HDF5 support (requires HDF5) ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) # Put the binary file name here diff --git a/examples/attach_file/attach_file.cc b/examples/attach_file/attach_file.cc index dab74d5fb1..f988643e51 100644 --- a/examples/attach_file/attach_file.cc +++ b/examples/attach_file/attach_file.cc @@ -462,4 +462,4 @@ int main(int argc, char **argv) } return Runtime::start(argc, argv); -} +} \ No newline at end of file diff --git a/runtime/legion/legion_c.cc b/runtime/legion/legion_c.cc index 2e2a8b2adb..30fae7b865 100644 --- a/runtime/legion/legion_c.cc +++ b/runtime/legion/legion_c.cc @@ -6279,3 +6279,39 @@ legion_mapper_runtime_acquire_instances( instances.push_back(*CObjectWrapper::unwrap(instances_[idx])); return runtime->acquire_instances(ctx, instances); } + +legion_physical_region_t +legion_get_physical_region_by_id( + legion_physical_region_t *regionptr, + int id, + int num_regions) +{ + assert(id < num_regions); + return regionptr[id]; +} + +legion_index_space_t +legion_logical_region_get_index_space(legion_logical_region_t lr_) +{ + LogicalRegion lr = CObjectWrapper::unwrap(lr_); + return CObjectWrapper::wrap(lr.get_index_space()); +} + +legion_index_space_t +legion_task_get_index_space_from_logical_region( + legion_task_t task, unsigned idx) +{ + legion_region_requirement_t req = legion_task_get_region(task, idx); + legion_logical_region_t lr = legion_region_requirement_get_region(req); + return legion_logical_region_get_index_space(lr); +} + +void +legion_convert_1d_to_2d_column_major( + void *src, void *dst[], legion_byte_offset_t offset, int num_columns) +{ + int i; + for (i = 0; i < num_columns; i++) { + dst[i] = (void*)((unsigned char*)src + offset.offset * i); + } +} \ No newline at end of file diff --git a/runtime/legion/legion_c.h b/runtime/legion/legion_c.h index 5487e11ef3..820fb8f05a 100644 --- a/runtime/legion/legion_c.h +++ b/runtime/legion/legion_c.h @@ -1661,6 +1661,11 @@ extern "C" { legion_logical_region_t handle, const char **result); + /** + * @see Legion::LogicalRegion::get_index_space + */ + legion_index_space_t + legion_logical_region_get_index_space(legion_logical_region_t handle); // ----------------------------------------------------------------------- // Logical Region Tree Traversal Operations // ----------------------------------------------------------------------- @@ -4754,7 +4759,31 @@ extern "C" { legion_mapper_context_t ctx, legion_physical_instance_t *instances, size_t instances_size); + + /** + * used by fortran API + */ + legion_physical_region_t + legion_get_physical_region_by_id( + legion_physical_region_t *regionptr, + int id, + int num_regions); + + // ----------------------------------------------------------------------- + // Combined Operations (combined of some functions) + // ----------------------------------------------------------------------- + + /** + * @see Legion::Task::RegionRequirement::LogicalRegion::get_index_space + */ + legion_index_space_t + legion_task_get_index_space_from_logical_region( + legion_task_t task, unsigned idx); + + void + legion_convert_1d_to_2d_column_major( + void *src, void *dst[], legion_byte_offset_t offset, int num_columns); #ifdef __cplusplus } #endif diff --git a/runtime/legion/legion_f.f90 b/runtime/legion/legion_f.f90 new file mode 100644 index 0000000000..2655b7c6ba --- /dev/null +++ b/runtime/legion/legion_f.f90 @@ -0,0 +1,1593 @@ +module legion_fortran + use, intrinsic :: iso_c_binding + use legion_fortran_types + use legion_fortran_c_interface + ! use legion_fortran_object_oriented + implicit none + + interface legion_accessor_array_1d_read_point_f + module procedure legion_accessor_array_1d_read_point_ptr_f + module procedure legion_accessor_array_1d_read_point_integer2_f + module procedure legion_accessor_array_1d_read_point_integer4_f + module procedure legion_accessor_array_1d_read_point_integer8_f + module procedure legion_accessor_array_1d_read_point_real4_f + module procedure legion_accessor_array_1d_read_point_real8_f + module procedure legion_accessor_array_1d_read_point_complex4_f + module procedure legion_accessor_array_1d_read_point_complex8_f + end interface + + interface legion_accessor_array_2d_read_point_f + module procedure legion_accessor_array_2d_read_point_ptr_f + module procedure legion_accessor_array_2d_read_point_integer2_f + module procedure legion_accessor_array_2d_read_point_integer4_f + module procedure legion_accessor_array_2d_read_point_integer8_f + module procedure legion_accessor_array_2d_read_point_real4_f + module procedure legion_accessor_array_2d_read_point_real8_f + module procedure legion_accessor_array_2d_read_point_complex4_f + module procedure legion_accessor_array_2d_read_point_complex8_f + end interface + + interface legion_accessor_array_3d_read_point_f + module procedure legion_accessor_array_3d_read_point_ptr_f + module procedure legion_accessor_array_3d_read_point_integer2_f + module procedure legion_accessor_array_3d_read_point_integer4_f + module procedure legion_accessor_array_3d_read_point_integer8_f + module procedure legion_accessor_array_3d_read_point_real4_f + module procedure legion_accessor_array_3d_read_point_real8_f + module procedure legion_accessor_array_3d_read_point_complex4_f + module procedure legion_accessor_array_3d_read_point_complex8_f + end interface + + interface legion_accessor_array_1d_write_point_f + module procedure legion_accessor_array_1d_write_point_ptr_f + module procedure legion_accessor_array_1d_write_point_integer2_f + module procedure legion_accessor_array_1d_write_point_integer4_f + module procedure legion_accessor_array_1d_write_point_integer8_f + module procedure legion_accessor_array_1d_write_point_real4_f + module procedure legion_accessor_array_1d_write_point_real8_f + module procedure legion_accessor_array_1d_write_point_complex4_f + module procedure legion_accessor_array_1d_write_point_complex8_f + end interface + + interface legion_accessor_array_2d_write_point_f + module procedure legion_accessor_array_2d_write_point_ptr_f + module procedure legion_accessor_array_2d_write_point_integer2_f + module procedure legion_accessor_array_2d_write_point_integer4_f + module procedure legion_accessor_array_2d_write_point_integer8_f + module procedure legion_accessor_array_2d_write_point_real4_f + module procedure legion_accessor_array_2d_write_point_real8_f + module procedure legion_accessor_array_2d_write_point_complex4_f + module procedure legion_accessor_array_2d_write_point_complex8_f + end interface + + interface legion_accessor_array_3d_write_point_f + module procedure legion_accessor_array_3d_write_point_ptr_f + module procedure legion_accessor_array_3d_write_point_integer2_f + module procedure legion_accessor_array_3d_write_point_integer4_f + module procedure legion_accessor_array_3d_write_point_integer8_f + module procedure legion_accessor_array_3d_write_point_real4_f + module procedure legion_accessor_array_3d_write_point_real8_f + module procedure legion_accessor_array_3d_write_point_complex4_f + module procedure legion_accessor_array_3d_write_point_complex8_f + end interface + + contains + + ! ----------------------------------------------------------------------- + ! Start-up Operations + ! ----------------------------------------------------------------------- + ! Legion::Runtime::set_top_level_task_id() + subroutine legion_runtime_set_top_level_task_id_f(top_id) + implicit none + + integer(c_int), value, intent(in) :: top_id + + call legion_runtime_set_top_level_task_id_c(top_id) + end subroutine legion_runtime_set_top_level_task_id_f + + ! Legion::ExecutionConstraintSet::ExecutionConstraintSet() + subroutine legion_execution_constraint_set_create_f(execution_constraints) + implicit none + + type(legion_execution_constraint_set_f_t), intent(out) :: execution_constraints + + execution_constraints = legion_execution_constraint_set_create_c() + end subroutine legion_execution_constraint_set_create_f + + ! Legion::ExecutionConstraintSet::add_constraint(Legion::ProcessorConstraint) + subroutine legion_execution_constraint_set_add_processor_constraint_f(handle, proc_kind) + implicit none + + type(legion_execution_constraint_set_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: proc_kind + + call legion_execution_constraint_set_add_processor_constraint_c(handle, proc_kind) + end subroutine legion_execution_constraint_set_add_processor_constraint_f + + ! Legion::TaskLayoutConstraintSet::TaskLayoutConstraintSet() + subroutine legion_task_layout_constraint_set_create_f(layout_constraint) + implicit none + + type(legion_task_layout_constraint_set_f_t), intent(out) :: layout_constraint + + layout_constraint = legion_task_layout_constraint_set_create_c() + end subroutine legion_task_layout_constraint_set_create_f + + ! Legion::Runtime::preregister_task_variant() + subroutine legion_runtime_preregister_task_variant_fnptr_f(id, task_name, & + variant_name, & + execution_constraints, & + layout_constraints, & + options, & + wrapped_task_pointer, & + userdata, & + userlen, task_id) + implicit none + + character(kind=c_char), intent(in) :: task_name(*) + character(kind=c_char), intent(in) :: variant_name(*) + integer(c_int), value, intent(in) :: id + type(legion_execution_constraint_set_f_t), value, intent(in) :: execution_constraints + type(legion_task_layout_constraint_set_f_t), value, intent(in) :: layout_constraints + type(legion_task_config_options_f_t), value, intent(in) :: options + type(c_funptr), value, intent(in) :: wrapped_task_pointer + type(c_ptr), value, intent(in) :: userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_int), intent(out) :: task_id + + task_id = legion_runtime_preregister_task_variant_fnptr_c(id, task_name, & + variant_name, & + execution_constraints, & + layout_constraints, & + options, & + wrapped_task_pointer, & + userdata, & + userlen) + end subroutine legion_runtime_preregister_task_variant_fnptr_f + + ! Legion::Runtime::start() + subroutine legion_runtime_start_f(argc, argv, background, return_value) + implicit none + + integer(c_int), value, intent(in) :: argc + type(c_ptr), value, intent(in) :: argv + logical, value, intent(in) :: background + integer(c_int), intent(out) :: return_value + + return_value = legion_runtime_start_c(argc, argv, logical(background, kind=c_bool)) + end subroutine legion_runtime_start_f + + ! Legion::LegionTaskWrapper::legion_task_preamble() + subroutine legion_task_preamble_f(tdata, tdatalen, proc_id, & + task, regionptr, num_regions, & + ctx, runtime) + implicit none + + type(c_ptr), intent(in) :: tdata ! pass reference + integer(c_size_t), value, intent(in) :: tdatalen + integer(c_long_long), value, intent(in) :: proc_id + type(legion_task_f_t), intent(out) :: task ! pass reference + type(c_ptr), intent(out) :: regionptr + integer(c_int), intent(out) :: num_regions ! pass reference + type(legion_context_f_t), intent(out) :: ctx ! pass reference + type(legion_runtime_f_t), intent(out) :: runtime ! pass reference + + call legion_task_preamble_c(tdata, tdatalen, proc_id, & + task, regionptr, num_regions, & + ctx, runtime) + end subroutine legion_task_preamble_f + + ! Legion::LegionTaskWrapper::legion_task_postamble() + subroutine legion_task_postamble_f(runtime, ctx, retval, retsize) + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(c_ptr), value, intent(in) :: retval + integer(c_size_t), value, intent(in) :: retsize + + call legion_task_postamble_c(runtime, ctx, retval, retsize) + end subroutine legion_task_postamble_f + + ! ----------------------------------------------------------------------- + ! Task Launcher + ! ----------------------------------------------------------------------- + ! @see Legion::TaskLauncher::TaskLauncher() + subroutine legion_task_launcher_create_f(tid, arg, pred, id, tag, task_launcher) + implicit none + + integer(c_int), intent(in) :: tid + type(legion_task_argument_f_t), intent(in) :: arg + type(legion_predicate_f_t), intent(in) :: pred + integer(c_int), intent(in) :: id + integer(c_long), intent(in) :: tag + type(legion_task_launcher_f_t), intent(out) :: task_launcher + + task_launcher = legion_task_launcher_create_c(tid, arg, pred, id, tag) + end subroutine legion_task_launcher_create_f + + ! @see Legion::TaskLauncher::~TaskLauncher() + subroutine legion_task_launcher_destroy_f(handle) + implicit none + + type(legion_task_launcher_f_t), value, intent(in) :: handle + + call legion_task_launcher_destroy_c(handle) + end subroutine legion_task_launcher_destroy_f + + ! @see Legion::Runtime::execute_task() + subroutine legion_task_launcher_execute_f(runtime, ctx, launcher, future) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_task_launcher_f_t), intent(in) :: launcher + type(legion_future_f_t), intent(out) :: future + + future = legion_task_launcher_execute_c(runtime, ctx, launcher) + end subroutine legion_task_launcher_execute_f + + ! @see Legion::TaskLauncher::add_region_requirement() + subroutine legion_task_launcher_add_region_requirement_logical_region_f(launcher, handle, priv, prop, & + parent, tag, verified, rr_idx) + implicit none + + type(legion_task_launcher_f_t), intent(in) :: launcher + type(legion_logical_region_f_t), intent(in) :: handle + integer(c_int), intent(in) :: priv + integer(c_int), intent(in) :: prop + type(legion_logical_region_f_t), intent(in) :: parent + integer(c_long), intent(in) :: tag + logical, intent(in) :: verified + integer(c_int), intent(out) :: rr_idx + + rr_idx = legion_task_launcher_add_region_requirement_logical_region_c(launcher, handle, priv, prop, parent, tag, & + logical(verified, kind=c_bool)) + end subroutine legion_task_launcher_add_region_requirement_logical_region_f + + ! @see Legion::TaskLaunchxer::add_field() + subroutine legion_task_launcher_add_field_f(launcher, idx, fid, inst) + implicit none + + type(legion_task_launcher_f_t), intent(in) :: launcher + integer(c_int), intent(in) :: idx + integer(c_int), intent(in) :: fid + logical, intent(in) :: inst + + call legion_task_launcher_add_field_c(launcher, idx, fid, logical(inst, kind=c_bool)) + end subroutine legion_task_launcher_add_field_f + + ! ----------------------------------------------------------------------- + ! Index Launcher + ! ----------------------------------------------------------------------- + ! @see Legion::IndexTaskLauncher::IndexTaskLauncher() + subroutine legion_index_launcher_create_f(tid, domain, global_arg, map, pred, must, id, tag, index_launcher) + implicit none + + integer(c_int), intent(in) :: tid + type(legion_domain_f_t), intent(in) :: domain + type(legion_task_argument_f_t), intent(in) :: global_arg + type(legion_argument_map_f_t), intent(in) :: map + type(legion_predicate_f_t), intent(in) :: pred + logical, intent(in) :: must + integer(c_int), intent(in) :: id + integer(c_long), intent(in) :: tag + type(legion_index_launcher_f_t), intent(out) :: index_launcher + + index_launcher = legion_index_launcher_create_c(tid, domain, global_arg, map, pred, logical(must, kind=c_bool), id, tag) + end subroutine legion_index_launcher_create_f + + ! @see Legion::IndexTaskLauncher::~IndexTaskLauncher() + subroutine legion_index_launcher_destroy_f(handle) + implicit none + + type(legion_index_launcher_f_t), intent(in) :: handle + + call legion_index_launcher_destroy_c(handle) + end subroutine legion_index_launcher_destroy_f + + ! @see Legion::Runtime::execute_index_space(Context, const IndexTaskLauncher &) + subroutine legion_index_launcher_execute_f(runtime, ctx, launcher, future_map) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_index_launcher_f_t), intent(in) :: launcher + type(legion_future_map_f_t), intent(out) :: future_map + + future_map = legion_index_launcher_execute_c(runtime, ctx, launcher) + end subroutine legion_index_launcher_execute_f + + ! @see Legion::Runtime::execute_index_space(Context, const IndexTaskLauncher &, ReductionOpID) + subroutine legion_index_launcher_execute_reduction_f(runtime, ctx, launcher, redop, future) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_index_launcher_f_t), intent(in) :: launcher + integer(c_int), intent(in) :: redop + type(legion_future_f_t), intent(out) :: future + + future = legion_index_launcher_execute_reduction_c(runtime, ctx, launcher, redop) + end subroutine legion_index_launcher_execute_reduction_f + + ! @see Legion::IndexTaskLauncher::add_region_requirement() + subroutine legion_index_launcher_add_region_requirement_lp_f(launcher, handle, proj, priv, & + prop, parent, tag, verified, rr_idx) + implicit none + + type(legion_index_launcher_f_t), intent(in) :: launcher + type(legion_logical_partition_f_t), intent(in) :: handle + integer(c_int), intent(in) :: proj + integer(c_int), intent(in) :: priv + integer(c_int), intent(in) :: prop + type(legion_logical_region_f_t), intent(in) :: parent + integer(c_long), intent(in) :: tag + logical, intent(in) :: verified + integer(c_int), intent(out) :: rr_idx + + rr_idx = legion_index_launcher_add_region_requirement_lp_c(launcher, handle, proj, priv, & + prop, parent, tag, logical(verified, kind=c_bool)) + end subroutine legion_index_launcher_add_region_requirement_lp_f + + ! @see Legion::TaskLaunchxer::add_field() + subroutine legion_index_launcher_add_field_f(launcher, idx, fid, inst) + implicit none + + type(legion_index_launcher_f_t), intent(in) :: launcher + integer(c_int), intent(in) :: idx + integer(c_int), intent(in) :: fid + logical, intent(in) :: inst + + call legion_index_launcher_add_field_c(launcher, idx, fid, logical(inst, kind=c_bool)) + end subroutine legion_index_launcher_add_field_f + + ! ----------------------------------------------------------------------- + ! Predicate Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Predicate::TRUE_PRED + subroutine legion_predicate_true_f(pred) + implicit none + + type(legion_predicate_f_t), intent(out) :: pred + + pred = legion_predicate_true_c() + end subroutine legion_predicate_true_f + + ! @see Legion::Predicate::FALSE_PRED + subroutine legion_predicate_false_f(pred) + implicit none + + type(legion_predicate_f_t), intent(out) :: pred + pred = legion_predicate_false_c() + end subroutine legion_predicate_false_f + + ! ----------------------------------------------------------------------- + ! Argument Map + ! ----------------------------------------------------------------------- + ! @see Legion::ArgumentMap::ArgumentMap() + subroutine legion_argument_map_create_f(arg_map) + implicit none + + type(legion_argument_map_f_t), intent(out) :: arg_map + + arg_map = legion_argument_map_create_c() + end subroutine legion_argument_map_create_f + + ! @see Legion::ArgumentMap::set_point() + subroutine legion_argument_map_set_point_f(map, dp, arg, replace) + implicit none + + type(legion_argument_map_f_t), intent(in) :: map + type(legion_domain_point_f_t), intent(in) :: dp + type(legion_task_argument_f_t), intent(in) :: arg + logical, intent(in) :: replace + + call legion_argument_map_set_point_c(map, dp, arg, logical(replace, kind=c_bool)) + end subroutine legion_argument_map_set_point_f + + ! ----------------------------------------------------------------------- + ! Task Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Task::args + subroutine legion_task_get_args_f(task, args) + implicit none + + type(legion_task_f_t), intent(in) :: task + type(c_ptr), intent(out) :: args + + args = legion_task_get_args_c(task) + end subroutine legion_task_get_args_f + + ! @see Legion::Task::arglen + subroutine legion_task_get_arglen_f(task, arglen) + implicit none + + type(legion_task_f_t), intent(in) :: task + integer(c_size_t), intent(out) :: arglen + + arglen = legion_task_get_arglen_c(task) + end subroutine legion_task_get_arglen_f + + ! @see Legion::Task::local_args + subroutine legion_task_get_local_args_f(task, local_args) + implicit none + + type(legion_task_f_t), intent(in) :: task + type(c_ptr), intent(out) :: local_args + + local_args = legion_task_get_local_args_c(task) + end subroutine legion_task_get_local_args_f + + ! @see Legion::Task::local_arglen + subroutine legion_task_get_local_arglen_f(task, local_arglen) + implicit none + + type(legion_task_f_t), intent(in) :: task + integer(c_size_t), intent(out) :: local_arglen + + local_arglen = legion_task_get_local_arglen_c(task) + end subroutine legion_task_get_local_arglen_f + + ! @see Legion::Task::index_domain + subroutine legion_task_get_index_domain_f(task, index_domain) + implicit none + + type(legion_task_f_t), intent(in) :: task + type(legion_domain_f_t), intent(out) :: index_domain + + index_domain = legion_task_get_index_domain_c(task) + end subroutine legion_task_get_index_domain_f + + ! @see Legion::Task::regions + subroutine legion_task_get_region_f(task, idx, rr) + implicit none + + type(legion_task_f_t), intent(in) :: task + integer(c_int), intent(in) :: idx + type(legion_region_requirement_f_t), intent(out) :: rr + + rr = legion_task_get_region_c(task, idx) + end subroutine legion_task_get_region_f + + ! ----------------------------------------------------------------------- + ! Domain Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Domain::from_rect() + subroutine legion_domain_from_rect_1d_f(r, domain) + implicit none + + type(legion_rect_1d_f_t), intent(in) :: r + type(legion_domain_f_t), intent(out) :: domain + + domain = legion_domain_from_rect_1d_c(r) + end subroutine legion_domain_from_rect_1d_f + + ! @see Legion::Domain::from_rect() + subroutine legion_domain_from_rect_2d_f(r, domain) + implicit none + + type(legion_rect_2d_f_t), intent(in) :: r + type(legion_domain_f_t), intent(out) :: domain + + domain = legion_domain_from_rect_2d_c(r) + end subroutine legion_domain_from_rect_2d_f + + ! @see Legion::Domain::from_rect() + subroutine legion_domain_from_rect_3d_f(r, domain) + implicit none + + type(legion_rect_3d_f_t), intent(in) :: r + type(legion_domain_f_t), intent(out) :: domain + + domain = legion_domain_from_rect_3d_c(r) + end subroutine legion_domain_from_rect_3d_f + + ! @see Legion::Domain::get_rect() + subroutine legion_domain_get_rect_1d_f(d, rect) + implicit none + + type(legion_domain_f_t), intent(in) :: d + type(legion_rect_1d_f_t), intent(out) :: rect + + rect = legion_domain_get_rect_1d_c(d) + end subroutine legion_domain_get_rect_1d_f + + ! @see Legion::Domain::get_rect() + subroutine legion_domain_get_rect_2d_f(d, rect) + implicit none + + type(legion_domain_f_t), intent(in) :: d + type(legion_rect_2d_f_t), intent(out) :: rect + + rect = legion_domain_get_rect_2d_c(d) + end subroutine legion_domain_get_rect_2d_f + + ! @see Legion::Domain::get_rect() + subroutine legion_domain_get_rect_3d_f(d, rect) + implicit none + + type(legion_domain_f_t), intent(in) :: d + type(legion_rect_3d_f_t), intent(out) :: rect + + rect = legion_domain_get_rect_3d_c(d) + end subroutine legion_domain_get_rect_3d_f + + ! @see Legion::Domain::get_volume() + subroutine legion_domain_get_volume_f(d, volume) + implicit none + + type(legion_domain_f_t), intent(in) :: d + integer(c_size_t), intent(out) :: volume + + volume = legion_domain_get_volume_c(d) + end subroutine legion_domain_get_volume_f + + ! ----------------------------------------------------------------------- + ! Domain Point Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Domain::from_point() + subroutine legion_domain_point_from_point_1d_f(p, domain_point) + implicit none + + type(legion_point_1d_f_t), intent(in) :: p + type(legion_domain_point_f_t), intent(out) :: domain_point + + domain_point = legion_domain_point_from_point_1d_c(p) + end subroutine legion_domain_point_from_point_1d_f + + ! @see Legion::Domain::from_point() + subroutine legion_domain_point_from_point_2d_f(p, domain_point) + implicit none + + type(legion_point_2d_f_t), intent(in) :: p + type(legion_domain_point_f_t), intent(out) :: domain_point + + domain_point = legion_domain_point_from_point_2d_c(p) + end subroutine legion_domain_point_from_point_2d_f + + ! @see Legion::Domain::from_point() + subroutine legion_domain_point_from_point_3d_f(p, domain_point) + implicit none + + type(legion_point_3d_f_t), intent(in) :: p + type(legion_domain_point_f_t), intent(out) :: domain_point + + domain_point = legion_domain_point_from_point_3d_c(p) + end subroutine legion_domain_point_from_point_3d_f + + ! ----------------------------------------------------------------------- + ! Future Map Operations + ! ----------------------------------------------------------------------- + ! @see Legion::FutureMap::wait_all_results() + subroutine legion_future_map_wait_all_results_f(handle) + implicit none + + type(legion_future_map_f_t), intent(in) :: handle + + call legion_future_map_wait_all_results_c(handle) + end subroutine legion_future_map_wait_all_results_f + + ! ----------------------------------------------------------------------- + ! Index Space Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_index_space(Context, Domain) + subroutine legion_index_space_create_domain_f(runtime, ctx, domain, index_space) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_domain_f_t), intent(in) :: domain + type(legion_index_space_f_t), intent(out) :: index_space + + index_space = legion_index_space_create_domain_c(runtime, ctx, domain) + end subroutine legion_index_space_create_domain_f + + ! @see Legion::Runtime::destroy_index_space() + subroutine legion_index_space_destroy_f(runtime, ctx, handle) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_index_space_f_t), intent(in) :: handle + + call legion_index_space_destroy_c(runtime, ctx, handle) + end subroutine legion_index_space_destroy_f + + ! @see Legion::Runtime::get_index_space_domain() + subroutine legion_index_space_get_domain_f(runtime, handle, domain) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_index_space_f_t), intent(in) :: handle + type(legion_domain_f_t), intent(out) :: domain + + domain = legion_index_space_get_domain_c(runtime, handle) + end subroutine legion_index_space_get_domain_f + + ! @see Legion::Runtime::attach_name() + subroutine legion_index_space_attach_name_f(runtime, handle, name, is_mutable) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_index_space_f_t), intent(in) :: handle + character(len=*), target, intent(in) :: name + logical(c_bool), intent(in) :: is_mutable + + call legion_index_space_attach_name_c(runtime, handle, c_loc(name), is_mutable) + end subroutine legion_index_space_attach_name_f + + ! ----------------------------------------------------------------------- + ! Index Partition Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_equal_partition() + subroutine legion_index_partition_create_equal_f(runtime, ctx, parent, color_space, granularity, color, index_partition) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_index_space_f_t), intent(in) :: parent + type(legion_index_space_f_t), intent(in) :: color_space + integer(c_size_t), intent(in) :: granularity + integer(c_int), intent(in) :: color + type(legion_index_partition_f_t), intent(out) :: index_partition + + index_partition = legion_index_partition_create_equal_c(runtime, ctx, parent, color_space, granularity, color) + end subroutine legion_index_partition_create_equal_f + + ! @see Legion::Runtime::attach_name() + subroutine legion_index_partition_attach_name_f(runtime, handle, name, is_mutable) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_index_partition_f_t), intent(in) :: handle + character(len=*), target, intent(in) :: name + logical, intent(in) :: is_mutable + + call legion_index_partition_attach_name_c(runtime, handle, c_loc(name), logical(is_mutable, kind=c_bool)) + end subroutine legion_index_partition_attach_name_f + + ! ----------------------------------------------------------------------- + ! Logical Region Tree Traversal Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::get_logical_partition() + subroutine legion_logical_partition_create_f(runtime, ctx, parent, handle, logical_partition) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_logical_region_f_t), intent(in) :: parent + type(legion_index_partition_f_t), intent(in) :: handle + type(legion_logical_partition_f_t), intent(out) :: logical_partition + + logical_partition = legion_logical_partition_create_c(runtime, ctx, parent, handle) + end subroutine legion_logical_partition_create_f + + ! @see Legion::Runtime::attach_name() + subroutine legion_logical_partition_attach_name_f(runtime, handle, name, is_mutable) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_logical_partition_f_t), intent(in) :: handle + character(len=*), target, intent(in) :: name + logical, intent(in) :: is_mutable + + call legion_logical_partition_attach_name_c(runtime, handle, c_loc(name), logical(is_mutable, kind=c_bool)) + end subroutine legion_logical_partition_attach_name_f + + ! ----------------------------------------------------------------------- + ! Field Space Operatiins + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_field_space() + subroutine legion_field_space_create_f(runtime, ctx, field_space) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_field_space_f_t), intent(out) :: field_space + + field_space = legion_field_space_create_c(runtime, ctx) + end subroutine legion_field_space_create_f + + ! @see Legion::Runtime::destroy_field_space() + subroutine legion_field_space_destroy_f(runtime, ctx, handle) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_field_space_f_t), intent(in) :: handle + + call legion_field_space_destroy_c(runtime, ctx, handle) + end subroutine legion_field_space_destroy_f + + ! ----------------------------------------------------------------------- + ! Field Allocator + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_field_allocator() + subroutine legion_field_allocator_create_f(runtime, ctx, handle, field_allocator) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_field_space_f_t), intent(in) :: handle + type(legion_field_allocator_f_t), intent(out) :: field_allocator + + field_allocator = legion_field_allocator_create_c(runtime, ctx, handle) + end subroutine legion_field_allocator_create_f + + ! @see Legion::FieldAllocator::~FieldAllocator() + subroutine legion_field_allocator_destroy_f(handle) + implicit none + + type(legion_field_allocator_f_t), intent(in) :: handle + + call legion_field_allocator_destroy_c(handle) + end subroutine legion_field_allocator_destroy_f + + ! @see Legion::FieldAllocator::allocate_field() + subroutine legion_field_allocator_allocate_field_f(allocator, field_size, desired_fieldid, field_id) + implicit none + + type(legion_field_allocator_f_t), intent(in) :: allocator + integer(c_size_t), intent(in) :: field_size + integer(c_int), intent(in) :: desired_fieldid + integer(c_int), intent(out) :: field_id + + field_id = legion_field_allocator_allocate_field_c(allocator, field_size, desired_fieldid) + end subroutine legion_field_allocator_allocate_field_f + + ! ----------------------------------------------------------------------- + ! Logical Region + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_logical_region() + subroutine legion_logical_region_create_f(runtime, ctx, index, fields, logical_region) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_index_space_f_t), intent(in) :: index + type(legion_field_space_f_t), intent(in) :: fields + type(legion_logical_region_f_t), intent(out) :: logical_region + + logical_region = legion_logical_region_create_c(runtime, ctx, index, fields) + end subroutine legion_logical_region_create_f + + ! @see Legion::Runtime::destroy_logical_region() + subroutine legion_logical_region_destroy_f(runtime, ctx, handle) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_logical_region_f_t), intent(in) :: handle + + call legion_logical_region_destroy_c(runtime, ctx, handle) + end subroutine legion_logical_region_destroy_f + + ! @see Legion::LogicalRegion::get_index_space + subroutine legion_logical_region_get_index_space_f(handle, index_space) + implicit none + + type(legion_logical_region_f_t), intent(in) :: handle + type(legion_index_space_f_t), intent(out) :: index_space + + index_space = legion_logical_region_get_index_space_c(handle) + end subroutine legion_logical_region_get_index_space_f + + ! ----------------------------------------------------------------------- + ! Region Requirement Operations + ! ----------------------------------------------------------------------- + ! @see Legion::RegionRequirement::region + subroutine legion_region_requirement_get_region_f(handle, logical_region) + implicit none + + type(legion_region_requirement_f_t), intent(in) :: handle + type(legion_logical_region_f_t), intent(out) :: logical_region + + logical_region = legion_region_requirement_get_region_c(handle) + end subroutine legion_region_requirement_get_region_f + + ! @see Legion::RegionRequirement::privilege_fields + subroutine legion_region_requirement_get_privilege_field_f(handle, idx, field_id) + implicit none + + type(legion_region_requirement_f_t), intent(in) :: handle + integer(c_int), intent(in) :: idx + integer(c_int), intent(out) :: field_id + + field_id = legion_region_requirement_get_privilege_field_c(handle, idx) + end subroutine legion_region_requirement_get_privilege_field_f + + ! ----------------------------------------------------------------------- + ! Physical Data Operations + ! ----------------------------------------------------------------------- + subroutine legion_get_physical_region_by_id_f(regionptr, id, num_regions, physical_region) + implicit none + + type(c_ptr), intent(in) :: regionptr + integer(c_int), intent(in) :: id + integer(c_int), intent(in) :: num_regions + type(legion_physical_region_f_t), intent(out) :: physical_region + + physical_region = legion_get_physical_region_by_id_c(regionptr, id, num_regions) + end subroutine legion_get_physical_region_by_id_f + + ! @see Legion::PhysicalRegion::get_field_accessor() + subroutine legion_physical_region_get_field_accessor_array_1d_f(handle, fid, accessor) + implicit none + + type(legion_physical_region_f_t), intent(in) :: handle + integer(c_int), intent(in) :: fid + type(legion_accessor_array_1d_f_t), intent(out) :: accessor + + accessor = legion_physical_region_get_field_accessor_array_1d_c(handle, fid) + end subroutine legion_physical_region_get_field_accessor_array_1d_f + + ! @see Legion::PhysicalRegion::get_field_accessor() + subroutine legion_physical_region_get_field_accessor_array_2d_f(handle, fid, accessor) + implicit none + + type(legion_physical_region_f_t), intent(in) :: handle + integer(c_int), intent(in) :: fid + type(legion_accessor_array_2d_f_t), intent(out) :: accessor + + accessor = legion_physical_region_get_field_accessor_array_2d_c(handle, fid) + end subroutine legion_physical_region_get_field_accessor_array_2d_f + + ! @see Legion::PhysicalRegion::get_field_accessor() + subroutine legion_physical_region_get_field_accessor_array_3d_f(handle, fid, accessor) + implicit none + + type(legion_physical_region_f_t), intent(in) :: handle + integer(c_int), intent(in) :: fid + type(legion_accessor_array_3d_f_t), intent(out) :: accessor + + accessor = legion_physical_region_get_field_accessor_array_3d_c(handle, fid) + end subroutine legion_physical_region_get_field_accessor_array_3d_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_raw_rect_ptr_f(handle, rect, subrect, offset, raw_ptr) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_rect_1d_f_t), intent(in) :: rect + type(legion_rect_1d_f_t), intent(out) :: subrect ! pass reference + type(legion_byte_offset_f_t), intent(out) :: offset ! pass reference + type(c_ptr), intent(out) :: raw_ptr + + raw_ptr = legion_accessor_array_1d_raw_rect_ptr_c(handle, rect, subrect, offset) + end subroutine legion_accessor_array_1d_raw_rect_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_raw_rect_ptr_f(handle, rect, subrect, offset, raw_ptr) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_rect_2d_f_t), intent(in) :: rect + type(legion_rect_2d_f_t), intent(out) :: subrect ! pass reference + type(legion_byte_offset_f_t), intent(out) :: offset(2) ! pass reference + type(c_ptr), intent(out) :: raw_ptr + + raw_ptr = legion_accessor_array_2d_raw_rect_ptr_c(handle, rect, subrect, offset) + end subroutine legion_accessor_array_2d_raw_rect_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_raw_rect_ptr_f(handle, rect, subrect, offset, raw_ptr) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_rect_3d_f_t), intent(in) :: rect + type(legion_rect_3d_f_t), intent(out) :: subrect ! pass reference + type(legion_byte_offset_f_t), intent(out) :: offset(3) ! pass reference + type(c_ptr), intent(out) :: raw_ptr + + raw_ptr = legion_accessor_array_3d_raw_rect_ptr_c(handle, rect, subrect, offset) + end subroutine legion_accessor_array_3d_raw_rect_ptr_f + + ! --------- 1D read ----------- + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_ptr_f(handle, point, dst, bytes) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + type(c_ptr), intent(out) :: dst + integer(c_size_t), intent(in) :: bytes + + call legion_accessor_array_1d_read_point_c(handle, point, dst, bytes) + end subroutine legion_accessor_array_1d_read_point_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_integer2_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + integer(kind=2), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_integer2_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_integer4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + integer(kind=4), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_integer4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_integer8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + integer(kind=8), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_integer8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_real4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + real(kind=4), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_real4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_real8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + real(kind=8), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_real8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_complex4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + complex(kind=4), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_complex4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_complex8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + complex(kind=8), target, intent(out) :: dst + + call legion_accessor_array_1d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_1d_read_point_complex8_f + + ! --------- 2D read ----------- + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_ptr_f(handle, point, dst, bytes) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + type(c_ptr), intent(out) :: dst + integer(c_size_t), intent(in) :: bytes + + call legion_accessor_array_2d_read_point_c(handle, point, dst, bytes) + end subroutine legion_accessor_array_2d_read_point_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_integer2_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + integer(kind=2), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_integer2_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_integer4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + integer(kind=4), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_integer4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_integer8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + integer(kind=8), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_integer8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_real4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + real(kind=4), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_real4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_real8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + real(kind=8), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_real8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_complex4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + complex(kind=4), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_complex4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_complex8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + complex(kind=8), target, intent(out) :: dst + + call legion_accessor_array_2d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_2d_read_point_complex8_f + + ! --------- 3D read ----------- + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_ptr_f(handle, point, dst, bytes) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + type(c_ptr), intent(out) :: dst + integer(c_size_t), intent(in) :: bytes + + call legion_accessor_array_3d_read_point_c(handle, point, dst, bytes) + end subroutine legion_accessor_array_3d_read_point_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_integer2_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + integer(kind=2), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_integer2_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_integer4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + integer(kind=4), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_integer4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_integer8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + integer(kind=8), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_integer8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_real4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + real(kind=4), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_real4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_real8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + real(kind=8), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_real8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_complex4_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + complex(kind=4), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_complex4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_complex8_f(handle, point, dst) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + complex(kind=8), target, intent(out) :: dst + + call legion_accessor_array_3d_read_point_c(handle, point, c_loc(dst), c_sizeof(dst)) + end subroutine legion_accessor_array_3d_read_point_complex8_f + + ! --------- 1D write ----------- + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_ptr_f(handle, point, src, bytes) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + type(c_ptr), intent(in) :: src + integer(c_size_t), intent(in) :: bytes + + call legion_accessor_array_1d_write_point_c(handle, point, src, bytes) + end subroutine legion_accessor_array_1d_write_point_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_integer2_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + integer(kind=2), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_integer2_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_integer4_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + integer(kind=4), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_integer4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_integer8_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + integer(kind=8), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_integer8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_real4_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + real(kind=4), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_real4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_real8_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + real(kind=8), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_real8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_complex4_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + complex(kind=4), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_complex4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_complex8_f(handle, point, src) + implicit none + + type(legion_accessor_array_1d_f_t), intent(in) :: handle + type(legion_point_1d_f_t), intent(in) :: point + complex(kind=8), target, intent(in) :: src + + call legion_accessor_array_1d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_1d_write_point_complex8_f + + ! --------- 2D write ----------- + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_ptr_f(handle, point, src, bytes) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + type(c_ptr), intent(in) :: src + integer(c_size_t), intent(in) :: bytes + + call legion_accessor_array_2d_write_point_c(handle, point, src, bytes) + end subroutine legion_accessor_array_2d_write_point_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_integer2_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + integer(kind=2), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_integer2_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_integer4_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + integer(kind=4), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_integer4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_integer8_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + integer(kind=8), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_integer8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_real4_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + real(kind=4), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_real4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_real8_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + real(kind=8), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_real8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_complex4_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + complex(kind=4), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_complex4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_complex8_f(handle, point, src) + implicit none + + type(legion_accessor_array_2d_f_t), intent(in) :: handle + type(legion_point_2d_f_t), intent(in) :: point + complex(kind=8), target, intent(in) :: src + + call legion_accessor_array_2d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_2d_write_point_complex8_f + + ! --------- 3D write ----------- + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_ptr_f(handle, point, src, bytes) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + type(c_ptr), intent(in) :: src + integer(c_size_t), intent(in) :: bytes + + call legion_accessor_array_3d_write_point_c(handle, point, src, bytes) + end subroutine legion_accessor_array_3d_write_point_ptr_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_integer2_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + integer(kind=2), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_integer2_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_integer4_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + integer(kind=4), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_integer4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_integer8_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + integer(kind=8), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_integer8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_real4_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + real(kind=4), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_real4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_real8_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + real(kind=8), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_real8_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_complex4_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + complex(kind=4), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_complex4_f + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_complex8_f(handle, point, src) + implicit none + + type(legion_accessor_array_3d_f_t), intent(in) :: handle + type(legion_point_3d_f_t), intent(in) :: point + complex(kind=8), target, intent(in) :: src + + call legion_accessor_array_3d_write_point_c(handle, point, c_loc(src), c_sizeof(src)) + end subroutine legion_accessor_array_3d_write_point_complex8_f + + ! ----------------------------------------------------------------------- + ! File Operations + ! ----------------------------------------------------------------------- + subroutine legion_field_map_create_f(field_map) + implicit none + + type(legion_field_map_f_t), intent(out) :: field_map + + field_map = legion_field_map_create_c() + end subroutine legion_field_map_create_f + + subroutine legion_field_map_destroy_f(handle) + implicit none + + type(legion_field_map_f_t), intent(in) :: handle + + call legion_field_map_destroy_c(handle) + end subroutine legion_field_map_destroy_f + + subroutine legion_field_map_insert_f(handle, key, value) + implicit none + + type(legion_field_map_f_t), intent(in) :: handle + integer(c_int), intent(in) :: key + character(len=*), target, intent(in) :: value + + call legion_field_map_insert_c(handle, key, c_loc(value)) + end subroutine legion_field_map_insert_f + + ! @see Legion::Runtime::attach_hdf5() + subroutine legion_runtime_attach_hdf5_f(runtime, ctx, filename, handle, parent, field_map, mode, physical_region) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + character(len=*), target, intent(in) :: filename + type(legion_logical_region_f_t), intent(in) :: handle + type(legion_logical_region_f_t), intent(in) :: parent + type(legion_field_map_f_t), intent(in) :: field_map + integer(c_int), intent(in) :: mode + type(legion_physical_region_f_t), intent(out) :: physical_region + + physical_region = legion_runtime_attach_hdf5_c(runtime, ctx, c_loc(filename), handle, parent, field_map, mode) + end subroutine legion_runtime_attach_hdf5_f + + ! @see Legion::Runtime::detach_hdf5() + subroutine legion_runtime_detach_hdf5_f(runtime, ctx, region) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_physical_region_f_t), intent(in) :: region + + call legion_runtime_detach_hdf5_c(runtime, ctx, region) + end subroutine legion_runtime_detach_hdf5_f + + ! ----------------------------------------------------------------------- + ! Copy Operations + ! ----------------------------------------------------------------------- + ! @see Legion::CopyLauncher::CopyLauncher() + subroutine legion_copy_launcher_create_f(pred, id, launcher_tag, copy_launcher) + implicit none + + type(legion_predicate_f_t), intent(in) :: pred + integer(c_int), intent(in) :: id + integer(c_long), intent(in) :: launcher_tag + type(legion_copy_launcher_f_t), intent(out) :: copy_launcher + + copy_launcher = legion_copy_launcher_create_c(pred, id, launcher_tag) + end subroutine legion_copy_launcher_create_f + + ! @see Legion::CopyLauncher::~CopyLauncher() + subroutine legion_copy_launcher_destroy_f(handle) + implicit none + + type(legion_copy_launcher_f_t), intent(in) :: handle + + call legion_copy_launcher_destroy_c(handle) + end subroutine legion_copy_launcher_destroy_f + + ! @see Legion::Runtime::issue_copy_operation() + subroutine legion_copy_launcher_execute_f(runtime, ctx, launcher) + implicit none + + type(legion_runtime_f_t), intent(in) :: runtime + type(legion_context_f_t), intent(in) :: ctx + type(legion_copy_launcher_f_t), intent(in) :: launcher + + call legion_copy_launcher_execute_c(runtime, ctx, launcher) + end subroutine legion_copy_launcher_execute_f + + ! @see Legion::CopyLauncher::add_copy_requirements() + subroutine legion_copy_launcher_add_src_region_requirement_lr_f(launcher, handle, priv, prop, & + parent, tag, verified, rr_idx) + implicit none + + type(legion_copy_launcher_f_t), intent(in) :: launcher + type(legion_logical_region_f_t), intent(in) :: handle + integer(c_int), intent(in) :: priv + integer(c_int), intent(in) :: prop + type(legion_logical_region_f_t), intent(in) :: parent + integer(c_long), intent(in) :: tag + logical(c_bool), intent(in) :: verified + integer(c_int), intent(out) :: rr_idx + + rr_idx = legion_copy_launcher_add_src_region_requirement_lr_c(launcher, handle, priv, prop, parent, tag, verified) + end subroutine legion_copy_launcher_add_src_region_requirement_lr_f + + ! @see Legion::CopyLauncher::add_copy_requirements() + subroutine legion_copy_launcher_add_dst_region_requirement_lr_f(launcher, handle, priv, prop, & + parent, tag, verified, rr_idx) + implicit none + + type(legion_copy_launcher_f_t), intent(in) :: launcher + type(legion_logical_region_f_t), intent(in) :: handle + integer(c_int), intent(in) :: priv + integer(c_int), intent(in) :: prop + type(legion_logical_region_f_t), intent(in) :: parent + integer(c_long), intent(in) :: tag + logical(c_bool), intent(in) :: verified + integer(c_int), intent(out) :: rr_idx + + rr_idx = legion_copy_launcher_add_dst_region_requirement_lr_c(launcher, handle, priv, prop, parent, tag, verified) + end subroutine legion_copy_launcher_add_dst_region_requirement_lr_f + + ! @see Legion::CopyLauncher::add_src_field() + subroutine legion_copy_launcher_add_src_field_f(launcher, idx, fid, inst) + implicit none + + type(legion_copy_launcher_f_t), intent(in) :: launcher + integer(c_int), intent(in) :: idx + integer(c_int), intent(in) :: fid + logical(c_bool), intent(in) :: inst + + call legion_copy_launcher_add_src_field_c(launcher, idx, fid, inst) + end subroutine legion_copy_launcher_add_src_field_f + + ! @see Legion::CopyLauncher::add_dst_field() + subroutine legion_copy_launcher_add_dst_field_f(launcher, idx, fid, inst) + implicit none + + type(legion_copy_launcher_f_t), intent(in) :: launcher + integer(c_int), intent(in) :: idx + integer(c_int), intent(in) :: fid + logical(c_bool), intent(in) :: inst + + call legion_copy_launcher_add_dst_field_c(launcher, idx, fid, inst) + end subroutine legion_copy_launcher_add_dst_field_f + + ! ----------------------------------------------------------------------- + ! Combined Operations + ! ----------------------------------------------------------------------- + subroutine legion_task_get_index_space_from_logical_region_f(handle, tid, index_space) + implicit none + + type(legion_task_f_t), intent(in) :: handle + integer(c_int), intent(in) :: tid + type(legion_index_space_f_t), intent(out) :: index_space + + !index_space = legion_task_get_index_space_from_logical_region_c(handle, tid) + type(legion_region_requirement_f_t) :: rr + type(legion_logical_region_f_t) :: lr + + call legion_task_get_region_f(handle, tid, rr) + call legion_region_requirement_get_region_f(rr, lr) + call legion_logical_region_get_index_space_f(lr, index_space) + end subroutine legion_task_get_index_space_from_logical_region_f +end module legion_fortran \ No newline at end of file diff --git a/runtime/legion/legion_f_c_interface.f90 b/runtime/legion/legion_f_c_interface.f90 new file mode 100644 index 0000000000..4e6d75c265 --- /dev/null +++ b/runtime/legion/legion_f_c_interface.f90 @@ -0,0 +1,1229 @@ +module legion_fortran_c_interface + use, intrinsic :: iso_c_binding + use legion_fortran_types + implicit none + + interface + ! ----------------------------------------------------------------------- + ! Start-up Operations + ! ----------------------------------------------------------------------- + ! Legion::Runtime::set_top_level_task_id() + subroutine legion_runtime_set_top_level_task_id_c(top_id) & + bind(C, name="legion_runtime_set_top_level_task_id") + use iso_c_binding + implicit none + + integer(c_int), value, intent(in) :: top_id + end subroutine legion_runtime_set_top_level_task_id_c + + ! Legion::ExecutionConstraintSet::ExecutionConstraintSet() + function legion_execution_constraint_set_create_c() & + bind(C, name="legion_execution_constraint_set_create") + use iso_c_binding + import legion_execution_constraint_set_f_t + implicit none + + type(legion_execution_constraint_set_f_t) :: legion_execution_constraint_set_create_c + end function legion_execution_constraint_set_create_c + + ! Legion::ExecutionConstraintSet::add_constraint(Legion::ProcessorConstraint) + subroutine legion_execution_constraint_set_add_processor_constraint_c(handle, proc_kind) & + bind(C, name="legion_execution_constraint_set_add_processor_constraint") + use iso_c_binding + import legion_execution_constraint_set_f_t + implicit none + + type(legion_execution_constraint_set_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: proc_kind + end subroutine legion_execution_constraint_set_add_processor_constraint_c + + ! Legion::TaskLayoutConstraintSet::TaskLayoutConstraintSet() + function legion_task_layout_constraint_set_create_c() & + bind(C, name="legion_task_layout_constraint_set_create") + use iso_c_binding + import legion_task_layout_constraint_set_f_t + implicit none + + type(legion_task_layout_constraint_set_f_t) :: legion_task_layout_constraint_set_create_c + end function legion_task_layout_constraint_set_create_c + + ! Legion::Runtime::preregister_task_variant() + function legion_runtime_preregister_task_variant_fnptr_c(id, task_name, & + variant_name, & + execution_constraints, & + layout_constraints, & + options, & + wrapped_task_pointer, & + userdata, & + userlen) & + bind(C, name="legion_runtime_preregister_task_variant_fnptr") + use iso_c_binding + import legion_execution_constraint_set_f_t + import legion_task_layout_constraint_set_f_t + import legion_task_config_options_f_t + implicit none + + integer(c_int) :: legion_runtime_preregister_task_variant_fnptr_c + character(kind=c_char), intent(in) :: task_name(*) + character(kind=c_char), intent(in) :: variant_name(*) + integer(c_int), value, intent(in) :: id + type(legion_execution_constraint_set_f_t), value, intent(in) :: execution_constraints + type(legion_task_layout_constraint_set_f_t), value, intent(in) :: layout_constraints + type(legion_task_config_options_f_t), value, intent(in) :: options + type(c_funptr), value, intent(in) :: wrapped_task_pointer + type(c_ptr), value, intent(in) :: userdata + integer(c_size_t), value, intent(in) :: userlen + end function legion_runtime_preregister_task_variant_fnptr_c + + ! Legion::Runtime::start() + function legion_runtime_start_c(argc, argv, background) & + bind(C, name="legion_runtime_start") + use iso_c_binding + implicit none + + integer(c_int) :: legion_runtime_start_c + integer(c_int), value, intent(in) :: argc + type(c_ptr), value, intent(in) :: argv + logical(c_bool), value, intent(in) :: background + end function legion_runtime_start_c + + ! Legion::LegionTaskWrapper::legion_task_preamble() + subroutine legion_task_preamble_c(tdata, tdatalen, proc_id, & + task, regionptr, num_regions, & + ctx, runtime) & + bind(C, name="legion_task_preamble") + use iso_c_binding + import legion_task_f_t + import legion_physical_region_f_t + import legion_context_f_t + import legion_runtime_f_t + implicit none + + type(c_ptr), intent(in) :: tdata ! pass reference + integer(c_size_t), value, intent(in) :: tdatalen + integer(c_long_long), value, intent(in) :: proc_id + type(legion_task_f_t), intent(out) :: task ! pass reference + type(c_ptr), intent(out) :: regionptr + integer(c_int), intent(out) :: num_regions ! pass reference + type(legion_context_f_t), intent(out) :: ctx ! pass reference + type(legion_runtime_f_t), intent(out) :: runtime ! pass reference + end subroutine legion_task_preamble_c + + ! Legion::LegionTaskWrapper::legion_task_postamble() + subroutine legion_task_postamble_c(runtime, ctx, retval, retsize) & + bind(C, name="legion_task_postamble") + use iso_c_binding + import legion_runtime_f_t + import legion_context_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(c_ptr), value, intent(in) :: retval + integer(c_size_t), value, intent(in) :: retsize + end subroutine legion_task_postamble_c + + ! ----------------------------------------------------------------------- + ! Task Launcher + ! ----------------------------------------------------------------------- + ! @see Legion::TaskLauncher::TaskLauncher() + function legion_task_launcher_create_c(tid, arg, pred, id, tag) & + bind(C, name="legion_task_launcher_create") + use iso_c_binding + import legion_task_launcher_f_t + import legion_task_argument_f_t + import legion_predicate_f_t + implicit none + + type(legion_task_launcher_f_t) :: legion_task_launcher_create_c + integer(c_int), value, intent(in) :: tid + type(legion_task_argument_f_t), value, intent(in) :: arg + type(legion_predicate_f_t), value, intent(in) :: pred + integer(c_int), value, intent(in) :: id + integer(c_long), value, intent(in) :: tag + end function legion_task_launcher_create_c + + ! @see Legion::TaskLauncher::~TaskLauncher() + subroutine legion_task_launcher_destroy_c(handle) & + bind(C, name="legion_task_launcher_destroy") + use iso_c_binding + import legion_task_launcher_f_t + implicit none + + type(legion_task_launcher_f_t), value, intent(in) :: handle + end subroutine legion_task_launcher_destroy_c + + ! @see Legion::Runtime::execute_task() + function legion_task_launcher_execute_c(runtime, ctx, launcher) & + bind(C, name="legion_task_launcher_execute") + use iso_c_binding + import legion_future_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_task_launcher_f_t + implicit none + + type(legion_future_f_t) :: legion_task_launcher_execute_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_task_launcher_f_t), value, intent(in) :: launcher + end function legion_task_launcher_execute_c + + ! @see Legion::TaskLauncher::add_region_requirement() + function legion_task_launcher_add_region_requirement_logical_region_c(launcher, handle, priv, prop, parent, tag, verified) & + bind (C, name="legion_task_launcher_add_region_requirement_logical_region") + use iso_c_binding + import legion_task_launcher_f_t + import legion_logical_region_f_t + implicit none + + integer(c_int) :: legion_task_launcher_add_region_requirement_logical_region_c + type(legion_task_launcher_f_t), value, intent(in) :: launcher + type(legion_logical_region_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: priv + integer(c_int), value, intent(in) :: prop + type(legion_logical_region_f_t), value, intent(in) :: parent + integer(c_long), value, intent(in) :: tag + logical(c_bool), value, intent(in) :: verified + end function legion_task_launcher_add_region_requirement_logical_region_c + + ! @see Legion::TaskLaunchxer::add_field() + subroutine legion_task_launcher_add_field_c(launcher, idx, fid, inst) & + bind(C, name="legion_task_launcher_add_field") + use iso_c_binding + import legion_task_launcher_f_t + implicit none + + type(legion_task_launcher_f_t), value, intent(in) :: launcher + integer(c_int), value, intent(in) :: idx + integer(c_int), value, intent(in) :: fid + logical(c_bool), value, intent(in) :: inst + end subroutine legion_task_launcher_add_field_c + + ! ----------------------------------------------------------------------- + ! Index Launcher + ! ----------------------------------------------------------------------- + ! @see Legion::IndexTaskLauncher::IndexTaskLauncher() + function legion_index_launcher_create_c(tid, domain, global_arg, map, pred, must, id, tag) & + bind(C, name="legion_index_launcher_create") + use iso_c_binding + import legion_index_launcher_f_t + import legion_domain_f_t + import legion_task_argument_f_t + import legion_argument_map_f_t + import legion_predicate_f_t + implicit none + + type(legion_index_launcher_f_t) :: legion_index_launcher_create_c + integer(c_int), value, intent(in) :: tid + type(legion_domain_f_t), value, intent(in) :: domain + type(legion_task_argument_f_t), value, intent(in) :: global_arg + type(legion_argument_map_f_t), value, intent(in) :: map + type(legion_predicate_f_t), value, intent(in) :: pred + logical(c_bool), value, intent(in) :: must + integer(c_int), value, intent(in) :: id + integer(c_long), value, intent(in) :: tag + end function legion_index_launcher_create_c + + ! @see Legion::IndexTaskLauncher::~IndexTaskLauncher() + subroutine legion_index_launcher_destroy_c(handle) & + bind(C, name="legion_index_launcher_destroy") + use iso_c_binding + import legion_index_launcher_f_t + implicit none + + type(legion_index_launcher_f_t), value, intent(in) :: handle + end subroutine legion_index_launcher_destroy_c + + ! @see Legion::Runtime::execute_index_space(Context, const IndexTaskLauncher &) + function legion_index_launcher_execute_c(runtime, ctx, launcher) & + bind(C, name="legion_index_launcher_execute") + use iso_c_binding + import legion_future_map_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_index_launcher_f_t + implicit none + + type(legion_future_map_f_t) :: legion_index_launcher_execute_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_index_launcher_f_t), value, intent(in) :: launcher + end function legion_index_launcher_execute_c + + ! @see Legion::Runtime::execute_index_space(Context, const IndexTaskLauncher &, ReductionOpID) + function legion_index_launcher_execute_reduction_c(runtime, ctx, launcher, redop) & + bind(C, name="legion_index_launcher_execute_reduction") + use iso_c_binding + import legion_future_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_index_launcher_f_t + implicit none + + type(legion_future_f_t) :: legion_index_launcher_execute_reduction_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_index_launcher_f_t), value, intent(in) :: launcher + integer(c_int), value, intent(in) :: redop + end function legion_index_launcher_execute_reduction_c + + ! @see Legion::IndexTaskLauncher::add_region_requirement() + function legion_index_launcher_add_region_requirement_lp_c(launcher, handle, proj, priv, & + prop, parent, tag, verified) & + bind (C, name="legion_index_launcher_add_region_requirement_logical_partition") + use iso_c_binding + import legion_index_launcher_f_t + import legion_logical_partition_f_t + import legion_logical_region_f_t + implicit none + + integer(c_int) :: legion_index_launcher_add_region_requirement_lp_c + type(legion_index_launcher_f_t), value, intent(in) :: launcher + type(legion_logical_partition_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: proj + integer(c_int), value, intent(in) :: priv + integer(c_int), value, intent(in) :: prop + type(legion_logical_region_f_t), value, intent(in) :: parent + integer(c_long), value, intent(in) :: tag + logical(c_bool), value, intent(in) :: verified + end function legion_index_launcher_add_region_requirement_lp_c + + ! @see Legion::TaskLaunchxer::add_field() + subroutine legion_index_launcher_add_field_c(launcher, idx, fid, inst) & + bind(C, name="legion_index_launcher_add_field") + use iso_c_binding + import legion_index_launcher_f_t + implicit none + + type(legion_index_launcher_f_t), value, intent(in) :: launcher + integer(c_int), value, intent(in) :: idx + integer(c_int), value, intent(in) :: fid + logical(c_bool), value, intent(in) :: inst + end subroutine legion_index_launcher_add_field_c + + ! ----------------------------------------------------------------------- + ! Predicate Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Predicate::TRUE_PRED + function legion_predicate_true_c() & + bind(C, name="legion_predicate_true") + use iso_c_binding + import legion_predicate_f_t + implicit none + + type(legion_predicate_f_t) :: legion_predicate_true_c + end function legion_predicate_true_c + + ! @see Legion::Predicate::FALSE_PRED + function legion_predicate_false_c() & + bind(C, name="legion_predicate_false") + use iso_c_binding + import legion_predicate_f_t + implicit none + + type(legion_predicate_f_t) :: legion_predicate_false_c + end function legion_predicate_false_c + + ! ----------------------------------------------------------------------- + ! Argument Map + ! ----------------------------------------------------------------------- + ! @see Legion::ArgumentMap::ArgumentMap() + function legion_argument_map_create_c() & + bind(C, name="legion_argument_map_create") + use iso_c_binding + import legion_argument_map_f_t + implicit none + + type(legion_argument_map_f_t) :: legion_argument_map_create_c + end function legion_argument_map_create_c + + ! @see Legion::ArgumentMap::set_point() + subroutine legion_argument_map_set_point_c(map, dp, arg, replace) & + bind(C, name="legion_argument_map_set_point") + use iso_c_binding + import legion_argument_map_f_t + import legion_domain_point_f_t + import legion_task_argument_f_t + implicit none + + type(legion_argument_map_f_t), value, intent(in) :: map + type(legion_domain_point_f_t), value, intent(in) :: dp + type(legion_task_argument_f_t), value, intent(in) :: arg + logical(c_bool), value, intent(in) :: replace + end subroutine legion_argument_map_set_point_c + + ! ----------------------------------------------------------------------- + ! Task Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Task::args + function legion_task_get_args_c(task) & + bind(C, name="legion_task_get_args") + use iso_c_binding + import legion_task_f_t + implicit none + + type(c_ptr) :: legion_task_get_args_c + type(legion_task_f_t), value, intent(in) :: task + end function legion_task_get_args_c + + ! @see Legion::Task::arglen + function legion_task_get_arglen_c(task) & + bind(C, name="legion_task_get_arglen") + use iso_c_binding + import legion_task_f_t + implicit none + + integer(c_size_t) :: legion_task_get_arglen_c + type(legion_task_f_t), value, intent(in) :: task + end function legion_task_get_arglen_c + + ! @see Legion::Task::local_args + function legion_task_get_local_args_c(task) & + bind(C, name="legion_task_get_local_args") + use iso_c_binding + import legion_task_f_t + implicit none + + type(c_ptr) :: legion_task_get_local_args_c + type(legion_task_f_t), value, intent(in) :: task + end function legion_task_get_local_args_c + + ! @see Legion::Task::local_arglen + function legion_task_get_local_arglen_c(task) & + bind(C, name="legion_task_get_local_arglen") + use iso_c_binding + import legion_task_f_t + implicit none + + integer(c_size_t) :: legion_task_get_local_arglen_c + type(legion_task_f_t), value, intent(in) :: task + end function legion_task_get_local_arglen_c + + ! @see Legion::Task::index_domain + function legion_task_get_index_domain_c(task) & + bind(C, name="legion_task_get_index_domain") + use iso_c_binding + import legion_domain_f_t + import legion_task_f_t + implicit none + + type(legion_domain_f_t) :: legion_task_get_index_domain_c + type(legion_task_f_t), value, intent(in) :: task + end function legion_task_get_index_domain_c + + ! @see Legion::Task::regions + function legion_task_get_region_c(task, idx) & + bind(C, name="legion_task_get_region") + use iso_c_binding + import legion_region_requirement_f_t + import legion_task_f_t + implicit none + + type(legion_region_requirement_f_t) :: legion_task_get_region_c + type(legion_task_f_t), value, intent(in) :: task + integer(c_int), value, intent(in) :: idx + end function legion_task_get_region_c + + ! ----------------------------------------------------------------------- + ! Domain Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Domain::from_rect() + function legion_domain_from_rect_1d_c(r) & + bind(C, name="legion_domain_from_rect_1d") + use iso_c_binding + import legion_rect_1d_f_t + import legion_domain_f_t + implicit none + + type(legion_domain_f_t) :: legion_domain_from_rect_1d_c + type(legion_rect_1d_f_t), value, intent(in) :: r + end function legion_domain_from_rect_1d_c + + ! @see Legion::Domain::from_rect() + function legion_domain_from_rect_2d_c(r) & + bind(C, name="legion_domain_from_rect_2d") + use iso_c_binding + import legion_rect_2d_f_t + import legion_domain_f_t + implicit none + + type(legion_domain_f_t) :: legion_domain_from_rect_2d_c + type(legion_rect_2d_f_t), value, intent(in) :: r + end function legion_domain_from_rect_2d_c + + ! @see Legion::Domain::from_rect() + function legion_domain_from_rect_3d_c(r) & + bind(C, name="legion_domain_from_rect_3d") + use iso_c_binding + import legion_rect_3d_f_t + import legion_domain_f_t + implicit none + + type(legion_domain_f_t) :: legion_domain_from_rect_3d_c + type(legion_rect_3d_f_t), value, intent(in) :: r + end function legion_domain_from_rect_3d_c + + ! @see Legion::Domain::get_rect() + function legion_domain_get_rect_1d_c(d) & + bind(C, name="legion_domain_get_rect_1d") + use iso_c_binding + import legion_rect_1d_f_t + import legion_domain_f_t + implicit none + + type(legion_rect_1d_f_t) :: legion_domain_get_rect_1d_c + type(legion_domain_f_t), value, intent(in) :: d + end function legion_domain_get_rect_1d_c + + ! @see Legion::Domain::get_rect() + function legion_domain_get_rect_2d_c(d) & + bind(C, name="legion_domain_get_rect_2d") + use iso_c_binding + import legion_rect_2d_f_t + import legion_domain_f_t + implicit none + + type(legion_rect_2d_f_t) :: legion_domain_get_rect_2d_c + type(legion_domain_f_t), value, intent(in) :: d + end function legion_domain_get_rect_2d_c + + ! @see Legion::Domain::get_rect() + function legion_domain_get_rect_3d_c(d) & + bind(C, name="legion_domain_get_rect_3d") + use iso_c_binding + import legion_rect_3d_f_t + import legion_domain_f_t + implicit none + + type(legion_rect_3d_f_t) :: legion_domain_get_rect_3d_c + type(legion_domain_f_t), value, intent(in) :: d + end function legion_domain_get_rect_3d_c + + ! @see Legion::Domain::get_volume() + function legion_domain_get_volume_c(d) & + bind(C, name="legion_domain_get_volume") + use iso_c_binding + import legion_domain_f_t + implicit none + + integer(c_size_t) :: legion_domain_get_volume_c + type(legion_domain_f_t), value, intent(in) :: d + end function legion_domain_get_volume_c + + ! ----------------------------------------------------------------------- + ! Domain Point Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Domain::from_point() + function legion_domain_point_from_point_1d_c(p) & + bind(C, name="legion_domain_point_from_point_1d") + use iso_c_binding + import legion_domain_point_f_t + import legion_point_1d_f_t + implicit none + + type(legion_domain_point_f_t) :: legion_domain_point_from_point_1d_c + type(legion_point_1d_f_t), value, intent(in) :: p + end function legion_domain_point_from_point_1d_c + + ! @see Legion::Domain::from_point() + function legion_domain_point_from_point_2d_c(p) & + bind(C, name="legion_domain_point_from_point_2d") + use iso_c_binding + import legion_domain_point_f_t + import legion_point_2d_f_t + implicit none + + type(legion_domain_point_f_t) :: legion_domain_point_from_point_2d_c + type(legion_point_2d_f_t), value, intent(in) :: p + end function legion_domain_point_from_point_2d_c + + ! @see Legion::Domain::from_point() + function legion_domain_point_from_point_3d_c(p) & + bind(C, name="legion_domain_point_from_point_3d") + use iso_c_binding + import legion_domain_point_f_t + import legion_point_3d_f_t + implicit none + + type(legion_domain_point_f_t) :: legion_domain_point_from_point_3d_c + type(legion_point_3d_f_t), value, intent(in) :: p + end function legion_domain_point_from_point_3d_c + + ! ----------------------------------------------------------------------- + ! Future Map Operations + ! ----------------------------------------------------------------------- + ! @see Legion::FutureMap::wait_all_results() + subroutine legion_future_map_wait_all_results_c(handle) & + bind(C, name="legion_future_map_wait_all_results") + use iso_c_binding + import legion_future_map_f_t + implicit none + + type(legion_future_map_f_t), value, intent(in) :: handle + end subroutine legion_future_map_wait_all_results_c + + ! ----------------------------------------------------------------------- + ! Index Space Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_index_space(Context, Domain) + function legion_index_space_create_domain_c(runtime, ctx, domain) & + bind(C, name="legion_index_space_create_domain") + use iso_c_binding + import legion_index_space_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_domain_f_t + implicit none + + type(legion_index_space_f_t) :: legion_index_space_create_domain_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_domain_f_t), value, intent(in) :: domain + end function legion_index_space_create_domain_c + + ! @see Legion::Runtime::destroy_index_space() + subroutine legion_index_space_destroy_c(runtime, ctx, handle) & + bind(C, name="legion_index_space_destroy") + use iso_c_binding + import legion_runtime_f_t + import legion_context_f_t + import legion_index_space_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_index_space_f_t), value, intent(in) :: handle + end subroutine legion_index_space_destroy_c + + ! @see Legion::Runtime::get_index_space_domain() + function legion_index_space_get_domain_c(runtime, handle) & + bind(C, name="legion_index_space_get_domain") + use iso_c_binding + import legion_domain_f_t + import legion_runtime_f_t + import legion_index_space_f_t + implicit none + + type(legion_domain_f_t) :: legion_index_space_get_domain_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_index_space_f_t), value, intent(in) :: handle + end function legion_index_space_get_domain_c + + ! @see Legion::Runtime::attach_name() + subroutine legion_index_space_attach_name_c(runtime, handle, name, is_mutable) & + bind (C, name="legion_index_space_attach_name") + use iso_c_binding + import legion_runtime_f_t + import legion_index_space_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_index_space_f_t), value, intent(in) :: handle + type(c_ptr), value, intent(in) :: name + logical(c_bool), value, intent(in) :: is_mutable + end subroutine legion_index_space_attach_name_c + + ! ----------------------------------------------------------------------- + ! Index Partition Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_equal_partition() + function legion_index_partition_create_equal_c(runtime, ctx, parent, color_space, granularity, color) & + bind(C, name="legion_index_partition_create_equal") + use iso_c_binding + import legion_index_partition_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_index_space_f_t + implicit none + + type(legion_index_partition_f_t) :: legion_index_partition_create_equal_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_index_space_f_t), value, intent(in) :: parent + type(legion_index_space_f_t), value, intent(in) :: color_space + integer(c_size_t), value, intent(in) :: granularity + integer(c_int), value, intent(in) :: color + end function legion_index_partition_create_equal_c + + ! @see Legion::Runtime::attach_name() + subroutine legion_index_partition_attach_name_c(runtime, handle, name, is_mutable) & + bind (C, name="legion_index_partition_attach_name") + use iso_c_binding + import legion_runtime_f_t + import legion_index_partition_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_index_partition_f_t), value, intent(in) :: handle + type(c_ptr), value, intent(in) :: name + logical(c_bool), value, intent(in) :: is_mutable + end subroutine legion_index_partition_attach_name_c + + ! ----------------------------------------------------------------------- + ! Logical Region Tree Traversal Operations + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::get_logical_partition() + function legion_logical_partition_create_c(runtime, ctx, parent, handle) & + bind (C, name="legion_logical_partition_create") + use iso_c_binding + import legion_logical_partition_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_logical_region_f_t + import legion_index_partition_f_t + implicit none + + type(legion_logical_partition_f_t) :: legion_logical_partition_create_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_logical_region_f_t), value, intent(in) :: parent + type(legion_index_partition_f_t), value, intent(in) :: handle + end function legion_logical_partition_create_c + + ! @see Legion::Runtime::attach_name() + subroutine legion_logical_partition_attach_name_c(runtime, handle, name, is_mutable) & + bind (C, name="legion_logical_partition_attach_name") + use iso_c_binding + import legion_runtime_f_t + import legion_logical_partition_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_logical_partition_f_t), value, intent(in) :: handle + type(c_ptr), value, intent(in) :: name + logical(c_bool), value, intent(in) :: is_mutable + end subroutine legion_logical_partition_attach_name_c + + ! ----------------------------------------------------------------------- + ! Field Space Operatiins + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_field_space() + function legion_field_space_create_c(runtime, ctx) & + bind(C, name="legion_field_space_create") + use iso_c_binding + import legion_field_space_f_t + import legion_runtime_f_t + import legion_context_f_t + implicit none + + type(legion_field_space_f_t) :: legion_field_space_create_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + end function legion_field_space_create_c + + ! @see Legion::Runtime::destroy_field_space() + subroutine legion_field_space_destroy_c(runtime, ctx, handle) & + bind(C, name="legion_field_space_destroy") + use iso_c_binding + import legion_runtime_f_t + import legion_context_f_t + import legion_field_space_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_field_space_f_t), value, intent(in) :: handle + end subroutine legion_field_space_destroy_c + + ! ----------------------------------------------------------------------- + ! Field Allocator + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_field_allocator() + function legion_field_allocator_create_c(runtime, ctx, handle) & + bind(C, name="legion_field_allocator_create") + use iso_c_binding + import legion_field_allocator_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_field_space_f_t + implicit none + + type(legion_field_allocator_f_t) :: legion_field_allocator_create_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_field_space_f_t), value, intent(in) :: handle + end function legion_field_allocator_create_c + + ! @see Legion::FieldAllocator::~FieldAllocator() + subroutine legion_field_allocator_destroy_c(handle) & + bind(C, name="legion_field_allocator_destroy") + use iso_c_binding + import legion_field_allocator_f_t + implicit none + + type(legion_field_allocator_f_t), value, intent(in) :: handle + end subroutine legion_field_allocator_destroy_c + + ! @see Legion::FieldAllocator::allocate_field() + function legion_field_allocator_allocate_field_c(allocator, field_size, desired_fieldid) & + bind (C, name="legion_field_allocator_allocate_field") + use iso_c_binding + import legion_field_allocator_f_t + implicit none + + integer(c_int) :: legion_field_allocator_allocate_field_c + type(legion_field_allocator_f_t), value, intent(in) :: allocator + integer(c_size_t), value, intent(in) :: field_size + integer(c_int), value, intent(in) :: desired_fieldid + end function legion_field_allocator_allocate_field_c + + ! ----------------------------------------------------------------------- + ! Logical Region + ! ----------------------------------------------------------------------- + ! @see Legion::Runtime::create_logical_region() + function legion_logical_region_create_c(runtime, ctx, index, fields) & + bind(C, name="legion_logical_region_create") + use iso_c_binding + import legion_logical_region_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_index_space_f_t + import legion_field_space_f_t + implicit none + + type(legion_logical_region_f_t) :: legion_logical_region_create_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_index_space_f_t), value, intent(in) :: index + type(legion_field_space_f_t), value, intent(in) :: fields + end function legion_logical_region_create_c + + ! @see Legion::Runtime::destroy_logical_region() + subroutine legion_logical_region_destroy_c(runtime, ctx, handle) & + bind(C, name="legion_logical_region_destroy") + use iso_c_binding + import legion_runtime_f_t + import legion_context_f_t + import legion_logical_region_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_logical_region_f_t), value, intent(in) :: handle + end subroutine legion_logical_region_destroy_c + + ! @see Legion::LogicalRegion::get_index_space + function legion_logical_region_get_index_space_c(handle) & + bind(C, name="legion_logical_region_get_index_space") + use iso_c_binding + import legion_index_space_f_t + import legion_logical_region_f_t + implicit none + + type(legion_index_space_f_t) :: legion_logical_region_get_index_space_c + type(legion_logical_region_f_t), value, intent(in) :: handle + end function legion_logical_region_get_index_space_c + + ! ----------------------------------------------------------------------- + ! Region Requirement Operations + ! ----------------------------------------------------------------------- + ! @see Legion::RegionRequirement::region + function legion_region_requirement_get_region_c(handle) & + bind(C, name="legion_region_requirement_get_region") + use iso_c_binding + import legion_region_requirement_f_t + import legion_logical_region_f_t + implicit none + + type(legion_logical_region_f_t) :: legion_region_requirement_get_region_c + type(legion_region_requirement_f_t), value, intent(in) :: handle + end function legion_region_requirement_get_region_c + + ! @see Legion::RegionRequirement::privilege_fields + function legion_region_requirement_get_privilege_field_c(handle, idx) & + bind (C, name="legion_region_requirement_get_privilege_field") + use iso_c_binding + import legion_region_requirement_f_t + implicit none + + integer(c_int) :: legion_region_requirement_get_privilege_field_c + type(legion_region_requirement_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: idx + end function legion_region_requirement_get_privilege_field_c + + ! ----------------------------------------------------------------------- + ! Physical Data Operations + ! ----------------------------------------------------------------------- + function legion_get_physical_region_by_id_c(regionptr, id, num_regions) & + bind(C, name="legion_get_physical_region_by_id") + use iso_c_binding + import legion_physical_region_f_t + implicit none + + type(legion_physical_region_f_t) :: legion_get_physical_region_by_id_c + type(c_ptr), value, intent(in) :: regionptr + integer(c_int), value, intent(in) :: id + integer(c_int), value, intent(in) :: num_regions + end function legion_get_physical_region_by_id_c + + ! @see Legion::PhysicalRegion::get_field_accessor() + function legion_physical_region_get_field_accessor_array_1d_c(handle, fid) & + bind(C, name="legion_physical_region_get_field_accessor_array_1d") + use iso_c_binding + import legion_accessor_array_1d_f_t + import legion_physical_region_f_t + implicit none + + type(legion_accessor_array_1d_f_t) :: legion_physical_region_get_field_accessor_array_1d_c + type(legion_physical_region_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: fid + end function legion_physical_region_get_field_accessor_array_1d_c + + ! @see Legion::PhysicalRegion::get_field_accessor() + function legion_physical_region_get_field_accessor_array_2d_c(handle, fid) & + bind(C, name="legion_physical_region_get_field_accessor_array_2d") + use iso_c_binding + import legion_accessor_array_2d_f_t + import legion_physical_region_f_t + implicit none + + type(legion_accessor_array_2d_f_t) :: legion_physical_region_get_field_accessor_array_2d_c + type(legion_physical_region_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: fid + end function legion_physical_region_get_field_accessor_array_2d_c + + ! @see Legion::PhysicalRegion::get_field_accessor() + function legion_physical_region_get_field_accessor_array_3d_c(handle, fid) & + bind(C, name="legion_physical_region_get_field_accessor_array_3d") + use iso_c_binding + import legion_accessor_array_3d_f_t + import legion_physical_region_f_t + implicit none + + type(legion_accessor_array_3d_f_t) :: legion_physical_region_get_field_accessor_array_3d_c + type(legion_physical_region_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: fid + end function legion_physical_region_get_field_accessor_array_3d_c + + ! @see Legion::UnsafeFieldAccessor::ptr + function legion_accessor_array_1d_raw_rect_ptr_c(handle, rect, subrect, offset) & + bind(C, name="legion_accessor_array_1d_raw_rect_ptr") + use iso_c_binding + import legion_accessor_array_1d_f_t + import legion_rect_1d_f_t + import legion_byte_offset_f_t + implicit none + + type(c_ptr) :: legion_accessor_array_1d_raw_rect_ptr_c + type(legion_accessor_array_1d_f_t), value, intent(in) :: handle + type(legion_rect_1d_f_t), value, intent(in) :: rect + type(legion_rect_1d_f_t), intent(out) :: subrect ! pass reference + type(legion_byte_offset_f_t), intent(out) :: offset ! pass reference + end function legion_accessor_array_1d_raw_rect_ptr_c + + ! @see Legion::UnsafeFieldAccessor::ptr + function legion_accessor_array_2d_raw_rect_ptr_c(handle, rect, subrect, offset) & + bind(C, name="legion_accessor_array_2d_raw_rect_ptr") + use iso_c_binding + import legion_accessor_array_2d_f_t + import legion_rect_2d_f_t + import legion_byte_offset_f_t + implicit none + + type(c_ptr) :: legion_accessor_array_2d_raw_rect_ptr_c + type(legion_accessor_array_2d_f_t), value, intent(in) :: handle + type(legion_rect_2d_f_t), value, intent(in) :: rect + type(legion_rect_2d_f_t), intent(out) :: subrect ! pass reference + type(legion_byte_offset_f_t), intent(out) :: offset(2) ! pass reference + end function legion_accessor_array_2d_raw_rect_ptr_c + + ! @see Legion::UnsafeFieldAccessor::ptr + function legion_accessor_array_3d_raw_rect_ptr_c(handle, rect, subrect, offset) & + bind(C, name="legion_accessor_array_3d_raw_rect_ptr") + use iso_c_binding + import legion_accessor_array_3d_f_t + import legion_rect_3d_f_t + import legion_byte_offset_f_t + implicit none + + type(c_ptr) :: legion_accessor_array_3d_raw_rect_ptr_c + type(legion_accessor_array_3d_f_t), value, intent(in) :: handle + type(legion_rect_3d_f_t), value, intent(in) :: rect + type(legion_rect_3d_f_t), intent(out) :: subrect ! pass reference + type(legion_byte_offset_f_t), intent(out) :: offset(3) ! pass reference + end function legion_accessor_array_3d_raw_rect_ptr_c + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_read_point_c(handle, point, dst, bytes) & + bind(C, name="legion_accessor_array_1d_read_point") + use iso_c_binding + import legion_accessor_array_1d_f_t + import legion_point_1d_f_t + implicit none + + type(legion_accessor_array_1d_f_t), value, intent(in) :: handle + type(legion_point_1d_f_t), value, intent(in) :: point + type(c_ptr), value, intent(in) :: dst ! should be OUT, set to IN to cheat compiler + integer(c_size_t), value, intent(in) :: bytes + end subroutine legion_accessor_array_1d_read_point_c + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_read_point_c(handle, point, dst, bytes) & + bind(C, name="legion_accessor_array_2d_read_point") + use iso_c_binding + import legion_accessor_array_2d_f_t + import legion_point_2d_f_t + implicit none + + type(legion_accessor_array_2d_f_t), value, intent(in) :: handle + type(legion_point_2d_f_t), value, intent(in) :: point + type(c_ptr), value, intent(in) :: dst ! should be OUT, set to IN to cheat compiler + integer(c_size_t), value, intent(in) :: bytes + end subroutine legion_accessor_array_2d_read_point_c + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_read_point_c(handle, point, dst, bytes) & + bind(C, name="legion_accessor_array_3d_read_point") + use iso_c_binding + import legion_accessor_array_3d_f_t + import legion_point_3d_f_t + implicit none + + type(legion_accessor_array_3d_f_t), value, intent(in) :: handle + type(legion_point_3d_f_t), value, intent(in) :: point + type(c_ptr), value, intent(in) :: dst ! should be OUT, set to IN to cheat compiler + integer(c_size_t), value, intent(in) :: bytes + end subroutine legion_accessor_array_3d_read_point_c + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_1d_write_point_c(handle, point, src, bytes) & + bind(C, name="legion_accessor_array_1d_write_point") + use iso_c_binding + import legion_accessor_array_1d_f_t + import legion_point_1d_f_t + implicit none + + type(legion_accessor_array_1d_f_t), value, intent(in) :: handle + type(legion_point_1d_f_t), value, intent(in) :: point + type(c_ptr), value, intent(in) :: src + integer(c_size_t), value, intent(in) :: bytes + end subroutine legion_accessor_array_1d_write_point_c + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_2d_write_point_c(handle, point, src, bytes) & + bind(C, name="legion_accessor_array_2d_write_point") + use iso_c_binding + import legion_accessor_array_2d_f_t + import legion_point_2d_f_t + implicit none + + type(legion_accessor_array_2d_f_t), value, intent(in) :: handle + type(legion_point_2d_f_t), value, intent(in) :: point + type(c_ptr), value, intent(in) :: src + integer(c_size_t), value, intent(in) :: bytes + end subroutine legion_accessor_array_2d_write_point_c + + ! @see Legion::UnsafeFieldAccessor::ptr + subroutine legion_accessor_array_3d_write_point_c(handle, point, src, bytes) & + bind(C, name="legion_accessor_array_3d_write_point") + use iso_c_binding + import legion_accessor_array_3d_f_t + import legion_point_3d_f_t + implicit none + + type(legion_accessor_array_3d_f_t), value, intent(in) :: handle + type(legion_point_3d_f_t), value, intent(in) :: point + type(c_ptr), value, intent(in) :: src + integer(c_size_t), value, intent(in) :: bytes + end subroutine legion_accessor_array_3d_write_point_c + + ! ----------------------------------------------------------------------- + ! File Operations + ! ----------------------------------------------------------------------- + function legion_field_map_create_c() & + bind(C, name="legion_field_map_create") + use iso_c_binding + import legion_field_map_f_t + implicit none + + type(legion_field_map_f_t) :: legion_field_map_create_c + end function legion_field_map_create_c + + subroutine legion_field_map_destroy_c(handle) & + bind(C, name="legion_field_map_destroy") + use iso_c_binding + import legion_field_map_f_t + implicit none + + type(legion_field_map_f_t), value, intent(in) :: handle + end subroutine legion_field_map_destroy_c + + subroutine legion_field_map_insert_c(handle, key, value) & + bind(C, name="legion_field_map_insert") + use iso_c_binding + import legion_field_map_f_t + implicit none + + type(legion_field_map_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: key + type(c_ptr), value, intent(in) :: value + end subroutine legion_field_map_insert_c + + ! @see Legion::Runtime::attach_hdf5() + function legion_runtime_attach_hdf5_c(runtime, ctx, filename, handle, parent, field_map, mode) & + bind(C, name="legion_runtime_attach_hdf5") + use iso_c_binding + import legion_physical_region_f_t + import legion_runtime_f_t + import legion_context_f_t + import legion_logical_region_f_t + import legion_field_map_f_t + implicit none + + type(legion_physical_region_f_t) :: legion_runtime_attach_hdf5_c + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(c_ptr), value, intent(in) :: filename + type(legion_logical_region_f_t), value, intent(in) :: handle + type(legion_logical_region_f_t), value, intent(in) :: parent + type(legion_field_map_f_t), value, intent(in) :: field_map + integer(c_int), value, intent(in) :: mode + end function legion_runtime_attach_hdf5_c + + ! @see Legion::Runtime::detach_hdf5() + subroutine legion_runtime_detach_hdf5_c(runtime, ctx, region) & + bind(C, name="legion_runtime_detach_hdf5") + use iso_c_binding + import legion_runtime_f_t + import legion_context_f_t + import legion_physical_region_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_physical_region_f_t), value, intent(in) :: region + end subroutine legion_runtime_detach_hdf5_c + ! ----------------------------------------------------------------------- + ! Copy Operations + ! ----------------------------------------------------------------------- + ! @see Legion::CopyLauncher::CopyLauncher() + function legion_copy_launcher_create_c(pred, id, launcher_tag) & + bind(C, name="legion_copy_launcher_create") + use iso_c_binding + import legion_copy_launcher_f_t + import legion_predicate_f_t + implicit none + + type(legion_copy_launcher_f_t) :: legion_copy_launcher_create_c + type(legion_predicate_f_t), value, intent(in) :: pred + integer(c_int), value, intent(in) :: id + integer(c_long), value, intent(in) :: launcher_tag + end function legion_copy_launcher_create_c + + ! @see Legion::CopyLauncher::~CopyLauncher() + subroutine legion_copy_launcher_destroy_c(handle) & + bind(C, name="legion_copy_launcher_destroy") + use iso_c_binding + import legion_copy_launcher_f_t + implicit none + + type(legion_copy_launcher_f_t), value, intent(in) :: handle + end subroutine legion_copy_launcher_destroy_c + + ! @see Legion::Runtime::issue_copy_operation() + subroutine legion_copy_launcher_execute_c(runtime, ctx, launcher) & + bind(C, name="legion_copy_launcher_execute") + use iso_c_binding + import legion_runtime_f_t + import legion_context_f_t + import legion_copy_launcher_f_t + implicit none + + type(legion_runtime_f_t), value, intent(in) :: runtime + type(legion_context_f_t), value, intent(in) :: ctx + type(legion_copy_launcher_f_t), value, intent(in) :: launcher + end subroutine legion_copy_launcher_execute_c + + ! @see Legion::CopyLauncher::add_copy_requirements() + function legion_copy_launcher_add_src_region_requirement_lr_c(launcher, handle, priv, prop, & + parent, tag, verified) & + bind(C, name="legion_copy_launcher_add_src_region_requirement_logical_region") + use iso_c_binding + import legion_copy_launcher_f_t + import legion_logical_region_f_t + implicit none + + integer(c_int) :: legion_copy_launcher_add_src_region_requirement_lr_c + type(legion_copy_launcher_f_t), value, intent(in) :: launcher + type(legion_logical_region_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: priv + integer(c_int), value, intent(in) :: prop + type(legion_logical_region_f_t), value, intent(in) :: parent + integer(c_long), value, intent(in) :: tag + logical(c_bool), value, intent(in) :: verified + end function legion_copy_launcher_add_src_region_requirement_lr_c + + ! @see Legion::CopyLauncher::add_copy_requirements() + function legion_copy_launcher_add_dst_region_requirement_lr_c(launcher, handle, priv, prop, & + parent, tag, verified) & + bind(C, name="legion_copy_launcher_add_dst_region_requirement_logical_region") + use iso_c_binding + import legion_copy_launcher_f_t + import legion_logical_region_f_t + implicit none + + integer(c_int) :: legion_copy_launcher_add_dst_region_requirement_lr_c + type(legion_copy_launcher_f_t), value, intent(in) :: launcher + type(legion_logical_region_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: priv + integer(c_int), value, intent(in) :: prop + type(legion_logical_region_f_t), value, intent(in) :: parent + integer(c_long), value, intent(in) :: tag + logical(c_bool), value, intent(in) :: verified + end function legion_copy_launcher_add_dst_region_requirement_lr_c + + ! @see Legion::CopyLauncher::add_src_field() + subroutine legion_copy_launcher_add_src_field_c(launcher, idx, fid, inst) & + bind(C, name="legion_copy_launcher_add_src_field") + use iso_c_binding + import legion_copy_launcher_f_t + implicit none + + type(legion_copy_launcher_f_t), value, intent(in) :: launcher + integer(c_int), value, intent(in) :: idx + integer(c_int), value, intent(in) :: fid + logical(c_bool), value, intent(in) :: inst + end subroutine legion_copy_launcher_add_src_field_c + + ! @see Legion::CopyLauncher::add_dst_field() + subroutine legion_copy_launcher_add_dst_field_c(launcher, idx, fid, inst) & + bind(C, name="legion_copy_launcher_add_dst_field") + use iso_c_binding + import legion_copy_launcher_f_t + implicit none + + type(legion_copy_launcher_f_t), value, intent(in) :: launcher + integer(c_int), value, intent(in) :: idx + integer(c_int), value, intent(in) :: fid + logical(c_bool), value, intent(in) :: inst + end subroutine legion_copy_launcher_add_dst_field_c + + ! ----------------------------------------------------------------------- + ! Combined Operations + ! ----------------------------------------------------------------------- + function legion_task_get_index_space_from_logical_region_c(handle, tid) & + bind (C, name="legion_task_get_index_space_from_logical_region") + use iso_c_binding + import legion_index_space_f_t + import legion_task_f_t + implicit none + + type(legion_index_space_f_t) :: legion_task_get_index_space_from_logical_region_c + type(legion_task_f_t), value, intent(in) :: handle + integer(c_int), value, intent(in) :: tid + end function legion_task_get_index_space_from_logical_region_c + + subroutine legion_convert_1d_to_2d_column_major_c(src, dst, offset, num_columns) & + bind (C, name="legion_convert_1d_to_2d_column_major") + use iso_c_binding + import legion_byte_offset_f_t + implicit none + + type(c_ptr), value, intent(in) :: src + type(c_ptr), intent(in) :: dst(num_columns) ! this is OUT, set IN to cheat compiler + type(legion_byte_offset_f_t), value, intent(in) :: offset + integer(c_int), value, intent(in) :: num_columns + end subroutine + end interface +end module diff --git a/runtime/legion/legion_f_oo.f90 b/runtime/legion/legion_f_oo.f90 new file mode 100644 index 0000000000..1d57b62694 --- /dev/null +++ b/runtime/legion/legion_f_oo.f90 @@ -0,0 +1,473 @@ +module legion_fortran_object_oriented + use, intrinsic :: iso_c_binding + use legion_fortran_types + use legion_fortran_c_interface + implicit none + + ! Point Class + type LegionPoint + integer :: dim + end type LegionPoint + + type, extends(LegionPoint) :: LegionPoint1D + type(legion_point_1d_f_t) :: point + end type LegionPoint1D + + type, extends(LegionPoint) :: LegionPoint2D + type(legion_point_2d_f_t) :: point + end type LegionPoint2D + + type, extends(LegionPoint) :: LegionPoint3D + type(legion_point_3d_f_t) :: point + end type LegionPoint3D + + interface LegionPoint1D + module procedure legion_point_1d_constructor_integer4 + module procedure legion_point_1d_constructor_integer8 + end interface + + interface LegionPoint2D + module procedure legion_point_2d_constructor_integer4 + module procedure legion_point_2d_constructor_integer8 + end interface + + interface LegionPoint3D + module procedure legion_point_3d_constructor_integer4 + module procedure legion_point_3d_constructor_integer8 + end interface + + ! Accessor Class + type LegionFieldAccessor + integer :: dim + integer(c_size_t) :: data_size + contains + procedure :: init => legion_field_accessor_init + procedure, private :: legion_field_accessor_read_point_ptr + procedure, private :: legion_field_accessor_read_point_integer4 + procedure, private :: legion_field_accessor_read_point_integer8 + procedure, private :: legion_field_accessor_read_point_real4 + procedure, private :: legion_field_accessor_read_point_real8 + procedure, private :: legion_field_accessor_read_point_complex4 + procedure, private :: legion_field_accessor_read_point_complex8 + procedure, private :: legion_field_accessor_write_point_ptr + procedure, private :: legion_field_accessor_write_point_integer4 + procedure, private :: legion_field_accessor_write_point_integer8 + procedure, private :: legion_field_accessor_write_point_real4 + procedure, private :: legion_field_accessor_write_point_real8 + procedure, private :: legion_field_accessor_write_point_complex4 + procedure, private :: legion_field_accessor_write_point_complex8 + generic :: read_point => legion_field_accessor_read_point_ptr, & + legion_field_accessor_read_point_integer4, legion_field_accessor_read_point_integer8, & + legion_field_accessor_read_point_real4, legion_field_accessor_read_point_real8, & + legion_field_accessor_read_point_complex4, legion_field_accessor_read_point_complex8 + generic :: write_point => legion_field_accessor_write_point_ptr, & + legion_field_accessor_write_point_integer4, legion_field_accessor_write_point_integer8, & + legion_field_accessor_write_point_real4, legion_field_accessor_write_point_real8, & + legion_field_accessor_write_point_complex4, legion_field_accessor_write_point_complex8 + end type LegionFieldAccessor + + type, extends(LegionFieldAccessor) :: LegionFieldAccessor1D + type(legion_accessor_array_1d_f_t) :: accessor + end type LegionFieldAccessor1D + + type, extends(LegionFieldAccessor) :: LegionFieldAccessor2D + type(legion_accessor_array_2d_f_t) :: accessor + end type LegionFieldAccessor2D + + type, extends(LegionFieldAccessor) :: LegionFieldAccessor3D + type(legion_accessor_array_3d_f_t) :: accessor + end type LegionFieldAccessor3D + + interface LegionFieldAccessor1D + module procedure legion_field_accessor_1d_constructor + end interface + + interface LegionFieldAccessor2D + module procedure legion_field_accessor_2d_constructor + end interface + + interface LegionFieldAccessor3D + module procedure legion_field_accessor_3d_constructor + end interface + + Type CellReal8 + real(kind=8), dimension(:), pointer :: y + end type CellReal8 + + type LegionArray2DReal8 + type(CellReal8), dimension(3) :: x + integer :: dim_x + integer :: dim_y + integer :: ld + end type LegionArray2DReal8 + + interface LegionArray2DReal8 + module procedure legion_array_2d_real8_constructor + end interface +contains + + function legion_point_1d_constructor_integer4(x) + implicit none + + type(LegionPoint1D) :: legion_point_1d_constructor_integer4 + integer(kind=4), intent(in) :: x + + legion_point_1d_constructor_integer4%point%x(0) = int(x, 8) + + end function legion_point_1d_constructor_integer4 + + function legion_point_1d_constructor_integer8(x) + implicit none + + type(LegionPoint1D) :: legion_point_1d_constructor_integer8 + integer(kind=8), intent(in) :: x + + legion_point_1d_constructor_integer8%point%x(0) = x + + end function legion_point_1d_constructor_integer8 + + function legion_point_2d_constructor_integer4(x, y) + implicit none + + type(LegionPoint2D) :: legion_point_2d_constructor_integer4 + integer(kind=4), intent(in) :: x + integer(kind=4), intent(in) :: y + + legion_point_2d_constructor_integer4%point%x(0) = int(x, 8) + legion_point_2d_constructor_integer4%point%x(1) = int(y, 8) + + end function legion_point_2d_constructor_integer4 + + function legion_point_2d_constructor_integer8(x, y) + implicit none + + type(LegionPoint2D) :: legion_point_2d_constructor_integer8 + integer(kind=8), intent(in) :: x + integer(kind=8), intent(in) :: y + + legion_point_2d_constructor_integer8%point%x(0) = x + legion_point_2d_constructor_integer8%point%x(1) = y + + end function legion_point_2d_constructor_integer8 + + function legion_point_3d_constructor_integer4(x, y, z) + implicit none + + type(LegionPoint3D) :: legion_point_3d_constructor_integer4 + integer(kind=4), intent(in) :: x + integer(kind=4), intent(in) :: y + integer(kind=4), intent(in) :: z + + legion_point_3d_constructor_integer4%point%x(0) = int(x, 8) + legion_point_3d_constructor_integer4%point%x(1) = int(y, 8) + legion_point_3d_constructor_integer4%point%x(2) = int(z, 8) + + end function legion_point_3d_constructor_integer4 + + function legion_point_3d_constructor_integer8(x, y, z) + implicit none + + type(LegionPoint3D) :: legion_point_3d_constructor_integer8 + integer(kind=8), intent(in) :: x + integer(kind=8), intent(in) :: y + integer(kind=8), intent(in) :: z + + legion_point_3d_constructor_integer8%point%x(0) = x + legion_point_3d_constructor_integer8%point%x(1) = y + legion_point_3d_constructor_integer8%point%x(2) = z + + end function legion_point_3d_constructor_integer8 + + function legion_field_accessor_1d_constructor(physical_region, fid, data_size) + implicit none + + type(LegionFieldAccessor1D) :: legion_field_accessor_1d_constructor + type(legion_physical_region_f_t), intent(in) :: physical_region + integer(c_int), intent(in) :: fid + integer(c_size_t), intent(in) :: data_size + + + legion_field_accessor_1d_constructor%dim = 1 + legion_field_accessor_1d_constructor%data_size = data_size + legion_field_accessor_1d_constructor%accessor = legion_physical_region_get_field_accessor_array_1d_c(physical_region, fid) + end function legion_field_accessor_1d_constructor + + function legion_field_accessor_2d_constructor(physical_region, fid, data_size) + implicit none + + type(LegionFieldAccessor2D) :: legion_field_accessor_2d_constructor + type(legion_physical_region_f_t), intent(in) :: physical_region + integer(c_int), intent(in) :: fid + integer(c_size_t), intent(in) :: data_size + + + legion_field_accessor_2d_constructor%dim = 1 + legion_field_accessor_2d_constructor%data_size = data_size + legion_field_accessor_2d_constructor%accessor = legion_physical_region_get_field_accessor_array_2d_c(physical_region, fid) + end function legion_field_accessor_2d_constructor + + function legion_field_accessor_3d_constructor(physical_region, fid, data_size) + implicit none + + type(LegionFieldAccessor3D) :: legion_field_accessor_3d_constructor + type(legion_physical_region_f_t), intent(in) :: physical_region + integer(c_int), intent(in) :: fid + integer(c_size_t), intent(in) :: data_size + + + legion_field_accessor_3d_constructor%dim = 1 + legion_field_accessor_3d_constructor%data_size = data_size + legion_field_accessor_3d_constructor%accessor = legion_physical_region_get_field_accessor_array_3d_c(physical_region, fid) + end function legion_field_accessor_3d_constructor + + subroutine legion_field_accessor_init(this, physical_region, fid, data_size) + implicit none + + class(LegionFieldAccessor), intent(inout) :: this + type(legion_physical_region_f_t), intent(in) :: physical_region + integer(c_int), intent(in) :: fid + integer(c_size_t), intent(in) :: data_size + + select type (this) + type is (LegionFieldAccessor1D) + ! 1D + this%dim = 1 + this%data_size = data_size + this%accessor = legion_physical_region_get_field_accessor_array_1d_c(physical_region, fid) + type is (LegionFieldAccessor2D) + ! 2D + this%dim = 2 + this%data_size = data_size + this%accessor = legion_physical_region_get_field_accessor_array_2d_c(physical_region, fid) + type is (LegionFieldAccessor3D) + ! 3D + this%dim = 3 + this%data_size = data_size + this%accessor = legion_physical_region_get_field_accessor_array_3d_c(physical_region, fid) + class default + ! give error for unexpected/unsupported type + stop 'initialize: unexpected type for LegionFieldAccessor object!' + end select + end subroutine legion_field_accessor_init + + subroutine legion_field_accessor_read_point_ptr(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + type(c_ptr) :: dst + + select type (this) + type is (LegionFieldAccessor1D) + ! 1D + select type (point) + type is (LegionPoint1D) + call legion_accessor_array_1d_read_point_c(this%accessor, point%point, dst, this%data_size) + end select + type is (LegionFieldAccessor2D) + ! 2D + select type (point) + type is (LegionPoint2D) + call legion_accessor_array_2d_read_point_c(this%accessor, point%point, dst, this%data_size) + end select + type is (LegionFieldAccessor3D) + ! 3D + select type (point) + type is (LegionPoint3D) + call legion_accessor_array_3d_read_point_c(this%accessor, point%point, dst, this%data_size) + end select + class default + ! give error for unexpected/unsupported type + stop 'initialize: unexpected type for LegionFieldAccessor object!' + end select + end subroutine legion_field_accessor_read_point_ptr + + subroutine legion_field_accessor_read_point_integer4(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + integer(kind=4), target, intent(out) :: dst + + call legion_field_accessor_read_point_ptr(this, point, c_loc(dst)) + end subroutine legion_field_accessor_read_point_integer4 + + subroutine legion_field_accessor_read_point_integer8(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + integer(kind=8), target, intent(out) :: dst + + call legion_field_accessor_read_point_ptr(this, point, c_loc(dst)) + end subroutine legion_field_accessor_read_point_integer8 + + subroutine legion_field_accessor_read_point_real4(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + real(kind=4), target, intent(out) :: dst + + call legion_field_accessor_read_point_ptr(this, point, c_loc(dst)) + end subroutine legion_field_accessor_read_point_real4 + + subroutine legion_field_accessor_read_point_real8(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + real(kind=8), target, intent(out) :: dst + + call legion_field_accessor_read_point_ptr(this, point, c_loc(dst)) + end subroutine legion_field_accessor_read_point_real8 + + subroutine legion_field_accessor_read_point_complex4(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + complex(kind=4), target, intent(out) :: dst + + call legion_field_accessor_read_point_ptr(this, point, c_loc(dst)) + end subroutine legion_field_accessor_read_point_complex4 + + subroutine legion_field_accessor_read_point_complex8(this, point, dst) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + complex(kind=8), target, intent(out) :: dst + + call legion_field_accessor_read_point_ptr(this, point, c_loc(dst)) + end subroutine legion_field_accessor_read_point_complex8 + + subroutine legion_field_accessor_write_point_ptr(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + type(c_ptr), intent(in) :: src + + select type (this) + type is (LegionFieldAccessor1D) + ! 1D + select type (point) + type is (LegionPoint1D) + call legion_accessor_array_1d_write_point_c(this%accessor, point%point, src, this%data_size) + end select + type is (LegionFieldAccessor2D) + ! 2D + select type (point) + type is (LegionPoint2D) + call legion_accessor_array_2d_write_point_c(this%accessor, point%point, src, this%data_size) + end select + type is (LegionFieldAccessor3D) + ! 3D + select type (point) + type is (LegionPoint3D) + call legion_accessor_array_3d_write_point_c(this%accessor, point%point, src, this%data_size) + end select + class default + ! give error for unexpected/unsupported type + stop 'initialize: unexpected type for LegionFieldAccessor object!' + end select + end subroutine legion_field_accessor_write_point_ptr + + subroutine legion_field_accessor_write_point_integer4(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + integer(kind=4), target, intent(in) :: src + + call legion_field_accessor_write_point_ptr(this, point, c_loc(src)) + end subroutine legion_field_accessor_write_point_integer4 + + subroutine legion_field_accessor_write_point_integer8(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + integer(kind=8), target, intent(in) :: src + + call legion_field_accessor_write_point_ptr(this, point, c_loc(src)) + end subroutine legion_field_accessor_write_point_integer8 + + subroutine legion_field_accessor_write_point_real4(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + real(kind=4), target, intent(in) :: src + + call legion_field_accessor_write_point_ptr(this, point, c_loc(src)) + end subroutine legion_field_accessor_write_point_real4 + + subroutine legion_field_accessor_write_point_real8(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + real(kind=8), target, intent(in) :: src + + call legion_field_accessor_write_point_ptr(this, point, c_loc(src)) + end subroutine legion_field_accessor_write_point_real8 + + subroutine legion_field_accessor_write_point_complex4(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + complex(kind=4), target, intent(in) :: src + + call legion_field_accessor_write_point_ptr(this, point, c_loc(src)) + end subroutine legion_field_accessor_write_point_complex4 + + subroutine legion_field_accessor_write_point_complex8(this, point, src) + implicit none + + class(LegionFieldAccessor), intent(in) :: this + class(LegionPoint), intent(in) :: point + complex(kind=8), target, intent(in) :: src + + call legion_field_accessor_write_point_ptr(this, point, c_loc(src)) + end subroutine legion_field_accessor_write_point_complex8 + + function legion_array_2d_real8_constructor(raw_ptr, num_rows, num_columns, ld) + implicit none + + type(LegionArray2DReal8) :: legion_array_2d_real8_constructor + type(c_ptr), intent(in) :: raw_ptr + integer, intent(in) :: num_rows + integer, intent(in) :: num_columns + type(legion_byte_offset_f_t), intent(in) :: ld + + type(c_ptr), allocatable :: ptr_columns(:) + type(LegionArray2DReal8) :: tmp_2d_array + real(kind=8), pointer :: column(:) + real(kind=8), target :: col(10) + integer :: i + type(CellReal8), allocatable :: matrix(:) + + allocate(matrix(num_columns)) + + ! allocate(tmp_2d_array%x(1:num_columns)) + col(1:10) = 1 + tmp_2d_array%x(1)%y(1:10) => col + matrix(1)%y =>col + column => col + + tmp_2d_array%dim_x = num_columns + tmp_2d_array%dim_y = num_rows + tmp_2d_array%ld = ld%offset + allocate(ptr_columns(num_columns)) + call legion_convert_1d_to_2d_column_major_c(raw_ptr, ptr_columns, ld, num_columns) + do i = 1, num_columns + call c_f_pointer(ptr_columns(i), column, [num_rows]) + call c_f_pointer(ptr_columns(i), tmp_2d_array%x(i)%y, [num_rows]) + end do + legion_array_2d_real8_constructor = tmp_2d_array + end function legion_array_2d_real8_constructor + +end module \ No newline at end of file diff --git a/runtime/legion/legion_f_types.f90 b/runtime/legion/legion_f_types.f90 new file mode 100644 index 0000000000..ec98d6c65a --- /dev/null +++ b/runtime/legion/legion_f_types.f90 @@ -0,0 +1,177 @@ +module legion_fortran_types + use, intrinsic :: iso_c_binding + implicit none + + ! legion_privilege_mode_t + integer(c_int), parameter :: NO_ACCESS = Z'00000000' + integer(c_int), parameter :: READ_PRIV = Z'00000001' + integer(c_int), parameter :: READ_ONLY = Z'00000001' + integer(c_int), parameter :: WRITE_PRIV = Z'00000002' + integer(c_int), parameter :: REDUCE_PRIV = Z'00000004' + integer(c_int), parameter :: REDUCE = Z'00000004' + integer(c_int), parameter :: READ_WRITE = Z'00000007' + integer(c_int), parameter :: DISCARD_MASK = Z'10000000' + integer(c_int), parameter :: WRITE_ONLY = Z'10000002' + integer(c_int), parameter :: WRITE_DISCARD = Z'10000007' + + ! legion_coherence_property_t + integer(c_int), parameter :: EXCLUSIVE = 0 + integer(c_int), parameter :: ATOMIC = 1 + integer(c_int), parameter :: SIMULTANEOUS = 2 + integer(c_int), parameter :: RELAXED = 3 + + !legion_file_mode_t + integer(c_int), parameter :: LEGION_FILE_READ_ONLY = 0 + integer(c_int), parameter :: LEGION_FILE_READ_WRITE = 0 + integer(c_int), parameter :: LEGION_FILE_CREATE = 0 + + !legion_processor_kind_t + integer(c_int), parameter :: NO_KIND = 0 + integer(c_int), parameter :: TOC_PROC = 1 + integer(c_int), parameter :: LOC_PROC = 2 + integer(c_int), parameter :: UTIL_PROC = 3 + integer(c_int), parameter :: IO_PROC = 4 + integer(c_int), parameter :: PROC_GROUP = 5 + integer(c_int), parameter :: PROC_SET = 6 + integer(c_int), parameter :: OMP_PROC = 7 + integer(c_int), parameter :: PY_PROC = 8 + + ! C NEW_OPAQUE_TYPE_F +#define NEW_OPAQUE_TYPE_F(T) type, bind(C) :: T; type(c_ptr) :: impl; end type T + NEW_OPAQUE_TYPE_F(legion_runtime_f_t) + NEW_OPAQUE_TYPE_F(legion_context_f_t) + NEW_OPAQUE_TYPE_F(legion_domain_point_iterator_f_t) + NEW_OPAQUE_TYPE_F(legion_coloring_f_t) + NEW_OPAQUE_TYPE_F(legion_domain_coloring_f_t) + NEW_OPAQUE_TYPE_F(legion_point_coloring_f_t) + NEW_OPAQUE_TYPE_F(legion_domain_point_coloring_f_t) + NEW_OPAQUE_TYPE_F(legion_multi_domain_point_coloring_f_t) + NEW_OPAQUE_TYPE_F(legion_index_space_allocator_f_t) + NEW_OPAQUE_TYPE_F(legion_field_allocator_f_t) + NEW_OPAQUE_TYPE_F(legion_argument_map_f_t) + NEW_OPAQUE_TYPE_F(legion_predicate_f_t) + NEW_OPAQUE_TYPE_F(legion_future_f_t) + NEW_OPAQUE_TYPE_F(legion_future_map_f_t) + NEW_OPAQUE_TYPE_F(legion_task_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_index_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_inline_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_copy_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_acquire_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_release_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_must_epoch_launcher_f_t) + NEW_OPAQUE_TYPE_F(legion_physical_region_f_t) + NEW_OPAQUE_TYPE_F(legion_accessor_array_1d_f_t) + NEW_OPAQUE_TYPE_F(legion_accessor_array_2d_f_t) + NEW_OPAQUE_TYPE_F(legion_accessor_array_3d_f_t) + NEW_OPAQUE_TYPE_F(legion_index_iterator_f_t) + NEW_OPAQUE_TYPE_F(legion_task_f_t) + NEW_OPAQUE_TYPE_F(legion_inline_f_t) + NEW_OPAQUE_TYPE_F(legion_mappable_f_t) + NEW_OPAQUE_TYPE_F(legion_region_requirement_f_t) + NEW_OPAQUE_TYPE_F(legion_machine_f_t) + NEW_OPAQUE_TYPE_F(legion_mapper_f_t) + NEW_OPAQUE_TYPE_F(legion_default_mapper_f_t) + NEW_OPAQUE_TYPE_F(legion_processor_query_f_t) + NEW_OPAQUE_TYPE_F(legion_memory_query_f_t) + NEW_OPAQUE_TYPE_F(legion_machine_query_interface_f_t) + NEW_OPAQUE_TYPE_F(legion_execution_constraint_set_f_t) + NEW_OPAQUE_TYPE_F(legion_layout_constraint_set_f_t) + NEW_OPAQUE_TYPE_F(legion_task_layout_constraint_set_f_t) + NEW_OPAQUE_TYPE_F(legion_slice_task_output_f_t) + NEW_OPAQUE_TYPE_F(legion_map_task_input_f_t) + NEW_OPAQUE_TYPE_F(legion_map_task_output_f_t) + NEW_OPAQUE_TYPE_F(legion_physical_instance_f_t) + NEW_OPAQUE_TYPE_F(legion_mapper_runtime_f_t) + NEW_OPAQUE_TYPE_F(legion_mapper_context_f_t) + NEW_OPAQUE_TYPE_F(legion_field_map_f_t) +#undef NEW_OPAQUE_TYPE_F + + ! point 1d, 2d, 3d +#define NEW_POINT_TYPE_F(T, DIM) type, bind(C) :: T; integer(c_long_long), dimension(0:DIM-1) :: x; end type T + NEW_POINT_TYPE_F(legion_point_1d_f_t, 1) + NEW_POINT_TYPE_F(legion_point_2d_f_t, 2) + NEW_POINT_TYPE_F(legion_point_3d_f_t, 3) +#undef NEW_POINT_TYPE_F + + ! rect 1d, 2d, 3d +#define NEW_RECT_TYPE_F(T, PT) type, bind(C) :: T; type(PT) :: lo, hi; end type T + NEW_RECT_TYPE_F(legion_rect_1d_f_t, legion_point_1d_f_t) + NEW_RECT_TYPE_F(legion_rect_2d_f_t, legion_point_2d_f_t) + NEW_RECT_TYPE_F(legion_rect_3d_f_t, legion_point_3d_f_t) +#undef NEW_RECT_TYPE_F + + ! Legion::Domain + type, bind(C) :: legion_domain_f_t + integer(c_long_long) :: is_id + integer(c_int) :: dim + ! check MAX_DOMAIN_DIM = 2 * REALM_MAX_RECT_DIM +#define MAX_DOMAIN_DIM_F 6 + integer(c_long_long), dimension(0:MAX_DOMAIN_DIM_F-1) :: rect_data +#undef MAX_DOMAIN_DIM_F + end type legion_domain_f_t + + ! Legion::DomainPoint + type, bind(C) :: legion_domain_point_f_t + integer(c_int) :: dim +#define MAX_POINT_DIM_F 6 + integer(c_long_long), dimension(0:MAX_POINT_DIM_F-1) :: point_data +#undef MAX_POINT_DIM_F + end type legion_domain_point_f_t + + ! Legion::IndexSpace + type, bind(C) :: legion_index_space_f_t + integer(c_int) :: id + integer(c_int) :: tid + integer(c_int) :: type_tag + end type legion_index_space_f_t + + ! Legion::IndexPartition + type, bind(C) :: legion_index_partition_f_t + integer(c_int) :: id + integer(c_int) :: tid + integer(c_int) :: type_tag + end type legion_index_partition_f_t + + ! Legion::FieldSpace + type, bind(C) :: legion_field_space_f_t + integer(c_int) :: id + end type legion_field_space_f_t + + ! Legion::LogicalRegion + type, bind(C) :: legion_logical_region_f_t + integer(c_int) :: tree_id + type(legion_index_space_f_t) :: index_space + type(legion_field_space_f_t) :: field_space + end type legion_logical_region_f_t + + ! Legion::LogicalPartition + type, bind(C) :: legion_logical_partition_f_t + integer(c_int) :: tree_id + type(legion_index_partition_f_t) :: index_partition + type(legion_field_space_f_t) :: field_space + end type legion_logical_partition_f_t + + ! Legion::TaskConfigOptions + type, bind(C) :: legion_task_config_options_f_t + logical(c_bool) :: leaf + logical(c_bool) :: inner + logical(c_bool) :: idempotent + end type legion_task_config_options_f_t + + ! Legion::TaskArgument + type, bind(C) :: legion_task_argument_f_t + type(c_ptr) :: args + integer(c_size_t) :: arglen + end type legion_task_argument_f_t + + ! offest + type, bind(C) :: legion_byte_offset_f_t + integer(c_int) :: offset + end type legion_byte_offset_f_t + + ! C typedef enum + ! enum, bind(C) :: legion_processor_kind_t + ! enumrator :: NO_KIND = 0 + ! TOC_PROC, LOC_PROC, UTIL_PROC, IO_PROC, PROC_GROUP, PROC_SET, OMP_PROC + !end enum +end module \ No newline at end of file diff --git a/runtime/runtime.mk b/runtime/runtime.mk index 6ddbfb3e7d..dd397c1193 100644 --- a/runtime/runtime.mk +++ b/runtime/runtime.mk @@ -17,9 +17,11 @@ ifeq ($(shell uname -s),Darwin) DARWIN = 1 CC_FLAGS += -DDARWIN +FC_FLAGS += -DDARWIN else #use disk unless on DARWIN CC_FLAGS += -DUSE_DISK +FC_FLAGS += -DUSE_DISK endif ifndef LG_RT_DIR @@ -77,7 +79,13 @@ CONDUIT ?= aries GPU_ARCH ?= pascal endif ifeq ($(findstring excalibur,$(shell uname -n)),excalibur) -CONDUIT ?= aries +CXX=CC +F90=ftn +# Cray's magic wrappers automatically provide LAPACK goodness? +LAPACK_LIBS= +CC_FLAGS += -DGASNETI_BUG1389_WORKAROUND=1 +FC_FLAGS += -DGASNETI_BUG1389_WORKAROUND=1 +CONDUIT=aries endif ifeq ($(findstring cori,$(shell uname -n)),cori) CONDUIT ?= aries @@ -113,6 +121,9 @@ CXX=CC F90=ftn # Cray's magic wrappers automatically provide LAPACK goodness? LAPACK_LIBS ?= +CC_FLAGS += -DGASNETI_BUG1389_WORKAROUND=1 +FC_FLAGS += -DGASNETI_BUG1389_WORKAROUND=1 +CONDUIT=aries LEGION_LD_FLAGS += ${CRAY_UGNI_POST_LINK_OPTS} LEGION_LD_FLAGS += ${CRAY_UDREG_POST_LINK_OPTS} LEGION_LD_FLAGS += ${CRAY_PMI_POST_LINK_OPTS} @@ -129,6 +140,7 @@ ifneq (${MARCH},) else CC_FLAGS += -march=${MARCH} endif + FC_FLAGS += -march=${MARCH} endif INC_FLAGS += -I$(LG_RT_DIR) -I$(LG_RT_DIR)/mappers @@ -143,6 +155,7 @@ ifeq ($(strip $(USE_HWLOC)),1) $(error HWLOC variable is not defined, aborting build) endif CC_FLAGS += -DREALM_USE_HWLOC + FC_FLAGS += -DREALM_USE_HWLOC INC_FLAGS += -I$(HWLOC)/include LEGION_LD_FLAGS += -L$(HWLOC)/lib -lhwloc endif @@ -156,6 +169,7 @@ ifeq ($(strip $(USE_PAPI)),1) endif endif CC_FLAGS += -DREALM_USE_PAPI + FC_FLAGS += -DREALM_USE_PAPI INC_FLAGS += -I$(PAPI_ROOT)/include LEGION_LD_FLAGS += -L$(PAPI_ROOT)/lib -lpapi endif @@ -180,6 +194,7 @@ ifeq ($(strip $(USE_LLVM)),1) endif LLVM_VERSION_NUMBER := $(shell $(LLVM_CONFIG) --version | cut -c1,3) CC_FLAGS += -DREALM_USE_LLVM -DREALM_LLVM_VERSION=$(LLVM_VERSION_NUMBER) + FC_FLAGS += -DREALM_USE_LLVM -DREALM_LLVM_VERSION=$(LLVM_VERSION_NUMBER) # NOTE: do not use these for all source files - just the ones that include llvm include files LLVM_CXXFLAGS ?= -std=c++11 -I$(shell $(LLVM_CONFIG) --includedir) ifeq ($(LLVM_VERSION_NUMBER),35) @@ -197,13 +212,16 @@ endif USE_OPENMP ?= 0 ifeq ($(strip $(USE_OPENMP)),1) CC_FLAGS += -DREALM_USE_OPENMP + FC_FLAGS += -DREALM_USE_OPENMP REALM_OPENMP_GOMP_SUPPORT ?= 1 ifeq ($(strip $(REALM_OPENMP_GOMP_SUPPORT)),1) CC_FLAGS += -DREALM_OPENMP_GOMP_SUPPORT + FC_FLAGS += -DREALM_OPENMP_GOMP_SUPPORT endif REALM_OPENMP_KMP_SUPPORT ?= 1 ifeq ($(strip $(REALM_OPENMP_KMP_SUPPORT)),1) CC_FLAGS += -DREALM_OPENMP_KMP_SUPPORT + FC_FLAGS += -DREALM_OPENMP_GOMP_SUPPORT endif endif @@ -293,6 +311,7 @@ endif # General CUDA variables ifeq ($(strip $(USE_CUDA)),1) CC_FLAGS += -DUSE_CUDA +FC_FLAGS += -DUSE_CUDA NVCC_FLAGS += -DUSE_CUDA INC_FLAGS += -I$(CUDA)/include -I$(LG_RT_DIR)/realm/transfer ifeq ($(strip $(DEBUG)),1) @@ -357,13 +376,16 @@ ifeq ($(strip $(USE_GASNET)),1) LEGION_LD_FLAGS += -L$(GASNET)/lib -lrt -lm endif CC_FLAGS += -DUSE_GASNET + FC_FLAGS += -DUSE_GASNET # newer versions of gasnet seem to need this CC_FLAGS += -DGASNETI_BUG1389_WORKAROUND=1 + FC_FLAGS += -DGASNETI_BUG1389_WORKAROUND=1 # GASNET conduit variables ifeq ($(strip $(CONDUIT)),ibv) INC_FLAGS += -I$(GASNET)/include/ibv-conduit CC_FLAGS += -DGASNET_CONDUIT_IBV + FC_FLAGS += -DGASNET_CONDUIT_IBV LEGION_LD_FLAGS += -lgasnet-ibv-par -libverbs # GASNet needs MPI for interop support USE_MPI = 1 @@ -371,6 +393,7 @@ ifeq ($(strip $(USE_GASNET)),1) ifeq ($(strip $(CONDUIT)),gemini) INC_FLAGS += -I$(GASNET)/include/gemini-conduit CC_FLAGS += -DGASNET_CONDUIT_GEMINI + FC_FLAGS += -DGASNET_CONDUIT_GEMINI LEGION_LD_FLAGS += -lgasnet-gemini-par -lugni -ludreg -lpmi -lhugetlbfs # GASNet needs MPI for interop support USE_MPI = 1 @@ -378,6 +401,7 @@ ifeq ($(strip $(USE_GASNET)),1) ifeq ($(strip $(CONDUIT)),aries) INC_FLAGS += -I$(GASNET)/include/aries-conduit CC_FLAGS += -DGASNET_CONDUIT_ARIES + FC_FLAGS += -DGASNET_CONDUIT_ARIES LEGION_LD_FLAGS += -lgasnet-aries-par -lugni -ludreg -lpmi -lhugetlbfs # GASNet needs MPI for interop support USE_MPI = 1 @@ -385,6 +409,7 @@ ifeq ($(strip $(USE_GASNET)),1) ifeq ($(strip $(CONDUIT)),psm) INC_FLAGS += -I$(GASNET)/include/psm-conduit CC_FLAGS += -DGASNET_CONDUIT_PSM + FC_FLAGS += -DGASNET_CONDUIT_PSM LEGION_LD_FLAGS += -lgasnet-psm-par -lpsm2 -lpmi2 # PMI2 is required for OpenMPI # GASNet needs MPI for interop support USE_MPI = 1 @@ -392,12 +417,14 @@ ifeq ($(strip $(USE_GASNET)),1) ifeq ($(strip $(CONDUIT)),mpi) INC_FLAGS += -I$(GASNET)/include/mpi-conduit CC_FLAGS += -DGASNET_CONDUIT_MPI + FC_FLAGS += -DGASNET_CONDUIT_MPI LEGION_LD_FLAGS += -lgasnet-mpi-par -lammpi -lmpi USE_MPI = 1 endif ifeq ($(strip $(CONDUIT)),udp) INC_FLAGS += -I$(GASNET)/include/udp-conduit CC_FLAGS += -DGASNET_CONDUIT_UDP + FC_FLAGS += -DGASNET_CONDUIT_UDP LEGION_LD_FLAGS += -lgasnet-udp-par -lamudp endif @@ -408,12 +435,15 @@ USE_HDF ?= 0 HDF_LIBNAME ?= hdf5 ifeq ($(strip $(USE_HDF)), 1) CC_FLAGS += -DUSE_HDF + FC_FLAGS += -DUSE_HDF LEGION_LD_FLAGS += -l$(HDF_LIBNAME) ifdef HDF_ROOT CC_FLAGS += -I$(HDF_ROOT)/include + FC_FLAGS += -I$(HDF_ROOT)/include LD_FLAGS += -L$(HDF_ROOT)/lib else CC_FLAGS += -I/usr/include/hdf5/serial + FC_FLAGS += -I/usr/include/hdf5/serial endif endif @@ -440,24 +470,30 @@ USE_ZLIB ?= 1 ZLIB_LIBNAME ?= z ifeq ($(strip $(USE_ZLIB)),1) CC_FLAGS += -DUSE_ZLIB + FC_FLAGS += -DUSE_ZLIB LEGION_LD_FLAGS += -l$(ZLIB_LIBNAME) endif ifeq ($(strip $(DEBUG)),1) CC_FLAGS += -DDEBUG_REALM -DDEBUG_LEGION -O0 -ggdb #-ggdb -Wall +FC_FLAGS += -DDEBUG_REALM -DDEBUG_LEGION -O0 -ggdb #-ggdb -Wall else CC_FLAGS += -O2 -fno-strict-aliasing #-ggdb +FC_FLAGS += -O2 -fno-strict-aliasing #-ggdb endif # Manage the output setting CC_FLAGS += -DCOMPILE_TIME_MIN_LEVEL=$(OUTPUT_LEVEL) +FC_FLAGS += -DCOMPILE_TIME_MIN_LEVEL=$(OUTPUT_LEVEL) # demand warning-free compilation CC_FLAGS += -Wall -Wno-strict-overflow +FC_FLAGS += -Wall -Wno-strict-overflow ifeq ($(strip $(WARN_AS_ERROR)),1) CC_FLAGS += -Werror +FC_FLAGS += -Werror endif #CC_FLAGS += -DUSE_MASKED_COPIES @@ -556,6 +592,11 @@ LEGION_SRC += $(LG_RT_DIR)/legion/legion.cc \ $(LG_RT_DIR)/legion/garbage_collection.cc \ $(LG_RT_DIR)/legion/mapper_manager.cc +LEGION_FORTRAN_API_SRC += $(LG_RT_DIR)/legion/legion_f_types.f90 \ + $(LG_RT_DIR)/legion/legion_f_c_interface.f90 \ + $(LG_RT_DIR)/legion/legion_f_oo.f90 \ + $(LG_RT_DIR)/legion/legion_f.f90 + # General shell commands SHELL := /bin/sh SH := sh @@ -579,6 +620,8 @@ REALM_OBJS := $(REALM_SRC:.cc=.cc.o) LEGION_OBJS := $(LEGION_SRC:.cc=.cc.o) MAPPER_OBJS := $(MAPPER_SRC:.cc=.cc.o) ASM_OBJS := $(ASM_SRC:.S=.S.o) +LEGION_FORTRAN_API_OBJS := $(LEGION_FORTRAN_API_SRC:.f90=.o) +LEGION_FORTRAN_API_MODS := $(LEGION_FORTRAN_API_SRC:.f90=.mod) # Only compile the gpu objects if we need to ifeq ($(strip $(USE_CUDA)),1) GEN_GPU_OBJS := $(GEN_GPU_SRC:.cu=.cu.o) @@ -588,6 +631,16 @@ GEN_GPU_OBJS := GPU_RUNTIME_OBJS:= endif +ifeq ($(strip $(LEGION_WITH_FORTRAN)),1) +GEN_FORTRAN_OBJS := $(GEN_FORTRAN_SRC:.f90=.o) +LD_FLAGS += -lgfortran +F90 := gfortran +endif + +ifeq ($(strip $(LEGION_WITH_C)),1) +GEN_C_OBJS := $(GEN_C_SRC:.c=.o) +endif + # Provide build rules unless the user asks us not to ifndef NO_BUILD_RULES # Provide an all unless the user asks us not to @@ -597,11 +650,21 @@ all: $(OUTFILE) endif # If we're using CUDA we have to link with nvcc +ifeq ($(strip $(LEGION_WITH_C)),1) +$(OUTFILE) : $(GEN_OBJS) $(GEN_C_OBJS) $(GEN_GPU_OBJS) $(SLIB_LEGION) $(SLIB_REALM) + @echo "---> Linking objects into one binary: $(OUTFILE)" + $(CXX) -o $(OUTFILE) $(GEN_OBJS) $(GEN_C_OBJS) $(GEN_GPU_OBJS) $(LD_FLAGS) $(LEGION_LIBS) $(LEGION_LD_FLAGS) $(GASNET_FLAGS) +else ifeq ($(strip $(LEGION_WITH_FORTRAN)),1) +$(OUTFILE) : $(SLIB_LEGION) $(SLIB_REALM) $(GEN_OBJS) $(GEN_FORTRAN_OBJS) $(GEN_GPU_OBJS) + @echo "---> Linking objects into one binary: $(OUTFILE)" + $(CXX) -o $(OUTFILE) $(GEN_OBJS) $(GEN_FORTRAN_OBJS) $(GEN_GPU_OBJS) $(LD_FLAGS) $(LEGION_LIBS) $(LEGION_LD_FLAGS) $(GASNET_FLAGS) +else $(OUTFILE) : $(GEN_OBJS) $(GEN_GPU_OBJS) $(SLIB_LEGION) $(SLIB_REALM) @echo "---> Linking objects into one binary: $(OUTFILE)" $(CXX) -o $(OUTFILE) $(GEN_OBJS) $(GEN_GPU_OBJS) $(LD_FLAGS) $(LEGION_LIBS) $(LEGION_LD_FLAGS) $(GASNET_FLAGS) +endif -$(SLIB_LEGION) : $(LEGION_OBJS) $(MAPPER_OBJS) +$(SLIB_LEGION) : $(LEGION_OBJS) $(MAPPER_OBJS) $(LEGION_FORTRAN_API_OBJS) rm -f $@ $(AR) rc $@ $^ @@ -611,7 +674,7 @@ $(SLIB_REALM) : $(REALM_OBJS) $(GEN_OBJS) : %.cc.o : %.cc $(CXX) -o $@ -c $< $(CC_FLAGS) $(INC_FLAGS) - + $(ASM_OBJS) : %.S.o : %.S $(CXX) -o $@ -c $< $(CC_FLAGS) $(INC_FLAGS) @@ -629,12 +692,25 @@ $(GEN_GPU_OBJS) : %.cu.o : %.cu $(GPU_RUNTIME_OBJS): %.cu.o : %.cu $(NVCC) -o $@ -c $< $(NVCC_FLAGS) $(INC_FLAGS) + +$(LEGION_FORTRAN_API_OBJS) : %.o : %.f90 + $(F90) -cpp -J$(LG_RT_DIR) -o $@ -c $< $(FC_FLAGS) $(INC_FLAGS) + +ifeq ($(strip $(LEGION_WITH_FORTRAN)),1) +$(GEN_FORTRAN_OBJS) : %.o : %.f90 + $(F90) -cpp -o $@ -c $< $(CC_FLAGS) $(INC_FLAGS) +endif + +ifeq ($(strip $(LEGION_WITH_C)),1) +$(GEN_C_OBJS) : %.o : %.c + gcc -o $@ -c $< $(CC_FLAGS) $(INC_FLAGS) +endif # disable gmake's default rule for building % from %.o % : %.o clean:: - $(RM) -f $(OUTFILE) $(SLIB_LEGION) $(SLIB_REALM) $(GEN_OBJS) $(GEN_GPU_OBJS) $(REALM_OBJS) $(LEGION_OBJS) $(GPU_RUNTIME_OBJS) $(MAPPER_OBJS) $(ASM_OBJS) + $(RM) -f $(OUTFILE) $(SLIB_LEGION) $(SLIB_REALM) $(GEN_OBJS) $(GEN_GPU_OBJS) $(REALM_OBJS) $(LEGION_OBJS) $(GPU_RUNTIME_OBJS) $(MAPPER_OBJS) $(ASM_OBJS) $(LEGION_FORTRAN_API_OBJS) $(LEGION_FORTRAN_API_MODS) endif diff --git a/tutorial-c/00_hello_world/CMakeLists.txt b/tutorial-c/00_hello_world/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-c/00_hello_world/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-c/00_hello_world/Makefile b/tutorial-c/00_hello_world/Makefile new file mode 100644 index 0000000000..21f087deba --- /dev/null +++ b/tutorial-c/00_hello_world/Makefile @@ -0,0 +1,50 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= hello_world +# List all the application source files here +GEN_C_SRC ?= hello_world.c # .c files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= -I/$(LG_RT_DIR)/legion +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_C ?= 1 + +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-c/00_hello_world/hello_world.c b/tutorial-c/00_hello_world/hello_world.c new file mode 100644 index 0000000000..5d3f6646c0 --- /dev/null +++ b/tutorial-c/00_hello_world/hello_world.c @@ -0,0 +1,139 @@ +/* Copyright 2017 Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "legion_c.h" + + +// We use an enum to declare the IDs for user-level tasks +enum TaskID { + TOP_LEVEL_TASK_ID, + HELLO_WORLD_TASK_ID, +}; + +void hello_world_task(const void *data, size_t datalen, + const void *userdata, size_t userlen, realm_id_t p) +{ + // assert(task->arglen == sizeof(int)); +// int rank = *(const int*)task->args; + legion_task_t task; + const legion_physical_region_t *regions; + unsigned num_regions; + legion_context_t ctx; + legion_runtime_t runtime; + legion_task_preamble(data, datalen, p, + &task, + ®ions, + &num_regions, + &ctx, + &runtime); + + int *args = (int *)legion_task_get_args(task); + size_t arglen = legion_task_get_arglen(task); + printf("Hello from hello_world_task %d, arglen %ld\n", *args, arglen); + legion_task_postamble(runtime, ctx, NULL, 0); +} + + +void top_level_task(const void *data, size_t datalen, + const void *userdata, size_t userlen, realm_id_t p) +{ + legion_task_t task; + const legion_physical_region_t *regions; + unsigned num_regions; + legion_context_t ctx; + legion_runtime_t runtime; + task.impl = NULL; + ctx.impl = NULL; + runtime.impl = NULL; + legion_task_preamble(data, datalen, p, + &task, + ®ions, + &num_regions, + &ctx, + &runtime); + printf("Hello from top_level_task (msg='%.*s')\n", + (int)userlen, (const char *)userdata); + //legion_task_postamble(runtime, ctx, 0, 0); + + /* + legion_execution_constraint_set_t execution_constraints = legion_execution_constraint_set_create(); + legion_execution_constraint_set_add_processor_constraint(execution_constraints, LOC_PROC); + legion_task_layout_constraint_set_t layout_constraints = legion_task_layout_constraint_set_create(); + legion_task_config_options_t config_options = {.leaf = false, .inner = false, .idempotent = false}; + legion_runtime_register_task_variant_fnptr(runtime, HELLO_WORLD_TASK_ID, + "hello_world_task", true, + execution_constraints, + layout_constraints, + config_options, + hello_world_task, + NULL, + 0);*/ + + for (int i = 0; i < 10; i++) { + legion_task_argument_t task_args; + task_args.args = &i; + task_args.arglen = sizeof(i); + legion_task_launcher_t launcher = legion_task_launcher_create(HELLO_WORLD_TASK_ID, task_args, legion_predicate_true(), 0, 0); + legion_task_launcher_execute(runtime, ctx, launcher); + } + legion_task_postamble(runtime, ctx, 0, 0); +} + +/* +void top_level_task(legion_task_t task, legion_physical_region_t *regions, unsigned num_regions, + legion_context_t ctx, legion_runtime_t runtime) +{ + printf("Hello from top_level_task\n"); + legion_task_postamble(runtime, ctx, 0, 0); +}*/ + +// We have a main function just like a standard C++ program. +// Once we start the runtime, it will begin running the top-level task. +int main(int argc, char **argv) +{ + legion_runtime_set_top_level_task_id(TOP_LEVEL_TASK_ID); + + legion_execution_constraint_set_t execution_constraints = legion_execution_constraint_set_create(); + legion_execution_constraint_set_add_processor_constraint(execution_constraints, LOC_PROC); + legion_task_layout_constraint_set_t layout_constraints = legion_task_layout_constraint_set_create(); + legion_task_config_options_t config_options = {.leaf = false, .inner = false, .idempotent = false}; + legion_runtime_preregister_task_variant_fnptr(TOP_LEVEL_TASK_ID, + "top_leve_task", + "cpu_variant", + execution_constraints, + layout_constraints, + config_options, + top_level_task, + NULL, + 0); + + legion_runtime_preregister_task_variant_fnptr(HELLO_WORLD_TASK_ID, + "hello_world_task", + "cpu_variant", + execution_constraints, + layout_constraints, + config_options, + hello_world_task, + NULL, + 0); + + + legion_runtime_start(argc, argv, false); +} diff --git a/tutorial-c/02_index_tasks/CMakeLists.txt b/tutorial-c/02_index_tasks/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-c/02_index_tasks/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-c/02_index_tasks/Makefile b/tutorial-c/02_index_tasks/Makefile new file mode 100644 index 0000000000..d843788cba --- /dev/null +++ b/tutorial-c/02_index_tasks/Makefile @@ -0,0 +1,50 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= index_tasks +# List all the application source files here +GEN_C_SRC ?= index_tasks.c # .c files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= -I/$(LG_RT_DIR)/legion +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_C ?= 1 + +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-c/02_index_tasks/index_tasks.c b/tutorial-c/02_index_tasks/index_tasks.c new file mode 100644 index 0000000000..f1a172803b --- /dev/null +++ b/tutorial-c/02_index_tasks/index_tasks.c @@ -0,0 +1,149 @@ +/* Copyright 2017 Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "legion_c.h" + + +// We use an enum to declare the IDs for user-level tasks +enum TaskID { + TOP_LEVEL_TASK_ID, + HELLO_WORLD_TASK_ID, +}; + +void hello_world_task(const void *data, size_t datalen, + const void *userdata, size_t userlen, realm_id_t p) +{ + // assert(task->arglen == sizeof(int)); +// int rank = *(const int*)task->args; + legion_task_t task; + const legion_physical_region_t *regions; + unsigned num_regions; + legion_context_t ctx; + legion_runtime_t runtime; + legion_task_preamble(data, datalen, p, + &task, + ®ions, + &num_regions, + &ctx, + &runtime); + + legion_domain_point_t dp = legion_task_get_index_point(task); + + int *args = (int *)legion_task_get_local_args(task); + size_t arglen = legion_task_get_local_arglen(task); + int *global_args = (int *)legion_task_get_args(task); + printf("Hello from hello_world_task, %lld, arg %d, arglen %ld, global arg %d\n", dp.point_data[0], *args, arglen, *global_args); + legion_task_postamble(runtime, ctx, NULL, 0); +} + + +void top_level_task(const void *data, size_t datalen, + const void *userdata, size_t userlen, realm_id_t p) +{ + legion_task_t task; + const legion_physical_region_t *regions; + unsigned num_regions; + legion_context_t ctx; + legion_runtime_t runtime; + task.impl = NULL; + ctx.impl = NULL; + runtime.impl = NULL; + legion_task_preamble(data, datalen, p, + &task, + ®ions, + &num_regions, + &ctx, + &runtime); + printf("Hello from top_level_task (msg='%.*s')\n", + (int)userlen, (const char *)userdata); + + + legion_point_1d_t lo, hi; + legion_rect_1d_t launch_bound; + lo.x[0] = 0; + hi.x[0] = 9; + launch_bound.lo = lo; + launch_bound.hi = hi; + legion_domain_t domain = legion_domain_from_rect_1d(launch_bound); + + int i = 0; + legion_argument_map_t arg_map = legion_argument_map_create(); + for (i = 0; i < 10; i++) { + legion_task_argument_t local_task_args; + int input = i + 10; + local_task_args.args = &input; + local_task_args.arglen = sizeof(input); + legion_point_1d_t tmp_p; + tmp_p.x[0] = i; + legion_domain_point_t dp = legion_domain_point_from_point_1d(tmp_p); + legion_argument_map_set_point(arg_map, dp, local_task_args, true); + } + legion_task_argument_t global_task_args; + global_task_args.args = &i; + global_task_args.arglen = sizeof(i); + + legion_index_launcher_t index_launcher = legion_index_launcher_create(HELLO_WORLD_TASK_ID, domain, global_task_args, arg_map, + legion_predicate_true(), false, 0, 0); + legion_future_map_t fm = legion_index_launcher_execute(runtime, ctx, index_launcher); + legion_future_map_wait_all_results(fm); + legion_task_postamble(runtime, ctx, 0, 0); +} + +/* +void top_level_task(legion_task_t task, legion_physical_region_t *regions, unsigned num_regions, + legion_context_t ctx, legion_runtime_t runtime) +{ + printf("Hello from top_level_task\n"); + legion_task_postamble(runtime, ctx, 0, 0); +}*/ + +// We have a main function just like a standard C++ program. +// Once we start the runtime, it will begin running the top-level task. +int main(int argc, char **argv) +{ + legion_runtime_set_top_level_task_id(TOP_LEVEL_TASK_ID); + + legion_execution_constraint_set_t execution_constraints = legion_execution_constraint_set_create(); + legion_execution_constraint_set_add_processor_constraint(execution_constraints, LOC_PROC); + legion_task_layout_constraint_set_t layout_constraints = legion_task_layout_constraint_set_create(); + legion_task_config_options_t config_options = {.leaf = false, .inner = false, .idempotent = false}; + legion_runtime_preregister_task_variant_fnptr(TOP_LEVEL_TASK_ID, + "top_leve_task", + "cpu_variant", + execution_constraints, + layout_constraints, + config_options, + top_level_task, + NULL, + 0); + + legion_runtime_preregister_task_variant_fnptr(HELLO_WORLD_TASK_ID, + "hello_world_task", + "cpu_variant", + execution_constraints, + layout_constraints, + config_options, + hello_world_task, + NULL, + 0); + + + legion_runtime_start(argc, argv, false); +} diff --git a/tutorial-fortran/c_with_fortran/00_hello_world/CMakeLists.txt b/tutorial-fortran/c_with_fortran/00_hello_world/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/c_with_fortran/00_hello_world/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/c_with_fortran/00_hello_world/Makefile b/tutorial-fortran/c_with_fortran/00_hello_world/Makefile new file mode 100644 index 0000000000..0284f04770 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/00_hello_world/Makefile @@ -0,0 +1,53 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= hello_world +# List all the application source files here +GEN_SRC ?= hello_world.cc # .cc files +GEN_GPU_SRC ?= # .cu files + +# Fortran task file name +GEN_FORTRAN_SRC ?= hello_world_f.f90 + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 + +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/c_with_fortran/00_hello_world/hello_world.cc b/tutorial-fortran/c_with_fortran/00_hello_world/hello_world.cc new file mode 100644 index 0000000000..33220675d0 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/00_hello_world/hello_world.cc @@ -0,0 +1,108 @@ +/* Copyright 2017 Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include + +#include "legion.h" + +// All of the important user-level objects live +// in the Legion namespace. +using namespace Legion; + +// We use an enum to declare the IDs for user-level tasks +enum TaskID { + TOP_LEVEL_TASK_ID, + HELLO_WORLD_TASK_ID, +}; + +#ifdef __cplusplus +extern "C" { +void hello_world_task_f(int* rank, int* n, const char* cstring[], int* rt_val); +} +#endif + +void top_level_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + int nb_tasks = 10; + + { + const InputArgs &command_args = Runtime::get_input_args(); + for (int i = 1; i < command_args.argc; i++) + { + if (!strcmp(command_args.argv[i],"-n")) + nb_tasks = atoi(command_args.argv[++i]); + } + } + + for (int i = 0; i < nb_tasks; i++) { + TaskLauncher launcher(HELLO_WORLD_TASK_ID, TaskArgument(&i,sizeof(i))); + runtime->execute_task(ctx, launcher); + } +} + +// All single-launch tasks in Legion must have this signature with +// the extension that they can have different return values. +void hello_world_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(task->arglen == sizeof(int)); + int rank = *(const int*)task->args; + + const char* cstring[] = { "Hello", "World"}; + int n = 2; + int rt_val = -1; + hello_world_task_f(&rank, &n, cstring, &rt_val); + assert(rt_val == rank); +} + +// We have a main function just like a standard C++ program. +// Once we start the runtime, it will begin running the top-level task. +int main(int argc, char **argv) +{ + // Before starting the Legion runtime, you first have to tell it + // what the ID is for the top-level task. + Runtime::set_top_level_task_id(TOP_LEVEL_TASK_ID); + // Before starting the Legion runtime, all possible tasks that the + // runtime can potentially run must be registered with the runtime. + // A task may have multiple variants (versions of the same code for + // different processors, data layouts, etc.) Each variant is + // registered described by a TaskVariantRegistrar object. The + // registrar takes a number of constraints which determine where it + // is valid to run the task variant. The ProcessorConstraint + // specifies the kind of processor on which the task can be run: + // latency optimized cores (LOC) aka CPUs or throughput optimized + // cores (TOC) aka GPUs. The function pointer is passed as a + // template argument to the preregister_task_variant call. + + { + TaskVariantRegistrar registrar(TOP_LEVEL_TASK_ID, "top_level"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + Runtime::preregister_task_variant(registrar, "top_level"); + } + { + TaskVariantRegistrar registrar(HELLO_WORLD_TASK_ID, "hello_world"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + Runtime::preregister_task_variant(registrar, "hello_world"); + } + + // Now we're ready to start the runtime, so tell it to begin the + // execution. We'll never return from this call, but its return + // signature will return an int to satisfy the type checker. + return Runtime::start(argc, argv); +} diff --git a/tutorial-fortran/c_with_fortran/00_hello_world/hello_world_f.f90 b/tutorial-fortran/c_with_fortran/00_hello_world/hello_world_f.f90 new file mode 100644 index 0000000000..1900d56217 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/00_hello_world/hello_world_f.f90 @@ -0,0 +1,25 @@ +subroutine hello_world_task_f(rank, n, cstring, rt_val) bind(C) + use iso_c_binding, only: c_ptr, c_int, c_f_pointer, c_loc, c_null_char + implicit none + + integer(kind=c_int), intent(in) :: n + integer(kind=c_int), intent(in) :: rank + type(c_ptr), dimension(n), target, intent(in) :: cstring + integer(kind=c_int), intent(out) :: rt_val + character, pointer :: fstring(:) + integer :: i, j + character, allocatable :: print_string(:) + + allocate(print_string(n*5)) + do i = 1, n + call c_f_pointer(cstring(i), fstring, [5]) + do j = 1, 5 + print_string((i-1)*5+j:(i-1)*5+j) = fstring(j) + end do + end do + + print *, print_string, rank + + rt_val = rank; + +end subroutine hello_world_task_f diff --git a/tutorial-fortran/c_with_fortran/06_privileges/CMakeLists.txt b/tutorial-fortran/c_with_fortran/06_privileges/CMakeLists.txt new file mode 100644 index 0000000000..f6f8927ee7 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/06_privileges/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_06_privileges) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(privileges privileges.cc) +target_link_libraries(privileges Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME privileges COMMAND $) +endif() diff --git a/tutorial-fortran/c_with_fortran/06_privileges/Makefile b/tutorial-fortran/c_with_fortran/06_privileges/Makefile new file mode 100644 index 0000000000..a05c1aad57 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/06_privileges/Makefile @@ -0,0 +1,53 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG := 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= privileges +# List all the application source files here +GEN_SRC ?= privileges.cc # .cc files +GEN_GPU_SRC ?= # .cu files + +# Fortran task file name +GEN_FORTRAN_SRC ?= daxpy_task_f.f90 + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 + +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/c_with_fortran/06_privileges/daxpy_task_f.f90 b/tutorial-fortran/c_with_fortran/06_privileges/daxpy_task_f.f90 new file mode 100644 index 0000000000..779b221561 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/06_privileges/daxpy_task_f.f90 @@ -0,0 +1,17 @@ +subroutine daxpy_task_f(alpha, n, x_ptr, y_ptr, z_ptr) bind(C) + use iso_c_binding, only: c_double, c_int + + real(c_double), intent(in) :: alpha + integer(kind=c_int), intent(in) :: n + real(c_double), intent(in), dimension(n) :: x_ptr + real(c_double), intent(in), dimension(n) :: y_ptr + real(c_double), intent(out), dimension(n) :: z_ptr + + integer :: i + real(c_double) :: value + do i = 1, n + value = alpha * x_ptr(i) + y_ptr(i) + z_ptr(i) = value + end do + +end subroutine daxpy_task_f diff --git a/tutorial-fortran/c_with_fortran/06_privileges/privileges.cc b/tutorial-fortran/c_with_fortran/06_privileges/privileges.cc new file mode 100644 index 0000000000..1ca94203b5 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/06_privileges/privileges.cc @@ -0,0 +1,315 @@ +/* Copyright 2017 Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include "legion.h" +using namespace Legion; + +enum TaskIDs { + TOP_LEVEL_TASK_ID, + INIT_FIELD_TASK_ID, + DAXPY_TASK_ID, + CHECK_TASK_ID, +}; + +enum FieldIDs { + FID_X, + FID_Y, + FID_Z, +}; + +#ifdef __cplusplus +extern "C" { +void daxpy_task_f(double *alpha, int* n, double* x_ptr, double* y_ptr, double* z_ptr); +} +#endif + +void top_level_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + int num_elements = 1024; + // See if we have any command line arguments to parse + { + const InputArgs &command_args = Runtime::get_input_args(); + for (int i = 1; i < command_args.argc; i++) + { + if (!strcmp(command_args.argv[i],"-n")) + num_elements = atoi(command_args.argv[++i]); + } + } + printf("Running daxpy for %d elements...\n", num_elements); + + // Create our logical regions using the same schema that + // we used in the previous example. + const Rect<1> elem_rect(0,num_elements-1); + IndexSpace is = runtime->create_index_space(ctx, elem_rect); + FieldSpace input_fs = runtime->create_field_space(ctx); + { + FieldAllocator allocator = + runtime->create_field_allocator(ctx, input_fs); + allocator.allocate_field(sizeof(double),FID_X); + allocator.allocate_field(sizeof(double),FID_Y); + } + FieldSpace output_fs = runtime->create_field_space(ctx); + { + FieldAllocator allocator = + runtime->create_field_allocator(ctx, output_fs); + allocator.allocate_field(sizeof(double),FID_Z); + } + LogicalRegion input_lr = runtime->create_logical_region(ctx, is, input_fs); + LogicalRegion output_lr = runtime->create_logical_region(ctx, is, output_fs); + + // Instead of using an inline mapping to initialize the fields for + // daxpy, in this case we will launch two separate tasks for initializing + // each of the fields in parallel. To launch the sub-tasks for performing + // the initialization we again use the launcher objects that were + // introduced earlier. The only difference now is that instead of passing + // arguments by value, we now want to specify the logical regions + // that the tasks may access as their arguments. We again make use of + // the RegionRequirement struct to name the logical regions and fields + // for which the task should have privileges. In this case we launch + // a task that asks for WRITE_DISCARD privileges on the 'X' field. + // + // An important property of the Legion programming model is that sub-tasks + // are only allowed to request privileges which are a subset of a + // parent task's privileges. When a task creates a logical region it + // is granted full read-write privileges for that logical region. It + // can then pass them down to sub-tasks. In this example the top-level + // task has full privileges on all the fields of input_lr and output_lr. + // In this call it passing read-write privileges down to the sub-task + // on input_lr on field 'X'. Legion will enforce the property that the + // sub-task only accesses the 'X' field of input_lr. This property of + // Legion is crucial for the implementation of Legion's hierarchical + // scheduling algorithm which is described in detail in our two papers. + TaskLauncher init_launcher(INIT_FIELD_TASK_ID, TaskArgument(NULL, 0)); + init_launcher.add_region_requirement( + RegionRequirement(input_lr, WRITE_DISCARD, EXCLUSIVE, input_lr)); + init_launcher.add_field(0/*idx*/, FID_X); + // Note that when we launch this task we don't record the future. + // This is because we're going to let Legion be responsible for + // computing the data dependences between how different tasks access + // logical regions. + runtime->execute_task(ctx, init_launcher); + + // Re-use the same launcher but with a slightly different RegionRequirement + // that requests privileges on field 'Y' instead of 'X'. Since these + // two instances of the init_field_task are accessing different fields + // of the input_lr region, they can be run in parallel (whether or not + // they do is dependent on the mapping discussed in a later example). + // Legion automatically will discover this parallelism since the runtime + // understands the fields present on the logical region. + // + // We now call attention to a unique property of the init_field_task. + // In this example we've actually called the task with two different + // region requirements containing different fields. The init_field_task + // is an example of a field-polymorphic task which is capable of + // performing the same operation on different fields of a logical region. + // In practice this is very useful property for a task to maintain as + // it allows one implementation of a task to be written which is capable + // of being used in many places. + init_launcher.region_requirements[0].privilege_fields.clear(); + init_launcher.region_requirements[0].instance_fields.clear(); + init_launcher.add_field(0/*idx*/, FID_Y); + + runtime->execute_task(ctx, init_launcher); + + // Now we launch the task to perform the daxpy computation. We pass + // in the alpha value as an argument. All the rest of the arguments + // are RegionRequirements specifying that we are reading the two + // fields on the input_lr region and writing results to the output_lr + // region. Legion will automatically compute data dependences + // from the two init_field_tasks and will ensure that the program + // order execution is obeyed. + const double alpha = drand48(); + TaskLauncher daxpy_launcher(DAXPY_TASK_ID, TaskArgument(&alpha, sizeof(alpha))); + daxpy_launcher.add_region_requirement( + RegionRequirement(input_lr, READ_ONLY, EXCLUSIVE, input_lr)); + daxpy_launcher.add_field(0/*idx*/, FID_X); + daxpy_launcher.add_field(0/*idx*/, FID_Y); + daxpy_launcher.add_region_requirement( + RegionRequirement(output_lr, WRITE_DISCARD, EXCLUSIVE, output_lr)); + daxpy_launcher.add_field(1/*idx*/, FID_Z); + + runtime->execute_task(ctx, daxpy_launcher); + + // Finally we launch a task to perform the check on the output. Note + // that Legion will compute a data dependence on the first RegionRequirement + // with the two init_field_tasks, but not on daxpy task since they + // both request read-only privileges on the 'X' and 'Y' fields. However, + // Legion will compute a data dependence on the second region requirement + // as the daxpy task was writing the 'Z' field on output_lr and this task + // is reading the 'Z' field of the output_lr region. + TaskLauncher check_launcher(CHECK_TASK_ID, TaskArgument(&alpha, sizeof(alpha))); + check_launcher.add_region_requirement( + RegionRequirement(input_lr, READ_ONLY, EXCLUSIVE, input_lr)); + check_launcher.add_field(0/*idx*/, FID_X); + check_launcher.add_field(0/*idx*/, FID_Y); + check_launcher.add_region_requirement( + RegionRequirement(output_lr, READ_ONLY, EXCLUSIVE, output_lr)); + check_launcher.add_field(1/*idx*/, FID_Z); + + runtime->execute_task(ctx, check_launcher); + + // Notice that we never once blocked waiting on the result of any sub-task + // in the execution of the top-level task. We don't even block before + // destroying any of our resources. This works because Legion understands + // the data being accessed by all of these operations and defers all of + // their executions until they are safe to perform. Legion is still smart + // enough to know that the top-level task is not finished until all of + // the sub operations that have been performed are completed. However, + // from the programmer's perspective, all of these operations can be + // done without ever blocking and thereby exposing as much task-level + // parallelism to the Legion runtime as possible. We'll discuss the + // implications of Legion's deferred execution model in a later example. + runtime->destroy_logical_region(ctx, input_lr); + runtime->destroy_logical_region(ctx, output_lr); + runtime->destroy_field_space(ctx, input_fs); + runtime->destroy_field_space(ctx, output_fs); + runtime->destroy_index_space(ctx, is); +} + +// Note that tasks get a physical region for every region requirement +// that they requested when they were launched in the vector of 'regions'. +// In some cases the mapper may have chosen not to map the logical region +// which means that the task has the necessary privileges to access the +// region but not a physical instance to access. +void init_field_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + // Check that the inputs look right since we have no + // static checking to help us out. + assert(regions.size() == 1); + assert(task->regions.size() == 1); + assert(task->regions[0].privilege_fields.size() == 1); + // This is a field polymorphic function so figure out + // which field we are responsible for initializing. + FieldID fid = *(task->regions[0].privilege_fields.begin()); + printf("Initializing field %d...\n", fid); + // Note that Legion's default mapper always map regions + // and the Legion runtime is smart enough not to start + // the task until all the regions contain valid data. + // Therefore in this case we don't need to call 'wait_until_valid' + // on our physical regions and we know that getting this + // accessor will never block the task's execution. If + // however we chose to unmap this physical region and then + // remap it then we would need to call 'wait_until_valid' + // again to ensure that we were accessing valid data. + const FieldAccessor acc(regions[0], fid); + + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + for (PointInRectIterator<1> pir(rect); pir(); pir++) + acc[*pir] = drand48(); +} + +void daxpy_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 2); + assert(task->regions.size() == 2); + assert(task->arglen == sizeof(double)); + double alpha = *((const double*)task->args); + LogicalRegion lr = regions[0].get_logical_region(); + IndexSpace id = lr.get_index_space(); + Rect<1> rect = runtime->get_index_space_domain(ctx, id); + const FieldAccessor > acc_x(regions[0], FID_X); + const FieldAccessor > acc_y(regions[0], FID_Y); + const FieldAccessor > acc_z(regions[1], FID_Z); + + // Get dense pointers for use with thrust + + double *x_ptr = (double *)acc_x.ptr(rect.lo); + double *y_ptr = (double *)acc_y.ptr(rect.lo); + double *z_ptr = (double *)acc_z.ptr(rect.lo); + + printf("Running daxpy computation with alpha %.8g, x_ptr %p, y_ptr %p, z_ptr %p...\n", alpha, x_ptr, y_ptr, z_ptr); + int n = rect.volume(); + daxpy_task_f(&alpha, &n, x_ptr, y_ptr, z_ptr); +} + +void check_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 2); + assert(task->regions.size() == 2); + assert(task->arglen == sizeof(double)); + const double alpha = *((const double*)task->args); + const FieldAccessor acc_x(regions[0], FID_X); + const FieldAccessor acc_y(regions[0], FID_Y); + const FieldAccessor acc_z(regions[1], FID_Z); + + printf("Checking results..."); + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + bool all_passed = true; + for (PointInRectIterator<1> pir(rect); pir(); pir++) + { + double expected = alpha * acc_x[*pir] + acc_y[*pir]; + double received = acc_z[*pir]; + // Probably shouldn't check for floating point equivalence but + // the order of operations are the same should they should + // be bitwise equal. + if (expected != received) + all_passed = false; + } + if (all_passed) + printf("SUCCESS!\n"); + else + printf("FAILURE!\n"); +} + +int main(int argc, char **argv) +{ + Runtime::set_top_level_task_id(TOP_LEVEL_TASK_ID); + + { + TaskVariantRegistrar registrar(TOP_LEVEL_TASK_ID, "top_level"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + Runtime::preregister_task_variant(registrar, "top_level"); + } + + { + TaskVariantRegistrar registrar(INIT_FIELD_TASK_ID, "init_field"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "init_field"); + } + + { + TaskVariantRegistrar registrar(DAXPY_TASK_ID, "daxpy"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "daxpy"); + } + + { + TaskVariantRegistrar registrar(CHECK_TASK_ID, "check"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "check"); + } + + return Runtime::start(argc, argv); +} diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/CMakeLists.txt b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/CMakeLists.txt new file mode 100644 index 0000000000..7ac8d0d5dc --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_07_partitioning) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(partitioning partitioning.cc) +target_link_libraries(partitioning Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME partitioning COMMAND $) +endif() diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/Makefile b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/Makefile new file mode 100644 index 0000000000..f2e496856f --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/Makefile @@ -0,0 +1,53 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG := 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 1 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= partitioning +# List all the application source files here +GEN_SRC ?= partitioning.cc # .cc files +GEN_GPU_SRC ?= # .cu files + +# Fortran task file name +GEN_FORTRAN_SRC ?= daxpy_task_f.f90 + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= -I/$(LG_RT_DIR)/legion +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 + +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/daxpy_task_f.f90 b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/daxpy_task_f.f90 new file mode 100644 index 0000000000..b0678ee3a4 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/daxpy_task_f.f90 @@ -0,0 +1,64 @@ +subroutine daxpy_task_f(tdata, tdatalen, userdata, userlen, p) bind(C) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + real(kind=8), pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + real(c_double), target :: xy_value, x_value, y_value + type(c_ptr) :: xy_ptr, x_ptr, y_ptr + type(legion_point_1d_f_t) :: point + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Daxpy Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + x_ptr = c_loc(x_value) + y_ptr = c_loc(y_value) + call legion_accessor_array_1d_read_point_f(accessor_x, point, x_ptr, c_sizeof(x_value)) + call legion_accessor_array_1d_read_point_f(accessor_y, point, y_ptr, c_sizeof(y_value)) + xy_value = x_value + y_value + xy_ptr = c_loc(xy_value) + call legion_accessor_array_1d_write_point_f(accessor_z, point, xy_ptr, c_sizeof(xy_value)) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) +end subroutine \ No newline at end of file diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/partitioning.cc b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/partitioning.cc new file mode 100644 index 0000000000..9f6cddc1ca --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_fortran_task/partitioning.cc @@ -0,0 +1,339 @@ +/* Copyright 2017 Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include "legion.h" +#include "legion_c.h" +using namespace Legion; + +enum TaskIDs { + TOP_LEVEL_TASK_ID, + INIT_FIELD_TASK_ID, + DAXPY_TASK_ID, + CHECK_TASK_ID, +}; + +enum FieldIDs { + FID_X, + FID_Y, + FID_Z, +}; + +#ifdef __cplusplus +extern "C" { +void daxpy_task_f(const void *data, size_t datalen, const void *userdata, size_t userlen, realm_id_t p); +} +#endif + +void top_level_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + int num_elements = 1024; + int num_subregions = 4; + // See if we have any command line arguments to parse + // Note we now have a new command line parameter which specifies + // how many subregions we should make. + { + const InputArgs &command_args = Runtime::get_input_args(); + for (int i = 1; i < command_args.argc; i++) + { + if (!strcmp(command_args.argv[i],"-n")) + num_elements = atoi(command_args.argv[++i]); + if (!strcmp(command_args.argv[i],"-b")) + num_subregions = atoi(command_args.argv[++i]); + } + } + printf("Running daxpy for %d elements...\n", num_elements); + printf("Partitioning data into %d sub-regions...\n", num_subregions); + + // Create our logical regions using the same schemas as earlier examples + Rect<1> elem_rect(0,num_elements-1); + IndexSpace is = runtime->create_index_space(ctx, elem_rect); + runtime->attach_name(is, "is"); + FieldSpace input_fs = runtime->create_field_space(ctx); + runtime->attach_name(input_fs, "input_fs"); + { + FieldAllocator allocator = + runtime->create_field_allocator(ctx, input_fs); + allocator.allocate_field(sizeof(double),FID_X); + runtime->attach_name(input_fs, FID_X, "X"); + allocator.allocate_field(sizeof(double),FID_Y); + runtime->attach_name(input_fs, FID_Y, "Y"); + } + FieldSpace output_fs = runtime->create_field_space(ctx); + runtime->attach_name(output_fs, "output_fs"); + { + FieldAllocator allocator = + runtime->create_field_allocator(ctx, output_fs); + allocator.allocate_field(sizeof(double),FID_Z); + runtime->attach_name(output_fs, FID_Z, "Z"); + } + LogicalRegion input_lr = runtime->create_logical_region(ctx, is, input_fs); + runtime->attach_name(input_lr, "input_lr"); + LogicalRegion output_lr = runtime->create_logical_region(ctx, is, output_fs); + runtime->attach_name(output_lr, "output_lr"); + + // In addition to using rectangles and domains for launching index spaces + // of tasks (see example 02), Legion also uses them for performing + // operations on logical regions. Here we create a rectangle and a + // corresponding domain for describing the space of subregions that we + // want to create. Each subregion is assigned a 'color' which is why + // we name the variables 'color_bounds' and 'color_domain'. We'll use + // these below when we partition the region. + Rect<1> color_bounds(0,num_subregions-1); + IndexSpace color_is = runtime->create_index_space(ctx, color_bounds); + + // Parallelism in Legion is implicit. This means that rather than + // explicitly saying what should run in parallel, Legion applications + // partition up data and tasks specify which regions they access. + // The Legion runtime computes non-interference as a function of + // regions, fields, and privileges and then determines which tasks + // are safe to run in parallel. + // + // Data partitioning is performed on index spaces. The partitioning + // operation is used to break an index space of points into subsets + // of points each of which will become a sub index space. Partitions + // created on an index space are then transitively applied to all the + // logical regions created using the index space. We will show how + // to get names to the subregions later in this example. + // + // Here we want to create the IndexPartition 'ip'. We'll illustrate + // two ways of creating an index partition depending on whether the + // array being partitioned can be evenly partitioned into subsets + // or not. There are other methods to partitioning index spaces + // which are not covered here. We'll cover the case of coloring + // individual points in an index space in our capstone circuit example. + IndexPartition ip = runtime->create_equal_partition(ctx, is, color_is); + runtime->attach_name(ip, "ip"); + + // The index space 'is' was used in creating two logical regions: 'input_lr' + // and 'output_lr'. By creating an IndexPartitiong of 'is' we implicitly + // created a LogicalPartition for each of the logical regions created using + // 'is'. The Legion runtime provides several ways of getting the names for + // these LogicalPartitions. We'll look at one of them here. The + // 'get_logical_partition' method takes a LogicalRegion and an IndexPartition + // and returns the LogicalPartition of the given LogicalRegion that corresponds + // to the given IndexPartition. + LogicalPartition input_lp = runtime->get_logical_partition(ctx, input_lr, ip); + runtime->attach_name(input_lp, "input_lp"); + LogicalPartition output_lp = runtime->get_logical_partition(ctx, output_lr, ip); + runtime->attach_name(output_lp, "output_lp"); + + // Create our launch domain. Note that is the same as color domain + // as we are going to launch one task for each subregion we created. + ArgumentMap arg_map; + + // As in previous examples, we now want to launch tasks for initializing + // both the fields. However, to increase the amount of parallelism + // exposed to the runtime we will launch separate sub-tasks for each of + // the logical subregions created by our partitioning. To express this + // we create an IndexLauncher for launching an index space of tasks + // the same as example 02. + IndexLauncher init_launcher(INIT_FIELD_TASK_ID, color_is, + TaskArgument(NULL, 0), arg_map); + // For index space task launches we don't want to have to explicitly + // enumerate separate region requirements for all points in our launch + // domain. Instead Legion allows applications to place an upper bound + // on privileges required by subtasks and then specify which privileges + // each subtask receives using a projection function. In the case of + // the field initialization task, we say that all the subtasks will be + // using some subregion of the LogicalPartition 'input_lp'. Applications + // may also specify upper bounds using logical regions and not partitions. + // + // The Legion implementation assumes that all all points in an index + // space task launch request non-interfering privileges and for performance + // reasons this is unchecked. This means if two tasks in the same index + // space are accessing aliased data, then they must either both be + // with read-only or reduce privileges. + // + // When the runtime enumerates the launch_domain, it will invoke the + // projection function for each point in the space and use the resulting + // LogicalRegion computed for each point in the index space of tasks. + // The projection ID '0' is reserved and corresponds to the identity + // function which simply zips the space of tasks with the space of + // subregions in the partition. Applications can register their own + // projections functions via the 'register_region_projection' and + // 'register_partition_projection' functions before starting + // the runtime similar to how tasks are registered. + init_launcher.add_region_requirement( + RegionRequirement(input_lp, 0/*projection ID*/, + WRITE_DISCARD, EXCLUSIVE, input_lr)); + init_launcher.region_requirements[0].add_field(FID_X); + runtime->execute_index_space(ctx, init_launcher); + + // Modify our region requirement to initialize the other field + // in the same way. Note that after we do this we have exposed + // 2*num_subregions task-level parallelism to the runtime because + // we have launched tasks that are both data-parallel on + // sub-regions and task-parallel on accessing different fields. + // The power of Legion is that it allows programmers to express + // these data usage patterns and automatically extracts both + // kinds of parallelism in a unified programming framework. + init_launcher.region_requirements[0].privilege_fields.clear(); + init_launcher.region_requirements[0].instance_fields.clear(); + init_launcher.region_requirements[0].add_field(FID_Y); + runtime->execute_index_space(ctx, init_launcher); + + const double alpha = 1.0; + // We launch the subtasks for performing the daxpy computation + // in a similar way to the initialize field tasks. Note we + // again make use of two RegionRequirements which use a + // partition as the upper bound for the privileges for the task. + IndexLauncher daxpy_launcher(DAXPY_TASK_ID, color_is, + TaskArgument(&alpha, sizeof(alpha)), arg_map); + daxpy_launcher.add_region_requirement( + RegionRequirement(input_lp, 0/*projection ID*/, + READ_ONLY, EXCLUSIVE, input_lr)); + daxpy_launcher.region_requirements[0].add_field(FID_X); + daxpy_launcher.region_requirements[0].add_field(FID_Y); + daxpy_launcher.add_region_requirement( + RegionRequirement(output_lp, 0/*projection ID*/, + WRITE_DISCARD, EXCLUSIVE, output_lr)); + daxpy_launcher.region_requirements[1].add_field(FID_Z); + runtime->execute_index_space(ctx, daxpy_launcher); + + // While we could also issue parallel subtasks for the checking + // task, we only issue a single task launch to illustrate an + // important Legion concept. Note the checking task operates + // on the entire 'input_lr' and 'output_lr' regions and not + // on the subregions. Even though the previous tasks were + // all operating on subregions, Legion will correctly compute + // data dependences on all the subtasks that generated the + // data in these two regions. + TaskLauncher check_launcher(CHECK_TASK_ID, TaskArgument(&alpha, sizeof(alpha))); + check_launcher.add_region_requirement( + RegionRequirement(input_lr, READ_ONLY, EXCLUSIVE, input_lr)); + check_launcher.region_requirements[0].add_field(FID_X); + check_launcher.region_requirements[0].add_field(FID_Y); + check_launcher.add_region_requirement( + RegionRequirement(output_lr, READ_ONLY, EXCLUSIVE, output_lr)); + check_launcher.region_requirements[1].add_field(FID_Z); + runtime->execute_task(ctx, check_launcher); + + runtime->destroy_logical_region(ctx, input_lr); + runtime->destroy_logical_region(ctx, output_lr); + runtime->destroy_field_space(ctx, input_fs); + runtime->destroy_field_space(ctx, output_fs); + runtime->destroy_index_space(ctx, is); +} + +void init_field_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 1); + assert(task->regions.size() == 1); + assert(task->regions[0].privilege_fields.size() == 1); + + FieldID fid = *(task->regions[0].privilege_fields.begin()); + const int point = task->index_point.point_data[0]; + printf("Initializing field %d for block %d...\n", fid, point); + + const FieldAccessor acc(regions[0], fid); + // Note here that we get the domain for the subregion for + // this task from the runtime which makes it safe for running + // both as a single task and as part of an index space of tasks. + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + for (PointInRectIterator<1> pir(rect); pir(); pir++) + acc[*pir] = drand48(); +} + + + +void daxpy_task(const void *data, size_t datalen, const void *userdata, size_t userlen, realm_id_t p) +{ + printf("daxpy task C\n"); + daxpy_task_f(data, datalen, userdata, userlen, p); +} + +void check_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 2); + assert(task->regions.size() == 2); + assert(task->arglen == sizeof(double)); + const double alpha = *((const double*)task->args); + + const FieldAccessor acc_x(regions[0], FID_X); + const FieldAccessor acc_y(regions[0], FID_Y); + const FieldAccessor acc_z(regions[1], FID_Z); + + printf("Checking results..."); + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + bool all_passed = true; + for (PointInRectIterator<1> pir(rect); pir(); pir++) + { + double expected = alpha * acc_x[*pir] + acc_y[*pir]; + double received = acc_z[*pir]; + // Probably shouldn't check for floating point equivalence but + // the order of operations are the same should they should + // be bitwise equal. + if (expected != received) + all_passed = false; + } + if (all_passed) + printf("SUCCESS!\n"); + else + printf("FAILURE!\n"); +} + +int main(int argc, char **argv) +{ + Runtime::set_top_level_task_id(TOP_LEVEL_TASK_ID); + + { + TaskVariantRegistrar registrar(TOP_LEVEL_TASK_ID, "top_level"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + Runtime::preregister_task_variant(registrar, "top_level"); + } + + { + TaskVariantRegistrar registrar(INIT_FIELD_TASK_ID, "init_field"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "init_field"); + } + + + legion_execution_constraint_set_t execution_constraints = legion_execution_constraint_set_create(); + legion_execution_constraint_set_add_processor_constraint(execution_constraints, LOC_PROC); + legion_task_layout_constraint_set_t layout_constraints = legion_task_layout_constraint_set_create(); + legion_task_config_options_t config_options = {.leaf = false, .inner = false, .idempotent = false}; + legion_runtime_preregister_task_variant_fnptr(DAXPY_TASK_ID, + "daxpy", + "cpu_variant", + execution_constraints, + layout_constraints, + config_options, + daxpy_task, + NULL, + 0); + + { + TaskVariantRegistrar registrar(CHECK_TASK_ID, "check"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "check"); + } + + return Runtime::start(argc, argv); +} diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/CMakeLists.txt b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/CMakeLists.txt new file mode 100644 index 0000000000..7ac8d0d5dc --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_07_partitioning) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(partitioning partitioning.cc) +target_link_libraries(partitioning Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME partitioning COMMAND $) +endif() diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/Makefile b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/Makefile new file mode 100644 index 0000000000..42c79072f3 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/Makefile @@ -0,0 +1,53 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG := 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= partitioning +# List all the application source files here +GEN_SRC ?= partitioning.cc # .cc files +GEN_GPU_SRC ?= # .cu files + +# Fortran task file name +GEN_FORTRAN_SRC ?= daxpy_task_f.f90 + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 + +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/daxpy_task_f.f90 b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/daxpy_task_f.f90 new file mode 100644 index 0000000000..779b221561 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/daxpy_task_f.f90 @@ -0,0 +1,17 @@ +subroutine daxpy_task_f(alpha, n, x_ptr, y_ptr, z_ptr) bind(C) + use iso_c_binding, only: c_double, c_int + + real(c_double), intent(in) :: alpha + integer(kind=c_int), intent(in) :: n + real(c_double), intent(in), dimension(n) :: x_ptr + real(c_double), intent(in), dimension(n) :: y_ptr + real(c_double), intent(out), dimension(n) :: z_ptr + + integer :: i + real(c_double) :: value + do i = 1, n + value = alpha * x_ptr(i) + y_ptr(i) + z_ptr(i) = value + end do + +end subroutine daxpy_task_f diff --git a/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/partitioning.cc b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/partitioning.cc new file mode 100644 index 0000000000..6724654a88 --- /dev/null +++ b/tutorial-fortran/c_with_fortran/07_partitioning_raw_ptr/partitioning.cc @@ -0,0 +1,354 @@ +/* Copyright 2017 Stanford University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include "legion.h" +using namespace Legion; + +enum TaskIDs { + TOP_LEVEL_TASK_ID, + INIT_FIELD_TASK_ID, + DAXPY_TASK_ID, + CHECK_TASK_ID, +}; + +enum FieldIDs { + FID_X, + FID_Y, + FID_Z, +}; + +#ifdef __cplusplus +extern "C" { +void daxpy_task_f(double *alpha, int* n, double* x_ptr, double* y_ptr, double* z_ptr); +} +#endif + +void top_level_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + int num_elements = 1024; + int num_subregions = 4; + // See if we have any command line arguments to parse + // Note we now have a new command line parameter which specifies + // how many subregions we should make. + { + const InputArgs &command_args = Runtime::get_input_args(); + for (int i = 1; i < command_args.argc; i++) + { + if (!strcmp(command_args.argv[i],"-n")) + num_elements = atoi(command_args.argv[++i]); + if (!strcmp(command_args.argv[i],"-b")) + num_subregions = atoi(command_args.argv[++i]); + } + } + printf("Running daxpy for %d elements...\n", num_elements); + printf("Partitioning data into %d sub-regions...\n", num_subregions); + + // Create our logical regions using the same schemas as earlier examples + Rect<1> elem_rect(0,num_elements-1); + IndexSpace is = runtime->create_index_space(ctx, elem_rect); + runtime->attach_name(is, "is"); + FieldSpace input_fs = runtime->create_field_space(ctx); + runtime->attach_name(input_fs, "input_fs"); + { + FieldAllocator allocator = + runtime->create_field_allocator(ctx, input_fs); + allocator.allocate_field(sizeof(double),FID_X); + runtime->attach_name(input_fs, FID_X, "X"); + allocator.allocate_field(sizeof(double),FID_Y); + runtime->attach_name(input_fs, FID_Y, "Y"); + } + FieldSpace output_fs = runtime->create_field_space(ctx); + runtime->attach_name(output_fs, "output_fs"); + { + FieldAllocator allocator = + runtime->create_field_allocator(ctx, output_fs); + allocator.allocate_field(sizeof(double),FID_Z); + runtime->attach_name(output_fs, FID_Z, "Z"); + } + LogicalRegion input_lr = runtime->create_logical_region(ctx, is, input_fs); + runtime->attach_name(input_lr, "input_lr"); + LogicalRegion output_lr = runtime->create_logical_region(ctx, is, output_fs); + runtime->attach_name(output_lr, "output_lr"); + + // In addition to using rectangles and domains for launching index spaces + // of tasks (see example 02), Legion also uses them for performing + // operations on logical regions. Here we create a rectangle and a + // corresponding domain for describing the space of subregions that we + // want to create. Each subregion is assigned a 'color' which is why + // we name the variables 'color_bounds' and 'color_domain'. We'll use + // these below when we partition the region. + Rect<1> color_bounds(0,num_subregions-1); + IndexSpace color_is = runtime->create_index_space(ctx, color_bounds); + + // Parallelism in Legion is implicit. This means that rather than + // explicitly saying what should run in parallel, Legion applications + // partition up data and tasks specify which regions they access. + // The Legion runtime computes non-interference as a function of + // regions, fields, and privileges and then determines which tasks + // are safe to run in parallel. + // + // Data partitioning is performed on index spaces. The partitioning + // operation is used to break an index space of points into subsets + // of points each of which will become a sub index space. Partitions + // created on an index space are then transitively applied to all the + // logical regions created using the index space. We will show how + // to get names to the subregions later in this example. + // + // Here we want to create the IndexPartition 'ip'. We'll illustrate + // two ways of creating an index partition depending on whether the + // array being partitioned can be evenly partitioned into subsets + // or not. There are other methods to partitioning index spaces + // which are not covered here. We'll cover the case of coloring + // individual points in an index space in our capstone circuit example. + IndexPartition ip = runtime->create_equal_partition(ctx, is, color_is); + runtime->attach_name(ip, "ip"); + + // The index space 'is' was used in creating two logical regions: 'input_lr' + // and 'output_lr'. By creating an IndexPartitiong of 'is' we implicitly + // created a LogicalPartition for each of the logical regions created using + // 'is'. The Legion runtime provides several ways of getting the names for + // these LogicalPartitions. We'll look at one of them here. The + // 'get_logical_partition' method takes a LogicalRegion and an IndexPartition + // and returns the LogicalPartition of the given LogicalRegion that corresponds + // to the given IndexPartition. + LogicalPartition input_lp = runtime->get_logical_partition(ctx, input_lr, ip); + runtime->attach_name(input_lp, "input_lp"); + LogicalPartition output_lp = runtime->get_logical_partition(ctx, output_lr, ip); + runtime->attach_name(output_lp, "output_lp"); + + // Create our launch domain. Note that is the same as color domain + // as we are going to launch one task for each subregion we created. + ArgumentMap arg_map; + + // As in previous examples, we now want to launch tasks for initializing + // both the fields. However, to increase the amount of parallelism + // exposed to the runtime we will launch separate sub-tasks for each of + // the logical subregions created by our partitioning. To express this + // we create an IndexLauncher for launching an index space of tasks + // the same as example 02. + IndexLauncher init_launcher(INIT_FIELD_TASK_ID, color_is, + TaskArgument(NULL, 0), arg_map); + // For index space task launches we don't want to have to explicitly + // enumerate separate region requirements for all points in our launch + // domain. Instead Legion allows applications to place an upper bound + // on privileges required by subtasks and then specify which privileges + // each subtask receives using a projection function. In the case of + // the field initialization task, we say that all the subtasks will be + // using some subregion of the LogicalPartition 'input_lp'. Applications + // may also specify upper bounds using logical regions and not partitions. + // + // The Legion implementation assumes that all all points in an index + // space task launch request non-interfering privileges and for performance + // reasons this is unchecked. This means if two tasks in the same index + // space are accessing aliased data, then they must either both be + // with read-only or reduce privileges. + // + // When the runtime enumerates the launch_domain, it will invoke the + // projection function for each point in the space and use the resulting + // LogicalRegion computed for each point in the index space of tasks. + // The projection ID '0' is reserved and corresponds to the identity + // function which simply zips the space of tasks with the space of + // subregions in the partition. Applications can register their own + // projections functions via the 'register_region_projection' and + // 'register_partition_projection' functions before starting + // the runtime similar to how tasks are registered. + init_launcher.add_region_requirement( + RegionRequirement(input_lp, 0/*projection ID*/, + WRITE_DISCARD, EXCLUSIVE, input_lr)); + init_launcher.region_requirements[0].add_field(FID_X); + runtime->execute_index_space(ctx, init_launcher); + + // Modify our region requirement to initialize the other field + // in the same way. Note that after we do this we have exposed + // 2*num_subregions task-level parallelism to the runtime because + // we have launched tasks that are both data-parallel on + // sub-regions and task-parallel on accessing different fields. + // The power of Legion is that it allows programmers to express + // these data usage patterns and automatically extracts both + // kinds of parallelism in a unified programming framework. + init_launcher.region_requirements[0].privilege_fields.clear(); + init_launcher.region_requirements[0].instance_fields.clear(); + init_launcher.region_requirements[0].add_field(FID_Y); + runtime->execute_index_space(ctx, init_launcher); + + const double alpha = drand48(); + // We launch the subtasks for performing the daxpy computation + // in a similar way to the initialize field tasks. Note we + // again make use of two RegionRequirements which use a + // partition as the upper bound for the privileges for the task. + IndexLauncher daxpy_launcher(DAXPY_TASK_ID, color_is, + TaskArgument(&alpha, sizeof(alpha)), arg_map); + daxpy_launcher.add_region_requirement( + RegionRequirement(input_lp, 0/*projection ID*/, + READ_ONLY, EXCLUSIVE, input_lr)); + daxpy_launcher.region_requirements[0].add_field(FID_X); + daxpy_launcher.region_requirements[0].add_field(FID_Y); + daxpy_launcher.add_region_requirement( + RegionRequirement(output_lp, 0/*projection ID*/, + WRITE_DISCARD, EXCLUSIVE, output_lr)); + daxpy_launcher.region_requirements[1].add_field(FID_Z); + runtime->execute_index_space(ctx, daxpy_launcher); + + // While we could also issue parallel subtasks for the checking + // task, we only issue a single task launch to illustrate an + // important Legion concept. Note the checking task operates + // on the entire 'input_lr' and 'output_lr' regions and not + // on the subregions. Even though the previous tasks were + // all operating on subregions, Legion will correctly compute + // data dependences on all the subtasks that generated the + // data in these two regions. + TaskLauncher check_launcher(CHECK_TASK_ID, TaskArgument(&alpha, sizeof(alpha))); + check_launcher.add_region_requirement( + RegionRequirement(input_lr, READ_ONLY, EXCLUSIVE, input_lr)); + check_launcher.region_requirements[0].add_field(FID_X); + check_launcher.region_requirements[0].add_field(FID_Y); + check_launcher.add_region_requirement( + RegionRequirement(output_lr, READ_ONLY, EXCLUSIVE, output_lr)); + check_launcher.region_requirements[1].add_field(FID_Z); + runtime->execute_task(ctx, check_launcher); + + runtime->destroy_logical_region(ctx, input_lr); + runtime->destroy_logical_region(ctx, output_lr); + runtime->destroy_field_space(ctx, input_fs); + runtime->destroy_field_space(ctx, output_fs); + runtime->destroy_index_space(ctx, is); +} + +void init_field_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 1); + assert(task->regions.size() == 1); + assert(task->regions[0].privilege_fields.size() == 1); + + FieldID fid = *(task->regions[0].privilege_fields.begin()); + const int point = task->index_point.point_data[0]; + printf("Initializing field %d for block %d...\n", fid, point); + + const FieldAccessor > acc(regions[0], fid); + // Note here that we get the domain for the subregion for + // this task from the runtime which makes it safe for running + // both as a single task and as part of an index space of tasks. + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + for (PointInRectIterator<1> pir(rect); pir(); pir++) + acc[*pir] = drand48(); +} + +void daxpy_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 2); + assert(task->regions.size() == 2); + assert(task->arglen == sizeof(double)); + double alpha = *((const double*)task->args); + const int point = task->index_point.point_data[0]; + + const FieldAccessor > acc_x(regions[0], FID_X); + const FieldAccessor > acc_y(regions[0], FID_Y); + const FieldAccessor > acc_z(regions[1], FID_Z); + + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + double *x_ptr = (double *)acc_x.ptr(rect.lo); + double *y_ptr = (double *)acc_y.ptr(rect.lo); + double *z_ptr = (double *)acc_z.ptr(rect.lo); + + printf("Running daxpy computation with alpha %.8g, x_ptr %p, y_ptr %p, z_ptr %p for point %d...\n", alpha, x_ptr, y_ptr, z_ptr, point); + int n = rect.volume(); + daxpy_task_f(&alpha, &n, x_ptr, y_ptr, z_ptr); +} + +void check_task(const Task *task, + const std::vector ®ions, + Context ctx, Runtime *runtime) +{ + assert(regions.size() == 2); + assert(task->regions.size() == 2); + assert(task->arglen == sizeof(double)); + const double alpha = *((const double*)task->args); + + const FieldAccessor > acc_x(regions[0], FID_X); + const FieldAccessor > acc_y(regions[0], FID_Y); + const FieldAccessor > acc_z(regions[1], FID_Z); + + printf("Checking results..."); + Rect<1> rect = runtime->get_index_space_domain(ctx, + task->regions[0].region.get_index_space()); + bool all_passed = true; + for (PointInRectIterator<1> pir(rect); pir(); pir++) + { + double expected = alpha * acc_x[*pir] + acc_y[*pir]; + double received = acc_z[*pir]; + // Probably shouldn't check for floating point equivalence but + // the order of operations are the same should they should + // be bitwise equal. + if (expected != received) + all_passed = false; + } + if (all_passed) + printf("SUCCESS!\n"); + else + printf("FAILURE!\n"); +} + +int main(int argc, char **argv) +{ + Runtime::set_top_level_task_id(TOP_LEVEL_TASK_ID); + + { + TaskVariantRegistrar registrar(TOP_LEVEL_TASK_ID, "top_level"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + Runtime::preregister_task_variant(registrar, "top_level"); + } + + { + TaskVariantRegistrar registrar(INIT_FIELD_TASK_ID, "init_field"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "init_field"); + } + + { + TaskVariantRegistrar registrar(DAXPY_TASK_ID, "daxpy"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "daxpy"); + } + + { + TaskVariantRegistrar registrar(CHECK_TASK_ID, "check"); + registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC)); + registrar.set_leaf(); + Runtime::preregister_task_variant(registrar, "check"); + } + + return Runtime::start(argc, argv); +} \ No newline at end of file diff --git a/tutorial-fortran/fortran/00_hello_world/CMakeLists.txt b/tutorial-fortran/fortran/00_hello_world/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/00_hello_world/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/00_hello_world/Makefile b/tutorial-fortran/fortran/00_hello_world/Makefile new file mode 100644 index 0000000000..d9b79c053e --- /dev/null +++ b/tutorial-fortran/fortran/00_hello_world/Makefile @@ -0,0 +1,49 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 1 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= hello_world +# List all the application source files here +GEN_FORTRAN_SRC ?= hello_world.f90 # .f90 files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/00_hello_world/hello_world.f90 b/tutorial-fortran/fortran/00_hello_world/hello_world.f90 new file mode 100644 index 0000000000..a9bc8a7453 --- /dev/null +++ b/tutorial-fortran/fortran/00_hello_world/hello_world.f90 @@ -0,0 +1,133 @@ +module hello_world + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID = 0 + integer(c_int), parameter :: HELLO_WORLD_TASK_ID = 1 + +contains + subroutine hello_world_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), optional, intent(in) ::userdata + integer(c_size_t), value, optional, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Hello World Task!", task_arg, arglen + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine hello_world_task + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: task_args + type(legion_task_launcher_f_t) :: launcher + integer(c_long) :: tag = 0 + type(legion_future_f_t) :: hello_world_task_future + + integer*4, target :: i + + Print *, "TOP Level Task!" + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_predicate_true_f(pred) + do i = 0, 10 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(HELLO_WORLD_TASK_ID, task_args, pred, 0, tag, launcher) + call legion_task_launcher_execute_f(runtime, ctx, launcher, hello_world_task_future) + end do + call legion_task_launcher_destroy_f(launcher) + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module hello_world + + +Program hello + use legion_fortran + use iso_c_binding + use hello_world + implicit none + + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2, runtime_start_rv + integer(c_size_t) :: userlen = 0 + type(c_funptr) :: c_func_ptr + + Print *, "Hello World from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f( & + TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + c_func_ptr = c_funloc(hello_world_task) + + call legion_runtime_preregister_task_variant_fnptr_f( & + HELLO_WORLD_TASK_ID, c_char_"hello_world_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program hello diff --git a/tutorial-fortran/fortran/02_index_tasks/CMakeLists.txt b/tutorial-fortran/fortran/02_index_tasks/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/02_index_tasks/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/02_index_tasks/Makefile b/tutorial-fortran/fortran/02_index_tasks/Makefile new file mode 100644 index 0000000000..0d660bc9c9 --- /dev/null +++ b/tutorial-fortran/fortran/02_index_tasks/Makefile @@ -0,0 +1,49 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= index_tasks +# List all the application source files here +GEN_FORTRAN_SRC ?= index_tasks.f90 # .f90 files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/02_index_tasks/index_tasks.f90 b/tutorial-fortran/fortran/02_index_tasks/index_tasks.f90 new file mode 100644 index 0000000000..2354f78ded --- /dev/null +++ b/tutorial-fortran/fortran/02_index_tasks/index_tasks.f90 @@ -0,0 +1,168 @@ +module hello_world_index + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID = 0 + integer(c_int), parameter :: HELLO_WORLD_TASK_ID = 1 + +contains + subroutine hello_world_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: global_arglen, local_arglen + integer*4, pointer :: global_task_args, local_task_args + type(c_ptr) :: global_task_args_ptr, local_task_args_ptr + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_task_get_args_f(task, global_task_args_ptr) + call c_f_pointer(global_task_args_ptr, global_task_args) + call legion_task_get_arglen_f(task, global_arglen) + + call legion_task_get_local_args_f(task, local_task_args_ptr) + call c_f_pointer(local_task_args_ptr, local_task_args) + call legion_task_get_local_arglen_f(task, local_arglen) + Print *, "Hello World Index Task!", local_task_args, local_arglen, global_task_args, global_arglen + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine hello_world_task + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: global_task_args, local_task_args(0:9) + type(legion_index_launcher_f_t) :: index_launcher + integer(c_long) :: tag = 0 + type(legion_argument_map_f_t) :: arg_map + type(legion_point_1d_f_t) :: lo, hi, tmp_p + type(legion_domain_point_f_t) :: dp + type(legion_rect_1d_f_t) :: launch_bound + type(legion_domain_f_t) :: domain + + type(legion_future_map_f_t) :: hello_world_task_future_map + + integer*4, target :: i = 0 + integer*4, target :: input = 0 + + Print *, "TOP Level Task!" + + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_predicate_true_f(pred) + global_task_args%args = c_loc(i) + global_task_args%arglen = c_sizeof(i) + + ! init launch domain + lo%x(0) = 0 + hi%x(0) = 9 + launch_bound%lo = lo + launch_bound%hi = hi + call legion_domain_from_rect_1d_f(launch_bound, domain) + + ! create arg map + call legion_argument_map_create_f(arg_map) + do i = 0, 9 + input = i + 10 + local_task_args(i)%args = c_loc(input) + local_task_args(i)%arglen = c_sizeof(input) + tmp_p%x(0) = i + call legion_domain_point_from_point_1d_f(tmp_p, dp) + call legion_argument_map_set_point_f(arg_map, dp, local_task_args(i), .true.) + end do + + ! index launcher + call legion_index_launcher_create_f(HELLO_WORLD_TASK_ID, domain, global_task_args, & + arg_map, pred, .FALSE., 0, tag, index_launcher) + call legion_index_launcher_execute_f(runtime, ctx, index_launcher, hello_world_task_future_map) + call legion_future_map_wait_all_results_f(hello_world_task_future_map) + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module hello_world_index + +Program hello_index + use legion_fortran + use iso_c_binding + use hello_world_index + implicit none + + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2 + integer(c_size_t) :: userlen = 0 + integer(c_int) :: runtime_start_rv + type(c_funptr) :: c_func_ptr + + Print *, "Hello World from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f( & + TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + c_func_ptr = c_funloc(hello_world_task) + + call legion_runtime_preregister_task_variant_fnptr_f( & + HELLO_WORLD_TASK_ID, c_char_"hello_world_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program hello_index diff --git a/tutorial-fortran/fortran/06_privileges_2d_accessor/CMakeLists.txt b/tutorial-fortran/fortran/06_privileges_2d_accessor/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_2d_accessor/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/06_privileges_2d_accessor/Makefile b/tutorial-fortran/fortran/06_privileges_2d_accessor/Makefile new file mode 100644 index 0000000000..11a7797fe7 --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_2d_accessor/Makefile @@ -0,0 +1,49 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= privileges +# List all the application source files here +GEN_FORTRAN_SRC ?= privileges.f90 # .f90 files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/06_privileges_2d_accessor/privileges.f90 b/tutorial-fortran/fortran/06_privileges_2d_accessor/privileges.f90 new file mode 100644 index 0000000000..a4646deaea --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_2d_accessor/privileges.f90 @@ -0,0 +1,431 @@ +module daxpy + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID=0 + integer(c_int), parameter :: INIT_TASK_ID=1 + integer(c_int), parameter :: DAXPY_TASK_ID=2 + integer(c_int), parameter :: CHECK_TASK_ID=3 + +contains + subroutine init_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + type(legion_physical_region_f_t) :: pr + integer(c_int) :: fid + type(legion_accessor_array_2d_f_t) :: accessor + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_point_2d_f_t) :: lo, hi + type(legion_rect_2d_f_t) :: index_rect + real(kind=8), target :: x_value + type(legion_point_2d_f_t) :: point + integer :: i, j + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + fid = task_arg + Print *, "Init Task!", fid, arglen + + call legion_physical_region_get_field_accessor_array_2d_f(pr, fid, accessor) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_2d_f(index_domain, index_rect) + lo = index_rect%lo + hi = index_rect%hi + + do i = lo%x(0), hi%x(0) + do j = lo%x(1), hi%x(1) + point%x(0) = j + point%x(1) = i + x_value = 1.1 * (fid+1) + call legion_accessor_array_2d_write_point_f(accessor, point, x_value) + end do + end do + + print *, "Init done", hi%x(0) + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine init_task + + subroutine daxpy_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_2d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_point_2d_f_t) :: lo, hi + type(legion_rect_2d_f_t) :: index_rect + real(kind=8), target :: xy_value, x_value, y_value + type(legion_point_2d_f_t) :: point + integer :: i, j + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Daxpy Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_2d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_2d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_2d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_2d_f(index_domain, index_rect) + lo = index_rect%lo + hi = index_rect%hi + + do i = lo%x(0), hi%x(0) + do j = lo%x(1), hi%x(1) + point%x(0) = j + point%x(1) = i + call legion_accessor_array_2d_read_point_f(accessor_x, point, x_value) + call legion_accessor_array_2d_read_point_f(accessor_y, point, y_value) + xy_value = x_value + y_value + call legion_accessor_array_2d_write_point_f(accessor_z, point, xy_value) + end do + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine daxpy_task + + subroutine check_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_2d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_point_2d_f_t) :: lo, hi + type(legion_rect_2d_f_t) :: index_rect + type(legion_point_2d_f_t) :: point + real(kind=8), target :: x_value = 0 + real(kind=8), target :: y_value = 0 + real(kind=8), target :: z_value = 0 + integer :: i, j + logical :: all_passed = .true. + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Check Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_2d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_2d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_2d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_2d_f(index_domain, index_rect) + lo = index_rect%lo + hi = index_rect%hi + + do i = lo%x(0), hi%x(0) + do j = lo%x(1), hi%x(1) + point%x(0) = i + point%x(1) = j + call legion_accessor_array_2d_read_point_f(accessor_x, point, x_value) + call legion_accessor_array_2d_read_point_f(accessor_y, point, y_value) + call legion_accessor_array_2d_read_point_f(accessor_z, point, z_value) + if (x_value + y_value == z_value) then + else + print *, "wrong", i, x_value, y_value, z_value + all_passed = .false. + end if + end do + end do + + if (all_passed .eqv. .true.) then + print *, "Pass" + else + print *, "Failed" + end if + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine check_task + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + + type(legion_point_2d_f_t) :: lo, hi + type(legion_domain_f_t) :: index_domain + type(legion_rect_2d_f_t) :: index_rect + type(legion_index_space_f_t) :: is + type(legion_field_space_f_t) :: input_fs, output_fs + type(legion_logical_region_f_t) :: input_lr, output_lr + type(legion_field_allocator_f_t) :: ifs_allocator, ofs_allocator + real(kind=8) :: real_number = 0.0 + integer(c_int) :: fid_x, fid_y, fid_z + + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: task_args + integer(c_int) :: rr_ix, rr_iy, rr_cxy, rr_cz + type(legion_task_launcher_f_t) :: init_launcher_x, init_launcher_y, daxpy_launcher, check_launcher + integer(c_long) :: tag = 0 + type(legion_future_f_t) :: init_task_future, daxpy_task_future, check_task_future + + integer*4, target :: i + integer*4 :: num_elements = 1024 + ! common HELLO_WORLD_TASK_ID + + Print *, "TOP Level Task!" + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + ! create index space, field space and logical region + lo%x(0) = 0 + lo%x(1) = 0 + hi%x(0) = num_elements-1 + hi%x(1) = num_elements-1 + index_rect%lo = lo + index_rect%hi = hi + call legion_domain_from_rect_2d_f(index_rect, index_domain) + call legion_index_space_create_domain_f(runtime, ctx, index_domain, is) + call legion_field_space_create_f(runtime, ctx, input_fs) + call legion_field_allocator_create_f(runtime, ctx, input_fs, ifs_allocator) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 0, fid_x) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 1, fid_y) + call legion_field_allocator_destroy_f(ifs_allocator) + + call legion_field_space_create_f(runtime, ctx, output_fs) + call legion_field_allocator_create_f(runtime, ctx, output_fs, ofs_allocator) + call legion_field_allocator_allocate_field_f(ofs_allocator, c_sizeof(real_number), 2, fid_z) + call legion_field_allocator_destroy_f(ofs_allocator) + print *, fid_x, fid_y, fid_z + + call legion_logical_region_create_f(runtime, ctx, is, input_fs, input_lr) + call legion_logical_region_create_f(runtime, ctx, is, output_fs, output_lr) + + call legion_predicate_true_f(pred) + + !init task for X + i = 0 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(INIT_TASK_ID, task_args, pred, 0, tag, init_launcher_x) + call legion_task_launcher_add_region_requirement_logical_region_f(init_launcher_x, input_lr, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_ix) + call legion_task_launcher_add_field_f(init_launcher_x, rr_ix, 0, .true.) + call legion_task_launcher_execute_f(runtime, ctx, init_launcher_x, init_task_future) + + !init task for Y + i = 1 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(INIT_TASK_ID, task_args, pred, 0, tag, init_launcher_y) + call legion_task_launcher_add_region_requirement_logical_region_f(init_launcher_y, input_lr, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_iy) + call legion_task_launcher_add_field_f(init_launcher_y, rr_iy, 1, .true.) + call legion_task_launcher_execute_f(runtime, ctx, init_launcher_y, init_task_future) + + !daxpy task + i = 2 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(DAXPY_TASK_ID, task_args, pred, 0, tag, daxpy_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(daxpy_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cxy, 0, .true.) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cxy, 1, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(daxpy_launcher, output_lr, & + WRITE_DISCARD, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cz, 2, .true.) + call legion_task_launcher_execute_f(runtime, ctx, daxpy_launcher, daxpy_task_future) + + !check task + i = 3 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(CHECK_TASK_ID, task_args, pred, 0, tag, check_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 0, .true.) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 1, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, output_lr, & + READ_ONLY, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(check_launcher, rr_cz, 2, .true.) + call legion_task_launcher_execute_f(runtime, ctx, check_launcher, check_task_future) + + + ! clean up + call legion_logical_region_destroy_f(runtime, ctx, input_lr) + call legion_logical_region_destroy_f(runtime, ctx, output_lr) + call legion_field_space_destroy_f(runtime, ctx, input_fs) + call legion_field_space_destroy_f(runtime, ctx, output_fs) + call legion_index_space_destroy_f(runtime, ctx, is) + call legion_task_launcher_destroy_f(init_launcher_x) + call legion_task_launcher_destroy_f(init_launcher_y) + call legion_task_launcher_destroy_f(daxpy_launcher) + call legion_task_launcher_destroy_f(check_launcher) + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module daxpy + +Program daxpy_2d_accessor + use legion_fortran + use iso_c_binding + use daxpy + implicit none + + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2, task_id_3, task_id_4 + integer(c_size_t) :: userlen = 0 + integer(c_int) :: runtime_start_rv + type(c_funptr) :: c_func_ptr + + Print *, "Hello World from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f(TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + c_func_ptr = c_funloc(init_task) + + call legion_runtime_preregister_task_variant_fnptr_f(INIT_TASK_ID, c_char_"init_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + c_func_ptr = c_funloc(daxpy_task) + + call legion_runtime_preregister_task_variant_fnptr_f(DAXPY_TASK_ID, c_char_"daxpy_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_3) + + c_func_ptr = c_funloc(check_task) + + call legion_runtime_preregister_task_variant_fnptr_f(CHECK_TASK_ID, c_char_"check_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_4) + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program daxpy_2d_accessor diff --git a/tutorial-fortran/fortran/06_privileges_accessor/CMakeLists.txt b/tutorial-fortran/fortran/06_privileges_accessor/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_accessor/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/06_privileges_accessor/Makefile b/tutorial-fortran/fortran/06_privileges_accessor/Makefile new file mode 100644 index 0000000000..11a7797fe7 --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_accessor/Makefile @@ -0,0 +1,49 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= privileges +# List all the application source files here +GEN_FORTRAN_SRC ?= privileges.f90 # .f90 files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/06_privileges_accessor/privileges.f90 b/tutorial-fortran/fortran/06_privileges_accessor/privileges.f90 new file mode 100644 index 0000000000..7cf01a8f86 --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_accessor/privileges.f90 @@ -0,0 +1,409 @@ +module daxpy + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID=0 + integer(c_int), parameter :: INIT_TASK_ID=1 + integer(c_int), parameter :: DAXPY_TASK_ID=2 + integer(c_int), parameter :: CHECK_TASK_ID=3 + +contains + subroutine init_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + type(legion_physical_region_f_t) :: pr + integer(c_int) :: fid + type(legion_accessor_array_1d_f_t) :: accessor + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + real(kind=8), target :: x_value + type(legion_point_1d_f_t) :: point + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + fid = task_arg + Print *, "Init Task!", fid, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr, fid, accessor) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + x_value = 1.1 * (fid+1) + i + call legion_accessor_array_1d_write_point_f(accessor, point, x_value) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine init_task + + subroutine daxpy_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + real(kind=8), target :: xy_value, x_value, y_value + type(legion_point_1d_f_t) :: point + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Daxpy Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + call legion_accessor_array_1d_read_point_f(accessor_x, point, x_value) + call legion_accessor_array_1d_read_point_f(accessor_y, point, y_value) + xy_value = x_value + y_value + call legion_accessor_array_1d_write_point_f(accessor_z, point, xy_value) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine daxpy_task + + subroutine check_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + type(legion_point_1d_f_t) :: point + real(kind=8), target :: x_value = 0 + real(kind=8), target :: y_value = 0 + real(kind=8), target :: z_value = 0 + integer :: i + logical :: all_passed = .true. + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Check Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + call legion_accessor_array_1d_read_point_f(accessor_x, point, x_value) + call legion_accessor_array_1d_read_point_f(accessor_y, point, y_value) + call legion_accessor_array_1d_read_point_f(accessor_z, point, z_value) + if (x_value + y_value == z_value) then + else + print *, "wrong", i, x_value, y_value, z_value + all_passed = .false. + end if + end do + + if (all_passed .eqv. .true.) then + print *, "Pass" + else + print *, "Failed" + end if + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine check_task + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + + type(legion_point_1d_f_t) :: lo, hi + type(legion_domain_f_t) :: index_domain + type(legion_rect_1d_f_t) :: index_rect + type(legion_index_space_f_t) :: is + type(legion_field_space_f_t) :: input_fs, output_fs + type(legion_logical_region_f_t) :: input_lr, output_lr + type(legion_field_allocator_f_t) :: ifs_allocator, ofs_allocator + real(kind=8) :: real_number = 0.0 + integer(c_int) :: fid_x, fid_y, fid_z + + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: task_args + integer(c_int) :: rr_ix, rr_iy, rr_cxy, rr_cz + type(legion_task_launcher_f_t) :: init_launcher_x, init_launcher_y, daxpy_launcher, check_launcher + integer(c_long) :: tag = 0 + type(legion_future_f_t) :: init_task_future, daxpy_task_future, check_task_future + + integer*4, target :: i + integer*4 :: num_elements = 1024 + ! common HELLO_WORLD_TASK_ID + + Print *, "TOP Level Task!" + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + ! create index space, field space and logical region + lo%x(0) = 0 + hi%x(0) = num_elements-1 + index_rect%lo = lo + index_rect%hi = hi + call legion_domain_from_rect_1d_f(index_rect, index_domain) + call legion_index_space_create_domain_f(runtime, ctx, index_domain, is) + call legion_field_space_create_f(runtime, ctx, input_fs) + call legion_field_allocator_create_f(runtime, ctx, input_fs, ifs_allocator) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 0, fid_x) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 1, fid_y) + call legion_field_allocator_destroy_f(ifs_allocator) + + call legion_field_space_create_f(runtime, ctx, output_fs) + call legion_field_allocator_create_f(runtime, ctx, output_fs, ofs_allocator) + call legion_field_allocator_allocate_field_f(ofs_allocator, c_sizeof(real_number), 2, fid_z) + call legion_field_allocator_destroy_f(ofs_allocator) + print *, fid_x, fid_y, fid_z + + call legion_logical_region_create_f(runtime, ctx, is, input_fs, input_lr) + call legion_logical_region_create_f(runtime, ctx, is, output_fs, output_lr) + + call legion_predicate_true_f(pred) + + !init task for X + i = 0 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(INIT_TASK_ID, task_args, pred, 0, tag, init_launcher_x) + call legion_task_launcher_add_region_requirement_logical_region_f(init_launcher_x, input_lr, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_ix) + call legion_task_launcher_add_field_f(init_launcher_x, rr_ix, 0, .true.) + call legion_task_launcher_execute_f(runtime, ctx, init_launcher_x, init_task_future) + + !init task for Y + i = 1 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(INIT_TASK_ID, task_args, pred, 0, tag, init_launcher_y) + call legion_task_launcher_add_region_requirement_logical_region_f(init_launcher_y, input_lr, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_iy) + call legion_task_launcher_add_field_f(init_launcher_y, rr_iy, 1, .true.) + call legion_task_launcher_execute_f(runtime, ctx, init_launcher_y, init_task_future) + + !daxpy task + i = 2 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(DAXPY_TASK_ID, task_args, pred, 0, tag, daxpy_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(daxpy_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cxy, 0, .true.) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cxy, 1, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(daxpy_launcher, output_lr, & + WRITE_DISCARD, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cz, 2, .true.) + call legion_task_launcher_execute_f(runtime, ctx, daxpy_launcher, daxpy_task_future) + + !check task + i = 3 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(CHECK_TASK_ID, task_args, pred, 0, tag, check_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 0, .true.) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 1, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, output_lr, & + READ_ONLY, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(check_launcher, rr_cz, 2, .true.) + call legion_task_launcher_execute_f(runtime, ctx, check_launcher, check_task_future) + + + ! clean up + call legion_logical_region_destroy_f(runtime, ctx, input_lr) + call legion_logical_region_destroy_f(runtime, ctx, output_lr) + call legion_field_space_destroy_f(runtime, ctx, input_fs) + call legion_field_space_destroy_f(runtime, ctx, output_fs) + call legion_index_space_destroy_f(runtime, ctx, is) + call legion_task_launcher_destroy_f(init_launcher_x) + call legion_task_launcher_destroy_f(init_launcher_y) + call legion_task_launcher_destroy_f(daxpy_launcher) + call legion_task_launcher_destroy_f(check_launcher) + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module daxpy + +Program daxpy_1d_accessor + use legion_fortran + use iso_c_binding + use daxpy + implicit none + + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2, task_id_3, task_id_4 + integer(c_size_t) :: userlen = 0 + integer(c_int) :: runtime_start_rv + type(c_funptr) :: c_func_ptr + + Print *, "Hello World from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f(TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + c_func_ptr = c_funloc(init_task) + + call legion_runtime_preregister_task_variant_fnptr_f(INIT_TASK_ID, c_char_"init_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + c_func_ptr = c_funloc(daxpy_task) + + call legion_runtime_preregister_task_variant_fnptr_f(DAXPY_TASK_ID, c_char_"daxpy_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_3) + + c_func_ptr = c_funloc(check_task) + + call legion_runtime_preregister_task_variant_fnptr_f(CHECK_TASK_ID, c_char_"check_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_4) + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program daxpy_1d_accessor diff --git a/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/CMakeLists.txt b/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/Makefile b/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/Makefile new file mode 100644 index 0000000000..8d25612bb2 --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/Makefile @@ -0,0 +1,49 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 1 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= privileges +# List all the application source files here +GEN_FORTRAN_SRC ?= privileges.f90 # .f90 files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/privileges.f90 b/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/privileges.f90 new file mode 100644 index 0000000000..5b81ec41b0 --- /dev/null +++ b/tutorial-fortran/fortran/06_privileges_raw_rect_ptr/privileges.f90 @@ -0,0 +1,427 @@ +module daxpy + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID = 0 + integer(c_int), parameter :: INIT_TASK_ID=1 + integer(c_int), parameter :: DAXPY_TASK_ID=2 + integer(c_int), parameter :: CHECK_TASK_ID=3 + +contains + subroutine init_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + type(legion_physical_region_f_t) :: pr + integer(c_int) :: fid + type(legion_accessor_array_1d_f_t) :: accessor + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + integer(c_size_t) :: index_size + type(legion_rect_1d_f_t) :: index_rect, subrect + type(legion_byte_offset_f_t) :: offset + type(c_ptr) :: raw_ptr + real(kind=8), pointer :: x(:) + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + fid = task_arg + Print *, "Init Task!", fid, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr, fid, accessor) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + call legion_domain_get_volume_f(index_domain, index_size) + + call legion_accessor_array_1d_raw_rect_ptr_f(accessor, index_rect, subrect, offset, raw_ptr) + call c_f_pointer(raw_ptr, x, [index_size-1]) + print *, raw_ptr + + ! fortran array starts from 1 + do i = 1, index_size + x(i) = 1.1 * (fid+1) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine init_task + + subroutine daxpy_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + integer(c_size_t) :: index_size + type(legion_rect_1d_f_t) :: index_rect, subrect + type(legion_byte_offset_f_t) :: offset + type(c_ptr) :: raw_ptr_x, raw_ptr_y, raw_ptr_z + real(kind=8), pointer :: x(:), y(:), z(:) + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Daxpy Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + call legion_domain_get_volume_f(index_domain, index_size) + + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_x, index_rect, subrect, offset, raw_ptr_x) + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_y, index_rect, subrect, offset, raw_ptr_y) + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_z, index_rect, subrect, offset, raw_ptr_z) + print *, raw_ptr_x, raw_ptr_y, raw_ptr_z + + call c_f_pointer(raw_ptr_x, x, [index_size-1]) + call c_f_pointer(raw_ptr_y, y, [index_size-1]) + call c_f_pointer(raw_ptr_z, z, [index_size-1]) + + do i = 1, index_size + z(i) = x(i) + y(i) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine daxpy_task + + subroutine check_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + integer(c_size_t) :: index_size + type(legion_rect_1d_f_t) :: index_rect, subrect + type(legion_byte_offset_f_t) :: offset + type(c_ptr) :: raw_ptr_x, raw_ptr_y, raw_ptr_z + real(kind=8), pointer :: x(:), y(:), z(:) + integer :: i + logical :: all_passed = .true. + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Check Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + call legion_domain_get_volume_f(index_domain, index_size) + + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_x, index_rect, subrect, offset, raw_ptr_x) + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_y, index_rect, subrect, offset, raw_ptr_y) + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_z, index_rect, subrect, offset, raw_ptr_z) + print *, raw_ptr_x, raw_ptr_y, raw_ptr_z, index_size + + call c_f_pointer(raw_ptr_x, x, [index_size-1]) + call c_f_pointer(raw_ptr_y, y, [index_size-1]) + call c_f_pointer(raw_ptr_z, z, [index_size-1]) + + do i = 1, index_size + if (x(i) + y(i) == z(i)) then + else + print *, "wrong", x(i), y(i), z(i) + all_passed = .false. + end if + end do + + if (all_passed .eqv. .true.) then + print *, "Pass" + else + print *, "Failed" + end if + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine check_task + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + + type(legion_point_1d_f_t) :: lo, hi + type(legion_domain_f_t) :: index_domain + type(legion_rect_1d_f_t) :: index_rect + type(legion_index_space_f_t) :: is + type(legion_field_space_f_t) :: input_fs, output_fs + type(legion_logical_region_f_t) :: input_lr, output_lr + type(legion_field_allocator_f_t) :: ifs_allocator, ofs_allocator + real*8 :: real_number = 0.0 + integer(c_int) :: fid_x, fid_y, fid_z + + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: task_args + integer(c_int) :: rr_ix, rr_iy, rr_cxy, rr_cz + type(legion_task_launcher_f_t) :: init_launcher_x, init_launcher_y, daxpy_launcher, check_launcher + integer(c_long) :: tag = 0 + type(legion_future_f_t) :: init_task_future, daxpy_task_future, check_task_future + + integer*4, target :: i + integer*4 :: num_elements = 2048 + + Print *, "TOP Level Task!" + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + ! create index space, field space and logical region + lo%x(0) = 0 + hi%x(0) = num_elements-1 + index_rect%lo = lo + index_rect%hi = hi + call legion_domain_from_rect_1d_f(index_rect, index_domain) + call legion_index_space_create_domain_f(runtime, ctx, index_domain, is) + call legion_field_space_create_f(runtime, ctx, input_fs) + call legion_field_allocator_create_f(runtime, ctx, input_fs, ifs_allocator) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 0, fid_x) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 1, fid_y) + call legion_field_allocator_destroy_f(ifs_allocator) + + call legion_field_space_create_f(runtime, ctx, output_fs) + call legion_field_allocator_create_f(runtime, ctx, output_fs, ofs_allocator) + call legion_field_allocator_allocate_field_f(ofs_allocator, c_sizeof(real_number), 2, fid_z) + call legion_field_allocator_destroy_f(ofs_allocator) + print *, fid_x, fid_y, fid_z + + call legion_logical_region_create_f(runtime, ctx, is, input_fs, input_lr) + call legion_logical_region_create_f(runtime, ctx, is, output_fs, output_lr) + + call legion_predicate_true_f(pred) + + !init task for X + i = 0 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(INIT_TASK_ID, task_args, pred, 0, tag, init_launcher_x) + call legion_task_launcher_add_region_requirement_logical_region_f(init_launcher_x, input_lr, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_ix) + call legion_task_launcher_add_field_f(init_launcher_x, rr_ix, fid_x, .true.) + call legion_task_launcher_execute_f(runtime, ctx, init_launcher_x, init_task_future) + + !init task for Y + i = 1 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(INIT_TASK_ID, task_args, pred, 0, tag, init_launcher_y) + call legion_task_launcher_add_region_requirement_logical_region_f(init_launcher_y, input_lr, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_iy) + call legion_task_launcher_add_field_f(init_launcher_y, rr_iy, fid_y, .true.) + call legion_task_launcher_execute_f(runtime, ctx, init_launcher_y, init_task_future) + + !daxpy task + i = 2 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(DAXPY_TASK_ID, task_args, pred, 0, tag, daxpy_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(daxpy_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cxy, fid_x, .true.) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cxy, fid_y, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(daxpy_launcher, output_lr, & + WRITE_DISCARD, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(daxpy_launcher, rr_cz, fid_z, .true.) + call legion_task_launcher_execute_f(runtime, ctx, daxpy_launcher, daxpy_task_future) + + !check task + i = 3 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(CHECK_TASK_ID, task_args, pred, 0, tag, check_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, fid_x, .true.) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, fid_y, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, output_lr, & + READ_ONLY, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(check_launcher, rr_cz, fid_z, .true.) + call legion_task_launcher_execute_f(runtime, ctx, check_launcher, check_task_future) + + ! clean up + call legion_logical_region_destroy_f(runtime, ctx, input_lr) + call legion_logical_region_destroy_f(runtime, ctx, output_lr) + call legion_field_space_destroy_f(runtime, ctx, input_fs) + call legion_field_space_destroy_f(runtime, ctx, output_fs) + call legion_index_space_destroy_f(runtime, ctx, is) + call legion_task_launcher_destroy_f(init_launcher_x) + call legion_task_launcher_destroy_f(init_launcher_y) + call legion_task_launcher_destroy_f(daxpy_launcher) + call legion_task_launcher_destroy_f(check_launcher) + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module daxpy + +Program daxpy_raw_rect_pointer + use legion_fortran + use iso_c_binding + use daxpy + implicit none + + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2, task_id_3, task_id_4 + integer(c_size_t) :: userlen = 0 + integer(c_int) :: runtime_start_rv + type(c_funptr) :: c_func_ptr + + Print *, "Hello World from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f(TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + c_func_ptr = c_funloc(init_task) + + call legion_runtime_preregister_task_variant_fnptr_f(INIT_TASK_ID, c_char_"init_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + c_func_ptr = c_funloc(daxpy_task) + + call legion_runtime_preregister_task_variant_fnptr_f(DAXPY_TASK_ID, c_char_"daxpy_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_3) + + c_func_ptr = c_funloc(check_task) + + call legion_runtime_preregister_task_variant_fnptr_f(CHECK_TASK_ID, c_char_"check_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_4) + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program daxpy_raw_rect_pointer diff --git a/tutorial-fortran/fortran/07_partitioning/CMakeLists.txt b/tutorial-fortran/fortran/07_partitioning/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/07_partitioning/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/07_partitioning/Makefile b/tutorial-fortran/fortran/07_partitioning/Makefile new file mode 100644 index 0000000000..22af626fd9 --- /dev/null +++ b/tutorial-fortran/fortran/07_partitioning/Makefile @@ -0,0 +1,49 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= partitioning +# List all the application source files here +GEN_FORTRAN_SRC ?= partitioning.f90 # .f90 files +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/07_partitioning/partitioning.f90 b/tutorial-fortran/fortran/07_partitioning/partitioning.f90 new file mode 100644 index 0000000000..e6738643c9 --- /dev/null +++ b/tutorial-fortran/fortran/07_partitioning/partitioning.f90 @@ -0,0 +1,453 @@ +module daxpy_partition + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID=0 + integer(c_int), parameter :: INIT_TASK_ID=1 + integer(c_int), parameter :: DAXPY_TASK_ID=2 + integer(c_int), parameter :: CHECK_TASK_ID=3 + +contains + subroutine init_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + type(legion_physical_region_f_t) :: pr + integer(c_int) :: fid + type(legion_accessor_array_1d_f_t) :: accessor + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect, subrect + type(legion_byte_offset_f_t) :: offset + type(c_ptr) :: raw_ptr_x, raw_ptr_y, raw_ptr_z + real(kind=8), target :: x_value + type(legion_point_1d_f_t) :: point + integer :: i + + type(legion_region_requirement_f_t) :: rr + integer(c_int) :: rrfid + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + fid = task_arg + + call legion_task_get_region_f(task, 0, rr) + call legion_region_requirement_get_privilege_field_f(rr, 0, rrfid) + + + call legion_physical_region_get_field_accessor_array_1d_f(pr, fid, accessor) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + call legion_accessor_array_1d_raw_rect_ptr_f(accessor, index_rect, subrect, offset, raw_ptr_x) + + Print *, "Init Task!", rrfid, fid, index_rect%lo%x(0), arglen, raw_ptr_x + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + x_value = 1.1 * (fid+1) + i + call legion_accessor_array_1d_write_point_f(accessor, point, x_value) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine init_task + + subroutine daxpy_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use legion_fortran_object_oriented + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(LegionFieldAccessor1D) :: accessor_x, accessor_y, accessor_z + type(LegionPoint1D) ::point_1d + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect, subrect + real(kind=8), target :: xy_value, x_value, y_value + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Daxpy Task!", task_arg, arglen + + accessor_x = LegionFieldAccessor1D(pr1, 0, c_sizeof(x_value)) + accessor_y = LegionFieldAccessor1D(pr1, 1, c_sizeof(y_value)) + accessor_z = LegionFieldAccessor1D(pr2, 2, c_sizeof(xy_value)) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point_1d = LegionPoint1D(i) + call accessor_x%read_point(point_1d, x_value) + call accessor_y%read_point(point_1d, y_value) + xy_value = x_value + y_value + call accessor_z%write_point(point_1d, xy_value) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine daxpy_task + + subroutine check_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect, subrect + type(legion_point_1d_f_t) :: point + real(kind=8), target :: x_value = 0 + real(kind=8), target :: y_value = 0 + real(kind=8), target :: z_value = 0 + integer :: i + logical :: all_passed = .true. + type(c_ptr) :: raw_ptr_x, raw_ptr_y, raw_ptr_z + type(legion_byte_offset_f_t) :: offset + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_x, index_rect, subrect, offset, raw_ptr_x) + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_y, index_rect, subrect, offset, raw_ptr_y) + call legion_accessor_array_1d_raw_rect_ptr_f(accessor_z, index_rect, subrect, offset, raw_ptr_z) + + Print *, "Check Task!", task_arg, arglen, raw_ptr_x, raw_ptr_y, raw_ptr_z + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + call legion_accessor_array_1d_read_point_f(accessor_x, point, x_value) + call legion_accessor_array_1d_read_point_f(accessor_y, point, y_value) + call legion_accessor_array_1d_read_point_f(accessor_z, point, z_value) + if (x_value + y_value == z_value) then + else + print *, "wrong", i, x_value, y_value, z_value + all_passed = .false. + end if + end do + + if (all_passed .eqv. .true.) then + print *, "Pass" + else + print *, "Failed" + end if + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine check_task + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + + type(legion_point_1d_f_t) :: lo, hi, lo_c, hi_c + type(legion_domain_f_t) :: index_domain, color_domain + type(legion_rect_1d_f_t) :: index_rect, color_rect + type(legion_index_space_f_t) :: is, color_is + type(legion_index_partition_f_t) :: ip + type(legion_field_space_f_t) :: input_fs, output_fs + type(legion_logical_region_f_t) :: input_lr, output_lr + type(legion_field_allocator_f_t) :: ifs_allocator, ofs_allocator + real(kind=8) :: real_number = 0.0 + integer(c_int) :: fid_x, fid_y, fid_z + integer(c_size_t) :: granularity = 1 + character (len=3), target :: ip_name = "ip"//c_null_char + character (len=9), target :: input_ip_name = "input_ip"//c_null_char + character (len=10), target :: output_ip_name = "output_ip"//c_null_char + type(legion_logical_partition_f_t) :: input_lp, output_lp + + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: task_args + integer(c_int) :: rr_ix, rr_iy, rr_cxy, rr_cz + type(legion_index_launcher_f_t) :: init_launcher_x, init_launcher_y, daxpy_launcher + type(legion_task_launcher_f_t) :: check_launcher + integer(c_long) :: tag = 0 + type(legion_future_f_t) :: check_task_future + type(legion_future_map_f_t) :: init_task_future_map, daxpy_task_future_map + type(legion_argument_map_f_t) :: arg_map + + integer*4, target :: i + integer*4 :: num_elements = 1024 + integer*4 :: num_subregions = 8 + ! common HELLO_WORLD_TASK_ID + + Print *, "TOP Level Task!" + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + ! create index space, field space and logical region + lo%x(0) = 0 + hi%x(0) = num_elements-1 + index_rect%lo = lo + index_rect%hi = hi + call legion_domain_from_rect_1d_f(index_rect, index_domain) + call legion_index_space_create_domain_f(runtime, ctx, index_domain, is) + call legion_field_space_create_f(runtime, ctx, input_fs) + call legion_field_allocator_create_f(runtime, ctx, input_fs, ifs_allocator) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 0, fid_x) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 1, fid_y) + call legion_field_allocator_destroy_f(ifs_allocator) + + call legion_field_space_create_f(runtime, ctx, output_fs) + call legion_field_allocator_create_f(runtime, ctx, output_fs, ofs_allocator) + call legion_field_allocator_allocate_field_f(ofs_allocator, c_sizeof(real_number), 2, fid_z) + call legion_field_allocator_destroy_f(ofs_allocator) + print *, fid_x, fid_y, fid_z + + call legion_logical_region_create_f(runtime, ctx, is, input_fs, input_lr) + call legion_logical_region_create_f(runtime, ctx, is, output_fs, output_lr) + + ! create partition + lo_c%x(0) = 0 + hi_c%x(0) = num_subregions-1 + color_rect%lo = lo_c + color_rect%hi = hi_c + call legion_domain_from_rect_1d_f(color_rect, color_domain) + call legion_index_space_create_domain_f(runtime, ctx, color_domain, color_is) + call legion_index_partition_create_equal_f(runtime, ctx, is, color_is, granularity, 0, ip) + call legion_index_partition_attach_name_f(runtime, ip, ip_name, .false.) + + call legion_logical_partition_create_f(runtime, ctx, input_lr, ip, input_lp) + call legion_logical_partition_attach_name_f(runtime, input_lp, input_ip_name, .false.) + call legion_logical_partition_create_f(runtime, ctx, output_lr, ip, output_lp) + call legion_logical_partition_attach_name_f(runtime, output_lp, output_ip_name, .false.) + + call legion_predicate_true_f(pred) + call legion_argument_map_create_f(arg_map) + + !init task for X + i = 0 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_index_launcher_create_f(INIT_TASK_ID, color_domain, task_args, arg_map, pred, .false., 0, tag, init_launcher_x) + call legion_index_launcher_add_region_requirement_lp_f(init_launcher_x, input_lp, 0, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_ix) + call legion_index_launcher_add_field_f(init_launcher_x, rr_ix, 0, .true.) + call legion_index_launcher_execute_f(runtime, ctx, init_launcher_x, init_task_future_map) + + !init task for Y + i = 1 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_index_launcher_create_f(INIT_TASK_ID, color_domain, task_args, arg_map, pred, .false., 0, tag, init_launcher_y) + call legion_index_launcher_add_region_requirement_lp_f(init_launcher_y, input_lp, 0, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_iy) + call legion_index_launcher_add_field_f(init_launcher_y, rr_iy, 1, .true.) + call legion_index_launcher_execute_f(runtime, ctx, init_launcher_y, init_task_future_map) + + !daxpy task + i = 2 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_index_launcher_create_f(DAXPY_TASK_ID, color_domain, task_args, arg_map, pred, .false., 0, tag, daxpy_launcher) + call legion_index_launcher_add_region_requirement_lp_f(daxpy_launcher, input_lp, 0, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_index_launcher_add_field_f(daxpy_launcher, rr_cxy, 0, .true.) + call legion_index_launcher_add_field_f(daxpy_launcher, rr_cxy, 1, .true.) + call legion_index_launcher_add_region_requirement_lp_f(daxpy_launcher, output_lp, 0, & + WRITE_DISCARD, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_index_launcher_add_field_f(daxpy_launcher, rr_cz, 2, .true.) + call legion_index_launcher_execute_f(runtime, ctx, daxpy_launcher, daxpy_task_future_map) + + !check task + i = 3 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(CHECK_TASK_ID, task_args, pred, 0, tag, check_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 0, .true.) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 1, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, output_lr, & + READ_ONLY, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(check_launcher, rr_cz, 2, .true.) + call legion_task_launcher_execute_f(runtime, ctx, check_launcher, check_task_future) + + ! clean up + call legion_logical_region_destroy_f(runtime, ctx, input_lr) + call legion_logical_region_destroy_f(runtime, ctx, output_lr) + call legion_field_space_destroy_f(runtime, ctx, input_fs) + call legion_field_space_destroy_f(runtime, ctx, output_fs) + call legion_index_space_destroy_f(runtime, ctx, is) + call legion_index_launcher_destroy_f(init_launcher_x) + call legion_index_launcher_destroy_f(init_launcher_y) + call legion_index_launcher_destroy_f(daxpy_launcher) + call legion_task_launcher_destroy_f(check_launcher) + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module daxpy_partition + +Program daxpy_partition_accessor + use legion_fortran + use iso_c_binding + use daxpy_partition + implicit none + + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2, task_id_3, task_id_4 + integer(c_size_t) :: userlen = 0 + integer(c_int) :: runtime_start_rv + type(c_funptr) :: c_func_ptr + + Print *, "Hello World from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f(TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + config_options%leaf = .true. + c_func_ptr = c_funloc(init_task) + + call legion_runtime_preregister_task_variant_fnptr_f(INIT_TASK_ID, c_char_"init_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + c_func_ptr = c_funloc(daxpy_task) + + call legion_runtime_preregister_task_variant_fnptr_f(DAXPY_TASK_ID, c_char_"daxpy_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_3) + + c_func_ptr = c_funloc(check_task) + + call legion_runtime_preregister_task_variant_fnptr_f(CHECK_TASK_ID, c_char_"check_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_4) + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program daxpy_partition_accessor diff --git a/tutorial-fortran/fortran/attach_file/CMakeLists.txt b/tutorial-fortran/fortran/attach_file/CMakeLists.txt new file mode 100644 index 0000000000..027bacda7d --- /dev/null +++ b/tutorial-fortran/fortran/attach_file/CMakeLists.txt @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------# +# Copyright 2017 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.1) +project(LegionExample_00_hello_world) + +# Only search if were building stand-alone and not as part of Legion +if(NOT Legion_SOURCE_DIR) + find_package(Legion REQUIRED) +endif() + +add_executable(hello_world hello_world.cc) +target_link_libraries(hello_world Legion::Legion) +if(Legion_ENABLE_TESTING) + add_test(NAME hello_world COMMAND $) +endif() diff --git a/tutorial-fortran/fortran/attach_file/Makefile b/tutorial-fortran/fortran/attach_file/Makefile new file mode 100644 index 0000000000..9ccb48d4cd --- /dev/null +++ b/tutorial-fortran/fortran/attach_file/Makefile @@ -0,0 +1,50 @@ +# Copyright 2017 Stanford University +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +ifndef LG_RT_DIR +$(error LG_RT_DIR variable is not defined, aborting build) +endif + +# Flags for directing the runtime makefile what to include +DEBUG ?= 1 # Include debugging symbols +OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level +USE_CUDA ?= 0 # Include CUDA support (requires CUDA) +USE_GASNET ?= 0 # Include GASNet support (requires GASNet) +USE_HDF ?= 1 # Include HDF5 support (requires HDF5) +ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) + +# Put the binary file name here +OUTFILE ?= attach_file +# List all the application source files here +GEN_FORTRAN_SRC ?= attach_file.f90 # .f90 files +GEN_SRC ?= generate_hdf_file.cc +GEN_GPU_SRC ?= # .cu files + +# You can modify these variables, some will be appended to by the runtime makefile +INC_FLAGS ?= +CC_FLAGS ?= +NVCC_FLAGS ?= +GASNET_FLAGS ?= +LD_FLAGS ?= +LEGION_WITH_FORTRAN ?= 1 +########################################################################### +# +# Don't change anything below here +# +########################################################################### + +include $(LG_RT_DIR)/runtime.mk + diff --git a/tutorial-fortran/fortran/attach_file/attach_file.f90 b/tutorial-fortran/fortran/attach_file/attach_file.f90 new file mode 100644 index 0000000000..4db5da81eb --- /dev/null +++ b/tutorial-fortran/fortran/attach_file/attach_file.f90 @@ -0,0 +1,497 @@ +module daxpy_partition_attach + use iso_c_binding + implicit none + + integer(c_int), parameter :: TOP_LEVEL_TASK_ID=0 + integer(c_int), parameter :: INIT_TASK_ID=1 + integer(c_int), parameter :: DAXPY_TASK_ID=2 + integer(c_int), parameter :: CHECK_TASK_ID=3 + + subroutine init_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + type(legion_physical_region_f_t) :: pr + integer(c_int) :: fid + type(legion_accessor_array_1d_f_t) :: accessor + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + real(c_double), target :: x_value + type(c_ptr) :: x_ptr + type(legion_point_1d_f_t) :: point + integer :: i + + type(legion_region_requirement_f_t) :: rr + integer(c_int) :: rrfid + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + fid = task_arg + + call legion_task_get_region_f(task, 0, rr) + call legion_region_requirement_get_privilege_field_f(rr, 0, rrfid) + + + call legion_physical_region_get_field_accessor_array_1d_f(pr, fid, accessor) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + Print *, "Init Task!", rrfid, fid, index_rect%lo%x(0), arglen + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + x_value = 1.1 * (fid+1) + i + x_ptr = c_loc(x_value) + call legion_accessor_array_1d_write_point_f(accessor, point, x_ptr, c_sizeof(x_value)) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine init_task + + subroutine daxpy_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use legion_fortran_object_oriented + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x + type(LegionFieldAccessor1D) :: accessor_y, accessor_z + type(LegionPoint1D) ::point_1d + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + real(c_double), target :: xy_value, x_value, y_value + type(c_ptr) :: xy_ptr, x_ptr, y_ptr + type(legion_point_1d_f_t) :: point + integer :: i + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Daxpy Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + accessor_y = LegionFieldAccessor1D(pr1, 1, c_sizeof(y_value)) + accessor_z = LegionFieldAccessor1D(pr2, 2, c_sizeof(xy_value)) + + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + point_1d = LegionPoint1D(i) + x_ptr = c_loc(x_value) + y_ptr = c_loc(y_value) + call legion_accessor_array_1d_read_point_f(accessor_x, point, x_value) + !call legion_accessor_array_1d_read_point_f(accessor_y, point, y_ptr, c_sizeof(y_value)) + call accessor_y%read_point(point_1d, y_value) + xy_value = x_value + y_value + xy_ptr = c_loc(xy_value) + call accessor_z%write_point(point_1d, xy_value) + !call legion_accessor_array_1d_write_point_f(accessor_z, point, xy_ptr, c_sizeof(xy_value)) + end do + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine daxpy_task + + subroutine check_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + integer(c_int) ::check_task + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + type(legion_accessor_array_1d_f_t) :: accessor_x, accessor_y, accessor_z + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + integer(c_size_t) :: arglen + integer*4, pointer :: task_arg + type(c_ptr) :: task_arg_ptr + + type(legion_physical_region_f_t) :: pr1, pr2 + + type(legion_domain_f_t) :: index_domain + type(legion_index_space_f_t) :: index_space + type(legion_rect_1d_f_t) :: index_rect + type(legion_point_1d_f_t) :: point + type(c_ptr) :: x_ptr, y_ptr, z_ptr + real(c_double), target :: x_value = 0 + real(c_double), target :: y_value = 0 + real(c_double), target :: z_value = 0 + integer :: i + logical :: all_passed = .true. + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + call legion_get_physical_region_by_id_f(regionptr, 0, num_regions, pr1) + call legion_get_physical_region_by_id_f(regionptr, 1, num_regions, pr2) + call legion_task_get_args_f(task, task_arg_ptr) + call c_f_pointer(task_arg_ptr, task_arg) + call legion_task_get_arglen_f(task, arglen) + Print *, "Check Task!", task_arg, arglen + + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 0, accessor_x) + call legion_physical_region_get_field_accessor_array_1d_f(pr1, 1, accessor_y) + call legion_physical_region_get_field_accessor_array_1d_f(pr2, 2, accessor_z) + call legion_task_get_index_space_from_logical_region_f(task, 0, index_space) + call legion_index_space_get_domain_f(runtime, index_space, index_domain) + call legion_domain_get_rect_1d_f(index_domain, index_rect) + + do i = index_rect%lo%x(0), index_rect%hi%x(0) + point%x(0) = i + x_ptr = c_loc(x_value) + y_ptr = c_loc(y_value) + z_ptr = c_loc(z_value) + call legion_accessor_array_1d_read_point_f(accessor_x, point, x_ptr, c_sizeof(x_value)) + call legion_accessor_array_1d_read_point_f(accessor_y, point, y_ptr, c_sizeof(y_value)) + call legion_accessor_array_1d_read_point_f(accessor_z, point, z_ptr, c_sizeof(z_value)) + if (x_value + y_value == z_value) then + else + print *, "wrong", i, x_value, y_value, z_value + all_passed = .false. + end if + end do + + if (all_passed .eqv. .true.) then + print *, "Pass" + else + print *, "Failed" + end if + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine check_task + + + subroutine top_level_task(tdata, tdatalen, userdata, userlen, p) + use legion_fortran + use iso_c_binding + implicit none + + type(c_ptr), intent(in) :: tdata + integer(c_size_t), value, intent(in) :: tdatalen + type(c_ptr), intent(in) ::userdata + integer(c_size_t), value, intent(in) :: userlen + integer(c_long_long), value, intent(in) :: p + + type(legion_task_f_t) :: task + integer(c_int) :: num_regions + type(legion_context_f_t) :: ctx + type(legion_runtime_f_t) :: runtime + type(c_ptr) :: regionptr + integer(c_size_t) :: retsize = 0 + + type(legion_point_1d_f_t) :: lo, hi, lo_c, hi_c + type(legion_domain_f_t) :: index_domain, color_domain + type(legion_rect_1d_f_t) :: index_rect, color_rect + type(legion_index_space_f_t) :: is, color_is + type(legion_index_partition_f_t) :: ip + type(legion_field_space_f_t) :: input_fs, output_fs, cp_fs + type(legion_logical_region_f_t) :: input_lr, output_lr, cp_lr + type(legion_field_allocator_f_t) :: ifs_allocator, ofs_allocator, cpfs_allocator + real(c_double) :: real_number = 0.0 + integer(c_int) :: fid_x, fid_y, fid_z, fid_cpz + integer(c_size_t) :: granularity = 1 + character (len=3), target :: ip_name = "ip"//c_null_char + character (len=9), target :: input_ip_name = "input_ip"//c_null_char + character (len=10), target :: output_ip_name = "output_ip"//c_null_char + type(legion_logical_partition_f_t) :: input_lp, output_lp + + type(legion_predicate_f_t) :: pred + type(legion_task_argument_f_t) :: task_args + integer(c_int) :: rr_ix, rr_iy, rr_cxy, rr_cz + type(legion_index_launcher_f_t) :: init_launcher_x, init_launcher_y, daxpy_launcher + type(legion_task_launcher_f_t) :: check_launcher + integer(c_long) :: tag = 0 + logical(c_bool) :: must = .FALSE. + type(legion_future_f_t) :: check_task_future + type(legion_future_map_f_t) :: init_task_future_map, daxpy_task_future_map + type(legion_argument_map_f_t) :: arg_map + + character (len=10) :: hdf5_file_name = "hdf5_file"//c_null_char + character (len=13) :: hdf5_dataset_name = "hdf5_dataset"//c_null_char + logical(c_bool) :: hdf5_file_is_valid + type(legion_field_map_f_t) :: hdf5_field_map + type(legion_physical_region_f_t) :: cp_pr + type(legion_copy_launcher_f_t) :: cp_launcher + integer(c_int) :: rridx_cp + logical(c_bool), external :: generate_hdf_file + + integer*4, target :: i + integer*4 :: num_elements = 1024 + integer*4 :: num_subregions = 8 + + Print *, "TOP Level Task!" + + call legion_task_preamble_f(tdata, tdatalen, p, & + task, & + regionptr, num_regions, & + ctx, runtime) + + ! create index space, field space and logical region + lo%x(0) = 0 + hi%x(0) = num_elements-1 + index_rect%lo = lo + index_rect%hi = hi + call legion_domain_from_rect_1d_f(index_rect, index_domain) + call legion_index_space_create_domain_f(runtime, ctx, index_domain, is) + call legion_field_space_create_f(runtime, ctx, input_fs) + call legion_field_allocator_create_f(runtime, ctx, input_fs, ifs_allocator) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 0, fid_x) + call legion_field_allocator_allocate_field_f(ifs_allocator, c_sizeof(real_number), 1, fid_y) + call legion_field_allocator_destroy_f(ifs_allocator) + + call legion_field_space_create_f(runtime, ctx, output_fs) + call legion_field_allocator_create_f(runtime, ctx, output_fs, ofs_allocator) + call legion_field_allocator_allocate_field_f(ofs_allocator, c_sizeof(real_number), 2, fid_z) + call legion_field_allocator_destroy_f(ofs_allocator) + + call legion_logical_region_create_f(runtime, ctx, is, input_fs, input_lr) + call legion_logical_region_create_f(runtime, ctx, is, output_fs, output_lr) + + ! create logical region for hdf5 file + call legion_field_space_create_f(runtime, ctx, cp_fs) + call legion_field_allocator_create_f(runtime, ctx, cp_fs, cpfs_allocator) + call legion_field_allocator_allocate_field_f(cpfs_allocator, c_sizeof(real_number), 3, fid_cpz) + call legion_field_allocator_destroy_f(cpfs_allocator) + call legion_logical_region_create_f(runtime, ctx, is, cp_fs, cp_lr) + + print *, fid_x, fid_y, fid_z, fid_cpz + + ! create partition + lo_c%x(0) = 0 + hi_c%x(0) = num_subregions-1 + color_rect%lo = lo_c + color_rect%hi = hi_c + call legion_domain_from_rect_1d_f(color_rect, color_domain) + call legion_index_space_create_domain_f(runtime, ctx, color_domain, color_is) + call legion_index_partition_create_equal_f(runtime, ctx, is, color_is, granularity, 0, ip) + call legion_index_partition_attach_name_f(runtime, ip, ip_name, .false.) + + call legion_logical_partition_create_f(runtime, ctx, input_lr, ip, input_lp) + call legion_logical_partition_attach_name_f(runtime, input_lp, input_ip_name, .false.) + call legion_logical_partition_create_f(runtime, ctx, output_lr, ip, output_lp) + call legion_logical_partition_attach_name_f(runtime, output_lp, output_ip_name, .false.) + + call legion_predicate_true_f(pred) + call legion_argument_map_create_f(arg_map) + + !init task for X + i = 0 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_index_launcher_create_f(INIT_TASK_ID, color_domain, task_args, arg_map, pred, must, 0, tag, init_launcher_x) + call legion_index_launcher_add_region_requirement_lp_f(init_launcher_x, input_lp, 0, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_ix) + call legion_index_launcher_add_field_f(init_launcher_x, rr_ix, 0, .true.) + call legion_index_launcher_execute_f(runtime, ctx, init_launcher_x, init_task_future_map) + + !init task for Y + i = 1 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_index_launcher_create_f(INIT_TASK_ID, color_domain, task_args, arg_map, pred, must, 0, tag, init_launcher_y) + call legion_index_launcher_add_region_requirement_lp_f(init_launcher_y, input_lp, 0, & + WRITE_DISCARD, EXCLUSIVE, & + input_lr, tag, .false., rr_iy) + call legion_index_launcher_add_field_f(init_launcher_y, rr_iy, 1, .true.) + call legion_index_launcher_execute_f(runtime, ctx, init_launcher_y, init_task_future_map) + + print *, rr_ix, rr_iy + + !daxpy task + i = 2 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_index_launcher_create_f(DAXPY_TASK_ID, color_domain, task_args, arg_map, pred, must, 0, tag, daxpy_launcher) + call legion_index_launcher_add_region_requirement_lp_f(daxpy_launcher, input_lp, 0, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_index_launcher_add_field_f(daxpy_launcher, rr_cxy, 0, .true.) + call legion_index_launcher_add_field_f(daxpy_launcher, rr_cxy, 1, .true.) + call legion_index_launcher_add_region_requirement_lp_f(daxpy_launcher, output_lp, 0, & + WRITE_DISCARD, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_index_launcher_add_field_f(daxpy_launcher, rr_cz, 2, .true.) + call legion_index_launcher_execute_f(runtime, ctx, daxpy_launcher, daxpy_task_future_map) + + !create HDF5 file + hdf5_file_is_valid = generate_hdf_file(hdf5_file_name, hdf5_dataset_name, num_elements) + call legion_field_map_create_f(hdf5_field_map) + call legion_field_map_insert_f(hdf5_field_map, 3, hdf5_dataset_name) + call legion_runtime_attach_hdf5_f(runtime, ctx, hdf5_file_name, & + cp_lr, cp_lr, hdf5_field_map, LEGION_FILE_READ_WRITE, cp_pr) + + ! create copy task + call legion_copy_launcher_create_f(pred, 0, tag, cp_launcher) + call legion_copy_launcher_add_src_region_requirement_lr_f(cp_launcher, output_lr, READ_ONLY, EXCLUSIVE, & + output_lr, tag, .false., rridx_cp) + call legion_copy_launcher_add_dst_region_requirement_lr_f(cp_launcher, cp_lr, WRITE_DISCARD, EXCLUSIVE, & + cp_lr, tag, .false., rridx_cp) + call legion_copy_launcher_add_src_field_f(cp_launcher, 0, 2, .true.) + call legion_copy_launcher_add_dst_field_f(cp_launcher, 0, 3, .true.) + call legion_copy_launcher_execute_f(runtime, ctx, cp_launcher) + call legion_runtime_detach_hdf5_f(runtime, ctx, cp_pr) + + !check task + i = 3 + task_args%args = c_loc(i) + task_args%arglen = c_sizeof(i) + call legion_task_launcher_create_f(CHECK_TASK_ID, task_args, pred, 0, tag, check_launcher) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, input_lr, & + READ_ONLY, EXCLUSIVE, & + input_lr, tag, .false., rr_cxy) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 0, .true.) + call legion_task_launcher_add_field_f(check_launcher, rr_cxy, 1, .true.) + call legion_task_launcher_add_region_requirement_logical_region_f(check_launcher, output_lr, & + READ_ONLY, EXCLUSIVE, & + output_lr, tag, .false., rr_cz) + call legion_task_launcher_add_field_f(check_launcher, rr_cz, 2, .true.) + call legion_task_launcher_execute_f(runtime, ctx, check_launcher, check_task_future) + + ! clean up + call legion_logical_region_destroy_f(runtime, ctx, input_lr) + call legion_logical_region_destroy_f(runtime, ctx, output_lr) + call legion_field_space_destroy_f(runtime, ctx, input_fs) + call legion_field_space_destroy_f(runtime, ctx, output_fs) + call legion_index_space_destroy_f(runtime, ctx, is) + call legion_index_launcher_destroy_f(init_launcher_x) + call legion_index_launcher_destroy_f(init_launcher_y) + call legion_index_launcher_destroy_f(daxpy_launcher) + call legion_copy_launcher_destroy_f(cp_launcher) + call legion_task_launcher_destroy_f(check_launcher) + + call legion_task_postamble_f(runtime, ctx, c_null_ptr, retsize) + end subroutine top_level_task +end module daxpy_partition_attach + +Program attach + use legion_fortran + use iso_c_binding + implicit none + type(legion_execution_constraint_set_f_t) :: execution_constraints + type(legion_task_layout_constraint_set_f_t) :: layout_constraints + type(legion_task_config_options_f_t) :: config_options + integer(c_int) :: task_id_1, task_id_2, task_id_3, task_id_4 + integer(c_size_t) :: userlen = 0 + integer(c_int) :: runtime_start_rv + type(c_funptr) :: c_func_ptr + + Print *, "Hello from Main!" + call legion_runtime_set_top_level_task_id_f(TOP_LEVEL_TASK_ID) + call legion_execution_constraint_set_create_f(execution_constraints) + call legion_execution_constraint_set_add_processor_constraint_f(execution_constraints, LOC_PROC) + call legion_task_layout_constraint_set_create_f(layout_constraints) + config_options%leaf = .false. + config_options%inner = .false. + config_options%idempotent = .false. + + c_func_ptr = c_funloc(top_level_task) + + call legion_runtime_preregister_task_variant_fnptr_f(TOP_LEVEL_TASK_ID, c_char_"top_level_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_1) + + config_options%leaf = .true. + c_func_ptr = c_funloc(init_task) + + call legion_runtime_preregister_task_variant_fnptr_f(INIT_TASK_ID, c_char_"init_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_2) + + c_func_ptr = c_funloc(daxpy_task) + + call legion_runtime_preregister_task_variant_fnptr_f(DAXPY_TASK_ID, c_char_"daxpy_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_3) + + c_func_ptr = c_funloc(check_task) + + call legion_runtime_preregister_task_variant_fnptr_f(CHECK_TASK_ID, c_char_"check_task"//c_null_char, & + c_char_"cpu_variant"//c_null_char, & + execution_constraints, & + layout_constraints, & + config_options, & + c_func_ptr, & + c_null_ptr, & + userlen, task_id_4) + call legion_runtime_start_f(0, c_null_ptr, .false., runtime_start_rv) +End Program attach diff --git a/tutorial/07_partitioning/Makefile b/tutorial/07_partitioning/Makefile index cfd26ee9b2..078dcac9b5 100644 --- a/tutorial/07_partitioning/Makefile +++ b/tutorial/07_partitioning/Makefile @@ -23,7 +23,7 @@ DEBUG := 1 # Include debugging symbols OUTPUT_LEVEL ?= LEVEL_DEBUG # Compile time logging level USE_CUDA ?= 0 # Include CUDA support (requires CUDA) USE_GASNET ?= 0 # Include GASNet support (requires GASNet) -USE_HDF ?= 0 # Include HDF5 support (requires HDF5) +USE_HDF ?= 1 # Include HDF5 support (requires HDF5) ALT_MAPPERS ?= 0 # Include alternative mappers (not recommended) # Put the binary file name here diff --git a/tutorial/07_partitioning/partitioning.cc b/tutorial/07_partitioning/partitioning.cc index cf2a739e67..72bd624eb7 100644 --- a/tutorial/07_partitioning/partitioning.cc +++ b/tutorial/07_partitioning/partitioning.cc @@ -335,4 +335,4 @@ int main(int argc, char **argv) } return Runtime::start(argc, argv); -} +} \ No newline at end of file