-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Merge random pipeline generator #8836
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
I think we need to have some way to compile and run it, and some build target that does so. Maybe RunGen-based? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some feedback re: the handling of randomness in this. There are good utilities in C++ for generating uniform randomness. Using mod introduces bias. I'm not sure about the division thing for floats either.
result.push_back(i); | ||
} | ||
return result; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could at least take a const reference, but it could be more simply written as
vector<Expr> arguments{vars.begin(), vars.end()};
wherever it is used.
} | ||
float rand_float() { | ||
return rand_int(0, 1 << 30) / (float)(1 << 30); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is janky. We should really use the proper RNG types...
class Random {
std::mt19937 eng_;
uint32_t seed_;
public:
explicit Random(uint32_t seed) : eng_(seed), seed_(seed) {}
void reseed(uint32_t seed) {
eng_.seed(seed);
seed_ = seed;
}
uint32_t seed() const { return seed_; }
int integer(int min, int max) {
std::uniform_int_distribution<int> dist(min, max);
return dist(eng_);
}
bool boolean(double p = 0.5) {
std::bernoulli_distribution dist(p);
return dist(eng_);
}
float real() {
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
return dist(eng_);
}
template <typename T>
decltype(auto) element(T&& t) {
auto n = std::size(t);
std::uniform_int_distribution<std::size_t> dist(0, n - 1);
return t[dist(eng_)];
}
};
Random R;
Something like this should work.
// subexpressions. At the base case where depth is 0, we just return | ||
// a randomly chosen input. | ||
Type expr_types[] = {UInt(8), UInt(16), UInt(32), Int(8), Int(16), Int(32), Float(32)}; | ||
const int expr_type_count = sizeof(expr_types) / sizeof(expr_types[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for the _count
if we use the element
helper above.
int op = rng() % comp_bin_op_count; | ||
return make_comp_bin_op[op](a, b); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int op = rng() % comp_bin_op_count; | |
return make_comp_bin_op[op](a, b); | |
return R.element(make_comp_bin_op)(a, b); |
const int bin_op_count = sizeof(make_bin_op) / sizeof(make_bin_op[0]); | ||
const int bool_bin_op_count = sizeof(make_bool_bin_op) / sizeof(make_bool_bin_op[0]); | ||
const int comp_bin_op_count = sizeof(make_comp_bin_op) / sizeof(make_comp_bin_op[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for counts
} else if (t.is_int() || t.is_uint()) { | ||
return cast(t, rand_int(1, 127)); | ||
} else if (t.is_float()) { | ||
return cast(t, rand_float()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return cast(t, rand_float()); | |
return cast(t, R.real()); |
} | ||
|
||
void generate() { | ||
rng.seed((int)seed); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rng.seed((int)seed); | |
R.reseed(seed); |
public: | ||
int num_stage_types = 18; | ||
// The random seed to use to generate the pipeline. | ||
GeneratorParam<int> seed{"seed", 1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GeneratorParam<int> seed{"seed", 1}; | |
GeneratorParam<uint32_t> seed{"seed", 1}; |
} | ||
}; | ||
|
||
HALIDE_REGISTER_GENERATOR(RandomPipeline, random_pipeline) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newline
add_app(unsharp) | ||
add_app(wavelet) | ||
add_app(HelloBaremetal) | ||
add_app(random_pipeline) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please insert this in alphabetical order (and fix HelloBaremetal, apparently)
This PR attempts to merge the random pipeline generator that is used to generate autoscheduling training data into main, originally from: https://github.com/halide/Halide/tree/abadams/random_pipelines/
One thing I'm not sure about is do we want to include
process.cpp
like other apps that just test if the generator code can compile and run (see examples likebgu
)cc @abadams @alexreinking