This is an automated email from the ASF dual-hosted git repository.
syfeng 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 11f8606ef4 Revert "[FFI] Replace `Arg2Str` with a more powerful
`for_each`" (#18121)
11f8606ef4 is described below
commit 11f8606ef4699ebb9b3e84a55a23fce51fcf82af
Author: Tianqi Chen <[email protected]>
AuthorDate: Mon Jul 7 10:47:17 2025 -0400
Revert "[FFI] Replace `Arg2Str` with a more powerful `for_each`" (#18121)
Revert "[FFI] Replace `Arg2Str` with a more powerful `for_each` (#18117)"
This reverts commit 49b139be8b76aef69e537c44b22a8f370cb72901.
---
ffi/include/tvm/ffi/base_details.h | 21 +--------------------
ffi/include/tvm/ffi/function_details.h | 27 +++++++++++++++++++--------
2 files changed, 20 insertions(+), 28 deletions(-)
diff --git a/ffi/include/tvm/ffi/base_details.h
b/ffi/include/tvm/ffi/base_details.h
index d078a5963a..fb7be1a955 100644
--- a/ffi/include/tvm/ffi/base_details.h
+++ b/ffi/include/tvm/ffi/base_details.h
@@ -29,7 +29,6 @@
#include <tvm/ffi/endian.h>
#include <cstddef>
-#include <type_traits>
#include <utility>
#if defined(_MSC_VER)
@@ -136,32 +135,14 @@ namespace tvm {
namespace ffi {
namespace details {
-// a dependent-name version of false, for static_assert
-template <typename>
-inline constexpr bool always_false = false;
-
// for each iterator
struct for_each_dispatcher {
template <typename F, typename... Args, size_t... I>
static void run(std::index_sequence<I...>, const F& f, Args&&... args) { //
NOLINT(*)
- if constexpr (std::conjunction_v<
- std::is_invocable<F, std::integral_constant<size_t, I>,
Args>...>) {
- (f(std::integral_constant<size_t, I>{}, std::forward<Args>(args)), ...);
- } else if constexpr (std::conjunction_v<std::is_invocable<F, size_t,
Args>...>) {
- (f(I, std::forward<Args>(args)), ...);
- } else if constexpr (std::conjunction_v<std::is_invocable<F, Args>...>) {
- (f(std::forward<Args>(args)), ...);
- } else {
- static_assert(always_false<F>, "The function is not invocable with the
provided arguments");
- }
+ (f(I, std::forward<Args>(args)), ...);
}
};
-// Three kinds of function F are acceptable in `for_each`:
-// 1. F(size_t, Arg): argument with its index
-// 2. F(Arg): just the argument
-// 3. F(std::integral_constant<size_t, I>, Arg): argument with its constexpr
index
-// The third one can make the index available in template arguments and `if
constexpr`.
template <typename F, typename... Args>
void for_each(const F& f, Args&&... args) { // NOLINT(*)
for_each_dispatcher::run(std::index_sequence_for<Args...>{}, f,
std::forward<Args>(args)...);
diff --git a/ffi/include/tvm/ffi/function_details.h
b/ffi/include/tvm/ffi/function_details.h
index 34e9979d5d..d029c19dd1 100644
--- a/ffi/include/tvm/ffi/function_details.h
+++ b/ffi/include/tvm/ffi/function_details.h
@@ -36,6 +36,23 @@ namespace tvm {
namespace ffi {
namespace details {
+template <typename ArgType>
+struct Arg2Str {
+ template <size_t i>
+ TVM_FFI_INLINE static void Apply(std::ostream& os) {
+ using Arg = std::tuple_element_t<i, ArgType>;
+ if constexpr (i != 0) {
+ os << ", ";
+ }
+ os << i << ": " << Type2Str<Arg>::v();
+ }
+ template <size_t... I>
+ TVM_FFI_INLINE static void Run(std::ostream& os, std::index_sequence<I...>) {
+ using TExpander = int[];
+ (void)TExpander{0, (Apply<I>(os), 0)...};
+ }
+};
+
template <typename T>
static constexpr bool ArgSupported =
(std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>, Any> ||
@@ -61,16 +78,10 @@ struct FuncFunctorImpl {
#endif
TVM_FFI_INLINE static std::string Sig() {
+ using IdxSeq = std::make_index_sequence<sizeof...(Args)>;
std::ostringstream ss;
ss << "(";
- for_each(
- [&ss](auto i, const auto& v) {
- if constexpr (i() != 0) {
- ss << ", ";
- }
- ss << i() << ": " << v;
- },
- Type2Str<Args>::v()...);
+ Arg2Str<std::tuple<Args...>>::Run(ss, IdxSeq{});
ss << ") -> " << Type2Str<R>::v();
return ss.str();
}