mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 18:45:43 +00:00
Merge topic 'proper_atomics_with_serial_device'
ee4e490f Moved SMP atomic operations from TBB to General. Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !357
This commit is contained in:
commit
62dd5e6a2a
@ -28,6 +28,16 @@
|
|||||||
|
|
||||||
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
|
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
|
||||||
|
|
||||||
|
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||||
|
#if defined(VTKM_MSVC)
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define NOMINMAX
|
||||||
|
#include <Windows.h>
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
#undef NOMINMAX
|
||||||
|
#endif
|
||||||
|
VTKM_THIRDPARTY_POST_INCLUDE
|
||||||
|
|
||||||
namespace vtkm {
|
namespace vtkm {
|
||||||
namespace cont {
|
namespace cont {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -710,60 +720,100 @@ class DeviceAdapterAtomicArrayImplementation
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VTKM_CONT_EXPORT
|
VTKM_CONT_EXPORT
|
||||||
DeviceAdapterAtomicArrayImplementation(vtkm::cont::ArrayHandle<T> handle):
|
DeviceAdapterAtomicArrayImplementation(
|
||||||
Portal( handle.PrepareForInPlace(DeviceTag()) )
|
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> handle):
|
||||||
|
Iterators( IteratorsType( handle.PrepareForInPlace(DeviceTag()) ) )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
VTKM_EXEC_EXPORT
|
||||||
T Add(vtkm::Id index, const T& value) const
|
T Add(vtkm::Id index, const T& value) const
|
||||||
{
|
{
|
||||||
return vtkmAtomicAdd(index, value);
|
T* lockedValue;
|
||||||
|
#if defined(VTKM_MSVC)
|
||||||
|
typedef typename vtkm::cont::ArrayPortalToIterators<PortalType>::IteratorType IteratorType;
|
||||||
|
typename IteratorType::pointer temp = &(*(Iterators.GetBegin()+index));
|
||||||
|
lockedValue = temp;
|
||||||
|
return vtkmAtomicAdd(lockedValue, value);
|
||||||
|
#else
|
||||||
|
lockedValue = (Iterators.GetBegin()+index);
|
||||||
|
return vtkmAtomicAdd(lockedValue, value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
VTKM_EXEC_EXPORT
|
||||||
T CompareAndSwap(vtkm::Id index, const T& newValue, const T& oldValue) const
|
T CompareAndSwap(vtkm::Id index, const T& newValue, const T& oldValue) const
|
||||||
{
|
{
|
||||||
return vtkmCompareAndSwap(index, newValue, oldValue);
|
T* lockedValue;
|
||||||
|
#if defined(VTKM_MSVC)
|
||||||
|
typedef typename vtkm::cont::ArrayPortalToIterators<PortalType>::IteratorType IteratorType;
|
||||||
|
typename IteratorType::pointer temp = &(*(Iterators.GetBegin()+index));
|
||||||
|
lockedValue = temp;
|
||||||
|
return vtkmCompareAndSwap(lockedValue, newValue, oldValue);
|
||||||
|
#else
|
||||||
|
lockedValue = (Iterators.GetBegin()+index);
|
||||||
|
return vtkmCompareAndSwap(lockedValue, newValue, oldValue);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef typename vtkm::cont::ArrayHandle<T>
|
typedef typename vtkm::cont::ArrayHandle<T,vtkm::cont::StorageTagBasic>
|
||||||
::template ExecutionTypes<DeviceTag>::Portal PortalType;
|
::template ExecutionTypes<DeviceTag>::Portal PortalType;
|
||||||
PortalType Portal;
|
typedef vtkm::cont::ArrayPortalToIterators<PortalType> IteratorsType;
|
||||||
|
IteratorsType Iterators;
|
||||||
|
|
||||||
|
#if defined(VTKM_MSVC) //MSVC atomics
|
||||||
VTKM_EXEC_EXPORT
|
VTKM_EXEC_EXPORT
|
||||||
vtkm::Int32 vtkmAtomicAdd(const vtkm::Id &index, const vtkm::Int32 &value) const
|
vtkm::Int32 vtkmAtomicAdd(vtkm::Int32 *address, const vtkm::Int32 &value) const
|
||||||
{
|
{
|
||||||
const vtkm::Int32 old = this->Portal.Get(index);
|
return InterlockedExchangeAdd(reinterpret_cast<volatile long *>(address),value);
|
||||||
this->Portal.Set(index, old + value);
|
|
||||||
return old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
VTKM_EXEC_EXPORT
|
||||||
vtkm::Int64 vtkmAtomicAdd(const vtkm::Id &index, const vtkm::Int64 &value) const
|
vtkm::Int64 vtkmAtomicAdd(vtkm::Int64 *address, const vtkm::Int64 &value) const
|
||||||
{
|
{
|
||||||
const vtkm::Int64 old = this->Portal.Get(index);
|
return InterlockedExchangeAdd64(reinterpret_cast<volatile long long *>(address),value);
|
||||||
this->Portal.Set(index, old + value);
|
|
||||||
return old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
VTKM_EXEC_EXPORT
|
||||||
vtkm::Int32 vtkmCompareAndSwap(const vtkm::Id &index, const vtkm::Int32 &newValue, const vtkm::Int32 &oldValue) const
|
vtkm::Int32 vtkmCompareAndSwap(vtkm::Int32 *address, const vtkm::Int32 &newValue, const vtkm::Int32 &oldValue) const
|
||||||
{
|
{
|
||||||
const vtkm::Int32 old = this->Portal.Get(index);
|
return InterlockedCompareExchange(reinterpret_cast<volatile long *>(address),newValue,oldValue);
|
||||||
if(old == oldValue) this->Portal.Set(index, newValue);
|
|
||||||
return old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
VTKM_EXEC_EXPORT
|
||||||
vtkm::Int64 vtkmCompareAndSwap(const vtkm::Id &index, const vtkm::Int64 &newValue, const vtkm::Int64 &oldValue) const
|
vtkm::Int64 vtkmCompareAndSwap(vtkm::Int64 *address,const vtkm::Int64 &newValue, const vtkm::Int64 &oldValue) const
|
||||||
{
|
{
|
||||||
const vtkm::Int64 old = this->Portal.Get(index);
|
return InterlockedCompareExchange64(reinterpret_cast<volatile long long *>(address),newValue, oldValue);
|
||||||
if(old == oldValue) this->Portal.Set(index, newValue);
|
|
||||||
return old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else //gcc built-in atomics
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
vtkm::Int32 vtkmAtomicAdd(vtkm::Int32 *address, const vtkm::Int32 &value) const
|
||||||
|
{
|
||||||
|
return __sync_fetch_and_add(address,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
vtkm::Int64 vtkmAtomicAdd(vtkm::Int64 *address, const vtkm::Int64 &value) const
|
||||||
|
{
|
||||||
|
return __sync_fetch_and_add(address,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
vtkm::Int32 vtkmCompareAndSwap(vtkm::Int32 *address, const vtkm::Int32 &newValue, const vtkm::Int32 &oldValue) const
|
||||||
|
{
|
||||||
|
return __sync_val_compare_and_swap(address,oldValue, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
vtkm::Int64 vtkmCompareAndSwap(vtkm::Int64 *address,const vtkm::Int64 &newValue, const vtkm::Int64 &oldValue) const
|
||||||
|
{
|
||||||
|
return __sync_val_compare_and_swap(address,oldValue,newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,7 @@
|
|||||||
|
|
||||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||||
|
|
||||||
// gcc || clang
|
#if defined(VTKM_MSVC)
|
||||||
#if defined(_WIN32)
|
|
||||||
// TBB includes windows.h, which clobbers min and max functions so we
|
// TBB includes windows.h, which clobbers min and max functions so we
|
||||||
// define NOMINMAX to fix that problem. We also include WIN32_LEAN_AND_MEAN
|
// define NOMINMAX to fix that problem. We also include WIN32_LEAN_AND_MEAN
|
||||||
// to reduce the number of macros and objects windows.h imports as those also
|
// to reduce the number of macros and objects windows.h imports as those also
|
||||||
@ -62,14 +61,12 @@ VTKM_THIRDPARTY_PRE_INCLUDE
|
|||||||
#include <tbb/partitioner.h>
|
#include <tbb/partitioner.h>
|
||||||
#include <tbb/tick_count.h>
|
#include <tbb/tick_count.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(VTKM_MSVC)
|
||||||
|
#include <Windows.h>
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#undef NOMINMAX
|
#undef NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(VTKM_MSVC)
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
VTKM_THIRDPARTY_POST_INCLUDE
|
VTKM_THIRDPARTY_POST_INCLUDE
|
||||||
|
|
||||||
namespace vtkm {
|
namespace vtkm {
|
||||||
@ -300,110 +297,6 @@ private:
|
|||||||
::tbb::tick_count StartTime;
|
::tbb::tick_count StartTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class DeviceAdapterAtomicArrayImplementation<T,vtkm::cont::DeviceAdapterTagTBB>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VTKM_CONT_EXPORT
|
|
||||||
DeviceAdapterAtomicArrayImplementation(
|
|
||||||
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> handle):
|
|
||||||
Iterators( IteratorsType( handle.PrepareForInPlace(
|
|
||||||
vtkm::cont::DeviceAdapterTagTBB())
|
|
||||||
) )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
T Add(vtkm::Id index, const T& value) const
|
|
||||||
{
|
|
||||||
T* lockedValue;
|
|
||||||
#if defined(VTKM_MSVC)
|
|
||||||
typedef typename vtkm::cont::ArrayPortalToIterators<PortalType>::IteratorType IteratorType;
|
|
||||||
typename IteratorType::pointer temp = &(*(Iterators.GetBegin()+index));
|
|
||||||
lockedValue = temp;
|
|
||||||
return vtkmAtomicAdd(lockedValue, value);
|
|
||||||
#else
|
|
||||||
lockedValue = (Iterators.GetBegin()+index);
|
|
||||||
return vtkmAtomicAdd(lockedValue, value);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
T CompareAndSwap(vtkm::Id index, const T& newValue, const T& oldValue) const
|
|
||||||
{
|
|
||||||
T* lockedValue;
|
|
||||||
#if defined(VTKM_MSVC)
|
|
||||||
typedef typename vtkm::cont::ArrayPortalToIterators<PortalType>::IteratorType IteratorType;
|
|
||||||
typename IteratorType::pointer temp = &(*(Iterators.GetBegin()+index));
|
|
||||||
lockedValue = temp;
|
|
||||||
return vtkmCompareAndSwap(lockedValue, newValue, oldValue);
|
|
||||||
#else
|
|
||||||
lockedValue = (Iterators.GetBegin()+index);
|
|
||||||
return vtkmCompareAndSwap(lockedValue, newValue, oldValue);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef typename vtkm::cont::ArrayHandle<T,vtkm::cont::StorageTagBasic>
|
|
||||||
::template ExecutionTypes<DeviceAdapterTagTBB>::Portal PortalType;
|
|
||||||
typedef vtkm::cont::ArrayPortalToIterators<PortalType> IteratorsType;
|
|
||||||
IteratorsType Iterators;
|
|
||||||
|
|
||||||
#if defined(VTKM_MSVC) //MSVC atomics
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int32 vtkmAtomicAdd(vtkm::Int32 *address, const vtkm::Int32 &value) const
|
|
||||||
{
|
|
||||||
return InterlockedExchangeAdd(reinterpret_cast<volatile long *>(address),value);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int64 vtkmAtomicAdd(vtkm::Int64 *address, const vtkm::Int64 &value) const
|
|
||||||
{
|
|
||||||
return InterlockedExchangeAdd64(reinterpret_cast<volatile long long *>(address),value);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int32 vtkmCompareAndSwap(vtkm::Int32 *address, const vtkm::Int32 &newValue, const vtkm::Int32 &oldValue) const
|
|
||||||
{
|
|
||||||
return InterlockedCompareExchange(reinterpret_cast<volatile long *>(address),newValue,oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int64 vtkmCompareAndSwap(vtkm::Int64 *address,const vtkm::Int64 &newValue, const vtkm::Int64 &oldValue) const
|
|
||||||
{
|
|
||||||
return InterlockedCompareExchange64(reinterpret_cast<volatile long long *>(address),newValue, oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else //gcc built-in atomics
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int32 vtkmAtomicAdd(vtkm::Int32 *address, const vtkm::Int32 &value) const
|
|
||||||
{
|
|
||||||
return __sync_fetch_and_add(address,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int64 vtkmAtomicAdd(vtkm::Int64 *address, const vtkm::Int64 &value) const
|
|
||||||
{
|
|
||||||
return __sync_fetch_and_add(address,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int32 vtkmCompareAndSwap(vtkm::Int32 *address, const vtkm::Int32 &newValue, const vtkm::Int32 &oldValue) const
|
|
||||||
{
|
|
||||||
return __sync_val_compare_and_swap(address,oldValue, newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_EXPORT
|
|
||||||
vtkm::Int64 vtkmCompareAndSwap(vtkm::Int64 *address,const vtkm::Int64 &newValue, const vtkm::Int64 &oldValue) const
|
|
||||||
{
|
|
||||||
return __sync_val_compare_and_swap(address,oldValue,newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} // namespace vtkm::cont
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user