Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/deterministic_random.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

#include "siphash.h"

RngSeed::RngSeed() : seed(UINT64_MAX), stream(0) {}

RngSeed::RngSeed(uint64_t _seed) : seed(_seed), stream(0) {}

RngStream RngSeed::make_stream() {
Expand Down
8 changes: 4 additions & 4 deletions src/deterministic_random.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class RngChannel;

class RngSeed {
public:
RngSeed();
RngSeed(uint64_t seed);
RngSeed() = delete;
explicit RngSeed(uint64_t seed);

RngSeed(const RngSeed &rng) = delete;
RngSeed(RngSeed &&rng);
Expand All @@ -58,7 +58,7 @@ class RngSeed {

class RngStream {
private:
RngStream(uint64_t seed, uint64_t stream);
explicit RngStream(uint64_t seed, uint64_t stream);

public:
uint64_t uniform_uint64_t();
Expand All @@ -81,7 +81,7 @@ static_assert(std::is_trivially_copyable_v<RngStream>);
class RngChannel {
private:
template <typename T>
RngChannel(uint64_t seed, uint64_t stream, const T &hashable);
explicit RngChannel(uint64_t seed, uint64_t stream, const T &hashable);

public:
uint64_t uniform_uint64_t();
Expand Down
120 changes: 71 additions & 49 deletions src/fuzzer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ enum ProjectionIDs {

static Logger log_fuzz("fuzz");

static RngSeed root_seed;
static uint64_t replicate_levels = 0;
static bool mapper_logging = false;

static long long parse_long_long(const std::string &flag, const std::string &arg) {
long long result;
size_t consumed;
Expand Down Expand Up @@ -119,7 +115,7 @@ struct FuzzerConfig {
return config;
}

void log_config(Runtime *runtime, Context ctx) {
void log_config(Runtime *runtime, Context ctx) const {
LOG_ONCE(log_fuzz.print() << "Fuzzer Configuration:");
LOG_ONCE(log_fuzz.print() << " config.initial_seed = " << initial_seed);
LOG_ONCE(log_fuzz.print() << " config.region_tree_depth = " << region_tree_depth);
Expand All @@ -139,7 +135,7 @@ struct FuzzerConfig {

class OffsetProjection : public ProjectionFunctor {
public:
OffsetProjection(uint64_t _offset) : offset(_offset) {}
explicit OffsetProjection(uint64_t _offset) : offset(_offset) {}
bool is_functional(void) const override { return true; }
bool is_invertible(void) const override { return false; }
unsigned get_depth(void) const override { return 0; }
Expand All @@ -160,7 +156,7 @@ class OffsetProjection : public ProjectionFunctor {

class RandomProjection : public ProjectionFunctor {
public:
RandomProjection(RngStream _stream) : stream(_stream) {}
explicit RandomProjection(RngStream _stream) : stream(_stream) {}
bool is_functional(void) const override { return true; }
bool is_invertible(void) const override { return false; }
unsigned get_depth(void) const override { return 0; }
Expand Down Expand Up @@ -214,7 +210,8 @@ void color_points_task(const Task *task, const std::vector<PhysicalRegion> &regi

class RegionForest {
public:
RegionForest(Runtime *_runtime, Context _ctx, const FuzzerConfig &config, RngSeed &seed)
explicit RegionForest(Runtime *_runtime, Context _ctx, const FuzzerConfig &config,
RngSeed &seed)
: runtime(_runtime), ctx(_ctx) {
ispace = runtime->create_index_space<1>(
ctx,
Expand Down Expand Up @@ -360,7 +357,7 @@ class RegionForest {
return true;
}

void verify_contents() {
bool verify_contents() {
std::vector<FieldID> fields;
shadow_inst.get_fields(fields);

Expand Down Expand Up @@ -404,11 +401,12 @@ class RegionForest {
}
}
if (bad_points > 0) {
log_fuzz.fatal() << "Encountered " << bad_points << " bad region values";
abort();
log_fuzz.error() << "Encountered " << bad_points << " bad region values";
}

runtime->unmap_region(ctx, inst);

return bad_points == 0;
}

private:
Expand Down Expand Up @@ -528,7 +526,7 @@ const char *redop_name(ReductionOpID redop) {

class RequirementBuilder {
public:
RequirementBuilder(const FuzzerConfig &_config, RegionForest &_forest)
explicit RequirementBuilder(const FuzzerConfig &_config, RegionForest &_forest)
: config(_config), forest(_forest) {}

void build(RngStream &rng, bool launch_complete, bool requires_projection) {
Expand Down Expand Up @@ -739,7 +737,7 @@ using FutureCheck = std::pair<Future, uint64_t>;

class OperationBuilder {
public:
OperationBuilder(const FuzzerConfig &_config, RegionForest &_forest)
explicit OperationBuilder(const FuzzerConfig &_config, RegionForest &_forest)
: config(_config),
forest(_forest),
launch_domain(Rect<1>::make_empty()),
Expand Down Expand Up @@ -1015,13 +1013,19 @@ class OperationBuilder {
uint64_t gpu_task_use_stream = 0;
};

void top_level(const Task *task, const std::vector<PhysicalRegion> &regions, Context ctx,
Runtime *runtime) {
InputArgs args = Runtime::get_input_args();
FuzzerConfig config = FuzzerConfig::parse_args(args.argc, args.argv);
static bool consensus_match(Context ctx, Runtime *runtime, bool value) {
// Ensure we're encoding this in a consistent way.
int64_t input = value ? 1 : 0;
int64_t output = -1;
Future result = runtime->consensus_match(ctx, &input, &output, 1, sizeof(int64_t));
// Since we only provide a single input, a result size of 1 means they all
// matched.
return result.get_result<size_t>() == 1 && output == 1;
}

int top_level(const FuzzerConfig &config, RngSeed &&seed, Context ctx, Runtime *runtime) {
config.log_config(runtime, ctx);

RngSeed seed = std::move(root_seed);
RngStream rng = seed.make_stream();

RegionForest forest(runtime, ctx, config, seed);
Expand All @@ -1040,42 +1044,35 @@ void top_level(const Task *task, const std::vector<PhysicalRegion> &regions, Con
}
}

forest.verify_contents();
bool region_ok = forest.verify_contents();

bool future_ok = true;
for (FutureCheck &check : futures) {
uint64_t result = check.first.get_result<uint64_t>();
uint64_t expected = check.second;
if (result != expected) {
LOG_ONCE(log_fuzz.fatal()
LOG_ONCE(log_fuzz.error()
<< "Bad future: " << result << ", expected: " << expected);
abort();
future_ok = false;
}
}
}

static void create_mappers(Machine machine, Runtime *runtime,
const std::set<Processor> &local_procs) {
for (Processor proc : local_procs) {
Mapping::Mapper *mapper =
new FuzzMapper::FuzzMapper(runtime->get_mapper_runtime(), machine, proc,
root_seed.make_stream(), replicate_levels);
if (mapper_logging) {
mapper = new Mapping::LoggingWrapper(mapper);
}
runtime->replace_default_mapper(mapper, proc);
}
}
region_ok = consensus_match(ctx, runtime, region_ok);
future_ok = consensus_match(ctx, runtime, future_ok);

void add_mapper_registration_callback(RngSeed &seed) {
Runtime::add_registration_callback(create_mappers);
if (!region_ok) {
return 1;
} else if (!future_ok) {
return 2;
} else {
return 0;
}
}

int main(int argc, char **argv) {
Runtime::initialize(&argc, &argv, true /* filter */);
FuzzerConfig config = FuzzerConfig::parse_args(argc, argv);
root_seed = RngSeed(config.initial_seed);
replicate_levels = config.replicate_levels;
mapper_logging = config.mapper_logging;
RngSeed root_seed(config.initial_seed);

Runtime::preregister_projection_functor(PROJECTION_OFFSET_1_ID,
new OffsetProjection(1));
Expand All @@ -1084,14 +1081,6 @@ int main(int argc, char **argv) {
Runtime::preregister_projection_functor(PROJECTION_RANDOM_DEPTH_0_ID,
new RandomProjection(root_seed.make_stream()));

Runtime::set_top_level_task_id(TOP_LEVEL_TASK_ID);
{
TaskVariantRegistrar registrar(TOP_LEVEL_TASK_ID, "CPU");
registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC));
registrar.set_replicable();
Runtime::preregister_task_variant<top_level>(registrar, "top_level");
}

{
TaskVariantRegistrar registrar(COLOR_POINTS_TASK_ID, "CPU");
registrar.add_constraint(ProcessorConstraint(Processor::LOC_PROC));
Expand Down Expand Up @@ -1200,7 +1189,40 @@ int main(int argc, char **argv) {
registrar, "uint64_replicable_inner");
}

Runtime::add_registration_callback(create_mappers);
Runtime::add_registration_callback(
// Guaranteed to run before Runtime::start returns
[&](Machine machine, Runtime *runtime, const std::set<Processor> &local_procs) {
for (Processor proc : local_procs) {
Mapping::Mapper *mapper = new FuzzMapper::FuzzMapper(
runtime->get_mapper_runtime(), machine, proc, root_seed.make_stream(),
config.replicate_levels);
if (config.mapper_logging) {
mapper = new Mapping::LoggingWrapper(mapper);
}
runtime->replace_default_mapper(mapper, proc);
}
},
false /*dedup*/);

int start_code = Runtime::start(argc, argv, true /*background*/);
if (start_code != 0) {
return start_code;
}

int top_level_code;
{
Runtime *runtime = Runtime::get_runtime();
Context ctx =
runtime->begin_implicit_task(TOP_LEVEL_TASK_ID, 0 /*default*/, Processor::NO_KIND,
nullptr, true /*control_replicable*/);
top_level_code = top_level(config, std::move(root_seed), ctx, runtime);
runtime->finish_implicit_task(ctx);
}

int shutdown_code = Runtime::wait_for_shutdown();
if (shutdown_code != 0) {
return shutdown_code;
}

return Runtime::start(argc, argv);
return top_level_code;
}