1*da0073e9SAndroid Build Coastguard Worker #ifndef C10_UTIL_REGISTRY_H_
2*da0073e9SAndroid Build Coastguard Worker #define C10_UTIL_REGISTRY_H_
3*da0073e9SAndroid Build Coastguard Worker
4*da0073e9SAndroid Build Coastguard Worker /**
5*da0073e9SAndroid Build Coastguard Worker * Simple registry implementation that uses static variables to
6*da0073e9SAndroid Build Coastguard Worker * register object creators during program initialization time.
7*da0073e9SAndroid Build Coastguard Worker */
8*da0073e9SAndroid Build Coastguard Worker
9*da0073e9SAndroid Build Coastguard Worker // NB: This Registry works poorly when you have other namespaces.
10*da0073e9SAndroid Build Coastguard Worker // Make all macro invocations from inside the at namespace.
11*da0073e9SAndroid Build Coastguard Worker
12*da0073e9SAndroid Build Coastguard Worker #include <cstdio>
13*da0073e9SAndroid Build Coastguard Worker #include <cstdlib>
14*da0073e9SAndroid Build Coastguard Worker #include <functional>
15*da0073e9SAndroid Build Coastguard Worker #include <memory>
16*da0073e9SAndroid Build Coastguard Worker #include <mutex>
17*da0073e9SAndroid Build Coastguard Worker #include <stdexcept>
18*da0073e9SAndroid Build Coastguard Worker #include <string>
19*da0073e9SAndroid Build Coastguard Worker #include <unordered_map>
20*da0073e9SAndroid Build Coastguard Worker #include <vector>
21*da0073e9SAndroid Build Coastguard Worker
22*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Export.h>
23*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Macros.h>
24*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Type.h>
25*da0073e9SAndroid Build Coastguard Worker
26*da0073e9SAndroid Build Coastguard Worker namespace c10 {
27*da0073e9SAndroid Build Coastguard Worker
28*da0073e9SAndroid Build Coastguard Worker template <typename KeyType>
KeyStrRepr(const KeyType &)29*da0073e9SAndroid Build Coastguard Worker inline std::string KeyStrRepr(const KeyType& /*key*/) {
30*da0073e9SAndroid Build Coastguard Worker return "[key type printing not supported]";
31*da0073e9SAndroid Build Coastguard Worker }
32*da0073e9SAndroid Build Coastguard Worker
33*da0073e9SAndroid Build Coastguard Worker template <>
KeyStrRepr(const std::string & key)34*da0073e9SAndroid Build Coastguard Worker inline std::string KeyStrRepr(const std::string& key) {
35*da0073e9SAndroid Build Coastguard Worker return key;
36*da0073e9SAndroid Build Coastguard Worker }
37*da0073e9SAndroid Build Coastguard Worker
38*da0073e9SAndroid Build Coastguard Worker enum RegistryPriority {
39*da0073e9SAndroid Build Coastguard Worker REGISTRY_FALLBACK = 1,
40*da0073e9SAndroid Build Coastguard Worker REGISTRY_DEFAULT = 2,
41*da0073e9SAndroid Build Coastguard Worker REGISTRY_PREFERRED = 3,
42*da0073e9SAndroid Build Coastguard Worker };
43*da0073e9SAndroid Build Coastguard Worker
44*da0073e9SAndroid Build Coastguard Worker /**
45*da0073e9SAndroid Build Coastguard Worker * @brief A template class that allows one to register classes by keys.
46*da0073e9SAndroid Build Coastguard Worker *
47*da0073e9SAndroid Build Coastguard Worker * The keys are usually a std::string specifying the name, but can be anything
48*da0073e9SAndroid Build Coastguard Worker * that can be used in a std::map.
49*da0073e9SAndroid Build Coastguard Worker *
50*da0073e9SAndroid Build Coastguard Worker * You should most likely not use the Registry class explicitly, but use the
51*da0073e9SAndroid Build Coastguard Worker * helper macros below to declare specific registries as well as registering
52*da0073e9SAndroid Build Coastguard Worker * objects.
53*da0073e9SAndroid Build Coastguard Worker */
54*da0073e9SAndroid Build Coastguard Worker template <class SrcType, class ObjectPtrType, class... Args>
55*da0073e9SAndroid Build Coastguard Worker class Registry {
56*da0073e9SAndroid Build Coastguard Worker public:
57*da0073e9SAndroid Build Coastguard Worker typedef std::function<ObjectPtrType(Args...)> Creator;
58*da0073e9SAndroid Build Coastguard Worker
registry_()59*da0073e9SAndroid Build Coastguard Worker Registry(bool warning = true) : registry_(), priority_(), warning_(warning) {}
60*da0073e9SAndroid Build Coastguard Worker
61*da0073e9SAndroid Build Coastguard Worker void Register(
62*da0073e9SAndroid Build Coastguard Worker const SrcType& key,
63*da0073e9SAndroid Build Coastguard Worker Creator creator,
64*da0073e9SAndroid Build Coastguard Worker const RegistryPriority priority = REGISTRY_DEFAULT) {
65*da0073e9SAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(register_mutex_);
66*da0073e9SAndroid Build Coastguard Worker // The if statement below is essentially the same as the following line:
67*da0073e9SAndroid Build Coastguard Worker // TORCH_CHECK_EQ(registry_.count(key), 0) << "Key " << key
68*da0073e9SAndroid Build Coastguard Worker // << " registered twice.";
69*da0073e9SAndroid Build Coastguard Worker // However, TORCH_CHECK_EQ depends on google logging, and since registration
70*da0073e9SAndroid Build Coastguard Worker // is carried out at static initialization time, we do not want to have an
71*da0073e9SAndroid Build Coastguard Worker // explicit dependency on glog's initialization function.
72*da0073e9SAndroid Build Coastguard Worker if (registry_.count(key) != 0) {
73*da0073e9SAndroid Build Coastguard Worker auto cur_priority = priority_[key];
74*da0073e9SAndroid Build Coastguard Worker if (priority > cur_priority) {
75*da0073e9SAndroid Build Coastguard Worker #ifdef DEBUG
76*da0073e9SAndroid Build Coastguard Worker std::string warn_msg =
77*da0073e9SAndroid Build Coastguard Worker "Overwriting already registered item for key " + KeyStrRepr(key);
78*da0073e9SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", warn_msg.c_str());
79*da0073e9SAndroid Build Coastguard Worker #endif
80*da0073e9SAndroid Build Coastguard Worker registry_[key] = creator;
81*da0073e9SAndroid Build Coastguard Worker priority_[key] = priority;
82*da0073e9SAndroid Build Coastguard Worker } else if (priority == cur_priority) {
83*da0073e9SAndroid Build Coastguard Worker std::string err_msg =
84*da0073e9SAndroid Build Coastguard Worker "Key already registered with the same priority: " + KeyStrRepr(key);
85*da0073e9SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", err_msg.c_str());
86*da0073e9SAndroid Build Coastguard Worker if (terminate_) {
87*da0073e9SAndroid Build Coastguard Worker std::exit(1);
88*da0073e9SAndroid Build Coastguard Worker } else {
89*da0073e9SAndroid Build Coastguard Worker throw std::runtime_error(err_msg);
90*da0073e9SAndroid Build Coastguard Worker }
91*da0073e9SAndroid Build Coastguard Worker } else if (warning_) {
92*da0073e9SAndroid Build Coastguard Worker std::string warn_msg =
93*da0073e9SAndroid Build Coastguard Worker "Higher priority item already registered, skipping registration of " +
94*da0073e9SAndroid Build Coastguard Worker KeyStrRepr(key);
95*da0073e9SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", warn_msg.c_str());
96*da0073e9SAndroid Build Coastguard Worker }
97*da0073e9SAndroid Build Coastguard Worker } else {
98*da0073e9SAndroid Build Coastguard Worker registry_[key] = creator;
99*da0073e9SAndroid Build Coastguard Worker priority_[key] = priority;
100*da0073e9SAndroid Build Coastguard Worker }
101*da0073e9SAndroid Build Coastguard Worker }
102*da0073e9SAndroid Build Coastguard Worker
103*da0073e9SAndroid Build Coastguard Worker void Register(
104*da0073e9SAndroid Build Coastguard Worker const SrcType& key,
105*da0073e9SAndroid Build Coastguard Worker Creator creator,
106*da0073e9SAndroid Build Coastguard Worker const std::string& help_msg,
107*da0073e9SAndroid Build Coastguard Worker const RegistryPriority priority = REGISTRY_DEFAULT) {
108*da0073e9SAndroid Build Coastguard Worker Register(key, creator, priority);
109*da0073e9SAndroid Build Coastguard Worker help_message_[key] = help_msg;
110*da0073e9SAndroid Build Coastguard Worker }
111*da0073e9SAndroid Build Coastguard Worker
Has(const SrcType & key)112*da0073e9SAndroid Build Coastguard Worker inline bool Has(const SrcType& key) {
113*da0073e9SAndroid Build Coastguard Worker return (registry_.count(key) != 0);
114*da0073e9SAndroid Build Coastguard Worker }
115*da0073e9SAndroid Build Coastguard Worker
Create(const SrcType & key,Args...args)116*da0073e9SAndroid Build Coastguard Worker ObjectPtrType Create(const SrcType& key, Args... args) {
117*da0073e9SAndroid Build Coastguard Worker auto it = registry_.find(key);
118*da0073e9SAndroid Build Coastguard Worker if (it == registry_.end()) {
119*da0073e9SAndroid Build Coastguard Worker // Returns nullptr if the key is not registered.
120*da0073e9SAndroid Build Coastguard Worker return nullptr;
121*da0073e9SAndroid Build Coastguard Worker }
122*da0073e9SAndroid Build Coastguard Worker return it->second(args...);
123*da0073e9SAndroid Build Coastguard Worker }
124*da0073e9SAndroid Build Coastguard Worker
125*da0073e9SAndroid Build Coastguard Worker /**
126*da0073e9SAndroid Build Coastguard Worker * Returns the keys currently registered as a std::vector.
127*da0073e9SAndroid Build Coastguard Worker */
Keys()128*da0073e9SAndroid Build Coastguard Worker std::vector<SrcType> Keys() const {
129*da0073e9SAndroid Build Coastguard Worker std::vector<SrcType> keys;
130*da0073e9SAndroid Build Coastguard Worker keys.reserve(registry_.size());
131*da0073e9SAndroid Build Coastguard Worker for (const auto& it : registry_) {
132*da0073e9SAndroid Build Coastguard Worker keys.push_back(it.first);
133*da0073e9SAndroid Build Coastguard Worker }
134*da0073e9SAndroid Build Coastguard Worker return keys;
135*da0073e9SAndroid Build Coastguard Worker }
136*da0073e9SAndroid Build Coastguard Worker
HelpMessage()137*da0073e9SAndroid Build Coastguard Worker inline const std::unordered_map<SrcType, std::string>& HelpMessage() const {
138*da0073e9SAndroid Build Coastguard Worker return help_message_;
139*da0073e9SAndroid Build Coastguard Worker }
140*da0073e9SAndroid Build Coastguard Worker
HelpMessage(const SrcType & key)141*da0073e9SAndroid Build Coastguard Worker const char* HelpMessage(const SrcType& key) const {
142*da0073e9SAndroid Build Coastguard Worker auto it = help_message_.find(key);
143*da0073e9SAndroid Build Coastguard Worker if (it == help_message_.end()) {
144*da0073e9SAndroid Build Coastguard Worker return nullptr;
145*da0073e9SAndroid Build Coastguard Worker }
146*da0073e9SAndroid Build Coastguard Worker return it->second.c_str();
147*da0073e9SAndroid Build Coastguard Worker }
148*da0073e9SAndroid Build Coastguard Worker
149*da0073e9SAndroid Build Coastguard Worker // Used for testing, if terminate is unset, Registry throws instead of
150*da0073e9SAndroid Build Coastguard Worker // calling std::exit
SetTerminate(bool terminate)151*da0073e9SAndroid Build Coastguard Worker void SetTerminate(bool terminate) {
152*da0073e9SAndroid Build Coastguard Worker terminate_ = terminate;
153*da0073e9SAndroid Build Coastguard Worker }
154*da0073e9SAndroid Build Coastguard Worker
155*da0073e9SAndroid Build Coastguard Worker private:
156*da0073e9SAndroid Build Coastguard Worker std::unordered_map<SrcType, Creator> registry_;
157*da0073e9SAndroid Build Coastguard Worker std::unordered_map<SrcType, RegistryPriority> priority_;
158*da0073e9SAndroid Build Coastguard Worker bool terminate_{true};
159*da0073e9SAndroid Build Coastguard Worker const bool warning_;
160*da0073e9SAndroid Build Coastguard Worker std::unordered_map<SrcType, std::string> help_message_;
161*da0073e9SAndroid Build Coastguard Worker std::mutex register_mutex_;
162*da0073e9SAndroid Build Coastguard Worker
163*da0073e9SAndroid Build Coastguard Worker C10_DISABLE_COPY_AND_ASSIGN(Registry);
164*da0073e9SAndroid Build Coastguard Worker };
165*da0073e9SAndroid Build Coastguard Worker
166*da0073e9SAndroid Build Coastguard Worker template <class SrcType, class ObjectPtrType, class... Args>
167*da0073e9SAndroid Build Coastguard Worker class Registerer {
168*da0073e9SAndroid Build Coastguard Worker public:
169*da0073e9SAndroid Build Coastguard Worker explicit Registerer(
170*da0073e9SAndroid Build Coastguard Worker const SrcType& key,
171*da0073e9SAndroid Build Coastguard Worker Registry<SrcType, ObjectPtrType, Args...>* registry,
172*da0073e9SAndroid Build Coastguard Worker typename Registry<SrcType, ObjectPtrType, Args...>::Creator creator,
173*da0073e9SAndroid Build Coastguard Worker const std::string& help_msg = "") {
174*da0073e9SAndroid Build Coastguard Worker registry->Register(key, creator, help_msg);
175*da0073e9SAndroid Build Coastguard Worker }
176*da0073e9SAndroid Build Coastguard Worker
177*da0073e9SAndroid Build Coastguard Worker explicit Registerer(
178*da0073e9SAndroid Build Coastguard Worker const SrcType& key,
179*da0073e9SAndroid Build Coastguard Worker const RegistryPriority priority,
180*da0073e9SAndroid Build Coastguard Worker Registry<SrcType, ObjectPtrType, Args...>* registry,
181*da0073e9SAndroid Build Coastguard Worker typename Registry<SrcType, ObjectPtrType, Args...>::Creator creator,
182*da0073e9SAndroid Build Coastguard Worker const std::string& help_msg = "") {
183*da0073e9SAndroid Build Coastguard Worker registry->Register(key, creator, help_msg, priority);
184*da0073e9SAndroid Build Coastguard Worker }
185*da0073e9SAndroid Build Coastguard Worker
186*da0073e9SAndroid Build Coastguard Worker template <class DerivedType>
DefaultCreator(Args...args)187*da0073e9SAndroid Build Coastguard Worker static ObjectPtrType DefaultCreator(Args... args) {
188*da0073e9SAndroid Build Coastguard Worker return ObjectPtrType(new DerivedType(args...));
189*da0073e9SAndroid Build Coastguard Worker }
190*da0073e9SAndroid Build Coastguard Worker };
191*da0073e9SAndroid Build Coastguard Worker
192*da0073e9SAndroid Build Coastguard Worker /**
193*da0073e9SAndroid Build Coastguard Worker * C10_DECLARE_TYPED_REGISTRY is a macro that expands to a function
194*da0073e9SAndroid Build Coastguard Worker * declaration, as well as creating a convenient typename for its corresponding
195*da0073e9SAndroid Build Coastguard Worker * registerer.
196*da0073e9SAndroid Build Coastguard Worker */
197*da0073e9SAndroid Build Coastguard Worker // Note on C10_IMPORT and C10_EXPORT below: we need to explicitly mark DECLARE
198*da0073e9SAndroid Build Coastguard Worker // as import and DEFINE as export, because these registry macros will be used
199*da0073e9SAndroid Build Coastguard Worker // in downstream shared libraries as well, and one cannot use *_API - the API
200*da0073e9SAndroid Build Coastguard Worker // macro will be defined on a per-shared-library basis. Semantically, when one
201*da0073e9SAndroid Build Coastguard Worker // declares a typed registry it is always going to be IMPORT, and when one
202*da0073e9SAndroid Build Coastguard Worker // defines a registry (which should happen ONLY ONCE and ONLY IN SOURCE FILE),
203*da0073e9SAndroid Build Coastguard Worker // the instantiation unit is always going to be exported.
204*da0073e9SAndroid Build Coastguard Worker //
205*da0073e9SAndroid Build Coastguard Worker // The only unique condition is when in the same file one does DECLARE and
206*da0073e9SAndroid Build Coastguard Worker // DEFINE - in Windows compilers, this generates a warning that dllimport and
207*da0073e9SAndroid Build Coastguard Worker // dllexport are mixed, but the warning is fine and linker will be properly
208*da0073e9SAndroid Build Coastguard Worker // exporting the symbol. Same thing happens in the gflags flag declaration and
209*da0073e9SAndroid Build Coastguard Worker // definition caes.
210*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_TYPED_REGISTRY( \
211*da0073e9SAndroid Build Coastguard Worker RegistryName, SrcType, ObjectType, PtrType, ...) \
212*da0073e9SAndroid Build Coastguard Worker C10_API ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>* \
213*da0073e9SAndroid Build Coastguard Worker RegistryName(); \
214*da0073e9SAndroid Build Coastguard Worker typedef ::c10::Registerer<SrcType, PtrType<ObjectType>, ##__VA_ARGS__> \
215*da0073e9SAndroid Build Coastguard Worker Registerer##RegistryName
216*da0073e9SAndroid Build Coastguard Worker
217*da0073e9SAndroid Build Coastguard Worker #define TORCH_DECLARE_TYPED_REGISTRY( \
218*da0073e9SAndroid Build Coastguard Worker RegistryName, SrcType, ObjectType, PtrType, ...) \
219*da0073e9SAndroid Build Coastguard Worker TORCH_API ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>* \
220*da0073e9SAndroid Build Coastguard Worker RegistryName(); \
221*da0073e9SAndroid Build Coastguard Worker typedef ::c10::Registerer<SrcType, PtrType<ObjectType>, ##__VA_ARGS__> \
222*da0073e9SAndroid Build Coastguard Worker Registerer##RegistryName
223*da0073e9SAndroid Build Coastguard Worker
224*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_TYPED_REGISTRY( \
225*da0073e9SAndroid Build Coastguard Worker RegistryName, SrcType, ObjectType, PtrType, ...) \
226*da0073e9SAndroid Build Coastguard Worker C10_EXPORT ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>* \
227*da0073e9SAndroid Build Coastguard Worker RegistryName() { \
228*da0073e9SAndroid Build Coastguard Worker static ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>* \
229*da0073e9SAndroid Build Coastguard Worker registry = new ::c10:: \
230*da0073e9SAndroid Build Coastguard Worker Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>(); \
231*da0073e9SAndroid Build Coastguard Worker return registry; \
232*da0073e9SAndroid Build Coastguard Worker }
233*da0073e9SAndroid Build Coastguard Worker
234*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_TYPED_REGISTRY_WITHOUT_WARNING( \
235*da0073e9SAndroid Build Coastguard Worker RegistryName, SrcType, ObjectType, PtrType, ...) \
236*da0073e9SAndroid Build Coastguard Worker C10_EXPORT ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>* \
237*da0073e9SAndroid Build Coastguard Worker RegistryName() { \
238*da0073e9SAndroid Build Coastguard Worker static ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>* \
239*da0073e9SAndroid Build Coastguard Worker registry = \
240*da0073e9SAndroid Build Coastguard Worker new ::c10::Registry<SrcType, PtrType<ObjectType>, ##__VA_ARGS__>( \
241*da0073e9SAndroid Build Coastguard Worker false); \
242*da0073e9SAndroid Build Coastguard Worker return registry; \
243*da0073e9SAndroid Build Coastguard Worker }
244*da0073e9SAndroid Build Coastguard Worker
245*da0073e9SAndroid Build Coastguard Worker // Note(Yangqing): The __VA_ARGS__ below allows one to specify a templated
246*da0073e9SAndroid Build Coastguard Worker // creator with comma in its templated arguments.
247*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_TYPED_CREATOR(RegistryName, key, ...) \
248*da0073e9SAndroid Build Coastguard Worker static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \
249*da0073e9SAndroid Build Coastguard Worker key, RegistryName(), ##__VA_ARGS__);
250*da0073e9SAndroid Build Coastguard Worker
251*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_TYPED_CREATOR_WITH_PRIORITY( \
252*da0073e9SAndroid Build Coastguard Worker RegistryName, key, priority, ...) \
253*da0073e9SAndroid Build Coastguard Worker static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \
254*da0073e9SAndroid Build Coastguard Worker key, priority, RegistryName(), ##__VA_ARGS__);
255*da0073e9SAndroid Build Coastguard Worker
256*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_TYPED_CLASS(RegistryName, key, ...) \
257*da0073e9SAndroid Build Coastguard Worker static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \
258*da0073e9SAndroid Build Coastguard Worker key, \
259*da0073e9SAndroid Build Coastguard Worker RegistryName(), \
260*da0073e9SAndroid Build Coastguard Worker Registerer##RegistryName::DefaultCreator<__VA_ARGS__>, \
261*da0073e9SAndroid Build Coastguard Worker ::c10::demangle_type<__VA_ARGS__>());
262*da0073e9SAndroid Build Coastguard Worker
263*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_TYPED_CLASS_WITH_PRIORITY( \
264*da0073e9SAndroid Build Coastguard Worker RegistryName, key, priority, ...) \
265*da0073e9SAndroid Build Coastguard Worker static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \
266*da0073e9SAndroid Build Coastguard Worker key, \
267*da0073e9SAndroid Build Coastguard Worker priority, \
268*da0073e9SAndroid Build Coastguard Worker RegistryName(), \
269*da0073e9SAndroid Build Coastguard Worker Registerer##RegistryName::DefaultCreator<__VA_ARGS__>, \
270*da0073e9SAndroid Build Coastguard Worker ::c10::demangle_type<__VA_ARGS__>());
271*da0073e9SAndroid Build Coastguard Worker
272*da0073e9SAndroid Build Coastguard Worker // C10_DECLARE_REGISTRY and C10_DEFINE_REGISTRY are hard-wired to use
273*da0073e9SAndroid Build Coastguard Worker // std::string as the key type, because that is the most commonly used cases.
274*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_REGISTRY(RegistryName, ObjectType, ...) \
275*da0073e9SAndroid Build Coastguard Worker C10_DECLARE_TYPED_REGISTRY( \
276*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__)
277*da0073e9SAndroid Build Coastguard Worker
278*da0073e9SAndroid Build Coastguard Worker #define TORCH_DECLARE_REGISTRY(RegistryName, ObjectType, ...) \
279*da0073e9SAndroid Build Coastguard Worker TORCH_DECLARE_TYPED_REGISTRY( \
280*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__)
281*da0073e9SAndroid Build Coastguard Worker
282*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_REGISTRY(RegistryName, ObjectType, ...) \
283*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_TYPED_REGISTRY( \
284*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__)
285*da0073e9SAndroid Build Coastguard Worker
286*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_REGISTRY_WITHOUT_WARNING(RegistryName, ObjectType, ...) \
287*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_TYPED_REGISTRY_WITHOUT_WARNING( \
288*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__)
289*da0073e9SAndroid Build Coastguard Worker
290*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_SHARED_REGISTRY(RegistryName, ObjectType, ...) \
291*da0073e9SAndroid Build Coastguard Worker C10_DECLARE_TYPED_REGISTRY( \
292*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__)
293*da0073e9SAndroid Build Coastguard Worker
294*da0073e9SAndroid Build Coastguard Worker #define TORCH_DECLARE_SHARED_REGISTRY(RegistryName, ObjectType, ...) \
295*da0073e9SAndroid Build Coastguard Worker TORCH_DECLARE_TYPED_REGISTRY( \
296*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__)
297*da0073e9SAndroid Build Coastguard Worker
298*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_SHARED_REGISTRY(RegistryName, ObjectType, ...) \
299*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_TYPED_REGISTRY( \
300*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__)
301*da0073e9SAndroid Build Coastguard Worker
302*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_SHARED_REGISTRY_WITHOUT_WARNING( \
303*da0073e9SAndroid Build Coastguard Worker RegistryName, ObjectType, ...) \
304*da0073e9SAndroid Build Coastguard Worker C10_DEFINE_TYPED_REGISTRY_WITHOUT_WARNING( \
305*da0073e9SAndroid Build Coastguard Worker RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__)
306*da0073e9SAndroid Build Coastguard Worker
307*da0073e9SAndroid Build Coastguard Worker // C10_REGISTER_CREATOR and C10_REGISTER_CLASS are hard-wired to use std::string
308*da0073e9SAndroid Build Coastguard Worker // as the key
309*da0073e9SAndroid Build Coastguard Worker // type, because that is the most commonly used cases.
310*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_CREATOR(RegistryName, key, ...) \
311*da0073e9SAndroid Build Coastguard Worker C10_REGISTER_TYPED_CREATOR(RegistryName, #key, __VA_ARGS__)
312*da0073e9SAndroid Build Coastguard Worker
313*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_CREATOR_WITH_PRIORITY(RegistryName, key, priority, ...) \
314*da0073e9SAndroid Build Coastguard Worker C10_REGISTER_TYPED_CREATOR_WITH_PRIORITY( \
315*da0073e9SAndroid Build Coastguard Worker RegistryName, #key, priority, __VA_ARGS__)
316*da0073e9SAndroid Build Coastguard Worker
317*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_CLASS(RegistryName, key, ...) \
318*da0073e9SAndroid Build Coastguard Worker C10_REGISTER_TYPED_CLASS(RegistryName, #key, __VA_ARGS__)
319*da0073e9SAndroid Build Coastguard Worker
320*da0073e9SAndroid Build Coastguard Worker #define C10_REGISTER_CLASS_WITH_PRIORITY(RegistryName, key, priority, ...) \
321*da0073e9SAndroid Build Coastguard Worker C10_REGISTER_TYPED_CLASS_WITH_PRIORITY( \
322*da0073e9SAndroid Build Coastguard Worker RegistryName, #key, priority, __VA_ARGS__)
323*da0073e9SAndroid Build Coastguard Worker
324*da0073e9SAndroid Build Coastguard Worker } // namespace c10
325*da0073e9SAndroid Build Coastguard Worker
326*da0073e9SAndroid Build Coastguard Worker #endif // C10_UTIL_REGISTRY_H_
327