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



##########
File path: src/tir/schedule/primitive/loop_transformation.cc
##########
@@ -253,6 +277,137 @@ class WrongFactorProductError : public ScheduleError {
   For loop_;
 };
 
+class LoopMultiAppearanceError : public ScheduleError {
+ public:
+  explicit LoopMultiAppearanceError(IRModule mod, For loop)
+      : mod_(std::move(mod)), loop_(std::move(loop)) {}
+
+  String FastErrorString() const final {
+    return "ScheduleError: Some loop appears in the input array for multiple 
times.";
+  }
+
+  String DetailRenderTemplate() const final {
+    return "Loop {0} appears in the input array for multiple times.";
+  }
+
+  IRModule mod() const final { return mod_; }
+  Array<ObjectRef> LocationsOfInterest() const final { return {loop_}; }
+
+  IRModule mod_;
+  For loop_;
+};
+
+class LoopsNotALineError : public ScheduleError {
+ public:
+  enum ProblemKind { kNotUnderAScope, kHaveNonSingleBranchStmt };
+
+  explicit LoopsNotALineError(IRModule mod, Optional<Stmt> problematic_loop, 
ProblemKind kind)
+      : mod_(std::move(mod)), problematic_loop_(std::move(problematic_loop)), 
kind_(kind) {}
+
+  String FastErrorString() const final { return "ScheduleError: the loops are 
not in a line"; }
+
+  String DetailRenderTemplate() const final {
+    std::stringstream ss;
+    ss << "The loops are not in a line because";
+    if (kind_ == kNotUnderAScope) {
+      ss << " they are not under the same scope.";
+    } else {
+      ss << " there is a non-single-branch stmt in between. Problematic stmt: 
{0}";
+    }
+    return ss.str();
+  }
+
+  IRModule mod() const final { return mod_; }
+  Array<ObjectRef> LocationsOfInterest() const final {
+    if (kind_ == kNotUnderAScope) {
+      return {};
+    } else {
+      ICHECK(problematic_loop_.defined());
+      return {problematic_loop_.value()};
+    }
+  }
+
+  IRModule mod_;
+  Optional<Stmt> problematic_loop_;
+  ProblemKind kind_;
+};
+
+class DependentLoopError : public ScheduleError {
+ public:
+  explicit DependentLoopError(IRModule mod, For loop, String inner_var)
+      : mod_(std::move(mod)), loop_(std::move(loop)), 
inner_var_(std::move(inner_var)) {}
+
+  String FastErrorString() const final {
+    return "ScheduleError: An outer loop's `min` or `extent` is dependent on 
an inner loop "
+           "in the new order";
+  }
+
+  String DetailRenderTemplate() const final {
+    return "Outer Loop {0}'s `min` or `extent` is dependent on an inner loop " 
+ inner_var_ +
+           " in the new order";
+  }
+
+  IRModule mod() const final { return mod_; }
+  Array<ObjectRef> LocationsOfInterest() const final { return {loop_}; }
+
+  IRModule mod_;
+  For loop_;
+  String inner_var_;
+};
+
+/*!
+ * \brief Collect all loops under a specific block scope in the inverse 
pre-order
+ * \param self The state of the schedule
+ * \param root_block_sref the sref to the root of block scope
+ * \return The array of srefs of all loops under the block scope, in inverse 
pre-order
+ */
+std::vector<const StmtSRefNode*> GetLoopsInversePreOrderUnderScope(
+    const ScheduleState& self, const StmtSRef& root_block_sref) {
+  std::vector<const StmtSRefNode*> loops;
+  const BlockNode* root_block = TVM_SREF_TO_BLOCK(root_block, root_block_sref);
+  // Gather all the loops under parent_block
+  PreOrderVisit(root_block->body, [&loops, self](const ObjectRef& node) {
+    // Stops at a new BlockNode
+    if (node->IsInstance<BlockNode>()) {
+      return false;
+    }
+    // Collects every ForNode
+    if (const auto* loop = node.as<ForNode>()) {
+      loops.push_back(self->stmt2ref.at(loop).operator->());
+    }
+    return true;
+  });
+  // Reverse to get inverse preorder
+  std::reverse(loops.begin(), loops.end());
+  return loops;
+}
+/*!
+ * \brief Check that all the blocks under the specific stmt have affine 
bindings and only have
+ *     data-parallel or reduction block iters
+ * \param self The state of the schedule
+ * \param sref The sref to the specific stmt
+ */
+void CheckBlockIterTypeAndAffineBinding(const ScheduleState& self, const 
StmtSRefNode* sref) {

Review comment:
       Move this into `BlockIterTypeError` and rename the error to 
`BlockPropertyError`, where property includes affinity as well as iter types




-- 
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