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 7ab970d38e [Lint] Add check to prevent usage of #include <regex> 
(#16412)
7ab970d38e is described below

commit 7ab970d38e2dc14b6c8b77dea0d560e6ccc38f19
Author: Eric Lunderberg <[email protected]>
AuthorDate: Sun Mar 10 11:01:50 2024 -0500

    [Lint] Add check to prevent usage of #include <regex> (#16412)
    
    Currently, the pytorch wheels available through `pip install` use the
    pre-C++11 ABI by setting `-DUSE_CXX11_ABI=0` [0].  If TVM were to user
    the pre-C++11 ABI, this would cause breakages with dynamically-linked
    LLVM environments.
    
    This commit adds a lint check to search for use of `#include <regex>`
    in any C++ files.  Use of this header should be avoided, as its
    implementation is not supported by gcc's dual ABI.  This ABI
    incompatibility results in runtime errors either when `std::regex` is
    called from TVM, or when `std::regex` is called from pytorch,
    depending on which library was loaded first.
    
    This restriction can be removed when a version of pytorch compiled
    using `-DUSE_CXX11_ABI=1` is available from PyPI.
    
    [0] https://github.com/pytorch/pytorch/issues/51039
---
 python/tvm/runtime/__init__.py                  |  2 +
 python/tvm/runtime/support.py                   | 69 +++++++++++++++++++++++++
 python/tvm/support.py                           | 44 ----------------
 src/ir/transform.cc                             |  9 +---
 src/relax/transform/update_param_struct_info.cc |  2 +-
 src/relay/backend/contrib/dnnl/codegen.cc       |  1 -
 src/relay/backend/contrib/dnnl/query_layout.cc  | 18 +++----
 src/relay/backend/contrib/mrvl/codegen.cc       |  1 -
 src/runtime/contrib/dnnl/dnnl_json_runtime.cc   | 63 +++++++++++-----------
 src/runtime/regex.cc                            | 41 +++++++++++++++
 src/runtime/regex.h                             | 64 +++++++++++++++++++++++
 tests/lint/cpplint.sh                           | 10 ++++
 12 files changed, 230 insertions(+), 94 deletions(-)

diff --git a/python/tvm/runtime/__init__.py b/python/tvm/runtime/__init__.py
index 3a68c567ee..f182cd9bfd 100644
--- a/python/tvm/runtime/__init__.py
+++ b/python/tvm/runtime/__init__.py
@@ -41,3 +41,5 @@ from .params import (
 
 from . import executor
 from . import disco
+
+from .support import _regex_match
diff --git a/python/tvm/runtime/support.py b/python/tvm/runtime/support.py
new file mode 100644
index 0000000000..3716460a27
--- /dev/null
+++ b/python/tvm/runtime/support.py
@@ -0,0 +1,69 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""Runtime support infra of TVM."""
+
+import re
+
+import tvm._ffi
+
+
+@tvm._ffi.register_func("tvm.runtime.regex_match")
+def _regex_match(regex_pattern: str, match_against: str) -> bool:
+    """Check if a pattern matches a regular expression
+
+    This function should be used instead of `std::regex` within C++
+    call sites, to avoid ABI incompatibilities with pytorch.
+
+    Currently, the pytorch wheels available through pip install use
+    the pre-C++11 ABI by setting `-DUSE_CXX11_ABI=0` [0]. If TVM were to
+    user the pre-C++11 ABI, this would cause breakages with
+    dynamically-linked LLVM environments.
+
+    Use of the `<regex>` header in TVM should be avoided, as its
+    implementation is not supported by gcc's dual ABI. This ABI
+    incompatibility results in runtime errors either when `std::regex`
+    is called from TVM, or when `std::regex` is called from pytorch,
+    depending on which library was loaded first.  This restriction can
+    be removed when a version of pytorch compiled using
+    `-DUSE_CXX11_ABI=1` is available from PyPI.
+
+    This is exposed as part of `libtvm_runtime.so` as it is used by
+    the DNNL runtime.
+
+    [0] https://github.com/pytorch/pytorch/issues/51039
+
+    Parameters
+    ----------
+    regex_pattern: str
+
+         The regular expression
+
+    match_against: str
+
+        The string against which to match the regular expression
+
+    Returns
+    -------
+    match_result: bool
+
+        True if `match_against` matches the pattern defined by
+        `regex_pattern`, and False otherwise.
+
+    """
+    match = re.match(regex_pattern, match_against)
+    return match is not None
diff --git a/python/tvm/support.py b/python/tvm/support.py
index 4fa95fac89..a50a5e7b57 100644
--- a/python/tvm/support.py
+++ b/python/tvm/support.py
@@ -19,7 +19,6 @@ import json
 import textwrap
 import ctypes
 import os
-import re
 import sys
 
 import tvm
@@ -88,46 +87,3 @@ class FrontendTestModule(Module):
 
     def __setitem__(self, key, value):
         self.add_function(key, value)
-
-
-@tvm._ffi.register_func("tvm.support.regex_match")
-def _regex_match(regex_pattern: str, match_against: str) -> bool:
-    """Check if a pattern matches a regular expression
-
-    This function should be used instead of `std::regex` within C++
-    call sites, to avoid ABI incompatibilities with pytorch.
-
-    Currently, the pytorch wheels available through pip install use
-    the pre-C++11 ABI by setting `-DUSE_CXX11_ABI=0` [0]. If TVM were to
-    user the pre-C++11 ABI, this would cause breakages with
-    dynamically-linked LLVM environments.
-
-    Use of the `<regex>` header in TVM should be avoided, as its
-    implementation is not supported by gcc's dual ABI. This ABI
-    incompatibility results in runtime errors either when `std::regex`
-    is called from TVM, or when `std::regex` is called from pytorch,
-    depending on which library was loaded first.  This restriction can
-    be removed when a version of pytorch compiled using
-    `-DUSE_CXX11_ABI=1` is available from PyPI.
-
-    [0] https://github.com/pytorch/pytorch/issues/51039
-
-    Parameters
-    ----------
-    regex_pattern: str
-
-         The regular expression
-
-    match_against: str
-
-        The string against which to match the regular expression
-
-    Returns
-    -------
-    match_result: bool
-
-        True if `match_against` matches the pattern defined by
-        `regex_pattern`, and False otherwise.
-    """
-    match = re.match(regex_pattern, match_against)
-    return match is not None
diff --git a/src/ir/transform.cc b/src/ir/transform.cc
index 766bd28875..3eb64fec84 100644
--- a/src/ir/transform.cc
+++ b/src/ir/transform.cc
@@ -35,6 +35,7 @@
 #include <unordered_set>
 
 #include "../runtime/object_internal.h"
+#include "../runtime/regex.h"
 
 namespace tvm {
 namespace transform {
@@ -538,17 +539,11 @@ Pass ApplyPassToFunction(Pass pass, String 
func_name_regex,
           .str();
 
   auto pass_func = [pass, func_name_regex](IRModule mod, PassContext) -> 
IRModule {
-    const auto* regex_match_func = 
tvm::runtime::Registry::Get("tvm.support.regex_match");
-    CHECK(regex_match_func)
-        << "RuntimeError: "
-        << "The PackedFunc 'tvm.support.regex_match' has not been registered.  
"
-        << "This can occur if the TVM Python library has not yet been 
imported.";
-
     IRModule subset;
 
     for (const auto& [gvar, func] : mod->functions) {
       std::string name = gvar->name_hint;
-      if ((*regex_match_func)(func_name_regex, name)) {
+      if (tvm::runtime::regex_match(name, func_name_regex)) {
         subset->Add(gvar, func);
       }
     }
diff --git a/src/relax/transform/update_param_struct_info.cc 
b/src/relax/transform/update_param_struct_info.cc
index 327185fd0b..b3fa0464be 100644
--- a/src/relax/transform/update_param_struct_info.cc
+++ b/src/relax/transform/update_param_struct_info.cc
@@ -27,10 +27,10 @@
 #include <tvm/relax/transform.h>
 
 #include <optional>
-#include <regex>
 #include <unordered_map>
 #include <vector>
 
+#include "../../runtime/regex.h"
 #include "utils.h"
 
 namespace tvm {
diff --git a/src/relay/backend/contrib/dnnl/codegen.cc 
b/src/relay/backend/contrib/dnnl/codegen.cc
index 9a9ed5f83d..3b7bc8f10d 100644
--- a/src/relay/backend/contrib/dnnl/codegen.cc
+++ b/src/relay/backend/contrib/dnnl/codegen.cc
@@ -31,7 +31,6 @@
 
 #include <fstream>
 #include <numeric>
-#include <regex>
 #include <sstream>
 
 #include "../../utils.h"
diff --git a/src/relay/backend/contrib/dnnl/query_layout.cc 
b/src/relay/backend/contrib/dnnl/query_layout.cc
index 63e0d73ce2..2660481e00 100755
--- a/src/relay/backend/contrib/dnnl/query_layout.cc
+++ b/src/relay/backend/contrib/dnnl/query_layout.cc
@@ -31,10 +31,10 @@
 
 #include <fstream>
 #include <numeric>
-#include <regex>
 #include <sstream>
 
 #include "../../../../runtime/contrib/dnnl/dnnl_utils.h"
+#include "../../../../runtime/regex.h"
 #include "../../utils.h"
 #include "dnnl.hpp"
 namespace tvm {
@@ -173,12 +173,12 @@ dnnl::memory::dims str2dims(const std::string& str_shape, 
bool dilates = false,
 }
 
 void check_shapes(const std::vector<std::string> shapes) {
-  std::regex valid_pat("(\\d*)(,(\\d*))*");
-  bool checked = std::regex_match(shapes[0], valid_pat);
+  std::string valid_pat("(\\d*)(,(\\d*))*");
+  bool checked = tvm::runtime::regex_match(shapes[0], valid_pat);
   for (size_t i = 1; i < shapes.size() - 1; i++) {
-    checked &= std::regex_match(shapes[i], valid_pat);
+    checked &= tvm::runtime::regex_match(shapes[i], valid_pat);
   }
-  checked &= std::regex_match(shapes[shapes.size() - 1], std::regex("\\d*"));
+  checked &= tvm::runtime::regex_match(shapes[shapes.size() - 1], "\\d*");
   if (!checked) {
     LOG(FATAL) << "Invalid input args for query dnnl optimal layout.";
   }
@@ -194,8 +194,8 @@ std::string get_optimal_layout_for_conv(std::string 
data_layout, std::string ker
                                         std::string weight_shape, std::string 
out_shape,
                                         std::string paddings, std::string 
strides,
                                         std::string dilates, std::string G, 
std::string dtype) {
-  check_layout(std::regex_match(data_layout, std::regex("NC(D?)(H?)W")), true);
-  check_layout(std::regex_match(kernel_layout, std::regex("(G?)OI(D?)(H?)W")), 
true);
+  check_layout(tvm::runtime::regex_match(data_layout, "NC(D?)(H?)W"), true);
+  check_layout(tvm::runtime::regex_match(kernel_layout, "(G?)OI(D?)(H?)W"), 
true);
   check_shapes({weight_shape, out_shape, paddings, strides, dilates, G});
 
   dnnl::engine eng(dnnl::engine::kind::cpu, 0);
@@ -278,8 +278,8 @@ std::string 
get_optimal_layout_for_conv_transpose(std::string data_layout,
                                                   std::string paddings, 
std::string output_paddings,
                                                   std::string strides, 
std::string dilates,
                                                   std::string G, std::string 
dtype) {
-  check_layout(std::regex_match(data_layout, std::regex("NC(D?)(H?)W")), true);
-  check_layout(std::regex_match(kernel_layout, 
std::regex("(G?)((IO)|(OI))(D?)(H?)W")), true);
+  check_layout(tvm::runtime::regex_match(data_layout, "NC(D?)(H?)W"), true);
+  check_layout(tvm::runtime::regex_match(kernel_layout, 
"(G?)((IO)|(OI))(D?)(H?)W"), true);
   check_shapes({weight_shape, out_shape, paddings, output_paddings, strides, 
dilates, G});
 
   dnnl::engine eng(dnnl::engine::kind::cpu, 0);
diff --git a/src/relay/backend/contrib/mrvl/codegen.cc 
b/src/relay/backend/contrib/mrvl/codegen.cc
index 527b53acf4..d395de6694 100644
--- a/src/relay/backend/contrib/mrvl/codegen.cc
+++ b/src/relay/backend/contrib/mrvl/codegen.cc
@@ -31,7 +31,6 @@
 #include <iostream>
 #include <limits>
 #include <memory>
-#include <regex>
 #include <string>
 #include <unordered_map>
 #include <utility>
diff --git a/src/runtime/contrib/dnnl/dnnl_json_runtime.cc 
b/src/runtime/contrib/dnnl/dnnl_json_runtime.cc
index 0b674f08f2..f29628d56b 100644
--- a/src/runtime/contrib/dnnl/dnnl_json_runtime.cc
+++ b/src/runtime/contrib/dnnl/dnnl_json_runtime.cc
@@ -26,10 +26,10 @@
 #include <tvm/runtime/registry.h>
 
 #include <cstddef>
-#include <regex>
 #include <string>
 #include <vector>
 
+#include "../../../runtime/regex.h"
 #include "../json/json_node.h"
 #include "../json/json_runtime.h"
 
@@ -194,45 +194,45 @@ class DNNLJSONRuntime : public JSONRuntimeBase {
     if (o_scl_tr || activation[0] != "none" || sum_scl_tr || dst_zp_tr) return 
attr;
 
     // Define RegExp.
-    std::regex bias_add_pat(".*_bias.*");
-    std::regex relu_pat(".*_relu.*");
-    std::regex tanh_pat(".*_tanh.*");
-    std::regex sigmoid_pat(".*_sigmoid.*");
-    std::regex clip_pat(".*_clip.*");
-    std::regex gelu_pat(".*_gelu.*");
-    std::regex swish_pat(".*_swish.*");
-    std::regex sum_pat(".*_sum.*");
-    std::regex mish_pat(".*_mish.*");
+    std::string bias_add_pat(".*_bias.*");
+    std::string relu_pat(".*_relu.*");
+    std::string tanh_pat(".*_tanh.*");
+    std::string sigmoid_pat(".*_sigmoid.*");
+    std::string clip_pat(".*_clip.*");
+    std::string gelu_pat(".*_gelu.*");
+    std::string swish_pat(".*_swish.*");
+    std::string sum_pat(".*_sum.*");
+    std::string mish_pat(".*_mish.*");
 
     // parsing of name to extract attributes
     auto op_name = nodes_[nid].GetOpName();
 
     // Parsing post-ops.
     dnnl::post_ops ops;
-    if (std::regex_match(op_name, sum_pat)) {
+    if (tvm::runtime::regex_match(op_name, sum_pat)) {
       ops.append_sum(1.f);
     }
-    if (std::regex_match(op_name, relu_pat)) {
+    if (tvm::runtime::regex_match(op_name, relu_pat)) {
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_relu, 0.f, 0.f);
     }
-    if (std::regex_match(op_name, tanh_pat)) {
+    if (tvm::runtime::regex_match(op_name, tanh_pat)) {
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_tanh, 0.f, 0.f);
     }
-    if (std::regex_match(op_name, clip_pat)) {
+    if (tvm::runtime::regex_match(op_name, clip_pat)) {
       float a_min = GetNodeAttr<float>(nodes_[nid], "a_min");
       float a_max = GetNodeAttr<float>(nodes_[nid], "a_max");
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_clip, a_min, a_max);
     }
-    if (std::regex_match(op_name, sigmoid_pat)) {
+    if (tvm::runtime::regex_match(op_name, sigmoid_pat)) {
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_logistic, 0.f, 0.f);
     }
-    if (std::regex_match(op_name, swish_pat)) {
+    if (tvm::runtime::regex_match(op_name, swish_pat)) {
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_swish, 1.f, 1.f);
     }
-    if (std::regex_match(op_name, gelu_pat)) {
+    if (tvm::runtime::regex_match(op_name, gelu_pat)) {
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_gelu_erf, 0.f, 0.f);
     }
-    if (std::regex_match(op_name, mish_pat)) {
+    if (tvm::runtime::regex_match(op_name, mish_pat)) {
       ops.append_eltwise(1.f, dnnl::algorithm::eltwise_mish, 1.f, 0.f);
     }
     if (ops.len() != 0) {
@@ -240,7 +240,8 @@ class DNNLJSONRuntime : public JSONRuntimeBase {
     }
 
     // Parsing bias_add.
-    *bias_tr = std::regex_match(op_name, bias_add_pat) ? GetInput(nid, 2) : 
TensorRequisite{};
+    *bias_tr =
+        tvm::runtime::regex_match(op_name, bias_add_pat) ? GetInput(nid, 2) : 
TensorRequisite{};
 
     return attr;
   }
@@ -253,12 +254,12 @@ class DNNLJSONRuntime : public JSONRuntimeBase {
     std::set<uint32_t> io_eid_set(run_arg_eid_.begin(), run_arg_eid_.end());
     tensor_registry_ = TensorRegistry(engine_, io_eid_set);
 
-    std::regex conv_pat(".*conv[1-3]d.*");
-    std::regex deconv_pat(".*deconv[1-3]d.*");
-    std::regex conv_transpose_pat(".*conv[1-3]d_transpose.*");
-    std::regex dense_pat(".*dense.*");
-    std::regex max_pool_pat(".*max_pool[1-3]d");
-    std::regex avg_pool_pat(".*avg_pool[1-3]d");
+    std::string conv_pat(".*conv[1-3]d.*");
+    std::string deconv_pat(".*deconv[1-3]d.*");
+    std::string conv_transpose_pat(".*conv[1-3]d_transpose.*");
+    std::string dense_pat(".*dense.*");
+    std::string max_pool_pat(".*max_pool[1-3]d");
+    std::string avg_pool_pat(".*avg_pool[1-3]d");
 
     // Build subgraph engine.
     for (size_t nid = 0; nid < nodes_.size(); ++nid) {
@@ -266,18 +267,18 @@ class DNNLJSONRuntime : public JSONRuntimeBase {
       if (node.GetOpType() == "kernel") {
         ICHECK_EQ(node.GetOpType(), "kernel");
         auto op_name = node.GetOpName();
-        if (std::regex_match(op_name, deconv_pat) ||
-            std::regex_match(op_name, conv_transpose_pat)) {
+        if (tvm::runtime::regex_match(op_name, deconv_pat) ||
+            tvm::runtime::regex_match(op_name, conv_transpose_pat)) {
           Deconvolution(nid);
-        } else if (std::regex_match(op_name, conv_pat)) {
+        } else if (tvm::runtime::regex_match(op_name, conv_pat)) {
           Convolution(nid);
-        } else if (std::regex_match(op_name, dense_pat)) {
+        } else if (tvm::runtime::regex_match(op_name, dense_pat)) {
           Dense(nid);
         } else if ("nn.batch_norm" == op_name) {
           BatchNorm(nid);
-        } else if (std::regex_match(op_name, max_pool_pat)) {
+        } else if (tvm::runtime::regex_match(op_name, max_pool_pat)) {
           Pooling(nid, dnnl::algorithm::pooling_max);
-        } else if (std::regex_match(op_name, avg_pool_pat)) {
+        } else if (tvm::runtime::regex_match(op_name, avg_pool_pat)) {
           Pooling(nid, dnnl::algorithm::pooling_avg);
         } else if (elt_name2algo.count(op_name)) {
           Eltwise(nid);
diff --git a/src/runtime/regex.cc b/src/runtime/regex.cc
new file mode 100644
index 0000000000..ef6c068edf
--- /dev/null
+++ b/src/runtime/regex.cc
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file src/runtime/regex.cc
+ * \brief Exposes calls to python's `re` library.
+ */
+
+#include "./regex.h"
+
+#include <tvm/runtime/registry.h>
+
+namespace tvm {
+namespace runtime {
+
+bool regex_match(const std::string& match_against, const std::string& 
regex_pattern) {
+  const auto* regex_match_func = 
tvm::runtime::Registry::Get("tvm.runtime.regex_match");
+  CHECK(regex_match_func) << "RuntimeError: "
+                          << "The PackedFunc 'tvm.runtime.regex_match' has not 
been registered.  "
+                          << "This can occur if the TVM Python library has not 
yet been imported.";
+  return (*regex_match_func)(regex_pattern, match_against);
+}
+
+}  // namespace runtime
+}  // namespace tvm
diff --git a/src/runtime/regex.h b/src/runtime/regex.h
new file mode 100644
index 0000000000..a072700c91
--- /dev/null
+++ b/src/runtime/regex.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file regex.h
+ * \brief Exposes calls to python's `re` library.
+ */
+#ifndef TVM_RUNTIME_REGEX_H_
+#define TVM_RUNTIME_REGEX_H_
+
+#include <string>
+
+namespace tvm {
+namespace runtime {
+
+/* \brief Check if a pattern matches a regular expression
+ *
+ * This function should be used instead of `std::regex` within C++
+ * call sites, to avoid ABI incompatibilities with pytorch.
+ *
+ * Currently, the pytorch wheels available through pip install use
+ * the pre-C++11 ABI by setting `-DUSE_CXX11_ABI=0` [0]. If TVM were to
+ * user the pre-C++11 ABI, this would cause breakages with
+ * dynamically-linked LLVM environments.
+ *
+ * Use of the `<regex>` header in TVM should be avoided, as its
+ * implementation is not supported by gcc's dual ABI. This ABI
+ * incompatibility results in runtime errors either when `std::regex`
+ * is called from TVM, or when `std::regex` is called from pytorch,
+ * depending on which library was loaded first.  This restriction can
+ * be removed when a version of pytorch compiled using
+ * `-DUSE_CXX11_ABI=1` is available from PyPI.
+ *
+ * [0] https://github.com/pytorch/pytorch/issues/51039
+ *
+ * \param match_against The string against which to match the regular 
expression
+ *
+ * \param regex_pattern The regular expression
+ *
+ * \returns match_result True if `match_against` matches the pattern
+ *     defined by `regex_pattern`, and False otherwise.
+ */
+
+bool regex_match(const std::string& match_against, const std::string& 
regex_pattern);
+
+}  // namespace runtime
+}  // namespace tvm
+#endif  // TVM_RUNTIME_REGEX_H_
diff --git a/tests/lint/cpplint.sh b/tests/lint/cpplint.sh
index 38c30b2ed6..b948c91c1e 100755
--- a/tests/lint/cpplint.sh
+++ b/tests/lint/cpplint.sh
@@ -28,3 +28,13 @@ python3 3rdparty/dmlc-core/scripts/lint.py --quiet tvm cpp \
                        "src/runtime/hexagon/rpc/hexagon_rpc_skel.c" \
                        "src/runtime/hexagon/rpc/hexagon_rpc_stub.c" \
                        "src/relay/backend/contrib/libtorch/libtorch_codegen.cc"
+
+
+if find src -name "*.cc" -exec grep -Hn '^#include <regex>$' {} +; then
+    echo "The <regex> header file may not be used in TVM," 1>&2
+    echo "because it causes ABI incompatibility with most pytorch 
installations." 1>&2
+    echo "Pytorch packages on PyPI currently set `-DUSE_CXX11_ABI=0`," 1>&2
+    echo "which causes ABI compatibility when calling <regex> functions." 1>&2
+    echo "See https://github.com/pytorch/pytorch/issues/51039 for more 
details." 1>&2
+    exit 1
+fi

Reply via email to