isa.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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. namespace embree
  18. {
  19. #define DEFINE_SYMBOL2(type,name) \
  20. typedef type (*name##Func)(); \
  21. name##Func name;
  22. #define DECLARE_SYMBOL2(type,name) \
  23. namespace isa { extern type name(); } \
  24. namespace sse41 { extern type name(); } \
  25. namespace sse42 { extern type name(); } \
  26. namespace avx { extern type name(); } \
  27. namespace avx2 { extern type name(); } \
  28. namespace avx512knl { extern type name(); } \
  29. namespace avx512skx { extern type name(); } \
  30. void name##_error2() { throw_RTCError(RTC_UNKNOWN_ERROR,"internal error in ISA selection for " TOSTRING(name)); } \
  31. type name##_error() { return type(name##_error2); } \
  32. type name##_zero() { return type(nullptr); }
  33. #define DEFINE_BUILDER2(Accel,Mesh,Args,symbol) \
  34. typedef Builder* (*symbol##Func)(Accel* accel, Mesh* mesh, Args args); \
  35. symbol##Func symbol;
  36. #define DECLARE_BUILDER2(Accel,Mesh,Args,symbol) \
  37. namespace isa { extern Builder* symbol(Accel* accel, Mesh* scene, Args args); } \
  38. namespace sse41 { extern Builder* symbol(Accel* accel, Mesh* scene, Args args); } \
  39. namespace avx { extern Builder* symbol(Accel* accel, Mesh* scene, Args args); } \
  40. namespace avx2 { extern Builder* symbol(Accel* accel, Mesh* scene, Args args); } \
  41. namespace avx512knl { extern Builder* symbol(Accel* accel, Mesh* scene, Args args); } \
  42. namespace avx512skx { extern Builder* symbol(Accel* accel, Mesh* scene, Args args); } \
  43. void symbol##_error() { throw_RTCError(RTC_UNSUPPORTED_CPU,"builder " TOSTRING(symbol) " not supported by your CPU"); } \
  44. #define ZERO_SYMBOL(features,intersector) \
  45. intersector = intersector##_zero;
  46. #define INIT_SYMBOL(features,intersector) \
  47. intersector = decltype(intersector)(intersector##_error);
  48. #define SELECT_SYMBOL_DEFAULT(features,intersector) \
  49. intersector = isa::intersector;
  50. #if defined(__SSE__)
  51. #if !defined(__TARGET_SIMD4__)
  52. #define __TARGET_SIMD4__
  53. #endif
  54. #endif
  55. #if defined(__TARGET_SSE42__)
  56. #define SELECT_SYMBOL_SSE42(features,intersector) \
  57. if ((features & SSE42) == SSE42) intersector = sse42::intersector;
  58. #else
  59. #define SELECT_SYMBOL_SSE42(features,intersector)
  60. #endif
  61. #if defined(__TARGET_AVX__)
  62. #if !defined(__TARGET_SIMD8__)
  63. #define __TARGET_SIMD8__
  64. #endif
  65. #define SELECT_SYMBOL_AVX(features,intersector) \
  66. if ((features & AVX) == AVX) intersector = avx::intersector;
  67. #else
  68. #define SELECT_SYMBOL_AVX(features,intersector)
  69. #endif
  70. #if defined(__TARGET_AVX2__)
  71. #if !defined(__TARGET_SIMD8__)
  72. #define __TARGET_SIMD8__
  73. #endif
  74. #define SELECT_SYMBOL_AVX2(features,intersector) \
  75. if ((features & AVX2) == AVX2) intersector = avx2::intersector;
  76. #else
  77. #define SELECT_SYMBOL_AVX2(features,intersector)
  78. #endif
  79. #if defined(__TARGET_AVX512KNL__)
  80. #if !defined(__TARGET_SIMD16__)
  81. #define __TARGET_SIMD16__
  82. #endif
  83. #define SELECT_SYMBOL_AVX512KNL(features,intersector) \
  84. if ((features & AVX512KNL) == AVX512KNL) intersector = avx512knl::intersector;
  85. #else
  86. #define SELECT_SYMBOL_AVX512KNL(features,intersector)
  87. #endif
  88. #if defined(__TARGET_AVX512SKX__)
  89. #if !defined(__TARGET_SIMD16__)
  90. #define __TARGET_SIMD16__
  91. #endif
  92. #define SELECT_SYMBOL_AVX512SKX(features,intersector) \
  93. if ((features & AVX512SKX) == AVX512SKX) intersector = avx512skx::intersector;
  94. #else
  95. #define SELECT_SYMBOL_AVX512SKX(features,intersector)
  96. #endif
  97. #define SELECT_SYMBOL_DEFAULT_SSE42(features,intersector) \
  98. SELECT_SYMBOL_DEFAULT(features,intersector); \
  99. SELECT_SYMBOL_SSE42(features,intersector);
  100. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX(features,intersector) \
  101. SELECT_SYMBOL_DEFAULT(features,intersector); \
  102. SELECT_SYMBOL_SSE42(features,intersector); \
  103. SELECT_SYMBOL_AVX(features,intersector);
  104. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2(features,intersector) \
  105. SELECT_SYMBOL_DEFAULT(features,intersector); \
  106. SELECT_SYMBOL_SSE42(features,intersector); \
  107. SELECT_SYMBOL_AVX(features,intersector); \
  108. SELECT_SYMBOL_AVX2(features,intersector);
  109. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512SKX(features,intersector) \
  110. SELECT_SYMBOL_DEFAULT(features,intersector); \
  111. SELECT_SYMBOL_SSE42(features,intersector); \
  112. SELECT_SYMBOL_AVX(features,intersector); \
  113. SELECT_SYMBOL_AVX512SKX(features,intersector);
  114. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
  115. SELECT_SYMBOL_DEFAULT(features,intersector); \
  116. SELECT_SYMBOL_AVX(features,intersector); \
  117. SELECT_SYMBOL_AVX2(features,intersector); \
  118. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  119. SELECT_SYMBOL_AVX512SKX(features,intersector);
  120. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512SKX(features,intersector) \
  121. SELECT_SYMBOL_DEFAULT(features,intersector); \
  122. SELECT_SYMBOL_AVX(features,intersector); \
  123. SELECT_SYMBOL_AVX2(features,intersector); \
  124. SELECT_SYMBOL_AVX512SKX(features,intersector);
  125. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
  126. SELECT_SYMBOL_DEFAULT(features,intersector); \
  127. SELECT_SYMBOL_SSE42(features,intersector); \
  128. SELECT_SYMBOL_AVX(features,intersector); \
  129. SELECT_SYMBOL_AVX2(features,intersector); \
  130. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  131. SELECT_SYMBOL_AVX512SKX(features,intersector);
  132. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512SKX(features,intersector) \
  133. SELECT_SYMBOL_DEFAULT(features,intersector); \
  134. SELECT_SYMBOL_SSE42(features,intersector); \
  135. SELECT_SYMBOL_AVX(features,intersector); \
  136. SELECT_SYMBOL_AVX2(features,intersector); \
  137. SELECT_SYMBOL_AVX512SKX(features,intersector);
  138. #define SELECT_SYMBOL_DEFAULT_AVX(features,intersector) \
  139. SELECT_SYMBOL_DEFAULT(features,intersector); \
  140. SELECT_SYMBOL_AVX(features,intersector);
  141. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2(features,intersector) \
  142. SELECT_SYMBOL_DEFAULT(features,intersector); \
  143. SELECT_SYMBOL_AVX(features,intersector); \
  144. SELECT_SYMBOL_AVX2(features,intersector);
  145. #define SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL(features,intersector) \
  146. SELECT_SYMBOL_DEFAULT(features,intersector); \
  147. SELECT_SYMBOL_AVX(features,intersector); \
  148. SELECT_SYMBOL_AVX512KNL(features,intersector);
  149. #define SELECT_SYMBOL_DEFAULT_AVX_AVX512KNL_AVX512SKX(features,intersector) \
  150. SELECT_SYMBOL_DEFAULT(features,intersector); \
  151. SELECT_SYMBOL_AVX(features,intersector); \
  152. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  153. SELECT_SYMBOL_AVX512SKX(features,intersector);
  154. #define SELECT_SYMBOL_DEFAULT_AVX_AVX512SKX(features,intersector) \
  155. SELECT_SYMBOL_DEFAULT(features,intersector); \
  156. SELECT_SYMBOL_AVX(features,intersector); \
  157. SELECT_SYMBOL_AVX512SKX(features,intersector);
  158. #define SELECT_SYMBOL_INIT_AVX(features,intersector) \
  159. INIT_SYMBOL(features,intersector); \
  160. SELECT_SYMBOL_AVX(features,intersector);
  161. #define SELECT_SYMBOL_INIT_AVX_AVX2(features,intersector) \
  162. INIT_SYMBOL(features,intersector); \
  163. SELECT_SYMBOL_AVX(features,intersector); \
  164. SELECT_SYMBOL_AVX2(features,intersector);
  165. #define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512SKX(features,intersector) \
  166. INIT_SYMBOL(features,intersector); \
  167. SELECT_SYMBOL_AVX(features,intersector); \
  168. SELECT_SYMBOL_AVX2(features,intersector); \
  169. SELECT_SYMBOL_AVX512SKX(features,intersector);
  170. #define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2(features,intersector) \
  171. INIT_SYMBOL(features,intersector); \
  172. SELECT_SYMBOL_SSE42(features,intersector); \
  173. SELECT_SYMBOL_AVX(features,intersector); \
  174. SELECT_SYMBOL_AVX2(features,intersector);
  175. #define SELECT_SYMBOL_INIT_AVX_AVX512KNL(features,intersector) \
  176. INIT_SYMBOL(features,intersector); \
  177. SELECT_SYMBOL_AVX(features,intersector); \
  178. SELECT_SYMBOL_AVX512KNL(features,intersector);
  179. #define SELECT_SYMBOL_INIT_AVX_AVX512KNL_AVX512SKX(features,intersector) \
  180. INIT_SYMBOL(features,intersector); \
  181. SELECT_SYMBOL_AVX(features,intersector); \
  182. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  183. SELECT_SYMBOL_AVX512SKX(features,intersector);
  184. #define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL(features,intersector) \
  185. INIT_SYMBOL(features,intersector); \
  186. SELECT_SYMBOL_AVX(features,intersector); \
  187. SELECT_SYMBOL_AVX2(features,intersector); \
  188. SELECT_SYMBOL_AVX512KNL(features,intersector);
  189. #define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
  190. INIT_SYMBOL(features,intersector); \
  191. SELECT_SYMBOL_AVX(features,intersector); \
  192. SELECT_SYMBOL_AVX2(features,intersector); \
  193. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  194. SELECT_SYMBOL_AVX512SKX(features,intersector);
  195. #define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
  196. INIT_SYMBOL(features,intersector); \
  197. SELECT_SYMBOL_SSE42(features,intersector); \
  198. SELECT_SYMBOL_AVX(features,intersector); \
  199. SELECT_SYMBOL_AVX2(features,intersector); \
  200. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  201. SELECT_SYMBOL_AVX512SKX(features,intersector);
  202. #define SELECT_SYMBOL_ZERO_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
  203. ZERO_SYMBOL(features,intersector); \
  204. SELECT_SYMBOL_SSE42(features,intersector); \
  205. SELECT_SYMBOL_AVX(features,intersector); \
  206. SELECT_SYMBOL_AVX2(features,intersector); \
  207. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  208. SELECT_SYMBOL_AVX512SKX(features,intersector);
  209. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512KNL_AVX512SKX(features,intersector) \
  210. SELECT_SYMBOL_DEFAULT(features,intersector); \
  211. SELECT_SYMBOL_AVX(features,intersector); \
  212. SELECT_SYMBOL_AVX2(features,intersector); \
  213. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  214. SELECT_SYMBOL_AVX512SKX(features,intersector);
  215. #define SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,intersector) \
  216. INIT_SYMBOL(features,intersector); \
  217. SELECT_SYMBOL_AVX512KNL(features,intersector); \
  218. SELECT_SYMBOL_AVX512SKX(features,intersector);
  219. #define SELECT_SYMBOL_SSE42_AVX_AVX2(features,intersector) \
  220. SELECT_SYMBOL_SSE42(features,intersector); \
  221. SELECT_SYMBOL_AVX(features,intersector); \
  222. SELECT_SYMBOL_AVX2(features,intersector);
  223. struct VerifyMultiTargetLinking {
  224. static __noinline int getISA(int depth = 5) {
  225. if (depth == 0) return ISA;
  226. else return getISA(depth-1);
  227. }
  228. };
  229. namespace isa { int getISA(); };
  230. namespace sse41 { int getISA(); };
  231. namespace sse42 { int getISA(); };
  232. namespace avx { int getISA(); };
  233. namespace avx2 { int getISA(); };
  234. namespace avx512knl { int getISA(); };
  235. namespace avx512skx { int getISA(); };
  236. }