From ac441a7e8eece007375266e3d886a89014c9d046 Mon Sep 17 00:00:00 2001 From: MartinFx Date: Tue, 11 Mar 2025 22:41:38 +0100 Subject: [PATCH 1/2] support onetbb and boost 1.87.0 --- .../IECorePython/VectorTypedDataBinding.inl | 1 + .../IECoreScene/private/PrimitiveAlgoUtils.h | 144 +++++++++++++++++- include/IECoreVDB/VDBObject.h | 2 +- src/IECore/DirNameParameter.cpp | 6 +- src/IECore/FileNameParameter.cpp | 11 +- src/IECore/FileSequenceFunctions.cpp | 8 +- src/IECore/FileSequenceParameter.cpp | 11 +- src/IECore/FileSequenceVectorParameter.cpp | 12 +- src/IECore/IndexedIO.cpp | 10 +- src/IECore/IndexedIOAlgo.cpp | 73 ++++++++- src/IECore/PathParameter.cpp | 7 +- src/IECore/PathVectorParameter.cpp | 6 +- src/IECore/Reader.cpp | 10 +- src/IECore/SearchPath.cpp | 15 +- src/IECore/Writer.cpp | 18 ++- .../DeferredRendererImplementation.cpp | 119 ++++++++++++++- src/IECoreGL/Selector.cpp | 8 +- src/IECoreImage/ClientDisplayDriver.cpp | 35 ++++- src/IECoreImage/DisplayDriverServer.cpp | 50 +++++- src/IECorePythonModule/TBBBinding.cpp | 16 +- src/IECoreScene/SceneAlgo.cpp | 84 +++++++++- src/IECoreScene/SceneInterface.cpp | 13 +- 22 files changed, 625 insertions(+), 34 deletions(-) diff --git a/include/IECorePython/VectorTypedDataBinding.inl b/include/IECorePython/VectorTypedDataBinding.inl index b26410c744..6fc7a74e8e 100644 --- a/include/IECorePython/VectorTypedDataBinding.inl +++ b/include/IECorePython/VectorTypedDataBinding.inl @@ -36,6 +36,7 @@ #define IECOREPYTHON_VECTORTYPEDDATABINDING_INL #include "boost/python.hpp" +#include "boost/numeric/conversion/cast.hpp" #include "IECorePython/IECoreBinding.h" #include "IECorePython/RunTimeTypedBinding.h" diff --git a/include/IECoreScene/private/PrimitiveAlgoUtils.h b/include/IECoreScene/private/PrimitiveAlgoUtils.h index 15c107d5c8..3a2ee888f1 100644 --- a/include/IECoreScene/private/PrimitiveAlgoUtils.h +++ b/include/IECoreScene/private/PrimitiveAlgoUtils.h @@ -48,8 +48,15 @@ #include "boost/format.hpp" +#include +#if TBB_INTERFACE_VERSION >= 12040 +#include "oneapi/tbb/blocked_range.h" +#include "oneapi/tbb/parallel_for.h" +#include +#else #include "tbb/blocked_range.h" #include "tbb/parallel_for.h" +#endif #include #include @@ -174,7 +181,120 @@ struct FillVectorFromValue /// Numeric & string like arrays, which contain elements which can be added to a std::set template struct IsDeletablePrimVar : boost::mpl::or_< IECore::TypeTraits::IsStringVectorTypedData, IECore::TypeTraits::IsNumericVectorTypedData > {}; +#if TBB_INTERFACE_VERSION >= 12040 +template +class SplitTask +{ + private: + typedef typename P::Ptr Ptr; + public: + SplitTask(const std::vector &segments, typename P::Ptr primitive, const S& splitter, const std::string &primvarName, std::vector &outputPrimitives, size_t offset, size_t depth, const IECore::Canceller *canceller ) + : m_segments(segments), m_primitive(primitive), m_splitter(splitter), m_primvarName(primvarName), m_outputPrimitives( outputPrimitives ), m_offset(offset), m_depth(depth), m_canceller( canceller ) + { + } + + void execute() + { + + if ( numPrimitives ( m_primitive.get() ) == 0 && !m_segments.empty() ) + { + m_outputPrimitives[m_offset] = m_primitive; + } + + if ( m_segments.size () == 0 ) + { + return; + } + + size_t offset = m_segments.size() / 2; + typename std::vector::iterator mid = m_segments.begin() + offset; + + IECoreScene::PrimitiveVariable segmentPrimVar = m_primitive->variables.find( m_primvarName )->second; + + std::vector lowerSegments (m_segments.begin(), mid); + std::vector upperSegments (mid, m_segments.end()); + + std::set lowerSegmentsSet ( m_segments.begin(), mid ); + std::set upperSegmentsSet (mid, m_segments.end()); + + const auto &readable = IECore::runTimeCast > >( segmentPrimVar.data )->readable(); + + IECore::BoolVectorDataPtr deletionArrayLower = new IECore::BoolVectorData(); + auto &writableLower = deletionArrayLower->writable(); + + IECore::BoolVectorDataPtr deletionArrayUpper = new IECore::BoolVectorData(); + auto &writableUpper = deletionArrayUpper->writable(); + + size_t deleteCount = 0; + if( segmentPrimVar.indices ) + { + auto &readableIndices = segmentPrimVar.indices->readable(); + writableLower.resize( readableIndices.size() ); + writableUpper.resize( readableIndices.size() ); + + for( size_t i = 0; i < readableIndices.size(); ++i ) + { + size_t index = readableIndices[i]; + writableLower[i] = lowerSegmentsSet.find( readable[index] ) == lowerSegmentsSet.end(); + writableUpper[i] = upperSegmentsSet.find( readable[index] ) == upperSegmentsSet.end(); + + deleteCount += ( writableLower[i] && !lowerSegments.empty() ) || ( writableUpper[i] && !upperSegments.empty() ) ? 1 : 0; + } + } + else + { + writableLower.resize( readable.size() ); + writableUpper.resize( readable.size() ); + + for( size_t i = 0; i < readable.size(); ++i ) + { + writableLower[i] = lowerSegmentsSet.find( readable[i] ) == lowerSegmentsSet.end(); + writableUpper[i] = upperSegmentsSet.find( readable[i] ) == upperSegmentsSet.end(); + deleteCount += ( writableLower[i] && !lowerSegments.empty() ) || ( writableUpper[i] && !upperSegments.empty() ) ? 1 : 0; + } + } + + if ( m_segments.size() == 1 && deleteCount == 0) + { + m_outputPrimitives[m_offset] = m_primitive; + } + + IECoreScene::PrimitiveVariable::Interpolation i = splitPrimvarInterpolation( m_primitive.get() ); + + IECoreScene::PrimitiveVariable delPrimVarLower( i, deletionArrayLower ); + Ptr a = m_splitter( m_primitive.get(), delPrimVarLower, false, m_canceller ) ; + + IECoreScene::PrimitiveVariable delPrimVarUpper( i, deletionArrayUpper); + Ptr b = m_splitter( m_primitive.get(), delPrimVarUpper, false, m_canceller ) ; + + size_t numSplits = 2; + + oneapi::tbb::task_group tg; + tg.run([=] { + SplitTask lowerTask(lowerSegments, a, m_splitter, m_primvarName, m_outputPrimitives, m_offset, m_depth + 1, m_canceller); + lowerTask.execute(); + }); + + tg.run([=] { + SplitTask upperTask(upperSegments, b, m_splitter, m_primvarName, m_outputPrimitives, m_offset + offset, m_depth + 1, m_canceller); + upperTask.execute(); + }); + + tg.wait(); + } + private: + + std::vector m_segments; + typename P::Ptr m_primitive; + const S &m_splitter; + std::string m_primvarName; + std::vector &m_outputPrimitives; + size_t m_offset; + size_t m_depth; + const IECore::Canceller *m_canceller; +}; +#else template class SplitTask : public tbb::task { @@ -288,6 +408,7 @@ class SplitTask : public tbb::task size_t m_depth; const IECore::Canceller *m_canceller; }; +#endif template class TaskSegmenter @@ -322,6 +443,27 @@ class TaskSegmenter ReturnType results( segmentsReadable.size() ); +#if TBB_INTERFACE_VERSION >= 12040 + oneapi::tbb::task_group_context taskGroupContext(oneapi::tbb::task_group_context::isolated); + oneapi::tbb::task_group tg(taskGroupContext); + + tg.run([&] { + SplitTask task( + segmentsReadable, + const_cast(m_primitive), + m_splitter, + m_primVarName, + results, + 0, + 0, + m_canceller + ); + task.execute(); + }); + + tg.wait(); + +#else tbb::task_group_context taskGroupContext( tbb::task_group_context::isolated ); SplitTask *task = new( tbb::task::allocate_root( taskGroupContext ) ) SplitTask( segmentsReadable, @@ -334,7 +476,7 @@ class TaskSegmenter m_canceller ); tbb::task::spawn_root_and_wait( *task ); - +#endif return results; } diff --git a/include/IECoreVDB/VDBObject.h b/include/IECoreVDB/VDBObject.h index ea2f7eb650..972a1e015d 100644 --- a/include/IECoreVDB/VDBObject.h +++ b/include/IECoreVDB/VDBObject.h @@ -58,7 +58,7 @@ IECORE_PUSH_DEFAULT_VISIBILITY #endif IECORE_POP_DEFAULT_VISIBILITY -#include "tbb/recursive_mutex.h" +#include #include diff --git a/src/IECore/DirNameParameter.cpp b/src/IECore/DirNameParameter.cpp index c1e1119c33..2d057a5b7a 100644 --- a/src/IECore/DirNameParameter.cpp +++ b/src/IECore/DirNameParameter.cpp @@ -38,7 +38,11 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif #include "boost/filesystem/operations.hpp" #include diff --git a/src/IECore/FileNameParameter.cpp b/src/IECore/FileNameParameter.cpp index 6dac471876..364ce33fc0 100644 --- a/src/IECore/FileNameParameter.cpp +++ b/src/IECore/FileNameParameter.cpp @@ -39,7 +39,11 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif #include "boost/filesystem/operations.hpp" #include "boost/format.hpp" @@ -87,8 +91,11 @@ bool FileNameParameter::valueValid( const Object *value, std::string *reason ) c // extensions check if( extensions().size() ) { +#if BOOST_VERSION >= 108500 + string ext = boost::filesystem::path(boost::filesystem::path( s->readable())).extension().string(); +#else string ext = boost::filesystem::extension(boost::filesystem::path( s->readable())); - +#endif const vector &exts = extensions(); bool found = false; for( vector::const_iterator it=exts.begin(); it!=exts.end(); it++ ) diff --git a/src/IECore/FileSequenceFunctions.cpp b/src/IECore/FileSequenceFunctions.cpp index 51f1d228e7..18d190208e 100644 --- a/src/IECore/FileSequenceFunctions.cpp +++ b/src/IECore/FileSequenceFunctions.cpp @@ -42,13 +42,17 @@ #include "IECore/ReversedFrameList.h" #include "boost/algorithm/string.hpp" -#include "boost/filesystem/convenience.hpp" #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/format.hpp" #include "boost/lexical_cast.hpp" #include "boost/regex.hpp" -#include "boost/version.hpp" +#include +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif #include #include diff --git a/src/IECore/FileSequenceParameter.cpp b/src/IECore/FileSequenceParameter.cpp index 399a49cebf..b85d53f1ae 100644 --- a/src/IECore/FileSequenceParameter.cpp +++ b/src/IECore/FileSequenceParameter.cpp @@ -41,7 +41,12 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#if BOOST_VERSION >= 108500 +#include +#include +#else +#include +#endif #include #include @@ -130,7 +135,11 @@ bool FileSequenceParameter::valueValid( const Object *value, std::string *reason if ( m_extensions.size() ) { +#if BOOST_VERSION >= 108500 + std::string ext = boost::filesystem::path( boost::filesystem::path( fileSequence->getFileName() ) ).extension().string(); +#else std::string ext = boost::filesystem::extension( boost::filesystem::path( fileSequence->getFileName() ) ); +#endif if ( ext.size() && ext[0] == '.' ) { ext = ext.substr( 1, ext.size() - 1 ); diff --git a/src/IECore/FileSequenceVectorParameter.cpp b/src/IECore/FileSequenceVectorParameter.cpp index 3939b09df7..061b616b19 100644 --- a/src/IECore/FileSequenceVectorParameter.cpp +++ b/src/IECore/FileSequenceVectorParameter.cpp @@ -41,7 +41,13 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#include +#if BOOST_VERSION >= 108500 +#include +#include +#else +#include +#endif #include #include @@ -131,7 +137,11 @@ bool FileSequenceVectorParameter::valueValid( const Object *value, std::string * if ( m_extensions.size() ) { +#if BOOST_VERSION >= 108500 + std::string ext = boost::filesystem::path( boost::filesystem::path( fileSequence->getFileName())).extension().string(); +#else std::string ext = boost::filesystem::extension( boost::filesystem::path( fileSequence->getFileName() ) ); +#endif if ( ext.size() && ext[0] == '.' ) { ext = ext.substr( 1, ext.size() - 1 ); diff --git a/src/IECore/IndexedIO.cpp b/src/IECore/IndexedIO.cpp index b6af9d3bb8..7cde691e9a 100644 --- a/src/IECore/IndexedIO.cpp +++ b/src/IECore/IndexedIO.cpp @@ -33,10 +33,14 @@ ////////////////////////////////////////////////////////////////////////// #include "IECore/IndexedIO.h" - #include "IECore/Exception.h" +#include +#if BOOST_VERSION >= 108500 +#include "boost/filesystem/path.hpp" +#else #include "boost/filesystem/convenience.hpp" +#endif #include "boost/algorithm/string.hpp" #include @@ -76,7 +80,11 @@ IndexedIOPtr IndexedIO::create( const std::string &path, const IndexedIO::EntryI { IndexedIOPtr result = nullptr; +#if BOOST_VERSION >= 108500 + std::string extension = fs::path(path).extension().string(); +#else std::string extension = fs::extension(path); +#endif boost::to_lower( extension ); const CreatorMap &createFns = creators(); diff --git a/src/IECore/IndexedIOAlgo.cpp b/src/IECore/IndexedIOAlgo.cpp index 50f809d95e..418a15ed83 100644 --- a/src/IECore/IndexedIOAlgo.cpp +++ b/src/IECore/IndexedIOAlgo.cpp @@ -33,8 +33,12 @@ ////////////////////////////////////////////////////////////////////////// #include "IECore/IndexedIOAlgo.h" - +#include +#if TBB_INTERFACE_VERSION >= 12140 +#include +#else #include "tbb/task.h" +#endif #include @@ -227,6 +231,49 @@ void recursiveCopy( const IndexedIO *src, IndexedIO *dst ) } } +#if TBB_INTERFACE_VERSION >= 12040 +template class FileHandler, typename FileCallback> +class FileTask +{ +public: + FileTask(const IndexedIO* src, FileCallback& fileCallback) + : m_src(src), m_fileCallback(fileCallback) + { + } + + void operator()() const + { + IndexedIO::EntryIDList fileNames; + m_src->entryIds(fileNames, IndexedIO::EntryType::File); + + for (const auto& fileName : fileNames) + { + handleFile(m_src, nullptr, fileName, m_fileCallback); + } + + IndexedIO::EntryIDList directoryNames; + m_src->entryIds(directoryNames, IndexedIO::EntryType::Directory); + + std::vector childDirectories; + childDirectories.reserve(directoryNames.size()); + for (const auto& directoryName : directoryNames) + { + childDirectories.push_back(m_src->subdirectory(directoryName, IndexedIO::ThrowIfMissing)); + } + + oneapi::tbb::task_group tg; + for (const auto& childDirectory : childDirectories) + { + tg.run(FileTask(childDirectory.get(), m_fileCallback)); + } + tg.wait(); + } + +private: + const IndexedIO* m_src; + FileCallback& m_fileCallback; +}; +#else //! Task for traversing all files in parallel. New tasks are spawned for each directory template class FileHandler, typename FileCallback> class FileTask : public tbb::task @@ -280,7 +327,7 @@ class FileTask : public tbb::task const IndexedIO *m_src; FileCallback &m_fileCallback; }; - +#endif } // namespace namespace IECore @@ -293,6 +340,26 @@ void copy( const IndexedIO *src, IndexedIO *dst ) ::recursiveCopy( src, dst ); } +#if TBB_INTERFACE_VERSION >= 12140 +FileStats parallelReadAll(const IndexedIO* src) +{ + FileStats> fileStats; + + auto fileCallback = [&fileStats](size_t numBytes) + { + fileStats.addBlock(numBytes); + }; + + oneapi::tbb::task_group tg; + tg.run([src, &fileCallback, &tg]() + { + FileTask(src, fileCallback); + }); + tg.wait(); + + return fileStats; +} +#else FileStats parallelReadAll( const IndexedIO *src ) { FileStats > fileStats; @@ -307,6 +374,6 @@ FileStats parallelReadAll( const IndexedIO *src ) tbb::task::spawn_root_and_wait( *task ); return fileStats; } - +#endif } // IndexedIOAlgo } // IECore diff --git a/src/IECore/PathParameter.cpp b/src/IECore/PathParameter.cpp index 3743376e09..c05c6cdab9 100644 --- a/src/IECore/PathParameter.cpp +++ b/src/IECore/PathParameter.cpp @@ -38,7 +38,12 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#include +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif #include "boost/filesystem/operations.hpp" #include diff --git a/src/IECore/PathVectorParameter.cpp b/src/IECore/PathVectorParameter.cpp index 1a76aea167..9e5cc16186 100644 --- a/src/IECore/PathVectorParameter.cpp +++ b/src/IECore/PathVectorParameter.cpp @@ -38,7 +38,11 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif #include "boost/filesystem/operations.hpp" #include diff --git a/src/IECore/Reader.cpp b/src/IECore/Reader.cpp index 40e7d06d3c..7ddf1735d3 100644 --- a/src/IECore/Reader.cpp +++ b/src/IECore/Reader.cpp @@ -40,7 +40,11 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif using namespace std; using namespace IECore; @@ -84,7 +88,11 @@ ReaderPtr Reader::create( const std::string &fileName ) bool knownExtension = false; ExtensionsToFnsMap *m = extensionsToFns(); assert( m ); +#if BOOST_VERSION >= 108500 + string ext = path(boost::filesystem::path(fileName)).extension().string(); +#else string ext = extension(boost::filesystem::path(fileName)); +#endif if( ext!="" ) { ExtensionsToFnsMap::const_iterator it = m->find( ext ); diff --git a/src/IECore/SearchPath.cpp b/src/IECore/SearchPath.cpp index 372e393565..e7f6e3cdf8 100644 --- a/src/IECore/SearchPath.cpp +++ b/src/IECore/SearchPath.cpp @@ -34,6 +34,7 @@ #include "IECore/SearchPath.h" +#include "boost/version.hpp" #include "boost/filesystem/operations.hpp" #include "boost/tokenizer.hpp" @@ -106,6 +107,18 @@ std::string SearchPath::getPaths( const std::string &separator ) const boost::filesystem::path SearchPath::find( const boost::filesystem::path &file ) const { // if it's a full path then there's no need to do any searching +#if BOOST_VERSION >= 108500 + if (file.is_absolute()) { + if( exists( file ) ) + { + return file; + } + else + { + return ""; + } + } +#else if( file.is_complete() ) { if( exists( file ) ) @@ -117,7 +130,7 @@ boost::filesystem::path SearchPath::find( const boost::filesystem::path &file ) return ""; } } - +#endif // do some searching for( list::const_iterator it = paths.begin(); it!=paths.end(); it++ ) { diff --git a/src/IECore/Writer.cpp b/src/IECore/Writer.cpp index 151b6a7607..1ce200c25a 100644 --- a/src/IECore/Writer.cpp +++ b/src/IECore/Writer.cpp @@ -41,7 +41,13 @@ #include "boost/algorithm/string/classification.hpp" #include "boost/algorithm/string/split.hpp" -#include "boost/filesystem/convenience.hpp" +#include +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif + #include @@ -116,8 +122,11 @@ void Writer::registerWriter( const std::string &extensions, CanWriteFn canWrite, WriterPtr Writer::create( ObjectPtr object, const std::string &fileName ) { +#if BOOST_VERSION >= 108500 + string ext = path(boost::filesystem::path(fileName)).extension().string(); +#else string ext = extension(boost::filesystem::path(fileName)); - +#endif ExtensionsToFnsMap *m = extensionsToFns(); assert( m ); ExtensionsToFnsMap::const_iterator it = m->find( ext ); @@ -146,8 +155,11 @@ WriterPtr Writer::create( ObjectPtr object, const std::string &fileName ) WriterPtr Writer::create( const std::string &fileName ) { +#if BOOST_VERSION >= 108500 + string ext = path(boost::filesystem::path(fileName)).extension().string(); +#else string ext = extension(boost::filesystem::path(fileName)); - +#endif ExtensionsToFnsMap *m = extensionsToFns(); ExtensionsToFnsMap::const_iterator it = m->find( ext ); diff --git a/src/IECoreGL/DeferredRendererImplementation.cpp b/src/IECoreGL/DeferredRendererImplementation.cpp index 13bc67b499..3c257ea1d7 100644 --- a/src/IECoreGL/DeferredRendererImplementation.cpp +++ b/src/IECoreGL/DeferredRendererImplementation.cpp @@ -47,8 +47,14 @@ #include "boost/noncopyable.hpp" +#include +#if TBB_INTERFACE_VERSION >= 12040 +#include +#include +#else #include "tbb/task.h" #include "tbb/task_scheduler_init.h" +#endif #include @@ -354,6 +360,59 @@ struct DeferredRendererImplementation::ScopedRenderContext : private boost::nonc const char *m_msgContext; }; +#if TBB_INTERFACE_VERSION >= 12040 +class DeferredRendererImplementation::ProceduralTask : private boost::noncopyable +{ + public: + + ProceduralTask( DeferredRendererImplementation &renderer, IECoreScene::Renderer::ProceduralPtr proc, IECoreScene::RendererPtr param ) : + m_renderer(renderer), m_procedural(proc), m_param(param) + { + m_numSubtasks = 0; + RenderContext *curContext = m_renderer.currentContext(); + + // create a RenderContext for a new Procedural based on the current context + StatePtr completeState = new State( false ); + for ( StateStack::iterator it = curContext->stateStack.begin(); it != curContext->stateStack.end(); it++ ) + { + completeState->add( *it ); + } + m_proceduralContext = new RenderContext(); + m_proceduralContext->localTransform = curContext->localTransform; + m_proceduralContext->transformStack.push( curContext->transformStack.top() ); + m_proceduralContext->stateStack.push_back( completeState ); + m_proceduralContext->groupStack.push( curContext->groupStack.top() ); + } + + ~ProceduralTask() + { + } + + void execute() { + oneapi::tbb::task_group taskGroup; + + // Activate the render context on the task's thread. + ScopedRenderContext scopedProceduralContext(m_proceduralContext, m_renderer, "DeferredRendererImplementation::ProceduralTask::execute"); + m_procedural->render(m_param.get()); + + taskGroup.wait(); + } + + void addSubtask(std::function subtask) { + m_taskGroup.run(subtask); + m_numSubtasks++; + } + +private: + std::atomic m_numSubtasks; + RenderContextPtr m_proceduralContext; + DeferredRendererImplementation& m_renderer; + IECoreScene::Renderer::ProceduralPtr m_procedural; + IECoreScene::RendererPtr m_param; + oneapi::tbb::task_group m_taskGroup; + +}; +#else class DeferredRendererImplementation::ProceduralTask : public tbb::task, private boost::noncopyable { public: @@ -417,9 +476,63 @@ class DeferredRendererImplementation::ProceduralTask : public tbb::task, private IECoreScene::RendererPtr m_param; tbb::task_list *m_taskList; }; +#endif - - +#if TBB_INTERFACE_VERSION >= 12040 +void DeferredRendererImplementation::addProcedural( IECoreScene::Renderer::ProceduralPtr proc, IECoreScene::RendererPtr renderer ) +{ + bool visible = static_cast( getState( CameraVisibilityStateComponent::staticTypeId() ) )->value(); + if( !visible ) + { + return; + } + + bool withThreads = static_cast( getState( ProceduralThreadingStateComponent::staticTypeId() ) )->value(); + if( withThreads ) + { + bool mainProcedural = ( m_threadContextPool.size() == 0 ); + + if ( mainProcedural ) + { + // Vytvoření task_arena pro řízení prostředí úloh + oneapi::tbb::task_arena arena; + arena.execute([&] { + // Vytvoření task_group pro správu skupiny úloh + oneapi::tbb::task_group tg; + tg.run([&] { + // Spuštění procedurální úlohy + proc->render( renderer.get() ); + }); + tg.wait(); + }); + + // Kontrola, zda byly všechny kontexty vyčištěny + for ( const auto& context : m_threadContextPool ) + { + if ( !context.empty() ) + { + IECore::msg( IECore::Msg::Error, "DeferredRendererImplementation::procedural", "Non empty thread render context detected!" ); + } + } + m_threadContextPool.clear(); + } + else + { + // Spuštění procedurální úlohy v rámci existující task_arena + oneapi::tbb::task_group tg; + tg.run([&] { + proc->render( renderer.get() ); + }); + tg.wait(); + } + } + else + { + // Pokud není požadováno vlákno, provede se okamžitě + proc->render( renderer.get() ); + } +} +#else void DeferredRendererImplementation::addProcedural( IECoreScene::Renderer::ProceduralPtr proc, IECoreScene::RendererPtr renderer ) { bool visible = static_cast( getState( CameraVisibilityStateComponent::staticTypeId() ) )->value(); @@ -478,6 +591,8 @@ void DeferredRendererImplementation::addProcedural( IECoreScene::Renderer::Proce } } +#endif + ScenePtr DeferredRendererImplementation::scene() { return m_scene; diff --git a/src/IECoreGL/Selector.cpp b/src/IECoreGL/Selector.cpp index 53dd5d063a..79dba969c8 100644 --- a/src/IECoreGL/Selector.cpp +++ b/src/IECoreGL/Selector.cpp @@ -53,8 +53,12 @@ #include "IECore/MessageHandler.h" #include "boost/format.hpp" -#include "boost/timer.hpp" - +#include +#if BOOST_VERSION >= 107000 +#include +#else +#include +#endif using namespace IECoreGL; ////////////////////////////////////////////////////////////////////////// diff --git a/src/IECoreImage/ClientDisplayDriver.cpp b/src/IECoreImage/ClientDisplayDriver.cpp index 6358c0ff3f..e14c465301 100644 --- a/src/IECoreImage/ClientDisplayDriver.cpp +++ b/src/IECoreImage/ClientDisplayDriver.cpp @@ -42,7 +42,13 @@ // This header needs to be here so that on Windows it doesn't fail with // winsock2.h included more than once, and under the above include so that it // doesn't fail on macOS as intrusive_ptr needs to be defined via RefCounted.h -#include "boost/asio.hpp" +#include +#if BOOST_VERSION >= 106600 +#include +#include +#else +#include +#endif #include "IECoreImage/Private/DisplayDriverServerHeader.h" @@ -73,7 +79,11 @@ class ClientDisplayDriver::PrivateData : public RefCounted m_socket.close(); } +#if BOOST_VERSION >= 106600 + boost::asio::io_context m_service; +#else boost::asio::io_service m_service; +#endif std::string m_host; std::string m_port; bool m_scanLineOrderOnly; @@ -96,11 +106,33 @@ ClientDisplayDriver::ClientDisplayDriver( const Imath::Box2i &displayWindow, con m_data->m_host = displayHostData->readable(); m_data->m_port = displayPortData->readable(); +#if BOOST_VERSION >= 106600 + boost::asio::io_context io_context; + tcp::resolver resolver(io_context); + boost::system::error_code error; + auto endpoints = resolver.resolve(m_data->m_host, m_data->m_port, error); + + if (!error) + { + error = boost::asio::error::host_not_found; + for (auto it = endpoints.begin(); it != endpoints.end() && error; ++it) + { + m_data->m_socket.close(); + m_data->m_socket.connect(*it, error); + } + } + + if (error) + { + throw Exception("Could not connect to remote display driver server: " + error.message()); + } +#else tcp::resolver resolver(m_data->m_service); tcp::resolver::query query(m_data->m_host, m_data->m_port); boost::system::error_code error; tcp::resolver::iterator iterator = resolver.resolve( query, error ); + if( !error ) { error = boost::asio::error::host_not_found; @@ -114,6 +146,7 @@ ClientDisplayDriver::ClientDisplayDriver( const Imath::Box2i &displayWindow, con { throw Exception( std::string( "Could not connect to remote display driver server : " ) + error.message() ); } +#endif MemoryIndexedIOPtr io; ConstCharVectorDataPtr buf; diff --git a/src/IECoreImage/DisplayDriverServer.cpp b/src/IECoreImage/DisplayDriverServer.cpp index 3afd6b7fa1..dd3d023251 100644 --- a/src/IECoreImage/DisplayDriverServer.cpp +++ b/src/IECoreImage/DisplayDriverServer.cpp @@ -41,7 +41,14 @@ // This header needs to be here so that on Windows it doesn't fail with // winsock2.h included more than once, and under the above include so that it // doesn't fail on macOS as intrusive_ptr needs to be defined via RefCounted.h -#include "boost/asio.hpp" +#include +#if BOOST_VERSION >= 106600 +#include +#include +#else +#include +#include +#endif #include "IECoreImage/Private/DisplayDriverServerHeader.h" @@ -102,6 +109,34 @@ static std::map g_portRegistr } // namespace +#if BOOST_VERSION >= 106600 +class DisplayDriverServer::Session : public RefCounted +{ + public: + + Session( boost::asio::io_context& io_service, MergeMap& mergeMap ); + ~Session() override; + + boost::asio::ip::tcp::socket& socket(); + void start(); + + private: + + void handleReadHeader( const boost::system::error_code& error ); + void handleReadOpenParameters( const boost::system::error_code& error ); + void handleReadDataParameters( const boost::system::error_code& error ); + void sendResult( DisplayDriverServerHeader::MessageType msg, size_t dataSize ); + void sendException( const char *message ); + + private: + boost::asio::ip::tcp::socket m_socket; + DisplayDriverPtr m_displayDriver; + DisplayDriverServerHeader m_header; + CharVectorDataPtr m_buffer; + MergeMap& m_mergeMap; + std::optional m_mergeId; +}; +#else class DisplayDriverServer::Session : public RefCounted { public: @@ -128,6 +163,7 @@ class DisplayDriverServer::Session : public RefCounted MergeMap& m_mergeMap; std::optional m_mergeId; }; +#endif class DisplayDriverServer::PrivateData : public RefCounted { @@ -135,7 +171,11 @@ class DisplayDriverServer::PrivateData : public RefCounted public : boost::asio::ip::tcp::endpoint m_endpoint; +#if BOOST_VERSION >= 106600 + boost::asio::io_context m_service; +#else boost::asio::io_service m_service; +#endif boost::asio::ip::tcp::acceptor m_acceptor; std::thread m_thread; MergeMap m_mergeMap; @@ -305,11 +345,17 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session, /* * DisplayDriverServer::Session functions */ - +#if BOOST_VERSION >= 106600 +DisplayDriverServer::Session::Session( boost::asio::io_context& io_service, MergeMap& mergeMap ) : + m_socket( io_service ), m_displayDriver(nullptr), m_buffer( new CharVectorData( ) ), m_mergeMap( mergeMap ) +{ +} +#else DisplayDriverServer::Session::Session( boost::asio::io_service& io_service, MergeMap& mergeMap ) : m_socket( io_service ), m_displayDriver(nullptr), m_buffer( new CharVectorData( ) ), m_mergeMap( mergeMap ) { } +#endif DisplayDriverServer::Session::~Session() { diff --git a/src/IECorePythonModule/TBBBinding.cpp b/src/IECorePythonModule/TBBBinding.cpp index 970cca5b9e..bc3f8a7187 100644 --- a/src/IECorePythonModule/TBBBinding.cpp +++ b/src/IECorePythonModule/TBBBinding.cpp @@ -37,11 +37,14 @@ #include "boost/python.hpp" #include "TBBBinding.h" - +#include "tbb/version.h" +#if TBB_INTERFACE_VERSION >= 12040 +#include "oneapi/tbb/global_control.h" +#else #include "tbb/task_scheduler_init.h" - #define TBB_PREVIEW_GLOBAL_CONTROL 1 #include "tbb/global_control.h" +#endif #include @@ -50,6 +53,9 @@ using namespace boost::python; namespace { +#if TBB_INTERFACE_VERSION >= 12040 +// from onetbb was remove task_scheduler_init +#else // Wraps task_scheduler_init so it can be used as a python // context manager. class TaskSchedulerInitWrapper : public tbb::task_scheduler_init @@ -83,6 +89,7 @@ class TaskSchedulerInitWrapper : public tbb::task_scheduler_init int m_maxThreads; }; +#endif class GlobalControlWrapper : public boost::noncopyable { @@ -117,13 +124,16 @@ class GlobalControlWrapper : public boost::noncopyable void IECorePythonModule::bindTBB() { +#if TBB_INTERFACE_VERSION >= 12040 +// from onetbb was remove task_scheduler_init +#else object tsi = class_( "tbb_task_scheduler_init", no_init ) .def( init( arg( "max_threads" ) = int( tbb::task_scheduler_init::automatic ) ) ) .def( "__enter__", &TaskSchedulerInitWrapper::enter, return_self<>() ) .def( "__exit__", &TaskSchedulerInitWrapper::exit ) ; tsi.attr( "automatic" ) = int( tbb::task_scheduler_init::automatic ); - +#endif class_ globalControl( "tbb_global_control", no_init ); { scope globalControlScope = globalControl; diff --git a/src/IECoreScene/SceneAlgo.cpp b/src/IECoreScene/SceneAlgo.cpp index f71577fbd4..a13358f30a 100644 --- a/src/IECoreScene/SceneAlgo.cpp +++ b/src/IECoreScene/SceneAlgo.cpp @@ -39,7 +39,12 @@ #include "IECoreScene/PointsPrimitive.h" #include "IECoreScene/SceneInterface.h" +#include +#if TBB_INTERFACE_VERSION >= 12040 +#include +#else #include "tbb/task.h" +#endif #include @@ -49,6 +54,64 @@ using namespace IECoreScene; namespace { +#if TBB_INTERFACE_VERSION >= 12040 +template +class Task +{ + + public : + + Task( + const SceneInterface *src, SceneInterface *dst, LocationFn &locationFn, double time, unsigned int flags + ) : m_src( src ), m_dst( dst ), m_locationFn( locationFn ), m_time( time ), m_flags( flags ) + { + } + + ~Task() + { + } + + void operator()() const + { + m_locationFn(m_src, m_dst, m_time, m_flags); + + SceneInterface::NameList childNames; + m_src->childNames(childNames); + + std::vector childSceneInterfaces; + childSceneInterfaces.reserve(childNames.size()); + + std::vector srcChildSceneInterfaces; + srcChildSceneInterfaces.reserve(childNames.size()); + + oneapi::tbb::task_group tg; + for (const auto& childName : childNames) + { + SceneInterfacePtr dstChild = m_dst ? m_dst->child(childName, SceneInterface::CreateIfMissing) : nullptr; + if (dstChild) + { + childSceneInterfaces.push_back(dstChild); + } + + ConstSceneInterfacePtr srcChild = m_src->child(childName); + srcChildSceneInterfaces.push_back(srcChild); + + tg.run(Task(srcChild.get(), dstChild.get(), m_locationFn, m_time, m_flags)); + } + + tg.wait(); + } + + private : + + const SceneInterface *m_src; + SceneInterface *m_dst; + LocationFn &m_locationFn; + double m_time; + unsigned int m_flags; + +}; +#else template class Task : public tbb::task { @@ -108,7 +171,7 @@ class Task : public tbb::task unsigned int m_flags; }; - +#endif template struct CopyInfo { @@ -257,6 +320,21 @@ SceneStats parallelReadAll( const SceneInterface *src, int startFrame, int endFr copyInfos.pointCount += copyInfo.pointCount; }; +#if TBB_INTERFACE_VERSION >= 12040 + for (int f = startFrame; f <= endFrame; ++f) + { + double time = f / frameRate; + oneapi::tbb::task_group_context taskGroupContext(oneapi::tbb::task_group_context::isolated); + oneapi::tbb::task_group tg(taskGroupContext); + + tg.run([=, &locationFn]() { + Task task(src, nullptr, locationFn, time, flags); + task(); + }); + + tg.wait(); + } +#else for( int f = startFrame; f <= endFrame; ++f ) { double time = f / frameRate; @@ -264,7 +342,7 @@ SceneStats parallelReadAll( const SceneInterface *src, int startFrame, int endFr Task *task = new( tbb::task::allocate_root( taskGroupContext ) ) Task( src, nullptr, locationFn, time, flags ); tbb::task::spawn_root_and_wait( *task ); } - +#endif SceneStats stats; stats["locations"] = locationCount; stats["polygons"] = copyInfos.polygonCount; @@ -293,4 +371,4 @@ void copy( const SceneInterface *src, SceneInterface *dst, int startFrame, int e } // SceneAlgo -} // IECoreScene \ No newline at end of file +} // IECoreScene diff --git a/src/IECoreScene/SceneInterface.cpp b/src/IECoreScene/SceneInterface.cpp index 661d7ef276..6b9c710b67 100644 --- a/src/IECoreScene/SceneInterface.cpp +++ b/src/IECoreScene/SceneInterface.cpp @@ -34,7 +34,14 @@ #include "IECoreScene/SceneInterface.h" -#include "boost/filesystem/convenience.hpp" +#include + +#if BOOST_VERSION >= 108500 +#include +#else +#include +#endif + #include "boost/tokenizer.hpp" #include "boost/algorithm/string.hpp" @@ -104,7 +111,11 @@ SceneInterfacePtr SceneInterface::create( const std::string &path, IndexedIO::Op { SceneInterfacePtr result = nullptr; +#if BOOST_VERSION >= 108500 + std::string extension = boost::filesystem::path(path).extension().string(); +#else std::string extension = boost::filesystem::extension(path); +#endif boost::algorithm::to_lower( extension ); IndexedIO::OpenModeFlags openMode = IndexedIO::OpenModeFlags( mode & (IndexedIO::Read|IndexedIO::Write|IndexedIO::Append) ); std::pair< std::string, IndexedIO::OpenModeFlags > key( extension, openMode ); From 1dd417ff2ba0ce9d18124584cb9da008ee4ce915 Mon Sep 17 00:00:00 2001 From: MartinFx Date: Wed, 12 Mar 2025 10:41:58 +0100 Subject: [PATCH 2/2] support onetbb and boost 1.87.0 --- src/IECoreImage/ClientDisplayDriver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/IECoreImage/ClientDisplayDriver.cpp b/src/IECoreImage/ClientDisplayDriver.cpp index e14c465301..b38886fa06 100644 --- a/src/IECoreImage/ClientDisplayDriver.cpp +++ b/src/IECoreImage/ClientDisplayDriver.cpp @@ -47,6 +47,7 @@ #include #include #else +#include #include #endif