-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
[ARITH][IR] Introduce FloorDiv/Mod #3479
Conversation
src/arithmetic/canonical_simplify.cc
Outdated
@@ -63,6 +64,29 @@ class CanonicalExprNode : public BaseExprNode { | |||
TVM_DECLARE_BASE_NODE_INFO(CanonicalExprNode, BaseExprNode); | |||
}; | |||
|
|||
enum DivMode { | |||
/*! \brief Trucated division. */ | |||
kTrucDiv, |
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.
Typo Truc
-> Trunc
inline Expr ModImpl(Expr a, Expr b, DivMode mode) { | ||
if (mode == kTrucDiv) { | ||
return a % b; | ||
} else { |
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.
Maybe explicitly check mode == kFloorDiv
src/arithmetic/canonical_simplify.cc
Outdated
/*! | ||
* \brief Detect if psum = q * coeff + r such that (q >= 0 && r >= 0) | ||
* f\brief Separate psum into divisible and non-divisible parts. |
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 guess f
at the beginning is a typo
* \param div_mode The new div_mode. | ||
* \return The transformed SplitExpr. | ||
*/ | ||
SplitExpr ConvertDivMode(SplitExpr expr, DivMode div_mode) { |
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 function doesn't perform full conversion of one division into another, so it only works in simple cases. It is not clear from the description whether it is intentional or the function is just unfinished.
CHECK_NE(pb->value, 0) << "Divide by zero"; | ||
} | ||
if (fa && fb && fb->value != 0) { | ||
return FloatImm::make(rtype, std::floor(fa->value / fb->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'm not sure that FloorDiv for floats should be allowed.
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 debatable. There used to be some need in terms of floordiv for floats(in tensorflow etc), given that this is a simple op, perhaps we could allow this.
(x % y == 0); | ||
return round_down ? (x % y) : (x % y + y); | ||
} | ||
|
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 am not sure why these two functions are written in int_op_overflow.h
if (analyzer->CanProveGreaterEqual(b->min_value, 0)) { | ||
Expr min_value = a->HasLowerBound() ? floordiv(a->min_value, b->min_value) : neg_inf(); | ||
Expr max_value = a->HasUpperBound() ? floordiv(a->max_value, b->min_value) : pos_inf(); | ||
return IntervalSet(min_value, max_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.
What will happen if a
with a negative min_value
and a positive max_value
? Does it will cause problems?
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.
Because b is positive, the division of floordiv(a, b) is monotonic with respect to a, so it should be fine.
Thanks, @sgrechanik-h @Hzfengsy , I have addressed your comments. |
src/arithmetic/int_operator.h
Outdated
* \file int_op_overflow.h | ||
* \brief Utility functions to detect if an integer op will overflow. | ||
* \file int_operator.h | ||
* \brief Additional useful operators for intteger. |
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.
typo 'intteger'
* \param y The right operand. | ||
* \return the result. | ||
*/ | ||
inline int64_t floordiv(int64_t x, int64_t y) { |
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.
shall we check y == 0?
@sgrechanik-h @Hzfengsy please take another look and https://docs.tvm.ai/contribute/code_review.html#approve-and-request-changes-explicitly |
} | ||
if (is_one(b->min_value)) return a; | ||
// no relaxation is needed in here due to set is inclusive | ||
if (analyzer->CanProveGreaterEqual(b->min_value, 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.
I guess we have to compare with 1 here to avoid division by zero, like in the next if-branch. (Or compare with 0 and remove the check from the TryConstFold function since b->min_value == 0
may result from relaxation and shouldn't lead to failure).
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.
good point, I added a condition to catch this problem
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.
Oh, sorry, I forgot that we are in the b->IsSinglePoint()
branch, so I guess my comment is meaningless since b->min_value == 0
definitely leads to division by zero in this case, and failing in TryConstFold shouldn't be a problem.
However, I think it is possible to replace analyzer->CanProveGreaterEqual(-b->min_value, 1)
with analyzer->CanProveGreaterEqual(-b->min_value, 0)
in the next branch, for symmetry.
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.
OK, I will make the change
(x / c1) * c1 + x % c1, x, | ||
CanProveGreaterEqual(x.Eval(), 0) && c1.Eval()->value > 0); | ||
// DivMod rules | ||
// truc div |
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.
multiple truc/trunc
typos in the file
2e67abf
to
974286a
Compare
Thanks @Hzfengsy @sgrechanik-h @yzhliu this pr is now merged |
* [ARITH][IR] Introduce FloorDiv/Mod * Address review comments * address review comments, fix div sub rule
* [ARITH][IR] Introduce FloorDiv/Mod * Address review comments * address review comments, fix div sub rule
Code acompany #3478