platform.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #define _CRT_SECURE_NO_WARNINGS
  18. //__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
  19. #include <cstddef>
  20. #include <cassert>
  21. #include <cstdlib>
  22. #include <cstdio>
  23. #include <memory>
  24. #include <stdexcept>
  25. #include <iostream>
  26. #include <iomanip>
  27. #include <fstream>
  28. #include <string>
  29. #include <cstring>
  30. #include <stdint.h>
  31. #include <functional>
  32. ////////////////////////////////////////////////////////////////////////////////
  33. /// detect platform
  34. ////////////////////////////////////////////////////////////////////////////////
  35. /* detect 32 or 64 platform */
  36. #if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
  37. #define __X86_64__
  38. #endif
  39. /* detect Linux platform */
  40. #if defined(linux) || defined(__linux__) || defined(__LINUX__)
  41. # if !defined(__LINUX__)
  42. # define __LINUX__
  43. # endif
  44. # if !defined(__UNIX__)
  45. # define __UNIX__
  46. # endif
  47. #endif
  48. /* detect FreeBSD platform */
  49. #if defined(__FreeBSD__) || defined(__FREEBSD__)
  50. # if !defined(__FREEBSD__)
  51. # define __FREEBSD__
  52. # endif
  53. # if !defined(__UNIX__)
  54. # define __UNIX__
  55. # endif
  56. #endif
  57. /* detect Windows 95/98/NT/2000/XP/Vista/7/8/10 platform */
  58. #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(__CYGWIN__)
  59. # if !defined(__WIN32__)
  60. # define __WIN32__
  61. # endif
  62. #endif
  63. /* detect Cygwin platform */
  64. #if defined(__CYGWIN__)
  65. # if !defined(__UNIX__)
  66. # define __UNIX__
  67. # endif
  68. #endif
  69. /* detect MAC OS X platform */
  70. #if defined(__APPLE__) || defined(MACOSX) || defined(__MACOSX__)
  71. # if !defined(__MACOSX__)
  72. # define __MACOSX__
  73. # endif
  74. # if !defined(__UNIX__)
  75. # define __UNIX__
  76. # endif
  77. #endif
  78. /* try to detect other Unix systems */
  79. #if defined(__unix__) || defined (unix) || defined(__unix) || defined(_unix)
  80. # if !defined(__UNIX__)
  81. # define __UNIX__
  82. # endif
  83. #endif
  84. #if defined (_DEBUG)
  85. #define DEBUG
  86. #endif
  87. ////////////////////////////////////////////////////////////////////////////////
  88. /// ISA configuration
  89. ////////////////////////////////////////////////////////////////////////////////
  90. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
  91. #define __SSE__
  92. #define __SSE2__
  93. #endif
  94. #if defined(CONFIG_SSE41) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
  95. #define __SSE3__
  96. #define __SSSE3__
  97. #define __SSE4_1__
  98. #endif
  99. #if defined(CONFIG_SSE42) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
  100. #define __SSE3__
  101. #define __SSSE3__
  102. #define __SSE4_1__
  103. #define __SSE4_2__
  104. #endif
  105. #if defined(CONFIG_AVX) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
  106. #define __SSE3__
  107. #define __SSSE3__
  108. #define __SSE4_1__
  109. #define __SSE4_2__
  110. #if !defined(__AVX__)
  111. #define __AVX__
  112. #endif
  113. #endif
  114. #if defined(CONFIG_AVX2) && defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__)
  115. #define __SSE3__
  116. #define __SSSE3__
  117. #define __SSE4_1__
  118. #define __SSE4_2__
  119. #if !defined(__AVX__)
  120. #define __AVX__
  121. #endif
  122. #if !defined(__AVX2__)
  123. #define __AVX2__
  124. #endif
  125. #endif
  126. ////////////////////////////////////////////////////////////////////////////////
  127. /// Makros
  128. ////////////////////////////////////////////////////////////////////////////////
  129. #ifdef __WIN32__
  130. #define __dllexport __declspec(dllexport)
  131. #define __dllimport __declspec(dllimport)
  132. #else
  133. #define __dllexport __attribute__ ((visibility ("default")))
  134. #define __dllimport
  135. #endif
  136. #ifdef __WIN32__
  137. #undef __noinline
  138. #define __noinline __declspec(noinline)
  139. //#define __forceinline __forceinline
  140. //#define __restrict __restrict
  141. #if defined(__INTEL_COMPILER)
  142. #define __restrict__ __restrict
  143. #else
  144. #define __restrict__ //__restrict // causes issues with MSVC
  145. #endif
  146. #define __thread __declspec(thread)
  147. #define __aligned(...) __declspec(align(__VA_ARGS__))
  148. //#define __FUNCTION__ __FUNCTION__
  149. #define debugbreak() __debugbreak()
  150. #else
  151. #if !defined(__noinline)
  152. #define __noinline __attribute__((noinline))
  153. #endif
  154. #if !defined(__forceinline)
  155. #define __forceinline inline __attribute__((always_inline))
  156. #endif
  157. //#define __restrict __restrict
  158. //#define __thread __thread
  159. #if !defined(__aligned)
  160. #define __aligned(...) __attribute__((aligned(__VA_ARGS__)))
  161. #endif
  162. #if !defined(__FUNCTION__)
  163. #define __FUNCTION__ __PRETTY_FUNCTION__
  164. #endif
  165. #define debugbreak() asm ("int $3")
  166. #endif
  167. #if defined(__clang__) || defined(__GNUC__)
  168. #define MAYBE_UNUSED __attribute__((unused))
  169. #else
  170. #define MAYBE_UNUSED
  171. #endif
  172. #if defined(_MSC_VER) && (_MSC_VER < 1900) // before VS2015 deleted functions are not supported properly
  173. #define DELETED
  174. #else
  175. #define DELETED = delete
  176. #endif
  177. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
  178. #define likely(expr) (expr)
  179. #define unlikely(expr) (expr)
  180. #else
  181. #define likely(expr) __builtin_expect((bool)(expr),true )
  182. #define unlikely(expr) __builtin_expect((bool)(expr),false)
  183. #endif
  184. ////////////////////////////////////////////////////////////////////////////////
  185. /// Error handling and debugging
  186. ////////////////////////////////////////////////////////////////////////////////
  187. /* debug printing macros */
  188. #define STRING(x) #x
  189. #define TOSTRING(x) STRING(x)
  190. #define PING std::cout << __FILE__ << " (" << __LINE__ << "): " << __FUNCTION__ << std::endl
  191. #define PRINT(x) std::cout << STRING(x) << " = " << (x) << std::endl
  192. #define PRINT2(x,y) std::cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << std::endl
  193. #define PRINT3(x,y,z) std::cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << std::endl
  194. #define PRINT4(x,y,z,w) std::cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << std::endl
  195. #if defined(DEBUG) // only report file and line in debug mode
  196. #define THROW_RUNTIME_ERROR(str) \
  197. throw std::runtime_error(std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str));
  198. #else
  199. #define THROW_RUNTIME_ERROR(str) \
  200. throw std::runtime_error(str);
  201. #endif
  202. #define FATAL(x) THROW_RUNTIME_ERROR(x)
  203. #define WARNING(x) { std::cerr << "Warning: " << x << std::endl << std::flush; }
  204. #define NOT_IMPLEMENTED FATAL(std::string(__FUNCTION__) + " not implemented")
  205. ////////////////////////////////////////////////////////////////////////////////
  206. /// Basic types
  207. ////////////////////////////////////////////////////////////////////////////////
  208. /* default floating-point type */
  209. typedef float real;
  210. /* windows does not have ssize_t */
  211. #if defined(__WIN32__)
  212. #if defined(__X86_64__)
  213. typedef int64_t ssize_t;
  214. #else
  215. typedef int32_t ssize_t;
  216. #endif
  217. #endif
  218. ////////////////////////////////////////////////////////////////////////////////
  219. /// Basic utility functions
  220. ////////////////////////////////////////////////////////////////////////////////
  221. __forceinline std::string toString(long long value) {
  222. return std::to_string(value);
  223. }
  224. ////////////////////////////////////////////////////////////////////////////////
  225. /// Disable some compiler warnings
  226. ////////////////////////////////////////////////////////////////////////////////
  227. #if defined(__INTEL_COMPILER)
  228. //#pragma warning(disable:265 ) // floating-point operation result is out of range
  229. //#pragma warning(disable:383 ) // value copied to temporary, reference to temporary used
  230. //#pragma warning(disable:869 ) // parameter was never referenced
  231. //#pragma warning(disable:981 ) // operands are evaluated in unspecified order
  232. //#pragma warning(disable:1418) // external function definition with no prior declaration
  233. //#pragma warning(disable:1419) // external declaration in primary source file
  234. //#pragma warning(disable:1572) // floating-point equality and inequality comparisons are unreliable
  235. //#pragma warning(disable:94 ) // the size of an array must be greater than zero
  236. //#pragma warning(disable:1599) // declaration hides parameter
  237. //#pragma warning(disable:424 ) // extra ";" ignored
  238. #pragma warning(disable:2196) // routine is both "inline" and "noinline"
  239. //#pragma warning(disable:177 ) // label was declared but never referenced
  240. //#pragma warning(disable:114 ) // function was referenced but not defined
  241. //#pragma warning(disable:819 ) // template nesting depth does not match the previous declaration of function
  242. #endif
  243. #if defined(_MSC_VER)
  244. //#pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union
  245. #pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning)
  246. //#pragma warning(disable:4267) // '=' : conversion from 'size_t' to 'unsigned long', possible loss of data
  247. //#pragma warning(disable:4244) // 'argument' : conversion from 'ssize_t' to 'unsigned int', possible loss of data
  248. //#pragma warning(disable:4355) // 'this' : used in base member initializer list
  249. //#pragma warning(disable:391 ) // '<=' : signed / unsigned mismatch
  250. //#pragma warning(disable:4018) // '<' : signed / unsigned mismatch
  251. //#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float'
  252. //#pragma warning(disable:4068) // unknown pragma
  253. //#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned
  254. //#pragma warning(disable:4838) // conversion from 'unsigned int' to 'const int' requires a narrowing conversion)
  255. //#pragma warning(disable:4227) // anachronism used : qualifiers on reference are ignored
  256. #pragma warning(disable:4503) // decorated name length exceeded, name was truncated
  257. #pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
  258. #pragma warning(disable:4258) // definition from the for loop is ignored; the definition from the enclosing scope is used
  259. #endif
  260. #if defined(__clang__) && !defined(__INTEL_COMPILER)
  261. //#pragma clang diagnostic ignored "-Wunknown-pragmas"
  262. //#pragma clang diagnostic ignored "-Wunused-variable"
  263. //#pragma clang diagnostic ignored "-Wreorder"
  264. //#pragma clang diagnostic ignored "-Wmicrosoft"
  265. //#pragma clang diagnostic ignored "-Wunused-private-field"
  266. //#pragma clang diagnostic ignored "-Wunused-local-typedef"
  267. //#pragma clang diagnostic ignored "-Wunused-function"
  268. //#pragma clang diagnostic ignored "-Wnarrowing"
  269. //#pragma clang diagnostic ignored "-Wc++11-narrowing"
  270. //#pragma clang diagnostic ignored "-Wdeprecated-register"
  271. //#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  272. #endif
  273. #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
  274. //#pragma GCC diagnostic ignored "-Wnarrowing"
  275. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  276. //#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  277. //#pragma GCC diagnostic ignored "-Warray-bounds"
  278. #pragma GCC diagnostic ignored "-Wattributes"
  279. #endif
  280. #if defined(__clang__) && defined(__WIN32__)
  281. #pragma clang diagnostic ignored "-Wunused-parameter"
  282. #pragma clang diagnostic ignored "-Wmicrosoft-cast"
  283. #pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
  284. #pragma clang diagnostic ignored "-Wmicrosoft-include"
  285. #pragma clang diagnostic ignored "-Wunused-function"
  286. #pragma clang diagnostic ignored "-Wunknown-pragmas"
  287. #endif
  288. ////////////////////////////////////////////////////////////////////////////////
  289. /// Some macros for static profiling
  290. ////////////////////////////////////////////////////////////////////////////////
  291. #if defined (__GNUC__)
  292. #define IACA_SSC_MARK( MARK_ID ) \
  293. __asm__ __volatile__ ( \
  294. "\n\t movl $"#MARK_ID", %%ebx" \
  295. "\n\t .byte 0x64, 0x67, 0x90" \
  296. : : : "memory" );
  297. #define IACA_UD_BYTES __asm__ __volatile__ ("\n\t .byte 0x0F, 0x0B");
  298. #else
  299. #define IACA_UD_BYTES {__asm _emit 0x0F \
  300. __asm _emit 0x0B}
  301. #define IACA_SSC_MARK(x) {__asm mov ebx, x\
  302. __asm _emit 0x64 \
  303. __asm _emit 0x67 \
  304. __asm _emit 0x90 }
  305. #define IACA_VC64_START __writegsbyte(111, 111);
  306. #define IACA_VC64_END __writegsbyte(222, 222);
  307. #endif
  308. #define IACA_START {IACA_UD_BYTES \
  309. IACA_SSC_MARK(111)}
  310. #define IACA_END {IACA_SSC_MARK(222) \
  311. IACA_UD_BYTES}
  312. namespace embree
  313. {
  314. template<typename Closure>
  315. struct OnScopeExitHelper
  316. {
  317. OnScopeExitHelper (const Closure f) : active(true), f(f) {}
  318. ~OnScopeExitHelper() { if (active) f(); }
  319. void deactivate() { active = false; }
  320. bool active;
  321. const Closure f;
  322. };
  323. template <typename Closure>
  324. OnScopeExitHelper<Closure> OnScopeExit(const Closure f) {
  325. return OnScopeExitHelper<Closure>(f);
  326. };
  327. #define STRING_JOIN2(arg1, arg2) DO_STRING_JOIN2(arg1, arg2)
  328. #define DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2
  329. #define ON_SCOPE_EXIT(code) \
  330. auto STRING_JOIN2(on_scope_exit_, __LINE__) = OnScopeExit([&](){code;})
  331. template<typename Ty>
  332. std::unique_ptr<Ty> make_unique(Ty* ptr) {
  333. return std::unique_ptr<Ty>(ptr);
  334. }
  335. }