Commit 0b32831a authored by Kenneth Moreland's avatar Kenneth Moreland

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.
parent 03fc3d51
# 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.
This diff is collapsed.
......@@ -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,18 +30,20 @@ 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
......@@ -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,37 +43,13 @@ 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>()
{
}
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>()
template <typename T, typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<T, S>& ah)
: Superclass(vtkm::cont::make_ArrayHandleCast<ValueType>(ah))
{
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);
}
};
......@@ -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
......
//============================================================================
// 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
//============================================================================
// 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
......@@ -27,11 +27,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 +40,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 +48,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 +57,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 +66,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::ReleaseResourcesExecution()
{
this->DeviceTransferState->releaseDevice();
this->DeviceUpToDate = false;
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
void StorageVirtual::ReleaseResources()
{
this->DeviceTransferState->releaseAll();
this->HostUpToDate = false;
......@@ -88,15 +86,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 +118,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 +143,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 +168,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 +183,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,22 +196,20 @@ 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)
......@@ -227,3 +219,4 @@ void Storage<void, ::vtkm::cont::StorageTagVirtual>::TransferPortalForOutput(
}
}
}
}
......@@ -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,18 +42,20 @@ 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).
......@@ -111,7 +114,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
......@@ -159,8 +162,7 @@ private:
// 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 +183,118 @@ 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);
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 { return this->Handle.GetNumberOfValues(); }
void ReleaseResourcesExecution();
void ReleaseResources();
private:
std::unique_ptr<vtkm::cont::internal::detail::StorageVirtual> MakeNewInstance() const
{
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;
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;
};
} // namespace detail
template <typename T>
class Storage<T, vtkm::cont::StorageTagVirtual>
{
public:
using ValueType = T;
using PortalType = vtkm::ArrayPortalRef<T>;
using PortalConstType = vtkm::ArrayPortalRef<T>;
Storage() = default;
using StorageVirtual = internal::Storage<void, vtkm::cont::StorageTagVirtual>;
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()),