xref: /aosp_15_r20/external/pytorch/c10/util/Flags.h (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker #ifndef C10_UTIL_FLAGS_H_
2*da0073e9SAndroid Build Coastguard Worker #define C10_UTIL_FLAGS_H_
3*da0073e9SAndroid Build Coastguard Worker 
4*da0073e9SAndroid Build Coastguard Worker /* Commandline flags support for C10.
5*da0073e9SAndroid Build Coastguard Worker  *
6*da0073e9SAndroid Build Coastguard Worker  * This is a portable commandline flags tool for c10, so we can optionally
7*da0073e9SAndroid Build Coastguard Worker  * choose to use gflags or a lightweight custom implementation if gflags is
8*da0073e9SAndroid Build Coastguard Worker  * not possible on a certain platform. If you have gflags installed, set the
9*da0073e9SAndroid Build Coastguard Worker  * macro C10_USE_GFLAGS will seamlessly route everything to gflags.
10*da0073e9SAndroid Build Coastguard Worker  *
11*da0073e9SAndroid Build Coastguard Worker  * To define a flag foo of type bool default to true, do the following in the
12*da0073e9SAndroid Build Coastguard Worker  * *global* namespace:
13*da0073e9SAndroid Build Coastguard Worker  *     C10_DEFINE_bool(foo, true, "An example.");
14*da0073e9SAndroid Build Coastguard Worker  *
15*da0073e9SAndroid Build Coastguard Worker  * To use it in another .cc file, you can use C10_DECLARE_* as follows:
16*da0073e9SAndroid Build Coastguard Worker  *     C10_DECLARE_bool(foo);
17*da0073e9SAndroid Build Coastguard Worker  *
18*da0073e9SAndroid Build Coastguard Worker  * In both cases, you can then access the flag via FLAGS_foo.
19*da0073e9SAndroid Build Coastguard Worker  *
20*da0073e9SAndroid Build Coastguard Worker  * It is recommended that you build with gflags. To learn more about the flags
21*da0073e9SAndroid Build Coastguard Worker  * usage, refer to the gflags page here:
22*da0073e9SAndroid Build Coastguard Worker  *
23*da0073e9SAndroid Build Coastguard Worker  * https://gflags.github.io/gflags/
24*da0073e9SAndroid Build Coastguard Worker  *
25*da0073e9SAndroid Build Coastguard Worker  * Note about Python users / devs: gflags is initiated from a C++ function
26*da0073e9SAndroid Build Coastguard Worker  * ParseCommandLineFlags, and is usually done in native binaries in the main
27*da0073e9SAndroid Build Coastguard Worker  * function. As Python does not have a modifiable main function, it is usually
28*da0073e9SAndroid Build Coastguard Worker  * difficult to change the flags after Python starts. Hence, it is recommended
29*da0073e9SAndroid Build Coastguard Worker  * that one sets the default value of the flags to one that's acceptable in
30*da0073e9SAndroid Build Coastguard Worker  * general - that will allow Python to run without wrong flags.
31*da0073e9SAndroid Build Coastguard Worker  */
32*da0073e9SAndroid Build Coastguard Worker 
33*da0073e9SAndroid Build Coastguard Worker #include <c10/macros/Export.h>
34*da0073e9SAndroid Build Coastguard Worker #include <string>
35*da0073e9SAndroid Build Coastguard Worker 
36*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Registry.h>
37*da0073e9SAndroid Build Coastguard Worker 
38*da0073e9SAndroid Build Coastguard Worker namespace c10 {
39*da0073e9SAndroid Build Coastguard Worker /**
40*da0073e9SAndroid Build Coastguard Worker  * Sets the usage message when a commandline tool is called with "--help".
41*da0073e9SAndroid Build Coastguard Worker  */
42*da0073e9SAndroid Build Coastguard Worker C10_API void SetUsageMessage(const std::string& str);
43*da0073e9SAndroid Build Coastguard Worker 
44*da0073e9SAndroid Build Coastguard Worker /**
45*da0073e9SAndroid Build Coastguard Worker  * Returns the usage message for the commandline tool set by SetUsageMessage.
46*da0073e9SAndroid Build Coastguard Worker  */
47*da0073e9SAndroid Build Coastguard Worker C10_API const char* UsageMessage();
48*da0073e9SAndroid Build Coastguard Worker 
49*da0073e9SAndroid Build Coastguard Worker /**
50*da0073e9SAndroid Build Coastguard Worker  * Parses the commandline flags.
51*da0073e9SAndroid Build Coastguard Worker  *
52*da0073e9SAndroid Build Coastguard Worker  * This command parses all the commandline arguments passed in via pargc
53*da0073e9SAndroid Build Coastguard Worker  * and argv. Once it is finished, partc and argv will contain the remaining
54*da0073e9SAndroid Build Coastguard Worker  * commandline args that c10 does not deal with. Note that following
55*da0073e9SAndroid Build Coastguard Worker  * convention, argv[0] contains the binary name and is not parsed.
56*da0073e9SAndroid Build Coastguard Worker  */
57*da0073e9SAndroid Build Coastguard Worker C10_API bool ParseCommandLineFlags(int* pargc, char*** pargv);
58*da0073e9SAndroid Build Coastguard Worker 
59*da0073e9SAndroid Build Coastguard Worker /**
60*da0073e9SAndroid Build Coastguard Worker  * Checks if the commandline flags has already been passed.
61*da0073e9SAndroid Build Coastguard Worker  */
62*da0073e9SAndroid Build Coastguard Worker C10_API bool CommandLineFlagsHasBeenParsed();
63*da0073e9SAndroid Build Coastguard Worker 
64*da0073e9SAndroid Build Coastguard Worker } // namespace c10
65*da0073e9SAndroid Build Coastguard Worker 
66*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
67*da0073e9SAndroid Build Coastguard Worker // Below are gflags and non-gflags specific implementations.
68*da0073e9SAndroid Build Coastguard Worker // In general, they define the following macros for one to declare (use
69*da0073e9SAndroid Build Coastguard Worker // C10_DECLARE) or define (use C10_DEFINE) flags:
70*da0073e9SAndroid Build Coastguard Worker // C10_{DECLARE,DEFINE}_{int,int64,double,bool,string}
71*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
72*da0073e9SAndroid Build Coastguard Worker 
73*da0073e9SAndroid Build Coastguard Worker #ifdef C10_USE_GFLAGS
74*da0073e9SAndroid Build Coastguard Worker 
75*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
76*da0073e9SAndroid Build Coastguard Worker // Begin gflags section: most functions are basically rerouted to gflags.
77*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
78*da0073e9SAndroid Build Coastguard Worker #include <gflags/gflags.h>
79*da0073e9SAndroid Build Coastguard Worker 
80*da0073e9SAndroid Build Coastguard Worker // C10 uses hidden visibility by default. However, in gflags, it only uses
81*da0073e9SAndroid Build Coastguard Worker // export on Windows platform (with dllexport) but not on linux/mac (with
82*da0073e9SAndroid Build Coastguard Worker // default visibility). As a result, to ensure that we are always exporting
83*da0073e9SAndroid Build Coastguard Worker // global variables, we will redefine the GFLAGS_DLL_DEFINE_FLAG macro if we
84*da0073e9SAndroid Build Coastguard Worker // are building C10 as a shared library.
85*da0073e9SAndroid Build Coastguard Worker // This has to be done after the inclusion of gflags, because some early
86*da0073e9SAndroid Build Coastguard Worker // versions of gflags.h (e.g. 2.0 on ubuntu 14.04) directly defines the
87*da0073e9SAndroid Build Coastguard Worker // macros, so we need to do definition after gflags is done.
88*da0073e9SAndroid Build Coastguard Worker #ifdef GFLAGS_DLL_DEFINE_FLAG
89*da0073e9SAndroid Build Coastguard Worker #undef GFLAGS_DLL_DEFINE_FLAG
90*da0073e9SAndroid Build Coastguard Worker #endif // GFLAGS_DLL_DEFINE_FLAG
91*da0073e9SAndroid Build Coastguard Worker #ifdef GFLAGS_DLL_DECLARE_FLAG
92*da0073e9SAndroid Build Coastguard Worker #undef GFLAGS_DLL_DECLARE_FLAG
93*da0073e9SAndroid Build Coastguard Worker #endif // GFLAGS_DLL_DECLARE_FLAG
94*da0073e9SAndroid Build Coastguard Worker #define GFLAGS_DLL_DEFINE_FLAG C10_EXPORT
95*da0073e9SAndroid Build Coastguard Worker #define GFLAGS_DLL_DECLARE_FLAG C10_IMPORT
96*da0073e9SAndroid Build Coastguard Worker 
97*da0073e9SAndroid Build Coastguard Worker // gflags before 2.0 uses namespace google and after 2.1 uses namespace gflags.
98*da0073e9SAndroid Build Coastguard Worker // Using GFLAGS_GFLAGS_H_ to capture this change.
99*da0073e9SAndroid Build Coastguard Worker #ifndef GFLAGS_GFLAGS_H_
100*da0073e9SAndroid Build Coastguard Worker namespace gflags = google;
101*da0073e9SAndroid Build Coastguard Worker #endif // GFLAGS_GFLAGS_H_
102*da0073e9SAndroid Build Coastguard Worker 
103*da0073e9SAndroid Build Coastguard Worker // Motivation about the gflags wrapper:
104*da0073e9SAndroid Build Coastguard Worker // (1) We would need to make sure that the gflags version and the non-gflags
105*da0073e9SAndroid Build Coastguard Worker // version of C10 are going to expose the same flags abstraction. One should
106*da0073e9SAndroid Build Coastguard Worker // explicitly use FLAGS_flag_name to access the flags.
107*da0073e9SAndroid Build Coastguard Worker // (2) For flag names, it is recommended to start with c10_ to distinguish it
108*da0073e9SAndroid Build Coastguard Worker // from regular gflags flags. For example, do
109*da0073e9SAndroid Build Coastguard Worker //    C10_DEFINE_BOOL(c10_my_flag, true, "An example");
110*da0073e9SAndroid Build Coastguard Worker // to allow one to use FLAGS_c10_my_flag.
111*da0073e9SAndroid Build Coastguard Worker // (3) Gflags has a design issue that does not properly expose the global flags,
112*da0073e9SAndroid Build Coastguard Worker // if one builds the library with -fvisibility=hidden. The current gflags (as of
113*da0073e9SAndroid Build Coastguard Worker // Aug 2018) only deals with the Windows case using dllexport, and not the Linux
114*da0073e9SAndroid Build Coastguard Worker // counterparts. As a result, we will explicitly use C10_EXPORT to export the
115*da0073e9SAndroid Build Coastguard Worker // flags defined in C10. This is done via a global reference, so the flag
116*da0073e9SAndroid Build Coastguard Worker // itself is not duplicated - under the hood it is the same global gflags flag.
117*da0073e9SAndroid Build Coastguard Worker #define C10_GFLAGS_DEF_WRAPPER(type, real_type, name, default_value, help_str) \
118*da0073e9SAndroid Build Coastguard Worker   DEFINE_##type(name, default_value, help_str);
119*da0073e9SAndroid Build Coastguard Worker 
120*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int(name, default_value, help_str) \
121*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DEF_WRAPPER(int32, gflags::int32, name, default_value, help_str)
122*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int32(name, default_value, help_str) \
123*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_int(name, default_value, help_str)
124*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int64(name, default_value, help_str) \
125*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DEF_WRAPPER(int64, gflags::int64, name, default_value, help_str)
126*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_double(name, default_value, help_str) \
127*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DEF_WRAPPER(double, double, name, default_value, help_str)
128*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_bool(name, default_value, help_str) \
129*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DEF_WRAPPER(bool, bool, name, default_value, help_str)
130*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_string(name, default_value, help_str) \
131*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DEF_WRAPPER(string, ::fLS::clstring, name, default_value, help_str)
132*da0073e9SAndroid Build Coastguard Worker 
133*da0073e9SAndroid Build Coastguard Worker // DECLARE_typed_var should be used in header files and in the global namespace.
134*da0073e9SAndroid Build Coastguard Worker #define C10_GFLAGS_DECLARE_WRAPPER(type, real_type, name) DECLARE_##type(name);
135*da0073e9SAndroid Build Coastguard Worker 
136*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int(name) \
137*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DECLARE_WRAPPER(int32, gflags::int32, name)
138*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int32(name) C10_DECLARE_int(name)
139*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int64(name) \
140*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DECLARE_WRAPPER(int64, gflags::int64, name)
141*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_double(name) \
142*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DECLARE_WRAPPER(double, double, name)
143*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_bool(name) C10_GFLAGS_DECLARE_WRAPPER(bool, bool, name)
144*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_string(name) \
145*da0073e9SAndroid Build Coastguard Worker   C10_GFLAGS_DECLARE_WRAPPER(string, ::fLS::clstring, name)
146*da0073e9SAndroid Build Coastguard Worker 
147*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
148*da0073e9SAndroid Build Coastguard Worker // End gflags section.
149*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
150*da0073e9SAndroid Build Coastguard Worker 
151*da0073e9SAndroid Build Coastguard Worker #else // C10_USE_GFLAGS
152*da0073e9SAndroid Build Coastguard Worker 
153*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
154*da0073e9SAndroid Build Coastguard Worker // Begin non-gflags section: providing equivalent functionality.
155*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
156*da0073e9SAndroid Build Coastguard Worker 
157*da0073e9SAndroid Build Coastguard Worker namespace c10 {
158*da0073e9SAndroid Build Coastguard Worker 
159*da0073e9SAndroid Build Coastguard Worker class C10_API C10FlagParser {
160*da0073e9SAndroid Build Coastguard Worker  public:
success()161*da0073e9SAndroid Build Coastguard Worker   bool success() {
162*da0073e9SAndroid Build Coastguard Worker     return success_;
163*da0073e9SAndroid Build Coastguard Worker   }
164*da0073e9SAndroid Build Coastguard Worker 
165*da0073e9SAndroid Build Coastguard Worker  protected:
166*da0073e9SAndroid Build Coastguard Worker   template <typename T>
167*da0073e9SAndroid Build Coastguard Worker   bool Parse(const std::string& content, T* value);
168*da0073e9SAndroid Build Coastguard Worker   bool success_{false};
169*da0073e9SAndroid Build Coastguard Worker };
170*da0073e9SAndroid Build Coastguard Worker 
171*da0073e9SAndroid Build Coastguard Worker C10_DECLARE_REGISTRY(C10FlagsRegistry, C10FlagParser, const std::string&);
172*da0073e9SAndroid Build Coastguard Worker 
173*da0073e9SAndroid Build Coastguard Worker } // namespace c10
174*da0073e9SAndroid Build Coastguard Worker 
175*da0073e9SAndroid Build Coastguard Worker // The macros are defined outside the c10 namespace. In your code, you should
176*da0073e9SAndroid Build Coastguard Worker // write the C10_DEFINE_* and C10_DECLARE_* macros outside any namespace
177*da0073e9SAndroid Build Coastguard Worker // as well.
178*da0073e9SAndroid Build Coastguard Worker 
179*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_typed_var(type, name, default_value, help_str)       \
180*da0073e9SAndroid Build Coastguard Worker   C10_EXPORT type FLAGS_##name = default_value;                         \
181*da0073e9SAndroid Build Coastguard Worker   namespace c10 {                                                       \
182*da0073e9SAndroid Build Coastguard Worker   namespace {                                                           \
183*da0073e9SAndroid Build Coastguard Worker   class C10FlagParser_##name : public C10FlagParser {                   \
184*da0073e9SAndroid Build Coastguard Worker    public:                                                              \
185*da0073e9SAndroid Build Coastguard Worker     explicit C10FlagParser_##name(const std::string& content) {         \
186*da0073e9SAndroid Build Coastguard Worker       success_ = C10FlagParser::Parse<type>(content, &FLAGS_##name);    \
187*da0073e9SAndroid Build Coastguard Worker     }                                                                   \
188*da0073e9SAndroid Build Coastguard Worker   };                                                                    \
189*da0073e9SAndroid Build Coastguard Worker   }                                                                     \
190*da0073e9SAndroid Build Coastguard Worker   RegistererC10FlagsRegistry g_C10FlagsRegistry_##name(                 \
191*da0073e9SAndroid Build Coastguard Worker       #name,                                                            \
192*da0073e9SAndroid Build Coastguard Worker       C10FlagsRegistry(),                                               \
193*da0073e9SAndroid Build Coastguard Worker       RegistererC10FlagsRegistry::DefaultCreator<C10FlagParser_##name>, \
194*da0073e9SAndroid Build Coastguard Worker       "(" #type ", default " #default_value ") " help_str);             \
195*da0073e9SAndroid Build Coastguard Worker   }
196*da0073e9SAndroid Build Coastguard Worker 
197*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int(name, default_value, help_str) \
198*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_typed_var(int, name, default_value, help_str)
199*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int32(name, default_value, help_str) \
200*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_int(name, default_value, help_str)
201*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_int64(name, default_value, help_str) \
202*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_typed_var(int64_t, name, default_value, help_str)
203*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_double(name, default_value, help_str) \
204*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_typed_var(double, name, default_value, help_str)
205*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_bool(name, default_value, help_str) \
206*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_typed_var(bool, name, default_value, help_str)
207*da0073e9SAndroid Build Coastguard Worker #define C10_DEFINE_string(name, default_value, help_str) \
208*da0073e9SAndroid Build Coastguard Worker   C10_DEFINE_typed_var(std::string, name, default_value, help_str)
209*da0073e9SAndroid Build Coastguard Worker 
210*da0073e9SAndroid Build Coastguard Worker // DECLARE_typed_var should be used in header files and in the global namespace.
211*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_typed_var(type, name) C10_API extern type FLAGS_##name
212*da0073e9SAndroid Build Coastguard Worker 
213*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int(name) C10_DECLARE_typed_var(int, name)
214*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int32(name) C10_DECLARE_int(name)
215*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_int64(name) C10_DECLARE_typed_var(int64_t, name)
216*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_double(name) C10_DECLARE_typed_var(double, name)
217*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_bool(name) C10_DECLARE_typed_var(bool, name)
218*da0073e9SAndroid Build Coastguard Worker #define C10_DECLARE_string(name) C10_DECLARE_typed_var(std::string, name)
219*da0073e9SAndroid Build Coastguard Worker 
220*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
221*da0073e9SAndroid Build Coastguard Worker // End non-gflags section.
222*da0073e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
223*da0073e9SAndroid Build Coastguard Worker 
224*da0073e9SAndroid Build Coastguard Worker #endif // C10_USE_GFLAGS
225*da0073e9SAndroid Build Coastguard Worker 
226*da0073e9SAndroid Build Coastguard Worker #endif // C10_UTIL_FLAGS_H_
227