//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt 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. // // Copyright 2015 Sandia Corporation. // Copyright 2015 UT-Battelle, LLC. // Copyright 2015 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_exec_AtomicArray_h #define vtk_m_exec_AtomicArray_h #include #include #include namespace vtkm { namespace exec { /// A class that can be used to atomically operate on an array of values /// safely across multiple instances of the same worklet. This is useful when /// you have an algorithm that needs to accumulate values in parallel, but writing /// out a value per worklet might be memory prohibitive. /// /// To construct an AtomicArray you will need to pass in an vtkm::cont::ArrayHandle /// that is used as the underlying storage for the AtomicArray /// template class AtomicArray : public vtkm::exec::ExecutionObjectBase { public: template VTKM_CONT_EXPORT AtomicArray(vtkm::cont::ArrayHandle handle): AtomicImplementation( handle ) { } VTKM_EXEC_EXPORT T Add(vtkm::Id index, const T& value) const { return this->AtomicImplementation.Add(index,value); } // // Compare and Swap is an atomic exchange operation. If the value at // the index is equal to oldValue, then newValue is written to the index. // The operation was successful if return value is eqaul to oldValue // VTKM_EXEC_EXPORT T CompareAndSwap(vtkm::Id index, const T& newValue, const T& oldValue) const { return this->AtomicImplementation.CompareAndSwap(index,newValue, oldValue); } private: vtkm::cont::DeviceAdapterAtomicArrayImplementation AtomicImplementation; }; } } // namespace vtkm::exec #endif //vtk_m_exec_AtomicArray_h