You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by "wrongtest-intellif (via GitHub)" <gi...@apache.org> on 2023/06/12 07:54:02 UTC
[GitHub] [tvm] wrongtest-intellif commented on a diff in pull request #14854: [TIR][Compute-at] Enable complex floordiv/floormod expressions in compute_at
wrongtest-intellif commented on code in PR #14854:
URL: https://github.com/apache/tvm/pull/14854#discussion_r1226217746
##########
src/tir/schedule/primitive/compute_at.cc:
##########
@@ -422,19 +422,38 @@ std::pair<Var, BlockVarDomainInfo> SolveBlockVarDomain(const arith::IntSet& prov
var_dom = arith::IntSet::Interval(required_min, required_max);
var_bound = arith::IntSet::Interval(0, dim_max);
} else {
- arith::PVar<PrimExpr> p_f;
- if ((floordiv(p_v, p_f)).Match(provided_min)) {
- // a <= (x // factor) <= b, fac > 0 ==> (a * fac) <= x <= (b * fac + fac - 1)
- PrimExpr fac = p_f.Eval();
- if (analyzer->CanProveGreaterEqual(fac, 1)) {
- var = p_v.Eval();
- var_dom = arith::IntSet::Interval(required_min * fac,
- analyzer->Simplify(required_max * fac + fac - 1));
- var_bound = arith::IntSet::Interval(0, analyzer->Simplify(dim_max * fac + fac - 1));
+ arith::PVar<PrimExpr> p_f1, p_f2;
+ if ((floordiv(p_f1, p_f2).Match(provided_min))) {
+ PrimExpr var_expr = p_f1.Eval();
+ if (var_expr->IsInstance<VarNode>()) {
+ // a <= (x // factor) <= b, fac > 0 ==> (a * fac) <= x <= (b * fac + fac - 1)
+ PrimExpr fac = p_f2.Eval();
+ if (analyzer->CanProveGreaterEqual(fac, 1)) {
+ var = Downcast<Var>(var_expr);
+ var_dom = arith::IntSet::Interval(required_min * fac,
+ analyzer->Simplify(required_max * fac + fac - 1));
+ var_bound = arith::IntSet::Interval(0, analyzer->Simplify(dim_max * fac + fac - 1));
+ }
+ } else {
+ const arith::IntSet new_provided = arith::IntSet::SinglePoint(p_f1.Eval());
+ const arith::IntSet new_required = arith::IntSet::SinglePoint(p_f2.Eval());
Review Comment:
I think the `new_required` would be `arith::IntSet::Interval(required_min * fac, required_max * fac + fac - 1)`?
##########
src/tir/schedule/primitive/compute_at.cc:
##########
@@ -422,19 +422,38 @@ std::pair<Var, BlockVarDomainInfo> SolveBlockVarDomain(const arith::IntSet& prov
var_dom = arith::IntSet::Interval(required_min, required_max);
var_bound = arith::IntSet::Interval(0, dim_max);
} else {
- arith::PVar<PrimExpr> p_f;
- if ((floordiv(p_v, p_f)).Match(provided_min)) {
- // a <= (x // factor) <= b, fac > 0 ==> (a * fac) <= x <= (b * fac + fac - 1)
- PrimExpr fac = p_f.Eval();
- if (analyzer->CanProveGreaterEqual(fac, 1)) {
- var = p_v.Eval();
- var_dom = arith::IntSet::Interval(required_min * fac,
- analyzer->Simplify(required_max * fac + fac - 1));
- var_bound = arith::IntSet::Interval(0, analyzer->Simplify(dim_max * fac + fac - 1));
+ arith::PVar<PrimExpr> p_f1, p_f2;
+ if ((floordiv(p_f1, p_f2).Match(provided_min))) {
+ PrimExpr var_expr = p_f1.Eval();
+ if (var_expr->IsInstance<VarNode>()) {
+ // a <= (x // factor) <= b, fac > 0 ==> (a * fac) <= x <= (b * fac + fac - 1)
+ PrimExpr fac = p_f2.Eval();
+ if (analyzer->CanProveGreaterEqual(fac, 1)) {
+ var = Downcast<Var>(var_expr);
+ var_dom = arith::IntSet::Interval(required_min * fac,
+ analyzer->Simplify(required_max * fac + fac - 1));
+ var_bound = arith::IntSet::Interval(0, analyzer->Simplify(dim_max * fac + fac - 1));
+ }
+ } else {
+ const arith::IntSet new_provided = arith::IntSet::SinglePoint(p_f1.Eval());
+ const arith::IntSet new_required = arith::IntSet::SinglePoint(p_f2.Eval());
+ return SolveBlockVarDomain(new_provided, new_required, dim_max, analyzer);
+ }
+ } else if ((floormod(p_f1, p_f2).Match(provided_min))) {
+ PrimExpr var_expr = p_f1.Eval();
+ if (var_expr->IsInstance<VarNode>()) {
+ // generally domain of (x % fac) enforce no constraints to domain of x
+ Var var_mod = Downcast<Var>(var_expr);
+ return {var_mod, BlockVarDomainInfo()};
+ } else {
+ PrimExpr mod_1 = p_f1.Eval();
+ PrimExpr mod_2 = p_f2.Eval();
+ if (analyzer->CanProveGreaterEqual(mod_1, 1) &&
+ analyzer->CanProveGreaterEqual(mod_2, 1)) {
+ const arith::IntSet new_provided = arith::IntSet::SinglePoint(p_f1.Eval());
+ return SolveBlockVarDomain(new_provided, required, dim_max, analyzer);
Review Comment:
We are deducing required region of `lhs` from the required region of `lhs % fac`.
If `a <= lhs % fac <= b` and `lhs > 0 && fac > 0 && a >= 0`, we could know `a <= lhs` but could not know `lhs <= b`, thus the `new_required` should be `[origin_required_min, +inf)` generally instead of `required`. Thus here it would be great to change
- Add check to ensure `required_min >= 0`
- Construct the deduced new required set `[required_min, +inf]` instead of origin one
##########
src/tir/schedule/primitive/compute_at.cc:
##########
@@ -422,19 +422,38 @@ std::pair<Var, BlockVarDomainInfo> SolveBlockVarDomain(const arith::IntSet& prov
var_dom = arith::IntSet::Interval(required_min, required_max);
var_bound = arith::IntSet::Interval(0, dim_max);
} else {
- arith::PVar<PrimExpr> p_f;
- if ((floordiv(p_v, p_f)).Match(provided_min)) {
- // a <= (x // factor) <= b, fac > 0 ==> (a * fac) <= x <= (b * fac + fac - 1)
- PrimExpr fac = p_f.Eval();
- if (analyzer->CanProveGreaterEqual(fac, 1)) {
- var = p_v.Eval();
- var_dom = arith::IntSet::Interval(required_min * fac,
- analyzer->Simplify(required_max * fac + fac - 1));
- var_bound = arith::IntSet::Interval(0, analyzer->Simplify(dim_max * fac + fac - 1));
+ arith::PVar<PrimExpr> p_f1, p_f2;
+ if ((floordiv(p_f1, p_f2).Match(provided_min))) {
+ PrimExpr var_expr = p_f1.Eval();
+ if (var_expr->IsInstance<VarNode>()) {
+ // a <= (x // factor) <= b, fac > 0 ==> (a * fac) <= x <= (b * fac + fac - 1)
+ PrimExpr fac = p_f2.Eval();
+ if (analyzer->CanProveGreaterEqual(fac, 1)) {
Review Comment:
should we check `analyzer->CanProveGreaterEqual(fac, 1)` for both var and non-var case?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tvm.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org