mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 21:33:55 +00:00
Merge topic 'switch-to-new-arrayhandle'
3228752b2 Fix error message when using deprecated storage 5ef4e7eee Make new style of ArrayHandle the expected style Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Robert Maynard <robert.maynard@kitware.com> Merge-request: !2375
This commit is contained in:
commit
7a3f20560a
@ -16,6 +16,8 @@
|
||||
#include <vtkm/cont/ErrorExecution.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
|
||||
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
// TODO: When virtual arrays are available, compile the implementation in a .cxx/.cu file. Common
|
||||
@ -149,11 +151,12 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>&
|
||||
"Cannot copy to a read-only array with a different "
|
||||
"type than the source.");
|
||||
|
||||
using IsNewStyle =
|
||||
std::is_base_of<vtkm::cont::ArrayHandleNewStyle<InValueType, InStorage>, InArrayType>;
|
||||
using IsOldStyle =
|
||||
std::is_base_of<vtkm::cont::internal::ArrayHandleDeprecated<InValueType, InStorage>,
|
||||
InArrayType>;
|
||||
|
||||
// Static dispatch cases 1 & 2
|
||||
detail::ArrayCopyImpl(source, destination, std::integral_constant<bool, IsNewStyle::value>{});
|
||||
detail::ArrayCopyImpl(source, destination, std::integral_constant<bool, !IsOldStyle::value>{});
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <vtkm/Flags.h>
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/DeviceAdapterList.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/ErrorInternal.h>
|
||||
@ -33,10 +32,7 @@
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayHandleExecutionManager.h>
|
||||
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
|
||||
#include <vtkm/cont/internal/Buffer.h>
|
||||
#include <vtkm/cont/internal/StorageDeprecated.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -256,652 +252,6 @@ struct GetTypeInParentheses<void(T)>
|
||||
#define VTKM_ARRAY_HANDLE_SUBCLASS_NT(classname, superclass) \
|
||||
VTK_M_ARRAY_HANDLE_SUBCLASS_IMPL(classname, (classname), superclass, )
|
||||
|
||||
/// \brief Manages an array-worth of data.
|
||||
///
|
||||
/// \c ArrayHandle manages as array of data that can be manipulated by VTKm
|
||||
/// algorithms. The \c ArrayHandle may have up to two copies of the array, one
|
||||
/// for the control environment and one for the execution environment, although
|
||||
/// depending on the device and how the array is being used, the \c ArrayHandle
|
||||
/// will only have one copy when possible.
|
||||
///
|
||||
/// An ArrayHandle can be constructed one of two ways. Its default construction
|
||||
/// creates an empty, unallocated array that can later be allocated and filled
|
||||
/// either by the user or a VTKm algorithm. The \c ArrayHandle can also be
|
||||
/// constructed with iterators to a user's array. In this case the \c
|
||||
/// ArrayHandle will keep a reference to this array but will throw an exception
|
||||
/// if asked to re-allocate to a larger size.
|
||||
///
|
||||
/// \c ArrayHandle behaves like a shared smart pointer in that when it is copied
|
||||
/// each copy holds a reference to the same array. These copies are reference
|
||||
/// counted so that when all copies of the \c ArrayHandle are destroyed, any
|
||||
/// allocated memory is released.
|
||||
///
|
||||
///
|
||||
template <typename T, typename StorageTag_ = VTKM_DEFAULT_STORAGE_TAG>
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandle : public internal::ArrayHandleBase
|
||||
{
|
||||
private:
|
||||
// Basic storage is specialized; this template should not be instantiated
|
||||
// for it. Specialization is in ArrayHandleBasicImpl.h
|
||||
static_assert(!std::is_same<StorageTag_, StorageTagBasic>::value,
|
||||
"StorageTagBasic should not use this implementation.");
|
||||
|
||||
using ExecutionManagerType =
|
||||
vtkm::cont::internal::ArrayHandleExecutionManagerBase<T, StorageTag_>;
|
||||
|
||||
using MutexType = std::mutex;
|
||||
using LockType = std::unique_lock<MutexType>;
|
||||
|
||||
mutable vtkm::cont::internal::Buffer BufferAsStorageWrapper;
|
||||
|
||||
public:
|
||||
using StorageType = vtkm::cont::internal::Storage<T, StorageTag_>;
|
||||
using ValueType = T;
|
||||
using StorageTag = StorageTag_;
|
||||
using WritePortalType = typename StorageType::PortalType;
|
||||
using ReadPortalType = typename StorageType::PortalConstType;
|
||||
template <typename DeviceAdapterTag>
|
||||
struct ExecutionTypes
|
||||
{
|
||||
using Portal = typename ExecutionManagerType::template ExecutionTypes<DeviceAdapterTag>::Portal;
|
||||
using PortalConst =
|
||||
typename ExecutionManagerType::template ExecutionTypes<DeviceAdapterTag>::PortalConst;
|
||||
};
|
||||
|
||||
using PortalControl VTKM_DEPRECATED(1.6, "Use ArrayHandle::WritePortalType instead.") =
|
||||
typename StorageType::PortalType;
|
||||
using PortalConstControl VTKM_DEPRECATED(1.6, "Use ArrayHandle::ReadPortalType instead.") =
|
||||
typename StorageType::PortalConstType;
|
||||
|
||||
// Handle the fact that the ArrayHandle design has changed.
|
||||
VTKM_STATIC_ASSERT_MSG((std::is_same<typename StorageType::HasOldBridge, std::true_type>::value),
|
||||
"ArrayHandle design has changed. To support old-style arrays, have the "
|
||||
"Storage implementation subclass StorageDeprecated.");
|
||||
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers() { return 1; }
|
||||
VTKM_CONT vtkm::cont::internal::Buffer* GetBuffers() const
|
||||
{
|
||||
this->BufferAsStorageWrapper.SetMetaData(*this);
|
||||
return &this->BufferAsStorageWrapper;
|
||||
}
|
||||
|
||||
VTKM_CONT ArrayHandle(const vtkm::cont::internal::Buffer* buffers)
|
||||
{
|
||||
VTKM_ASSERT(buffers[0].MetaDataIsType<ArrayHandle>());
|
||||
*this = buffers[0].GetMetaData<ArrayHandle>();
|
||||
}
|
||||
|
||||
/// Constructs an empty ArrayHandle. Typically used for output or
|
||||
/// intermediate arrays that will be filled by a VTKm algorithm.
|
||||
///
|
||||
VTKM_CONT ArrayHandle();
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
/// Implemented so that it is defined exclusively in the control environment.
|
||||
/// If there is a separate device for the execution environment (for example,
|
||||
/// with CUDA), then the automatically generated copy constructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
ArrayHandle(const vtkm::cont::ArrayHandle<ValueType, StorageTag>& src);
|
||||
|
||||
/// Move constructor.
|
||||
///
|
||||
/// Implemented so that it is defined exclusively in the control environment.
|
||||
/// If there is a separate device for the execution environment (for example,
|
||||
/// with CUDA), then the automatically generated move constructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
ArrayHandle(vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src) noexcept;
|
||||
|
||||
/// Special constructor for subclass specializations that need to set the
|
||||
/// initial state of the control array. When this constructor is used, it
|
||||
/// is assumed that the control array is valid.
|
||||
///
|
||||
ArrayHandle(const StorageType& storage);
|
||||
|
||||
|
||||
/// Special constructor for subclass specializations that need to set the
|
||||
/// initial state of the control array. When this constructor is used, it
|
||||
/// is assumed that the control array is valid.
|
||||
///
|
||||
ArrayHandle(StorageType&& storage) noexcept;
|
||||
|
||||
/// Destructs an empty ArrayHandle.
|
||||
///
|
||||
/// Implemented so that it is defined exclusively in the control environment.
|
||||
/// If there is a separate device for the execution environment (for example,
|
||||
/// with CUDA), then the automatically generated destructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
~ArrayHandle();
|
||||
|
||||
/// \brief Copies an ArrayHandle
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
|
||||
const vtkm::cont::ArrayHandle<ValueType, StorageTag>& src);
|
||||
|
||||
/// \brief Move and Assignment of an ArrayHandle
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src) noexcept;
|
||||
|
||||
/// Like a pointer, two \c ArrayHandles are considered equal if they point
|
||||
/// to the same location in memory.
|
||||
///
|
||||
VTKM_CONT
|
||||
bool operator==(const ArrayHandle<ValueType, StorageTag>& rhs) const
|
||||
{
|
||||
return (this->Internals == rhs.Internals);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
bool operator!=(const ArrayHandle<ValueType, StorageTag>& rhs) const
|
||||
{
|
||||
return (this->Internals != rhs.Internals);
|
||||
}
|
||||
|
||||
template <typename VT, typename ST>
|
||||
VTKM_CONT bool operator==(const ArrayHandle<VT, ST>&) const
|
||||
{
|
||||
return false; // different valuetype and/or storage
|
||||
}
|
||||
|
||||
template <typename VT, typename ST>
|
||||
VTKM_CONT bool operator!=(const ArrayHandle<VT, ST>&) const
|
||||
{
|
||||
return true; // different valuetype and/or storage
|
||||
}
|
||||
|
||||
/// Get the storage.
|
||||
///
|
||||
VTKM_CONT StorageType& GetStorage();
|
||||
|
||||
/// Get the storage.
|
||||
///
|
||||
VTKM_CONT const StorageType& GetStorage() const;
|
||||
|
||||
/// Get the array portal of the control array.
|
||||
/// Since worklet invocations are asynchronous and this routine is a synchronization point,
|
||||
/// exceptions maybe thrown for errors from previously executed worklets.
|
||||
///
|
||||
/// \deprecated Use `WritePortal` instead. Note that the portal returned from `WritePortal`
|
||||
/// will disallow any other reads or writes to the array while it is in scope.
|
||||
///
|
||||
VTKM_CONT
|
||||
VTKM_DEPRECATED(1.6,
|
||||
"Use ArrayHandle::WritePortal() instead. "
|
||||
"Note that the returned portal will lock the array while it is in scope.")
|
||||
|
||||
/// \cond NOPE
|
||||
typename StorageType::PortalType GetPortalControl();
|
||||
/// \endcond
|
||||
|
||||
/// Get the array portal of the control array.
|
||||
/// Since worklet invocations are asynchronous and this routine is a synchronization point,
|
||||
/// exceptions maybe thrown for errors from previously executed worklets.
|
||||
///
|
||||
/// \deprecated Use `ReadPortal` instead. Note that the portal returned from `ReadPortal`
|
||||
/// will disallow any writes to the array while it is in scope.
|
||||
///
|
||||
VTKM_CONT
|
||||
VTKM_DEPRECATED(1.6,
|
||||
"Use ArrayHandle::ReadPortal() instead. "
|
||||
"Note that the returned portal will lock the array while it is in scope.")
|
||||
/// \cond NOPE
|
||||
typename StorageType::PortalConstType GetPortalConstControl() const;
|
||||
/// \endcond
|
||||
|
||||
/// \@{
|
||||
/// \brief Get an array portal that can be used in the control environment.
|
||||
///
|
||||
/// The returned array can be used in the control environment to read values from the array. (It
|
||||
/// is not possible to write to the returned portal. That is `Get` will work on the portal, but
|
||||
/// `Set` will not.)
|
||||
///
|
||||
/// **Note:** The returned portal cannot be used in the execution environment. This is because
|
||||
/// the portal will not work on some devices like GPUs. To get a portal that will work in the
|
||||
/// execution environment, use `PrepareForInput`.
|
||||
///
|
||||
VTKM_CONT ReadPortalType ReadPortal() const;
|
||||
/// \@}
|
||||
|
||||
/// \@{
|
||||
/// \brief Get an array portal that can be used in the control environment.
|
||||
///
|
||||
/// The returned array can be used in the control environment to reand and write values to the
|
||||
/// array.
|
||||
///
|
||||
///
|
||||
/// **Note:** The returned portal cannot be used in the execution environment. This is because
|
||||
/// the portal will not work on some devices like GPUs. To get a portal that will work in the
|
||||
/// execution environment, use `PrepareForInput`.
|
||||
///
|
||||
VTKM_CONT WritePortalType WritePortal() const;
|
||||
/// \@}
|
||||
|
||||
/// Returns the number of entries in the array.
|
||||
///
|
||||
VTKM_CONT vtkm::Id GetNumberOfValues() const
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
return this->GetNumberOfValues(lock);
|
||||
}
|
||||
|
||||
/// \brief Allocates an array large enough to hold the given number of values.
|
||||
///
|
||||
/// The allocation may be done on an already existing array, but can wipe out
|
||||
/// any data already in the array. This method can throw
|
||||
/// ErrorBadAllocation if the array cannot be allocated or
|
||||
/// ErrorBadValue if the allocation is not feasible (for example, the
|
||||
/// array storage is read-only).
|
||||
///
|
||||
VTKM_CONT
|
||||
void Allocate(vtkm::Id numberOfValues)
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Allocate(numberOfValues, token);
|
||||
}
|
||||
VTKM_CONT void Allocate(vtkm::Id numberOfValues, vtkm::cont::Token& token)
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToWrite(lock, token);
|
||||
this->ReleaseResourcesExecutionInternal(lock, token);
|
||||
this->Internals->GetControlArray(lock)->Allocate(numberOfValues);
|
||||
// Set to false and then to true to ensure anything pointing to an array before the allocate
|
||||
// is invalidated.
|
||||
this->Internals->SetControlArrayValid(lock, false);
|
||||
this->Internals->SetControlArrayValid(lock, true);
|
||||
}
|
||||
|
||||
/// \brief Reduces the size of the array without changing its values.
|
||||
///
|
||||
/// This method allows you to resize the array without reallocating it. The
|
||||
/// number of entries in the array is changed to \c numberOfValues. The data
|
||||
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
|
||||
/// \c numberOfValues must be equal or less than the preexisting size
|
||||
/// (returned from GetNumberOfValues). That is, this method can only be used
|
||||
/// to shorten the array, not lengthen.
|
||||
VTKM_CONT void Shrink(vtkm::Id numberOfValues)
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Shrink(numberOfValues, token);
|
||||
}
|
||||
VTKM_CONT void Shrink(vtkm::Id numberOfValues, vtkm::cont::Token& token);
|
||||
|
||||
/// Releases any resources being used in the execution environment (that are
|
||||
/// not being shared by the control environment).
|
||||
///
|
||||
VTKM_CONT void ReleaseResourcesExecution()
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToWrite(lock, token);
|
||||
|
||||
// Save any data in the execution environment by making sure it is synced
|
||||
// with the control environment.
|
||||
this->SyncControlArray(lock, token);
|
||||
|
||||
this->ReleaseResourcesExecutionInternal(lock, token);
|
||||
}
|
||||
}
|
||||
|
||||
/// Releases all resources in both the control and execution environments.
|
||||
///
|
||||
VTKM_CONT void ReleaseResources()
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
this->ReleaseResourcesExecutionInternal(lock, token);
|
||||
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
this->Internals->GetControlArray(lock)->ReleaseResources();
|
||||
this->Internals->SetControlArrayValid(lock, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Prepares this array to be used as an input to an operation in the
|
||||
/// execution environment. If necessary, copies data to the execution
|
||||
/// environment. Can throw an exception if this array does not yet contain
|
||||
/// any data. Returns a portal that can be used in code running in the
|
||||
/// execution environment.
|
||||
///
|
||||
/// The `Token` object provided will be attached to this `ArrayHandle`.
|
||||
/// The returned portal is guaranteed to be valid while the `Token` is
|
||||
/// still attached and in scope. Other operations on this `ArrayHandle`
|
||||
/// that would invalidate the returned portal will block until the `Token`
|
||||
/// is released. Likewise, this method will block if another `Token` is
|
||||
/// already attached. This can potentially lead to deadlocks.
|
||||
///
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::PortalConst PrepareForInput(
|
||||
DeviceAdapterTag,
|
||||
vtkm::cont::Token& token) const;
|
||||
|
||||
/// Prepares (allocates) this array to be used as an output from an operation
|
||||
/// in the execution environment. The internal state of this class is set to
|
||||
/// have valid data in the execution array with the assumption that the array
|
||||
/// will be filled soon (i.e. before any other methods of this object are
|
||||
/// called). Returns a portal that can be used in code running in the
|
||||
/// execution environment.
|
||||
///
|
||||
/// The `Token` object provided will be attached to this `ArrayHandle`.
|
||||
/// The returned portal is guaranteed to be valid while the `Token` is
|
||||
/// still attached and in scope. Other operations on this `ArrayHandle`
|
||||
/// that would invalidate the returned portal will block until the `Token`
|
||||
/// is released. Likewise, this method will block if another `Token` is
|
||||
/// already attached. This can potentially lead to deadlocks.
|
||||
///
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal
|
||||
PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag, vtkm::cont::Token& token);
|
||||
|
||||
/// Prepares this array to be used in an in-place operation (both as input
|
||||
/// and output) in the execution environment. If necessary, copies data to
|
||||
/// the execution environment. Can throw an exception if this array does not
|
||||
/// yet contain any data. Returns a portal that can be used in code running
|
||||
/// in the execution environment.
|
||||
///
|
||||
/// The `Token` object provided will be attached to this `ArrayHandle`.
|
||||
/// The returned portal is guaranteed to be valid while the `Token` is
|
||||
/// still attached and in scope. Other operations on this `ArrayHandle`
|
||||
/// that would invalidate the returned portal will block until the `Token`
|
||||
/// is released. Likewise, this method will block if another `Token` is
|
||||
/// already attached. This can potentially lead to deadlocks.
|
||||
///
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal PrepareForInPlace(
|
||||
DeviceAdapterTag,
|
||||
vtkm::cont::Token& token);
|
||||
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInput now requires a vtkm::cont::Token object.")
|
||||
typename ExecutionTypes<DeviceAdapterTag>::PortalConst PrepareForInput(DeviceAdapterTag) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
return this->PrepareForInput(DeviceAdapterTag{}, token);
|
||||
}
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForOutput now requires a vtkm::cont::Token object.")
|
||||
typename ExecutionTypes<DeviceAdapterTag>::Portal
|
||||
PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag)
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
return this->PrepareForOutput(numberOfValues, DeviceAdapterTag{}, token);
|
||||
}
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT VTKM_DEPRECATED(1.6, "PrepareForInPlace now requires a vtkm::cont::Token object.")
|
||||
typename ExecutionTypes<DeviceAdapterTag>::Portal PrepareForInPlace(DeviceAdapterTag)
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
return this->PrepareForInPlace(DeviceAdapterTag{}, token);
|
||||
}
|
||||
|
||||
/// Returns the DeviceAdapterId for the current device. If there is no device
|
||||
/// with an up-to-date copy of the data, VTKM_DEVICE_ADAPTER_UNDEFINED is
|
||||
/// returned.
|
||||
///
|
||||
/// Note that in a multithreaded environment the validity of this result can
|
||||
/// change.
|
||||
VTKM_CONT
|
||||
DeviceAdapterId GetDeviceAdapterId() const
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
return this->Internals->IsExecutionArrayValid(lock)
|
||||
? this->Internals->GetExecutionArray(lock)->GetDeviceAdapterId()
|
||||
: DeviceAdapterTagUndefined{};
|
||||
}
|
||||
|
||||
/// Synchronizes the control array with the execution array. If either the
|
||||
/// user array or control array is already valid, this method does nothing
|
||||
/// (because the data is already available in the control environment).
|
||||
/// Although the internal state of this class can change, the method is
|
||||
/// declared const because logically the data does not.
|
||||
///
|
||||
VTKM_CONT void SyncControlArray() const
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
this->SyncControlArray(lock, token);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Enqueue a token for access to this ArrayHandle.
|
||||
///
|
||||
/// This method places the given `Token` into the queue of `Token`s waiting for
|
||||
/// access to this `ArrayHandle` and then returns immediately. When this token
|
||||
/// is later used to get data from this `ArrayHandle` (for example, in a call to
|
||||
/// `PrepareForInput`), it will use this place in the queue while waiting for
|
||||
/// access.
|
||||
///
|
||||
/// This method is to be used to ensure that a set of accesses to an `ArrayHandle`
|
||||
/// that happen on multiple threads occur in a specified order. For example, if
|
||||
/// you spawn of a job to modify data in an `ArrayHandle` and then spawn off a job
|
||||
/// that reads that same data, you need to make sure that the first job gets
|
||||
/// access to the `ArrayHandle` before the second. If they both just attempt to call
|
||||
/// their respective `Prepare` methods, there is no guarantee which order they
|
||||
/// will occur. Having the spawning thread first call this method will ensure the order.
|
||||
///
|
||||
/// \warning After calling this method it is required to subsequently
|
||||
/// call a method like one of the `Prepare` methods that attaches the token
|
||||
/// to this `ArrayHandle`. Otherwise, the enqueued token will block any subsequent
|
||||
/// access to the `ArrayHandle`, even if the `Token` is destroyed.
|
||||
///
|
||||
VTKM_CONT void Enqueue(const vtkm::cont::Token& token) const;
|
||||
|
||||
private:
|
||||
/// Acquires a lock on the internals of this `ArrayHandle`. The calling
|
||||
/// function should keep the returned lock and let it go out of scope
|
||||
/// when the lock is no longer needed.
|
||||
///
|
||||
LockType GetLock() const { return LockType(this->Internals->Mutex); }
|
||||
|
||||
/// Returns true if read operations can currently be performed.
|
||||
///
|
||||
VTKM_CONT bool CanRead(const LockType& lock, const vtkm::cont::Token& token) const;
|
||||
|
||||
//// Returns true if write operations can currently be performed.
|
||||
///
|
||||
VTKM_CONT bool CanWrite(const LockType& lock, const vtkm::cont::Token& token) const;
|
||||
|
||||
//// Will block the current thread until a read can be performed.
|
||||
///
|
||||
VTKM_CONT void WaitToRead(LockType& lock, vtkm::cont::Token& token) const;
|
||||
|
||||
//// Will block the current thread until a write can be performed.
|
||||
///
|
||||
VTKM_CONT void WaitToWrite(LockType& lock, vtkm::cont::Token& token, bool fakeRead = false) const;
|
||||
|
||||
/// Gets this array handle ready to interact with the given device. If the
|
||||
/// array handle has already interacted with this device, then this method
|
||||
/// does nothing. Although the internal state of this class can change, the
|
||||
/// method is declared const because logically the data does not.
|
||||
///
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT void PrepareForDevice(LockType& lock, vtkm::cont::Token& token, DeviceAdapterTag) const;
|
||||
|
||||
/// Synchronizes the control array with the execution array. If either the
|
||||
/// user array or control array is already valid, this method does nothing
|
||||
/// (because the data is already available in the control environment).
|
||||
/// Although the internal state of this class can change, the method is
|
||||
/// declared const because logically the data does not.
|
||||
///
|
||||
VTKM_CONT void SyncControlArray(LockType& lock, vtkm::cont::Token& token) const;
|
||||
|
||||
vtkm::Id GetNumberOfValues(LockType& lock) const;
|
||||
|
||||
VTKM_CONT
|
||||
void ReleaseResourcesExecutionInternal(LockType& lock, vtkm::cont::Token& token) const
|
||||
{
|
||||
if (this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
this->WaitToWrite(lock, token);
|
||||
// Note that it is possible that while waiting someone else deleted the execution array.
|
||||
// That is why we check again.
|
||||
}
|
||||
if (this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
this->Internals->GetExecutionArray(lock)->ReleaseResources();
|
||||
this->Internals->SetExecutionArrayValid(lock, false);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void Enqueue(const LockType& lock, const vtkm::cont::Token& token) const;
|
||||
|
||||
class VTKM_ALWAYS_EXPORT InternalStruct
|
||||
{
|
||||
mutable StorageType ControlArray;
|
||||
mutable std::shared_ptr<bool> ControlArrayValid;
|
||||
|
||||
mutable std::unique_ptr<ExecutionManagerType> ExecutionArray;
|
||||
mutable bool ExecutionArrayValid = false;
|
||||
|
||||
mutable vtkm::cont::Token::ReferenceCount ReadCount = 0;
|
||||
mutable vtkm::cont::Token::ReferenceCount WriteCount = 0;
|
||||
|
||||
mutable std::deque<vtkm::cont::Token::Reference> Queue;
|
||||
|
||||
VTKM_CONT void CheckLock(const LockType& lock) const
|
||||
{
|
||||
VTKM_ASSERT((lock.mutex() == &this->Mutex) && (lock.owns_lock()));
|
||||
}
|
||||
|
||||
public:
|
||||
MutexType Mutex;
|
||||
std::condition_variable ConditionVariable;
|
||||
|
||||
InternalStruct() = default;
|
||||
InternalStruct(const StorageType& storage);
|
||||
InternalStruct(StorageType&& storage);
|
||||
|
||||
~InternalStruct()
|
||||
{
|
||||
// It should not be possible to destroy this array if any tokens are still attached to it.
|
||||
LockType lock(this->Mutex);
|
||||
VTKM_ASSERT((*this->GetReadCount(lock) == 0) && (*this->GetWriteCount(lock) == 0));
|
||||
this->SetControlArrayValid(lock, false);
|
||||
}
|
||||
|
||||
// To access any feature in InternalStruct, you must have locked the mutex. You have
|
||||
// to prove it by passing in a reference to a std::unique_lock.
|
||||
VTKM_CONT bool IsControlArrayValid(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
if (!this->ControlArrayValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this->ControlArrayValid;
|
||||
}
|
||||
}
|
||||
VTKM_CONT void SetControlArrayValid(const LockType& lock, bool value)
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
if (IsControlArrayValid(lock) == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (value) // ControlArrayValid == false or nullptr
|
||||
{
|
||||
// If we are changing the valid flag from false to true, then refresh the pointer.
|
||||
// There may be array portals that already have a reference to the flag. Those portals
|
||||
// will stay in an invalid state whereas new portals will go to a valid state. To
|
||||
// handle both conditions, drop the old reference and create a new one.
|
||||
this->ControlArrayValid.reset(new bool(true));
|
||||
}
|
||||
else // value == false and ControlArrayValid == true
|
||||
{
|
||||
*this->ControlArrayValid = false;
|
||||
}
|
||||
}
|
||||
VTKM_CONT std::shared_ptr<bool> GetControlArrayValidPointer(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return this->ControlArrayValid;
|
||||
}
|
||||
VTKM_CONT StorageType* GetControlArray(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return &this->ControlArray;
|
||||
}
|
||||
|
||||
VTKM_CONT bool IsExecutionArrayValid(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return this->ExecutionArrayValid;
|
||||
}
|
||||
VTKM_CONT void SetExecutionArrayValid(const LockType& lock, bool value)
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
this->ExecutionArrayValid = value;
|
||||
}
|
||||
VTKM_CONT ExecutionManagerType* GetExecutionArray(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return this->ExecutionArray.get();
|
||||
}
|
||||
VTKM_CONT void DeleteExecutionArray(const LockType& lock)
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
this->ExecutionArray.reset();
|
||||
this->ExecutionArrayValid = false;
|
||||
}
|
||||
template <typename DeviceAdapterTag>
|
||||
VTKM_CONT void NewExecutionArray(const LockType& lock, DeviceAdapterTag)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
|
||||
this->CheckLock(lock);
|
||||
VTKM_ASSERT(this->ExecutionArray == nullptr);
|
||||
VTKM_ASSERT(!this->ExecutionArrayValid);
|
||||
this->ExecutionArray.reset(
|
||||
new vtkm::cont::internal::ArrayHandleExecutionManager<T, StorageTag, DeviceAdapterTag>(
|
||||
&this->ControlArray));
|
||||
}
|
||||
VTKM_CONT vtkm::cont::Token::ReferenceCount* GetReadCount(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return &this->ReadCount;
|
||||
}
|
||||
VTKM_CONT vtkm::cont::Token::ReferenceCount* GetWriteCount(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return &this->WriteCount;
|
||||
}
|
||||
VTKM_CONT std::deque<vtkm::cont::Token::Reference>& GetQueue(const LockType& lock) const
|
||||
{
|
||||
this->CheckLock(lock);
|
||||
return this->Queue;
|
||||
}
|
||||
};
|
||||
|
||||
VTKM_CONT
|
||||
ArrayHandle(const std::shared_ptr<InternalStruct>& i)
|
||||
: Internals(i)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<InternalStruct> Internals;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@ -917,90 +267,26 @@ VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::DeviceAdapterId ArrayHandleGetDeviceAdapt
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// This macro is used to declare an ArrayHandle that uses the new style of Storage
|
||||
// that leverages Buffer objects. This macro will go away once ArrayHandle
|
||||
// is replaced with ArrayHandleNewStyle. To use this macro, first have a declaration
|
||||
// of the template and then put the macro like this:
|
||||
//
|
||||
// template <typename T>
|
||||
// VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagFoo);
|
||||
//
|
||||
// Don't forget to use VTKM_PASS_COMMAS if one of the macro arguments contains
|
||||
// a template with multiple parameters.
|
||||
#define VTKM_ARRAY_HANDLE_NEW_STYLE(ValueType_, StorageType_) \
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandle<ValueType_, StorageType_> \
|
||||
: public ArrayHandleNewStyle<ValueType_, StorageType_> \
|
||||
{ \
|
||||
using Superclass = ArrayHandleNewStyle<ValueType_, StorageType_>; \
|
||||
\
|
||||
public: \
|
||||
VTKM_CONT \
|
||||
ArrayHandle() \
|
||||
: Superclass() \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT \
|
||||
ArrayHandle(const ArrayHandle<ValueType_, StorageType_>& src) \
|
||||
: Superclass(src) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT \
|
||||
ArrayHandle(ArrayHandle<ValueType_, StorageType_>&& src) noexcept \
|
||||
: Superclass(std::move(src)) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT \
|
||||
ArrayHandle(const ArrayHandleNewStyle<ValueType_, StorageType_>& src) \
|
||||
: Superclass(src) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT \
|
||||
ArrayHandle(ArrayHandleNewStyle<ValueType_, StorageType_>&& src) noexcept \
|
||||
: Superclass(std::move(src)) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT ArrayHandle(const vtkm::cont::internal::Buffer* buffers) \
|
||||
: Superclass(buffers) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT ArrayHandle(const std::vector<vtkm::cont::internal::Buffer>& buffers) \
|
||||
: Superclass(buffers) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT ArrayHandle(std::vector<vtkm::cont::internal::Buffer>&& buffers) \
|
||||
: Superclass(std::move(buffers)) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT \
|
||||
ArrayHandle<ValueType_, StorageType_>& operator=( \
|
||||
const ArrayHandle<ValueType_, StorageType_>& src) \
|
||||
{ \
|
||||
this->Superclass::operator=(src); \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT \
|
||||
ArrayHandle<ValueType_, StorageType_>& operator=( \
|
||||
ArrayHandle<ValueType_, StorageType_>&& src) noexcept \
|
||||
{ \
|
||||
this->Superclass::operator=(std::move(src)); \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
VTKM_CONT ~ArrayHandle() {} \
|
||||
}
|
||||
|
||||
/// This new style of ArrayHandle will eventually replace the classic ArrayHandle
|
||||
/// \brief Manages an array-worth of data.
|
||||
///
|
||||
/// `ArrayHandle` manages as array of data that can be manipulated by VTKm
|
||||
/// algorithms. The `ArrayHandle` may have up to two copies of the array, one
|
||||
/// for the control environment and one for the execution environment, although
|
||||
/// depending on the device and how the array is being used, the `ArrayHandle`
|
||||
/// will only have one copy when possible.
|
||||
///
|
||||
/// An `ArrayHandle` is often constructed by instantiating one of the `ArrayHandle`
|
||||
/// subclasses. Several basic `ArrayHandle` types can also be constructed directly
|
||||
/// and then allocated. The `ArrayHandleBasic` subclass provides mechanisms for
|
||||
/// importing user arrays into an `ArrayHandle`.
|
||||
///
|
||||
/// `ArrayHandle` behaves like a shared smart pointer in that when it is copied
|
||||
/// each copy holds a reference to the same array. These copies are reference
|
||||
/// counted so that when all copies of the `ArrayHandle` are destroyed, any
|
||||
/// allocated memory is released.
|
||||
///
|
||||
template <typename T, typename StorageTag_ = VTKM_DEFAULT_STORAGE_TAG>
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandleNewStyle : public internal::ArrayHandleBase
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandle : public internal::ArrayHandleBase
|
||||
{
|
||||
public:
|
||||
using ValueType = T;
|
||||
@ -1025,7 +311,7 @@ public:
|
||||
|
||||
/// Constructs an empty ArrayHandle.
|
||||
///
|
||||
VTKM_CONT ArrayHandleNewStyle()
|
||||
VTKM_CONT ArrayHandle()
|
||||
: Buffers(static_cast<std::size_t>(StorageType::GetNumberOfBuffers()))
|
||||
{
|
||||
}
|
||||
@ -1037,7 +323,7 @@ public:
|
||||
/// with CUDA), then the automatically generated copy constructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
VTKM_CONT ArrayHandleNewStyle(const vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& src)
|
||||
VTKM_CONT ArrayHandle(const vtkm::cont::ArrayHandle<ValueType, StorageTag>& src)
|
||||
: Buffers(src.Buffers)
|
||||
{
|
||||
}
|
||||
@ -1049,8 +335,7 @@ public:
|
||||
/// with CUDA), then the automatically generated move constructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
VTKM_CONT ArrayHandleNewStyle(
|
||||
vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>&& src) noexcept
|
||||
VTKM_CONT ArrayHandle(vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src) noexcept
|
||||
: Buffers(std::move(src.Buffers))
|
||||
{
|
||||
}
|
||||
@ -1059,19 +344,19 @@ public:
|
||||
/// Special constructor for subclass specializations that need to set the
|
||||
/// initial state array. Used when pulling data from other sources.
|
||||
///
|
||||
VTKM_CONT ArrayHandleNewStyle(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
||||
VTKM_CONT ArrayHandle(const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
||||
: Buffers(buffers)
|
||||
{
|
||||
VTKM_ASSERT(static_cast<vtkm::IdComponent>(this->Buffers.size()) == this->GetNumberOfBuffers());
|
||||
}
|
||||
|
||||
VTKM_CONT ArrayHandleNewStyle(std::vector<vtkm::cont::internal::Buffer>&& buffers) noexcept
|
||||
VTKM_CONT ArrayHandle(std::vector<vtkm::cont::internal::Buffer>&& buffers) noexcept
|
||||
: Buffers(std::move(buffers))
|
||||
{
|
||||
VTKM_ASSERT(static_cast<vtkm::IdComponent>(this->Buffers.size()) == this->GetNumberOfBuffers());
|
||||
}
|
||||
|
||||
VTKM_CONT ArrayHandleNewStyle(const vtkm::cont::internal::Buffer* buffers)
|
||||
VTKM_CONT ArrayHandle(const vtkm::cont::internal::Buffer* buffers)
|
||||
: Buffers(buffers, buffers + StorageType::GetNumberOfBuffers())
|
||||
{
|
||||
}
|
||||
@ -1084,13 +369,13 @@ public:
|
||||
/// with CUDA), then the automatically generated destructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
VTKM_CONT ~ArrayHandleNewStyle() {}
|
||||
VTKM_CONT ~ArrayHandle() {}
|
||||
|
||||
/// \brief Copies an ArrayHandle
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& operator=(
|
||||
const vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& src)
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
|
||||
const vtkm::cont::ArrayHandle<ValueType, StorageTag>& src)
|
||||
{
|
||||
this->Buffers = src.Buffers;
|
||||
return *this;
|
||||
@ -1099,8 +384,8 @@ public:
|
||||
/// \brief Move and Assignment of an ArrayHandle
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& operator=(
|
||||
vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>&& src) noexcept
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src) noexcept
|
||||
{
|
||||
this->Buffers = std::move(src.Buffers);
|
||||
return *this;
|
||||
@ -1411,8 +696,7 @@ public:
|
||||
///
|
||||
/// Takes the data that is in \a source and copies that data into this array.
|
||||
///
|
||||
VTKM_CONT void DeepCopyFrom(
|
||||
const vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& source) const
|
||||
VTKM_CONT void DeepCopyFrom(const vtkm::cont::ArrayHandle<ValueType, StorageTag>& source) const
|
||||
{
|
||||
VTKM_ASSERT(this->Buffers.size() == source.Buffers.size());
|
||||
|
||||
@ -1667,8 +951,4 @@ VTKM_CONT inline std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const A
|
||||
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||
#endif
|
||||
|
||||
#ifndef vtk_m_cont_ArrayHandle_hxx
|
||||
#include <vtkm/cont/ArrayHandle.hxx>
|
||||
#endif
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandle_h
|
||||
|
@ -1,596 +0,0 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_ArrayHandle_hxx
|
||||
#define vtk_m_cont_ArrayHandle_hxx
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::InternalStruct::InternalStruct(
|
||||
const typename ArrayHandle<T, S>::StorageType& storage)
|
||||
: ControlArray(storage)
|
||||
, ControlArrayValid(new bool(true))
|
||||
, ExecutionArrayValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::InternalStruct::InternalStruct(typename ArrayHandle<T, S>::StorageType&& storage)
|
||||
: ControlArray(std::move(storage))
|
||||
, ControlArrayValid(new bool(true))
|
||||
, ExecutionArrayValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle()
|
||||
: Internals(std::make_shared<InternalStruct>())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle(const ArrayHandle<T, S>& src)
|
||||
: Internals(src.Internals)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle(ArrayHandle<T, S>&& src) noexcept
|
||||
: Internals(std::move(src.Internals))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle(const typename ArrayHandle<T, S>::StorageType& storage)
|
||||
: Internals(std::make_shared<InternalStruct>(storage))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle(typename ArrayHandle<T, S>::StorageType&& storage) noexcept
|
||||
: Internals(std::make_shared<InternalStruct>(std::move(storage)))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::~ArrayHandle()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(const ArrayHandle<T, S>& src)
|
||||
{
|
||||
this->Internals = src.Internals;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(ArrayHandle<T, S>&& src) noexcept
|
||||
{
|
||||
this->Internals = std::move(src.Internals);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
typename ArrayHandle<T, S>::StorageType& ArrayHandle<T, S>::GetStorage()
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
this->SyncControlArray(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
return *this->Internals->GetControlArray(lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorInternal(
|
||||
"ArrayHandle::SyncControlArray did not make control array valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
const typename ArrayHandle<T, S>::StorageType& ArrayHandle<T, S>::GetStorage() const
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
this->SyncControlArray(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
return *this->Internals->GetControlArray(lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorInternal(
|
||||
"ArrayHandle::SyncControlArray did not make control array valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
typename ArrayHandle<T, S>::StorageType::PortalType ArrayHandle<T, S>::GetPortalControl()
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
this->SyncControlArray(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
// If the user writes into the iterator we return, then the execution
|
||||
// array will become invalid. Play it safe and release the execution
|
||||
// resources. (Use the const version to preserve the execution array.)
|
||||
this->ReleaseResourcesExecutionInternal(lock, token);
|
||||
return this->Internals->GetControlArray(lock)->GetPortal();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorInternal(
|
||||
"ArrayHandle::SyncControlArray did not make control array valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
typename ArrayHandle<T, S>::StorageType::PortalConstType ArrayHandle<T, S>::GetPortalConstControl()
|
||||
const
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
this->SyncControlArray(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
return this->Internals->GetControlArray(lock)->GetPortalConst();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorInternal(
|
||||
"ArrayHandle::SyncControlArray did not make control array valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
typename ArrayHandle<T, S>::ReadPortalType ArrayHandle<T, S>::ReadPortal() const
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToRead(lock, token);
|
||||
|
||||
this->SyncControlArray(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
return ReadPortalType(this->Internals->GetControlArray(lock)->GetPortalConst());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorInternal(
|
||||
"ArrayHandle::SyncControlArray did not make control array valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
typename ArrayHandle<T, S>::WritePortalType ArrayHandle<T, S>::WritePortal() const
|
||||
{
|
||||
// A Token should not be declared within the scope of a lock. when the token goes out of scope
|
||||
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
|
||||
// the lock.
|
||||
vtkm::cont::Token token;
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToWrite(lock, token);
|
||||
|
||||
this->SyncControlArray(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
// If the user writes into the iterator we return, then the execution
|
||||
// array will become invalid. Play it safe and release the execution
|
||||
// resources. (Use the const version to preserve the execution array.)
|
||||
this->ReleaseResourcesExecutionInternal(lock, token);
|
||||
return WritePortalType(this->Internals->GetControlArray(lock)->GetPortal());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorInternal(
|
||||
"ArrayHandle::SyncControlArray did not make control array valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::Id ArrayHandle<T, S>::GetNumberOfValues(LockType& lock) const
|
||||
{
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
return this->Internals->GetControlArray(lock)->GetNumberOfValues();
|
||||
}
|
||||
else if (this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
return this->Internals->GetExecutionArray(lock)->GetNumberOfValues();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void ArrayHandle<T, S>::Shrink(vtkm::Id numberOfValues, vtkm::cont::Token& token)
|
||||
{
|
||||
VTKM_ASSERT(numberOfValues >= 0);
|
||||
|
||||
if (numberOfValues > 0)
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
|
||||
vtkm::Id originalNumberOfValues = this->GetNumberOfValues(lock);
|
||||
|
||||
if (numberOfValues < originalNumberOfValues)
|
||||
{
|
||||
this->WaitToWrite(lock, token);
|
||||
if (this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
this->Internals->GetControlArray(lock)->Shrink(numberOfValues);
|
||||
}
|
||||
if (this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
this->Internals->GetExecutionArray(lock)->Shrink(numberOfValues);
|
||||
}
|
||||
}
|
||||
else if (numberOfValues == originalNumberOfValues)
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
else // numberOfValues > originalNumberOfValues
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("ArrayHandle::Shrink cannot be used to grow array.");
|
||||
}
|
||||
|
||||
VTKM_ASSERT(this->GetNumberOfValues(lock) == numberOfValues);
|
||||
}
|
||||
else // numberOfValues == 0
|
||||
{
|
||||
// If we are shrinking to 0, there is nothing to save and we might as well
|
||||
// free up memory. Plus, some storage classes expect that data will be
|
||||
// deallocated when the size goes to zero.
|
||||
this->Allocate(0, token);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
template <typename DeviceAdapterTag>
|
||||
typename ArrayHandle<T, S>::template ExecutionTypes<DeviceAdapterTag>::PortalConst
|
||||
ArrayHandle<T, S>::PrepareForInput(DeviceAdapterTag device, vtkm::cont::Token& token) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
|
||||
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToRead(lock, token);
|
||||
|
||||
if (!this->Internals->IsControlArrayValid(lock) && !this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
// Want to use an empty array.
|
||||
// Set up ArrayHandle state so this actually works.
|
||||
this->Internals->GetControlArray(lock)->Allocate(0);
|
||||
this->Internals->SetControlArrayValid(lock, true);
|
||||
}
|
||||
|
||||
this->PrepareForDevice(lock, token, device);
|
||||
auto portal = this->Internals->GetExecutionArray(lock)->PrepareForInput(
|
||||
!this->Internals->IsExecutionArrayValid(lock), device, token);
|
||||
|
||||
this->Internals->SetExecutionArrayValid(lock, true);
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
template <typename DeviceAdapterTag>
|
||||
typename ArrayHandle<T, S>::template ExecutionTypes<DeviceAdapterTag>::Portal
|
||||
ArrayHandle<T, S>::PrepareForOutput(vtkm::Id numberOfValues,
|
||||
DeviceAdapterTag device,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
|
||||
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToWrite(lock, token);
|
||||
|
||||
// Invalidate any control arrays.
|
||||
// Should the control array resource be released? Probably not a good
|
||||
// idea when shared with execution.
|
||||
this->Internals->SetControlArrayValid(lock, false);
|
||||
|
||||
this->PrepareForDevice(lock, token, device);
|
||||
auto portal =
|
||||
this->Internals->GetExecutionArray(lock)->PrepareForOutput(numberOfValues, device, token);
|
||||
|
||||
// We are assuming that the calling code will fill the array using the
|
||||
// iterators we are returning, so go ahead and mark the execution array as
|
||||
// having valid data. (A previous version of this class had a separate call
|
||||
// to mark the array as filled, but that was onerous to call at the the
|
||||
// right time and rather pointless since it is basically always the case
|
||||
// that the array is going to be filled before anything else. In this
|
||||
// implementation the only access to the array is through the iterators
|
||||
// returned from this method, so you would have to work to invalidate this
|
||||
// assumption anyway.)
|
||||
this->Internals->SetExecutionArrayValid(lock, true);
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
template <typename DeviceAdapterTag>
|
||||
typename ArrayHandle<T, S>::template ExecutionTypes<DeviceAdapterTag>::Portal
|
||||
ArrayHandle<T, S>::PrepareForInPlace(DeviceAdapterTag device, vtkm::cont::Token& token)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
|
||||
|
||||
LockType lock = this->GetLock();
|
||||
this->WaitToWrite(lock, token);
|
||||
|
||||
if (!this->Internals->IsControlArrayValid(lock) && !this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
// Want to use an empty array.
|
||||
// Set up ArrayHandle state so this actually works.
|
||||
this->Internals->GetControlArray(lock)->Allocate(0);
|
||||
this->Internals->SetControlArrayValid(lock, true);
|
||||
}
|
||||
|
||||
this->PrepareForDevice(lock, token, device);
|
||||
auto portal = this->Internals->GetExecutionArray(lock)->PrepareForInPlace(
|
||||
!this->Internals->IsExecutionArrayValid(lock), device, token);
|
||||
|
||||
this->Internals->SetExecutionArrayValid(lock, true);
|
||||
|
||||
// Invalidate any control arrays since their data will become invalid when
|
||||
// the execution data is overwritten. Don't actually release the control
|
||||
// array. It may be shared as the execution array.
|
||||
this->Internals->SetControlArrayValid(lock, false);
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
template <typename DeviceAdapterTag>
|
||||
void ArrayHandle<T, S>::PrepareForDevice(LockType& lock,
|
||||
vtkm::cont::Token& token,
|
||||
DeviceAdapterTag device) const
|
||||
{
|
||||
if (this->Internals->GetExecutionArray(lock) != nullptr)
|
||||
{
|
||||
if (this->Internals->GetExecutionArray(lock)->IsDeviceAdapter(DeviceAdapterTag()))
|
||||
{
|
||||
// Already have manager for correct device adapter. Nothing to do.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have the wrong manager. Delete the old one and create a new one
|
||||
// of the right type. (TODO: it would be possible for the array handle
|
||||
// to hold references to execution arrays on multiple devices. When data
|
||||
// are written on one devices, all the other devices should get cleared.)
|
||||
|
||||
// BUG: There is a non-zero chance that while waiting for the write lock, another thread
|
||||
// could change the ExecutionInterface, which would cause problems. In the future we should
|
||||
// support multiple devices, in which case we would not have to delete one execution array
|
||||
// to load another.
|
||||
// BUG: The current implementation does not allow the ArrayHandle to be on two devices
|
||||
// at the same time. Thus, it is not possible for two simultaneously read from the same
|
||||
// ArrayHandle on two different devices. This might cause unexpected deadlocks.
|
||||
this->WaitToWrite(lock, token, true); // Make sure no one is reading device array
|
||||
this->SyncControlArray(lock, token);
|
||||
// Need to change some state that does not change the logical state from
|
||||
// an external point of view.
|
||||
this->Internals->DeleteExecutionArray(lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Need to change some state that does not change the logical state from
|
||||
// an external point of view.
|
||||
this->Internals->NewExecutionArray(lock, device);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void ArrayHandle<T, S>::SyncControlArray(LockType& lock, vtkm::cont::Token& token) const
|
||||
{
|
||||
if (!this->Internals->IsControlArrayValid(lock))
|
||||
{
|
||||
// It may be the case that `SyncControlArray` is called from a method that has a `Token`.
|
||||
// However, if we are here, that `Token` should not already be attached to this array.
|
||||
// If it were, then there should be no reason to move data arround (unless the `Token`
|
||||
// was used when preparing for multiple devices, which it should not be used like that).
|
||||
this->WaitToRead(lock, token);
|
||||
|
||||
// Need to change some state that does not change the logical state from
|
||||
// an external point of view.
|
||||
if (this->Internals->IsExecutionArrayValid(lock))
|
||||
{
|
||||
this->Internals->GetExecutionArray(lock)->RetrieveOutputData(
|
||||
this->Internals->GetControlArray(lock));
|
||||
this->Internals->SetControlArrayValid(lock, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This array is in the null state (there is nothing allocated), but
|
||||
// the calling function wants to do something with the array. Put this
|
||||
// class into a valid state by allocating an array of size 0.
|
||||
this->Internals->GetControlArray(lock)->Allocate(0);
|
||||
this->Internals->SetControlArrayValid(lock, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
bool ArrayHandle<T, S>::CanRead(const LockType& lock, const vtkm::cont::Token& token) const
|
||||
{
|
||||
// If the token is already attached to this array, then we allow reading.
|
||||
if (token.IsAttached(this->Internals->GetWriteCount(lock)) ||
|
||||
token.IsAttached(this->Internals->GetReadCount(lock)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If there is anyone else waiting at the top of the queue, we cannot access this array.
|
||||
auto& queue = this->Internals->GetQueue(lock);
|
||||
if (!queue.empty() && (queue.front() != token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// No one else is waiting, so we can read the array as long as no one else is writing.
|
||||
return (*this->Internals->GetWriteCount(lock) < 1);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
bool ArrayHandle<T, S>::CanWrite(const LockType& lock, const vtkm::cont::Token& token) const
|
||||
{
|
||||
// If the token is already attached to this array, then we allow writing.
|
||||
if (token.IsAttached(this->Internals->GetWriteCount(lock)) ||
|
||||
token.IsAttached(this->Internals->GetReadCount(lock)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If there is anyone else waiting at the top of the queue, we cannot access this array.
|
||||
auto& queue = this->Internals->GetQueue(lock);
|
||||
if (!queue.empty() && (queue.front() != token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// No one else is waiting, so we can write the array as long as no one else is reading or writing.
|
||||
return ((*this->Internals->GetWriteCount(lock) < 1) &&
|
||||
(*this->Internals->GetReadCount(lock) < 1));
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void ArrayHandle<T, S>::WaitToRead(LockType& lock, vtkm::cont::Token& token) const
|
||||
{
|
||||
this->Enqueue(lock, token);
|
||||
|
||||
// Note that if you deadlocked here, that means that you are trying to do a read operation on an
|
||||
// array where an object is writing to it.
|
||||
this->Internals->ConditionVariable.wait(
|
||||
lock, [&lock, &token, this] { return this->CanRead(lock, token); });
|
||||
|
||||
token.Attach(this->Internals,
|
||||
this->Internals->GetReadCount(lock),
|
||||
lock,
|
||||
&this->Internals->ConditionVariable);
|
||||
|
||||
// We successfully attached the token. Pop it off the queue.
|
||||
auto& queue = this->Internals->GetQueue(lock);
|
||||
if (!queue.empty() && queue.front() == token)
|
||||
{
|
||||
queue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void ArrayHandle<T, S>::WaitToWrite(LockType& lock, vtkm::cont::Token& token, bool fakeRead) const
|
||||
{
|
||||
this->Enqueue(lock, token);
|
||||
|
||||
// Note that if you deadlocked here, that means that you are trying to do a write operation on an
|
||||
// array where an object is reading or writing to it.
|
||||
this->Internals->ConditionVariable.wait(
|
||||
lock, [&lock, &token, this] { return this->CanWrite(lock, token); });
|
||||
|
||||
if (!fakeRead)
|
||||
{
|
||||
token.Attach(this->Internals,
|
||||
this->Internals->GetWriteCount(lock),
|
||||
lock,
|
||||
&this->Internals->ConditionVariable);
|
||||
}
|
||||
else
|
||||
{
|
||||
// A current feature limitation of ArrayHandle is that it can only exist on one device at
|
||||
// a time. Thus, if a read request comes in for a different device, the prepare has to
|
||||
// get satisfy a write lock to boot the array off the existing device. However, we don't
|
||||
// want to attach the Token as a write lock because the resulting state is for reading only
|
||||
// and others might also want to read. So, we have to pretend that this is a read lock even
|
||||
// though we have to make a change to the array.
|
||||
//
|
||||
// The main point is, this condition is a hack that should go away once ArrayHandle supports
|
||||
// multiple devices at once.
|
||||
token.Attach(this->Internals,
|
||||
this->Internals->GetReadCount(lock),
|
||||
lock,
|
||||
&this->Internals->ConditionVariable);
|
||||
}
|
||||
|
||||
// We successfully attached the token. Pop it off the queue.
|
||||
auto& queue = this->Internals->GetQueue(lock);
|
||||
if (!queue.empty() && queue.front() == token)
|
||||
{
|
||||
queue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void ArrayHandle<T, S>::Enqueue(const vtkm::cont::Token& token) const
|
||||
{
|
||||
LockType lock = this->GetLock();
|
||||
this->Enqueue(lock, token);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void ArrayHandle<T, S>::Enqueue(const LockType& lock, const vtkm::cont::Token& token) const
|
||||
{
|
||||
if (token.IsAttached(this->Internals->GetWriteCount(lock)) ||
|
||||
token.IsAttached(this->Internals->GetReadCount(lock)))
|
||||
{
|
||||
// Do not need to enqueue if we are already attached.
|
||||
return;
|
||||
}
|
||||
|
||||
auto& queue = this->Internals->GetQueue(lock);
|
||||
if (std::find(queue.begin(), queue.end(), token.GetReference()) != queue.end())
|
||||
{
|
||||
// This token is already in the queue.
|
||||
return;
|
||||
}
|
||||
|
||||
this->Internals->GetQueue(lock).push_back(token.GetReference());
|
||||
}
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandle_hxx
|
@ -41,11 +41,11 @@ VTKM_STORAGE_INSTANTIATE(vtkm::Float64)
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#define VTKM_ARRAYHANDLE_INSTANTIATE(Type) \
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<Type, StorageTagBasic>; \
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Vec<Type, 2>, StorageTagBasic>; \
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Vec<Type, 3>, StorageTagBasic>; \
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Vec<Type, 4>, StorageTagBasic>;
|
||||
#define VTKM_ARRAYHANDLE_INSTANTIATE(Type) \
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<Type, StorageTagBasic>; \
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<Type, 2>, StorageTagBasic>; \
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<Type, 3>, StorageTagBasic>; \
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<Type, 4>, StorageTagBasic>;
|
||||
|
||||
VTKM_ARRAYHANDLE_INSTANTIATE(char)
|
||||
VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Int8)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define vtk_m_cont_ArrayHandleBasic_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/SerializableTypeString.h>
|
||||
#include <vtkm/cont/Serialization.h>
|
||||
#include <vtkm/cont/Storage.h>
|
||||
@ -70,9 +71,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagBasic);
|
||||
|
||||
template <typename T>
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandleBasic : public ArrayHandle<T, vtkm::cont::StorageTagBasic>
|
||||
{
|
||||
@ -383,14 +381,13 @@ VTKM_STORAGE_EXPORT(vtkm::Float64)
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#define VTKM_ARRAYHANDLE_EXPORT(Type) \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<Type, StorageTagBasic>; \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT \
|
||||
ArrayHandleNewStyle<vtkm::Vec<Type, 2>, StorageTagBasic>; \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT \
|
||||
ArrayHandleNewStyle<vtkm::Vec<Type, 3>, StorageTagBasic>; \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT \
|
||||
ArrayHandleNewStyle<vtkm::Vec<Type, 4>, StorageTagBasic>;
|
||||
#define VTKM_ARRAYHANDLE_EXPORT(Type) \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<Type, StorageTagBasic>; \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT \
|
||||
ArrayHandle<vtkm::Vec<Type, 2>, StorageTagBasic>; \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT \
|
||||
ArrayHandle<vtkm::Vec<Type, 3>, StorageTagBasic>; \
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<Type, 4>, StorageTagBasic>;
|
||||
|
||||
VTKM_ARRAYHANDLE_EXPORT(char)
|
||||
VTKM_ARRAYHANDLE_EXPORT(vtkm::Int8)
|
||||
|
@ -136,9 +136,6 @@ public:
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::internal::StorageTagBitField);
|
||||
|
||||
/// The ArrayHandleBitField class is a boolean-valued ArrayHandle that is backed
|
||||
/// by a BitField.
|
||||
///
|
||||
|
@ -284,11 +284,6 @@ public:
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename ST1, typename ST2, typename ST3>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(
|
||||
T,
|
||||
VTKM_PASS_COMMAS(vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>));
|
||||
|
||||
/// ArrayHandleCartesianProduct is a specialization of ArrayHandle. It takes two delegate
|
||||
/// array handle and makes a new handle that access the corresponding entries
|
||||
/// in these arrays as a pair.
|
||||
|
@ -131,9 +131,6 @@ struct Storage<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceStorage_>>
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T1, typename T2, typename S>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T1, VTKM_PASS_COMMAS(vtkm::cont::StorageTagCast<T2, S>));
|
||||
|
||||
/// \brief Cast the values of an array to the specified type, on demand.
|
||||
///
|
||||
/// ArrayHandleCast is a specialization of ArrayHandleTransform. Given an ArrayHandle
|
||||
|
@ -402,9 +402,6 @@ struct Storage<T, vtkm::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, S
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename... Ss>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagCompositeVec<Ss...>);
|
||||
|
||||
/// \brief An \c ArrayHandle that combines components from other arrays.
|
||||
///
|
||||
/// \c ArrayHandleCompositeVector is a specialization of \c ArrayHandle that
|
||||
|
@ -245,9 +245,6 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T, typename S1, typename S2>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, VTKM_PASS_COMMAS(StorageTagConcatenate<S1, S2>));
|
||||
|
||||
template <typename ArrayHandleType1, typename ArrayHandleType2>
|
||||
class ArrayHandleConcatenate
|
||||
: public vtkm::cont::ArrayHandle<typename ArrayHandleType1::ValueType,
|
||||
|
@ -51,9 +51,6 @@ struct Storage<T, vtkm::cont::StorageTagConstant> : Storage<T, StorageTagConstan
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagConstant);
|
||||
|
||||
/// \brief An array handle with a constant value.
|
||||
///
|
||||
/// ArrayHandleConstant is an implicit array handle with a constant value. A
|
||||
|
@ -120,9 +120,6 @@ struct Storage<T, typename std::enable_if<CanCount<T>::value, vtkm::cont::Storag
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagCounting);
|
||||
|
||||
/// ArrayHandleCounting is a specialization of ArrayHandle. By default it
|
||||
/// contains a increment value, that is increment for each step between zero
|
||||
/// and the passed in length
|
||||
|
@ -590,11 +590,6 @@ struct DecoratorHandleTraits
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename DecoratorImplT, typename... ArrayTs>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(
|
||||
T,
|
||||
VTKM_PASS_COMMAS(internal::StorageTagDecorator<DecoratorImplT, ArrayTs...>));
|
||||
|
||||
/// \brief A fancy ArrayHandle that can be used to modify the results from one
|
||||
/// or more source ArrayHandle.
|
||||
///
|
||||
|
@ -144,10 +144,6 @@ struct ArrayHandleDiscardTraits
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
// This can go away once ArrayHandle is replaced with ArrayHandleNewStyle
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::internal::StorageTagDiscard);
|
||||
|
||||
/// ArrayHandleDiscard is a write-only array that discards all data written to
|
||||
/// it. This can be used to save memory when a filter provides optional outputs
|
||||
/// that are not needed.
|
||||
|
@ -170,9 +170,6 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T, typename ArrayT>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagExtractComponent<ArrayT>);
|
||||
|
||||
/// \brief A fancy ArrayHandle that turns a vector array into a scalar array by
|
||||
/// slicing out a single component of each vector.
|
||||
///
|
||||
|
@ -14,11 +14,17 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_DEPRECATED(VTKM_PASS_COMMAS(vtkm::Vec<T, 3>),
|
||||
vtkm::cont::internal::StorageTagExtrude);
|
||||
|
||||
template <typename T>
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandleExtrudeCoords
|
||||
: public vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, internal::StorageTagExtrude>
|
||||
|
@ -13,11 +13,16 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/StorageExtrude.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_DEPRECATED(T, vtkm::cont::internal::StorageTagExtrude);
|
||||
|
||||
template <typename T>
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandleExtrudeField
|
||||
: public vtkm::cont::ArrayHandle<T, internal::StorageTagExtrude>
|
||||
|
@ -174,9 +174,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, vtkm::IdComponent N, typename S>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, VTKM_PASS_COMMAS(vtkm::cont::StorageTagGroupVec<S, N>));
|
||||
|
||||
/// \brief Fancy array handle that groups values into vectors.
|
||||
///
|
||||
/// It is sometimes the case that an array is stored such that consecutive
|
||||
|
@ -211,9 +211,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename S1, typename S2>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, VTKM_PASS_COMMAS(vtkm::cont::StorageTagGroupVecVariable<S1, S2>));
|
||||
|
||||
/// \brief Fancy array handle that groups values into vectors of different sizes.
|
||||
///
|
||||
/// It is sometimes the case that you need to run a worklet with an input or
|
||||
|
@ -160,11 +160,6 @@ struct ArrayHandleImplicitTraits
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// This can go away once ArrayHandle is replaced with ArrayHandleNewStyle
|
||||
template <typename PortalType>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(typename PortalType::ValueType,
|
||||
vtkm::cont::StorageTagImplicit<PortalType>);
|
||||
|
||||
/// \brief An \c ArrayHandle that computes values on the fly.
|
||||
///
|
||||
/// \c ArrayHandleImplicit is a specialization of ArrayHandle.
|
||||
|
@ -45,9 +45,6 @@ struct Storage<vtkm::Id, vtkm::cont::StorageTagIndex> : Storage<vtkm::Id, Storag
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(vtkm::Id, vtkm::cont::StorageTagIndex);
|
||||
|
||||
/// \brief An implicit array handle containing the its own indices.
|
||||
///
|
||||
/// \c ArrayHandleIndex is an implicit array handle containing the values
|
||||
|
@ -353,9 +353,6 @@ struct ArrayHandleMultiplexerTraits
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename... Ss>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagMultiplexer<Ss...>);
|
||||
|
||||
/// \brief An ArrayHandle that can behave like several other handles.
|
||||
///
|
||||
/// An \c ArrayHandleMultiplexer simply redirects its calls to another \c ArrayHandle. However
|
||||
|
@ -172,9 +172,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename IS, typename VS>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, VTKM_PASS_COMMAS(vtkm::cont::StorageTagPermutation<IS, VS>));
|
||||
|
||||
/// \brief Implicitly permutes the values in an array.
|
||||
///
|
||||
/// ArrayHandlePermutation is a specialization of ArrayHandle. It takes two
|
||||
|
@ -529,9 +529,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::internal::StorageTagRecombineVec);
|
||||
|
||||
/// \brief A grouping of `ArrayHandleStride`s into an `ArrayHandle` of `Vec`s.
|
||||
///
|
||||
/// The main intention of `ArrayHandleStride` is to pull out a component of an
|
||||
|
@ -163,9 +163,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename S>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagReverse<S>);
|
||||
|
||||
/// \brief Reverse the order of an array, on demand.
|
||||
///
|
||||
/// ArrayHandleReverse is a specialization of ArrayHandle. Given an ArrayHandle,
|
||||
|
@ -204,9 +204,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagSOA);
|
||||
|
||||
/// \brief An `ArrayHandle` that for Vecs stores each component in a separate physical array.
|
||||
///
|
||||
/// `ArrayHandleSOA` behaves like a regular `ArrayHandle` (with a basic storage) except that
|
||||
|
@ -33,17 +33,17 @@ template class VTKM_CONT_EXPORT Storage<vtkm::Float64, StorageTagStride>;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<char, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Int8, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::UInt8, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Int16, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::UInt16, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Int32, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::UInt32, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Int64, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::UInt64, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Float32, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandleNewStyle<vtkm::Float64, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<char, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int8, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt8, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int16, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt16, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int32, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt32, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int64, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt64, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Float32, StorageTagStride>;
|
||||
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Float64, StorageTagStride>;
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -205,9 +205,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagStride);
|
||||
|
||||
/// \brief An `ArrayHandle` that accesses a basic array with strides and offsets.
|
||||
///
|
||||
/// `ArrayHandleStride` is a simple `ArrayHandle` that accesses data with a prescribed
|
||||
@ -393,19 +390,17 @@ extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Float64, StorageTa
|
||||
|
||||
} // namespace internal
|
||||
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<char, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::Int8, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::UInt8, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::Int16, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::UInt16, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::Int32, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::UInt32, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::Int64, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleNewStyle<vtkm::UInt64, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT
|
||||
ArrayHandleNewStyle<vtkm::Float32, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT
|
||||
ArrayHandleNewStyle<vtkm::Float64, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<char, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int8, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt8, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int16, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt16, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int32, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt32, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int64, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt64, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Float32, StorageTagStride>;
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Float64, StorageTagStride>;
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -416,9 +416,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename A, typename F, typename IF>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, VTKM_PASS_COMMAS(internal::StorageTagTransform<A, F, IF>));
|
||||
|
||||
/// \brief Implicitly transform values of one array to another with a functor.
|
||||
///
|
||||
/// ArrayHandleTransforms is a specialization of ArrayHandle. It takes a
|
||||
|
@ -37,9 +37,6 @@ struct Storage<vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints>
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(vtkm::Vec3f, vtkm::cont::StorageTagUniformPoints);
|
||||
|
||||
/// ArrayHandleUniformPointCoordinates is a specialization of ArrayHandle. It
|
||||
/// contains the information necessary to compute the point coordinates in a
|
||||
/// uniform orthogonal grid (extent, origin, and spacing) and implicitly
|
||||
|
@ -196,10 +196,6 @@ public:
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// This can go away once ArrayHandle is replaced with ArrayHandleNewStyle
|
||||
template <typename T, typename S>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(T, vtkm::cont::StorageTagView<S>);
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
class ArrayHandleView
|
||||
: public vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
|
||||
|
@ -15,9 +15,10 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||
|
||||
#include <vtkm/cont/StorageVirtual.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef VTKM_NO_DEPRECATED_VIRTUAL
|
||||
@ -29,8 +30,11 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
|
||||
VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
|
||||
template <typename T>
|
||||
VTKM_ARRAY_HANDLE_DEPRECATED(T, vtkm::cont::StorageTagVirtual);
|
||||
|
||||
template <typename T>
|
||||
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6) ArrayHandleVirtual
|
||||
: public vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>
|
||||
|
@ -201,10 +201,6 @@ public:
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
template <typename T1, typename S1, typename T2, typename S2>
|
||||
VTKM_ARRAY_HANDLE_NEW_STYLE(VTKM_PASS_COMMAS(vtkm::Pair<T1, T2>),
|
||||
VTKM_PASS_COMMAS(vtkm::cont::StorageTagZip<S1, S2>));
|
||||
|
||||
/// ArrayHandleZip is a specialization of ArrayHandle. It takes two delegate
|
||||
/// array handle and makes a new handle that access the corresponding entries
|
||||
/// in these arrays as a pair.
|
||||
|
@ -127,7 +127,6 @@ set(headers
|
||||
)
|
||||
|
||||
set(template_sources
|
||||
ArrayHandle.hxx
|
||||
ArrayRangeCompute.hxx # Deprecated, replaced with ArrayRangeComputeTemplate.h
|
||||
CellSetExplicit.hxx
|
||||
CellSetExtrude.hxx
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayTransfer.h>
|
||||
#include <vtkm/cont/internal/StorageDeprecated.h>
|
||||
|
||||
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
|
||||
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/Storage.h>
|
||||
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
|
||||
#include <vtkm/cont/internal/StorageDeprecated.h>
|
||||
#include <vtkm/cont/internal/TransferInfo.h>
|
||||
#include <vtkm/internal/ArrayPortalVirtual.h>
|
||||
|
||||
|
@ -12,8 +12,9 @@
|
||||
|
||||
#include <vtkm/cont/StorageVirtual.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
#include <vtkm/cont/internal/TransferInfo.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayTransfer.h>
|
||||
#include <vtkm/cont/internal/TransferInfo.h>
|
||||
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
|
||||
#include <vtkm/cont/internal/VirtualObjectTransferShareWithControl.h>
|
||||
|
||||
|
1355
vtkm/cont/internal/ArrayHandleDeprecated.h
Normal file
1355
vtkm/cont/internal/ArrayHandleDeprecated.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
##============================================================================
|
||||
|
||||
set(headers
|
||||
ArrayHandleDeprecated.h
|
||||
ArrayHandleExecutionManager.h
|
||||
ArrayPortalFromIterators.h
|
||||
ArrayTransfer.h
|
||||
|
@ -25,12 +25,12 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T, typename S>
|
||||
class ArrayHandle;
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename T, typename S>
|
||||
class ArrayHandleDeprecated;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@ -98,7 +98,7 @@ class StorageDeprecated
|
||||
using T = typename detail::StorageTemplateParams<StorageType>::ValueType;
|
||||
using StorageTag = typename detail::StorageTemplateParams<StorageType>::StorageTag;
|
||||
|
||||
using ArrayType = vtkm::cont::ArrayHandle<T, StorageTag>;
|
||||
using ArrayType = vtkm::cont::internal::ArrayHandleDeprecated<T, StorageTag>;
|
||||
|
||||
VTKM_CONT static ArrayType GetArray(const vtkm::cont::internal::Buffer* buffers)
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
|
||||
#include <vtkm/cont/internal/Buffer.h>
|
||||
|
||||
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
|
||||
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
Loading…
Reference in New Issue
Block a user