Merge topic 'array-virtual-not-special'

db0f5c31b Add a Transfer object for ArrayHandleVirtual
99cb10b9a Fix warnings about override keyword
0ff83e94b Properly handle conditions when VirtualStorage is null
0571c6335 Add missing allocation methods to ArrayHandleVirtual
68b2e5e65 Add move constructors to ArrayHandle subclasses
0b32831af Make ArrayHandleVirtual conform with other ArrayHandle structure

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Robert Maynard <robert.maynard@kitware.com>
Merge-request: !1557
This commit is contained in:
Kenneth Moreland 2019-03-04 19:13:07 +00:00 committed by Kitware Robot
commit 0aa99df394
14 changed files with 737 additions and 639 deletions

@ -0,0 +1,11 @@
# Make ArrayHandleVirtual conform with other ArrayHandle structure
Previously, ArrayHandleVirtual was defined as a specialization of
ArrayHandle with the virtual storage tag. This was because the storage
object was polymorphic and needed to be handled special. These changes
moved the existing storage definition to an internal class, and then
managed the pointer to that implementation class in a Storage object that
can be managed like any other storage object.
Also moved the implementation of StorageAny into the implementation of the
internal storage object.

@ -164,6 +164,9 @@ struct GetTypeInParentheses<void(T)>
} \
\
VTKM_CONT \
classname(Thisclass&& src) noexcept : Superclass(std::move(src)) {} \
\
VTKM_CONT \
classname(const vtkm::cont::ArrayHandle<typename__ Superclass::ValueType, \
typename__ Superclass::StorageTag>& src) \
: Superclass(src) \
@ -171,12 +174,26 @@ struct GetTypeInParentheses<void(T)>
} \
\
VTKM_CONT \
classname(vtkm::cont::ArrayHandle<typename__ Superclass::ValueType, \
typename__ Superclass::StorageTag>&& src) noexcept \
: Superclass(std::move(src)) \
{ \
} \
\
VTKM_CONT \
Thisclass& operator=(const Thisclass& src) \
{ \
this->Superclass::operator=(src); \
return *this; \
} \
\
VTKM_CONT \
Thisclass& operator=(Thisclass&& src) noexcept \
{ \
this->Superclass::operator=(std::move(src)); \
return *this; \
} \
\
using ValueType = typename__ Superclass::ValueType; \
using StorageTag = typename__ Superclass::StorageTag

@ -0,0 +1,52 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2019 UT-Battelle, LLC.
// Copyright 2019 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#define vtk_m_cont_ArrayHandleVirtual_cxx
#include <vtkm/cont/ArrayHandleVirtual.h>
namespace vtkm
{
namespace cont
{
#define VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT ArrayHandle<T, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<T>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<T, 2>, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 2>>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<T, 3>, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 3>>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<T, 4>, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(char);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int8);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt8);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int16);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt16);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int64);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt64);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE
}
} //namespace vtkm::cont

@ -6,9 +6,9 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
// Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2018 UT-Battelle, LLC.
// Copyright 2018 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
@ -26,7 +26,6 @@
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/StorageAny.h>
#include <vtkm/cont/StorageVirtual.h>
#include <memory>
@ -36,33 +35,17 @@ namespace vtkm
namespace cont
{
/// Specialization of ArrayHandle for virtual storage.
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>
: public vtkm::cont::internal::ArrayHandleBase
class VTKM_ALWAYS_EXPORT ArrayHandleVirtual
: public vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>
{
using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>;
public:
using StorageTag = vtkm::cont::StorageTagVirtual;
using StorageType = vtkm::cont::internal::Storage<void, vtkm::cont::StorageTagVirtual>;
using ValueType = T;
using PortalControl = vtkm::ArrayPortalRef<T>;
using PortalConstControl = vtkm::ArrayPortalRef<T>;
template <typename Device>
struct ExecutionTypes
{
using Portal = vtkm::ArrayPortalRef<T>;
using PortalConst = vtkm::ArrayPortalRef<T>;
};
///Construct a invalid ArrayHandleVirtual that has nullptr storage
VTKM_CONT ArrayHandle()
: Storage(nullptr)
{
}
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleVirtual,
(ArrayHandleVirtual<T>),
(vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>));
///Construct a valid ArrayHandleVirtual from an existing ArrayHandle
///that doesn't derive from ArrayHandleVirtual.
@ -78,110 +61,13 @@ public:
/// vtkm::cont::ArrayHandleCounting<vtkm::Float64> fancyArray(-1.0, 0.1, ARRAY_SIZE);
/// vectorOfArrays.push_back(fancyArray);
template <typename S>
ArrayHandle(const vtkm::cont::ArrayHandle<T, S>& ah)
: Storage(std::make_shared<vtkm::cont::StorageAny<T, S>>(ah))
ArrayHandleVirtual(const vtkm::cont::ArrayHandle<T, S>& ah)
: Superclass(StorageType(ah))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, S>;
using is_base = std::is_base_of<StorageType, S>;
static_assert(!is_base::value, "Wrong specialization for ArrayHandleVirtual selected");
}
///Copy an existing ArrayHandleVirtual into this instance
ArrayHandle(const ArrayHandle<T, vtkm::cont::StorageTagVirtual>& src) = default;
/// virtual destructor, as required to make sure derived classes that
/// might have member variables are properly cleaned up.
//
virtual ~ArrayHandle() = default;
///Move existing shared_ptr of vtkm::cont::StorageVirtual to be
///owned by this ArrayHandleVirtual.
///This is generally how derived class construct a valid ArrayHandleVirtual
template <typename DerivedStorage>
explicit ArrayHandle(std::shared_ptr<DerivedStorage>&& storage) noexcept
: Storage(std::move(storage))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, DerivedStorage>;
static_assert(is_base::value,
"Storage for ArrayHandleVirtual needs to derive from vtkm::cont::StorageVirual");
}
///Move existing unique_ptr of vtkm::cont::StorageVirtual to be
///owned by this ArrayHandleVirtual.
///This is how a derived class construct a valid ArrayHandleVirtual
template <typename DerivedStorage>
explicit ArrayHandle(std::unique_ptr<DerivedStorage>&& storage) noexcept
: Storage(std::move(storage))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, DerivedStorage>;
static_assert(is_base::value,
"Storage for ArrayHandleVirtual needs to derive from vtkm::cont::StorageVirual");
}
///move from one virtual array handle to another
ArrayHandle(ArrayHandle<T, vtkm::cont::StorageTagVirtual>&& src) noexcept
: Storage(std::move(src.Storage))
{
}
///move from one a non-virtual array handle to virtual array handle
template <typename S>
ArrayHandle(ArrayHandle<T, S>&& src) noexcept
: Storage(std::make_shared<vtkm::cont::StorageAny<T, S>>(std::move(src)))
{
}
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(
const ArrayHandle<T, vtkm::cont::StorageTagVirtual>& src) = default;
template <typename S>
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(const ArrayHandle<T, S>& src)
{
this->Storage = std::make_shared<vtkm::cont::StorageAny<T, S>>(src);
return *this;
}
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(
ArrayHandle<T, vtkm::cont::StorageTagVirtual>&& src) noexcept
{
this->Storage = std::move(src.Storage);
return *this;
}
template <typename S>
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(
ArrayHandle<T, S>&& src) noexcept
{
this->Storage = std::make_shared<vtkm::cont::StorageAny<T, S>>(std::move(src));
return *this;
}
/// Like a pointer, two \c ArrayHandles are considered equal if they point
/// to the same location in memory.
///
VTKM_CONT
bool operator==(const ArrayHandle<T, StorageTag>& rhs) const
{
return (this->Storage == rhs.Storage);
}
VTKM_CONT
bool operator!=(const ArrayHandle<T, StorageTag>& rhs) const
{
return (this->Storage != rhs.Storage);
}
template <typename VT, typename ST>
VTKM_CONT bool operator==(const ArrayHandle<VT, ST>&) const
{
return false; // different valuetype and/or storage
}
template <typename VT, typename ST>
VTKM_CONT bool operator!=(const ArrayHandle<VT, ST>&) const
{
return true; // different valuetype and/or storage
}
/// Returns true if this array matches the type passed in.
///
template <typename ArrayHandleType>
@ -231,129 +117,11 @@ public:
/// Returns a new instance of an ArrayHandleVirtual with the same storage
///
VTKM_CONT ArrayHandle<T, ::vtkm::cont::StorageTagVirtual> NewInstance() const
VTKM_CONT ArrayHandleVirtual<T> NewInstance() const
{
return (this->Storage)
? ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>(this->Storage->NewInstance())
: ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>();
return ArrayHandleVirtual<T>(this->GetStorage().NewInstance());
}
/// Returns a view on the internal storage of the ArrayHandleVirtual
///
VTKM_CONT const StorageType* GetStorage() const { return this->Storage.get(); }
/// Get the array portal of the control array.
/// Since worklet invocations are asynchronous and this routine is a synchronization point,
/// exceptions maybe thrown for errors from previously executed worklets.
///
PortalControl GetPortalControl()
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->GetPortalControl()),
this->GetNumberOfValues());
}
/// Get the array portal of the control array.
/// Since worklet invocations are asynchronous and this routine is a synchronization point,
/// exceptions maybe thrown for errors from previously executed worklets.
///
PortalConstControl GetPortalConstControl() const
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->GetPortalConstControl()),
this->GetNumberOfValues());
}
/// Returns the number of entries in the array.
///
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
/// \brief Allocates an array large enough to hold the given number of values.
///
/// The allocation may be done on an already existing array, but can wipe out
/// any data already in the array. This method can throw
/// ErrorBadAllocation if the array cannot be allocated or
/// ErrorBadValue if the allocation is not feasible (for example, the
/// array storage is read-only).
///
VTKM_CONT
void Allocate(vtkm::Id numberOfValues) { return this->Storage->Allocate(numberOfValues); }
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
void Shrink(vtkm::Id numberOfValues) { return this->Storage->Shrink(numberOfValues); }
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
void ReleaseResourcesExecution() { return this->Storage->ReleaseResourcesExecution(); }
/// Releases all resources in both the control and execution environments.
///
void ReleaseResources() { return this->Storage->ReleaseResources(); }
/// Prepares this array to be used as an input to an operation in the
/// execution environment. If necessary, copies data to the execution
/// environment. Can throw an exception if this array does not yet contain
/// any data. Returns a portal that can be used in code running in the
/// execution environment.
///
/// Return a ArrayPortalRef that wraps the real virtual portal. We need a stack object for
/// the following reasons:
/// 1. Device Adapter algorithms only support const AH<T,S>& and not const AH<T,S>*
/// 2. Devices will want to get the length of a portal before execution, but for CUDA
/// we can't ask this information of the portal as it only valid on the device, instead
/// we have to store this information also in the ref wrapper
vtkm::ArrayPortalRef<T> PrepareForInput(vtkm::cont::DeviceAdapterId devId) const
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->PrepareForInput(devId)),
this->GetNumberOfValues());
}
/// Prepares (allocates) this array to be used as an output from an operation
/// in the execution environment. The internal state of this class is set to
/// have valid data in the execution array with the assumption that the array
/// will be filled soon (i.e. before any other methods of this object are
/// called). Returns a portal that can be used in code running in the
/// execution environment.
///
vtkm::ArrayPortalRef<T> PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
return make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<T>*>(
this->Storage->PrepareForOutput(numberOfValues, devId)),
numberOfValues);
}
/// Prepares this array to be used in an in-place operation (both as input
/// and output) in the execution environment. If necessary, copies data to
/// the execution environment. Can throw an exception if this array does not
/// yet contain any data. Returns a portal that can be used in code running
/// in the execution environment.
///
vtkm::ArrayPortalRef<T> PrepareForInPlace(vtkm::cont::DeviceAdapterId devId)
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->PrepareForInPlace(devId)),
this->GetNumberOfValues());
}
/// Returns the DeviceAdapterId for the current device. If there is no device
/// with an up-to-date copy of the data, VTKM_DEVICE_ADAPTER_UNDEFINED is
/// returned.
VTKM_CONT
DeviceAdapterId GetDeviceAdapterId() const { return this->Storage->GetDeviceAdapterId(); }
protected:
std::shared_ptr<StorageType> Storage = nullptr;
private:
template <typename ArrayHandleType>
inline bool IsSameType(std::false_type, std::true_type) const
@ -380,12 +148,13 @@ private:
inline bool IsSameType(std::true_type vtkmNotUsed(valueTypesMatch),
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
if (!this->Storage)
auto* storage = this->GetStorage().GetStorageVirtual();
if (!storage)
{
return false;
}
using S = typename ArrayHandleType::StorageTag;
return this->Storage->template IsType<vtkm::cont::StorageAny<T, S>>();
return storage->template IsType<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
}
template <typename ArrayHandleType>
@ -428,11 +197,6 @@ private:
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const;
};
//=============================================================================
// Better name for the type
template <typename T>
using ArrayHandleVirtual = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>;
//=============================================================================
/// A convenience function for creating an ArrayHandleVirtual.
@ -464,6 +228,17 @@ VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::ArrayHandleVirtual<T>& v
return virtHandle.template Cast<ArrayHandleType>();
}
#if 0
// The following specialization of CastAndCall has been disabled. The problem with it is that it
// causes some common versions of GCC to give the warning "type attributes ignored after type is
// already defined." GCC seems to have a problem with declaring an instance of a template twice
// even when the type attributes match. (In some cases it is OK, in others it is not.) The easiest
// solution is to just disable this CastAndCall that instantiates a specific version of
// ArrayHandleVirtual. This specialization might be better handled elsewhere where the uniform
// point coordinates are coupled with a structured cell set (and thus can derive several fast
// paths) rather than generally for any field or array containing vec3s.
//=============================================================================
// Specializations of CastAndCall to help make sure ArrayHandleVirtual
// holding a ArrayHandleUniformPointCoordinates works properly
@ -477,15 +252,17 @@ void CastAndCall(vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>
using S = typename HandleType::StorageTag;
if (coords.IsType<HandleType>())
{
const vtkm::cont::StorageVirtual* storage = coords.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
f(any->GetHandle(), std::forward<Args>(args)...);
const vtkm::cont::internal::detail::StorageVirtual* storage =
coords.GetStorage().GetStorageVirtual();
auto* virtualImpl = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
f(virtualImpl->GetHandle(), std::forward<Args>(args)...);
}
else
{
f(coords, std::forward<Args>(args)...);
}
}
#endif
@ -500,6 +277,34 @@ struct SerializableTypeString<vtkm::cont::ArrayHandleVirtual<T>>
return name;
}
};
#ifndef vtk_m_cont_ArrayHandleVirtual_cxx
#define VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(T) \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<T, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<T>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<T, 2>, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 2>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<T, 3>, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 3>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<T, 4>, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(char);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int8);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt8);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int16);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt16);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int32);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt32);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int64);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt64);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Float32);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT
#endif //vtk_m_cont_ArrayHandleVirtual_cxx
}
} //namespace vtkm::cont

@ -6,9 +6,9 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
// Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2018 UT-Battelle, LLC.
// Copyright 2018 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
@ -21,7 +21,6 @@
#define vtk_m_cont_ArrayHandleVirtual_hxx
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/StorageAny.hxx>
#include <vtkm/cont/TryExecute.h>
namespace vtkm
@ -31,21 +30,23 @@ namespace cont
template <typename T>
template <typename ArrayHandleType>
ArrayHandleType inline ArrayHandle<T, StorageTagVirtual>::CastToType(
ArrayHandleType inline ArrayHandleVirtual<T>::CastToType(
std::true_type vtkmNotUsed(valueTypesMatch),
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
if (!this->Storage)
auto* storage = this->GetStorage().GetStorageVirtual();
if (!storage)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeToString<ArrayHandleType>());
}
using S = typename ArrayHandleType::StorageTag;
const auto* any = this->Storage->template Cast<vtkm::cont::StorageAny<T, S>>();
return any->GetHandle();
const auto* castStorage =
storage->template Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
return castStorage->GetHandle();
}
}
} // namespace vtkm::const
} // namespace vtkm::cont
#include <vtkm/cont/ArrayHandleConstant.h>
@ -89,18 +90,20 @@ struct IntAnySerializer
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<CountingType>::Get());
using S = typename CountingType::StorageTag;
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
vtkmdiy::save(bb, any->GetHandle());
const vtkm::cont::internal::detail::StorageVirtual* storage =
obj.GetStorage().GetStorageVirtual();
auto* castStorage = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, castStorage->GetHandle());
}
else if (obj.template IsType<ConstantType>())
{
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<ConstantType>::Get());
using S = typename ConstantType::StorageTag;
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
vtkmdiy::save(bb, any->GetHandle());
const vtkm::cont::internal::detail::StorageVirtual* storage =
obj.GetStorage().GetStorageVirtual();
auto* castStorage = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, castStorage->GetHandle());
}
else
{

@ -43,38 +43,14 @@ class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates final
: public vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
using StorageTag = vtkm::cont::StorageTagVirtual;
VTKM_ARRAY_HANDLE_SUBCLASS_NT(ArrayHandleVirtualCoordinates,
(vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>));
using NonDefaultCoord = typename std::conditional<std::is_same<vtkm::FloatDefault, float>::value,
vtkm::Vec<double, 3>,
vtkm::Vec<float, 3>>::type;
ArrayHandleVirtualCoordinates()
: vtkm::cont::ArrayHandleVirtual<ValueType>()
template <typename T, typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<T, S>& ah)
: Superclass(vtkm::cont::make_ArrayHandleCast<ValueType>(ah))
{
}
explicit ArrayHandleVirtualCoordinates(
const vtkm::cont::ArrayHandle<ValueType, vtkm::cont::StorageTagVirtual>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>(ah)
{
}
template <typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<ValueType, S>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>(ah)
{
}
template <typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<NonDefaultCoord, S>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>()
{
auto castedHandle = vtkm::cont::make_ArrayHandleCast<ValueType>(ah);
using ST = typename decltype(castedHandle)::StorageTag;
this->Storage = std::make_shared<vtkm::cont::StorageAny<ValueType, ST>>(castedHandle);
}
};
template <typename Functor, typename... Args>
@ -123,15 +99,17 @@ private:
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& baseObj)
{
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
Type obj(baseObj);
const vtkm::cont::internal::detail::StorageVirtual* storage =
obj.GetStorage().GetStorageVirtual();
if (obj.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{
using HandleType = vtkm::cont::ArrayHandleUniformPointCoordinates;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
auto array = storage->Cast<vtkm::cont::StorageAny<T, S>>();
auto array = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<HandleType>::Get());
vtkmdiy::save(bb, array->GetHandle());
}
@ -140,7 +118,7 @@ public:
using HandleType = RectilinearCoordsArrayType;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
auto array = storage->Cast<vtkm::cont::StorageAny<T, S>>();
auto array = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<HandleType>::Get());
vtkmdiy::save(bb, array->GetHandle());
}

@ -129,19 +129,23 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
{
using T = typename UniformHandleType::ValueType;
using S = typename UniformHandleType::StorageTag;
const vtkm::cont::StorageVirtual* storage = input.GetStorage();
const auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
const vtkm::cont::internal::detail::StorageVirtual* storage =
input.GetStorage().GetStorageVirtual();
const auto* castStorage =
storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
return ArrayRangeCompute(any->GetHandle(), tracker);
return ArrayRangeCompute(castStorage->GetHandle(), tracker);
}
else if (input.IsType<RectilinearHandleType>())
{
using T = typename RectilinearHandleType::ValueType;
using S = typename RectilinearHandleType::StorageTag;
const vtkm::cont::StorageVirtual* storage = input.GetStorage();
const auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
const vtkm::cont::internal::detail::StorageVirtual* storage =
input.GetStorage().GetStorageVirtual();
const auto* castStorage =
storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
return ArrayRangeCompute(any->GetHandle(), tracker);
return ArrayRangeCompute(castStorage->GetHandle(), tracker);
}
else
{

@ -100,7 +100,6 @@ set(headers
RuntimeDeviceTracker.h
Serialization.h
Storage.h
StorageAny.h
StorageBasic.h
StorageImplicit.h
StorageListTag.h
@ -123,7 +122,6 @@ set(template_sources
CoordinateSystem.hxx
FieldRangeCompute.hxx
FieldRangeGlobalCompute.hxx
StorageAny.hxx
StorageBasic.hxx
StorageVirtual.hxx
VirtualObjectHandle.hxx
@ -131,6 +129,7 @@ set(template_sources
set(sources
ArrayHandle.cxx
ArrayHandleVirtual.cxx
AssignerMultiBlock.cxx
BoundsCompute.cxx
BoundsGlobalCompute.cxx
@ -160,7 +159,6 @@ set(sources
RuntimeDeviceInformation.cxx
RuntimeDeviceTracker.cxx
StorageBasic.cxx
StorageVirtual.cxx
TryExecute.cxx
VariantArrayHandle.cxx
)
@ -171,6 +169,7 @@ set(device_sources
ArrayRangeCompute.cxx
CellSetExplicit.cxx
CoordinateSystem.cxx
StorageVirtual.cxx
Timer.cxx
)

@ -1,74 +0,0 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_StorageAny_h
#define vtk_m_cont_StorageAny_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/StorageVirtual.h>
namespace vtkm
{
namespace cont
{
template <typename T, typename S>
class VTKM_ALWAYS_EXPORT StorageAny final : public vtkm::cont::StorageVirtual
{
public:
VTKM_CONT
explicit StorageAny(const vtkm::cont::ArrayHandle<T, S>& ah);
explicit StorageAny(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept;
VTKM_CONT
~StorageAny() = default;
const vtkm::cont::ArrayHandle<T, S>& GetHandle() const { return this->Handle; }
vtkm::Id GetNumberOfValues() const { return this->Handle.GetNumberOfValues(); }
void ReleaseResourcesExecution();
void ReleaseResources();
private:
std::unique_ptr<StorageVirtual> MakeNewInstance() const
{
return std::unique_ptr<StorageVirtual>(new StorageAny<T, S>{ vtkm::cont::ArrayHandle<T, S>{} });
}
void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const;
void ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload);
void TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const;
void TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId);
vtkm::cont::ArrayHandle<T, S> Handle;
};
}
}
#endif //vtk_m_cont_StorageAny_h

@ -1,162 +0,0 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_StorageAny_hxx
#define vtk_m_cont_StorageAny_hxx
#include <vtkm/cont/StorageAny.h>
#include <vtkm/cont/StorageVirtual.hxx>
namespace vtkm
{
namespace cont
{
VTKM_CONT
template <typename T, typename S>
StorageAny<T, S>::StorageAny(const vtkm::cont::ArrayHandle<T, S>& ah)
: vtkm::cont::StorageVirtual()
, Handle(ah)
{
}
VTKM_CONT
template <typename T, typename S>
StorageAny<T, S>::StorageAny(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept
: vtkm::cont::StorageVirtual(),
Handle(std::move(ah))
{
}
/// release execution side resources
template <typename T, typename S>
void StorageAny<T, S>::ReleaseResourcesExecution()
{
vtkm::cont::StorageVirtual::ReleaseResourcesExecution();
this->Handle.ReleaseResourcesExecution();
}
/// release control side resources
template <typename T, typename S>
void StorageAny<T, S>::ReleaseResources()
{
vtkm::cont::StorageVirtual::ReleaseResources();
this->Handle.ReleaseResources();
}
namespace detail
{
struct PortalWrapperToDevice
{
template <typename DeviceAdapterTag, typename Handle>
bool operator()(DeviceAdapterTag device,
Handle&& handle,
vtkm::cont::internal::TransferInfoArray& payload) const
{
auto portal = handle.PrepareForInput(device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
template <typename DeviceAdapterTag, typename Handle>
bool operator()(DeviceAdapterTag device,
Handle&& handle,
vtkm::Id numberOfValues,
vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::StorageVirtual::OutputMode mode) const
{
using ACCESS_MODE = vtkm::cont::StorageVirtual::OutputMode;
if (mode == ACCESS_MODE::WRITE)
{
auto portal = handle.PrepareForOutput(numberOfValues, device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
else
{
auto portal = handle.PrepareForInPlace(device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
}
};
}
template <typename T, typename S>
void StorageAny<T, S>::ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const
{
auto portal = this->Handle.GetPortalConstControl();
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::make_hostPortal<DerivedPortal>(payload, portal);
}
namespace detail
{
template <typename HandleType>
void make_writableHostPortal(std::true_type,
vtkm::cont::internal::TransferInfoArray& payload,
HandleType& handle)
{
auto portal = handle.GetPortalControl();
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::make_hostPortal<DerivedPortal>(payload, portal);
}
template <typename HandleType>
void make_writableHostPortal(std::false_type,
vtkm::cont::internal::TransferInfoArray& payload,
HandleType&)
{
payload.updateHost(nullptr);
throw vtkm::cont::ErrorBadValue(
"ArrayHandleAny was bound to an ArrayHandle that doesn't support output.");
}
}
template <typename T, typename S>
void StorageAny<T, S>::ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload)
{
using HT = vtkm::cont::ArrayHandle<T, S>;
constexpr auto isWriteable = typename vtkm::cont::internal::IsWriteableArrayHandle<HT>::type{};
detail::make_writableHostPortal(isWriteable, payload, this->Handle);
}
template <typename T, typename S>
void StorageAny<T, S>::TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const
{
vtkm::cont::TryExecuteOnDevice(devId, detail::PortalWrapperToDevice(), this->Handle, payload);
}
template <typename T, typename S>
void StorageAny<T, S>::TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::StorageVirtual::OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
vtkm::cont::TryExecuteOnDevice(
devId, detail::PortalWrapperToDevice(), this->Handle, numberOfValues, payload, mode);
}
}
} // namespace vtkm::cont
#endif //vtk_m_cont_StorageAny_hxx

@ -17,6 +17,7 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#define vtk_m_cont_StorageVirtual_cxx
#include "StorageVirtual.h"
#include <vtkm/cont/internal/DeviceAdapterError.h>
@ -27,11 +28,12 @@ namespace cont
{
namespace internal
{
namespace detail
{
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
const Storage<void, vtkm::cont::StorageTagVirtual>& src)
StorageVirtual::StorageVirtual(const StorageVirtual& src)
: HostUpToDate(src.HostUpToDate)
, DeviceUpToDate(src.DeviceUpToDate)
, DeviceTransferState(src.DeviceTransferState)
@ -39,8 +41,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
}
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
StorageVirtual::StorageVirtual(StorageVirtual&& src) noexcept
: HostUpToDate(src.HostUpToDate),
DeviceUpToDate(src.DeviceUpToDate),
DeviceTransferState(std::move(src.DeviceTransferState))
@ -48,8 +49,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
}
//--------------------------------------------------------------------
Storage<void, vtkm::cont::StorageTagVirtual>& Storage<void, ::vtkm::cont::StorageTagVirtual>::
operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src)
StorageVirtual& StorageVirtual::operator=(const StorageVirtual& src)
{
this->HostUpToDate = src.HostUpToDate;
this->DeviceUpToDate = src.DeviceUpToDate;
@ -58,8 +58,7 @@ operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src)
}
//--------------------------------------------------------------------
Storage<void, vtkm::cont::StorageTagVirtual>& Storage<void, ::vtkm::cont::StorageTagVirtual>::
operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
StorageVirtual& StorageVirtual::operator=(StorageVirtual&& src) noexcept
{
this->HostUpToDate = src.HostUpToDate;
this->DeviceUpToDate = src.DeviceUpToDate;
@ -68,19 +67,19 @@ operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
}
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::~Storage()
StorageVirtual::~StorageVirtual()
{
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResourcesExecution()
void StorageVirtual::DropExecutionPortal()
{
this->DeviceTransferState->releaseDevice();
this->DeviceUpToDate = false;
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
void StorageVirtual::DropAllPortals()
{
this->DeviceTransferState->releaseAll();
this->HostUpToDate = false;
@ -88,15 +87,13 @@ void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
}
//--------------------------------------------------------------------
std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>>
Storage<void, ::vtkm::cont::StorageTagVirtual>::NewInstance() const
std::unique_ptr<StorageVirtual> StorageVirtual::NewInstance() const
{
return this->MakeNewInstance();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInput(
const vtkm::internal::PortalVirtualBase* StorageVirtual::PrepareForInput(
vtkm::cont::DeviceAdapterId devId) const
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
@ -122,8 +119,8 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInput(
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForOutput(vtkm::Id numberOfValues,
const vtkm::internal::PortalVirtualBase* StorageVirtual::PrepareForOutput(
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
@ -147,8 +144,8 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForOutput(vtkm::Id number
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInPlace(vtkm::cont::DeviceAdapterId devId)
const vtkm::internal::PortalVirtualBase* StorageVirtual::PrepareForInPlace(
vtkm::cont::DeviceAdapterId devId)
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
{
@ -172,8 +169,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInPlace(vtkm::cont::De
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalControl()
const vtkm::internal::PortalVirtualBase* StorageVirtual::GetPortalControl()
{
if (!this->HostUpToDate)
{
@ -188,8 +184,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalControl()
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalConstControl() const
const vtkm::internal::PortalVirtualBase* StorageVirtual::GetPortalConstControl() const
{
if (!this->HostUpToDate)
{
@ -202,28 +197,67 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalConstControl() const
}
//--------------------------------------------------------------------
DeviceAdapterId Storage<void, ::vtkm::cont::StorageTagVirtual>::GetDeviceAdapterId() const noexcept
DeviceAdapterId StorageVirtual::GetDeviceAdapterId() const noexcept
{
return this->DeviceTransferState->deviceId();
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ControlPortalForOutput(
vtkm::cont::internal::TransferInfoArray&)
void StorageVirtual::ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray&)
{
throw vtkm::cont::ErrorBadValue(
"StorageTagVirtual by default doesn't support control side writes.");
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::TransferPortalForOutput(
vtkm::cont::internal::TransferInfoArray&,
void StorageVirtual::TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray&,
OutputMode,
vtkm::Id,
vtkm::cont::DeviceAdapterId)
{
throw vtkm::cont::ErrorBadValue("StorageTagVirtual by default doesn't support exec side writes.");
}
#define VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<T>; \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 2>>; \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 3>>; \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(char);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE
#define VTK_M_STORAGE_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT StorageVirtualImpl<T, VTKM_DEFAULT_STORAGE_TAG>; \
template class VTKM_CONT_EXPORT StorageVirtualImpl<vtkm::Vec<T, 2>, VTKM_DEFAULT_STORAGE_TAG>; \
template class VTKM_CONT_EXPORT StorageVirtualImpl<vtkm::Vec<T, 3>, VTKM_DEFAULT_STORAGE_TAG>; \
template class VTKM_CONT_EXPORT StorageVirtualImpl<vtkm::Vec<T, 4>, VTKM_DEFAULT_STORAGE_TAG>
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(char);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int8);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt8);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int16);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt16);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int32);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt32);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int64);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt64);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_STORAGE_VIRTUAL_INSTANTIATE
}
}
}
} // namespace vtkm::cont::internal::detail

@ -22,6 +22,7 @@
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/internal/TransferInfo.h>
@ -41,31 +42,33 @@ struct VTKM_ALWAYS_EXPORT StorageTagVirtual
namespace internal
{
template <>
class VTKM_CONT_EXPORT Storage<void, vtkm::cont::StorageTagVirtual>
namespace detail
{
class VTKM_CONT_EXPORT StorageVirtual
{
public:
/// \brief construct storage that VTK-m is responsible for
Storage() = default;
Storage(const Storage<void, vtkm::cont::StorageTagVirtual>& src);
Storage(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept;
Storage& operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src);
Storage& operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept;
StorageVirtual() = default;
StorageVirtual(const StorageVirtual& src);
StorageVirtual(StorageVirtual&& src) noexcept;
StorageVirtual& operator=(const StorageVirtual& src);
StorageVirtual& operator=(StorageVirtual&& src) noexcept;
virtual ~Storage();
virtual ~StorageVirtual();
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
/// Only needs to overridden by subclasses such as Zip that have member
/// variables that themselves have execution memory
virtual void ReleaseResourcesExecution();
virtual void ReleaseResourcesExecution() = 0;
/// Releases all resources in both the control and execution environments.
///
/// Only needs to overridden by subclasses such as Zip that have member
/// variables that themselves have execution memory
virtual void ReleaseResources();
virtual void ReleaseResources() = 0;
/// Returns the number of entries in the array.
///
@ -79,10 +82,7 @@ public:
/// ErrorBadValue if the allocation is not feasible (for example, the
/// array storage is read-only).
///
void Allocate(vtkm::Id numberOfValues)
{
std::cout << "StorageVirtual::Allocate(" << numberOfValues << ") Not Implemented!" << std::endl;
} //return this->DoAllocate(numberOfValues); }
virtual void Allocate(vtkm::Id numberOfValues) = 0;
/// \brief Reduces the size of the array without changing its values.
///
@ -92,10 +92,7 @@ public:
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
void Shrink(vtkm::Id numberOfValues)
{
std::cout << "StorageVirtual::Shrink(" << numberOfValues << ") Not Implemented!." << std::endl;
} //return this->DoShrink(numberOfValues); }
virtual void Shrink(vtkm::Id numberOfValues) = 0;
/// Determines if storage types matches the type passed in.
///
@ -111,7 +108,7 @@ public:
/// returns a unique_ptr for it. This method is convenient when
/// creating output arrays that should be the same type as some input array.
///
std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>> NewInstance() const;
std::unique_ptr<StorageVirtual> NewInstance() const;
template <typename DerivedStorage>
const DerivedStorage* Cast() const
@ -153,14 +150,23 @@ public:
READ_WRITE
};
protected:
/// Drop the reference to the execution portal. The underlying array handle might still be
/// managing data on the execution side, but our references might be out of date, so drop
/// them and refresh them later if necessary.
void DropExecutionPortal();
/// Drop the reference to all portals. The underlying array handle might still be managing data,
/// but our references might be out of date, so drop them and refresh them later if necessary.
void DropAllPortals();
private:
//Memory management routines
// virtual void DoAllocate(vtkm::Id numberOfValues) = 0;
// virtual void DoShrink(vtkm::Id numberOfValues) = 0;
//RTTI routines
virtual std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>> MakeNewInstance()
const = 0;
virtual std::unique_ptr<StorageVirtual> MakeNewInstance() const = 0;
//Portal routines
virtual void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const = 0;
@ -181,10 +187,117 @@ private:
std::make_shared<vtkm::cont::internal::TransferInfoArray>();
};
} // namespace internal
template <typename T, typename S>
class VTKM_ALWAYS_EXPORT StorageVirtualImpl final
: public vtkm::cont::internal::detail::StorageVirtual
{
public:
VTKM_CONT
explicit StorageVirtualImpl(const vtkm::cont::ArrayHandle<T, S>& ah);
using StorageVirtual = internal::Storage<void, vtkm::cont::StorageTagVirtual>;
explicit StorageVirtualImpl(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept;
VTKM_CONT
~StorageVirtualImpl() = default;
const vtkm::cont::ArrayHandle<T, S>& GetHandle() const { return this->Handle; }
vtkm::Id GetNumberOfValues() const override { return this->Handle.GetNumberOfValues(); }
void ReleaseResourcesExecution() override;
void ReleaseResources() override;
void Allocate(vtkm::Id numberOfValues) override;
void Shrink(vtkm::Id numberOfValues) override;
private:
std::unique_ptr<vtkm::cont::internal::detail::StorageVirtual> MakeNewInstance() const override
{
return std::unique_ptr<vtkm::cont::internal::detail::StorageVirtual>(
new StorageVirtualImpl<T, S>{ vtkm::cont::ArrayHandle<T, S>{} });
}
void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const override;
void ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload) override;
void TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const override;
void TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId) override;
vtkm::cont::ArrayHandle<T, S> Handle;
};
} // namespace detail
template <typename T>
class VTKM_ALWAYS_EXPORT Storage<T, vtkm::cont::StorageTagVirtual>
{
public:
using ValueType = T;
using PortalType = vtkm::ArrayPortalRef<T>;
using PortalConstType = vtkm::ArrayPortalRef<T>;
Storage() = default;
// Should never really be used, but just in case.
Storage(const Storage<T, vtkm::cont::StorageTagVirtual>&) = default;
template <typename S>
Storage(const vtkm::cont::ArrayHandle<T, S>& srcArray)
: VirtualStorage(std::make_shared<detail::StorageVirtualImpl<T, S>>(srcArray))
{
}
~Storage() = default;
PortalType GetPortal()
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->VirtualStorage->GetPortalControl()),
this->GetNumberOfValues());
}
PortalConstType GetPortalConst() const
{
return make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<T>*>(
this->VirtualStorage->GetPortalConstControl()),
this->GetNumberOfValues());
}
vtkm::Id GetNumberOfValues() const { return this->VirtualStorage->GetNumberOfValues(); }
void Allocate(vtkm::Id numberOfValues);
void Shrink(vtkm::Id numberOfValues);
void ReleaseResources();
Storage<T, vtkm::cont::StorageTagVirtual> NewInstance() const;
const detail::StorageVirtual* GetStorageVirtual() const { return this->VirtualStorage.get(); }
detail::StorageVirtual* GetStorageVirtual() { return this->VirtualStorage.get(); }
private:
std::shared_ptr<detail::StorageVirtual> VirtualStorage;
Storage(std::shared_ptr<detail::StorageVirtual> virtualStorage)
: VirtualStorage(virtualStorage)
{
}
};
} // namespace internal
}
} // namespace vtkm::cont
#ifndef vtk_m_cont_StorageVirtual_hxx
#include <vtkm/cont/StorageVirtual.hxx>
#endif
#endif

@ -20,7 +20,7 @@
#ifndef vtk_m_cont_StorageVirtual_hxx
#define vtk_m_cont_StorageVirtual_hxx
#include <vtkm/cont/StorageAny.hxx>
#include <vtkm/cont/StorageVirtual.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/TransferInfo.h>
@ -78,7 +78,7 @@ struct TransferToDevice
return true;
}
};
}
} // namespace detail
template <typename DerivedPortal, typename... Args>
inline void make_transferToDevice(vtkm::cont::DeviceAdapterId devId, Args&&... args)
@ -93,8 +93,351 @@ inline void make_hostPortal(Payload&& payload, Args&&... args)
auto host = std::unique_ptr<DerivedPortal>(new DerivedPortal(std::forward<Args>(args)...));
payload.updateHost(std::move(host));
}
namespace internal
{
namespace detail
{
VTKM_CONT
template <typename T, typename S>
StorageVirtualImpl<T, S>::StorageVirtualImpl(const vtkm::cont::ArrayHandle<T, S>& ah)
: vtkm::cont::internal::detail::StorageVirtual()
, Handle(ah)
{
}
} // namespace vtkm::cont::
VTKM_CONT
template <typename T, typename S>
StorageVirtualImpl<T, S>::StorageVirtualImpl(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept
: vtkm::cont::internal::detail::StorageVirtual(),
Handle(std::move(ah))
{
}
#endif
/// release execution side resources
template <typename T, typename S>
void StorageVirtualImpl<T, S>::ReleaseResourcesExecution()
{
this->DropExecutionPortal();
this->Handle.ReleaseResourcesExecution();
}
/// release control side resources
template <typename T, typename S>
void StorageVirtualImpl<T, S>::ReleaseResources()
{
this->DropAllPortals();
this->Handle.ReleaseResources();
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::Allocate(vtkm::Id numberOfValues)
{
this->DropAllPortals();
this->Handle.Allocate(numberOfValues);
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::Shrink(vtkm::Id numberOfValues)
{
this->DropAllPortals();
this->Handle.Shrink(numberOfValues);
}
struct PortalWrapperToDevice
{
template <typename DeviceAdapterTag, typename Handle>
bool operator()(DeviceAdapterTag device,
Handle&& handle,
vtkm::cont::internal::TransferInfoArray& payload) const
{
auto portal = handle.PrepareForInput(device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
template <typename DeviceAdapterTag, typename Handle>
bool operator()(DeviceAdapterTag device,
Handle&& handle,
vtkm::Id numberOfValues,
vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::internal::detail::StorageVirtual::OutputMode mode) const
{
using ACCESS_MODE = vtkm::cont::internal::detail::StorageVirtual::OutputMode;
if (mode == ACCESS_MODE::WRITE)
{
auto portal = handle.PrepareForOutput(numberOfValues, device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
else
{
auto portal = handle.PrepareForInPlace(device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
}
};
template <typename T, typename S>
void StorageVirtualImpl<T, S>::ControlPortalForInput(
vtkm::cont::internal::TransferInfoArray& payload) const
{
auto portal = this->Handle.GetPortalConstControl();
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::make_hostPortal<DerivedPortal>(payload, portal);
}
template <typename HandleType>
void make_writableHostPortal(std::true_type,
vtkm::cont::internal::TransferInfoArray& payload,
HandleType& handle)
{
auto portal = handle.GetPortalControl();
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::make_hostPortal<DerivedPortal>(payload, portal);
}
template <typename HandleType>
void make_writableHostPortal(std::false_type,
vtkm::cont::internal::TransferInfoArray& payload,
HandleType&)
{
payload.updateHost(nullptr);
throw vtkm::cont::ErrorBadValue(
"ArrayHandleAny was bound to an ArrayHandle that doesn't support output.");
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::ControlPortalForOutput(
vtkm::cont::internal::TransferInfoArray& payload)
{
using HT = vtkm::cont::ArrayHandle<T, S>;
constexpr auto isWriteable = typename vtkm::cont::internal::IsWriteableArrayHandle<HT>::type{};
detail::make_writableHostPortal(isWriteable, payload, this->Handle);
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::TransferPortalForInput(
vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const
{
vtkm::cont::TryExecuteOnDevice(devId, detail::PortalWrapperToDevice(), this->Handle, payload);
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::TransferPortalForOutput(
vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::internal::detail::StorageVirtual::OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
vtkm::cont::TryExecuteOnDevice(
devId, detail::PortalWrapperToDevice(), this->Handle, numberOfValues, payload, mode);
}
} // namespace detail
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::Allocate(vtkm::Id numberOfValues)
{
if (this->VirtualStorage)
{
this->VirtualStorage->Allocate(numberOfValues);
}
else if (numberOfValues != 0)
{
throw vtkm::cont::ErrorBadAllocation("Attempted to allocate memory in a virtual array that "
"does not have an underlying concrete array.");
}
else
{
// Allocating a non-existing array to 0 is OK.
}
}
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::Shrink(vtkm::Id numberOfValues)
{
if (this->VirtualStorage)
{
this->VirtualStorage->Shrink(numberOfValues);
}
else if (numberOfValues != 0)
{
throw vtkm::cont::ErrorBadAllocation(
"Attempted to shrink a virtual array that does not have an underlying concrete array.");
}
else
{
// Shrinking a non-existing array to 0 is OK.
}
}
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::ReleaseResources()
{
if (this->VirtualStorage)
{
this->VirtualStorage->ReleaseResources();
}
else
{
// No concrete array, nothing allocated, nothing to do.
}
}
template <typename T>
Storage<T, vtkm::cont::StorageTagVirtual> Storage<T, vtkm::cont::StorageTagVirtual>::NewInstance()
const
{
if (this->GetStorageVirtual())
{
return Storage<T, vtkm::cont::StorageTagVirtual>(this->GetStorageVirtual()->NewInstance());
}
else
{
return Storage<T, vtkm::cont::StorageTagVirtual>();
}
}
namespace detail
{
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayTransferVirtual
{
using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>;
vtkm::cont::internal::detail::StorageVirtual* Storage;
public:
using ValueType = T;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
using PortalExecution = vtkm::ArrayPortalRef<ValueType>;
using PortalConstExecution = vtkm::ArrayPortalRef<ValueType>;
VTKM_CONT ArrayTransferVirtual(StorageType* storage)
: Storage(storage->GetStorageVirtual())
{
}
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT PortalConstExecution PrepareForInput(vtkm::cont::DeviceAdapterId device)
{
return vtkm::make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<ValueType>*>(
this->Storage->PrepareForInput(device)),
this->GetNumberOfValues());
}
VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId device)
{
return make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<T>*>(
this->Storage->PrepareForOutput(numberOfValues, device)),
numberOfValues);
}
VTKM_CONT PortalExecution PrepareForInPlace(vtkm::cont::DeviceAdapterId device)
{
return vtkm::make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<ValueType>*>(
this->Storage->PrepareForInPlace(device)),
this->GetNumberOfValues());
}
VTKM_CONT
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
// Implementation of this method should be unnecessary. The internal array handles should
// automatically retrieve the output data as necessary.
}
VTKM_CONT void Shrink(vtkm::Id numberOfValues) { this->Storage->Shrink(numberOfValues); }
VTKM_CONT void ReleaseResources() { this->Storage->ReleaseResourcesExecution(); }
};
#ifndef vtk_m_cont_StorageVirtual_cxx
#define VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(T) \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<T>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 2>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 3>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(char);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Float32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT
#define VTK_M_STORAGE_VIRTUAL_EXPORT(T) \
extern template class VTKM_CONT_TEMPLATE_EXPORT StorageVirtualImpl<T, VTKM_DEFAULT_STORAGE_TAG>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
StorageVirtualImpl<vtkm::Vec<T, 2>, VTKM_DEFAULT_STORAGE_TAG>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
StorageVirtualImpl<vtkm::Vec<T, 3>, VTKM_DEFAULT_STORAGE_TAG>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
StorageVirtualImpl<vtkm::Vec<T, 4>, VTKM_DEFAULT_STORAGE_TAG>
VTK_M_STORAGE_VIRTUAL_EXPORT(char);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int8);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt8);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int16);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt16);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int32);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt32);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int64);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt64);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Float32);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_STORAGE_VIRTUAL_EXPORT
#endif //!vtk_m_cont_StorageVirtual_cxx
} // namespace detail
template <typename T, typename Device>
struct ArrayTransfer<T, vtkm::cont::StorageTagVirtual, Device> : detail::ArrayTransferVirtual<T>
{
using Superclass = detail::ArrayTransferVirtual<T>;
VTKM_CONT ArrayTransfer(vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>* storage)
: Superclass(storage)
{
}
VTKM_CONT typename Superclass::PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
return this->Superclass::PrepareForInput(Device());
}
VTKM_CONT typename Superclass::PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
{
return this->Superclass::PrepareForOutput(numberOfValues, Device());
}
VTKM_CONT typename Superclass::PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
return this->Superclass::PrepareForInPlace(Device());
}
};
}
}
} // namespace vtkm::cont::internal
#endif // vtk_m_cont_StorageVirtual_hxx

@ -51,23 +51,23 @@ struct Test
void TestConstructors()
{
VirtHandle nullStorage;
VTKM_TEST_ASSERT(nullStorage.GetStorage() == nullptr,
VTKM_TEST_ASSERT(nullStorage.GetStorage().GetStorageVirtual() == nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VirtHandle fromArrayHandle{ ArrayHandle{} };
VTKM_TEST_ASSERT(fromArrayHandle.GetStorage() != nullptr,
VTKM_TEST_ASSERT(fromArrayHandle.GetStorage().GetStorageVirtual() != nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(fromArrayHandle),
"ArrayHandleVirtual should contain a ArrayHandle<ValueType>.");
VirtHandle fromVirtHandle(fromArrayHandle);
VTKM_TEST_ASSERT(fromVirtHandle.GetStorage() != nullptr,
VTKM_TEST_ASSERT(fromVirtHandle.GetStorage().GetStorageVirtual() != nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(fromVirtHandle),
"ArrayHandleVirtual should contain a ArrayHandle<ValueType>.");
VirtHandle fromNullPtrHandle(nullStorage);
VTKM_TEST_ASSERT(fromNullPtrHandle.GetStorage() == nullptr,
VTKM_TEST_ASSERT(fromNullPtrHandle.GetStorage().GetStorageVirtual() == nullptr,
"storage should be empty when constructing from a ArrayHandleVirtual that has "
"nullptr storage.");
VTKM_TEST_ASSERT((vtkm::cont::IsType<ArrayHandle>(fromNullPtrHandle) == false),
@ -77,31 +77,6 @@ struct Test
void TestMoveConstructors()
{
//test shared_ptr move constructor
{
vtkm::cont::ArrayHandleCounting<ValueType> countingHandle;
using ST = typename decltype(countingHandle)::StorageTag;
auto sharedPtr = std::make_shared<vtkm::cont::StorageAny<ValueType, ST>>(countingHandle);
VirtHandle virt(std::move(sharedPtr));
VTKM_TEST_ASSERT(
vtkm::cont::IsType<decltype(countingHandle)>(virt),
"ArrayHandleVirtual should be valid after move constructor shared_ptr<Storage>.");
}
//test unique_ptr move constructor
{
vtkm::cont::ArrayHandleCounting<ValueType> countingHandle;
using ST = typename decltype(countingHandle)::StorageTag;
auto uniquePtr = std::unique_ptr<vtkm::cont::StorageAny<ValueType, ST>>(
new vtkm::cont::StorageAny<ValueType, ST>(countingHandle));
VirtHandle virt(std::move(uniquePtr));
VTKM_TEST_ASSERT(
vtkm::cont::IsType<decltype(countingHandle)>(virt),
"ArrayHandleVirtual should be valid after move constructor unique_ptr<Storage>.");
}
//test ArrayHandle move constructor
{
ArrayHandle handle;