junrushao1994 commented on a change in pull request #9871:
URL: https://github.com/apache/tvm/pull/9871#discussion_r780718325



##########
File path: src/tir/schedule/analysis/analysis.cc
##########
@@ -1376,5 +1376,333 @@ void CheckStorageScope(const ScheduleState& self, 
String storage_scope) {
   }
 }
 
+/******** Tensorize Comparator ********/
+
+bool TensorizeComparator::VisitStmt(const Stmt& n, const Stmt& other) {
+  if (n.same_as(other)) return true;
+  if (n->type_index() != other->type_index()) return false;
+  bool equal = StmtComparator::VisitStmt(n, other);
+  if (!equal && assert_mode_)
+    LOG(FATAL) << "Stmts are not matching between:\n" << n << "\nand\n" << 
other;
+  return equal;
+}
+
+bool TensorizeComparator::VisitStmt_(const ForNode* op, const Stmt& other) {
+  const auto* rhs = other.as<ForNode>();
+  if (!DefEqual(op->loop_var, rhs->loop_var)) return false;
+  if (!VisitExpr(op->min, rhs->min)) return false;
+  if (!VisitExpr(op->extent, rhs->extent)) return false;
+  if (!VisitStmt(op->body, rhs->body)) return false;
+  if (op->kind != rhs->kind) return false;
+  if (op->thread_binding.defined() ^ rhs->thread_binding.defined()) return 
false;
+  if (op->thread_binding.defined() &&
+      !VisitExpr(op->thread_binding.value(), rhs->thread_binding.value()))
+    return false;
+  return CompareAnnotationMap(op->annotations, rhs->annotations);
+}
+
+bool TensorizeComparator::VisitStmt_(const SeqStmtNode* op, const Stmt& other) 
{
+  const auto* rhs = other.as<SeqStmtNode>();
+  return CompareArray(op->seq, rhs->seq, &TensorizeComparator::VisitStmt);
+}
+
+bool TensorizeComparator::VisitStmt_(const BufferStoreNode* op, const Stmt& 
other) {
+  const auto* rhs = other.as<BufferStoreNode>();
+  return CompareBufferAccess(op, rhs) && VisitExpr(op->value, rhs->value);
+}
+
+bool TensorizeComparator::VisitStmt_(const BlockRealizeNode* op, const Stmt& 
other) {
+  const auto* rhs = other.as<BlockRealizeNode>();
+  // Skip Compare binding values if the block is scope block (the outermost 
one).
+  if (!is_scope_block) {
+    size_t offset = op->iter_values.size() - rhs->iter_values.size();
+    if (rhs->iter_values.size() > op->iter_values.size()) return false;
+    if (is_inner_block) {
+      // weak pattern matching for the inner block (the son of the scope block)
+      // where the pattern is v + iter <=> expr + iter
+      for (size_t i = 0; i < rhs->iter_values.size(); ++i) {
+        PrimExpr lhs_expr, rhs_expr;
+        Optional<Var> lhs_iter, rhs_iter;
+        auto detect = [](const PrimExpr& binding) -> std::pair<PrimExpr, 
Optional<Var>> {
+          arith::PVar<PrimExpr> expr;
+          arith::PVar<Var> iter;
+          if (iter.Match(binding)) {
+            return std::make_pair(0, iter.Eval());
+          } else if ((expr + iter).Match(binding)) {
+            return std::make_pair(expr.Eval(), iter.Eval());
+          } else if ((iter + expr).Match(binding)) {
+            return std::make_pair(expr.Eval(), iter.Eval());
+          } else {
+            return std::make_pair(expr.Eval(), NullOpt);

Review comment:
       is expr.Eval() == nullptr?
   
   ```suggestion
               return std::make_pair(PrimExpr{nullptr}, NullOpt);
   ```




-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to