-
Notifications
You must be signed in to change notification settings - Fork 30
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
Threshold condition #2305
Threshold condition #2305
Conversation
This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):
See CI logs for the full diff. |
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.
Other than the specific comments in the code, I have two high-level concerns.
1.) The attempt to handle int vs float values is incomplete. The only state params of int type should be execution counters, so we can just merge all special cases into one:
indices == TimeScale => value has is of type int => tolerance == 0.
2.) I'm don't quite like the custom handling of absolute and relative tolerance. The comparator logic would IMO be eaiser to explain if it used numpy's is_close.
== -- is_close
!= -- not is_close
>= -- '>' or is_close
> -- '>' and not is_close
<= -- '<' or is_close
< -- '<' and not is_close
This should also help with weird corner cases like:
val == threshold-epsilon # epsilon < tolerance
under the current semantics val > threshold returns true (i.e. threshold - epsilon > threshold - tolerance) which is confusing.
The above semantics with 'is_close' would return false.
You can construct a reverse example (val == threshold + epsilon) to point to a disrepance there, but I think it's easier to explain that values within tolerance are considered equal and the user should use '>=' in that case.
The main benefit of implementing semantics based on is_close is that it maintains traditional comparison invariants (e.g a > b => a != b) which is not true in the current version.
psyneulink/core/llvm/helpers.py
Outdated
param_ptr, | ||
[self.ctx.int32_ty(x) for x in ([0] + list(indices))] | ||
) | ||
) |
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.
The above can be drastically shortened by reducing it to preprocessing indices,
The load statement would be more readable if it were reused and split into two expressions.
psyneulink/core/llvm/helpers.py
Outdated
comparator = condition.comparator | ||
indices = condition.indices | ||
|
||
tolerance_value = condition.rtol * abs(threshold) + condition.atol |
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 it'd be easier to use numpy is_close, rather than reimplementing own version of relative and absolute threshold. there are compiler helpers with the same behaviour as well (see helpers.is_close)
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 could replace some of the checks. I think a manual value would still need to be used for the strict inequalities, though I'm not really sure how much a tolerance even makes sense for those.
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.
agreed, I think the semantics need a bit of discussion.
using is_close in all of them made sense to me because it preserves the expected comparison invariants,
but at the same time breaking 'x + epsilon > x' is not very intuitive either.
I'm not sure what the user expectations are here, and how much we can restrict them.
Allowing only shape inequalities can be one way out, users can always combine scheduling decisions themselves.
psyneulink/core/llvm/helpers.py
Outdated
return cmp_method(comparator, val, threshold) | ||
else: | ||
abs_method = self.ctx.get_builtin(abs_method_name, [val.type]) | ||
val_thresh_diff = builder.call(abs_method, [builder.fsub(val, threshold)]) |
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 unravels the attempt to have general handling of ints vs floats. The abs method might be general, but you're using fsub
which will fail for integers anyway.
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.
True, is it better to handle int/float separately instead of just converting int to float? If any/all of the comparisons are to be done with helpers.is_close, I think that just takes floats.
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 was thinking about it too. with the current default of fp64 it should be ok (all int32 values can be represented in fp64).
Switching to fp32 will introduce problems for values above 16.7M, which might be too low for lifetime execution count.
I think it'd make sense to special case execution counts as the only integer codepath and maybe restrict allowed tolerances (e.g. only integer absolute tolerance?)
similarly to above, I don't have a good idea about what the users would expect here.
Conversion to fp64 and using is_close should be safe, for all situations, but might be unnecessary.
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'm fine with writing a special case for execution count if it's faster or otherwise better, but for now I've just converted
96b06cf
to
fd6af0f
Compare
This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):
See CI logs for the full diff. |
1 similar comment
This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):
See CI logs for the full diff. |
This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):
See CI logs for the full diff. |
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.
LGTM, other than a few nits about comments.
This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):
See CI logs for the full diff. |
This PR causes the following changes to the html docs (ubuntu-latest-3.7-x64):
See CI logs for the full diff. |
No description provided.