mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge topic 'allocate-and-fill'
d7b4390d1 Specify end position when filling values in Buffer 7a4cbaf10 Suggestions during review by Gunther Weber 8e4fb7ebd Suppress unhelpful nvcc warning bacca0693 Add Fill method for non-standard Storage 9da66ff32 Prefer ArrayHandle::Fill over Algorithm::Fill f79cf1d5f Add BitField::Fill and BitField::AllocateAndFill 926164049 Add Fill and AllocateAndFill to ArrayHandle 0cf996f41 Add ability to fill values in a Buffer Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !2660
This commit is contained in:
commit
e8a6d37190
@ -64,8 +64,7 @@ void BenchAddSeq(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> atomicArray;
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
atomicArray, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
atomicArray.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -115,7 +114,7 @@ void BenchAddSeqBaseline(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> array;
|
||||
vtkm::cont::Algorithm::Fill(array, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
array.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -175,8 +174,7 @@ void BenchAddStride(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> atomicArray;
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
atomicArray, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
atomicArray.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -235,7 +233,7 @@ void BenchAddStrideBaseline(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> array;
|
||||
vtkm::cont::Algorithm::Fill(array, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
array.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -289,8 +287,7 @@ void BenchCASSeq(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> atomicArray;
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
atomicArray, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
atomicArray.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -342,7 +339,7 @@ void BenchCASSeqBaseline(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> array;
|
||||
vtkm::cont::Algorithm::Fill(array, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
array.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -406,8 +403,7 @@ void BenchCASStride(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> atomicArray;
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
atomicArray, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
atomicArray.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
@ -468,7 +464,7 @@ void BenchCASStrideBaseline(benchmark::State& state)
|
||||
auto ones = vtkm::cont::make_ArrayHandleConstant<ValueType>(static_cast<ValueType>(1), numWrites);
|
||||
|
||||
vtkm::cont::ArrayHandle<ValueType> array;
|
||||
vtkm::cont::Algorithm::Fill(array, vtkm::TypeTraits<ValueType>::ZeroInitialization(), numValues);
|
||||
array.AllocateAndFill(numValues, vtkm::TypeTraits<ValueType>::ZeroInitialization());
|
||||
|
||||
vtkm::cont::Invoker invoker{ device };
|
||||
vtkm::cont::Timer timer{ device };
|
||||
|
18
docs/changelog/allocate-and-fill.md
Normal file
18
docs/changelog/allocate-and-fill.md
Normal file
@ -0,0 +1,18 @@
|
||||
# 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.
|
||||
|
||||
Also added a similar `Fill` and `AllocateAndFill` methods to `BitField` for
|
||||
similar reasons.
|
@ -528,12 +528,81 @@ 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, numberOfValues, 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 `endIndex`.
|
||||
/// of the array is set to `fillValue`. If `startIndex` or `endIndex` is not specified,
|
||||
/// then the fill happens from the begining or end, respectively.
|
||||
///
|
||||
VTKM_CONT void Fill(const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
StorageType::Fill(this->GetBuffers(), fillValue, startIndex, endIndex, token);
|
||||
}
|
||||
VTKM_CONT void Fill(const ValueType& fillValue, vtkm::Id startIndex, vtkm::Id endIndex) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Fill(fillValue, startIndex, endIndex, token);
|
||||
}
|
||||
VTKM_CONT void Fill(const ValueType& fillValue, vtkm::Id startIndex = 0) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Fill(fillValue, startIndex, this->GetNumberOfValues(), token);
|
||||
}
|
||||
/// @}
|
||||
|
||||
/// Releases any resources being used in the execution environment (that are
|
||||
/// not being shared by the control environment).
|
||||
///
|
||||
|
@ -52,6 +52,18 @@ public:
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(T)));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const T& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
constexpr vtkm::BufferSizeType fillValueSize =
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(fillValue));
|
||||
buffers[0].Fill(
|
||||
&fillValue, fillValueSize, startIndex * fillValueSize, endIndex * fillValueSize, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -110,6 +110,37 @@ public:
|
||||
return numberOfBits;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
bool fillValue,
|
||||
vtkm::Id startBit,
|
||||
vtkm::Id endBit,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
constexpr vtkm::BufferSizeType wordTypeSize =
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(WordType));
|
||||
constexpr vtkm::BufferSizeType wordNumBits = wordTypeSize * CHAR_BIT;
|
||||
// Special case where filling to end of array.
|
||||
vtkm::Id totalBitsInArray = GetNumberOfValues(buffers);
|
||||
if (endBit >= totalBitsInArray)
|
||||
{
|
||||
endBit = ((totalBitsInArray + (wordNumBits - 1)) / wordNumBits) * wordNumBits;
|
||||
}
|
||||
if (((startBit % wordNumBits) == 0) && ((endBit % wordNumBits) == 0))
|
||||
{
|
||||
WordType fillWord = (fillValue ? ~WordType{ 0 } : WordType{ 0 });
|
||||
buffers[0].Fill(&fillWord, wordTypeSize, startBit / CHAR_BIT, endBit / CHAR_BIT, token);
|
||||
}
|
||||
else if (((startBit % CHAR_BIT) == 0) && ((endBit % CHAR_BIT) == 0))
|
||||
{
|
||||
vtkm::UInt8 fillWord = (fillValue ? ~vtkm::UInt8{ 0 } : vtkm::UInt8{ 0 });
|
||||
buffers[0].Fill(&fillWord, 1, startBit / CHAR_BIT, endBit / CHAR_BIT, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Can only fill ArrayHandleBitField on 8-bit boundaries.");
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -248,6 +248,25 @@ public:
|
||||
Storage3::GetNumberOfValues(Buffers3(buffers)));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const vtkm::Vec<T, 3>& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
if ((startIndex != 0) || (endIndex != GetNumberOfValues(buffers)))
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Fill for ArrayHandleCartesianProduct can only be used to fill entire array.");
|
||||
}
|
||||
Storage1::Fill(
|
||||
Buffers1(buffers), fillValue[0], 0, Storage1::GetNumberOfValues(Buffers1(buffers)), token);
|
||||
Storage2::Fill(
|
||||
Buffers2(buffers), fillValue[1], 0, Storage2::GetNumberOfValues(Buffers2(buffers)), token);
|
||||
Storage3::Fill(
|
||||
Buffers3(buffers), fillValue[2], 0, Storage3::GetNumberOfValues(Buffers3(buffers)), token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -227,6 +227,8 @@ template <typename T, typename... StorageTags>
|
||||
class Storage<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags))>,
|
||||
vtkm::cont::StorageTagCompositeVec<StorageTags...>>
|
||||
{
|
||||
using ValueType = vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags))>;
|
||||
|
||||
template <typename S>
|
||||
using StorageFor = vtkm::cont::internal::Storage<T, S>;
|
||||
|
||||
@ -253,18 +255,6 @@ public:
|
||||
typename StorageFor<StorageTags>::WritePortalType...>;
|
||||
|
||||
private:
|
||||
// Hoop to jump through to use Storage::ResizeBuffer in an initializer list.
|
||||
template <typename StorageType>
|
||||
static bool ResizeBuffersCallthrough(StorageType,
|
||||
vtkm::Id numValues,
|
||||
vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::CopyFlag preserve,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
StorageType::ResizeBuffers(numValues, buffers, preserve, token);
|
||||
return false; // Return value does not matter. Hopefully just thrown away by compiler.
|
||||
}
|
||||
|
||||
template <std::size_t... Is>
|
||||
static void ResizeBuffersImpl(vtkmstd::index_sequence<Is...>,
|
||||
vtkm::Id numValues,
|
||||
@ -272,11 +262,27 @@ private:
|
||||
vtkm::CopyFlag preserve,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
auto init_list = { ResizeBuffersCallthrough(vtkm::tuple_element_t<Is, StorageTuple>{},
|
||||
numValues,
|
||||
Buffers<Is>(buffers),
|
||||
preserve,
|
||||
token)... };
|
||||
auto init_list = { (vtkm::tuple_element_t<Is, StorageTuple>::ResizeBuffers(
|
||||
numValues, Buffers<Is>(buffers), preserve, token),
|
||||
false)... };
|
||||
(void)init_list;
|
||||
}
|
||||
|
||||
template <std::size_t... Is>
|
||||
static void FillImpl(vtkmstd::index_sequence<Is...>,
|
||||
vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
auto init_list = { (
|
||||
vtkm::tuple_element_t<Is, StorageTuple>::Fill(Buffers<Is>(buffers),
|
||||
fillValue[static_cast<vtkm::IdComponent>(Is)],
|
||||
startIndex,
|
||||
endIndex,
|
||||
token),
|
||||
false)... };
|
||||
(void)init_list;
|
||||
}
|
||||
|
||||
@ -319,6 +325,15 @@ public:
|
||||
ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
FillImpl(IndexList{}, buffers, fillValue, startIndex, endIndex, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -202,6 +202,29 @@ public:
|
||||
SourceStorage2::GetNumberOfValues(Buffers2(buffers)));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const T& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
vtkm::Id size1 = SourceStorage1::GetNumberOfValues(Buffers1(buffers));
|
||||
if ((startIndex < size1) && (endIndex <= size1))
|
||||
{
|
||||
SourceStorage1::Fill(Buffers1(buffers), fillValue, startIndex, endIndex, token);
|
||||
}
|
||||
else if (startIndex < size1) // && (endIndex > size1)
|
||||
{
|
||||
SourceStorage1::Fill(Buffers1(buffers), fillValue, startIndex, size1, token);
|
||||
SourceStorage2::Fill(Buffers2(buffers), fillValue, 0, endIndex - size1, token);
|
||||
}
|
||||
else // startIndex >= size1
|
||||
{
|
||||
SourceStorage2::Fill(
|
||||
Buffers2(buffers), fillValue, startIndex - size1, endIndex - size1, token);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -119,6 +119,15 @@ public:
|
||||
return buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const ValueType&,
|
||||
vtkm::Id,
|
||||
vtkm::Id,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
// Fill is a NO-OP.
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer*,
|
||||
vtkm::cont::DeviceAdapterId,
|
||||
vtkm::cont::Token&)
|
||||
|
@ -129,6 +129,15 @@ public:
|
||||
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const ValueType&,
|
||||
vtkm::Id,
|
||||
vtkm::Id,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleExtractComponent.");
|
||||
}
|
||||
|
||||
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
|
||||
vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::CopyFlag preserve,
|
||||
|
@ -147,6 +147,15 @@ public:
|
||||
return componentsSize / NUM_COMPONENTS;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const ValueType&,
|
||||
vtkm::Id,
|
||||
vtkm::Id,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleGroupVec.");
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -158,6 +158,15 @@ public:
|
||||
return OffsetsStorage::GetNumberOfValues(OffsetsBuffers(buffers)) - 1;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const vtkm::VecFromPortal<ComponentsPortal>&,
|
||||
vtkm::Id,
|
||||
vtkm::Id,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleGroupVecVariable.");
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -170,6 +170,20 @@ struct MultiplexerResizeBuffersFunctor
|
||||
}
|
||||
};
|
||||
|
||||
struct MultiplexerFillFunctor
|
||||
{
|
||||
template <typename ValueType, typename StorageType>
|
||||
VTKM_CONT void operator()(StorageType,
|
||||
vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
StorageType::Fill(buffers, fillValue, startIndex, endIndex, token);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ReadPortalType>
|
||||
struct MultiplexerCreateReadPortalFunctor
|
||||
{
|
||||
@ -256,6 +270,20 @@ public:
|
||||
detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
Variant(buffers).CastAndCall(detail::MultiplexerFillFunctor{},
|
||||
ArrayBuffers(buffers),
|
||||
fillValue,
|
||||
startIndex,
|
||||
endIndex,
|
||||
token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -65,10 +65,11 @@ class VTKM_ALWAYS_EXPORT
|
||||
using OffsetsStorage = vtkm::cont::internal::Storage<vtkm::Id, OffsetsStorageTag>;
|
||||
|
||||
public:
|
||||
VTKM_STORAGE_NO_RESIZE;
|
||||
VTKM_STORAGE_NO_WRITE_PORTAL;
|
||||
|
||||
using ReadPortalType =
|
||||
vtkm::internal::ArrayPortalOffsetsToNumComponents<typename OffsetsStorage::ReadPortalType>;
|
||||
// Writing to ArrayHandleOffsetsToNumComponents not really supported, but we need to define this.
|
||||
using WritePortalType = ReadPortalType;
|
||||
|
||||
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
|
||||
{
|
||||
@ -86,23 +87,6 @@ public:
|
||||
return numOffsets - 1;
|
||||
}
|
||||
|
||||
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
|
||||
vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::CopyFlag,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
if (numValues == GetNumberOfValues(buffers))
|
||||
{
|
||||
// In general, we don't allow resizing of the array, but if it was "allocated" to the
|
||||
// correct size, we will allow that.
|
||||
}
|
||||
else
|
||||
{
|
||||
throw vtkm::cont::ErrorBadAllocation(
|
||||
"Cannot allocate/resize ArrayHandleOffsetsToNumComponents.");
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
@ -110,13 +94,6 @@ public:
|
||||
VTKM_ASSERT(OffsetsStorage::GetNumberOfValues(buffers) > 0);
|
||||
return ReadPortalType(OffsetsStorage::CreateReadPortal(buffers, device, token));
|
||||
}
|
||||
|
||||
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer*,
|
||||
vtkm::cont::DeviceAdapterId,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadAllocation("Cannot write to implicit arrays.");
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -140,6 +140,15 @@ public:
|
||||
return IndexStorage::GetNumberOfValues(IndexBuffers(buffers));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const T&,
|
||||
vtkm::Id,
|
||||
vtkm::Id,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandlePermutation.");
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -442,6 +442,15 @@ public:
|
||||
return SourceStorage::GetNumberOfValues(BuffersForComponent(buffers, 0));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const vtkm::internal::RecombineVec<ReadWritePortal>&,
|
||||
vtkm::Id,
|
||||
vtkm::Id,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleRecombineVec.");
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -146,6 +146,16 @@ public:
|
||||
return SourceStorage::GetNumberOfValues(buffers);
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const T& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
vtkm::Id numValues = GetNumberOfValues(buffers);
|
||||
SourceStorage::Fill(buffers, fillValue, numValues - endIndex, numValues - startIndex, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -162,6 +162,23 @@ public:
|
||||
static_cast<vtkm::Id>(sizeof(ComponentType));
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
constexpr vtkm::BufferSizeType sourceSize =
|
||||
static_cast<vtkm::BufferSizeType>(sizeof(ComponentType));
|
||||
vtkm::BufferSizeType startByte = startIndex * sourceSize;
|
||||
vtkm::BufferSizeType endByte = endIndex * sourceSize;
|
||||
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
|
||||
{
|
||||
ComponentType source = fillValue[componentIndex];
|
||||
buffers[componentIndex].Fill(&source, sourceSize, startByte, endByte, 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,15 @@ public:
|
||||
return GetInfo(buffers).NumberOfValues;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
|
||||
const T&,
|
||||
vtkm::Id,
|
||||
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)
|
||||
|
@ -168,6 +168,20 @@ public:
|
||||
return ReadPortalType(SourceStorage::CreateReadPortal(buffers + 1, device, token), indices);
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const T& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
|
||||
vtkm::Id adjustedStartIndex = startIndex + indices.StartIndex;
|
||||
vtkm::Id adjustedEndIndex = (endIndex < indices.NumberOfValues)
|
||||
? endIndex + indices.StartIndex
|
||||
: indices.NumberOfValues + indices.StartIndex;
|
||||
SourceStorage::Fill(buffers, fillValue, adjustedStartIndex, adjustedEndIndex, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -181,6 +181,16 @@ public:
|
||||
return numValues;
|
||||
}
|
||||
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
FirstStorage::Fill(FirstArrayBuffers(buffers), fillValue.first, startIndex, endIndex, token);
|
||||
SecondStorage::Fill(SecondArrayBuffers(buffers), fillValue.second, startIndex, endIndex, token);
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
|
@ -70,6 +70,13 @@ void BitField::Allocate(vtkm::Id numberOfBits,
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits = numberOfBits;
|
||||
}
|
||||
|
||||
void BitField::FillImpl(const void* word,
|
||||
vtkm::BufferSizeType wordSize,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
this->Buffer.Fill(word, wordSize, 0, this->Buffer.GetNumberOfBytes(), token);
|
||||
}
|
||||
|
||||
void BitField::ReleaseResourcesExecution()
|
||||
{
|
||||
this->Buffer.ReleaseDeviceResources();
|
||||
|
@ -546,6 +546,8 @@ public:
|
||||
using PortalConstControl VTKM_DEPRECATED(1.6, "Use ArrayBitField::ReadPortalType instead.") =
|
||||
detail::BitPortalConst;
|
||||
|
||||
using WordTypePreferred = vtkm::AtomicTypePreferred;
|
||||
|
||||
template <typename Device>
|
||||
struct ExecutionTypes
|
||||
{
|
||||
@ -622,6 +624,53 @@ public:
|
||||
this->Allocate(numberOfBits, preserve, token);
|
||||
}
|
||||
|
||||
/// Allocate the requested number of bits and fill with the requested bit or word.
|
||||
template <typename ValueType>
|
||||
VTKM_CONT void AllocateAndFill(vtkm::Id numberOfBits,
|
||||
ValueType value,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
this->Allocate(numberOfBits, vtkm::CopyFlag::Off, token);
|
||||
this->Fill(value, token);
|
||||
}
|
||||
template <typename ValueType>
|
||||
VTKM_CONT void AllocateAndFill(vtkm::Id numberOfBits, ValueType value) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->AllocateAndFill(numberOfBits, value, token);
|
||||
}
|
||||
|
||||
private:
|
||||
VTKM_CONT void FillImpl(const void* word,
|
||||
vtkm::BufferSizeType wordSize,
|
||||
vtkm::cont::Token& token) const;
|
||||
|
||||
public:
|
||||
/// Set subsequent words to the given word of bits.
|
||||
template <typename WordType>
|
||||
VTKM_CONT void Fill(WordType word, vtkm::cont::Token& token) const
|
||||
{
|
||||
this->FillImpl(&word, static_cast<vtkm::BufferSizeType>(sizeof(WordType)), token);
|
||||
}
|
||||
template <typename WordType>
|
||||
VTKM_CONT void Fill(WordType word) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Fill(word, token);
|
||||
}
|
||||
|
||||
/// Set all the bits to the given value
|
||||
VTKM_CONT void Fill(bool value, vtkm::cont::Token& token) const
|
||||
{
|
||||
using WordType = WordTypePreferred;
|
||||
this->Fill(value ? ~WordType{ 0 } : WordType{ 0 }, token);
|
||||
}
|
||||
VTKM_CONT void Fill(bool value) const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Fill(value, token);
|
||||
}
|
||||
|
||||
/// Shrink the bit field to the requested number of bits.
|
||||
VTKM_CONT VTKM_DEPRECATED(1.6,
|
||||
"Use Allocate with preserve = On.") void Shrink(vtkm::Id numberOfBits)
|
||||
|
@ -163,7 +163,6 @@ set(sources
|
||||
ErrorBadType.cxx
|
||||
FieldRangeCompute.cxx
|
||||
FieldRangeGlobalCompute.cxx
|
||||
internal/Buffer.cxx
|
||||
internal/DeviceAdapterMemoryManager.cxx
|
||||
internal/DeviceAdapterMemoryManagerShared.cxx
|
||||
internal/RuntimeDeviceConfiguration.cxx
|
||||
@ -193,6 +192,7 @@ set(device_sources
|
||||
ColorTable.cxx
|
||||
ConvertNumComponentsToOffsets.cxx
|
||||
Field.cxx
|
||||
internal/Buffer.cxx
|
||||
MergePartitionedDataSet.cxx
|
||||
PointLocatorSparseGrid.cxx
|
||||
RuntimeDeviceInformation.cxx
|
||||
|
@ -134,6 +134,14 @@ 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 and ending at the given indices.
|
||||
///
|
||||
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
|
||||
const ValueType& fillValue,
|
||||
vtkm::Id startIndex,
|
||||
vtkm::Id endIndex,
|
||||
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 +189,17 @@ 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::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&) \
|
||||
{ \
|
||||
|
@ -10,14 +10,18 @@
|
||||
|
||||
#include <vtkm/internal/Assume.h>
|
||||
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/ErrorBadAllocation.h>
|
||||
#include <vtkm/cont/ErrorBadDevice.h>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/cont/internal/Buffer.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterMemoryManager.h>
|
||||
|
||||
#include <vtkm/exec/FunctorBase.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
@ -45,6 +49,12 @@ vtkm::BufferSizeType NumberOfValuesToNumberOfBytes(vtkm::Id numValues, std::size
|
||||
} // namespace vtkm::internal
|
||||
|
||||
namespace
|
||||
// nvcc whines about things like conversion operators that are defined but never used.
|
||||
// I don't want to delete them because you never know when the code is going to change.
|
||||
// So make the namespace technically not anonymous.
|
||||
#ifdef VTKM_CUDA
|
||||
vtkm_buffer_ns
|
||||
#endif
|
||||
{
|
||||
|
||||
using LockType = std::unique_lock<std::mutex>;
|
||||
@ -157,7 +167,92 @@ struct MetaDataManager
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FillFunctor : vtkm::exec::FunctorBase
|
||||
{
|
||||
T* TargetArray;
|
||||
const T* SourceValues;
|
||||
vtkm::Id NumSourceValues;
|
||||
|
||||
VTKM_CONT FillFunctor(void* targetArray,
|
||||
const void* sourceValues,
|
||||
vtkm::BufferSizeType sourceValuesSize,
|
||||
vtkm::BufferSizeType start)
|
||||
: TargetArray(reinterpret_cast<T*>(targetArray))
|
||||
, SourceValues(reinterpret_cast<const T*>(sourceValues))
|
||||
, NumSourceValues(sourceValuesSize / sizeof(T))
|
||||
{
|
||||
VTKM_ASSERT((sourceValuesSize % sizeof(T)) == 0);
|
||||
VTKM_ASSERT((start % sizeof(T)) == 0);
|
||||
this->TargetArray += start / sizeof(T);
|
||||
}
|
||||
|
||||
VTKM_EXEC void operator()(vtkm::Id index) const
|
||||
{
|
||||
T* target = this->TargetArray + (index * this->NumSourceValues);
|
||||
for (vtkm::Id sourceIndex = 0; sourceIndex < this->NumSourceValues; ++sourceIndex)
|
||||
{
|
||||
*target = this->SourceValues[sourceIndex];
|
||||
++target;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Device>
|
||||
void FillBuffer(const vtkm::cont::internal::Buffer& target,
|
||||
const vtkm::cont::internal::Buffer& source,
|
||||
vtkm::BufferSizeType start,
|
||||
vtkm::BufferSizeType end,
|
||||
Device device,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
void* targetPointer = target.WritePointerDevice(device, token);
|
||||
const void* sourcePointer = source.ReadPointerDevice(device, token);
|
||||
|
||||
// Get after target locked with token.
|
||||
vtkm::BufferSizeType targetSize = target.GetNumberOfBytes();
|
||||
vtkm::BufferSizeType sourceSize = source.GetNumberOfBytes();
|
||||
if (targetSize <= start)
|
||||
{
|
||||
return;
|
||||
}
|
||||
VTKM_ASSERT((targetSize % sourceSize) == 0);
|
||||
VTKM_ASSERT((start % sourceSize) == 0);
|
||||
VTKM_ASSERT((end % sourceSize) == 0);
|
||||
VTKM_ASSERT(end <= targetSize);
|
||||
VTKM_ASSERT(end >= start);
|
||||
if (end <= start)
|
||||
{
|
||||
// Nothing to set.
|
||||
return;
|
||||
}
|
||||
|
||||
vtkm::Id numSourceRepetitions = (end - start) / sourceSize;
|
||||
|
||||
if ((sourceSize >= 8) && ((sourceSize % 8) == 0))
|
||||
{
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
|
||||
FillFunctor<vtkm::UInt64>{ targetPointer, sourcePointer, sourceSize, start },
|
||||
numSourceRepetitions);
|
||||
}
|
||||
else if ((sourceSize >= 4) && ((sourceSize % 4) == 0))
|
||||
{
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
|
||||
FillFunctor<vtkm::UInt32>{ targetPointer, sourcePointer, sourceSize, start },
|
||||
numSourceRepetitions);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
|
||||
FillFunctor<vtkm::UInt8>{ targetPointer, sourcePointer, sourceSize, start },
|
||||
numSourceRepetitions);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
#ifdef VTKM_CUDA
|
||||
using namespace vtkm_buffer_ns;
|
||||
#endif
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -1017,6 +1112,45 @@ vtkm::cont::internal::BufferInfo Buffer::GetDeviceBufferInfo(
|
||||
throw vtkm::cont::ErrorBadDevice("Called Buffer::GetDeviceBufferInfo with invalid device");
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::Fill(const void* source,
|
||||
vtkm::BufferSizeType sourceSize,
|
||||
vtkm::BufferSizeType start,
|
||||
vtkm::BufferSizeType end,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
vtkm::cont::internal::Buffer sourceBuffer;
|
||||
sourceBuffer.Reset(vtkm::cont::internal::BufferInfo(
|
||||
vtkm::cont::DeviceAdapterTagUndefined{},
|
||||
const_cast<void*>(source),
|
||||
const_cast<void*>(source),
|
||||
sourceSize,
|
||||
[](void*) {},
|
||||
[](void*&, void*&, vtkm::BufferSizeType, vtkm::BufferSizeType) {}));
|
||||
|
||||
// First, try setting on any device that already has the data.
|
||||
bool success = vtkm::cont::TryExecute([&](auto device) {
|
||||
if (this->IsAllocatedOnDevice(device))
|
||||
{
|
||||
FillBuffer(*this, sourceBuffer, start, end, device, token);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// Likely the data was not on any device. Fill on any device.
|
||||
vtkm::cont::TryExecute([&](auto device) {
|
||||
FillBuffer(*this, sourceBuffer, start, end, device, token);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::internal
|
||||
|
@ -310,6 +310,21 @@ public:
|
||||
VTKM_CONT vtkm::cont::internal::TransferredBuffer TakeDeviceBufferOwnership(
|
||||
vtkm::cont::DeviceAdapterId device);
|
||||
|
||||
/// \brief Fill up the buffer with particular values.
|
||||
///
|
||||
/// Given a short `source` C array (defined on the host), sets all values in the buffer
|
||||
/// to that source. The `sourceSize`, in bytes, is also specified. You also specify an
|
||||
/// offset to where the fill should `start` and `end`. Values before the `start` and
|
||||
/// after the `end` are not affected.
|
||||
///
|
||||
/// Both `start` and `end` must be divisible by `sourceSize`.
|
||||
///
|
||||
VTKM_CONT void Fill(const void* source,
|
||||
vtkm::BufferSizeType sourceSize,
|
||||
vtkm::BufferSizeType start,
|
||||
vtkm::BufferSizeType end,
|
||||
vtkm::cont::Token& token) const;
|
||||
|
||||
VTKM_CONT bool operator==(const vtkm::cont::internal::Buffer& rhs) const
|
||||
{
|
||||
return (this->Internals == rhs.Internals);
|
||||
|
@ -186,6 +186,29 @@ void DoTest()
|
||||
VTKM_TEST_ASSERT(buffer.IsAllocatedOnHost());
|
||||
VTKM_TEST_ASSERT(!buffer.IsAllocatedOnDevice(device));
|
||||
|
||||
std::cout << "Fill buffer" << std::endl;
|
||||
{
|
||||
constexpr vtkm::BufferSizeType fillValueSize = static_cast<vtkm::BufferSizeType>(sizeof(T));
|
||||
vtkm::cont::Token token;
|
||||
T fillValue1 = 1.234f;
|
||||
T fillValue2 = 5.678f;
|
||||
buffer.Fill(&fillValue1, fillValueSize, 0, BUFFER_SIZE * 2, token);
|
||||
buffer.Fill(&fillValue2, fillValueSize, BUFFER_SIZE / 2, BUFFER_SIZE, token);
|
||||
const T* array = reinterpret_cast<const T*>(buffer.ReadPointerHost(token));
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE / 2; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(array[index] == fillValue1);
|
||||
}
|
||||
for (vtkm::Id index = ARRAY_SIZE / 2; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(array[index] == fillValue2);
|
||||
}
|
||||
for (vtkm::Id index = ARRAY_SIZE; index < ARRAY_SIZE * 2; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(array[index] == fillValue1);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Reset with device data" << std::endl;
|
||||
std::vector<T> v(ARRAY_SIZE);
|
||||
void* devicePointer = v.data();
|
||||
|
@ -59,7 +59,7 @@ class TestingArrayHandleMultiplexer
|
||||
|
||||
static void BasicSwitch()
|
||||
{
|
||||
std::cout << std::endl << "--- Basic switch" << std::endl;
|
||||
std::cout << "\n--- Basic switch" << std::endl;
|
||||
|
||||
using ValueType = vtkm::FloatDefault;
|
||||
|
||||
@ -93,7 +93,7 @@ class TestingArrayHandleMultiplexer
|
||||
// algorithm on CUDA. Most likely related to:
|
||||
// https://github.com/thrust/thrust/issues/928
|
||||
// https://github.com/thrust/thrust/issues/1044
|
||||
std::cout << std::endl << "--- Reduce" << std::endl;
|
||||
std::cout << "\n--- Reduce" << std::endl;
|
||||
|
||||
using ValueType = vtkm::Vec3f;
|
||||
using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer<
|
||||
@ -127,10 +127,62 @@ class TestingArrayHandleMultiplexer
|
||||
}
|
||||
}
|
||||
|
||||
static void Fill()
|
||||
{
|
||||
std::cout << "\n--- Fill" << std::endl;
|
||||
|
||||
using ValueType = vtkm::Vec3f;
|
||||
using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer<
|
||||
vtkm::cont::ArrayHandleConstant<ValueType>,
|
||||
vtkm::cont::ArrayHandleCounting<ValueType>,
|
||||
vtkm::cont::ArrayHandle<ValueType>,
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates,
|
||||
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>;
|
||||
|
||||
const ValueType testValue1 = TestValue(1, ValueType{});
|
||||
const ValueType testValue2 = TestValue(2, ValueType{});
|
||||
|
||||
MultiplexerType multiplexer = vtkm::cont::ArrayHandle<ValueType>{};
|
||||
|
||||
multiplexer.AllocateAndFill(ARRAY_SIZE, testValue1);
|
||||
{
|
||||
auto portal = multiplexer.ReadPortal();
|
||||
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE);
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == testValue1);
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array1;
|
||||
array1.Allocate(ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array2;
|
||||
array2.Allocate(ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array3;
|
||||
array3.Allocate(ARRAY_SIZE);
|
||||
multiplexer = vtkm::cont::make_ArrayHandleCartesianProduct(array1, array2, array3);
|
||||
|
||||
multiplexer.Fill(testValue2);
|
||||
{
|
||||
auto portal1 = array1.ReadPortal();
|
||||
auto portal2 = array2.ReadPortal();
|
||||
auto portal3 = array3.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal1.Get(index) == testValue2[0]);
|
||||
VTKM_TEST_ASSERT(portal2.Get(index) == testValue2[1]);
|
||||
VTKM_TEST_ASSERT(portal3.Get(index) == testValue2[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TestAll()
|
||||
{
|
||||
BasicSwitch();
|
||||
Reduce();
|
||||
Fill();
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -700,6 +700,40 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
struct VerifyFill
|
||||
{
|
||||
template <typename T>
|
||||
VTKM_CONT void operator()(T) const
|
||||
{
|
||||
std::cout << "Initialize values of array." << std::endl;
|
||||
const T testValue1 = TestValue(13, T{});
|
||||
vtkm::cont::ArrayHandle<T> array;
|
||||
array.AllocateAndFill(ARRAY_SIZE, testValue1);
|
||||
{
|
||||
auto portal = array.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == testValue1);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Grow array with new values." << std::endl;
|
||||
const T testValue2 = TestValue(42, T{});
|
||||
array.AllocateAndFill(ARRAY_SIZE * 2, testValue2, vtkm::CopyFlag::On);
|
||||
{
|
||||
auto portal = array.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == testValue1);
|
||||
}
|
||||
for (vtkm::Id index = ARRAY_SIZE; index < ARRAY_SIZE * 2; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == testValue2);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TryArrayHandleType
|
||||
{
|
||||
void operator()() const
|
||||
@ -712,6 +746,7 @@ private:
|
||||
vtkm::testing::Testing::TryTypes(VerifyVTKMAllocatedHandle{});
|
||||
vtkm::testing::Testing::TryTypes(VerifyVTKMTransferredOwnership{});
|
||||
vtkm::testing::Testing::TryTypes(VerifyEqualityOperators{});
|
||||
vtkm::testing::Testing::TryTypes(VerifyFill{});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -531,6 +531,31 @@ struct TestingBitField
|
||||
testMask64(129, 0x0000000000000001);
|
||||
}
|
||||
|
||||
VTKM_CONT static void TestFill()
|
||||
{
|
||||
vtkm::cont::BitField bitField;
|
||||
bitField.Allocate(NUM_BITS);
|
||||
|
||||
bitField.Fill(true);
|
||||
{
|
||||
auto portal = bitField.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < NUM_BITS; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.GetBit(index));
|
||||
}
|
||||
}
|
||||
|
||||
constexpr vtkm::UInt8 word8 = 0xA6;
|
||||
bitField.Fill(word8);
|
||||
{
|
||||
auto portal = bitField.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < NUM_BITS; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.GetBit(index) == ((word8 >> (index % 8)) & 0x01));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ArrayHandleBitFieldChecker : vtkm::exec::FunctorBase
|
||||
{
|
||||
using PortalType = vtkm::cont::ArrayHandleBitField::WritePortalType;
|
||||
@ -574,13 +599,34 @@ struct TestingBitField
|
||||
" got: ",
|
||||
numBits);
|
||||
|
||||
vtkm::cont::Token token;
|
||||
Algo::Schedule(
|
||||
ArrayHandleBitFieldChecker{ handle.PrepareForInPlace(DeviceAdapterTag{}, token), false },
|
||||
numBits);
|
||||
Algo::Schedule(
|
||||
ArrayHandleBitFieldChecker{ handle.PrepareForInPlace(DeviceAdapterTag{}, token), true },
|
||||
numBits);
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
Algo::Schedule(
|
||||
ArrayHandleBitFieldChecker{ handle.PrepareForInPlace(DeviceAdapterTag{}, token), false },
|
||||
numBits);
|
||||
Algo::Schedule(
|
||||
ArrayHandleBitFieldChecker{ handle.PrepareForInPlace(DeviceAdapterTag{}, token), true },
|
||||
numBits);
|
||||
}
|
||||
|
||||
handle.Fill(true);
|
||||
{
|
||||
auto portal = handle.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < NUM_BITS; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index));
|
||||
}
|
||||
}
|
||||
|
||||
handle.Fill(false, 24);
|
||||
handle.Fill(true, 64);
|
||||
{
|
||||
auto portal = handle.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < NUM_BITS; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == ((index < 24) || (index >= 64)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -647,6 +693,7 @@ struct TestingBitField
|
||||
TestingBitField::TestControlPortals();
|
||||
TestingBitField::TestExecutionPortals();
|
||||
TestingBitField::TestFinalWordMask();
|
||||
TestingBitField::TestFill();
|
||||
TestingBitField::TestArrayHandleBitField();
|
||||
TestingBitField::TestArrayInvokeWorklet();
|
||||
TestingBitField::TestArrayInvokeWorklet2();
|
||||
|
@ -1495,6 +1495,28 @@ private:
|
||||
VTKM_TEST_ASSERT(test_equal(result_value, ValueType(static_cast<ValueComponentType>(i))),
|
||||
"ArrayHandleZip Failed as input for value");
|
||||
}
|
||||
|
||||
// Test filling the zipped array.
|
||||
vtkm::cont::printSummary_ArrayHandle(result_zip, std::cout, true);
|
||||
PairType fillValue{ TestValue(1, KeyType{}), TestValue(2, ValueType{}) };
|
||||
result_zip.Fill(fillValue, 1);
|
||||
vtkm::cont::printSummary_ArrayHandle(result_zip, std::cout, true);
|
||||
keysPortal = result_keys.ReadPortal();
|
||||
valsPortal = result_values.ReadPortal();
|
||||
// First entry should be the same.
|
||||
VTKM_TEST_ASSERT(
|
||||
test_equal(keysPortal.Get(0), KeyType(static_cast<KeyComponentType>(ARRAY_SIZE))));
|
||||
VTKM_TEST_ASSERT(
|
||||
test_equal(valsPortal.Get(0), ValueType(static_cast<ValueComponentType>(0))));
|
||||
// The rest should be fillValue
|
||||
for (vtkm::Id index = 1; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
const KeyType result_key = keysPortal.Get(index);
|
||||
const ValueType result_value = valsPortal.Get(index);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(result_key, fillValue.first));
|
||||
VTKM_TEST_ASSERT(test_equal(result_value, fillValue.second));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -219,6 +219,36 @@ void TryVector()
|
||||
TryVector1(MakeInputArray<vtkm::Vec3f>(0));
|
||||
}
|
||||
|
||||
void TryFill()
|
||||
{
|
||||
std::cout << "Trying fill." << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array0;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array1;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array2;
|
||||
|
||||
auto composite = vtkm::cont::make_ArrayHandleCompositeVector(array0, array1, array2);
|
||||
|
||||
const vtkm::Vec3f testValue = TestValue(0, vtkm::Vec3f{});
|
||||
|
||||
composite.AllocateAndFill(ARRAY_SIZE, testValue);
|
||||
|
||||
auto portal0 = array0.ReadPortal();
|
||||
auto portal1 = array1.ReadPortal();
|
||||
auto portal2 = array2.ReadPortal();
|
||||
|
||||
VTKM_TEST_ASSERT(portal0.GetNumberOfValues() == ARRAY_SIZE);
|
||||
VTKM_TEST_ASSERT(portal1.GetNumberOfValues() == ARRAY_SIZE);
|
||||
VTKM_TEST_ASSERT(portal2.GetNumberOfValues() == ARRAY_SIZE);
|
||||
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal0.Get(index) == testValue[0]);
|
||||
VTKM_TEST_ASSERT(portal1.Get(index) == testValue[1]);
|
||||
VTKM_TEST_ASSERT(portal2.Get(index) == testValue[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void TrySpecialArrays()
|
||||
{
|
||||
std::cout << "Trying special arrays." << std::endl;
|
||||
@ -251,6 +281,8 @@ void TestCompositeVector()
|
||||
|
||||
TryVector();
|
||||
|
||||
TryFill();
|
||||
|
||||
TrySpecialArrays();
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
namespace UnitTestArrayHandleConcatenateNamespace
|
||||
namespace
|
||||
{
|
||||
|
||||
const vtkm::Id ARRAY_SIZE = 5;
|
||||
constexpr vtkm::Id ARRAY_SIZE = 4;
|
||||
|
||||
void TestArrayHandleConcatenate()
|
||||
void TestConcatOfConcat()
|
||||
{
|
||||
vtkm::cont::ArrayHandleIndex array1(ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandleIndex array2(2 * ARRAY_SIZE);
|
||||
@ -36,10 +36,21 @@ void TestArrayHandleConcatenate()
|
||||
array5 = vtkm::cont::make_ArrayHandleConcatenate(array3, array4);
|
||||
}
|
||||
|
||||
auto array5Portal = array5.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < array5.GetNumberOfValues(); index++)
|
||||
vtkm::cont::printSummary_ArrayHandle(array5, std::cout, true);
|
||||
|
||||
VTKM_TEST_ASSERT(array5.GetNumberOfValues() == 4 * ARRAY_SIZE);
|
||||
|
||||
// Check the values in array5. If array5 is correct, all the `ArrayHandleConcatinate`s
|
||||
// (such as in array3) must be working.
|
||||
auto portal = array5.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
std::cout << array5Portal.Get(index) << std::endl;
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == index);
|
||||
VTKM_TEST_ASSERT(portal.Get(index + (3 * ARRAY_SIZE)) == index);
|
||||
}
|
||||
for (vtkm::Id index = 0; index < (2 * ARRAY_SIZE); ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index + ARRAY_SIZE) == index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +58,9 @@ void TestConcatenateEmptyArray()
|
||||
{
|
||||
std::vector<vtkm::Float64> vec;
|
||||
for (vtkm::Id i = 0; i < ARRAY_SIZE; i++)
|
||||
{
|
||||
vec.push_back(vtkm::Float64(i) * 1.5);
|
||||
}
|
||||
|
||||
using CoeffValueType = vtkm::Float64;
|
||||
using CoeffArrayTypeTmp = vtkm::cont::ArrayHandle<CoeffValueType>;
|
||||
@ -60,16 +73,59 @@ void TestConcatenateEmptyArray()
|
||||
ArrayConcat arrConc(arr2, arr1);
|
||||
ArrayConcat2 arrConc2(arrConc, arr3);
|
||||
|
||||
auto arrConc2Portal = arrConc2.ReadPortal();
|
||||
for (vtkm::Id i = 0; i < arrConc2.GetNumberOfValues(); i++)
|
||||
std::cout << arrConc2Portal.Get(i) << std::endl;
|
||||
vtkm::cont::printSummary_ArrayHandle(arrConc2, std::cout, true);
|
||||
|
||||
VTKM_TEST_ASSERT(arrConc2.GetNumberOfValues() == ARRAY_SIZE);
|
||||
}
|
||||
|
||||
} // namespace UnitTestArrayHandleIndexNamespace
|
||||
void TestConcatenateFill()
|
||||
{
|
||||
using T = vtkm::FloatDefault;
|
||||
vtkm::cont::ArrayHandle<T> array1;
|
||||
vtkm::cont::ArrayHandle<T> array2;
|
||||
array1.Allocate(ARRAY_SIZE);
|
||||
array2.Allocate(ARRAY_SIZE);
|
||||
|
||||
auto concatArray = vtkm::cont::make_ArrayHandleConcatenate(array1, array2);
|
||||
|
||||
const T value0 = TestValue(0, T{});
|
||||
const T value1 = TestValue(1, T{});
|
||||
const T value2 = TestValue(2, T{});
|
||||
|
||||
VTKM_STATIC_ASSERT_MSG((ARRAY_SIZE % 2) == 0, "ARRAY_SIZE must be even for this test.");
|
||||
|
||||
concatArray.Fill(value2, 3 * ARRAY_SIZE / 2);
|
||||
concatArray.Fill(value1, ARRAY_SIZE / 2, 3 * ARRAY_SIZE / 2);
|
||||
concatArray.Fill(value0, 0, ARRAY_SIZE / 2);
|
||||
|
||||
vtkm::cont::printSummary_ArrayHandle(concatArray, std::cout, true);
|
||||
|
||||
auto portal = concatArray.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < (ARRAY_SIZE / 2); ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == value0);
|
||||
}
|
||||
for (vtkm::Id index = (ARRAY_SIZE / 2); index < (3 * ARRAY_SIZE / 2); ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == value1);
|
||||
}
|
||||
for (vtkm::Id index = (3 * ARRAY_SIZE / 2); index < (2 * ARRAY_SIZE); ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == value2);
|
||||
}
|
||||
}
|
||||
|
||||
void TestArrayHandleConcatenate()
|
||||
{
|
||||
TestConcatOfConcat();
|
||||
TestConcatenateEmptyArray();
|
||||
TestConcatenateFill();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestArrayHandleConcatenate(int argc, char* argv[])
|
||||
{
|
||||
using namespace UnitTestArrayHandleConcatenateNamespace;
|
||||
//TestConcatenateEmptyArray();
|
||||
return vtkm::cont::testing::Testing::Run(TestArrayHandleConcatenate, argc, argv);
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ struct DecoratorTests
|
||||
auto ah1 = vtkm::cont::make_ArrayHandleCounting(ValueType{ 0 }, ValueType{ 2 }, ARRAY_SIZE);
|
||||
auto ah2 = vtkm::cont::make_ArrayHandleConstant(ValueType{ ARRAY_SIZE }, ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<ValueType> ah3;
|
||||
vtkm::cont::Algorithm::Fill(ah3, ValueType{ ARRAY_SIZE / 2 }, ARRAY_SIZE);
|
||||
ah3.AllocateAndFill(ARRAY_SIZE, ValueType{ ARRAY_SIZE / 2 });
|
||||
|
||||
auto ah3Const = vtkm::cont::make_ArrayHandleConstant(ValueType{ ARRAY_SIZE / 2 }, ARRAY_SIZE);
|
||||
|
||||
|
@ -107,10 +107,18 @@ struct Test
|
||||
handle.PrepareForOutput(ARRAY_SIZE, DeviceTag(), token);
|
||||
}
|
||||
|
||||
void TestFill()
|
||||
{
|
||||
DiscardHandle array;
|
||||
array.AllocateAndFill(ARRAY_SIZE, ValueType{ 0 });
|
||||
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE);
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
TestReduceByKey();
|
||||
TestPrepareExceptions();
|
||||
TestFill();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -88,11 +88,26 @@ void TestArrayHandleReverseScanInclusiveByKey()
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void TestArrayHandleReverseFill()
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> handle;
|
||||
auto reverse = vtkm::cont::make_ArrayHandleReverse(handle);
|
||||
|
||||
reverse.AllocateAndFill(ARRAY_SIZE, 20, vtkm::CopyFlag::Off);
|
||||
VTKM_TEST_ASSERT(reverse.GetNumberOfValues() == ARRAY_SIZE);
|
||||
auto portal = reverse.ReadPortal();
|
||||
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
||||
{
|
||||
VTKM_TEST_ASSERT(portal.Get(index) == 20);
|
||||
}
|
||||
}
|
||||
|
||||
void TestArrayHandleReverse()
|
||||
{
|
||||
TestArrayHandleReverseRead();
|
||||
TestArrayHandleReverseWrite();
|
||||
TestArrayHandleReverseScanInclusiveByKey();
|
||||
TestArrayHandleReverseFill();
|
||||
}
|
||||
|
||||
}; // namespace UnitTestArrayHandleReverseNamespace
|
||||
|
@ -348,16 +348,16 @@ public:
|
||||
auto activePoints = vtkm::cont::make_ArrayHandleBitField(activePointBits);
|
||||
|
||||
vtkm::cont::BitField activeCellBits;
|
||||
vtkm::cont::Algorithm::Fill(activeCellBits, false, numCells);
|
||||
activeCellBits.AllocateAndFill(numCells, false);
|
||||
auto activeCells = vtkm::cont::make_ArrayHandleBitField(activeCellBits);
|
||||
|
||||
// visited = cells / points that have been corrected.
|
||||
vtkm::cont::BitField visitedPointBits;
|
||||
vtkm::cont::Algorithm::Fill(visitedPointBits, false, numPoints);
|
||||
visitedPointBits.AllocateAndFill(numPoints, false);
|
||||
auto visitedPoints = vtkm::cont::make_ArrayHandleBitField(visitedPointBits);
|
||||
|
||||
vtkm::cont::BitField visitedCellBits;
|
||||
vtkm::cont::Algorithm::Fill(visitedCellBits, false, numCells);
|
||||
visitedCellBits.AllocateAndFill(numCells, false);
|
||||
auto visitedCells = vtkm::cont::make_ArrayHandleBitField(visitedCellBits);
|
||||
|
||||
vtkm::cont::Invoker invoke;
|
||||
|
@ -330,7 +330,7 @@ public:
|
||||
auto activePoints = vtkm::cont::make_ArrayHandleBitField(activePointBits);
|
||||
|
||||
vtkm::cont::BitField activeCellBits;
|
||||
vtkm::cont::Algorithm::Fill(activeCellBits, false, numCells);
|
||||
activeCellBits.AllocateAndFill(numCells, false);
|
||||
auto activeCells = vtkm::cont::make_ArrayHandleBitField(activeCellBits);
|
||||
|
||||
// visited = cells / points that have been corrected.
|
||||
@ -338,7 +338,7 @@ public:
|
||||
auto visitedPoints = vtkm::cont::make_ArrayHandleBitField(visitedPointBits);
|
||||
|
||||
vtkm::cont::BitField visitedCellBits;
|
||||
vtkm::cont::Algorithm::Fill(visitedCellBits, false, numCells);
|
||||
visitedCellBits.AllocateAndFill(numCells, false);
|
||||
auto visitedCells = vtkm::cont::make_ArrayHandleBitField(visitedCellBits);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> mask; // Allocated as needed
|
||||
|
@ -291,7 +291,7 @@ public:
|
||||
auto activePoints = vtkm::cont::make_ArrayHandleBitField(activePointBits);
|
||||
|
||||
vtkm::cont::BitField activeCellBits;
|
||||
vtkm::cont::Algorithm::Fill(activeCellBits, false, numCells);
|
||||
activeCellBits.AllocateAndFill(numCells, false);
|
||||
auto activeCells = vtkm::cont::make_ArrayHandleBitField(activeCellBits);
|
||||
|
||||
// visited = cells / points that have been corrected.
|
||||
@ -299,7 +299,7 @@ public:
|
||||
auto visitedPoints = vtkm::cont::make_ArrayHandleBitField(visitedPointBits);
|
||||
|
||||
vtkm::cont::BitField visitedCellBits;
|
||||
vtkm::cont::Algorithm::Fill(visitedCellBits, false, numCells);
|
||||
visitedCellBits.AllocateAndFill(numCells, false);
|
||||
auto visitedCells = vtkm::cont::make_ArrayHandleBitField(visitedCellBits);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> mask; // Allocated as needed
|
||||
|
@ -173,7 +173,7 @@ struct launchComputePass1
|
||||
vtkm::cont::Invoker invoke(device);
|
||||
metaDataMesh2D = make_metaDataMesh2D(SumYAxis{}, worklet.PointDims);
|
||||
|
||||
vtkm::cont::Algorithm::Fill(edgeCases, static_cast<vtkm::UInt8>(FlyingEdges3D::Below));
|
||||
edgeCases.Fill(static_cast<vtkm::UInt8>(FlyingEdges3D::Below));
|
||||
invoke(worklet, metaDataMesh2D, std::forward<Args>(args)..., edgeCases, inputField);
|
||||
return true;
|
||||
}
|
||||
|
@ -738,9 +738,8 @@ inline void ContourTreeMesh<FieldType>::MergeWith(ContourTreeMesh<FieldType>& ot
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> thisToCombinedSortOrderIsDuplicate;
|
||||
thisToCombinedSortOrderIsDuplicate.Allocate(thisToCombinedSortOrder.GetNumberOfValues());
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> otherToCombinedSortOrderIsDuplicate;
|
||||
vtkm::cont::Algorithm::Fill(otherToCombinedSortOrderIsDuplicate,
|
||||
vtkm::IdComponent{ 0 },
|
||||
otherToCombinedSortOrder.GetNumberOfValues());
|
||||
otherToCombinedSortOrderIsDuplicate.AllocateAndFill(otherToCombinedSortOrder.GetNumberOfValues(),
|
||||
vtkm::IdComponent{ 0 });
|
||||
this->Invoke(contourtree_mesh_inc_ns::FindDuplicateInOtherWorklet{},
|
||||
thisToCombinedSortOrder,
|
||||
otherToCombinedSortOrder,
|
||||
|
@ -215,13 +215,10 @@ HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::HierarchicalHype
|
||||
, NumOwnedRegularVertices(vtkm::Id{ 0 })
|
||||
{ // constructor
|
||||
// Initalize arrays with 0s
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
this->ValuePrefixSum, vtkm::Id{ 0 }, this->HierarchicalTree.Supernodes.GetNumberOfValues());
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
this->TransferTarget, vtkm::Id{ 0 }, this->HierarchicalTree.Supernodes.GetNumberOfValues());
|
||||
vtkm::cont::Algorithm::Fill(this->SortedTransferTarget,
|
||||
vtkm::Id{ 0 },
|
||||
this->HierarchicalTree.Supernodes.GetNumberOfValues());
|
||||
this->ValuePrefixSum.AllocateAndFill(this->HierarchicalTree.Supernodes.GetNumberOfValues(), 0);
|
||||
this->TransferTarget.AllocateAndFill(this->HierarchicalTree.Supernodes.GetNumberOfValues(), 0);
|
||||
this->SortedTransferTarget.AllocateAndFill(this->HierarchicalTree.Supernodes.GetNumberOfValues(),
|
||||
0);
|
||||
// Initialize the supersortPermute to the identity
|
||||
vtkm::cont::ArrayHandleIndex tempIndexArray(
|
||||
this->HierarchicalTree.Supernodes.GetNumberOfValues());
|
||||
@ -295,8 +292,7 @@ void HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::InitializeI
|
||||
#endif
|
||||
|
||||
// initialize the counts to zero.
|
||||
vtkm::cont::Algorithm::Fill(
|
||||
superarcRegularCounts, vtkm::Id{ 0 }, this->HierarchicalTree.Supernodes.GetNumberOfValues());
|
||||
superarcRegularCounts.AllocateAndFill(this->HierarchicalTree.Supernodes.GetNumberOfValues(), 0);
|
||||
|
||||
// set the count to the Id one off the high end of each range
|
||||
Invoke(vtkm::worklet::contourtree_distributed::hierarchical_hyper_sweeper::
|
||||
|
@ -222,8 +222,8 @@ private:
|
||||
|
||||
void Prepare()
|
||||
{
|
||||
vtkm::cont::Algorithm::Fill(this->VisitedPointsField, false, this->Coords.GetNumberOfPoints());
|
||||
vtkm::cont::Algorithm::Fill(this->VisitedCellsField, false, this->Cells.GetNumberOfCells());
|
||||
this->VisitedPointsField.AllocateAndFill(this->Coords.GetNumberOfPoints(), false);
|
||||
this->VisitedCellsField.AllocateAndFill(this->Cells.GetNumberOfCells(), false);
|
||||
}
|
||||
|
||||
void ValidateImpl(vtkm::Id startPtIdx, const NormalType& startRefNormal)
|
||||
|
@ -44,7 +44,7 @@ vtkm::cont::DataSet GenerateDataSet()
|
||||
const auto numCells = ds.GetNumberOfCells();
|
||||
|
||||
vtkm::cont::ArrayHandle<MyNormalT> cellNormals;
|
||||
vtkm::cont::Algorithm::Fill(cellNormals, MyNormalT{ 1., 0., 0. }, numCells);
|
||||
cellNormals.AllocateAndFill(numCells, MyNormalT{ 1., 0., 0. });
|
||||
|
||||
ds.AddField(vtkm::cont::make_FieldCell("normals", cellNormals));
|
||||
return ds;
|
||||
|
Loading…
Reference in New Issue
Block a user