/*========================================================================= Program: Visualization Toolkit Module: vtkSMPToolsAPI.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #ifndef vtkSMPToolsAPI_h #define vtkSMPToolsAPI_h #include "vtkCommonCoreModule.h" // For export macro #include "vtkNew.h" #include "vtkObject.h" #include "vtkSMP.h" #include #include "SMP/Common/vtkSMPToolsImpl.h" #if VTK_SMP_ENABLE_SEQUENTIAL #include "SMP/Sequential/vtkSMPToolsImpl.txx" #endif #if VTK_SMP_ENABLE_STDTHREAD #include "SMP/STDThread/vtkSMPToolsImpl.txx" #endif #if VTK_SMP_ENABLE_TBB #include "SMP/TBB/vtkSMPToolsImpl.txx" #endif #if VTK_SMP_ENABLE_OPENMP #include "SMP/OpenMP/vtkSMPToolsImpl.txx" #endif namespace vtk { namespace detail { namespace smp { using vtkSMPToolsDefaultImpl = vtkSMPToolsImpl; class VTKCOMMONCORE_EXPORT vtkSMPToolsAPI { public: //-------------------------------------------------------------------------------- static vtkSMPToolsAPI& GetInstance(); //-------------------------------------------------------------------------------- BackendType GetBackendType(); //-------------------------------------------------------------------------------- const char* GetBackend(); //-------------------------------------------------------------------------------- bool SetBackend(const char* type); //-------------------------------------------------------------------------------- void Initialize(int numThreads = 0); //-------------------------------------------------------------------------------- int GetEstimatedNumberOfThreads(); //------------------------------------------------------------------------------ void SetNestedParallelism(bool isNested); //-------------------------------------------------------------------------------- bool GetNestedParallelism(); //-------------------------------------------------------------------------------- bool IsParallelScope(); //-------------------------------------------------------------------------------- int GetInternalDesiredNumberOfThread() { return this->DesiredNumberOfThread; } //------------------------------------------------------------------------------ template void LocalScope(Config const& config, T&& lambda) { const Config oldConfig(*this); *this << config; try { lambda(); } catch (...) { *this << oldConfig; throw; } *this << oldConfig; } //-------------------------------------------------------------------------------- template void For(vtkIdType first, vtkIdType last, vtkIdType grain, FunctorInternal& fi) { switch (this->ActivatedBackend) { case BackendType::Sequential: this->SequentialBackend->For(first, last, grain, fi); break; case BackendType::STDThread: this->STDThreadBackend->For(first, last, grain, fi); break; case BackendType::TBB: this->TBBBackend->For(first, last, grain, fi); break; case BackendType::OpenMP: this->OpenMPBackend->For(first, last, grain, fi); break; } } //-------------------------------------------------------------------------------- template void Transform(InputIt inBegin, InputIt inEnd, OutputIt outBegin, Functor& transform) { switch (this->ActivatedBackend) { case BackendType::Sequential: this->SequentialBackend->Transform(inBegin, inEnd, outBegin, transform); break; case BackendType::STDThread: this->STDThreadBackend->Transform(inBegin, inEnd, outBegin, transform); break; case BackendType::TBB: this->TBBBackend->Transform(inBegin, inEnd, outBegin, transform); break; case BackendType::OpenMP: this->OpenMPBackend->Transform(inBegin, inEnd, outBegin, transform); break; } } //-------------------------------------------------------------------------------- template void Transform( InputIt1 inBegin1, InputIt1 inEnd, InputIt2 inBegin2, OutputIt outBegin, Functor& transform) { switch (this->ActivatedBackend) { case BackendType::Sequential: this->SequentialBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform); break; case BackendType::STDThread: this->STDThreadBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform); break; case BackendType::TBB: this->TBBBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform); break; case BackendType::OpenMP: this->OpenMPBackend->Transform(inBegin1, inEnd, inBegin2, outBegin, transform); break; } } //-------------------------------------------------------------------------------- template void Fill(Iterator begin, Iterator end, const T& value) { switch (this->ActivatedBackend) { case BackendType::Sequential: this->SequentialBackend->Fill(begin, end, value); break; case BackendType::STDThread: this->STDThreadBackend->Fill(begin, end, value); break; case BackendType::TBB: this->TBBBackend->Fill(begin, end, value); break; case BackendType::OpenMP: this->OpenMPBackend->Fill(begin, end, value); break; } } //-------------------------------------------------------------------------------- template void Sort(RandomAccessIterator begin, RandomAccessIterator end) { switch (this->ActivatedBackend) { case BackendType::Sequential: this->SequentialBackend->Sort(begin, end); break; case BackendType::STDThread: this->STDThreadBackend->Sort(begin, end); break; case BackendType::TBB: this->TBBBackend->Sort(begin, end); break; case BackendType::OpenMP: this->OpenMPBackend->Sort(begin, end); break; } } //-------------------------------------------------------------------------------- template void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp) { switch (this->ActivatedBackend) { case BackendType::Sequential: this->SequentialBackend->Sort(begin, end, comp); break; case BackendType::STDThread: this->STDThreadBackend->Sort(begin, end, comp); break; case BackendType::TBB: this->TBBBackend->Sort(begin, end, comp); break; case BackendType::OpenMP: this->OpenMPBackend->Sort(begin, end, comp); break; } } // disable copying vtkSMPToolsAPI(vtkSMPToolsAPI const&) = delete; void operator=(vtkSMPToolsAPI const&) = delete; private: //-------------------------------------------------------------------------------- vtkSMPToolsAPI(); //-------------------------------------------------------------------------------- void RefreshNumberOfThread(); //-------------------------------------------------------------------------------- // This operator overload is used to unpack Config parameters and set them // in vtkSMPToolsAPI (e.g `*this << config;`) template vtkSMPToolsAPI& operator<<(Config const& config) { this->Initialize(config.MaxNumberOfThreads); this->SetBackend(config.Backend.c_str()); this->SetNestedParallelism(config.NestedParallelism); return *this; } /** * Indicate which backend to use. */ BackendType ActivatedBackend = DefaultBackend; /** * Max threads number */ int DesiredNumberOfThread = 0; /** * Sequential backend */ #if VTK_SMP_ENABLE_SEQUENTIAL std::unique_ptr> SequentialBackend; #else std::unique_ptr SequentialBackend; #endif /** * STDThread backend */ #if VTK_SMP_ENABLE_STDTHREAD std::unique_ptr> STDThreadBackend; #else std::unique_ptr STDThreadBackend; #endif /** * TBB backend */ #if VTK_SMP_ENABLE_TBB std::unique_ptr> TBBBackend; #else std::unique_ptr TBBBackend; #endif /** * TBB backend */ #if VTK_SMP_ENABLE_OPENMP std::unique_ptr> OpenMPBackend; #else std::unique_ptr OpenMPBackend; #endif }; } // namespace smp } // namespace detail } // namespace vtk #endif