Last active
August 29, 2015 14:22
-
-
Save dotnwat/8c514ec5fa3d23de4523 to your computer and use it in GitHub Desktop.
Summation in Legion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Single task, one mapping. | |
*/ | |
#include "legion.h" | |
using namespace LegionRuntime::HighLevel; | |
using namespace LegionRuntime::Accessor; | |
enum TaskIDs { | |
TOP_LEVEL_TASK_ID, | |
}; | |
enum FieldIDs { | |
FID_VALUE, | |
}; | |
void top_level_task(const Task *task, | |
const std::vector<PhysicalRegion> ®ions, | |
Context ctx, HighLevelRuntime *runtime) | |
{ | |
/* size of sequence 1..num_elements */ | |
int num_elements = 1024; | |
/* | |
* Setup the logical region | |
*/ | |
Rect<1> elem_rect(Point<1>(0),Point<1>(num_elements-1)); | |
IndexSpace is = runtime->create_index_space(ctx, | |
Domain::from_rect<1>(elem_rect)); | |
FieldSpace fs = runtime->create_field_space(ctx); | |
{ | |
FieldAllocator allocator = runtime->create_field_allocator(ctx, fs); | |
allocator.allocate_field(sizeof(uint64_t), FID_VALUE); | |
} | |
LogicalRegion lr = runtime->create_logical_region(ctx, is, fs); | |
/* | |
* Map the region | |
*/ | |
RegionRequirement req(lr, READ_WRITE, EXCLUSIVE, lr); | |
req.add_field(FID_VALUE); | |
InlineLauncher fill_launcher(req); | |
PhysicalRegion region = runtime->map_region(ctx, fill_launcher); | |
region.wait_until_valid(); | |
/* | |
* Write values into region | |
*/ | |
RegionAccessor<AccessorType::Generic, uint64_t> acc = | |
region.get_field_accessor(FID_VALUE).typeify<uint64_t>(); | |
uint64_t value = 0; | |
for (GenericPointInRectIterator<1> pir(elem_rect); pir; pir++) | |
{ | |
value++; | |
acc.write(DomainPoint::from_point<1>(pir.p), value); | |
} | |
/* | |
* Perform summation | |
*/ | |
RegionAccessor<AccessorType::Generic, uint64_t> acc_read = | |
region.get_field_accessor(FID_VALUE).typeify<uint64_t>(); | |
uint64_t sum = 0; | |
for (GenericPointInRectIterator<1> pir(elem_rect); pir; pir++) | |
{ | |
sum += acc_read.read(DomainPoint::from_point<1>(pir.p)); | |
} | |
/* Verify */ | |
assert(sum == ((value * (value + 1)) / 2)); | |
} | |
int main(int argc, char **argv) | |
{ | |
HighLevelRuntime::set_top_level_task_id(TOP_LEVEL_TASK_ID); | |
HighLevelRuntime::register_legion_task<top_level_task>(TOP_LEVEL_TASK_ID, | |
Processor::LOC_PROC, true/*single*/, false/*index*/); | |
return HighLevelRuntime::start(argc, argv); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* - Index space launch to fill region | |
* - Index space launch to compute per-region summation | |
* - Reduction over FutureMap for final global summation | |
*/ | |
#include "legion.h" | |
using namespace LegionRuntime::HighLevel; | |
using namespace LegionRuntime::Accessor; | |
enum TaskIDs { | |
TOP_LEVEL_TASK_ID, | |
FILL_TASK_ID, | |
SUM_TASK_ID, | |
}; | |
enum FieldIDs { | |
FID_VALUE, | |
}; | |
enum RedopIDs { | |
ADD_REDOP_ID = 1, | |
}; | |
struct AddRedop { | |
typedef uint64_t LHS; | |
typedef uint64_t RHS; | |
static const uint64_t identity; | |
template <bool EXCLUSIVE> | |
static void apply(LHS& lhs, RHS rhs); | |
template <bool EXCLUSIVE> | |
static void fold(RHS& rhs1, RHS rhs2); | |
}; | |
const uint64_t AddRedop::identity = 0; | |
template<> | |
void AddRedop::apply<true>(LHS& lhs, RHS rhs) | |
{ | |
lhs += rhs; | |
} | |
template<> | |
void AddRedop::apply<false>(LHS& lhs, RHS rhs) | |
{ | |
int64_t *target = (int64_t *)&lhs; | |
union { int64_t as_int; uint64_t as_T; } oldval, newval; | |
do { | |
oldval.as_int = *target; | |
newval.as_T = oldval.as_T + rhs; | |
} while (!__sync_bool_compare_and_swap(target, oldval.as_int, newval.as_int)); | |
} | |
template<> | |
void AddRedop::fold<true>(RHS& rhs1, RHS rhs2) | |
{ | |
rhs1 += rhs2; | |
} | |
template<> | |
void AddRedop::fold<false>(RHS &rhs1, RHS rhs2) | |
{ | |
int64_t *target = (int64_t *)&rhs1; | |
union { int64_t as_int; uint64_t as_T; } oldval, newval; | |
do { | |
oldval.as_int = *target; | |
newval.as_T = oldval.as_T + rhs2; | |
} while (!__sync_bool_compare_and_swap(target, oldval.as_int, newval.as_int)); | |
} | |
void top_level_task(const Task *task, | |
const std::vector<PhysicalRegion> ®ions, | |
Context ctx, HighLevelRuntime *runtime) | |
{ | |
/* size of sequence 1..num_elements */ | |
int num_elements = 1024; | |
/* break problem up into num_subregions */ | |
int num_subregions = 4; | |
/* assumption makes stuff simpler */ | |
assert(num_elements % num_subregions == 0); | |
/* | |
* Setup the logical region | |
*/ | |
Rect<1> elem_rect(Point<1>(0),Point<1>(num_elements-1)); | |
IndexSpace is = runtime->create_index_space(ctx, | |
Domain::from_rect<1>(elem_rect)); | |
FieldSpace fs = runtime->create_field_space(ctx); | |
{ | |
FieldAllocator allocator = runtime->create_field_allocator(ctx, fs); | |
allocator.allocate_field(sizeof(uint64_t), FID_VALUE); | |
} | |
LogicalRegion lr = runtime->create_logical_region(ctx, is, fs); | |
/* | |
* Setup a partitioning | |
*/ | |
Rect<1> color_bounds(Point<1>(0),Point<1>(num_subregions-1)); | |
Domain color_domain = Domain::from_rect<1>(color_bounds); | |
Blockify<1> coloring(num_elements/num_subregions); | |
IndexPartition ip = runtime->create_index_partition(ctx, is, coloring); | |
LogicalPartition lp = runtime->get_logical_partition(ctx, lr, ip); | |
Domain launch_domain = color_domain; | |
ArgumentMap arg_map; | |
/* | |
* Fill up the logical region | |
*/ | |
IndexLauncher fill_launcher(FILL_TASK_ID, launch_domain, | |
TaskArgument(NULL, 0), arg_map); | |
fill_launcher.add_region_requirement( | |
RegionRequirement(lp, 0, WRITE_DISCARD, EXCLUSIVE, lr)); | |
fill_launcher.region_requirements[0].add_field(FID_VALUE); | |
runtime->execute_index_space(ctx, fill_launcher); | |
/* | |
* Sum up all the values | |
*/ | |
IndexLauncher sum_launcher(SUM_TASK_ID, launch_domain, | |
TaskArgument(NULL, 0), arg_map); | |
sum_launcher.add_region_requirement( | |
RegionRequirement(lp, 0, READ_ONLY, EXCLUSIVE, lr)); | |
sum_launcher.region_requirements[0].add_field(FID_VALUE); | |
Future sumf = runtime->execute_index_space(ctx, sum_launcher, ADD_REDOP_ID); | |
/* Verify */ | |
uint64_t sum = sumf.get_result<uint64_t>(); | |
assert(sum == ((num_elements * (num_elements - 1)) / 2)); | |
} | |
void fill_task(const Task *task, | |
const std::vector<PhysicalRegion> ®ions, | |
Context ctx, HighLevelRuntime *runtime) | |
{ | |
RegionAccessor<AccessorType::Generic, uint64_t> acc = | |
regions[0].get_field_accessor(FID_VALUE).typeify<uint64_t>(); | |
Domain dom = runtime->get_index_space_domain(ctx, | |
task->regions[0].region.get_index_space()); | |
Rect<1> rect = dom.get_rect<1>(); | |
/* | |
* Write the position as the "value" | |
*/ | |
for (GenericPointInRectIterator<1> pir(rect); pir; pir++) | |
{ | |
acc.write(DomainPoint::from_point<1>(pir.p), pir.p[0]); | |
} | |
} | |
uint64_t sum_task(const Task *task, | |
const std::vector<PhysicalRegion> ®ions, | |
Context ctx, HighLevelRuntime *runtime) | |
{ | |
RegionAccessor<AccessorType::Generic, uint64_t> acc = | |
regions[0].get_field_accessor(FID_VALUE).typeify<uint64_t>(); | |
Domain dom = runtime->get_index_space_domain(ctx, | |
task->regions[0].region.get_index_space()); | |
Rect<1> rect = dom.get_rect<1>(); | |
/* | |
* Add up all the value in this partition | |
*/ | |
uint64_t value = 0; | |
for (GenericPointInRectIterator<1> pir(rect); pir; pir++) | |
{ | |
value += acc.read(DomainPoint::from_point<1>(pir.p)); | |
} | |
return value; | |
} | |
int main(int argc, char **argv) | |
{ | |
HighLevelRuntime::set_top_level_task_id(TOP_LEVEL_TASK_ID); | |
HighLevelRuntime::register_legion_task<top_level_task>(TOP_LEVEL_TASK_ID, | |
Processor::LOC_PROC, true/*single*/, false/*index*/); | |
HighLevelRuntime::register_legion_task<fill_task>(FILL_TASK_ID, | |
Processor::LOC_PROC, true/*single*/, true/*index*/, | |
AUTO_GENERATE_ID, TaskConfigOptions(true), "fill"); | |
HighLevelRuntime::register_legion_task<uint64_t, sum_task>(SUM_TASK_ID, | |
Processor::LOC_PROC, true/*single*/, true/*index*/, | |
AUTO_GENERATE_ID, TaskConfigOptions(true), "sum"); | |
HighLevelRuntime::register_reduction_op<AddRedop>(ADD_REDOP_ID); | |
return HighLevelRuntime::start(argc, argv); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment