This is an automated email from the ASF dual-hosted git repository.

syfeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-rfcs.git


The following commit(s) were added to refs/heads/main by this push:
     new e17994b  [RFC] Introduce PresburgerSet (#99)
e17994b is described below

commit e17994b90d9278a280d019f3c8ad9065c9a3f584
Author: multiverstack <[email protected]>
AuthorDate: Tue Feb 28 16:33:43 2023 +0800

    [RFC] Introduce PresburgerSet (#99)
    
    This RFC proposes to introduce PresburgerSet as another integer set 
utility, aiming to tackle more complex analysis problems.
    
    
    ---------
    
    Co-authored-by: Min Chen <[email protected]>
---
 rfcs/0099-introduce-PresburgerSet.md | 67 ++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/rfcs/0099-introduce-PresburgerSet.md 
b/rfcs/0099-introduce-PresburgerSet.md
new file mode 100644
index 0000000..a8617aa
--- /dev/null
+++ b/rfcs/0099-introduce-PresburgerSet.md
@@ -0,0 +1,67 @@
+- Feature Name: Introduce PresburgerSet
+- Start Date: 2023-02-13
+- RFC PR: https://github.com/apache/tvm-rfcs/pull/99/
+- GitHub Issue: https://github.com/apache/tvm/issues/14006
+
+# Summary
+It would be great if TVMScript can grow into a generic programming language in 
marchine learning domain. To reach that, it seems some powerful analysis tools 
are needed. Integer set is pivotal in IR analyzing, but IntSet in TVM only 
represents ranges. This RFC is to seek an improvement for it so that we can 
perform the IR analysis more precisely. We found the Presburger Set in MLIR 
library could be leveraged for this purpose.
+# Motivation
+Current dependence analysis is carried out roughly and inconveniently. Due to 
the absence of necessary basic infrastructure, it's hard to consider complex if 
conditions in IR, and it's even more challenging to do element-wise dependence 
analysis, both for inside or between TIR block analysis.
+## Inner block analysis
+One goal of TVMscript is to provide an easy & flexible way to construct 
computation workload for both TVM compiler developers and machine learning 
algorithm developers. TVMscript requires users to annotate some extra 
information when programming, such as `T.block`/`T.remap`/`T.init`..., which 
seem not very intuitive if developers do not have deep compiler knowledge. If 
IR analysis can help users annotate this kind of information automatically, it 
would be a tremendous programming option  [...]
+```
+for i, j, k, m, n in grid(37, 23, 40, 57, 60):
+    if 3*m + 7n < 58 and 45*k + 77*j >= 34:
+        B[i*3324 + j*23 + k*103 + m*279] = A[i, j, k, m, n]
+```
+If we can detect the reduce axis, `T.init` pattern detection should not be a 
problem, then. Of course, this auto-detection should only work as an option 
because TVM developers may sometimes still want to handcraft some complex 
blocks, such as block nesting.
+## Interblock analysis
+Most TIR primitives and passes need to analyze the data denpendency between 
producer & consumer blocks. Without sufficient utility, it's hard to consider 
complex `if` conditions. Analysis without if-conditions leads to a rough 
dependency result and causes redundant data transfer & computation. The 
redundant workload could be neglective for CPU/GPU, but it could be painful for 
NPU, for which extra data is devastating both for DMA and computation. An 
if-condition-aware integer set should s [...]
+```
[email protected]_func
+def if_func(a: T.handle, c: T.handle) -> None:
+    A = T.match_buffer(a, (60,), "float32")
+    C = T.match_buffer(c, (20, 20), "float32")
+    with T.block():
+        B = T.alloc_buffer((60,), dtype="float32")
+        for i in T.grid(60,):
+            with T.block():
+                B[i] = A[i]
+        for i, j in T.grid(20, 20):
+            with T.block():
+                if i + j < 20 and i - j <= 0:
+                    C[i, j] = B[i + 2*j]
+                else:
+                    C[i, j] = 0.0
+```
+How to determine the maximum range of `B` and do compact buffer range for it? 
Shape of `B` only needs (39,) and currently CompactBufferAllocation does 
nothing on this. If we can determine the range automatically, the 
`T.Read`/`T.Write` annotations could be saved .
+# Guide-level explanation
+The proposal is to implement a `PresburgerSet` class. The key point is to 
support inequation constraints to consider if-conditions, so the inequation on 
multiple Vars will mainly be used to express the sets. The basic set 
manipulation functions and constructor functions in `IntSet` class will be 
reimplemented in `PresburgerSet`. An additional constructor function will be 
added to construct from inequations:
+```
+PresburgerSet FromConstraints(Array<Constraint> inequations)
+```
+In order to manage the analysis, we need to separate the vars in all the 
inequations into at least two kinds, the iteration(or domain) vars and other 
vars, say local(target) vars. `PresburgerSet` keeps the relationship between 
iteration vars and local vars, from iteration to local vars or vice versa. Some 
other utility functions are needed to transform the relationship, including:
+```
+PresburgerSet reverse()
+```
+  Reverse the relationship from local vars to iteration vars. So we can 
further analyze dependency based on read/write sets.
+```
+PresburgerSet apply_iteration()/apply_local()
+```
+  Merge two relationships targeting the iteration vars or local vars. Then we 
can propagate the relationship between multiple sets.
+```
+PresburgerSet solve_bounds(PrimExpr expr)
+```
+  Prove engine to solve the maximum/minimum optimization problem based on the 
inequations in `PresburgerSet`, such as simplex solver. Input parameter expr is 
the target expression of optimization problem.
+
+Other existing API, like intersect/union etc, will be reimplemented based on 
updated data structure.
+# Reference-level explanation
+You may have already noticed that this is just what other modern integer set 
library provides, like ISL. So an economical way to achieve this is to leverage 
existing public wheels. ISL is mostly used, but it seems not modular enough or 
open enough, so it could be difficult to integrate deeply. Presburger Set 
located in MLIR is modular designed and open developed. So building from it 
would be a good choice.
+
+No need to introduce MLIR as a source code submodule. Installing LLVM prebuilt 
package installs the necessary libs of Presburger Set, so MLIR can be 
integrated into TVM just like LLVM codegen uses LLVM libs, and it can be 
switched on/off on demand. The new-added util function needs to check whether 
MLIR is installed when called and falls back to the interval set when MLIR is 
not found.
+# Drawbacks
+The `PresburgerSet` serves as the basic infrastructure of IR analysis, and a 
wide range of lowering passes/primitives may need it. Part of its functionality 
is duplicated with `IntSet`, so people should make a decision which one to use 
according to the analysis task.
+# Alternatives
+The other way is to handcraft a copy of code similar to Presburger Set in 
MLIR, which minimizes the software dependence of TVM project, but it needs 
considerable effort and seems like reinventing the wheel, if there is no extra 
new idea to implement.
+# Future possiblities
+One day, when we make sure `PresburgerSet` can fully cover what `IntSet` 
provides, in terms of functionality and efficiency, we may consider phasing out 
the legacy IntSet, then no more decisions about `PresburgerSet` and `IntSet`.

Reply via email to