question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[RFC][ARITH] Introduce FloorDiv/Mod for Context-Independent Simplifications

See original GitHub issue

Many parts of our code base rely on integer simplifications that involves div/mod. These simplifications are in particular tricky due to the different division mode, and the dependence on knowing the sign of the operand.

DIvMod Variants

Trunc div/mod

IEEE standard integer division is truncated division, directly maps to the hardware. This is the division used by C and TVM by default. The problem of trunc div is that we usually relies on knowing the sign of both operands. For example, we cannot simplify (x * 4 + 3)/4 => x if x can be negative.

Floor div/mod

Always round down. This is the division mode adopted by python. To simplify floordiv, we usually need to know the sign of divisor, but not necessarily the sign of dividend floordiv(x * 4 + 3,4) => x .

Euclidean div/mod

Always ensures that the remainder is non-negative. This is the division mode used by Halide by default. Note that when the divisor is positive, Euclidean and floordiv are equivalent. But floordiv will produce a negative remainder when the divisor is negative.

Discussion

Different division mode has its own advantage and disadvantages. While Floor and Euclidean mode enjoys better invariance in simplification. However, we don’t really want to emit those operators in the low-level code, as we cannot find direct instruction correspondence. So ideally we will need to lower them back to truc div/mod after simplification is done, in which case we still want to know the sign of the operands. In summary, the two ways are:

  • Always use trunc div, but need to know sign of the operands during every transformation
  • Use floor/euclidean div, no need to know the sign of dividend during simplification, but need to know the sign when lowering back to trunc div.
    • We also need to be aware of potential risk of over-simplification (simplify something to a floordiv where we don’t know the sign of dividend)

To give a concrete example about the difference, consider the following case:

for (x = 0; x < 100; x++) {
   // trunc division
   a [(x * 4 + 3)/ 4] =  xyz.
}

(x * 5 + 3)/4 can be simplified to (x * 5 /4) , if we setup the simplifier, with currect context(x in [0, 100]). However, there can be cases where we forget to do so in our code, i that scenario the simplifcation cannot be done. If instead we use

for (x = 0; x < 100; x++) {
   // floor division
   a [floordiv(x * 4 + 3, 4)] =  xyz.
}

(x * 4 + 3)/4 can be simplified to x in the analysis. However, to get the most efficient version of the code. We need to lower the floor division to x knowing that x is non-negative. The context information is only needed during the floor division lowering.

In summary, using trunc div during analysis requires m ore information each time we transform it, using floor/euclidean div makes simplification easier, but still requires us to provide context information to most efficiently lowers to trunc div/mod.

Proposal to be Discussed: Adding Floor Div/Mod

It might be helpful to encourage the use of floor div/mod for integer analysis while providing an effective way to lower to trunc div when necessary. To avoid confusion between division mode, I propose we add an explicit floordiv/floormod node and operator to the IR.

The reason to choose floordiv/mod over Euclidean is mainly due to floor is more common(used by python) and easier to understand. The difference in behavior happens when the divisor is negative. In most cases, we will know the sign of divisor.

The original truc div/mod simplification will be kept around for a while, but we will encourage most index calculations to use floordiv/mod, and provide rewriter to rewrite truc div/mod into floor version when the sign of the dividend is positive

Embed more information in the IR

Besides introducing floor div/mod to make the transformation context independent. We can also start to think about embedding more information in the IR. For example, in the case of (x * 4 + 3) / 4, if we directly embed the bound information about x inside the Var itself, we can directly do the same analysis without manually injecting the context information to the analyzer. This is an interesting design trade-off that we might want to consider in the future.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13 (13 by maintainers)

github_iconTop GitHub Comments

1reaction
sgrechanik-hcommented, Jul 4, 2019

I think Euclidean division should be preferred since it is used in Halide and smt-lib, which I think are more relevant than python (e.g. it will be easier to borrow algorithms from Halide and to use SMT solvers to perform some proofs if we ever need it).

1reaction
tqchencommented, Jul 3, 2019

Sorry it should be (x * 4 + 3) / 4=>x

Read more comments on GitHub >

github_iconTop Results From Across the Web

[RFC][ARITH] Introduce FloorDiv/Mod for Context- ...
Use floor/euclidean div, no need to know the sign of dividend during simplification, but need to know the sign when lowering back to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found