Commit 90223b39 authored by Robert Maynard's avatar Robert Maynard

Add ArrayHandleAny to vtkm::cont

parent 6e1cbaa1
//============================================================================
// 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_ArrayHandleAny_h
#define vtk_m_cont_ArrayHandleAny_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/VecTraits.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
namespace vtkm
{
namespace cont
{
template <typename T, typename S>
class VTKM_ALWAYS_EXPORT StorageAny final : public vtkm::cont::StorageVirtual
{
public:
VTKM_CONT
StorageAny(const vtkm::cont::ArrayHandle<T, S>& ah);
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:
// StorageAny is meant to be seamless when it comes to IsType so we will match
// when either the type_info is 'StorageAny<T,S>' or 'Storage<T,S>'. That is why
// we need to override the default implementation.
bool IsSameType(const std::type_info& other) const
{
//We don't wan to check just 'S' as that just the tag
using ST = typename vtkm::cont::internal::Storage<T, S>;
return other == typeid(ST) || other == typeid(*this);
}
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,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId);
vtkm::cont::ArrayHandle<T, S> Handle;
};
/// ArrayHandleAny is a specialization of ArrayHandle.
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayHandleAny final : public vtkm::cont::ArrayHandleVirtual<T>
{
public:
template <typename S>
VTKM_CONT ArrayHandleAny(const vtkm::cont::ArrayHandle<T, S>& ah)
: vtkm::cont::ArrayHandleVirtual<T>(std::make_shared<StorageAny<T, S>>(ah))
{
}
~ArrayHandleAny() = default;
};
/// A convenience function for creating an ArrayHandleAny.
template <typename T>
VTKM_CONT vtkm::cont::ArrayHandleAny<T> make_ArrayHandleAny(const vtkm::cont::ArrayHandle<T>& ah)
{
return vtkm::cont::ArrayHandleAny<T>(ah);
}
template <typename Functor, typename... Args>
void CastAndCall(vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>> coords,
Functor&& f,
Args&&... args)
{
using HandleType = ArrayHandleUniformPointCoordinates;
using T = typename HandleType::ValueType;
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)...);
}
else
{
f(coords, std::forward<Args>(args)...);
}
}
}
} //namespace vtkm::cont
#endif //vtk_m_cont_ArrayHandleAny_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_ArrayHandleAny_hxx
#define vtk_m_cont_ArrayHandleAny_hxx
#include <vtkm/cont/ArrayHandleAny.h>
#include <vtkm/cont/ArrayHandleVirtual.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)
{
}
/// 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) const
{
auto portal = handle.PrepareForOutput(numberOfValues, 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::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
vtkm::cont::TryExecuteOnDevice(
devId, detail::PortalWrapperToDevice(), this->Handle, numberOfValues, payload);
}
}
} // namespace vtkm::cont
#endif //vtk_m_cont_ArrayHandleAny_hxx
......@@ -22,6 +22,7 @@ set(headers
Algorithm.h
ArrayCopy.h
ArrayHandle.h
ArrayHandleAny.h
ArrayHandleCast.h
ArrayHandleCartesianProduct.h
ArrayHandleCompositeVector.h
......@@ -111,6 +112,7 @@ set(headers
set(template_sources
ArrayHandle.hxx
ArrayHandleAny.hxx
ArrayHandleVirtual.hxx
ArrayRangeCompute.hxx
BoundingIntervalHierarchy.hxx
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment