Commit cb70c136 authored by Sujin Philip's avatar Sujin Philip

Remove the Kaapi and Simple backends

This removes the Kaapi and Simple backends, as they are no longer supported.
OpenMP and TBB are the supported backends.
parent 19c75043
......@@ -27,16 +27,14 @@ set(vtkCommonCore_EXPORT_OPTIONS
)
# Choose which multi-threaded parallelism library to use
set(VTK_SMP_IMPLEMENTATION_TYPE_DOC_STRING "Which multi-threaded parallelism implementation to use. Options are Sequential, Simple, Kaapi, OpenMP or TBB")
set(VTK_SMP_IMPLEMENTATION_TYPE_DOC_STRING "Which multi-threaded parallelism implementation to use. Options are Sequential, OpenMP or TBB")
set(VTK_SMP_IMPLEMENTATION_TYPE "Sequential" CACHE STRING ${VTK_SMP_IMPLEMENTATION_TYPE_DOC_STRING})
set_property(CACHE VTK_SMP_IMPLEMENTATION_TYPE PROPERTY STRINGS Sequential Simple Kaapi OpenMP TBB)
set_property(CACHE VTK_SMP_IMPLEMENTATION_TYPE PROPERTY STRINGS Sequential OpenMP TBB)
if( NOT ("${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "Kaapi" OR
"${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "OpenMP" OR
"${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "TBB" OR
"${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "Simple") )
if( NOT ("${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "OpenMP" OR
"${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "TBB") )
set(VTK_SMP_IMPLEMENTATION_TYPE "Sequential" CACHE STRING ${VTK_SMP_IMPLEMENTATION_TYPE_DOC_STRING} FORCE)
endif()
......@@ -77,25 +75,6 @@ elseif ("${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "OpenMP")
message(WARNING "Required OpenMP version (3.1) for atomics not detected. Using default atomics implementation.")
endif()
elseif ("${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "Kaapi")
find_package(XKaapi REQUIRED)
include_directories(${XKAAPI_INCLUDE_DIRS})
set(VTK_SMP_IMPLEMENTATION_LIBRARIES ${XKAAPI_LIBRARIES})
list(APPEND vtkCommonCore_SYSTEM_INCLUDE_DIRS ${XKAAPI_INCLUDE_DIRS})
set(VTK_SMP_IMPLEMENTATION_DIR "${CMAKE_CURRENT_SOURCE_DIR}/SMP/Kaapi")
set(VTK_SMP_SOURCES ${VTK_SMP_IMPLEMENTATION_DIR}/vtkSMPTools.cxx)
set(VTK_SMP_HEADERS_TO_CONFIG vtkSMPToolsInternal.h vtkSMPThreadLocal.h)
elseif ("${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "Simple")
set(VTK_SMP_IMPLEMENTATION_LIBRARIES)
set(VTK_SMP_IMPLEMENTATION_DIR "${CMAKE_CURRENT_SOURCE_DIR}/SMP/Simple")
set(VTK_SMP_SOURCES ${VTK_SMP_IMPLEMENTATION_DIR}/vtkSMPTools.cxx)
set(VTK_SMP_HEADERS_TO_CONFIG vtkSMPToolsInternal.h vtkSMPThreadLocal.h)
message(WARNING "The Simple backend for SMP operations is an experimental backend that is mainly used for debugging currently. We recommend that you use either the TBB or the Kaapi backend for production work. Use the Sequential backend if you would like to turn off any SMP parallelism.")
elseif ("${VTK_SMP_IMPLEMENTATION_TYPE}" STREQUAL "Sequential")
set(VTK_SMP_IMPLEMENTATION_LIBRARIES)
set(VTK_SMP_IMPLEMENTATION_DIR "${CMAKE_CURRENT_SOURCE_DIR}/SMP/Sequential")
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSMPThreadLocal.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.
=========================================================================*/
// .NAME vtkSMPThreadLocal - A Kaapi based thread local storage implementation.
// .SECTION Description
// A thread local object is one that maintains a copy of an object of the
// template type for each thread that processes data. vtkSMPThreadLocal
// creates storage for all threads but the actual objects are created
// the first time Local() is called. Note that some of the vtkSMPThreadLocal
// API is not thread safe. It can be safely used in a multi-threaded
// environment because Local() returns storage specific to a particular
// thread, which by default will be accessed sequentially. It is also
// thread-safe to iterate over vtkSMPThreadLocal as long as each thread
// creates its own iterator and does not change any of the thread local
// objects.
//
// A common design pattern in using a thread local storage object is to
// write/accumulate data to local object when executing in parallel and
// then having a sequential code block that iterates over the whole storage
// using the iterators to do the final accumulation.
//
// .SECTION Warning
// There is absolutely no guarantee to the order in which the local objects
// will be stored and hence the order in which they will be traversed when
// using iterators. You should not even assume that two vtkSMPThreadLocal
// populated in the same parallel section will be populated in the same
// order. For example, consider the following
// \verbatim
// vtkSMPThreadLocal<int> Foo;
// vtkSMPThreadLocal<int> Bar;
// class AFunctor
// {
// void Initialize() const
// {
// int& foo = Foo.Local();
// int& bar = Bar.Local();
// foo = random();
// bar = foo;
// }
//
// void operator()(vtkIdType, vtkIdType) const
// {}
// };
//
// AFunctor functor;
// vtkParalllelUtilities::For(0, 100000, functor);
//
// vtkSMPThreadLocal<int>::iterator itr1 = Foo.begin();
// vtkSMPThreadLocal<int>::iterator itr2 = Bar.begin();
// while (itr1 != Foo.end())
// {
// assert(*itr1 == *itr2);
// ++itr1; ++itr2;
// }
// \endverbatim
//
// It is possible and likely that the assert() will fail using the TBB
// backend. So if you need to store values related to each other and
// iterate over them together, use a struct or class to group them together
// and use a thread local of that class.
#ifndef vtkSMPThreadLocal_h
#define vtkSMPThreadLocal_h
#include "vtkAtomicTypes.h"
#include "vtkSystemIncludes.h"
#include <vector>
#include <kaapic.h>
VTKCOMMONCORE_EXPORT void vtkSMPToolsInitialize();
template <typename T>
class vtkSMPThreadLocal
{
typedef std::vector<T> TLS;
typedef typename TLS::iterator TLSIter;
public:
// Description:
// Default constructor. Creates a default exemplar.
vtkSMPThreadLocal() : Count(0)
{
this->Initialize();
}
// Description:
// Constructor that allows the specification of an exemplar object
// which is used when constructing objects when Local() is first called.
// Note that a copy of the exemplar is created using its copy constructor.
explicit vtkSMPThreadLocal(const T& exemplar) : Count(0), Exemplar(exemplar)
{
this->Initialize();
}
// Description:
// Returns an object of type T that is local to the current thread.
// This needs to be called mainly within a threaded execution path.
// It will create a new object (local to the tread so each thread
// get their own when calling Local) which is a copy of exemplar as passed
// to the constructor (or a default object if no exemplar was provided)
// the first time it is called. After the first time, it will return
// the same object.
T& Local()
{
int tid = this->GetThreadID();
if (!this->Initialized[tid])
{
this->Internal[tid] = this->Exemplar;
this->Initialized[tid] = true;
++this->Count;
}
return this->Internal[tid];
}
// Description:
// Return the number of thread local objects that have been initialized
size_t size() const
{
return this->Count.load();
}
// Description:
// Subset of the standard iterator API.
// The most common design pattern is to use iterators in a sequential
// code block and to use only the thread local objects in parallel
// code blocks.
// It is thread safe to iterate over the thread local containers
// as long as each thread uses its own iterator and does not modify
// objects in the container.
class iterator
{
public:
iterator& operator++()
{
this->InitIter++;
this->Iter++;
// Make sure to skip uninitialized
// entries.
while(this->InitIter != this->EndIter)
{
if (*this->InitIter)
{
break;
}
this->InitIter++;
this->Iter++;
}
return *this;
}
iterator operator++(int)
{
iterator copy = *this;
++(*this);
return copy;
}
bool operator==(const iterator& other)
{
return this->Iter == other.Iter;
}
bool operator!=(const iterator& other)
{
return this->Iter != other.Iter;
}
T& operator*()
{
return *this->Iter;
}
T* operator->()
{
return &*this->Iter;
}
private:
friend class vtkSMPThreadLocal<T>;
std::vector<unsigned char>::iterator InitIter;
std::vector<unsigned char>::iterator EndIter;
TLSIter Iter;
};
// Description:
// Returns a new iterator pointing to the beginning of
// the local storage container. Thread safe.
iterator begin()
{
TLSIter iter = this->Internal.begin();
std::vector<unsigned char>::iterator iter2 =
this->Initialized.begin();
std::vector<unsigned char>::iterator enditer =
this->Initialized.end();
// fast forward to first initialized
// value
while(iter2 != enditer)
{
if (*iter2)
{
break;
}
iter2++;
iter++;
}
iterator retVal;
retVal.InitIter = iter2;
retVal.EndIter = enditer;
retVal.Iter = iter;
return retVal;
};
// Description:
// Returns a new iterator pointing to past the end of
// the local storage container. Thread safe.
iterator end()
{
iterator retVal;
retVal.InitIter = this->Initialized.end();
retVal.EndIter = this->Initialized.end();
retVal.Iter = this->Internal.end();
return retVal;
}
private:
TLS Internal;
std::vector<unsigned char> Initialized;
vtkAtomicIdType Count;
T Exemplar;
void Initialize()
{
vtkSMPToolsInitialize();
this->Internal.resize(this->GetNumberOfThreads());
this->Initialized.resize(this->GetNumberOfThreads());
std::fill(this->Initialized.begin(),
this->Initialized.end(),
false);
}
inline int GetNumberOfThreads()
{
return kaapi_getconcurrency();
}
inline int GetThreadID()
{
return kaapi_get_self_kid();
}
// disable copying
vtkSMPThreadLocal(const vtkSMPThreadLocal&);
void operator=(const vtkSMPThreadLocal&);
};
#endif
// VTK-HeaderTest-Exclude: vtkSMPThreadLocal.h
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSMPTools.cxx
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.
=========================================================================*/
#include "vtkSMPTools.h"
#include "vtkCriticalSection.h"
#include <kaapic.h>
VTKCOMMONCORE_EXPORT void vtkSMPToolsInitialize()
{
vtkSMPTools::Initialize(0);
}
struct vtkSMPToolsInit
{
vtkSMPToolsInit()
{
kaapic_init(KAAPIC_START_ONLY_MAIN);
}
~vtkSMPToolsInit()
{
kaapic_finalize();
}
};
static bool vtkSMPToolsInitialized = 0;
static vtkSimpleCriticalSection vtkSMPToolsCS;
//--------------------------------------------------------------------------------
void vtkSMPTools::Initialize(int)
{
vtkSMPToolsCS.Lock();
if (!vtkSMPToolsInitialized)
{
static vtkSMPToolsInit aInit;
vtkSMPToolsInitialized = true;
}
vtkSMPToolsCS.Unlock();
}
int vtkSMPTools::GetEstimatedNumberOfThreads()
{
return kaapic_get_concurrency();
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSMPToolsInternal.h.in
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.
=========================================================================*/
#include <kaapic.h>
#include <algorithm> //for std::sort()
VTKCOMMONCORE_EXPORT void vtkSMPToolsInitialize();
namespace vtk
{
namespace detail
{
namespace smp
{
template <typename T>
inline void vtkSMPToolsDoFor(int32_t b, int32_t e, int32_t, T* o )
{
o->Execute(b, e);
}
template <typename FunctorInternal>
static void vtkSMPTools_Impl_For(
vtkIdType first, vtkIdType last, vtkIdType grain,
FunctorInternal& fi)
{
vtkSMPToolsInitialize();
vtkIdType n = last - first;
if (!n)
{
return;
}
vtkIdType g = grain ? grain : sqrt(n);
kaapic_begin_parallel(KAAPIC_FLAG_DEFAULT);
kaapic_foreach_attr_t attr;
kaapic_foreach_attr_init(&attr);
kaapic_foreach_attr_set_grains(&attr, g, g);
kaapic_foreach( first, last, &attr, 1, vtkSMPToolsDoFor<FunctorInternal>, &fi );
kaapic_end_parallel(KAAPIC_FLAG_DEFAULT);
kaapic_foreach_attr_destroy(&attr);
}
//--------------------------------------------------------------------------------
template<typename RandomAccessIterator>
static void vtkSMPTools_Impl_Sort(RandomAccessIterator begin,
RandomAccessIterator end)
{
std::sort(begin, end);
}
//--------------------------------------------------------------------------------
template<typename RandomAccessIterator, typename Compare>
static void vtkSMPTools_Impl_Sort(RandomAccessIterator begin,
RandomAccessIterator end,
Compare comp)
{
std::sort(begin, end, comp);
}
}//namespace smp
}//namespace detail
}//namespace vtk
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSMPThreadLocal.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.
=========================================================================*/
// .NAME vtkSMPThreadLocal - A simple thread local implementation for simple parallelism.
// .SECTION Description
// A thread local object is one that maintains a copy of an object of the
// template type for each thread that processes data. vtkSMPThreadLocal
// creates storage for all threads but the actual objects are created
// the first time Local() is called. Note that some of the vtkSMPThreadLocal
// API is not thread safe. It can be safely used in a multi-threaded
// environment because Local() returns storage specific to a particular
// thread, which by default will be accessed sequentially. It is also
// thread-safe to iterate over vtkSMPThreadLocal as long as each thread
// creates its own iterator and does not change any of the thread local
// objects.
//
// A common design pattern in using a thread local storage object is to
// write/accumulate data to local object when executing in parallel and
// then having a sequential code block that iterates over the whole storage
// using the iterators to do the final accumulation.
//
// Note that this particular implementation is designed to work in simple
// parallel mode which was mainly designed for debugging purposes.
//
// .SECTION Warning
// There is absolutely no guarantee to the order in which the local objects
// will be stored and hence the order in which they will be traversed when
// using iterators. You should not even assume that two vtkSMPThreadLocal
// populated in the same parallel section will be populated in the same
// order. For example, consider the following
// \verbatim
// vtkSMPThreadLocal<int> Foo;
// vtkSMPThreadLocal<int> Bar;
// class AFunctor
// {
// void Initialize() const
// {
// int& foo = Foo.Local();
// int& bar = Bar.Local();
// foo = random();
// bar = foo;
// }
//
// void operator()(vtkIdType, vtkIdType) const
// {}
// };
//
// AFunctor functor;
// vtkParalllelUtilities::For(0, 100000, functor);
//
// vtkSMPThreadLocal<int>::iterator itr1 = Foo.begin();
// vtkSMPThreadLocal<int>::iterator itr2 = Bar.begin();
// while (itr1 != Foo.end())
// {
// assert(*itr1 == *itr2);
// ++itr1; ++itr2;
// }
// \endverbatim
//
// It is possible and likely that the assert() will fail using the TBB
// backend. So if you need to store values related to each other and
// iterate over them together, use a struct or class to group them together
// and use a thread local of that class.
#ifndef vtkSMPThreadLocal_h
#define vtkSMPThreadLocal_h
#include "vtkCommonCoreModule.h" // For export macro
#include "vtkAtomicTypes.h"
#include "vtkSystemIncludes.h"
#include "vtkMultiThreader.h"
#include <vector>
VTKCOMMONCORE_EXPORT int vtkSMPToolsGetNumberOfThreads();
VTKCOMMONCORE_EXPORT int vtkSMPToolsGetThreadID();
template <typename T>
class vtkSMPThreadLocal
{
typedef std::vector<T> TLS;
typedef typename TLS::iterator TLSIter;
public:
// Description:
// Default constructor. Creates a default exemplar.
vtkSMPThreadLocal() : Count(0)
{
this->Initialize();
}
// Description:
// Constructor that allows the specification of an exemplar object
// which is used when constructing objects when Local() is first called.
// Note that a copy of the exemplar is created using its copy constructor.
explicit vtkSMPThreadLocal(const T& exemplar) : Count(0), Exemplar(exemplar)
{
this->Initialize();
}
// Description:
// Returns an object of type T that is local to the current thread.
// This needs to be called mainly within a threaded execution path.
// It will create a new object (local to the tread so each thread
// get their own when calling Local) which is a copy of exemplar as passed
// to the constructor (or a default object if no exemplar was provided)
// the first time it is called. After the first time, it will return
// the same object.
T& Local()
{
int tid = this->GetThreadID();
if (!this->Initialized[tid])
{
this->Internal[tid] = this->Exemplar;
this->Initialized[tid] = true;
++this->Count;
}
return this->Internal[tid];
}
// Description:
// Return the number of thread local objects that have been initialized
size_t size() const
{
return this->Count.load();
}
// Description:
// Subset of the standard iterator API.
// The most common design pattern is to use iterators in a sequential
// code block and to use only the thread local objects in parallel
// code blocks.
// It is thread safe to iterate over the thread local containers
// as long as each thread uses its own iterator and does not modify
// objects in the container.
class iterator
{
public:
iterator& operator++()
{
this->InitIter++;
this->Iter++;
// Make sure to skip uninitialized
// entries.
while(this->InitIter != this->EndIter)
{
if (*this->InitIter)
{
break;
}
this->InitIter++;
this->Iter++;
}
return *this;
}
iterator operator++(int)
{
iterator copy = *this;
++(*this);
return copy;
}
bool operator==(const iterator& other)
{
return this->Iter == other.Iter;
}
bool operator!=(const iterator& other)
{
return this->Iter != other.Iter;
}
T& operator*()
{
return *this->Iter;
}
T* operator->()
{
return &*this->Iter;
}
private:
friend class vtkSMPThreadLocal<T>;
std::vector<unsigned char>::iterator InitIter;
std::vector<unsigned char>::iterator EndIter;
TLSIter Iter;
};
// Description:
// Returns a new iterator pointing to the beginning of
// the local storage container. Thread safe.
iterator begin()
{
TLSIter iter = this->Internal.begin();
std::vector<unsigned char>::iterator iter2 =
this->Initialized.begin();
std::vector<unsigned char>::iterator enditer =
this->Initialized.end();
// fast forward to first initialized
// value
while(iter2 != enditer)
{
if (*iter2)
{
break;
}
iter2++;
iter++;
}
iterator retVal;
retVal.InitIter = iter2;
retVal.EndIter = enditer;
retVal.Iter = iter;
return retVal;
};
// Description:
// Returns a new iterator pointing to past the end of
// the local storage container. Thread safe.
iterator end()
{
iterator retVal;
retVal.InitIter = this->Initialized.end();
retVal.EndIter = this->Initialized.end();
retVal.Iter = this->Internal.end();
return retVal;
}
private:
TLS Internal;
std::vector<unsigned char> Initialized;
vtkAtomicIdType Count;
T Exemplar;
void Initialize()
{
int numThreads = vtkSMPToolsGetNumberOfThreads();
this->Internal.resize(numThreads);
this->Initialized.resize(numThreads);
std::fill(this->Initialized.begin(),
this->Initialized.end(),
false);
}
inline int GetThreadID()
{
return vtkSMPToolsGetThreadID();
}
// disable copying
vtkSMPThreadLocal(const vtkSMPThreadLocal&);
void operator=(const vtkSMPThreadLocal&);
};
#endif
// VTK-HeaderTest-Exclude: vtkSMPThreadLocal.h
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSMPTools.cxx
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.
=========================================================================*/
#include "vtkSMPTools.h"
#include "vtkObjectFactory.h"
#include <pthread.h>
static bool vtkSMPToolsInitialized = false;
static int vtkSMPToolsNumberOfThreads = 0;
static std::vector<vtkMultiThreaderIDType> vtkSMPToolsThreadIds;
//static pthread_barrier_t barr;
VTKCOMMONCORE_EXPORT void vtkSMPToolsInitialize()
{
vtkSMPTools::Initialize();
}
VTKCOMMONCORE_EXPORT int vtkSMPToolsGetNumberOfThreads()