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

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


The following commit(s) were added to refs/heads/main by this push:
     new 8c8b51f02b [Bugfix] Work around "Internal Compiler Error" in MSVC 
(#15385)
8c8b51f02b is described below

commit 8c8b51f02b144f0ad97a2fa6ba1a622dc99cbaf7
Author: Junru Shao <[email protected]>
AuthorDate: Sat Jul 22 16:56:45 2023 -0700

    [Bugfix] Work around "Internal Compiler Error" in MSVC (#15385)
    
    [Bugfix] Work around "Internal Compiler Error" in MSVC (#271)
    
    This PR found a workaround that prevents the nigthly windows pypi
    package of TVM Unity to be released. Basically it splits out a deeply
    nested method into several smaller ones so that MSVC's internal handling
    is supposed to be slightly simpler and less error prone.
---
 src/tir/transforms/compact_buffer_region.cc | 162 ++++++++++++++--------------
 1 file changed, 84 insertions(+), 78 deletions(-)

diff --git a/src/tir/transforms/compact_buffer_region.cc 
b/src/tir/transforms/compact_buffer_region.cc
index 6c6eb169a5..6acfe02a10 100644
--- a/src/tir/transforms/compact_buffer_region.cc
+++ b/src/tir/transforms/compact_buffer_region.cc
@@ -495,86 +495,29 @@ class BufferAccessRegionCollector : public 
StmtExprVisitor {
       access_annotations_;
 };
 
+/*! \brief The storage alignment for a dimension */
+struct DimAlignInfo {
+  /*! \brief The factor of the alignment */
+  int align_factor{0};
+  /*! \brief The offset of the alignment */
+  int align_offset{0};
+};
+
+struct BufferAllocInfo {
+  /*! \brief The buffer access region. */
+  Region region;
+  /*! \brief The storage alignment information. */
+  std::vector<DimAlignInfo> dim_aligns;
+  /*!
+   * \brief The reallocated buffer with minimal size.
+   * \note The value if NullOpt if the buffer do not need reallocate (e.g 
parameter buffer).
+   */
+  Buffer new_buffer;
+};
+
 /*! \brief Reallocate the buffers with minimal region. */
 class BufferCompactor : public StmtExprMutator {
  public:
-  static Stmt Compact(
-      const PrimFunc& f,
-      const std::unordered_map<Buffer, Region, ObjectPtrHash, ObjectPtrEqual>& 
regions,
-      const std::unordered_map<Var, StorageAlignAnnotation, ObjectPtrHash, 
ObjectPtrEqual>&
-          storage_align) {
-    // collect buffer allocation info for no-alias buffers
-    std::unordered_map<Var, BufferAllocInfo, ObjectPtrHash, ObjectPtrEqual> 
buffer_info;
-    for (const auto& kv : regions) {
-      const Buffer& buffer = kv.first;
-
-      // set dim alignment info
-      Region region = kv.second;
-      BufferAllocInfo alloc_info;
-      auto it = storage_align.find(buffer->data);
-      if (it != storage_align.end()) {
-        std::vector<DimAlignInfo> dim_aligns(buffer->shape.size());
-        for (const StorageAlignTuple& dim_align : (*it).second) {
-          ICHECK(dim_align.size() == 4);
-          int dim = dim_align[1]->value;
-          int factor = dim_align[2]->value;
-          int offset = dim_align[3]->value;
-          dim_aligns.at(dim) = {factor, offset};
-        }
-        alloc_info.dim_aligns = std::move(dim_aligns);
-      }
-
-      // prepare new buffer
-      Array<PrimExpr> shape = region.Map([](const Range& range) { return 
range->extent; });
-      Array<PrimExpr> strides;
-      if (alloc_info.dim_aligns.size()) {
-        ICHECK(alloc_info.dim_aligns.size() == shape.size());
-        strides.resize(shape.size());
-        PrimExpr stride = make_const(shape[0].dtype(), 1);
-        for (size_t i = shape.size(); i != 0; --i) {
-          size_t dim = i - 1;
-          if (alloc_info.dim_aligns[dim].align_factor != 0) {
-            PrimExpr factor = make_const(stride.dtype(), 
alloc_info.dim_aligns[dim].align_factor);
-            PrimExpr offset = make_const(stride.dtype(), 
alloc_info.dim_aligns[dim].align_offset);
-            stride = stride + indexmod(factor + offset - indexmod(stride, 
factor), factor);
-          }
-          strides.Set(dim, stride);
-          stride = stride * shape[dim];
-        }
-      }
-      ObjectPtr<BufferNode> n = make_object<BufferNode>(*buffer.get());
-      n->shape = std::move(shape);
-      n->strides = std::move(strides);
-      alloc_info.new_buffer = Buffer(std::move(n));
-      alloc_info.region = region;
-      buffer_info.emplace(buffer->data, std::move(alloc_info));
-    }
-    BufferCompactor compactor(std::move(buffer_info));
-    Stmt stmt = compactor(f->body);
-    return stmt;
-  }
-
- private:
-  /*! \brief The storage alignment for a dimension */
-  struct DimAlignInfo {
-    /*! \brief The factor of the alignment */
-    int align_factor{0};
-    /*! \brief The offset of the alignment */
-    int align_offset{0};
-  };
-
-  struct BufferAllocInfo {
-    /*! \brief The buffer access region. */
-    Region region;
-    /*! \brief The storage alignment information. */
-    std::vector<DimAlignInfo> dim_aligns;
-    /*!
-     * \brief The reallocated buffer with minimal size.
-     * \note The value if NullOpt if the buffer do not need reallocate (e.g 
parameter buffer).
-     */
-    Buffer new_buffer;
-  };
-
   explicit BufferCompactor(
       std::unordered_map<Var, BufferAllocInfo, ObjectPtrHash, ObjectPtrEqual> 
buffer_info)
       : buffer_info_(std::move(buffer_info)) {}
@@ -709,13 +652,76 @@ class BufferCompactor : public StmtExprMutator {
   std::unordered_map<Var, BufferAllocInfo, ObjectPtrHash, ObjectPtrEqual> 
buffer_info_;
 };
 
+Array<PrimExpr> CalcStrides(const BufferAllocInfo& alloc_info, const 
Array<PrimExpr>& shape) {
+  std::vector<PrimExpr> strides;
+  if (alloc_info.dim_aligns.size()) {
+    ICHECK(alloc_info.dim_aligns.size() == shape.size());
+    strides.resize(shape.size());
+    PrimExpr stride = make_const(shape[0].dtype(), 1);
+    for (size_t i = shape.size(); i != 0; --i) {
+      size_t dim = i - 1;
+      DimAlignInfo info = alloc_info.dim_aligns[dim];
+      int align_factor = info.align_factor;
+      int align_offset = info.align_offset;
+      if (align_factor != 0) {
+        PrimExpr factor = make_const(stride.dtype(), align_factor);
+        PrimExpr offset = make_const(stride.dtype(), align_offset);
+        stride = stride + indexmod(factor + offset - indexmod(stride, factor), 
factor);
+      }
+      strides[dim] = stride;
+      stride = stride * shape[dim];
+    }
+  }
+  return strides;
+}
+
+Stmt BufferCompactorCompact(
+    const PrimFunc& f,
+    const std::unordered_map<Buffer, Region, ObjectPtrHash, ObjectPtrEqual>& 
regions,
+    const std::unordered_map<Var, StorageAlignAnnotation, ObjectPtrHash, 
ObjectPtrEqual>&
+        storage_align) {
+  // collect buffer allocation info for no-alias buffers
+  std::unordered_map<Var, BufferAllocInfo, ObjectPtrHash, ObjectPtrEqual> 
buffer_info;
+  for (const auto& kv : regions) {
+    const Buffer& buffer = kv.first;
+    // set dim alignment info
+    Region region = kv.second;
+    BufferAllocInfo alloc_info;
+    auto it = storage_align.find(buffer->data);
+    if (it != storage_align.end()) {
+      std::vector<DimAlignInfo> dim_aligns(buffer->shape.size());
+      for (const StorageAlignTuple& dim_align : (*it).second) {
+        ICHECK(dim_align.size() == 4);
+        int dim = dim_align[1]->value;
+        int factor = dim_align[2]->value;
+        int offset = dim_align[3]->value;
+        dim_aligns.at(dim) = {factor, offset};
+      }
+      alloc_info.dim_aligns = std::move(dim_aligns);
+    }
+
+    // prepare new buffer
+    Array<PrimExpr> shape = region.Map([](const Range& range) { return 
range->extent; });
+    Array<PrimExpr> strides = CalcStrides(alloc_info, shape);
+    ObjectPtr<BufferNode> n = make_object<BufferNode>(*buffer.get());
+    n->shape = std::move(shape);
+    n->strides = std::move(strides);
+    alloc_info.new_buffer = Buffer(std::move(n));
+    alloc_info.region = region;
+    buffer_info.emplace(buffer->data, std::move(alloc_info));
+  }
+  BufferCompactor compactor(std::move(buffer_info));
+  Stmt stmt = compactor(f->body);
+  return stmt;
+}
+
 PrimFunc CompactBufferAllocation(PrimFunc f, bool is_strict) {
   // Only apply this pass to TIR that is not from TE schedules
   if (!IsFromLegacyTESchedule(f)) {
     PrimFuncNode* fptr = f.CopyOnWrite();
     auto region = BufferAccessRegionCollector::Collect(f, 
/*collect_inbound=*/is_strict);
     auto storage_align = CollectStorageAlignAnnotation(f->body);
-    fptr->body = BufferCompactor::Compact(f, region, storage_align);
+    fptr->body = BufferCompactorCompact(f, region, storage_align);
     return f;
   } else {
     return f;

Reply via email to