Skip to content

Conversation

@zasdfgbnm
Copy link
Collaborator

No description provided.

// simplifications involving div and mod requires the divisor to be
// non-zero, and I don't want this edge case to block the simplification of
// normal cases.
if (ns->getParallelDim().has_value() || ns->isTensorSize()) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't make sense to assume tensor size to be positive globally. All we want is to unblock the simplification of i / size * size + i % size -> i, but if we do assume size to be positive, we would also simplify predicates like 0 < size as true, which could potentially break zero tensor support. Instead, we should have a preserve_error flag for expr simplified to unblock that simplification even if we can not prove size to be non-zero.

@zasdfgbnm
Copy link
Collaborator Author

Marking this as ready, but I would like to wait for #2500 because I don't want this to conflict with the new assertCUDAKernels in loop rotation tests.

@zasdfgbnm zasdfgbnm marked this pull request as ready for review March 1, 2023 09:20
@zasdfgbnm zasdfgbnm requested a review from naoyam March 1, 2023 09:20
std::unordered_map<Val*, VarInfo> var_info_map_;
std::vector<Val*> var_order_;
std::unordered_set<Val*> set_;
bool preserve_error_ = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a comment what this flag means?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I found a comment at simplifyExpr().


namespace {

// If we can not prove `value` to be zero, then treat it as non-zero, unless we
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this comment is a little confusing to me.

If we can not prove value to be zero, then treat it as non-zero

Are you saying "treat it as potentially non-zero" rather than "definitely non-zero", right?

"If we can not prove value to be zero, then treat it as potentially non-zero" <- This seems generally true, so why "unless we want to preserve error"?

Copy link
Collaborator Author

@zasdfgbnm zasdfgbnm Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very confusing, I renamed it and rewrite its comments:

// If we want to do simplifications like (a * b) / b -> a, depending on whether
// we want to preserve error, the behavior could be different. If we don't care
// about preserving error, we can just go ahead and do the simplification.
// However, if we do want the division-by-zero error to be preserved, then we
// can only do the simplification if we can prove b != 0. This function tells us
// if the value of b is safe to do such optimization. Instead of completely
// ignoring error case, we do a bit extra: if b is proved to be zero, then we
// are sure that there will be an error, then we don't remove the error. That is,
// if we don't know if there will be an error, we procceed assuming no error. If
// we are sure there will be an error, then don't procceed.
bool isValidDenominator(Val* value, const Context& context) {
  if (context.preserveError()) {
    return prove::isNonZero(value, context);
  }
  return !foldConstants(value)->isZero();
}

if (context.preserveError()) {
return prove::isNonZero(value, context);
}
return !foldConstants(value)->isZero();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does folding of (a * b) / b to b happen in foldConstants(value)? Does foldConstants fold the expression no matter if b is zero or not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, foldConstants is just constant folding, that is, changing 3 - 3 into 0.

// we can prove that b is not zero. If we don't care about error case, then
// having `b` in the denominator already indicates that `b` is non-zero. So we
// can just do the simplification without worrying about `b` being zero.
bool notSurelyZero(Val* value, const Context& context) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this name doesn't sound very intuitive to me. What this tells is value is not proven to be zero, right? It seems it just says it may be or may not be zero. Am I right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your understanding is correct. The name and comment of this function is very confusing, I renamed it and rewite its comment. See #2534 (comment)

Copy link
Collaborator

@naoyam naoyam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. It's much clearer now. I added some comments, which I think would make it further easier to follow.

// are sure that there will be an error, then we don't remove the error. That
// is, if we don't know if there will be an error, we procceed assuming no
// error. If we are sure there will be an error, then don't procceed.
bool isValidDenominator(Val* value, const Context& context) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: value -> denominator

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent suggestion!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

Comment on lines 1208 to 1209
// Q1: Can we prove that value is nonzero?
// Q2: Can we prove that value is zero?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"that value" -> "the denominator"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

if (context.preserveError()) {
return false;
}
bool proved_zero = foldConstants(value)->isZero();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have prove::isNonZero(). Don't we have prove::isZero()? If so, why isn't it used here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are doing the same thing. I created prove::isZero when there were no Val::isZero, but later, I added Val::isZero, so prove::isZero is no longer needed. I am removing it in another PR, so I am not using it here.

@zasdfgbnm zasdfgbnm merged commit 0200e7a into devel Mar 1, 2023
@zasdfgbnm zasdfgbnm deleted the do-not-assume-size-nonzero branch March 1, 2023 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants