Path: blob/master/thirdparty/embree/kernels/common/state.cpp
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#include "state.h"4#include "../../common/lexers/streamfilters.h"56namespace embree7{8MutexSys g_printMutex;910State::ErrorHandler State::g_errorHandler;1112State::ErrorHandler::ErrorHandler()13: thread_error(createTls()) {}1415State::ErrorHandler::~ErrorHandler()16{17Lock<MutexSys> lock(errors_mutex);18for (size_t i=0; i<thread_errors.size(); i++) {19delete thread_errors[i];20}21destroyTls(thread_error);22thread_errors.clear();23}2425RTCErrorMessage* State::ErrorHandler::error()26{27RTCErrorMessage* stored_error = (RTCErrorMessage*) getTls(thread_error);28if (stored_error) {29return stored_error;30}3132Lock<MutexSys> lock(errors_mutex);33stored_error = new RTCErrorMessage(RTC_ERROR_NONE, "");34thread_errors.push_back(stored_error);35setTls(thread_error,stored_error);36return stored_error;37}3839State::State ()40: enabled_cpu_features(getCPUFeatures()),41enabled_builder_cpu_features(enabled_cpu_features),42frequency_level(FREQUENCY_SIMD256)43{44tri_accel = "default";45tri_builder = "default";46tri_traverser = "default";4748tri_accel_mb = "default";49tri_builder_mb = "default";50tri_traverser_mb = "default";5152quad_accel = "default";53quad_builder = "default";54quad_traverser = "default";5556quad_accel_mb = "default";57quad_builder_mb = "default";58quad_traverser_mb = "default";5960line_accel = "default";61line_builder = "default";62line_traverser = "default";6364line_accel_mb = "default";65line_builder_mb = "default";66line_traverser_mb = "default";6768hair_accel = "default";69hair_builder = "default";70hair_traverser = "default";7172hair_accel_mb = "default";73hair_builder_mb = "default";74hair_traverser_mb = "default";7576object_accel = "default";77object_builder = "default";78object_accel_min_leaf_size = 1;79object_accel_max_leaf_size = 1;8081object_accel_mb = "default";82object_builder_mb = "default";83object_accel_mb_min_leaf_size = 1;84object_accel_mb_max_leaf_size = 1;8586max_spatial_split_replications = 1.2f;87useSpatialPreSplits = false;8889max_triangles_per_leaf = inf;9091tessellation_cache_size = 128*1024*1024;9293subdiv_accel = "default";94subdiv_accel_mb = "default";9596grid_accel = "default";97grid_builder = "default";98grid_accel_mb = "default";99grid_builder_mb = "default";100101instancing_open_min = 0;102instancing_block_size = 0;103instancing_open_factor = 8.0f;104instancing_open_max_depth = 32;105instancing_open_max = 50000000;106107float_exceptions = false;108quality_flags = -1;109scene_flags = -1;110verbose = 0;111benchmark = 0;112113numThreads = 0;114numUserThreads = 0;115116#if TASKING_INTERNAL117set_affinity = true;118#else119set_affinity = false;120#endif121122start_threads = false;123enable_selockmemoryprivilege = false;124#if defined(__LINUX__)125hugepages = true;126#else127hugepages = false;128#endif129hugepages_success = true;130131alloc_main_block_size = 0;132alloc_num_main_slots = 0;133alloc_thread_block_size = 0;134alloc_single_thread_alloc = -1;135136error_function = nullptr;137error_function_userptr = nullptr;138139memory_monitor_function = nullptr;140memory_monitor_userptr = nullptr;141}142143State::~State() {144}145146bool State::hasISA(const int isa) {147return (enabled_cpu_features & isa) == isa;148}149150bool State::checkISASupport() {151#if defined(__ARM_NEON)152/*153* NEON CPU type is a mixture of NEON and SSE2154*/155156bool hasSSE2 = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_SSE2;157158/* this will be true when explicitly initialize Device with `isa=neon` config */159bool hasNEON = (getCPUFeatures() & enabled_cpu_features) & CPU_FEATURE_NEON;160161return hasSSE2 || hasNEON;162#else163return (getCPUFeatures() & enabled_cpu_features) == enabled_cpu_features;164#endif165}166167void State::verify()168{169/* verify that calculations stay in range */170assert(rcp(min_rcp_input)*FLT_LARGE+FLT_LARGE < 0.01f*FLT_MAX);171172/* here we verify that CPP files compiled for a specific ISA only173* call that same or lower ISA version of non-inlined class member174* functions */175#if defined(DEBUG)176#if defined(EMBREE_TARGET_SSE2)177#if !defined(__ARM_NEON)178assert(sse2::getISA() <= SSE2);179#endif180#endif181#if defined(EMBREE_TARGET_SSE42)182assert(sse42::getISA() <= SSE42);183#endif184#if defined(EMBREE_TARGET_AVX)185assert(avx::getISA() <= AVX);186#endif187#if defined(EMBREE_TARGET_AVX2)188assert(avx2::getISA() <= AVX2);189#endif190#if defined (EMBREE_TARGET_AVX512)191assert(avx512::getISA() <= AVX512);192#endif193#endif194}195196const char* symbols[3] = { "=", ",", "|" };197198bool State::parseFile(const FileName& fileName)199{200Ref<Stream<int> > file;201//try {202file = new FileStream(fileName);203//}204//catch (std::runtime_error& e) {205// (void) e;206// return false;207//}208209std::vector<std::string> syms;210for (size_t i=0; i<sizeof(symbols)/sizeof(void*); i++)211syms.push_back(symbols[i]);212213Ref<TokenStream> cin = new TokenStream(new LineCommentFilter(file,"#"),214TokenStream::alpha+TokenStream::ALPHA+TokenStream::numbers+"_.",215TokenStream::separators,syms);216parse(cin);217return true;218}219220void State::parseString(const char* cfg)221{222if (cfg == nullptr) return;223224std::vector<std::string> syms;225for (size_t i=0; i<sizeof(symbols)/sizeof(void*); i++)226syms.push_back(symbols[i]);227228Ref<TokenStream> cin = new TokenStream(new StrStream(cfg),229TokenStream::alpha+TokenStream::ALPHA+TokenStream::numbers+"_.",230TokenStream::separators,syms);231parse(cin);232}233234int string_to_cpufeatures(const std::string& isa)235{236if (isa == "sse" ) return SSE;237else if (isa == "sse2") return SSE2;238else if (isa == "sse3") return SSE3;239else if (isa == "ssse3") return SSSE3;240else if (isa == "sse41") return SSE41;241else if (isa == "sse4.1") return SSE41;242else if (isa == "sse42") return SSE42;243else if (isa == "sse4.2") return SSE42;244else if (isa == "avx") return AVX;245else if (isa == "avxi") return AVXI;246else if (isa == "avx2") return AVX2;247else if (isa == "avx512") return AVX512;248else return SSE2;249}250251void State::parse(Ref<TokenStream> cin)252{253/* parse until end of stream */254while (cin->peek() != Token::Eof())255{256const Token tok = cin->get();257258if (tok == Token::Id("threads") && cin->trySymbol("="))259numThreads = cin->get().Int();260261else if (tok == Token::Id("user_threads")&& cin->trySymbol("="))262numUserThreads = cin->get().Int();263264else if (tok == Token::Id("set_affinity")&& cin->trySymbol("="))265set_affinity = cin->get().Int();266267else if (tok == Token::Id("affinity")&& cin->trySymbol("="))268set_affinity = cin->get().Int();269270else if (tok == Token::Id("start_threads")&& cin->trySymbol("="))271start_threads = cin->get().Int();272273else if (tok == Token::Id("isa") && cin->trySymbol("=")) {274std::string isa_str = toLowerCase(cin->get().Identifier());275enabled_cpu_features = string_to_cpufeatures(isa_str);276enabled_builder_cpu_features = enabled_cpu_features;277}278279else if (tok == Token::Id("max_isa") && cin->trySymbol("=")) {280std::string isa_str = toLowerCase(cin->get().Identifier());281enabled_cpu_features &= string_to_cpufeatures(isa_str);282enabled_builder_cpu_features &= enabled_cpu_features;283}284285else if (tok == Token::Id("max_builder_isa") && cin->trySymbol("=")) {286std::string isa_str = toLowerCase(cin->get().Identifier());287enabled_builder_cpu_features &= string_to_cpufeatures(isa_str);288}289290else if (tok == Token::Id("frequency_level") && cin->trySymbol("=")) {291std::string freq = cin->get().Identifier();292if (freq == "simd128") frequency_level = FREQUENCY_SIMD128;293else if (freq == "simd256") frequency_level = FREQUENCY_SIMD256;294else if (freq == "simd512") frequency_level = FREQUENCY_SIMD512;295}296297else if (tok == Token::Id("enable_selockmemoryprivilege") && cin->trySymbol("=")) {298enable_selockmemoryprivilege = cin->get().Int();299}300else if (tok == Token::Id("hugepages") && cin->trySymbol("=")) {301hugepages = cin->get().Int();302}303304else if (tok == Token::Id("float_exceptions") && cin->trySymbol("="))305float_exceptions = cin->get().Int();306307else if ((tok == Token::Id("tri_accel") || tok == Token::Id("accel")) && cin->trySymbol("="))308tri_accel = cin->get().Identifier();309else if ((tok == Token::Id("tri_builder") || tok == Token::Id("builder")) && cin->trySymbol("="))310tri_builder = cin->get().Identifier();311else if ((tok == Token::Id("tri_traverser") || tok == Token::Id("traverser")) && cin->trySymbol("="))312tri_traverser = cin->get().Identifier();313314else if ((tok == Token::Id("tri_accel_mb") || tok == Token::Id("accel_mb")) && cin->trySymbol("="))315tri_accel_mb = cin->get().Identifier();316else if ((tok == Token::Id("tri_builder_mb") || tok == Token::Id("builder_mb")) && cin->trySymbol("="))317tri_builder_mb = cin->get().Identifier();318else if ((tok == Token::Id("tri_traverser_mb") || tok == Token::Id("traverser_mb")) && cin->trySymbol("="))319tri_traverser_mb = cin->get().Identifier();320321else if ((tok == Token::Id("quad_accel")) && cin->trySymbol("="))322quad_accel = cin->get().Identifier();323else if ((tok == Token::Id("quad_builder")) && cin->trySymbol("="))324quad_builder = cin->get().Identifier();325else if ((tok == Token::Id("quad_traverser")) && cin->trySymbol("="))326quad_traverser = cin->get().Identifier();327328else if ((tok == Token::Id("quad_accel_mb")) && cin->trySymbol("="))329quad_accel_mb = cin->get().Identifier();330else if ((tok == Token::Id("quad_builder_mb")) && cin->trySymbol("="))331quad_builder_mb = cin->get().Identifier();332else if ((tok == Token::Id("quad_traverser_mb")) && cin->trySymbol("="))333quad_traverser_mb = cin->get().Identifier();334335else if ((tok == Token::Id("line_accel")) && cin->trySymbol("="))336line_accel = cin->get().Identifier();337else if ((tok == Token::Id("line_builder")) && cin->trySymbol("="))338line_builder = cin->get().Identifier();339else if ((tok == Token::Id("line_traverser")) && cin->trySymbol("="))340line_traverser = cin->get().Identifier();341342else if ((tok == Token::Id("line_accel_mb")) && cin->trySymbol("="))343line_accel_mb = cin->get().Identifier();344else if ((tok == Token::Id("line_builder_mb")) && cin->trySymbol("="))345line_builder_mb = cin->get().Identifier();346else if ((tok == Token::Id("line_traverser_mb")) && cin->trySymbol("="))347line_traverser_mb = cin->get().Identifier();348349else if (tok == Token::Id("hair_accel") && cin->trySymbol("="))350hair_accel = cin->get().Identifier();351else if (tok == Token::Id("hair_builder") && cin->trySymbol("="))352hair_builder = cin->get().Identifier();353else if (tok == Token::Id("hair_traverser") && cin->trySymbol("="))354hair_traverser = cin->get().Identifier();355356else if (tok == Token::Id("hair_accel_mb") && cin->trySymbol("="))357hair_accel_mb = cin->get().Identifier();358else if (tok == Token::Id("hair_builder_mb") && cin->trySymbol("="))359hair_builder_mb = cin->get().Identifier();360else if (tok == Token::Id("hair_traverser_mb") && cin->trySymbol("="))361hair_traverser_mb = cin->get().Identifier();362363else if (tok == Token::Id("object_accel") && cin->trySymbol("="))364object_accel = cin->get().Identifier();365else if (tok == Token::Id("object_builder") && cin->trySymbol("="))366object_builder = cin->get().Identifier();367else if (tok == Token::Id("object_accel_min_leaf_size") && cin->trySymbol("="))368object_accel_min_leaf_size = cin->get().Int();369else if (tok == Token::Id("object_accel_max_leaf_size") && cin->trySymbol("="))370object_accel_max_leaf_size = cin->get().Int();371372else if (tok == Token::Id("object_accel_mb") && cin->trySymbol("="))373object_accel_mb = cin->get().Identifier();374else if (tok == Token::Id("object_builder_mb") && cin->trySymbol("="))375object_builder_mb = cin->get().Identifier();376else if (tok == Token::Id("object_accel_mb_min_leaf_size") && cin->trySymbol("="))377object_accel_mb_min_leaf_size = cin->get().Int();378else if (tok == Token::Id("object_accel_mb_max_leaf_size") && cin->trySymbol("="))379object_accel_mb_max_leaf_size = cin->get().Int();380381else if (tok == Token::Id("instancing_open_min") && cin->trySymbol("="))382instancing_open_min = cin->get().Int();383else if (tok == Token::Id("instancing_block_size") && cin->trySymbol("=")) {384instancing_block_size = cin->get().Int();385instancing_open_factor = 0.0f;386}387else if (tok == Token::Id("instancing_open_max_depth") && cin->trySymbol("="))388instancing_open_max_depth = cin->get().Int();389else if (tok == Token::Id("instancing_open_factor") && cin->trySymbol("=")) {390instancing_block_size = 0;391instancing_open_factor = cin->get().Float();392}393else if (tok == Token::Id("instancing_open_max") && cin->trySymbol("="))394instancing_open_max = cin->get().Int();395396else if (tok == Token::Id("subdiv_accel") && cin->trySymbol("="))397subdiv_accel = cin->get().Identifier();398else if (tok == Token::Id("subdiv_accel_mb") && cin->trySymbol("="))399subdiv_accel_mb = cin->get().Identifier();400401else if (tok == Token::Id("grid_accel") && cin->trySymbol("="))402grid_accel = cin->get().Identifier();403else if (tok == Token::Id("grid_accel_mb") && cin->trySymbol("="))404grid_accel_mb = cin->get().Identifier();405406else if (tok == Token::Id("verbose") && cin->trySymbol("="))407verbose = cin->get().Int();408else if (tok == Token::Id("benchmark") && cin->trySymbol("="))409benchmark = cin->get().Int();410411else if (tok == Token::Id("quality")) {412if (cin->trySymbol("=")) {413Token flag = cin->get();414if (flag == Token::Id("low")) quality_flags = RTC_BUILD_QUALITY_LOW;415else if (flag == Token::Id("medium")) quality_flags = RTC_BUILD_QUALITY_MEDIUM;416else if (flag == Token::Id("high")) quality_flags = RTC_BUILD_QUALITY_HIGH;417}418}419420else if (tok == Token::Id("scene_flags")) {421scene_flags = 0;422if (cin->trySymbol("=")) {423do {424Token flag = cin->get();425if (flag == Token::Id("dynamic") ) scene_flags |= RTC_SCENE_FLAG_DYNAMIC;426else if (flag == Token::Id("compact")) scene_flags |= RTC_SCENE_FLAG_COMPACT;427else if (flag == Token::Id("robust")) scene_flags |= RTC_SCENE_FLAG_ROBUST;428} while (cin->trySymbol("|"));429}430}431432else if (tok == Token::Id("max_spatial_split_replications") && cin->trySymbol("="))433max_spatial_split_replications = cin->get().Float();434435else if (tok == Token::Id("max_triangles_per_leaf") && cin->trySymbol("="))436max_triangles_per_leaf = cin->get().Float();437438else if (tok == Token::Id("presplits") && cin->trySymbol("="))439useSpatialPreSplits = cin->get().Int() != 0 ? true : false;440441else if (tok == Token::Id("tessellation_cache_size") && cin->trySymbol("="))442tessellation_cache_size = size_t(cin->get().Float()*1024.0f*1024.0f);443else if (tok == Token::Id("cache_size") && cin->trySymbol("="))444tessellation_cache_size = size_t(cin->get().Float()*1024.0f*1024.0f);445446else if (tok == Token::Id("alloc_main_block_size") && cin->trySymbol("="))447alloc_main_block_size = cin->get().Int();448else if (tok == Token::Id("alloc_num_main_slots") && cin->trySymbol("="))449alloc_num_main_slots = cin->get().Int();450else if (tok == Token::Id("alloc_thread_block_size") && cin->trySymbol("="))451alloc_thread_block_size = cin->get().Int();452else if (tok == Token::Id("alloc_single_thread_alloc") && cin->trySymbol("="))453alloc_single_thread_alloc = cin->get().Int();454455cin->trySymbol(","); // optional , separator456}457}458459bool State::verbosity(size_t N) {460return N <= verbose;461}462463void State::print()464{465std::cout << "general:" << std::endl;466std::cout << " build threads = " << numThreads << std::endl;467std::cout << " build user threads = " << numUserThreads << std::endl;468std::cout << " start_threads = " << start_threads << std::endl;469std::cout << " affinity = " << set_affinity << std::endl;470std::cout << " frequency_level = ";471switch (frequency_level) {472case FREQUENCY_SIMD128: std::cout << "simd128" << std::endl; break;473case FREQUENCY_SIMD256: std::cout << "simd256" << std::endl; break;474case FREQUENCY_SIMD512: std::cout << "simd512" << std::endl; break;475default: std::cout << "error" << std::endl; break;476}477478std::cout << " hugepages = ";479if (!hugepages) std::cout << "disabled" << std::endl;480else if (hugepages_success) std::cout << "enabled" << std::endl;481else std::cout << "failed" << std::endl;482483std::cout << " verbosity = " << verbose << std::endl;484std::cout << " cache_size = " << float(tessellation_cache_size)*1E-6 << " MB" << std::endl;485std::cout << " max_spatial_split_replications = " << max_spatial_split_replications << std::endl;486487std::cout << "triangles:" << std::endl;488std::cout << " accel = " << tri_accel << std::endl;489std::cout << " builder = " << tri_builder << std::endl;490std::cout << " traverser = " << tri_traverser << std::endl;491492std::cout << "motion blur triangles:" << std::endl;493std::cout << " accel = " << tri_accel_mb << std::endl;494std::cout << " builder = " << tri_builder_mb << std::endl;495std::cout << " traverser = " << tri_traverser_mb << std::endl;496497std::cout << "quads:" << std::endl;498std::cout << " accel = " << quad_accel << std::endl;499std::cout << " builder = " << quad_builder << std::endl;500std::cout << " traverser = " << quad_traverser << std::endl;501502std::cout << "motion blur quads:" << std::endl;503std::cout << " accel = " << quad_accel_mb << std::endl;504std::cout << " builder = " << quad_builder_mb << std::endl;505std::cout << " traverser = " << quad_traverser_mb << std::endl;506507std::cout << "line segments:" << std::endl;508std::cout << " accel = " << line_accel << std::endl;509std::cout << " builder = " << line_builder << std::endl;510std::cout << " traverser = " << line_traverser << std::endl;511512std::cout << "motion blur line segments:" << std::endl;513std::cout << " accel = " << line_accel_mb << std::endl;514std::cout << " builder = " << line_builder_mb << std::endl;515std::cout << " traverser = " << line_traverser_mb << std::endl;516517std::cout << "hair:" << std::endl;518std::cout << " accel = " << hair_accel << std::endl;519std::cout << " builder = " << hair_builder << std::endl;520std::cout << " traverser = " << hair_traverser << std::endl;521522std::cout << "motion blur hair:" << std::endl;523std::cout << " accel = " << hair_accel_mb << std::endl;524std::cout << " builder = " << hair_builder_mb << std::endl;525std::cout << " traverser = " << hair_traverser_mb << std::endl;526527std::cout << "subdivision surfaces:" << std::endl;528std::cout << " accel = " << subdiv_accel << std::endl;529530std::cout << "grids:" << std::endl;531std::cout << " accel = " << grid_accel << std::endl;532std::cout << " builder = " << grid_builder << std::endl;533534std::cout << "motion blur grids:" << std::endl;535std::cout << " accel = " << grid_accel_mb << std::endl;536std::cout << " builder = " << grid_builder_mb << std::endl;537538std::cout << "object_accel:" << std::endl;539std::cout << " min_leaf_size = " << object_accel_min_leaf_size << std::endl;540std::cout << " max_leaf_size = " << object_accel_max_leaf_size << std::endl;541542std::cout << "object_accel_mb:" << std::endl;543std::cout << " min_leaf_size = " << object_accel_mb_min_leaf_size << std::endl;544std::cout << " max_leaf_size = " << object_accel_mb_max_leaf_size << std::endl;545}546}547548549