"docs/Installation.md" did not exist on "64f17c2f369e612cc297d358f607307a615bbb59"
Unverified Commit e387102c authored by Lei Wang's avatar Lei Wang Committed by GitHub
Browse files

[Enhancement] Refactor vectorization checks in loop_vectorize (#1440)

* Introduced a new function, IsExprInvariantInVectorBoundary, to encapsulate the logic for checking if an expression is invariant within vector boundaries, improving code clarity and reusability.
* Updated the existing vectorization logic to utilize this new function, streamlining the process of determining vectorization feasibility based on boundary conditions.
* Enhanced comments for better understanding of the vectorization criteria and mathematical rationale behind the checks.
parent 4dbc910d
...@@ -187,9 +187,13 @@ private: ...@@ -187,9 +187,13 @@ private:
if (CanProveIndependent(elem_offset, inner_for_->loop_var, analyzer_)) { if (CanProveIndependent(elem_offset, inner_for_->loop_var, analyzer_)) {
return; return;
} }
// 3. Tight vectorize bound // 3. Check if current vector_size_ works with invariant boundary check
vector_size_ = arith::ZeroAwareGCD(vector_size_, vector_load_bits_max_ / if (!IsExprInvariantInVectorBoundary(elem_offset, inner_for_->loop_var,
buffer->dtype.bits()); vector_size_, analyzer_)) {
// If not, tight vectorize bound with buffer dtype constraint
vector_size_ = arith::ZeroAwareGCD(
vector_size_, vector_load_bits_max_ / buffer->dtype.bits());
}
// 4. Try to vectorize buffer load // 4. Try to vectorize buffer load
while (!IndiceCanVectorize(elem_offset, inner_for_->loop_var, while (!IndiceCanVectorize(elem_offset, inner_for_->loop_var,
inner_for_->extent, vector_size_, analyzer_)) { inner_for_->extent, vector_size_, analyzer_)) {
...@@ -272,6 +276,28 @@ bool CanProveIndependent(const PrimExpr &expr, Var var, ...@@ -272,6 +276,28 @@ bool CanProveIndependent(const PrimExpr &expr, Var var,
return false; return false;
} }
bool IsExprInvariantInVectorBoundary(const PrimExpr &expr, Var var,
int target_vectorized_size,
arith::Analyzer *analyzer) {
// Check if expr is invariant within vector boundaries
// We're trying to prove the access expression A[f(var)] depends only on
// floor(var/vecsize), not on var%vecsize
// Mathematically:
// \forall var, f(floor(var/vecsize)*vecsize + var%vecsize) ==
// f(floor(var/vecsize)*vecsize + 0)
// Example: for i in T.vectorized(8):
// A[i] = B[i] * C[i//4]
// if vecsize=4, f(i)=i//4 depends only on i//4
// Therefore A[i] = B[i] * C[i//4] can be vectorized with vecsize=4
PrimExpr var_aligned =
floordiv(var, target_vectorized_size) * target_vectorized_size;
PrimExpr expr_aligned = Substitute(expr, {{var, var_aligned}});
if (analyzer->CanProveEqual(expr, expr_aligned)) {
return true;
}
return false;
}
bool IndiceCanVectorize(const PrimExpr &expr, Var var, bool IndiceCanVectorize(const PrimExpr &expr, Var var,
const PrimExpr &iter_var_size, const PrimExpr &iter_var_size,
int target_vectorized_size, arith::Analyzer *analyzer) { int target_vectorized_size, arith::Analyzer *analyzer) {
...@@ -292,20 +318,8 @@ bool IndiceCanVectorize(const PrimExpr &expr, Var var, ...@@ -292,20 +318,8 @@ bool IndiceCanVectorize(const PrimExpr &expr, Var var,
0)) 0))
return false; return false;
// Check if expr is invariant within vector boundaries if (IsExprInvariantInVectorBoundary(expr, var, target_vectorized_size,
// We're trying to prove the access expression A[f(var)] depends only on analyzer)) {
// floor(var/vecsize), not on var%vecsize
// Mathematically:
// \forall var, f(floor(var/vecsize)*vecsize + var%vecsize) ==
// f(floor(var/vecsize)*vecsize + 0)
// Example: for i in T.vectorized(8):
// A[i] = B[i] * C[i//4]
// if vecsize=4, f(i)=i//4 depends only on i//4
// Therefore A[i] = B[i] * C[i//4] can be vectorized with vecsize=4
PrimExpr var_aligned =
floordiv(var, target_vectorized_size) * target_vectorized_size;
PrimExpr expr_aligned = Substitute(expr, {{var, var_aligned}});
if (analyzer->CanProveEqual(expr, expr_aligned)) {
return true; return true;
} }
......
...@@ -46,6 +46,12 @@ For VectorizeLoop(const For &loop, arith::Analyzer *analyzer, ...@@ -46,6 +46,12 @@ For VectorizeLoop(const For &loop, arith::Analyzer *analyzer,
// when var changes // when var changes
bool CanProveIndependent(const PrimExpr &expr, Var var, bool CanProveIndependent(const PrimExpr &expr, Var var,
arith::Analyzer *analyzer); arith::Analyzer *analyzer);
// Check if expr is invariant within vector boundaries
bool IsExprInvariantInVectorBoundary(const PrimExpr &expr, Var var,
int target_vectorized_size,
arith::Analyzer *analyzer);
bool IndiceCanVectorize(const PrimExpr &expr, Var var, bool IndiceCanVectorize(const PrimExpr &expr, Var var,
const PrimExpr &iter_var_size, const PrimExpr &iter_var_size,
int target_vectorized_size, arith::Analyzer *analyzer); int target_vectorized_size, arith::Analyzer *analyzer);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment