1 | /******************************************************************************* |
2 | copyright (c) the taichi authors (2016- ). all rights reserved. |
3 | the use of this software is governed by the license file. |
4 | *******************************************************************************/ |
5 | |
6 | #pragma once |
7 | |
8 | #ifndef _CRT_SECURE_NO_WARNINGS |
9 | #define _CRT_SECURE_NO_WARNINGS |
10 | #endif |
11 | |
12 | #include <iostream> |
13 | #include <type_traits> |
14 | #include <cstdint> |
15 | #include <algorithm> |
16 | #include <vector> |
17 | #include <string> |
18 | #include <functional> |
19 | |
20 | //****************************************************************************** |
21 | // System State |
22 | //****************************************************************************** |
23 | |
24 | // Reference: |
25 | // https://blog.kowalczyk.info/article/j/guide-to-predefined-macros-in-c-compilers-gcc-clang-msvc-etc..html |
26 | |
27 | // Platforms |
28 | #include "taichi/common/platform_macros.h" |
29 | |
30 | // Avoid dependency on glibc 2.27 |
31 | #if defined(TI_PLATFORM_LINUX) && defined(TI_ARCH_x64) |
32 | // objdump -T libtaichi_python.so| grep GLIBC_2.27 |
33 | __asm__(".symver logf,logf@GLIBC_2.2.5" ); |
34 | __asm__(".symver powf,powf@GLIBC_2.2.5" ); |
35 | __asm__(".symver expf,expf@GLIBC_2.2.5" ); |
36 | #endif |
37 | |
38 | // Compilers |
39 | |
40 | // MSVC |
41 | #if defined(_MSC_VER) |
42 | #define TI_COMPILER_MSVC |
43 | #endif |
44 | |
45 | // MINGW |
46 | #if defined(__MINGW64__) |
47 | #define TI_COMPILER_MINGW |
48 | #endif |
49 | |
50 | // gcc |
51 | #if defined(__GNUC__) |
52 | #define TI_COMPILER__GCC |
53 | #endif |
54 | |
55 | // clang |
56 | #if defined(__clang__) |
57 | #define TI_COMPILER_CLANG |
58 | #endif |
59 | |
60 | #if defined(TI_COMPILER_MSVC) |
61 | #define TI_ALIGNED(x) __declspec(align(x)) |
62 | #else |
63 | #define TI_ALIGNED(x) __attribute__((aligned(x))) |
64 | #endif |
65 | |
66 | #if __cplusplus >= 201703L |
67 | #define TI_CPP17 |
68 | #else |
69 | #if defined(TI_COMPILER_CLANG) |
70 | static_assert(false, "For clang compilers, use -std=c++17" ); |
71 | #endif |
72 | static_assert(__cplusplus >= 201402L, "C++14 required." ); |
73 | #define TI_CPP14 |
74 | #endif |
75 | |
76 | // Do not disable assert... |
77 | #ifdef NDEBUG |
78 | #undef NDEBUG |
79 | #endif |
80 | |
81 | #ifdef _WIN64 |
82 | #pragma warning(push) |
83 | #pragma warning(disable : 4005) |
84 | #include "taichi/platform/windows/windows.h" |
85 | #pragma warning(pop) |
86 | #include <intrin.h> |
87 | #endif // _WIN64 |
88 | |
89 | #ifndef _WIN64 |
90 | #define sscanf_s sscanf |
91 | #define sprintf_s sprintf |
92 | #endif |
93 | |
94 | #undef assert |
95 | #ifdef _WIN64 |
96 | #ifndef TI_PASS_EXCEPTION_TO_PYTHON |
97 | // For Visual Studio debugging... |
98 | #define DEBUG_TRIGGER __debugbreak() |
99 | #else |
100 | #define DEBUG_TRIGGER |
101 | #endif |
102 | #else |
103 | #define DEBUG_TRIGGER |
104 | #endif |
105 | |
106 | #define TI_STATIC_ASSERT(x) static_assert((x), #x) |
107 | |
108 | void taichi_raise_assertion_failure_in_python(const char *msg); |
109 | |
110 | namespace taichi { |
111 | |
112 | //****************************************************************************** |
113 | // System State |
114 | //****************************************************************************** |
115 | |
116 | class CoreState { |
117 | public: |
118 | bool python_imported = false; |
119 | bool trigger_gdb_when_crash = false; |
120 | |
121 | static CoreState &get_instance(); |
122 | |
123 | static void set_python_imported(bool val) { |
124 | get_instance().python_imported = val; |
125 | } |
126 | |
127 | static void set_trigger_gdb_when_crash(bool val) { |
128 | get_instance().trigger_gdb_when_crash = val; |
129 | } |
130 | }; |
131 | |
132 | //****************************************************************************** |
133 | // Types |
134 | //****************************************************************************** |
135 | |
136 | using uchar = unsigned char; |
137 | |
138 | using int8 = int8_t; |
139 | using uint8 = uint8_t; |
140 | |
141 | using int16 = int16_t; |
142 | using uint16 = uint16_t; |
143 | |
144 | using int32 = int32_t; |
145 | using uint32 = uint32_t; |
146 | using uint = unsigned int; |
147 | |
148 | using int64 = int64_t; |
149 | using uint64 = uint64_t; |
150 | |
151 | #ifdef _WIN64 |
152 | #define TI_FORCE_INLINE __forceinline |
153 | #else |
154 | #define TI_FORCE_INLINE inline __attribute__((always_inline)) |
155 | #endif |
156 | |
157 | using float32 = float; |
158 | using float64 = double; |
159 | |
160 | #ifdef TI_USE_DOUBLE |
161 | using real = float64; |
162 | #else |
163 | using real = float32; |
164 | #endif |
165 | |
166 | // Float literal for both float32/64 |
167 | // (Learned from https://github.com/hi2p-perim/lightmetrica-v2) |
168 | real constexpr operator"" _f(long double v) { |
169 | return real(v); |
170 | } |
171 | real constexpr operator"" _f(unsigned long long v) { |
172 | return real(v); |
173 | } |
174 | |
175 | float32 constexpr operator"" _f32(long double v) { |
176 | return float32(v); |
177 | } |
178 | float32 constexpr operator"" _f32(unsigned long long v) { |
179 | return float32(v); |
180 | } |
181 | |
182 | float32 constexpr operator"" _fs(long double v) { |
183 | return float32(v); |
184 | } |
185 | float32 constexpr operator"" _fs(unsigned long long v) { |
186 | return float32(v); |
187 | } |
188 | |
189 | float64 constexpr operator"" _f64(long double v) { |
190 | return float64(v); |
191 | } |
192 | float64 constexpr operator"" _f64(unsigned long long v) { |
193 | return float64(v); |
194 | } |
195 | |
196 | float64 constexpr operator"" _fd(long double v) { |
197 | return float64(v); |
198 | } |
199 | float64 constexpr operator"" _fd(unsigned long long v) { |
200 | return float64(v); |
201 | } |
202 | |
203 | } // namespace taichi |
204 | //****************************************************************************** |
205 | // Meta-programming |
206 | //****************************************************************************** |
207 | |
208 | #include "taichi/util/meta.h" |
209 | |
210 | #include "taichi/common/logging.h" |
211 | |
212 | namespace taichi { |
213 | |
214 | namespace zip { |
215 | |
216 | void write(std::string fn, const uint8 *data, std::size_t len); |
217 | void write(const std::string &fn, const std::string &data); |
218 | std::vector<uint8> read(const std::string fn, bool verbose = false); |
219 | |
220 | } // namespace zip |
221 | |
222 | //****************************************************************************** |
223 | // String Utils |
224 | //****************************************************************************** |
225 | |
226 | inline std::vector<std::string> split_string(const std::string &s, |
227 | const std::string &separators) { |
228 | std::vector<std::string> ret; |
229 | bool is_seperator[256] = {false}; |
230 | for (auto &ch : separators) { |
231 | is_seperator[(unsigned int)ch] = true; |
232 | } |
233 | int begin = 0; |
234 | for (int i = 0; i <= (int)s.size(); i++) { |
235 | if (is_seperator[(uint8)s[i]] || i == (int)s.size()) { |
236 | ret.push_back(std::string(s.begin() + begin, s.begin() + i)); |
237 | begin = i + 1; |
238 | } |
239 | } |
240 | return ret; |
241 | } |
242 | |
243 | inline std::string trim_string(const std::string &s) { |
244 | int begin = 0, end = (int)s.size(); |
245 | while (begin < end && s[begin] == ' ') { |
246 | begin++; |
247 | } |
248 | while (begin < end && s[end - 1] == ' ') { |
249 | end--; |
250 | } |
251 | return std::string(s.begin() + begin, s.begin() + end); |
252 | } |
253 | |
254 | inline bool ends_with(std::string const &str, std::string const &ending) { |
255 | if (ending.size() > str.size()) |
256 | return false; |
257 | else |
258 | return std::equal(ending.begin(), ending.end(), str.end() - ending.size()); |
259 | } |
260 | |
261 | inline bool starts_with(std::string const &str, std::string const &ending) { |
262 | if (ending.size() > str.size()) |
263 | return false; |
264 | else |
265 | return std::equal(ending.begin(), ending.end(), str.begin()); |
266 | } |
267 | |
268 | } // namespace taichi |
269 | |
270 | //****************************************************************************** |
271 | // Serialization |
272 | //****************************************************************************** |
273 | |
274 | #include "taichi/common/serialization.h" |
275 | |
276 | //****************************************************************************** |
277 | // Misc. |
278 | //****************************************************************************** |
279 | |
280 | namespace taichi { |
281 | |
282 | extern int __trash__; |
283 | template <typename T> |
284 | void trash(T &&t) { |
285 | static_assert(!std::is_same<T, void>::value, "" ); |
286 | __trash__ = *reinterpret_cast<uint8 *>(&t); |
287 | } |
288 | |
289 | class DeferedExecution { |
290 | std::function<void(void)> statement_; |
291 | |
292 | public: |
293 | explicit DeferedExecution(const std::function<void(void)> &statement) |
294 | : statement_(statement) { |
295 | } |
296 | |
297 | ~DeferedExecution() { |
298 | statement_(); |
299 | } |
300 | }; |
301 | |
302 | #define TI_DEFER(x) taichi::DeferedExecution _defered([&]() { x; }); |
303 | |
304 | std::string get_repo_dir(); |
305 | |
306 | std::string get_python_package_dir(); |
307 | |
308 | void set_python_package_dir(const std::string &dir); |
309 | |
310 | inline std::string assets_dir() { |
311 | return get_repo_dir() + "/assets/" ; |
312 | } |
313 | |
314 | std::string cpp_demangle(const std::string &mangled_name); |
315 | |
316 | int get_version_major(); |
317 | |
318 | int get_version_minor(); |
319 | |
320 | int get_version_patch(); |
321 | |
322 | std::string get_version_string(); |
323 | |
324 | std::string get_commit_hash(); |
325 | |
326 | std::string get_cuda_version_string(); |
327 | |
328 | class PID { |
329 | public: |
330 | static int get_pid(); |
331 | static int get_parent_pid(); |
332 | }; |
333 | |
334 | } // namespace taichi |
335 | |