-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Prevent use of uninitialized scalar Parameters in JIT code (#7847, partial) #7853
Conversation
src/Parameter.cpp
Outdated
@@ -20,6 +20,7 @@ struct ParameterContents { | |||
std::vector<BufferConstraint> buffer_constraints; | |||
Expr scalar_default, scalar_min, scalar_max, scalar_estimate; | |||
const bool is_buffer; | |||
bool data_ever_set = false; |
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 the place we realize whenever we add sth to the frontend IR, serialization needs to be updated at the same time
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 don't understand
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.
data_ever_set
looks like a field that needs to be consistent across serialization (i.e. A parameter that has a data set should also be known as data-ever-set after serialization roundtrip). In this case, we need to add this field to the serialization implementation to properly serialize it.
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.
Hmm... didn't think about that.
I'm actually kinda unsure as to whether we should be saving the scalar value of the Param (if any) to the Serialization or not -- I know we do now (and it's required for the serialization-round-trip-via-JIT hack), but conceptually, it seems like the wrong thing to do.
A Parameter (either scalar or buffer) is conceptually just a placeholder with required-type information. Is it really desirable (in the general sense) to save whatever happens to be stuff in there?
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.
it does seem weird to me at first as well, had to admit it.
But now I treat this new field in the PR same/similar to the purpose of defined
, then it makes more sense
PTAL -- this change ballooned quite a bit but I think this is all better now:
PTAL |
src/Pipeline.cpp
Outdated
@@ -808,6 +825,11 @@ void Pipeline::prepare_jit_call_arguments(RealizationArg &outputs, const Target | |||
bool is_bounds_inference, JITCallArgs &args_result) { | |||
user_assert(defined()) << "Can't realize an undefined Pipeline\n"; | |||
|
|||
FindVariablesWithUnsetParams find_unset; |
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 think this code is a hot path, so we can't do IR traversal here.
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.
Blarg. That's no good. I'm open for better suggestions.
src/Pipeline.cpp
Outdated
|
||
void visit(const Variable *op) override { | ||
if (op->param.defined() && !op->param.is_buffer() && op->param.name() != "__user_context") { | ||
user_assert(op->param.has_scalar_value()) |
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 don't think this error message is right. Won't it trigger on all attempts to realize a pipeline with unset params, regardless of whether or not you're in a generator? I think the much more likely scenario is someone using the JIT forgetting to set the value of a Param. Also, you can absolutely compile_to_callable without setting the scalar params.
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.
Won't it trigger on all attempts to realize a pipeline with unset params, regardless of whether or not you're in a generator?
Yes. That's a feature, not a bug.
I don't think this error message is right.
Yeah, this is a bit confusing -- IIRC the reason for wording it this way is that the "other" cases (realize, callable) end up being caught via read_only_scalar_address()
noting the invalid value and failing (apparently they don't add the interposed Variable, I don't recall why, it's been a few days).
OK, so upon further review:
|
…, partial) (halide#7853) * Prevent use of uninitialized scalar Parameters in JIT code (halide#7847, partial) * Fix broken tests * Update Parameter.h * Update func_clone.cpp * Fix Generators too * Fixes * Update InferArguments.cpp * Fixes * pacify clang-tidy * fixes
No description provided.