Add Fill and AllocateAndFill to ArrayHandle
These allow you to create an `ArrayHandle` filled with an inital value without having to compile code for the device.
This commit is contained in:
parent
0cf996f410
commit
926164049f
16
docs/changelog/allocate-and-fill.md
Normal file
16
docs/changelog/allocate-and-fill.md
Normal file
@ -0,0 +1,16 @@
|
||||
# ArrayHandle::Fill
|
||||
|
||||
`ArrayHandle` has a new method named `Fill`. As the name would suggest, the
|
||||
`Fill` method initializes all elements in the array to a specified value.
|
||||
In addition to being more convenient than calling `Algorithm::Fill` or
|
||||
`ArrayCopy` with a constant array, the `ArrayHandle::Fill` can be used
|
||||
without using a device adapter.
|
||||
|
||||
Calling `Fill` directly requires the `ArrayHandle` to first be allocated to
|
||||
the appropriate size. The `ArrayHandle` now also has a new member named
|
||||
`AllocateAndFill`. As the name would suggest, this method resizes the array
|
||||
and then fills it with the specified value. Another feature this method has
|
||||
over calling `Allocate` and `Fill` separately is if you call
|
||||
`AllocateAndFill` with `vtkm::CopyFlag::On`, it will fill only the extended
|
||||
portion of the array.
|
||||
|
@ -528,12 +528,75 @@ public:
|
||||
}
|
||||
///@}
|
||||
|
||||
///@{
|
||||
/// \brief Allocates an array and fills it with an initial value.
|
||||
///
|
||||
/// `AllocateAndFill` behaves similar to `Allocate` except that after allocation it fills
|
||||
/// the array with a given `fillValue`. This method is convenient when you wish to initialize
|
||||
/// the array.
|
||||
///
|
||||
/// If the `preserve` flag is `vtkm::CopyFlag::On`, then any data that existed before the
|
||||
/// call to `AllocateAndFill` will remain after the call (assuming the new array size is
|
||||
/// large enough). If the array size is expanded, then the new values at the end will be
|
||||
/// filled.
|
||||
///
|
||||
/// If the `preserve` flag is `vtkm::CopyFlag::Off` (the default), the entire array is
|
||||
/// filled with the given `fillValue`.
|
||||
///
|
||||
VTKM_CONT void AllocateAndFill(vtkm::Id numberOfValues,
|
||||
const ValueType& fillValue,
|
||||
vtkm::CopyFlag preserve,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
// Note that there is a slight potential for a race condition here. It is possible for someone
|
||||
// else to resize the array in between getting the startIndex and locking the array in the
|
||||
// Allocate call. If there really are 2 threads trying to allocate this array at the same time,
|
||||
// you probably have bigger problems than filling at the wrong index.
|
||||
vtkm::Id startIndex = (preserve == vtkm::CopyFlag::On) ? this->GetNumberOfValues() : 0;
|
||||
|
||||
this->Allocate(numberOfValues, preserve, token);
|
||||
|
||||
if (startIndex < numberOfValues)
|
||||
{
|
||||
this->Fill(fillValue, startIndex, token);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void AllocateAndFill(vtkm::Id numberOfValues,
|
||||
const ValueType& fillValue,
|
||||
vtkm::CopyFlag preserve = vtkm::CopyFlag::Off) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->AllocateAndFill(numberOfValues, fillValue, preserve, token);
|
||||
}
|
||||
///@}
|
||||
|
||||
VTKM_DEPRECATED(1.6, "Use Allocate(n, vtkm::CopyFlag::On) instead of Shrink(n).")
|
||||
VTKM_CONT void Shrink(vtkm::Id numberOfValues)
|
||||
{
|
||||
this->Allocate(numberOfValues, vtkm::CopyFlag::On);
|
||||
}
|
||||
|
||||
/// @{
|
||||
/// \brief Fills the array with a given value.
|
||||
///
|
||||
/// After calling this method, every entry in the array from `startIndex` to the
|
||||
/// end of the array is set to `fillValue`. If `startIndex` is not specified, then
|
||||
/// every entry is set to the fill value.
|
||||
///
|
||||
VTKM_CONT void Fill(const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
StorageType::Fill(this->GetBuffers(), fillValue, startIndex, token);
|
||||
}
|
||||
VTKM_CONT void Fill(const ValueType& fillValue, vtkm::Id startIndex = 0) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Fill(fillValue, startIndex, token);
|
||||
}
|
||||
/// @}
|
||||
|
||||
/// Releases any resources being used in the execution environment (that are
|
||||
/// not being shared by the control environment).
|
||||
///
|
||||
|
@ -52,6 +52,16 @@ public:
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(T)));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const T& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
constexpr vtkm::BufferSizeType fillValueSize =
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(fillValue));
|
||||
buffers[0].Fill(&fillValue, fillValueSize, startIndex * fillValueSize, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -162,6 +162,21 @@ public:
|
||||
static_cast<vtkm::Id>(sizeof(ComponentType));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
constexpr vtkm::BufferSizeType sourceSize =
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(ComponentType));
|
||||
vtkm::BufferSizeType startByte = startIndex * sourceSize;
|
||||
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
|
||||
{
|
||||
ComponentType source = fillValue[componentIndex];
|
||||
buffers[componentIndex].Fill(&source, sourceSize, startByte, token);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define vtk_m_cont_ArrayHandleStride_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
|
||||
#include <vtkm/internal/ArrayPortalBasic.h>
|
||||
|
||||
@ -174,6 +175,11 @@ public:
|
||||
return GetInfo(buffers).NumberOfValues;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*, const T&, vtkm::Id, vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleStride.");
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -134,6 +134,13 @@ public:
|
||||
/// \brief Returns the number of entries allocated in the array.
|
||||
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers);
|
||||
|
||||
/// \brief Fills the array with the given value starting at the given index.
|
||||
///
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::cont::Token& token);
|
||||
|
||||
/// \brief Create a read-only portal on the specified device.
|
||||
///
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
@ -181,6 +188,16 @@ struct StorageTraits<vtkm::cont::internal::Storage<T, S>>
|
||||
#define VTKM_STORAGE_NO_WRITE_PORTAL \
|
||||
using WritePortalType = vtkm::internal::ArrayPortalDummy< \
|
||||
typename vtkm::cont::internal::StorageTraits<Storage>::ValueType>; \
|
||||
VTKM_CONT static void Fill( \
|
||||
vtkm::cont::internal::Buffer*, \
|
||||
const typename vtkm::cont::internal::StorageTraits<Storage>::ValueType&, \
|
||||
vtkm::Id, \
|
||||
vtkm::cont::Token&) \
|
||||
{ \
|
||||
throw vtkm::cont::ErrorBadAllocation( \
|
||||
"Cannot write to arrays with storage type of " + \
|
||||
vtkm::cont::TypeToString<typename vtkm::cont::internal::StorageTraits<Storage>::Tag>()); \
|
||||
} \
|
||||
VTKM_CONT static WritePortalType CreateWritePortal( \
|
||||
vtkm::cont::internal::Buffer*, vtkm::cont::DeviceAdapterId, vtkm::cont::Token&) \
|
||||
{ \
|
||||
|
Loading…
Reference in New Issue
Block a user