state.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  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. #include "state.h"
  17. #include "../common/lexers/streamfilters.h"
  18. namespace embree
  19. {
  20. State::ErrorHandler State::g_errorHandler;
  21. State::ErrorHandler::ErrorHandler()
  22. : thread_error(createTls()) {}
  23. State::ErrorHandler::~ErrorHandler()
  24. {
  25. Lock<MutexSys> lock(errors_mutex);
  26. for (size_t i=0; i<thread_errors.size(); i++)
  27. delete thread_errors[i];
  28. destroyTls(thread_error);
  29. thread_errors.clear();
  30. }
  31. RTCError* State::ErrorHandler::error()
  32. {
  33. RTCError* stored_error = (RTCError*) getTls(thread_error);
  34. if (stored_error) return stored_error;
  35. Lock<MutexSys> lock(errors_mutex);
  36. stored_error = new RTCError(RTC_NO_ERROR);
  37. thread_errors.push_back(stored_error);
  38. setTls(thread_error,stored_error);
  39. return stored_error;
  40. }
  41. State::State (bool singledevice)
  42. : enabled_cpu_features(getCPUFeatures()),
  43. enabled_builder_cpu_features(enabled_cpu_features)
  44. {
  45. tri_accel = "default";
  46. tri_builder = "default";
  47. tri_traverser = "default";
  48. tri_accel_mb = "default";
  49. tri_builder_mb = "default";
  50. tri_traverser_mb = "default";
  51. quad_accel = "default";
  52. quad_builder = "default";
  53. quad_traverser = "default";
  54. quad_accel_mb = "default";
  55. quad_builder_mb = "default";
  56. quad_traverser_mb = "default";
  57. line_accel = "default";
  58. line_builder = "default";
  59. line_traverser = "default";
  60. line_accel_mb = "default";
  61. line_builder_mb = "default";
  62. line_traverser_mb = "default";
  63. hair_accel = "default";
  64. hair_builder = "default";
  65. hair_traverser = "default";
  66. hair_accel_mb = "default";
  67. hair_builder_mb = "default";
  68. hair_traverser_mb = "default";
  69. object_accel = "default";
  70. object_builder = "default";
  71. object_accel_min_leaf_size = 1;
  72. object_accel_max_leaf_size = 1;
  73. object_accel_mb_min_leaf_size = 1;
  74. object_accel_mb_max_leaf_size = 1;
  75. max_spatial_split_replications = 2.0f;
  76. tessellation_cache_size = 128*1024*1024;
  77. /* large default cache size only for old mode single device mode */
  78. #if defined(__X86_64__)
  79. if (singledevice) tessellation_cache_size = 1024*1024*1024;
  80. #else
  81. if (singledevice) tessellation_cache_size = 128*1024*1024;
  82. #endif
  83. subdiv_accel = "default";
  84. subdiv_accel_mb = "default";
  85. instancing_open_min = 0;
  86. instancing_block_size = 0;
  87. instancing_open_factor = 8.0f;
  88. instancing_open_max_depth = 32;
  89. instancing_open_max = 50000000;
  90. ignore_config_files = false;
  91. float_exceptions = false;
  92. scene_flags = -1;
  93. verbose = 0;
  94. benchmark = 0;
  95. numThreads = 0;
  96. #if TASKING_INTERNAL
  97. set_affinity = true;
  98. #else
  99. set_affinity = false;
  100. #endif
  101. /* per default enable affinity on KNL */
  102. if (hasISA(AVX512KNL)) set_affinity = true;
  103. start_threads = false;
  104. error_function = nullptr;
  105. error_function2 = nullptr;
  106. error_function_userptr = nullptr;
  107. memory_monitor_function = nullptr;
  108. memory_monitor_function2 = nullptr;
  109. memory_monitor_userptr = nullptr;
  110. }
  111. State::~State() {
  112. }
  113. bool State::hasISA(const int isa) {
  114. return (enabled_cpu_features & isa) == isa;
  115. }
  116. void State::verify()
  117. {
  118. /* CPU has to support at least SSE2 */
  119. if (!hasISA(SSE2))
  120. throw_RTCError(RTC_UNSUPPORTED_CPU,"CPU does not support SSE2");
  121. /* verify that calculations stay in range */
  122. assert(rcp(min_rcp_input)*FLT_LARGE+FLT_LARGE < 0.01f*FLT_MAX);
  123. /* here we verify that CPP files compiled for a specific ISA only
  124. * call that same or lower ISA version of non-inlined class member
  125. * functions */
  126. #if defined(DEBUG)
  127. assert(isa::getISA() == ISA);
  128. #if defined(__TARGET_SSE42__)
  129. assert(sse42::getISA() <= SSE42);
  130. #endif
  131. #if defined(__TARGET_AVX__)
  132. assert(avx::getISA() <= AVX);
  133. #endif
  134. #if defined(__TARGET_AVX2__)
  135. assert(avx2::getISA() <= AVX2);
  136. #endif
  137. #if defined (__TARGET_AVX512KNL__)
  138. assert(avx512knl::getISA() <= AVX512KNL);
  139. #endif
  140. #if defined (__TARGET_AVX512SKX__)
  141. assert(avx512skx::getISA() <= AVX512SKX);
  142. #endif
  143. #endif
  144. }
  145. const char* symbols[3] = { "=", ",", "|" };
  146. bool State::parseFile(const FileName& fileName)
  147. {
  148. FILE* f = fopen(fileName.c_str(),"r");
  149. if (!f) return false;
  150. Ref<Stream<int> > file = new FileStream(f,fileName);
  151. std::vector<std::string> syms;
  152. for (size_t i=0; i<sizeof(symbols)/sizeof(void*); i++)
  153. syms.push_back(symbols[i]);
  154. Ref<TokenStream> cin = new TokenStream(new LineCommentFilter(file,"#"),
  155. TokenStream::alpha+TokenStream::ALPHA+TokenStream::numbers+"_.",
  156. TokenStream::separators,syms);
  157. parse(cin);
  158. return true;
  159. }
  160. void State::parseString(const char* cfg)
  161. {
  162. if (cfg == nullptr) return;
  163. std::vector<std::string> syms;
  164. for (size_t i=0; i<sizeof(symbols)/sizeof(void*); i++)
  165. syms.push_back(symbols[i]);
  166. Ref<TokenStream> cin = new TokenStream(new StrStream(cfg),
  167. TokenStream::alpha+TokenStream::ALPHA+TokenStream::numbers+"_.",
  168. TokenStream::separators,syms);
  169. parse(cin);
  170. }
  171. int string_to_cpufeatures(const std::string& isa)
  172. {
  173. if (isa == "sse" ) return SSE;
  174. else if (isa == "sse2") return SSE2;
  175. else if (isa == "sse3") return SSE3;
  176. else if (isa == "ssse3") return SSSE3;
  177. else if (isa == "sse41") return SSE41;
  178. else if (isa == "sse4.1") return SSE41;
  179. else if (isa == "sse42") return SSE42;
  180. else if (isa == "sse4.2") return SSE42;
  181. else if (isa == "avx") return AVX;
  182. else if (isa == "avxi") return AVXI;
  183. else if (isa == "avx2") return AVX2;
  184. else if (isa == "avx512knl") return AVX512KNL;
  185. else if (isa == "avx512skx") return AVX512SKX;
  186. else return SSE2;
  187. }
  188. void State::parse(Ref<TokenStream> cin)
  189. {
  190. /* parse until end of stream */
  191. while (cin->peek() != Token::Eof())
  192. {
  193. const Token tok = cin->get();
  194. if (tok == Token::Id("threads") && cin->trySymbol("="))
  195. numThreads = cin->get().Int();
  196. else if (tok == Token::Id("set_affinity")&& cin->trySymbol("="))
  197. set_affinity = cin->get().Int();
  198. else if (tok == Token::Id("affinity")&& cin->trySymbol("="))
  199. set_affinity = cin->get().Int();
  200. else if (tok == Token::Id("start_threads")&& cin->trySymbol("="))
  201. start_threads = cin->get().Int();
  202. else if (tok == Token::Id("isa") && cin->trySymbol("=")) {
  203. std::string isa = toLowerCase(cin->get().Identifier());
  204. enabled_cpu_features = string_to_cpufeatures(isa);
  205. enabled_builder_cpu_features = enabled_cpu_features;
  206. }
  207. else if (tok == Token::Id("max_isa") && cin->trySymbol("=")) {
  208. std::string isa = toLowerCase(cin->get().Identifier());
  209. enabled_cpu_features &= string_to_cpufeatures(isa);
  210. enabled_builder_cpu_features &= enabled_cpu_features;
  211. }
  212. else if (tok == Token::Id("max_builder_isa") && cin->trySymbol("=")) {
  213. std::string isa = toLowerCase(cin->get().Identifier());
  214. enabled_builder_cpu_features &= string_to_cpufeatures(isa);
  215. }
  216. else if (tok == Token::Id("ignore_config_files") && cin->trySymbol("="))
  217. ignore_config_files = cin->get().Int();
  218. else if (tok == Token::Id("float_exceptions") && cin->trySymbol("="))
  219. float_exceptions = cin->get().Int();
  220. else if ((tok == Token::Id("tri_accel") || tok == Token::Id("accel")) && cin->trySymbol("="))
  221. tri_accel = cin->get().Identifier();
  222. else if ((tok == Token::Id("tri_builder") || tok == Token::Id("builder")) && cin->trySymbol("="))
  223. tri_builder = cin->get().Identifier();
  224. else if ((tok == Token::Id("tri_traverser") || tok == Token::Id("traverser")) && cin->trySymbol("="))
  225. tri_traverser = cin->get().Identifier();
  226. else if ((tok == Token::Id("tri_accel_mb") || tok == Token::Id("accel_mb")) && cin->trySymbol("="))
  227. tri_accel_mb = cin->get().Identifier();
  228. else if ((tok == Token::Id("tri_builder_mb") || tok == Token::Id("builder_mb")) && cin->trySymbol("="))
  229. tri_builder_mb = cin->get().Identifier();
  230. else if ((tok == Token::Id("tri_traverser_mb") || tok == Token::Id("traverser_mb")) && cin->trySymbol("="))
  231. tri_traverser_mb = cin->get().Identifier();
  232. else if ((tok == Token::Id("quad_accel")) && cin->trySymbol("="))
  233. quad_accel = cin->get().Identifier();
  234. else if ((tok == Token::Id("quad_builder")) && cin->trySymbol("="))
  235. quad_builder = cin->get().Identifier();
  236. else if ((tok == Token::Id("quad_traverser")) && cin->trySymbol("="))
  237. quad_traverser = cin->get().Identifier();
  238. else if ((tok == Token::Id("quad_accel_mb")) && cin->trySymbol("="))
  239. quad_accel_mb = cin->get().Identifier();
  240. else if ((tok == Token::Id("quad_builder_mb")) && cin->trySymbol("="))
  241. quad_builder_mb = cin->get().Identifier();
  242. else if ((tok == Token::Id("quad_traverser_mb")) && cin->trySymbol("="))
  243. quad_traverser_mb = cin->get().Identifier();
  244. else if ((tok == Token::Id("line_accel")) && cin->trySymbol("="))
  245. line_accel = cin->get().Identifier();
  246. else if ((tok == Token::Id("line_builder")) && cin->trySymbol("="))
  247. line_builder = cin->get().Identifier();
  248. else if ((tok == Token::Id("line_traverser")) && cin->trySymbol("="))
  249. line_traverser = cin->get().Identifier();
  250. else if ((tok == Token::Id("line_accel_mb")) && cin->trySymbol("="))
  251. line_accel_mb = cin->get().Identifier();
  252. else if ((tok == Token::Id("line_builder_mb")) && cin->trySymbol("="))
  253. line_builder_mb = cin->get().Identifier();
  254. else if ((tok == Token::Id("line_traverser_mb")) && cin->trySymbol("="))
  255. line_traverser_mb = cin->get().Identifier();
  256. else if (tok == Token::Id("hair_accel") && cin->trySymbol("="))
  257. hair_accel = cin->get().Identifier();
  258. else if (tok == Token::Id("hair_builder") && cin->trySymbol("="))
  259. hair_builder = cin->get().Identifier();
  260. else if (tok == Token::Id("hair_traverser") && cin->trySymbol("="))
  261. hair_traverser = cin->get().Identifier();
  262. else if (tok == Token::Id("hair_accel_mb") && cin->trySymbol("="))
  263. hair_accel_mb = cin->get().Identifier();
  264. else if (tok == Token::Id("hair_builder_mb") && cin->trySymbol("="))
  265. hair_builder_mb = cin->get().Identifier();
  266. else if (tok == Token::Id("hair_traverser_mb") && cin->trySymbol("="))
  267. hair_traverser_mb = cin->get().Identifier();
  268. else if (tok == Token::Id("object_accel") && cin->trySymbol("="))
  269. object_accel = cin->get().Identifier();
  270. else if (tok == Token::Id("object_builder") && cin->trySymbol("="))
  271. object_builder = cin->get().Identifier();
  272. else if (tok == Token::Id("object_accel_min_leaf_size") && cin->trySymbol("="))
  273. object_accel_min_leaf_size = cin->get().Int();
  274. else if (tok == Token::Id("object_accel_max_leaf_size") && cin->trySymbol("="))
  275. object_accel_max_leaf_size = cin->get().Int();
  276. else if (tok == Token::Id("object_accel_mb_min_leaf_size") && cin->trySymbol("="))
  277. object_accel_mb_min_leaf_size = cin->get().Int();
  278. else if (tok == Token::Id("object_accel_mb_max_leaf_size") && cin->trySymbol("="))
  279. object_accel_mb_max_leaf_size = cin->get().Int();
  280. else if (tok == Token::Id("instancing_open_min") && cin->trySymbol("="))
  281. instancing_open_min = cin->get().Int();
  282. else if (tok == Token::Id("instancing_block_size") && cin->trySymbol("=")) {
  283. instancing_block_size = cin->get().Int();
  284. instancing_open_factor = 0.0f;
  285. }
  286. else if (tok == Token::Id("instancing_open_max_depth") && cin->trySymbol("="))
  287. instancing_open_max_depth = cin->get().Int();
  288. else if (tok == Token::Id("instancing_open_factor") && cin->trySymbol("=")) {
  289. instancing_block_size = 0;
  290. instancing_open_factor = cin->get().Float();
  291. }
  292. else if (tok == Token::Id("instancing_open_max") && cin->trySymbol("="))
  293. instancing_open_max = cin->get().Int();
  294. else if (tok == Token::Id("subdiv_accel") && cin->trySymbol("="))
  295. subdiv_accel = cin->get().Identifier();
  296. else if (tok == Token::Id("subdiv_accel_mb") && cin->trySymbol("="))
  297. subdiv_accel_mb = cin->get().Identifier();
  298. else if (tok == Token::Id("verbose") && cin->trySymbol("="))
  299. verbose = cin->get().Int();
  300. else if (tok == Token::Id("benchmark") && cin->trySymbol("="))
  301. benchmark = cin->get().Int();
  302. else if (tok == Token::Id("flags")) {
  303. scene_flags = 0;
  304. if (cin->trySymbol("=")) {
  305. do {
  306. Token flag = cin->get();
  307. if (flag == Token::Id("static") ) scene_flags |= RTC_SCENE_STATIC;
  308. else if (flag == Token::Id("dynamic")) scene_flags |= RTC_SCENE_DYNAMIC;
  309. else if (flag == Token::Id("compact")) scene_flags |= RTC_SCENE_COMPACT;
  310. else if (flag == Token::Id("coherent")) scene_flags |= RTC_SCENE_COHERENT;
  311. else if (flag == Token::Id("incoherent")) scene_flags |= RTC_SCENE_INCOHERENT;
  312. else if (flag == Token::Id("high_quality")) scene_flags |= RTC_SCENE_HIGH_QUALITY;
  313. else if (flag == Token::Id("robust")) scene_flags |= RTC_SCENE_ROBUST;
  314. } while (cin->trySymbol("|"));
  315. }
  316. }
  317. else if (tok == Token::Id("max_spatial_split_replications") && cin->trySymbol("="))
  318. max_spatial_split_replications = cin->get().Float();
  319. else if (tok == Token::Id("tessellation_cache_size") && cin->trySymbol("="))
  320. tessellation_cache_size = size_t(cin->get().Float()*1024.0f*1024.0f);
  321. else if (tok == Token::Id("cache_size") && cin->trySymbol("="))
  322. tessellation_cache_size = size_t(cin->get().Float()*1024.0f*1024.0f);
  323. cin->trySymbol(","); // optional , separator
  324. }
  325. }
  326. bool State::verbosity(size_t N) {
  327. return N <= verbose;
  328. }
  329. void State::print()
  330. {
  331. std::cout << "general:" << std::endl;
  332. std::cout << " build threads = " << numThreads << std::endl;
  333. std::cout << " start_threads = " << start_threads << std::endl;
  334. std::cout << " affinity = " << set_affinity << std::endl;
  335. std::cout << " verbosity = " << verbose << std::endl;
  336. std::cout << " cache_size = " << float(tessellation_cache_size)*1E-6 << " MB" << std::endl;
  337. std::cout << " max_spatial_split_replications = " << max_spatial_split_replications << std::endl;
  338. std::cout << "triangles:" << std::endl;
  339. std::cout << " accel = " << tri_accel << std::endl;
  340. std::cout << " builder = " << tri_builder << std::endl;
  341. std::cout << " traverser = " << tri_traverser << std::endl;
  342. std::cout << "motion blur triangles:" << std::endl;
  343. std::cout << " accel = " << tri_accel_mb << std::endl;
  344. std::cout << " builder = " << tri_builder_mb << std::endl;
  345. std::cout << " traverser = " << tri_traverser_mb << std::endl;
  346. std::cout << "quads:" << std::endl;
  347. std::cout << " accel = " << quad_accel << std::endl;
  348. std::cout << " builder = " << quad_builder << std::endl;
  349. std::cout << " traverser = " << quad_traverser << std::endl;
  350. std::cout << "motion blur quads:" << std::endl;
  351. std::cout << " accel = " << quad_accel_mb << std::endl;
  352. std::cout << " builder = " << quad_builder_mb << std::endl;
  353. std::cout << " traverser = " << quad_traverser_mb << std::endl;
  354. std::cout << "line segments:" << std::endl;
  355. std::cout << " accel = " << line_accel << std::endl;
  356. std::cout << " builder = " << line_builder << std::endl;
  357. std::cout << " traverser = " << line_traverser << std::endl;
  358. std::cout << "motion blur line segments:" << std::endl;
  359. std::cout << " accel = " << line_accel_mb << std::endl;
  360. std::cout << " builder = " << line_builder_mb << std::endl;
  361. std::cout << " traverser = " << line_traverser_mb << std::endl;
  362. std::cout << "hair:" << std::endl;
  363. std::cout << " accel = " << hair_accel << std::endl;
  364. std::cout << " builder = " << hair_builder << std::endl;
  365. std::cout << " traverser = " << hair_traverser << std::endl;
  366. std::cout << "motion blur hair:" << std::endl;
  367. std::cout << " accel = " << hair_accel_mb << std::endl;
  368. std::cout << " builder = " << hair_builder_mb << std::endl;
  369. std::cout << " traverser = " << hair_traverser_mb << std::endl;
  370. std::cout << "subdivision surfaces:" << std::endl;
  371. std::cout << " accel = " << subdiv_accel << std::endl;
  372. std::cout << "object_accel:" << std::endl;
  373. std::cout << " min_leaf_size = " << object_accel_min_leaf_size << std::endl;
  374. std::cout << " max_leaf_size = " << object_accel_max_leaf_size << std::endl;
  375. std::cout << "object_accel_mb:" << std::endl;
  376. std::cout << " min_leaf_size = " << object_accel_mb_min_leaf_size << std::endl;
  377. std::cout << " max_leaf_size = " << object_accel_mb_max_leaf_size << std::endl;
  378. }
  379. }