Merge topic 'resizable-arrayhandle-buffer-vec'

05f144eb1 Allow ArrayHandle to have a runtime selectable number of buffers

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2798
This commit is contained in:
Kenneth Moreland 2022-07-12 16:04:07 +00:00 committed by Kitware Robot
commit 5659d74bd4
32 changed files with 872 additions and 720 deletions

@ -0,0 +1,30 @@
# Allow ArrayHandle to have a runtime selectable number of buffers
Previously, the number of buffers held by an `ArrayHandle` had to be
determined statically at compile time by the storage. Most of the time this
is fine. However, there are some exceptions where the number of buffers
need to be selected at runtime. For example, the `ArrayHandleRecombineVec`
does not specify the number of components it uses, and it needed a hack
where it stored buffers in the metadata of another buffer, which is bad.
This change allows the number of buffers to vary at runtime (at least at
construction). The buffers were already managed in a `std::vector`. It now
no longer forces the vector to be a specific size. `GetNumberOfBuffers` was
removed from the `Storage`. Instead, if the number of buffers was not
specified at construction, an allocation of size 0 is done to create
default buffers.
The biggest change is to the interface of the storage object methods, which
now take `std::vector` instead of pointers to `Buffer` objects. This adds a
little hassle in having to copy subsets of this `vector` when a storage
object has multiple sub-arrays. But it does simplify some of the
templating.
Other changes to the `Storage` structure include requiring all objects to
include a `CreateBuffers` method that accepts no arguments. This method
will be used by `ArrayHandle` in its default constructor. Previously,
`ArrayHandle` would create the `vector` of `Buffer` objects itself, but it
now must call this method in the `Storage` to do this. (It also has a nice
side effect of allowing the `Storage` to initialize the buffer objects if
necessary. Another change was to remove the `GetNumberOfBuffers` method
(which no longer has meaning).

@ -314,7 +314,7 @@ public:
/// Constructs an empty ArrayHandle.
///
VTKM_CONT ArrayHandle()
: Buffers(static_cast<std::size_t>(StorageType::GetNumberOfBuffers()))
: Buffers(StorageType::CreateBuffers())
{
}
@ -349,17 +349,10 @@ public:
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 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 ArrayHandle(const vtkm::cont::internal::Buffer* buffers)
: Buffers(buffers, buffers + StorageType::GetNumberOfBuffers())
{
}
///@}
@ -420,9 +413,10 @@ public:
return true; // different valuetype and/or storage
}
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
VTKM_DEPRECATED(1.9, "Use the size of the std::vector returned from GetBuffers.")
VTKM_CONT constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return StorageType::GetNumberOfBuffers();
return static_cast<vtkm::IdComponent>(this->GetBuffers().size());
}
/// Get the storage.
@ -776,9 +770,15 @@ public:
}
}
/// Returns the internal `Buffer` structures that hold the data.
/// \brief Returns the internal `Buffer` structures that hold the data.
///
VTKM_CONT vtkm::cont::internal::Buffer* GetBuffers() const { return this->Buffers.data(); }
/// Note that great care should be taken when modifying buffers outside of the ArrayHandle.
///
VTKM_CONT const std::vector<vtkm::cont::internal::Buffer>& GetBuffers() const
{
return this->Buffers;
}
VTKM_CONT std::vector<vtkm::cont::internal::Buffer>& GetBuffers() { return this->Buffers; }
private:
mutable std::vector<vtkm::cont::internal::Buffer> Buffers;
@ -789,11 +789,13 @@ protected:
this->Buffers[static_cast<std::size_t>(index)] = buffer;
}
// BufferContainer must be an iteratable container of Buffer objects.
template <typename BufferContainer>
VTKM_CONT void SetBuffers(const BufferContainer& buffers)
VTKM_CONT void SetBuffers(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
std::copy(buffers.begin(), buffers.end(), this->Iterators->Buffers.begin());
this->Buffers = buffers;
}
VTKM_CONT void SetBuffers(std::vector<vtkm::cont::internal::Buffer>&& buffers)
{
this->Buffers = std::move(buffers);
}
};
@ -915,6 +917,25 @@ namespace internal
namespace detail
{
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>&);
template <typename T, typename S, typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const vtkm::cont::ArrayHandle<T, S>& array,
const Args&... args);
template <typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const vtkm::cont::internal::Buffer& buffer,
const Args&... args);
template <typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const std::vector<vtkm::cont::internal::Buffer>& addbuffs,
const Args&... args);
template <typename Arg0, typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const Arg0& arg0,
const Args&... args);
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>&)
{
// Nothing left to add.
@ -925,9 +946,7 @@ VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer
const vtkm::cont::ArrayHandle<T, S>& array,
const Args&... args)
{
vtkm::cont::internal::Buffer* arrayBuffers = array.GetBuffers();
buffers.insert(buffers.end(), arrayBuffers, arrayBuffers + array.GetNumberOfBuffers());
CreateBuffersImpl(buffers, args...);
CreateBuffersImpl(buffers, array.GetBuffers(), args...);
}
template <typename... Args>
@ -948,11 +967,6 @@ VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer
CreateBuffersImpl(buffers, args...);
}
template <typename Arg0, typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const Arg0& arg0,
const Args&... args);
template <typename T, typename S, typename... Args>
VTKM_CONT inline void CreateBuffersResolveArrays(std::vector<vtkm::cont::internal::Buffer>& buffers,
std::true_type,
@ -1001,7 +1015,7 @@ VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer
/// - `ArrayHandle`: The buffers from the `ArrayHandle` are added to the list.
/// - `Buffer`: A copy of the buffer is added to the list.
/// - `std::vector<Buffer>`: A copy of all buffers in this vector are added to the list.
/// - Anything else: A buffer with the given object attached as metadata is
/// - Anything else: A buffer with the given object attached as metadata is added to the list.
///
template <typename... Args>
VTKM_CONT inline std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const Args&... args)

@ -35,10 +35,13 @@ public:
using ReadPortalType = vtkm::internal::ArrayPortalBasicRead<T>;
using WritePortalType = vtkm::internal::ArrayPortalBasicWrite<T>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return std::vector<vtkm::cont::internal::Buffer>(1);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -46,36 +49,43 @@ public:
vtkm::internal::NumberOfValuesToNumberOfBytes<T>(numValues), preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return static_cast<vtkm::Id>(buffers->GetNumberOfBytes() /
VTKM_ASSERT(buffers.size() == 1);
return static_cast<vtkm::Id>(buffers[0].GetNumberOfBytes() /
static_cast<vtkm::BufferSizeType>(sizeof(T)));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
return ReadPortalType(reinterpret_cast<const T*>(buffers[0].ReadPointerDevice(device, token)),
GetNumberOfValues(buffers));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
return WritePortalType(reinterpret_cast<T*>(buffers[0].WritePointerDevice(device, token)),
GetNumberOfValues(buffers));
}
@ -345,7 +355,8 @@ struct Serialization<vtkm::cont::ArrayHandleBasic<T>>
vtkm::cont::internal::Buffer buffer;
vtkmdiy::load(bb, buffer);
obj = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>(&buffer);
obj = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>(
vtkm::cont::internal::CreateBuffers(buffer));
}
};

@ -82,10 +82,13 @@ public:
using ReadPortalType = vtkm::cont::internal::ArrayPortalBitField<BitPortalConstType>;
using WritePortalType = vtkm::cont::internal::ArrayPortalBitField<BitPortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return std::vector<vtkm::cont::internal::Buffer>(1);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numberOfBits,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -102,20 +105,23 @@ public:
buffers[0].GetMetaData<vtkm::cont::internal::BitFieldMetaData>().NumberOfBits = numberOfBits;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
VTKM_ASSERT(buffers.size() == 1);
vtkm::Id numberOfBits =
buffers[0].GetMetaData<vtkm::cont::internal::BitFieldMetaData>().NumberOfBits;
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
return numberOfBits;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
bool fillValue,
vtkm::Id startBit,
vtkm::Id endBit,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
constexpr vtkm::BufferSizeType wordTypeSize =
static_cast<vtkm::BufferSizeType>(sizeof(WordType));
constexpr vtkm::BufferSizeType wordNumBits = wordTypeSize * CHAR_BIT;
@ -141,10 +147,12 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
vtkm::Id numberOfBits = GetNumberOfValues(buffers);
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
@ -152,10 +160,12 @@ public:
BitPortalConstType(buffers[0].ReadPointerDevice(device, token), numberOfBits));
}
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
vtkm::Id numberOfBits = GetNumberOfValues(buffers);
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);

@ -17,6 +17,8 @@
#include <vtkm/cont/ErrorBadAllocation.h>
#include <vtkm/cont/Token.h>
#include <array>
namespace vtkm
{
namespace internal
@ -199,26 +201,27 @@ struct ArrayHandleCartesianProductTraits
template <typename T, typename ST1, typename ST2, typename ST3>
class Storage<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>
{
struct Info
{
std::array<std::size_t, 4> BufferOffset;
};
using Storage1 = vtkm::cont::internal::Storage<T, ST1>;
using Storage2 = vtkm::cont::internal::Storage<T, ST2>;
using Storage3 = vtkm::cont::internal::Storage<T, ST3>;
template <typename Buffs>
VTKM_CONT constexpr static Buffs* Buffers1(Buffs* buffers)
{
return buffers;
}
using Array1 = vtkm::cont::ArrayHandle<T, ST1>;
using Array2 = vtkm::cont::ArrayHandle<T, ST2>;
using Array3 = vtkm::cont::ArrayHandle<T, ST3>;
template <typename Buffs>
VTKM_CONT constexpr static Buffs* Buffers2(Buffs* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
std::size_t subArray)
{
return buffers + Storage1::GetNumberOfBuffers();
}
template <typename Buffs>
VTKM_CONT constexpr static Buffs* Buffers3(Buffs* buffers)
{
return buffers + Storage1::GetNumberOfBuffers() + Storage2::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() +
info.BufferOffset[subArray - 1],
buffers.begin() + info.BufferOffset[subArray]);
}
public:
@ -235,20 +238,15 @@ public:
typename Storage2::WritePortalType,
typename Storage3::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Storage1::GetNumberOfBuffers() + Storage2::GetNumberOfBuffers() +
Storage3::GetNumberOfBuffers();
return (Storage1::GetNumberOfValues(GetBuffers(buffers, 1)) *
Storage2::GetNumberOfValues(GetBuffers(buffers, 2)) *
Storage3::GetNumberOfValues(GetBuffers(buffers, 3)));
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return (Storage1::GetNumberOfValues(Buffers1(buffers)) *
Storage2::GetNumberOfValues(Buffers2(buffers)) *
Storage3::GetNumberOfValues(Buffers3(buffers)));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const vtkm::Vec<T, 3>& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -259,46 +257,63 @@ public:
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);
auto subBuffers = GetBuffers(buffers, 1);
Storage1::Fill(subBuffers, fillValue[0], 0, Storage1::GetNumberOfValues(subBuffers), token);
subBuffers = GetBuffers(buffers, 2);
Storage2::Fill(subBuffers, fillValue[1], 0, Storage2::GetNumberOfValues(subBuffers), token);
subBuffers = GetBuffers(buffers, 3);
Storage3::Fill(subBuffers, fillValue[2], 0, Storage3::GetNumberOfValues(subBuffers), token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(Storage1::CreateReadPortal(Buffers1(buffers), device, token),
Storage2::CreateReadPortal(Buffers2(buffers), device, token),
Storage3::CreateReadPortal(Buffers3(buffers), device, token));
return ReadPortalType(Storage1::CreateReadPortal(GetBuffers(buffers, 1), device, token),
Storage2::CreateReadPortal(GetBuffers(buffers, 2), device, token),
Storage3::CreateReadPortal(GetBuffers(buffers, 3), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(Storage1::CreateWritePortal(Buffers1(buffers), device, token),
Storage2::CreateWritePortal(Buffers2(buffers), device, token),
Storage3::CreateWritePortal(Buffers3(buffers), device, token));
return WritePortalType(Storage1::CreateWritePortal(GetBuffers(buffers, 1), device, token),
Storage2::CreateWritePortal(GetBuffers(buffers, 2), device, token),
Storage3::CreateWritePortal(GetBuffers(buffers, 3), device, token));
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ST1> GetArrayHandle1(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static Array1 GetArrayHandle1(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ST1>(Buffers1(buffers));
return Array1(GetBuffers(buffers, 1));
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ST2> GetArrayHandle2(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static Array2 GetArrayHandle2(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ST2>(Buffers2(buffers));
return Array2(GetBuffers(buffers, 2));
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ST3> GetArrayHandle3(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static Array3 GetArrayHandle3(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ST3>(Buffers3(buffers));
return Array3(GetBuffers(buffers, 3));
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const Array1& array1 = Array1{},
const Array2& array2 = Array2{},
const Array3& array3 = Array3{})
{
const std::vector<vtkm::cont::internal::Buffer>& buffers1 = array1.GetBuffers();
const std::vector<vtkm::cont::internal::Buffer>& buffers2 = array2.GetBuffers();
const std::vector<vtkm::cont::internal::Buffer>& buffers3 = array3.GetBuffers();
Info info;
info.BufferOffset[0] = 1;
info.BufferOffset[1] = info.BufferOffset[0] + buffers1.size();
info.BufferOffset[2] = info.BufferOffset[1] + buffers2.size();
info.BufferOffset[3] = info.BufferOffset[2] + buffers3.size();
return vtkm::cont::internal::CreateBuffers(info, buffers1, buffers2, buffers3);
}
};
} // namespace internal
@ -335,7 +350,7 @@ public:
ArrayHandleCartesianProduct(const FirstHandleType& firstArray,
const SecondHandleType& secondArray,
const ThirdHandleType& thirdArray)
: Superclass(vtkm::cont::internal::CreateBuffers(firstArray, secondArray, thirdArray))
: Superclass(StorageType::CreateBuffers(firstArray, secondArray, thirdArray))
{
}

@ -20,6 +20,7 @@
#include <vtkmstd/integer_sequence.h>
#include <numeric>
#include <type_traits>
namespace vtkm
@ -169,31 +170,6 @@ struct VerifyArrayHandle
"must be a list of ArrayHandle types.");
};
template <std::size_t I>
struct BufferIndexImpl
{
template <typename... Ts>
static constexpr vtkm::IdComponent Value(vtkm::IdComponent n, Ts... remaining)
{
return n + BufferIndexImpl<I - 1>::Value(remaining...);
}
};
template <>
struct BufferIndexImpl<0>
{
template <typename... Ts>
static constexpr vtkm::IdComponent Value(Ts...)
{
return 0;
}
};
template <std::size_t I, typename... StorageTypes>
constexpr vtkm::IdComponent BufferIndex()
{
return BufferIndexImpl<I>::Value(StorageTypes::GetNumberOfBuffers()...);
}
} // end namespace compvec
} // namespace internal
@ -226,21 +202,31 @@ class Storage<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags)
{
using ValueType = vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags))>;
struct Info
{
std::array<std::size_t, sizeof...(StorageTags) + 1> BufferOffset;
};
template <typename S>
using StorageFor = vtkm::cont::internal::Storage<T, S>;
using StorageTuple = vtkm::Tuple<StorageFor<StorageTags>...>;
template <std::size_t I>
VTKM_CONT static constexpr vtkm::IdComponent BufferIndex()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
std::size_t subArray)
{
return compvec::BufferIndex<I, StorageFor<StorageTags>...>();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.BufferOffset[subArray],
buffers.begin() +
info.BufferOffset[subArray + 1]);
}
template <std::size_t I, typename Buff>
VTKM_CONT static Buff* Buffers(Buff* buffers)
template <std::size_t I>
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + BufferIndex<I>();
return GetBuffers(buffers, I);
}
using IndexList = vtkmstd::make_index_sequence<sizeof...(StorageTags)>;
@ -255,19 +241,21 @@ private:
template <std::size_t... Is>
static void ResizeBuffersImpl(vtkmstd::index_sequence<Is...>,
vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
std::vector<std::vector<vtkm::cont::internal::Buffer>> bufferPartitions = { Buffers<Is>(
buffers)... };
auto init_list = { (vtkm::tuple_element_t<Is, StorageTuple>::ResizeBuffers(
numValues, Buffers<Is>(buffers), preserve, token),
numValues, bufferPartitions[Is], preserve, token),
false)... };
(void)init_list;
}
template <std::size_t... Is>
static void FillImpl(vtkmstd::index_sequence<Is...>,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -284,45 +272,43 @@ private:
}
template <std::size_t... Is>
static ReadPortalType CreateReadPortalImpl(vtkmstd::index_sequence<Is...>,
const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
static ReadPortalType CreateReadPortalImpl(
vtkmstd::index_sequence<Is...>,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(vtkm::tuple_element_t<Is, StorageTuple>::CreateReadPortal(
Buffers<Is>(buffers), device, token)...);
}
template <std::size_t... Is>
static WritePortalType CreateWritePortalImpl(vtkmstd::index_sequence<Is...>,
vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
static WritePortalType CreateWritePortalImpl(
vtkmstd::index_sequence<Is...>,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(vtkm::tuple_element_t<Is, StorageTuple>::CreateWritePortal(
Buffers<Is>(buffers), device, token)...);
}
public:
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return BufferIndex<sizeof...(StorageTags)>();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return vtkm::TupleElement<0, StorageTuple>::GetNumberOfValues(buffers);
return vtkm::TupleElement<0, StorageTuple>::GetNumberOfValues(Buffers<0>(buffers));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -331,65 +317,51 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreateReadPortalImpl(IndexList{}, buffers, device, token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreateWritePortalImpl(IndexList{}, buffers, device, token);
}
private:
template <typename ArrayType>
VTKM_CONT static bool CopyBuffers(const ArrayType& array,
vtkm::cont::internal::Buffer* destBuffers)
{
vtkm::IdComponent numBuffers = array.GetNumberOfBuffers();
const vtkm::cont::internal::Buffer* srcBuffers = array.GetBuffers();
for (vtkm::IdComponent buffIndex = 0; buffIndex < numBuffers; ++buffIndex)
{
destBuffers[buffIndex] = srcBuffers[buffIndex];
}
return false; // Return value does not matter. Hopefully just thrown away by compiler.
}
template <std::size_t... Is, typename... ArrayTs>
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffersImpl(
vtkmstd::index_sequence<Is...>,
const ArrayTs... arrays)
{
std::vector<vtkm::cont::internal::Buffer> buffers(
static_cast<std::size_t>(GetNumberOfBuffers()));
auto init_list = { CopyBuffers(arrays, Buffers<Is>(&buffers.front()))... };
(void)init_list;
return buffers;
}
public:
template <typename... ArrayTs>
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const ArrayTs... arrays)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::ArrayHandle<T, StorageTags>&... arrays)
{
return CreateBuffersImpl(IndexList{}, arrays...);
auto numBuffers = { std::size_t{ 1 }, arrays.GetBuffers().size()... };
Info info;
std::partial_sum(numBuffers.begin(), numBuffers.end(), info.BufferOffset.begin());
return vtkm::cont::internal::CreateBuffers(info, arrays...);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return CreateBuffers(vtkm::cont::ArrayHandle<T, StorageTags>{}...);
}
private:
using ArrayTupleType = vtkm::Tuple<vtkm::cont::ArrayHandle<T, StorageTags>...>;
template <std::size_t... Is>
VTKM_CONT static ArrayTupleType GetArrayTupleImpl(vtkmstd::index_sequence<Is...>,
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayTupleType GetArrayTupleImpl(
vtkmstd::index_sequence<Is...>,
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayTupleType(vtkm::cont::ArrayHandle<T, StorageTags>(Buffers<Is>(buffers))...);
}
public:
VTKM_CONT static ArrayTupleType GetArrayTuple(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayTupleType GetArrayTuple(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetArrayTupleImpl(IndexList{}, buffers);
}
@ -400,13 +372,13 @@ template <typename T, typename StorageTag>
struct Storage<T, vtkm::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, StorageTag>
{
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::ArrayHandle<T, StorageTag>& array)
const vtkm::cont::ArrayHandle<T, StorageTag>& array = vtkm::cont::ArrayHandle<T, StorageTag>{})
{
return vtkm::cont::internal::CreateBuffers(array);
}
VTKM_CONT static vtkm::Tuple<vtkm::cont::ArrayHandle<T, StorageTag>> GetArrayTuple(
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, StorageTag>(buffers);
}

@ -169,16 +169,26 @@ class Storage<T, StorageTagConcatenate<ST1, ST2>>
using ArrayHandleType1 = typename detail::ConcatinateTypeArg<T, ST1>::ArrayHandle;
using ArrayHandleType2 = typename detail::ConcatinateTypeArg<T, ST2>::ArrayHandle;
template <typename Buff>
VTKM_CONT static Buff* Buffers1(Buff* buffers)
struct Info
{
return buffers;
std::size_t NumBuffers1;
std::size_t NumBuffers2;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers1(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + 1 + info.NumBuffers1);
}
template <typename Buff>
VTKM_CONT static Buff* Buffers2(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers2(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + SourceStorage1::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1 + info.NumBuffers1,
buffers.end());
}
public:
@ -191,18 +201,14 @@ public:
vtkm::internal::ArrayPortalConcatenate<typename SourceStorage1::WritePortalType,
typename SourceStorage2::WritePortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return (SourceStorage1::GetNumberOfBuffers() + SourceStorage2::GetNumberOfBuffers());
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return (SourceStorage1::GetNumberOfValues(Buffers1(buffers)) +
SourceStorage2::GetNumberOfValues(Buffers2(buffers)));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -225,35 +231,42 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage1::CreateReadPortal(Buffers1(buffers), device, token),
SourceStorage2::CreateReadPortal(Buffers2(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(SourceStorage1::CreateWritePortal(Buffers1(buffers), device, token),
SourceStorage2::CreateWritePortal(Buffers2(buffers), device, token));
}
VTKM_CONT static auto CreateBuffers(const ArrayHandleType1& array1,
const ArrayHandleType2& array2)
VTKM_CONT static auto CreateBuffers(const ArrayHandleType1& array1 = ArrayHandleType1{},
const ArrayHandleType2& array2 = ArrayHandleType2{})
-> decltype(vtkm::cont::internal::CreateBuffers())
{
return vtkm::cont::internal::CreateBuffers(array1, array2);
Info info;
info.NumBuffers1 = array1.GetBuffers().size();
info.NumBuffers2 = array2.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, array1, array2);
}
VTKM_CONT static const ArrayHandleType1 GetArray1(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static const ArrayHandleType1 GetArray1(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayHandleType1(Buffers1(buffers));
}
VTKM_CONT static const ArrayHandleType2 GetArray2(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static const ArrayHandleType2 GetArray2(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayHandleType2(Buffers2(buffers));
}

@ -24,6 +24,7 @@
#include <vtkmstd/integer_sequence.h>
#include <numeric>
#include <type_traits>
#include <utility>
@ -306,35 +307,22 @@ using GetWritePortalList =
std::declval<vtkm::cont::DeviceAdapterId>(),
std::declval<vtkm::cont::Token&>())))...>;
template <vtkm::IdComponent I, typename ArrayTupleType>
struct BufferIndexImpl
{
static constexpr vtkm::IdComponent Value()
{
return BufferIndexImpl<I - 1, ArrayTupleType>::Value() +
vtkm::TupleElement<I - 1, ArrayTupleType>::GetNumberOfBuffers();
}
};
template <typename ArrayTupleType>
struct BufferIndexImpl<0, ArrayTupleType>
{
static constexpr vtkm::IdComponent Value()
{
// One buffer reserved for metadata.
return 1;
}
};
template <typename DecoratorImplT>
template <typename DecoratorImplT, std::size_t NumArrays>
struct DecoratorMetaData
{
DecoratorImplT Implementation;
vtkm::Id NumberOfValues = 0;
std::array<std::size_t, NumArrays + 1> BufferOffsets;
DecoratorMetaData(const DecoratorImplT& implementation, vtkm::Id numValues)
template <typename... ArrayTs>
DecoratorMetaData(const DecoratorImplT& implementation,
vtkm::Id numValues,
const ArrayTs... arrays)
: Implementation(implementation)
, NumberOfValues(numValues)
{
auto numBuffers = { std::size_t{ 1 }, arrays.GetBuffers().size()... };
std::partial_sum(numBuffers.begin(), numBuffers.end(), this->BufferOffsets.begin());
}
DecoratorMetaData() = default;
@ -363,26 +351,22 @@ struct DecoratorStorageTraits
// size_t integral constants that index ArrayTs:
using IndexList = vtkmstd::make_index_sequence<sizeof...(ArrayTs)>;
// Returns the index into the buffers array for the array at the given index.
template <vtkm::IdComponent I>
static constexpr vtkm::IdComponent BufferIndex()
using MetaData = DecoratorMetaData<DecoratorImplT, sizeof...(ArrayTs)>;
static MetaData& GetMetaData(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return BufferIndexImpl<I, ArrayTupleType>::Value();
return buffers[0].GetMetaData<MetaData>();
}
// Converts a buffers array to the ArrayHandle at the given index.
template <vtkm::IdComponent I>
static vtkm::TupleElement<I, ArrayTupleType> BuffersToArray(
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::TupleElement<I, ArrayTupleType>(buffers + BufferIndex<I>());
}
using MetaData = DecoratorMetaData<DecoratorImplT>;
static MetaData& GetMetaData(const vtkm::cont::internal::Buffer* buffers)
{
return buffers[0].GetMetaData<MetaData>();
const MetaData& metaData = GetMetaData(buffers);
std::vector<vtkm::cont::internal::Buffer> subBuffers(
buffers.begin() + metaData.BufferOffsets[I], buffers.begin() + metaData.BufferOffsets[I + 1]);
return vtkm::TupleElement<I, ArrayTupleType>(std::move(subBuffers));
}
// true_type/false_type depending on whether the decorator supports Allocate:
@ -440,7 +424,7 @@ struct DecoratorStorageTraits
// Static dispatch for calling AllocateSourceArrays on supported implementations:
VTKM_CONT [[noreturn]] static void CallAllocate(std::false_type,
vtkm::Id,
vtkm::cont::internal::Buffer*,
const std::vector<vtkm::cont::internal::Buffer>&,
vtkm::CopyFlag,
vtkm::cont::Token&,
ArrayTs...)
@ -450,7 +434,7 @@ struct DecoratorStorageTraits
VTKM_CONT static void CallAllocate(std::true_type,
vtkm::Id newSize,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token,
ArrayTs... arrays)
@ -463,11 +447,12 @@ struct DecoratorStorageTraits
// Portal construction methods. These actually create portals.
template <std::size_t... Indices>
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<WritePortalType>(
numValues,
@ -476,11 +461,12 @@ struct DecoratorStorageTraits
}
template <std::size_t... Indices>
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<ReadPortalType>(
numValues,
@ -489,11 +475,12 @@ struct DecoratorStorageTraits
}
template <std::size_t... Indices>
VTKM_CONT static void AllocateSourceArrays(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token,
vtkmstd::index_sequence<Indices...>)
VTKM_CONT static void AllocateSourceArrays(
vtkm::Id numValues,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token,
vtkmstd::index_sequence<Indices...>)
{
CallAllocate(
IsAllocatable{}, numValues, buffers, preserve, token, BuffersToArray<Indices>(buffers)...);
@ -519,18 +506,14 @@ public:
using ReadPortalType = typename Traits::ReadPortalType;
using WritePortalType = typename Traits::WritePortalType;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return Traits::template BufferIndex<static_cast<vtkm::IdComponent>(sizeof...(ArrayTs))>();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Traits::GetMetaData(buffers).NumberOfValues;
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -545,17 +528,19 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Traits::CreateReadPortal(
buffers, GetNumberOfValues(buffers), IndexList{}, device, token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Traits::CreateWritePortal(
buffers, GetNumberOfValues(buffers), IndexList{}, device, token);
@ -564,7 +549,13 @@ public:
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer>
CreateBuffers(const DecoratorImplT& implementation, vtkm::Id numValues, const ArrayTs&... arrays)
{
return vtkm::cont::internal::CreateBuffers(MetaData(implementation, numValues), arrays...);
return vtkm::cont::internal::CreateBuffers(MetaData(implementation, numValues, arrays...),
arrays...);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return CreateBuffers(DecoratorImplT{}, 0, ArrayTs{}...);
}
};

@ -103,10 +103,15 @@ public:
// you actually try to use this read portal.
using ReadPortalType = vtkm::exec::internal::ArrayPortalDiscard<ValueType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
DiscardMetaData metaData;
metaData.NumberOfValues = 0;
return vtkm::cont::internal::CreateBuffers(metaData);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag,
vtkm::cont::Token&)
{
@ -114,12 +119,13 @@ public:
buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues = numValues;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const ValueType&,
vtkm::Id,
vtkm::Id,
@ -128,16 +134,17 @@ public:
// Fill is a NO-OP.
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer*,
VTKM_CONT static ReadPortalType CreateReadPortal(const std::vector<vtkm::cont::internal::Buffer>&,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadValue("Cannot read from ArrayHandleDiscard.");
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
return WritePortalType(GetNumberOfValues(buffers));
}

@ -98,15 +98,16 @@ class Storage<typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::Com
using SourceStorage = vtkm::cont::internal::Storage<SourceValueType, SourceStorageTag>;
public:
VTKM_CONT static vtkm::IdComponent ComponentIndex(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::IdComponent ComponentIndex(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<vtkm::IdComponent>();
}
template <typename Buff>
VTKM_CONT static Buff* SourceBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + 1;
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
using ReadPortalType =
@ -114,17 +115,13 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalExtractComponent<typename SourceStorage::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return SourceStorage::GetNumberOfBuffers() + 1;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const ValueType&,
vtkm::Id,
vtkm::Id,
@ -134,31 +131,33 @@ public:
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
SourceStorage::ResizeBuffers(numValues, SourceBuffers(buffers), preserve, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
ComponentIndex(buffers));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
ComponentIndex(buffers));
}
VTKM_CONT static auto CreateBuffers(vtkm::IdComponent componentIndex,
const ArrayHandleType& array)
VTKM_CONT static auto CreateBuffers(vtkm::IdComponent componentIndex = 0,
const ArrayHandleType& array = ArrayHandleType{})
-> decltype(vtkm::cont::internal::CreateBuffers())
{
return vtkm::cont::internal::CreateBuffers(componentIndex, array);

@ -128,26 +128,27 @@ public:
vtkm::internal::ArrayPortalGroupVec<typename ComponentsStorage::WritePortalType,
NUM_COMPONENTS>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return ComponentsStorage::GetNumberOfBuffers();
return ComponentsStorage::CreateBuffers();
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
ComponentsStorage::ResizeBuffers(NUM_COMPONENTS * numValues, buffers, preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
vtkm::Id componentsSize = ComponentsStorage::GetNumberOfValues(buffers);
return componentsSize / NUM_COMPONENTS;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const ValueType&,
vtkm::Id,
vtkm::Id,
@ -156,9 +157,10 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
{
@ -168,9 +170,10 @@ public:
return ReadPortalType(ComponentsStorage::CreateReadPortal(buffers, device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
{

@ -122,20 +122,32 @@ class Storage<vtkm::VecFromPortal<ComponentsPortal>,
using ComponentsStorage = vtkm::cont::internal::Storage<ComponentType, ComponentsStorageTag>;
using OffsetsStorage = vtkm::cont::internal::Storage<vtkm::Id, OffsetsStorageTag>;
using ComponentsArray = vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag>;
using OffsetsArray = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>;
VTKM_STATIC_ASSERT_MSG(
(std::is_same<ComponentsPortal, typename ComponentsStorage::WritePortalType>::value),
"Used invalid ComponentsPortal type with expected ComponentsStorageTag.");
template <typename Buff>
VTKM_CONT static Buff* ComponentsBuffers(Buff* buffers)
struct Info
{
return buffers;
std::size_t OffsetsBuffersOffset;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ComponentsBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + info.OffsetsBuffersOffset);
}
template <typename Buff>
VTKM_CONT static Buff* OffsetsBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> OffsetsBuffers(
const std::vector<vtkm::cont::internal::Buffer> buffers)
{
return buffers + ComponentsStorage::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.OffsetsBuffersOffset,
buffers.end());
}
public:
@ -148,17 +160,13 @@ public:
vtkm::internal::ArrayPortalGroupVecVariable<typename ComponentsStorage::WritePortalType,
typename OffsetsStorage::ReadPortalType>;
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers()
{
return ComponentsStorage::GetNumberOfBuffers() + OffsetsStorage::GetNumberOfBuffers();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return OffsetsStorage::GetNumberOfValues(OffsetsBuffers(buffers)) - 1;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const vtkm::VecFromPortal<ComponentsPortal>&,
vtkm::Id,
vtkm::Id,
@ -167,18 +175,20 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(
ComponentsStorage::CreateReadPortal(ComponentsBuffers(buffers), device, token),
OffsetsStorage::CreateReadPortal(OffsetsBuffers(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(
ComponentsStorage::CreateWritePortal(ComponentsBuffers(buffers), device, token),
@ -186,31 +196,24 @@ public:
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag>& componentsArray,
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsetsArray)
const ComponentsArray& componentsArray = ComponentsArray{},
const OffsetsArray& offsetsArray = OffsetsArray{})
{
std::vector<vtkm::cont::internal::Buffer> destBuffer(
static_cast<std::size_t>(GetNumberOfBuffers()));
auto destIter = destBuffer.begin();
destIter =
std::copy_n(componentsArray.GetBuffers(), ComponentsStorage::GetNumberOfBuffers(), destIter);
destIter =
std::copy_n(offsetsArray.GetBuffers(), OffsetsStorage::GetNumberOfBuffers(), destIter);
return destBuffer;
Info info;
info.OffsetsBuffersOffset = 1 + componentsArray.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, componentsArray, offsetsArray);
}
VTKM_CONT static vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag> GetComponentsArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ComponentsArray GetComponentsArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag>(ComponentsBuffers(buffers));
return ComponentsArray(ComponentsBuffers(buffers));
}
VTKM_CONT static vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag> GetOffsetsArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static OffsetsArray GetOffsetsArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>(OffsetsBuffers(buffers));
return OffsetsArray(OffsetsBuffers(buffers));
}
};

@ -91,34 +91,6 @@ struct VTKM_ALWAYS_EXPORT StorageTagImplicit
namespace internal
{
template <class ArrayPortalType>
struct VTKM_ALWAYS_EXPORT
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
{
VTKM_IS_TRIVIALLY_COPYABLE(ArrayPortalType);
VTKM_STORAGE_NO_RESIZE;
VTKM_STORAGE_NO_WRITE_PORTAL;
using ReadPortalType = ArrayPortalType;
// Implicit array has one buffer that should be empty (NumberOfBytes = 0), but holds
// the metadata for the array.
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return buffers[0].GetMetaData<ArrayPortalType>().GetNumberOfValues();
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
return buffers[0].GetMetaData<ArrayPortalType>();
}
};
/// Given an array portal, returns the buffers for the `ArrayHandle` with a storage that
/// is (or is compatible with) a storage tag of `StorageTagImplicit<PortalType>`.
template <typename PortalType>
@ -141,6 +113,37 @@ VTKM_CONT inline std::vector<vtkm::cont::internal::Buffer> FunctorToArrayHandleI
vtkm::internal::ArrayPortalImplicit<FunctorType>(functor, numValues));
}
template <class ArrayPortalType>
struct VTKM_ALWAYS_EXPORT
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
{
VTKM_IS_TRIVIALLY_COPYABLE(ArrayPortalType);
VTKM_STORAGE_NO_RESIZE;
VTKM_STORAGE_NO_WRITE_PORTAL;
using ReadPortalType = ArrayPortalType;
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return vtkm::cont::internal::PortalToArrayHandleImplicitBuffers(ArrayPortalType{});
}
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<ArrayPortalType>().GetNumberOfValues();
}
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
return buffers[0].GetMetaData<ArrayPortalType>();
}
};
} // namespace internal
namespace detail

@ -151,7 +151,8 @@ namespace detail
struct MultiplexerGetNumberOfValuesFunctor
{
template <typename StorageType>
VTKM_CONT vtkm::Id operator()(StorageType, const vtkm::cont::internal::Buffer* buffers) const
VTKM_CONT vtkm::Id operator()(StorageType,
const std::vector<vtkm::cont::internal::Buffer>& buffers) const
{
return StorageType::GetNumberOfValues(buffers);
}
@ -162,7 +163,7 @@ struct MultiplexerResizeBuffersFunctor
template <typename StorageType>
VTKM_CONT void operator()(StorageType,
vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token) const
{
@ -174,7 +175,7 @@ struct MultiplexerFillFunctor
{
template <typename ValueType, typename StorageType>
VTKM_CONT void operator()(StorageType,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -189,7 +190,7 @@ struct MultiplexerCreateReadPortalFunctor
{
template <typename StorageType>
VTKM_CONT ReadPortalType operator()(StorageType,
const vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
@ -202,7 +203,7 @@ struct MultiplexerCreateWritePortalFunctor
{
template <typename StorageType>
VTKM_CONT WritePortalType operator()(StorageType,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
@ -217,7 +218,7 @@ struct MultiplexerArrayHandleVariantFunctor
template <typename StorageTag>
VTKM_CONT VariantType operator()(vtkm::cont::internal::Storage<T, StorageTag>,
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return VariantType(vtkm::cont::ArrayHandle<T, StorageTag>(buffers));
}
@ -233,15 +234,15 @@ class Storage<ValueType, StorageTagMultiplexer<StorageTags...>>
using StorageVariant = vtkm::cont::internal::Variant<StorageFor<StorageTags>...>;
VTKM_CONT static StorageVariant Variant(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static StorageVariant Variant(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<StorageVariant>();
}
template <typename Buff>
VTKM_CONT static Buff* ArrayBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ArrayBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + 1;
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
@ -250,19 +251,15 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::WritePortalType...>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return std::max({ StorageFor<StorageTags>::GetNumberOfBuffers()... }) + 1;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{},
ArrayBuffers(buffers));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -270,7 +267,7 @@ public:
detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -284,9 +281,10 @@ public:
token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Variant(buffers).CastAndCall(
detail::MultiplexerCreateReadPortalFunctor<ReadPortalType>{},
@ -295,9 +293,10 @@ public:
token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Variant(buffers).CastAndCall(
detail::MultiplexerCreateWritePortalFunctor<WritePortalType>{},
@ -306,7 +305,7 @@ public:
token);
}
VTKM_CONT static bool IsValid(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static bool IsValid(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Variant(buffers).IsValid();
}
@ -315,21 +314,17 @@ public:
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const ArrayType& array)
{
VTKM_IS_ARRAY_HANDLE(ArrayType);
std::vector<vtkm::cont::internal::Buffer> buffers =
vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
return vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
}
// Some arrays will require different numbers of buffers. Make sure we size the buffers
// array to accomodate any such one to avoid any troubles.
std::size_t numBuffers = static_cast<std::size_t>(GetNumberOfBuffers());
VTKM_ASSERT(numBuffers >= buffers.size());
buffers.resize(numBuffers);
return buffers;
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return vtkm::cont::internal::CreateBuffers(StorageVariant{});
}
VTKM_CONT static
typename detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>::VariantType
GetArrayHandleVariant(const vtkm::cont::internal::Buffer* buffers)
GetArrayHandleVariant(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Variant(buffers).CastAndCall(
detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>{},

@ -71,12 +71,13 @@ public:
using ReadPortalType =
vtkm::internal::ArrayPortalOffsetsToNumComponents<typename OffsetsStorage::ReadPortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return OffsetsStorage::GetNumberOfBuffers();
return OffsetsStorage::CreateBuffers();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
vtkm::Id numOffsets = OffsetsStorage::GetNumberOfValues(buffers);
if (numOffsets < 1)
@ -87,9 +88,10 @@ public:
return numOffsets - 1;
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(OffsetsStorage::GetNumberOfValues(buffers) > 0);
return ReadPortalType(OffsetsStorage::CreateReadPortal(buffers, device, token));

@ -109,15 +109,27 @@ class Storage<T, vtkm::cont::StorageTagPermutation<IndexStorageTag, ValueStorage
using IndexStorage = vtkm::cont::internal::Storage<vtkm::Id, IndexStorageTag>;
using ValueStorage = vtkm::cont::internal::Storage<T, ValueStorageTag>;
template <typename Buff>
VTKM_CONT constexpr static Buff* IndexBuffers(Buff* buffers)
using IndexArray = vtkm::cont::ArrayHandle<vtkm::Id, IndexStorageTag>;
using ValueArray = vtkm::cont::ArrayHandle<T, ValueStorageTag>;
struct Info
{
return buffers;
std::size_t ValueBufferOffset;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> IndexBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + info.ValueBufferOffset);
}
template <typename Buff>
VTKM_CONT constexpr static Buff* ValueBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ValueBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + IndexStorage::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.ValueBufferOffset,
buffers.end());
}
public:
@ -130,17 +142,13 @@ public:
vtkm::internal::ArrayPortalPermutation<typename IndexStorage::ReadPortalType,
typename ValueStorage::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return (IndexStorage::GetNumberOfBuffers() + ValueStorage::GetNumberOfBuffers());
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return IndexStorage::GetNumberOfValues(IndexBuffers(buffers));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const T&,
vtkm::Id,
vtkm::Id,
@ -149,33 +157,44 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
ValueStorage::CreateReadPortal(ValueBuffers(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
// Note: the index portal is always a read-only portal.
return WritePortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
ValueStorage::CreateWritePortal(ValueBuffers(buffers), device, token));
}
VTKM_CONT static vtkm::cont::ArrayHandle<vtkm::Id, IndexStorageTag> GetIndexArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const IndexArray& indexArray = IndexArray{},
const ValueArray& valueArray = ValueArray{})
{
return vtkm::cont::ArrayHandle<vtkm::Id, IndexStorageTag>(IndexBuffers(buffers));
Info info;
info.ValueBufferOffset = 1 + indexArray.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, indexArray, valueArray);
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ValueStorageTag> GetValueArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static IndexArray GetIndexArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ValueStorageTag>(ValueBuffers(buffers));
return IndexArray(IndexBuffers(buffers));
}
VTKM_CONT static ValueArray GetValueArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ValueArray(ValueBuffers(buffers));
}
};
@ -236,7 +255,7 @@ public:
VTKM_CONT
ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
const ValueArrayHandleType& valueArray)
: Superclass(vtkm::cont::internal::CreateBuffers(indexArray, valueArray))
: Superclass(StorageType::CreateBuffers(indexArray, valueArray))
{
}

@ -355,18 +355,10 @@ struct StorageTagRecombineVec
namespace detail
{
// Note: Normally a decorating ArrayHandle holds the buffers of the arrays it is decorating
// in its list of arrays. However, the numbers of buffers is expected to be compile-time static
// and ArrayHandleRecombineVec needs to set the number of buffers at runtime. We cheat around
// this by stuffing the decorated buffers in the metadata. To make sure deep copies work
// right, a copy of the metadata results in a deep copy of the contained buffers. The
// vtkm::cont::internal::Buffer holding the metadata is not supposed to copy the metadata
// except for a deep copy (and when it is first set). If this behavior changes, there could
// be a performance degredation.
struct RecombineVecMetaData
{
mutable std::vector<vtkm::cont::internal::Buffer> PortalBuffers;
std::vector<std::vector<vtkm::cont::internal::Buffer>> ArrayBuffers;
std::vector<std::size_t> ArrayBufferOffsets;
RecombineVecMetaData() = default;
@ -374,17 +366,7 @@ struct RecombineVecMetaData
RecombineVecMetaData& operator=(const RecombineVecMetaData& src)
{
this->ArrayBuffers.resize(src.ArrayBuffers.size());
for (std::size_t arrayIndex = 0; arrayIndex < src.ArrayBuffers.size(); ++arrayIndex)
{
this->ArrayBuffers[arrayIndex].resize(src.ArrayBuffers[arrayIndex].size());
for (std::size_t bufferIndex = 0; bufferIndex < src.ArrayBuffers[arrayIndex].size();
++bufferIndex)
{
this->ArrayBuffers[arrayIndex][bufferIndex].DeepCopyFrom(
src.ArrayBuffers[arrayIndex][bufferIndex]);
}
}
this->ArrayBufferOffsets = src.ArrayBufferOffsets;
this->PortalBuffers.clear();
// Intentionally not copying portals. Portals will be recreated from proper array when requsted.
@ -414,13 +396,15 @@ class Storage<vtkm::internal::RecombineVec<ReadWritePortal>,
VTKM_STATIC_ASSERT(
(std::is_same<ReadWritePortal, detail::RecombinedPortalType<ComponentType>>::value));
template <typename Buff>
VTKM_CONT static Buff* BuffersForComponent(Buff* buffers, vtkm::IdComponent componentIndex)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> BuffersForComponent(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::IdComponent componentIndex)
{
return buffers[0]
.template GetMetaData<detail::RecombineVecMetaData>()
.ArrayBuffers[componentIndex]
.data();
auto& metaData = buffers[0].GetMetaData<detail::RecombineVecMetaData>();
std::size_t index = static_cast<std::size_t>(componentIndex);
return std::vector<vtkm::cont::internal::Buffer>(
buffers.begin() + metaData.ArrayBufferOffsets[index],
buffers.begin() + metaData.ArrayBufferOffsets[index + 1]);
}
public:
@ -429,20 +413,20 @@ public:
using ReadPortalType = vtkm::internal::ArrayPortalRecombineVec<ReadWritePortal>;
using WritePortalType = vtkm::internal::ArrayPortalRecombineVec<ReadWritePortal>;
VTKM_CONT static vtkm::IdComponent NumberOfComponents(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::IdComponent NumberOfComponents(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return static_cast<vtkm::IdComponent>(
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBuffers.size());
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBufferOffsets.size() - 1);
}
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(BuffersForComponent(buffers, 0));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const vtkm::internal::RecombineVec<ReadWritePortal>&,
vtkm::Id,
vtkm::Id,
@ -451,9 +435,10 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
@ -488,9 +473,10 @@ public:
numComponents);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
@ -525,19 +511,28 @@ public:
numComponents);
}
VTKM_CONT static ArrayType ArrayForComponent(const vtkm::cont::internal::Buffer* buffers,
vtkm::IdComponent componentIndex)
VTKM_CONT static ArrayType ArrayForComponent(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::IdComponent componentIndex)
{
return ArrayType(BuffersForComponent(buffers, componentIndex));
}
VTKM_CONT static void AppendComponent(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
detail::RecombineVecMetaData metaData;
metaData.ArrayBufferOffsets.push_back(1);
return vtkm::cont::internal::CreateBuffers(metaData);
}
VTKM_CONT static void AppendComponent(std::vector<vtkm::cont::internal::Buffer>& buffers,
const ArrayType& array)
{
std::vector<vtkm::cont::internal::Buffer> arrayBuffers(
array.GetBuffers(), array.GetBuffers() + SourceStorage::GetNumberOfBuffers());
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBuffers.push_back(
std::move(arrayBuffers));
// Add buffers of new array to our list of buffers.
buffers.insert(buffers.end(), array.GetBuffers().begin(), array.GetBuffers().end());
// Update metadata for new offset to end.
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBufferOffsets.push_back(
buffers.size());
}
};
@ -588,7 +583,9 @@ public:
void AppendComponentArray(
const vtkm::cont::ArrayHandle<ComponentType, vtkm::cont::StorageTagStride>& array)
{
StorageType::AppendComponent(this->GetBuffers(), array);
std::vector<vtkm::cont::internal::Buffer> buffers = this->GetBuffers();
StorageType::AppendComponent(buffers, array);
this->SetBuffers(std::move(buffers));
}
};

@ -128,25 +128,26 @@ public:
using ReadPortalType = ArrayPortalReverse<typename ArrayHandleType::ReadPortalType>;
using WritePortalType = ArrayPortalReverse<typename ArrayHandleType::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return SourceStorage::GetNumberOfBuffers();
return SourceStorage::CreateBuffers();
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
SourceStorage::ResizeBuffers(numValues, buffers, preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(buffers);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -156,16 +157,18 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage::CreateReadPortal(buffers, device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(SourceStorage::CreateWritePortal(buffers, device, token));
}

@ -140,10 +140,13 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalSOA<ValueType, vtkm::internal::ArrayPortalBasicWrite<ComponentType>>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return NUM_COMPONENTS; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return std::vector<vtkm::cont::internal::Buffer>(static_cast<std::size_t>(NUM_COMPONENTS));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -155,14 +158,15 @@ public:
}
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
// Assume all buffers are the same size.
return static_cast<vtkm::Id>(buffers[0].GetNumberOfBytes()) /
static_cast<vtkm::Id>(sizeof(ComponentType));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -179,9 +183,10 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::Id numValues = GetNumberOfValues(buffers);
ReadPortalType portal(numValues);
@ -197,9 +202,10 @@ public:
return portal;
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::Id numValues = GetNumberOfValues(buffers);
WritePortalType portal(numValues);
@ -401,7 +407,7 @@ public:
VTKM_CONT vtkm::cont::ArrayHandleBasic<ComponentType> GetArray(vtkm::IdComponent index) const
{
return ComponentArrayType(&this->GetBuffers()[index]);
return ComponentArrayType({ this->GetBuffers()[index] });
}
VTKM_CONT void SetArray(vtkm::IdComponent index, const ComponentArrayType& array)

@ -163,19 +163,18 @@ public:
using ReadPortalType = vtkm::internal::ArrayPortalStrideRead<T>;
using WritePortalType = vtkm::internal::ArrayPortalStrideWrite<T>;
VTKM_CONT static StrideInfo& GetInfo(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static StrideInfo& GetInfo(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<StrideInfo>();
}
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers() { return 2; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetInfo(buffers).NumberOfValues;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const T&,
vtkm::Id,
vtkm::Id,
@ -184,32 +183,35 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(reinterpret_cast<const T*>(buffers[1].ReadPointerDevice(device, token)),
GetInfo(buffers));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(reinterpret_cast<T*>(buffers[1].WritePointerDevice(device, token)),
GetInfo(buffers));
}
static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::internal::Buffer& sourceBuffer,
vtkm::internal::ArrayStrideInfo&& info)
const vtkm::cont::internal::Buffer& sourceBuffer = vtkm::cont::internal::Buffer{},
vtkm::internal::ArrayStrideInfo&& info = vtkm::internal::ArrayStrideInfo{})
{
return vtkm::cont::internal::CreateBuffers(info, sourceBuffer);
}
static vtkm::cont::ArrayHandleBasic<T> GetBasicArray(const vtkm::cont::internal::Buffer* buffers)
static vtkm::cont::ArrayHandleBasic<T> GetBasicArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>(buffers + 1);
return vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>({ buffers[1] });
}
};

@ -249,7 +249,11 @@ class Storage<typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueT
using SourceStorage =
Storage<typename ArrayHandleType::ValueType, typename ArrayHandleType::StorageTag>;
static constexpr vtkm::IdComponent NUM_METADATA_BUFFERS = 1;
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
VTKM_STORAGE_NO_RESIZE;
@ -260,54 +264,51 @@ public:
typename ArrayHandleType::ReadPortalType,
typename FunctorManager::FunctorType>;
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfBuffers() + NUM_METADATA_BUFFERS;
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return SourceStorage::GetNumberOfValues(buffers + NUM_METADATA_BUFFERS);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if (device == vtkm::cont::DeviceAdapterTagUndefined{})
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl());
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl());
}
else
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token));
}
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const ArrayHandleType& handle,
const ArrayHandleType& handle = ArrayHandleType{},
const FunctorType& functor = FunctorType())
{
return vtkm::cont::internal::CreateBuffers(FunctorManager(functor), handle);
}
VTKM_CONT static ArrayHandleType GetArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayHandleType GetArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
typename ArrayHandleType::StorageTag>(buffers +
NUM_METADATA_BUFFERS);
typename ArrayHandleType::StorageTag>(SourceBuffers(buffers));
}
VTKM_CONT static FunctorType GetFunctor(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static FunctorType GetFunctor(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<FunctorManager>().Functor;
}
VTKM_CONT static NullFunctorType GetInverseFunctor(const vtkm::cont::internal::Buffer*)
VTKM_CONT static NullFunctorType GetInverseFunctor(
const std::vector<vtkm::cont::internal::Buffer>&)
{
return NullFunctorType{};
}
@ -325,7 +326,11 @@ class Storage<
using SourceStorage =
Storage<typename ArrayHandleType::ValueType, typename ArrayHandleType::StorageTag>;
static constexpr vtkm::IdComponent NUM_METADATA_BUFFERS = 2;
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 2, buffers.end());
}
public:
using ReadPortalType =
@ -339,56 +344,54 @@ public:
typename FunctorManager::FunctorType,
typename InverseFunctorManager::FunctorType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfBuffers() + NUM_METADATA_BUFFERS;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return SourceStorage::GetNumberOfValues(buffers + NUM_METADATA_BUFFERS);
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
SourceStorage::ResizeBuffers(numValues, buffers + NUM_METADATA_BUFFERS, preserve, token);
std::vector<vtkm::cont::internal::Buffer> sourceBuffers = SourceBuffers(buffers);
SourceStorage::ResizeBuffers(numValues, sourceBuffers, preserve, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if (device == vtkm::cont::DeviceAdapterTagUndefined{})
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl(),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForControl());
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl(),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForControl());
}
else
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForExecution(device, token));
}
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(
SourceStorage::CreateWritePortal(buffers + NUM_METADATA_BUFFERS, device, token),
SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForExecution(device, token));
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const ArrayHandleType& handle,
const ArrayHandleType& handle = ArrayHandleType{},
const FunctorType& functor = FunctorType(),
const InverseFunctorType& inverseFunctor = InverseFunctorType())
{
@ -396,19 +399,20 @@ public:
FunctorManager(functor), InverseFunctorManager(inverseFunctor), handle);
}
VTKM_CONT static ArrayHandleType GetArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayHandleType GetArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
typename ArrayHandleType::StorageTag>(buffers +
NUM_METADATA_BUFFERS);
typename ArrayHandleType::StorageTag>(SourceBuffers(buffers));
}
VTKM_CONT static FunctorType GetFunctor(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static FunctorType GetFunctor(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<FunctorManager>().Functor;
}
VTKM_CONT static InverseFunctorType GetInverseFunctor(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static InverseFunctorType GetInverseFunctor(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[1].GetMetaData<InverseFunctorManager>().Functor;
}

@ -143,6 +143,12 @@ class Storage<T, StorageTagView<ST>>
using ArrayHandleType = typename detail::ViewTypeArg<T, ST>::ArrayHandle;
using SourceStorage = Storage<T, ST>;
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
VTKM_STORAGE_NO_RESIZE;
@ -150,25 +156,23 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalView<typename ArrayHandleType::WritePortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return SourceStorage::GetNumberOfBuffers() + 1;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<vtkm::internal::ViewIndices>().NumberOfValues;
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
return ReadPortalType(SourceStorage::CreateReadPortal(buffers + 1, device, token), indices);
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
indices);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -179,30 +183,36 @@ public:
vtkm::Id adjustedEndIndex = (endIndex < indices.NumberOfValues)
? endIndex + indices.StartIndex
: indices.NumberOfValues + indices.StartIndex;
SourceStorage::Fill(buffers + 1, fillValue, adjustedStartIndex, adjustedEndIndex, token);
SourceStorage::Fill(
SourceBuffers(buffers), fillValue, adjustedStartIndex, adjustedEndIndex, token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
return WritePortalType(SourceStorage::CreateWritePortal(buffers + 1, device, token), indices);
return WritePortalType(SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
indices);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer>
CreateBuffers(vtkm::Id startIndex, vtkm::Id numValues, const ArrayHandleType& array)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
vtkm::Id startIndex = 0,
vtkm::Id numValues = 0,
const ArrayHandleType& array = ArrayHandleType{})
{
return vtkm::cont::internal::CreateBuffers(vtkm::internal::ViewIndices(startIndex, numValues),
array);
}
VTKM_CONT static ArrayHandleType GetSourceArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayHandleType GetSourceArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayHandleType(buffers + 1);
return ArrayHandleType(SourceBuffers(buffers));
}
VTKM_CONT static vtkm::Id GetStartIndex(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetStartIndex(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<vtkm::internal::ViewIndices>().StartIndex;
}

@ -170,60 +170,61 @@ class XGCCoordinatesStorageImpl
using SourceStorage = Storage<T, StorageTagBasic>; // only allow input AH to use StorageTagBasic
using MetaData = XGCCoordinatesMetaData;
static MetaData& GetMetaData(const vtkm::cont::internal::Buffer* buffers)
static MetaData& GetMetaData(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<MetaData>();
}
// Used to skip the metadata buffer and return only actual data buffers
template <typename Buffs>
VTKM_CONT constexpr static Buffs* SourceBuffers(Buffs* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + 1;
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
using ReadPortalType =
vtkm::internal::ArrayPortalXGCCoordinates<typename SourceStorage::ReadPortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return SourceStorage::GetNumberOfBuffers() + 1; // To account for metadata
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetNumberOfValuesPerPlane(buffers) * GetNumberOfPlanesOwned(buffers);
}
VTKM_CONT static vtkm::Id GetNumberOfValuesPerPlane(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValuesPerPlane(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers)) / 2;
}
VTKM_CONT static vtkm::Id GetNumberOfPlanes(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfPlanes(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).NumberOfPlanes;
}
VTKM_CONT static vtkm::Id GetNumberOfPlanesOwned(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfPlanesOwned(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).NumberOfPlanesOwned;
}
VTKM_CONT static vtkm::Id GetPlaneStartId(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetPlaneStartId(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).PlaneStartId;
}
VTKM_CONT static bool GetUseCylindrical(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static bool GetUseCylindrical(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).UseCylindrical;
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
GetNumberOfPlanes(buffers),
@ -233,7 +234,7 @@ public:
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
vtkm::cont::ArrayHandle<T> array,
const vtkm::cont::ArrayHandle<T>& array,
vtkm::Id numberOfPlanes,
vtkm::Id numberOfPlanesOwned,
vtkm::Id planeStartId,
@ -243,8 +244,13 @@ public:
MetaData(numberOfPlanes, numberOfPlanesOwned, planeStartId, useCylindrical), array);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return CreateBuffers(vtkm::cont::ArrayHandle<T>{}, 0, 0, 0, false);
}
VTKM_CONT static vtkm::cont::ArrayHandle<T> GetArrayHandle(
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T>(SourceBuffers(buffers));
}

@ -129,6 +129,10 @@ struct ArrayHandleZipTraits
using Tag =
StorageTagZip<typename FirstHandleType::StorageTag, typename SecondHandleType::StorageTag>;
/// The storage type.
///
using Storage = vtkm::cont::internal::Storage<ValueType, Tag>;
/// The superclass for ArrayHandleZip.
///
using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
@ -141,15 +145,27 @@ class Storage<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>
using SecondStorage = Storage<T2, ST2>;
using ValueType = vtkm::Pair<T1, T2>;
template <typename BufferType>
VTKM_CONT static BufferType* FirstArrayBuffers(BufferType* buffers)
using FirstArrayType = vtkm::cont::ArrayHandle<T1, ST1>;
using SecondArrayType = vtkm::cont::ArrayHandle<T2, ST2>;
struct Info
{
return buffers;
std::size_t SecondBuffersOffset;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> FirstArrayBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
const Info& info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + info.SecondBuffersOffset);
}
template <typename BufferType>
VTKM_CONT static BufferType* SecondArrayBuffers(BufferType* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SecondArrayBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + FirstStorage::GetNumberOfBuffers();
const Info& info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.SecondBuffersOffset,
buffers.end());
}
public:
@ -160,13 +176,17 @@ public:
vtkm::exec::internal::ArrayPortalZip<typename FirstStorage::WritePortalType,
typename SecondStorage::WritePortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const FirstArrayType& firstArray = FirstArrayType{},
const SecondArrayType& secondArray = SecondArrayType{})
{
return FirstStorage::GetNumberOfBuffers() + SecondStorage::GetNumberOfBuffers();
Info info;
info.SecondBuffersOffset = 1 + firstArray.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, firstArray, secondArray);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -174,14 +194,15 @@ public:
SecondStorage::ResizeBuffers(numValues, SecondArrayBuffers(buffers), preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
vtkm::Id numValues = FirstStorage::GetNumberOfValues(FirstArrayBuffers(buffers));
VTKM_ASSERT(numValues == SecondStorage::GetNumberOfValues(SecondArrayBuffers(buffers)));
return numValues;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -191,29 +212,31 @@ public:
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)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(
FirstStorage::CreateReadPortal(FirstArrayBuffers(buffers), device, token),
SecondStorage::CreateReadPortal(SecondArrayBuffers(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(
FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token),
SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token));
}
vtkm::cont::ArrayHandle<T1, ST1> GetFirstArray(const vtkm::cont::internal::Buffer* buffers)
static FirstArrayType GetFirstArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return { FirstArrayBuffers(buffers) };
}
vtkm::cont::ArrayHandle<T2, ST2> GetSecondArray(const vtkm::cont::internal::Buffer* buffers)
static SecondArrayType GetSecondArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return { SecondArrayBuffers(buffers) };
}
@ -236,6 +259,9 @@ class ArrayHandleZip
// template argument is not a valid ArrayHandle type.
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
using StorageType =
typename internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Storage;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleZip,
@ -244,17 +270,14 @@ public:
VTKM_CONT
ArrayHandleZip(const FirstHandleType& firstArray, const SecondHandleType& secondArray)
: Superclass(vtkm::cont::internal::CreateBuffers(firstArray, secondArray))
: Superclass(StorageType::CreateBuffers(firstArray, secondArray))
{
}
FirstHandleType GetFirstArray() const
{
return this->GetStorage().GetFirstArray(this->GetBuffers());
}
FirstHandleType GetFirstArray() const { return StorageType::GetFirstArray(this->GetBuffers()); }
SecondHandleType GetSecondArray() const
{
return this->GetStorage().GetSecondArray(this->GetBuffers());
return StorageType::GetSecondArray(this->GetBuffers());
}
};

@ -595,7 +595,8 @@ public:
VTKM_CONT VTKM_DEPRECATED(1.6, "BitField now uses a Buffer to store data.")
ArrayHandle<vtkm::WordTypeDefault, StorageTagBasic> GetData() const
{
return vtkm::cont::ArrayHandle<vtkm::WordTypeDefault, StorageTagBasic>(&this->Buffer);
return vtkm::cont::ArrayHandle<vtkm::WordTypeDefault, StorageTagBasic>(
std::vector<vtkm::cont::internal::Buffer>(1, this->Buffer));
}
/// Return the number of bits stored by this BitField.

@ -118,25 +118,30 @@ public:
///
using WritePortalType = vtkm::internal::ArrayPortalBasicWrite<T>;
/// \brief Returns the number of buffers required for this storage.
/// \brief Create the buffers for an empty array.
///
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers();
/// This is used by the `ArrayHandle` base class when constructed with no arguments.
/// A convenience subclass may construct the buffers in a different way based on
/// some provided objects.
///
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers();
/// \brief Resizes the array by changing the size of the buffers.
///
/// Can also modify any metadata attached to the buffers.
///
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token);
/// \brief Returns the number of entries allocated in the array.
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers);
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<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,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -144,15 +149,17 @@ public:
/// \brief Create a read-only portal on the specified device.
///
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token);
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token);
/// \brief Create a read/write portal on the specified device.
///
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
};
#endif // VTKM_DOXYGEN_ONLY
@ -175,22 +182,24 @@ struct StorageTraits<vtkm::cont::internal::Storage<T, S>>
using Tag = S;
};
#define VTKM_STORAGE_NO_RESIZE \
VTKM_CONT static void ResizeBuffers( \
vtkm::Id numValues, vtkm::cont::internal::Buffer* buffers, vtkm::CopyFlag, vtkm::cont::Token&) \
{ \
vtkm::cont::internal::detail::StorageNoResizeImpl( \
GetNumberOfValues(buffers), \
numValues, \
vtkm::cont::TypeToString<typename vtkm::cont::internal::StorageTraits<Storage>::Tag>()); \
} \
#define VTKM_STORAGE_NO_RESIZE \
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues, \
const std::vector<vtkm::cont::internal::Buffer>& buffers, \
vtkm::CopyFlag, \
vtkm::cont::Token&) \
{ \
vtkm::cont::internal::detail::StorageNoResizeImpl( \
GetNumberOfValues(buffers), \
numValues, \
vtkm::cont::TypeToString<typename vtkm::cont::internal::StorageTraits<Storage>::Tag>()); \
} \
using ResizeBuffersEatComma = void
#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 std::vector<vtkm::cont::internal::Buffer>&, \
const typename vtkm::cont::internal::StorageTraits<Storage>::ValueType&, \
vtkm::Id, \
vtkm::Id, \
@ -201,7 +210,9 @@ struct StorageTraits<vtkm::cont::internal::Storage<T, S>>
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&) \
const std::vector<vtkm::cont::internal::Buffer>&, \
vtkm::cont::DeviceAdapterId, \
vtkm::cont::Token&) \
{ \
throw vtkm::cont::ErrorBadAllocation( \
"Cannot write to arrays with storage type of " + \

@ -136,8 +136,7 @@ UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::Cop
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
auto componentArray = vtkm::cont::ArrayExtractComponent(*arrayHandle, componentIndex, allowCopy);
vtkm::cont::internal::Buffer* buffers = componentArray.GetBuffers();
return std::vector<vtkm::cont::internal::Buffer>(buffers, buffers + 2);
return componentArray.GetBuffers();
}
template <typename T, typename S>

@ -72,10 +72,10 @@ public:
"Storage implementation declare VTKM_STORAGE_OLD_STYLE at the bottom "
"of its implementation.");
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT vtkm::cont::internal::Buffer* GetBuffers() const
VTKM_CONT std::vector<vtkm::cont::internal::Buffer> GetBuffers() const
{
this->BufferAsStorageWrapper.SetMetaData(*this);
return &this->BufferAsStorageWrapper;
return std::vector<vtkm::cont::internal::Buffer>(1, this->BufferAsStorageWrapper);
}
VTKM_CONT ArrayHandleDeprecated(const vtkm::cont::internal::Buffer* buffers)

@ -771,7 +771,7 @@ vtkm::BufferSizeType Buffer::GetNumberOfBytes() const
void Buffer::SetNumberOfBytes(vtkm::BufferSizeType numberOfBytes,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
vtkm::cont::Token& token) const
{
LockType lock = this->Internals->GetLock();
detail::BufferHelper::SetNumberOfBytes(this->Internals, lock, numberOfBytes, preserve, token);
@ -1046,7 +1046,7 @@ vtkm::cont::internal::BufferInfo Buffer::GetHostBufferInfo() const
return this->Internals->GetHostBuffer(lock);
}
vtkm::cont::internal::TransferredBuffer Buffer::TakeHostBufferOwnership()
vtkm::cont::internal::TransferredBuffer Buffer::TakeHostBufferOwnership() const
{
// A Token should not be declared within the scope of a lock. when the token goes out of scope
// it will attempt to acquire the lock, which is undefined behavior of the thread already has
@ -1063,7 +1063,7 @@ vtkm::cont::internal::TransferredBuffer Buffer::TakeHostBufferOwnership()
}
vtkm::cont::internal::TransferredBuffer Buffer::TakeDeviceBufferOwnership(
vtkm::cont::DeviceAdapterId device)
vtkm::cont::DeviceAdapterId device) const
{
if (device.IsValueValid())
{

@ -123,7 +123,7 @@ public:
///
VTKM_CONT void SetNumberOfBytes(vtkm::BufferSizeType numberOfBytes,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token);
vtkm::cont::Token& token) const;
private:
VTKM_CONT bool MetaDataIsType(const std::string& type) const;
@ -302,13 +302,13 @@ public:
/// \brief Transfer ownership of the Host `BufferInfo` from this buffer
/// to the caller. This is used to allow memory owned by VTK-m to be
/// transferred to an owner whose lifespan is longer
VTKM_CONT vtkm::cont::internal::TransferredBuffer TakeHostBufferOwnership();
VTKM_CONT vtkm::cont::internal::TransferredBuffer TakeHostBufferOwnership() const;
/// \brief Transfer ownership of the device `BufferInfo` from this buffer
/// to the caller. This is used to allow memory owned by VTK-m to be
/// transferred to an owner whose lifespan is longer
VTKM_CONT vtkm::cont::internal::TransferredBuffer TakeDeviceBufferOwnership(
vtkm::cont::DeviceAdapterId device);
vtkm::cont::DeviceAdapterId device) const;
/// \brief Fill up the buffer with particular values.
///

@ -100,21 +100,20 @@ class StorageDeprecated
using ArrayType = vtkm::cont::internal::ArrayHandleDeprecated<T, StorageTag>;
VTKM_CONT static ArrayType GetArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayType GetArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<ArrayType>();
}
public:
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetArray(buffers).GetNumberOfValues();
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -129,9 +128,10 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if (device == vtkm::cont::DeviceAdapterTagUndefined{})
{
@ -153,10 +153,11 @@ public:
}
private:
VTKM_CONT static WritePortalType CreateWritePortalImpl(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token,
std::true_type)
VTKM_CONT static WritePortalType CreateWritePortalImpl(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token,
std::true_type)
{
if (device == vtkm::cont::DeviceAdapterTagUndefined{})
{
@ -177,10 +178,11 @@ private:
}
}
VTKM_CONT static WritePortalType CreateWritePortalImpl(vtkm::cont::internal::Buffer*,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&,
std::false_type)
VTKM_CONT static WritePortalType CreateWritePortalImpl(
const std::vector<vtkm::cont::internal::Buffer>&,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&,
std::false_type)
{
throw vtkm::cont::ErrorBadType("Attempted to get a writable portal to a read-only array.");
}
@ -188,32 +190,33 @@ private:
using SupportsWrite = vtkm::internal::PortalSupportsSets<WritePortalType>;
public:
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreateWritePortalImpl(buffers, device, token, SupportsWrite{});
}
};
#define VTKM_STORAGE_OLD_STYLE \
public: \
using HasOldBridge = std::true_type; \
using ReadPortalType = PortalConstType; \
using WritePortalType = PortalType; \
\
private: \
using StorageDeprecated = \
vtkm::cont::internal::StorageDeprecated<Storage, ReadPortalType, WritePortalType>; \
\
public: \
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers) \
{ \
return StorageDeprecated::GetNumberOfValues(buffers); \
} \
static constexpr auto& GetNumberOfBuffers = StorageDeprecated::GetNumberOfBuffers; \
static constexpr auto& ResizeBuffers = StorageDeprecated::ResizeBuffers; \
static constexpr auto& CreateReadPortal = StorageDeprecated::CreateReadPortal; \
#define VTKM_STORAGE_OLD_STYLE \
public: \
using HasOldBridge = std::true_type; \
using ReadPortalType = PortalConstType; \
using WritePortalType = PortalType; \
\
private: \
using StorageDeprecated = \
vtkm::cont::internal::StorageDeprecated<Storage, ReadPortalType, WritePortalType>; \
\
public: \
VTKM_CONT static vtkm::Id GetNumberOfValues( \
const std::vector<vtkm::cont::internal::Buffer>& buffers) \
{ \
return StorageDeprecated::GetNumberOfValues(buffers); \
} \
static constexpr auto& ResizeBuffers = StorageDeprecated::ResizeBuffers; \
static constexpr auto& CreateReadPortal = StorageDeprecated::CreateReadPortal; \
static constexpr auto& CreateWritePortal = StorageDeprecated::CreateWritePortal
}

@ -601,7 +601,7 @@ private:
Algorithm::Schedule(functor, ARRAY_SIZE * 2);
}
transferredMemory = copyOfHandle.GetBuffers()->TakeHostBufferOwnership();
transferredMemory = copyOfHandle.GetBuffers()[0].TakeHostBufferOwnership();
VTKM_TEST_ASSERT(copyOfHandle.GetNumberOfValues() == ARRAY_SIZE * 2,
"Array not allocated correctly.");