Skip to content

Commit 5ddc5bc

Browse files
authored
[FFI][REFACTOR] Update TVM_FFI_STATIC_INIT_BLOCK to fn style (#18312)
This PR updates TVM_FFI_STATIC_INIT_BLOCK to function style. Now we do the code as follows, which is cleaner in generally and also helps error reporting to locate the right place. ``` TVM_FFI_STATIC_INIT_BLOCK() { RegisterStaffs(); } ```
1 parent 678984f commit 5ddc5bc

File tree

543 files changed

+2241
-2209
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

543 files changed

+2241
-2209
lines changed

apps/cpp_rpc/rpc_server.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,9 @@ void RPCServerCreate(std::string host, int port, int port_end, std::string track
399399
rpc.Start();
400400
}
401401

402-
TVM_FFI_STATIC_INIT_BLOCK({
402+
TVM_FFI_STATIC_INIT_BLOCK() {
403403
namespace refl = tvm::ffi::reflection;
404404
refl::GlobalDef().def("rpc.ServerCreate", RPCServerCreate);
405-
});
405+
}
406406
} // namespace runtime
407407
} // namespace tvm

apps/ios_rpc/tvmrpc/TVMRuntime.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void LogMessageImpl(const std::string& file, int lineno, int level, const std::s
5252

5353
} // namespace detail
5454

55-
TVM_FFI_STATIC_INIT_BLOCK({
55+
TVM_FFI_STATIC_INIT_BLOCK() {
5656
namespace refl = tvm::ffi::reflection;
5757
refl::GlobalDef()
5858
.def_packed("tvm.rpc.server.workpath",
@@ -85,7 +85,7 @@ void LogMessageImpl(const std::string& file, int lineno, int level, const std::s
8585
*rv = Module::LoadFromFile(name, fmt);
8686
LOG(INFO) << "Load module from " << name << " ...";
8787
});
88-
});
88+
}
8989

9090
#if defined(USE_CUSTOM_DSO_LOADER) && USE_CUSTOM_DSO_LOADER == 1
9191

@@ -112,15 +112,15 @@ void Init(const std::string& name) {
112112
};
113113

114114
// Add UnsignedDSOLoader plugin in global registry
115-
TVM_FFI_STATIC_INIT_BLOCK({
115+
TVM_FFI_STATIC_INIT_BLOCK() {
116116
namespace refl = tvm::ffi::reflection;
117117
refl::GlobalDef().def_packed("ffi.Module.load_from_file.dylib_custom",
118118
[](ffi::PackedArgs args, ffi::Any* rv) {
119119
auto n = ffi::make_object<UnsignedDSOLoader>();
120120
n->Init(args[0]);
121121
*rv = tvm::ffi::CreateLibraryModule(n);
122122
});
123-
});
123+
}
124124

125125
#endif
126126

docs/arch/device_target_interactions.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ then be registered with the following steps.
153153

154154
#. Register the function to the tvm registry::
155155

156-
TVM_FFI_STATIC_INIT_BLOCK({
156+
TVM_FFI_STATIC_INIT_BLOCK() {
157157
namespace refl = tvm::ffi::reflection;
158158
refl::GlobalDef().def("device_api.foo", FooDeviceAPI::Global);
159-
});
159+
}
160160

161161
.. _base.h: https://github.com/apache/tvm/blob/main/include/tvm/runtime/base.h
162162

@@ -228,10 +228,10 @@ the same name as was used in the ``TVM_REGISTER_TARGET_KIND``
228228
definition above. ::
229229

230230
tvm::runtime::Module GeneratorFooCode(IRModule mod, Target target);
231-
TVM_FFI_STATIC_INIT_BLOCK({
231+
TVM_FFI_STATIC_INIT_BLOCK() {
232232
namespace refl = tvm::ffi::reflection;
233233
refl::GlobalDef().def("target.build.foo", GeneratorFooCode);
234-
});
234+
}
235235

236236
The code generator takes two arguments. The first is the ``IRModule``
237237
to compile, and the second is the ``Target`` that describes the device

docs/arch/pass_infra.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,10 @@ Python when needed.
376376
return CreateFunctionPass(pass_func, 0, "FoldConstant", {});
377377
}
378378

379-
TVM_FFI_STATIC_INIT_BLOCK({
379+
TVM_FFI_STATIC_INIT_BLOCK() {
380380
namespace refl = tvm::ffi::reflection;
381381
refl::GlobalDef().def("relax.transform.FoldConstant", FoldConstant);
382-
});
382+
}
383383

384384
} // namespace transform
385385

docs/arch/runtime.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ The following example registers PackedFunc in C++ and calls from python.
8080
.. code:: c
8181
8282
// register a global packed function in c++
83-
TVM_FFI_STATIC_INIT_BLOCK({
83+
TVM_FFI_STATIC_INIT_BLOCK() {
8484
namespace refl = tvm::ffi::reflection;
8585
refl::GlobalDef().def_packed("myadd", MyAdd);
86-
});
86+
}
8787
8888
.. code:: python
8989
@@ -112,13 +112,13 @@ we can pass functions from python (as PackedFunc) to C++.
112112

113113
.. code:: c
114114
115-
TVM_FFI_STATIC_INIT_BLOCK({
115+
TVM_FFI_STATIC_INIT_BLOCK() {
116116
namespace refl = tvm::ffi::reflection;
117117
refl::GlobalDef().def_packed("callhello", [](ffi::PackedArgs args, ffi::Any* rv) {
118118
ffi::Function f = args[0].cast<ffi::Function>();
119119
f("hello world");
120120
});
121-
});
121+
}
122122
123123
.. code:: python
124124
@@ -230,7 +230,7 @@ Each ``Object`` subclass will override this to register its members. Here is an
230230
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.IntImm", IntImmNode, PrimExprNode);
231231
};
232232
// in cc file
233-
TVM_FFI_STATIC_INIT_BLOCK({ IntImmNode::RegisterReflection(); });
233+
TVM_FFI_STATIC_INIT_BLOCK() { IntImmNode::RegisterReflection(); }
234234
235235
The RegisterReflection gives us a reflection API to register each member of the object.
236236
We can use this function to visit the node and serialize any language object recursively.

ffi/docs/guides/packaging.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,11 @@ void RaiseError(ffi::String msg) {
161161
TVM_FFI_THROW(RuntimeError) << msg;
162162
}
163163
164-
TVM_FFI_STATIC_INIT_BLOCK({
164+
TVM_FFI_STATIC_INIT_BLOCK() {
165165
namespace refl = tvm::ffi::reflection;
166166
refl::GlobalDef()
167167
.def("my_ffi_extension.raise_error", RaiseError);
168-
});
168+
}
169169
```
170170

171171
Make sure to have a unique name across all registered functions when registering a global function.

ffi/docs/guides/python_guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ public:
203203
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TestIntPair, tvm::ffi::ObjectRef, TestIntPairObj);
204204
};
205205

206-
TVM_FFI_STATIC_INIT_BLOCK({
206+
TVM_FFI_STATIC_INIT_BLOCK() {
207207
namespace refl = tvm::ffi::reflection;
208208
// register the object into the system
209209
// register field accessors and a global static function `__create__` as ffi::Function
@@ -213,7 +213,7 @@ TVM_FFI_STATIC_INIT_BLOCK({
213213
.def_static("__create__", [](int64_t a, int64_t b) -> TestIntPair {
214214
return TestIntPair(a, b);
215215
});
216-
});
216+
}
217217
```
218218
219219
You can then create wrapper classes for objects that are in the library as follows:

ffi/examples/packaging/src/extension.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ TVM_FFI_DLL_EXPORT_TYPED_FUNC(add_one, my_ffi_extension::AddOne);
6262

6363
// The static initialization block is
6464
// called once when the library is loaded.
65-
TVM_FFI_STATIC_INIT_BLOCK({
65+
TVM_FFI_STATIC_INIT_BLOCK() {
6666
namespace refl = tvm::ffi::reflection;
6767
// In this particular example, we use the reflection mechanisms to
6868
// register the functions directly into the global function table.
@@ -85,5 +85,5 @@ TVM_FFI_STATIC_INIT_BLOCK({
8585
// tvm::ffi::Module::LoadFromFile, instead, just load the dll or simply bundle into the
8686
// final project
8787
refl::GlobalDef().def("my_ffi_extension.raise_error", RaiseError);
88-
});
88+
}
8989
} // namespace my_ffi_extension

ffi/include/tvm/ffi/base_details.h

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@
7272
#define TVM_FFI_UNREACHABLE() __builtin_unreachable()
7373
#endif
7474

75-
/*! \brief helper macro to suppress unused warning */
76-
#define TVM_FFI_ATTRIBUTE_UNUSED [[maybe_unused]]
77-
7875
#define TVM_FFI_STR_CONCAT_(__x, __y) __x##__y
7976
#define TVM_FFI_STR_CONCAT(__x, __y) TVM_FFI_STR_CONCAT_(__x, __y)
8077

@@ -86,12 +83,39 @@
8683
#define TVM_FFI_FUNC_SIG __func__
8784
#endif
8885

89-
#define TVM_FFI_STATIC_INIT_BLOCK_VAR_DEF \
90-
TVM_FFI_ATTRIBUTE_UNUSED static inline int __##TVMFFIStaticInitReg
86+
#if defined(__GNUC__)
87+
// gcc and clang and attribute constructor
88+
/// \cond Doxygen_Suppress
89+
#define TVM_FFI_STATIC_INIT_BLOCK_DEF_(FnName) __attribute__((constructor)) static void FnName()
90+
/// \endcond
91+
/*
92+
* \brief Macro that defines a block that will be called during static initialization.
93+
*
94+
* \code
95+
* TVM_FFI_STATIC_INIT_BLOCK() {
96+
* RegisterFunctions();
97+
* }
98+
* \endcode
99+
*/
100+
#define TVM_FFI_STATIC_INIT_BLOCK() \
101+
TVM_FFI_STATIC_INIT_BLOCK_DEF_(TVM_FFI_STR_CONCAT(__TVMFFIStaticInitFunc, __COUNTER__))
91102

92-
/*! \brief helper macro to run code once during initialization */
93-
#define TVM_FFI_STATIC_INIT_BLOCK(Body) \
94-
TVM_FFI_STR_CONCAT(TVM_FFI_STATIC_INIT_BLOCK_VAR_DEF, __COUNTER__) = []() { Body return 0; }()
103+
#else
104+
/// \cond Doxygen_Suppress
105+
// for other compilers, use the variable trick
106+
#define TVM_FFI_STATIC_INIT_BLOCK_DEF_(FnName, RegVar) \
107+
static void FnName(); \
108+
[[maybe_unused]] static inline int RegVar = []() { \
109+
FnName(); \
110+
return 0; \
111+
}(); \
112+
static void FnName()
113+
114+
#define TVM_FFI_STATIC_INIT_BLOCK() \
115+
TVM_FFI_STATIC_INIT_BLOCK_DEF_(TVM_FFI_STR_CONCAT(__TVMFFIStaticInitFunc, __COUNTER__), \
116+
TVM_FFI_STR_CONCAT(__TVMFFIStaticInitReg, __COUNTER__))
117+
/// \endcond
118+
#endif
95119

96120
/*
97121
* \brief Define the default copy/move constructor and assign operator

0 commit comments

Comments
 (0)