Skip to content

Commit

Permalink
Fix memory query and add some more calls.
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottslaughter committed Apr 1, 2024
1 parent b54b1a2 commit 84c5ab1
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 120 deletions.
2 changes: 2 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Language: Cpp
BasedOnStyle: Google
ColumnLimit: 90
AccessModifierOffset: -2
DerivePointerAlignment: false
PointerAlignment: Right
218 changes: 119 additions & 99 deletions src/mapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ using namespace Legion::Mapping;
enum MapperCallIDs {
SELECT_TASKS_TO_MAP,
MAP_TASK,
MAP_INLINE,
};

static Logger log_map("fuzz_mapper");

FuzzMapper::FuzzMapper(MapperRuntime* rt, Machine machine, Processor local, RngStream st)
FuzzMapper::FuzzMapper(MapperRuntime *rt, Machine machine, Processor local, RngStream st)
: NullMapper(rt, machine),
stream(st),
select_tasks_to_map_channel(st.make_channel(int32_t(SELECT_TASKS_TO_MAP))),
map_inline_channel(st.make_channel(int32_t(MAP_INLINE))),
local_proc(local) {
// TODO: something other than CPU processor
{
Expand All @@ -45,14 +47,14 @@ FuzzMapper::FuzzMapper(MapperRuntime* rt, Machine machine, Processor local, RngS
}
}

const char* FuzzMapper::get_mapper_name(void) const { return "fuzz_mapper"; }
const char *FuzzMapper::get_mapper_name(void) const { return "fuzz_mapper"; }

Mapper::MapperSyncModel FuzzMapper::get_mapper_sync_model(void) const {
return SERIALIZED_REENTRANT_MAPPER_MODEL;
}

void FuzzMapper::select_task_options(const MapperContext ctx, const Task& task,
Mapper::TaskOptions& output) {
void FuzzMapper::select_task_options(const MapperContext ctx, const Task &task,
Mapper::TaskOptions &output) {
// output.initial_proc = local_proc; // Leave the task where it is.
output.inline_task = false;
output.stealable = false;
Expand All @@ -64,9 +66,9 @@ void FuzzMapper::select_task_options(const MapperContext ctx, const Task& task,
// output.check_collective_regions.insert(...); // TODO
}

void FuzzMapper::replicate_task(MapperContext ctx, const Task& task,
const ReplicateTaskInput& input,
ReplicateTaskOutput& output) {
void FuzzMapper::replicate_task(MapperContext ctx, const Task &task,
const ReplicateTaskInput &input,
ReplicateTaskOutput &output) {
// TODO: cache this?
std::vector<VariantID> variants;
runtime->find_valid_variants(ctx, task.task_id, variants);
Expand All @@ -79,8 +81,8 @@ void FuzzMapper::replicate_task(MapperContext ctx, const Task& task,
// TODO: actually replicate
}

void FuzzMapper::map_task(const MapperContext ctx, const Task& task,
const MapTaskInput& input, MapTaskOutput& output) {
void FuzzMapper::map_task(const MapperContext ctx, const Task &task,
const MapTaskInput &input, MapTaskOutput &output) {
RngChannel rng = make_task_channel(MAP_TASK, task);

log_map.debug() << "map_task: Start";
Expand Down Expand Up @@ -112,103 +114,44 @@ void FuzzMapper::map_task(const MapperContext ctx, const Task& task,
}
} else {
for (size_t idx = 0; idx < task.regions.size(); ++idx) {
const RegionRequirement& req = task.regions.at(idx);
if (req.privilege == LEGION_NO_ACCESS || req.privilege_fields.empty()) {
continue;
}

// Pick the memory this is going into
Machine::MemoryQuery query(machine);
query.only_kind(Memory::SYSTEM_MEM); // FIXME: without this it selects file memory?
query.best_affinity_to(local_proc);
uint64_t target = rng.uniform_range(0, query.count() - 1);
auto it = query.begin();
std::advance(it, target);
Memory memory = *it;
log_map.debug() << "map_task: Selected memory " << memory << " kind "
<< memory.kind() << " for requirement " << idx;

LayoutConstraintSet constraints;
if (req.privilege == LEGION_REDUCE) {
constraints.add_constraint(
SpecializedConstraint(LEGION_AFFINE_REDUCTION_SPECIALIZE, req.redop));
} else {
constraints.add_constraint(SpecializedConstraint());
}

constraints.add_constraint(MemoryConstraint(memory.kind()));

{
std::vector<FieldID> fields;
if (rng.uniform_range(0, 1) == 0) {
FieldSpace handle = req.region.get_field_space();
runtime->get_field_space_fields(ctx, handle, fields);
} else {
fields.insert(fields.end(), req.instance_fields.begin(),
req.instance_fields.end());
}
bool contiguous = rng.uniform_range(0, 1) == 0;
bool inorder = rng.uniform_range(0, 1) == 0;

constraints.add_constraint(FieldConstraint(fields, contiguous, inorder));
}

{
IndexSpace is = req.region.get_index_space();
Domain domain = runtime->get_index_space_domain(ctx, is);
int dim = domain.get_dim();
std::vector<DimensionKind> dimension_ordering(dim + 1);
for (int i = 0; i < dim; ++i)
dimension_ordering.at(i) =
static_cast<DimensionKind>(static_cast<int>(LEGION_DIM_X) + i);
dimension_ordering[dim] = LEGION_DIM_F;
// TODO: shuffle this ordering
bool contiguous = rng.uniform_range(0, 1) == 0;
constraints.add_constraint(OrderingConstraint(dimension_ordering, contiguous));
}

std::vector<LogicalRegion> regions = {req.region};

// Either force the runtime to create a fresh instance, or allow one to be reused
PhysicalInstance instance;
if (rng.uniform_range(0, 1) == 0) {
if (!runtime->create_physical_instance(ctx, memory, constraints, regions,
instance, true /* acquire */,
LEGION_GC_MAX_PRIORITY)) {
log_map.fatal() << "map_task: Failed to create instance";
abort();
}
} else {
bool created;
if (!runtime->find_or_create_physical_instance(
ctx, memory, constraints, regions, instance, created, true /* acquire */,
LEGION_GC_NEVER_PRIORITY)) {
log_map.fatal() << "map_task: Failed to create instance";
abort();
}
}
output.chosen_instances.at(idx).push_back(instance);
const RegionRequirement &req = task.regions.at(idx);
random_mapping(ctx, rng, req, output.chosen_instances.at(idx));
}
}
}

void FuzzMapper::map_inline(const MapperContext ctx, const InlineMapping &inline_op,
const MapInlineInput &input, MapInlineOutput &output) {
RngChannel &rng = map_inline_channel;
const RegionRequirement &req = inline_op.requirement;
random_mapping(ctx, rng, req, output.chosen_instances);
}

void FuzzMapper::select_partition_projection(const MapperContext ctx,
const Partition& partition,
const SelectPartitionProjectionInput& input,
SelectPartitionProjectionOutput& output) {
const Partition &partition,
const SelectPartitionProjectionInput &input,
SelectPartitionProjectionOutput &output) {
if (!input.open_complete_partitions.empty())
output.chosen_partition = input.open_complete_partitions.at(0);
else
output.chosen_partition = LogicalPartition::NO_PART;
}

void FuzzMapper::configure_context(const MapperContext ctx, const Task& task,
ContextConfigOutput& output) {}
void FuzzMapper::map_partition(const MapperContext ctx, const Partition &partition,
const MapPartitionInput &input,
MapPartitionOutput &output) {
output.chosen_instances = input.valid_instances;
if (!output.chosen_instances.empty())
runtime->acquire_and_filter_instances(ctx, output.chosen_instances);
}

void FuzzMapper::configure_context(const MapperContext ctx, const Task &task,
ContextConfigOutput &output) {}

void FuzzMapper::select_tasks_to_map(const MapperContext ctx,
const SelectMappingInput& input,
SelectMappingOutput& output) {
RngChannel& rng = select_tasks_to_map_channel;
const SelectMappingInput &input,
SelectMappingOutput &output) {
RngChannel &rng = select_tasks_to_map_channel;

log_map.debug() << "select_tasks_to_map: Start";
if (input.ready_tasks.empty()) {
Expand All @@ -217,7 +160,7 @@ void FuzzMapper::select_tasks_to_map(const MapperContext ctx,
}

// Just to really mess with things, we'll pick a random task on every invokation.
uint64_t target = rng.uniform_range(0, input.ready_tasks.size());
uint64_t target = rng.uniform_range(0, input.ready_tasks.size() - 1);
log_map.debug() << "select_tasks_to_map: Selected task " << target << " of "
<< input.ready_tasks.size();
auto it = input.ready_tasks.begin();
Expand Down Expand Up @@ -245,22 +188,99 @@ void FuzzMapper::select_tasks_to_map(const MapperContext ctx,
}

void FuzzMapper::select_steal_targets(const MapperContext ctx,
const SelectStealingInput& input,
SelectStealingOutput& output) {}
const SelectStealingInput &input,
SelectStealingOutput &output) {}

RngChannel FuzzMapper::make_task_channel(int mapper_call,
const Legion::Task& task) const {
const Legion::Task &task) const {
// TODO: index launches, mapper call ID
static_assert(sizeof(MappingTagID) <= sizeof(uint64_t));
return stream.make_channel(std::pair(mapper_call, uint64_t(task.tag)));
}

Processor FuzzMapper::random_local_proc(RngChannel& rng) {
Processor FuzzMapper::random_local_proc(RngChannel &rng) {
return local_procs.at(rng.uniform_range(0, local_procs.size() - 1));
}

Processor FuzzMapper::random_global_proc(RngChannel& rng) {
Processor FuzzMapper::random_global_proc(RngChannel &rng) {
return global_procs.at(rng.uniform_range(0, global_procs.size() - 1));
}

void FuzzMapper::random_mapping(const MapperContext ctx, RngChannel &rng,
const RegionRequirement &req,
std::vector<PhysicalInstance> &output) {
if (req.privilege == LEGION_NO_ACCESS || req.privilege_fields.empty()) {
return;
}

// Pick the memory this is going into
Machine::MemoryQuery query(machine);
query.has_affinity_to(local_proc);
query.has_capacity(1);
uint64_t target = rng.uniform_range(0, query.count() - 1);
auto it = query.begin();
std::advance(it, target);
Memory memory = *it;
log_map.debug() << "map_task: Selected memory " << memory << " kind " << memory.kind();

LayoutConstraintSet constraints;
if (req.privilege == LEGION_REDUCE) {
constraints.add_constraint(
SpecializedConstraint(LEGION_AFFINE_REDUCTION_SPECIALIZE, req.redop));
} else {
constraints.add_constraint(SpecializedConstraint());
}

constraints.add_constraint(MemoryConstraint(memory.kind()));

{
std::vector<FieldID> fields;
if (rng.uniform_range(0, 1) == 0) {
FieldSpace handle = req.region.get_field_space();
runtime->get_field_space_fields(ctx, handle, fields);
} else {
fields.insert(fields.end(), req.instance_fields.begin(), req.instance_fields.end());
}
bool contiguous = rng.uniform_range(0, 1) == 0;
bool inorder = rng.uniform_range(0, 1) == 0;

constraints.add_constraint(FieldConstraint(fields, contiguous, inorder));
}

{
IndexSpace is = req.region.get_index_space();
Domain domain = runtime->get_index_space_domain(ctx, is);
int dim = domain.get_dim();
std::vector<DimensionKind> dimension_ordering(dim + 1);
for (int i = 0; i < dim; ++i)
dimension_ordering.at(i) =
static_cast<DimensionKind>(static_cast<int>(LEGION_DIM_X) + i);
dimension_ordering[dim] = LEGION_DIM_F;
// TODO: shuffle this ordering
bool contiguous = rng.uniform_range(0, 1) == 0;
constraints.add_constraint(OrderingConstraint(dimension_ordering, contiguous));
}

std::vector<LogicalRegion> regions = {req.region};

// Either force the runtime to create a fresh instance, or allow one to be reused
PhysicalInstance instance;
if (rng.uniform_range(0, 1) == 0) {
if (!runtime->create_physical_instance(ctx, memory, constraints, regions, instance,
true /* acquire */, LEGION_GC_MAX_PRIORITY)) {
log_map.fatal() << "map_task: Failed to create instance";
abort();
}
} else {
bool created;
if (!runtime->find_or_create_physical_instance(ctx, memory, constraints, regions,
instance, created, true /* acquire */,
LEGION_GC_NEVER_PRIORITY)) {
log_map.fatal() << "map_task: Failed to create instance";
abort();
}
}
output.push_back(instance);
}

} // namespace FuzzMapper
53 changes: 32 additions & 21 deletions src/mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,45 +28,56 @@ using namespace Legion::Mapping;

class FuzzMapper : public NullMapper {
public:
FuzzMapper(MapperRuntime* runtime, Machine machine, Processor local, RngStream stream);
FuzzMapper(MapperRuntime *runtime, Machine machine, Processor local, RngStream stream);

public:
const char* get_mapper_name(void) const override;
const char *get_mapper_name(void) const override;
MapperSyncModel get_mapper_sync_model(void) const override;

public: // Task mapping calls
void select_task_options(const MapperContext ctx, const Task& task,
TaskOptions& output) override;
void replicate_task(MapperContext ctx, const Task& task,
const ReplicateTaskInput& input,
ReplicateTaskOutput& output) override;
void map_task(const MapperContext ctx, const Task& task, const MapTaskInput& input,
MapTaskOutput& output) override;
void select_task_options(const MapperContext ctx, const Task &task,
TaskOptions &output) override;
void replicate_task(MapperContext ctx, const Task &task,
const ReplicateTaskInput &input,
ReplicateTaskOutput &output) override;
void map_task(const MapperContext ctx, const Task &task, const MapTaskInput &input,
MapTaskOutput &output) override;

public: // Inline mapping calls
void map_inline(const MapperContext ctx, const InlineMapping &inline_op,
const MapInlineInput &input, MapInlineOutput &output) override;

public: // Partition mapping calls
void select_partition_projection(const MapperContext ctx, const Partition& partition,
const SelectPartitionProjectionInput& input,
SelectPartitionProjectionOutput& output) override;
void select_partition_projection(const MapperContext ctx, const Partition &partition,
const SelectPartitionProjectionInput &input,
SelectPartitionProjectionOutput &output) override;
void map_partition(const MapperContext ctx, const Partition &partition,
const MapPartitionInput &input, MapPartitionOutput &output) override;

public: // Task execution mapping calls
void configure_context(const MapperContext ctx, const Task& task,
ContextConfigOutput& output) override;
void configure_context(const MapperContext ctx, const Task &task,
ContextConfigOutput &output) override;

public: // Mapping control and stealing
void select_tasks_to_map(const MapperContext ctx, const SelectMappingInput& input,
SelectMappingOutput& output) override;
void select_steal_targets(const MapperContext ctx, const SelectStealingInput& input,
SelectStealingOutput& output) override;
void select_tasks_to_map(const MapperContext ctx, const SelectMappingInput &input,
SelectMappingOutput &output) override;
void select_steal_targets(const MapperContext ctx, const SelectStealingInput &input,
SelectStealingOutput &output) override;

private:
RngChannel make_task_channel(int mapper_call, const Task& task) const;
RngChannel make_task_channel(int mapper_call, const Task &task) const;

Processor random_local_proc(RngChannel &rng);
Processor random_global_proc(RngChannel &rng);

Processor random_local_proc(RngChannel& rng);
Processor random_global_proc(RngChannel& rng);
void random_mapping(const MapperContext ctx, RngChannel &rng,
const RegionRequirement &req,
std::vector<PhysicalInstance> &output);

private:
RngStream stream;
RngChannel select_tasks_to_map_channel;
RngChannel map_inline_channel;

Processor local_proc;
std::vector<Processor> local_procs;
Expand Down

0 comments on commit 84c5ab1

Please sign in to comment.