Skip to content
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

Merged
merged 3 commits into from
Jul 13, 2019
Merged

[ARITH][IR] Introduce FloorDiv/Mod #3479

merged 3 commits into from
Jul 13, 2019

Conversation

tqchen
Copy link
Member

@tqchen tqchen commented Jul 3, 2019

Code acompany #3478

@tqchen
Copy link
Member Author

tqchen commented Jul 4, 2019

@@ -63,6 +64,29 @@ class CanonicalExprNode : public BaseExprNode {
TVM_DECLARE_BASE_NODE_INFO(CanonicalExprNode, BaseExprNode);
};

enum DivMode {
/*! \brief Trucated division. */
kTrucDiv,
Copy link
Contributor

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 {
Copy link
Contributor

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

/*!
* \brief Detect if psum = q * coeff + r such that (q >= 0 && r >= 0)
* f\brief Separate psum into divisible and non-divisible parts.
Copy link
Contributor

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) {
Copy link
Contributor

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));
Copy link
Contributor

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.

Copy link
Member Author

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);
}

Copy link
Member

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);
Copy link
Member

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?

Copy link
Member Author

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.

@tqchen
Copy link
Member Author

tqchen commented Jul 6, 2019

Thanks, @sgrechanik-h @Hzfengsy , I have addressed your comments.

* \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.
Copy link
Member

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) {
Copy link
Member

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?

@tqchen
Copy link
Member Author

tqchen commented Jul 8, 2019

}
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)) {
Copy link
Contributor

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).

Copy link
Member Author

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

Copy link
Contributor

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.

Copy link
Member Author

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
Copy link
Contributor

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

@tqchen tqchen force-pushed the arithx branch 2 times, most recently from 2e67abf to 974286a Compare July 10, 2019 18:14
@tqchen
Copy link
Member Author

tqchen commented Jul 13, 2019

Thanks @Hzfengsy @sgrechanik-h @yzhliu this pr is now merged

wweic pushed a commit to wweic/tvm that referenced this pull request Aug 9, 2019
* [ARITH][IR] Introduce FloorDiv/Mod

* Address review comments

* address review comments, fix div sub rule
wweic pushed a commit to neo-ai/tvm that referenced this pull request Sep 6, 2019
* [ARITH][IR] Introduce FloorDiv/Mod

* Address review comments

* address review comments, fix div sub rule
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.

4 participants