2017-12-12 15:15:20 +00:00
|
|
|
//============================================================================
|
|
|
|
// 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_ArrayHandleVirtualCoordinates_h
|
|
|
|
#define vtk_m_cont_ArrayHandleVirtualCoordinates_h
|
|
|
|
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
2018-06-08 15:56:40 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
2017-12-12 15:15:20 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
2018-07-18 13:11:10 +00:00
|
|
|
#include <vtkm/cont/ErrorBadType.h>
|
2018-08-30 17:29:36 +00:00
|
|
|
#include <vtkm/cont/Logging.h>
|
2018-08-08 18:53:28 +00:00
|
|
|
#include <vtkm/cont/TryExecute.h>
|
2017-12-12 15:15:20 +00:00
|
|
|
#include <vtkm/cont/VirtualObjectHandle.h>
|
|
|
|
#include <vtkm/cont/internal/DynamicTransform.h>
|
|
|
|
|
|
|
|
#include <vtkm/VecTraits.h>
|
|
|
|
#include <vtkm/VirtualObjectBase.h>
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
|
|
|
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesPortalBase : public VirtualObjectBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_EXEC_CONT virtual vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const = 0;
|
|
|
|
VTKM_EXEC_CONT virtual void Set(vtkm::Id i,
|
|
|
|
const vtkm::Vec<vtkm::FloatDefault, 3>& val) const = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename PortalType, typename ValueType>
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl : public CoordinatesPortalBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT CoordinatesPortalImpl() = default;
|
|
|
|
VTKM_CONT explicit CoordinatesPortalImpl(const PortalType& portal)
|
|
|
|
: Portal(portal)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; }
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const override
|
|
|
|
{
|
|
|
|
auto val = this->Portal.Get(i);
|
|
|
|
return { static_cast<vtkm::FloatDefault>(val[0]),
|
|
|
|
static_cast<vtkm::FloatDefault>(val[1]),
|
|
|
|
static_cast<vtkm::FloatDefault>(val[2]) };
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT void Set(vtkm::Id i, const vtkm::Vec<vtkm::FloatDefault, 3>& val) const override
|
|
|
|
{
|
|
|
|
using VecType = typename PortalType::ValueType;
|
|
|
|
using ComponentType = typename vtkm::VecTraits<VecType>::ComponentType;
|
|
|
|
|
|
|
|
this->Portal.Set(i,
|
|
|
|
{ static_cast<ComponentType>(val[0]),
|
|
|
|
static_cast<ComponentType>(val[1]),
|
|
|
|
static_cast<ComponentType>(val[2]) });
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
PortalType Portal;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename PortalType>
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl<PortalType, void*> : public CoordinatesPortalBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT CoordinatesPortalImpl() = default;
|
|
|
|
VTKM_CONT explicit CoordinatesPortalImpl(const PortalType&) {}
|
|
|
|
VTKM_CONT void SetPortal(const PortalType&) {}
|
|
|
|
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id) const override { return {}; }
|
|
|
|
VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec<vtkm::FloatDefault, 3>&) const override {}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename PortalType>
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesPortal
|
|
|
|
: public CoordinatesPortalImpl<PortalType, typename PortalType::ValueType>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT CoordinatesPortal() = default;
|
|
|
|
VTKM_CONT explicit CoordinatesPortal(const PortalType& portal)
|
|
|
|
: CoordinatesPortalImpl<PortalType, typename PortalType::ValueType>(portal)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename PortalType>
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesPortalConst : public CoordinatesPortalBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT CoordinatesPortalConst() = default;
|
|
|
|
VTKM_CONT explicit CoordinatesPortalConst(const PortalType& portal)
|
|
|
|
: Portal(portal)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; }
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const override
|
|
|
|
{
|
|
|
|
auto val = this->Portal.Get(i);
|
|
|
|
return { static_cast<vtkm::FloatDefault>(val[0]),
|
|
|
|
static_cast<vtkm::FloatDefault>(val[1]),
|
|
|
|
static_cast<vtkm::FloatDefault>(val[2]) };
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec<vtkm::FloatDefault, 3>&) const override {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
PortalType Portal;
|
|
|
|
};
|
|
|
|
|
|
|
|
class VTKM_ALWAYS_EXPORT ArrayPortalVirtualCoordinates
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT ArrayPortalVirtualCoordinates()
|
|
|
|
: NumberOfValues(0)
|
|
|
|
, VirtualPortal(nullptr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT ArrayPortalVirtualCoordinates(vtkm::Id numberOfValues,
|
|
|
|
const CoordinatesPortalBase* virtualPortal)
|
|
|
|
: NumberOfValues(numberOfValues)
|
|
|
|
, VirtualPortal(virtualPortal)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT ValueType Get(vtkm::Id i) const { return this->VirtualPortal->Get(i); }
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT void Set(vtkm::Id i, const ValueType& val) const
|
|
|
|
{
|
|
|
|
this->VirtualPortal->Set(i, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
vtkm::Id NumberOfValues;
|
|
|
|
const CoordinatesPortalBase* VirtualPortal;
|
|
|
|
};
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using Portal = ArrayPortalVirtualCoordinates;
|
|
|
|
using PortalConst = ArrayPortalVirtualCoordinates;
|
|
|
|
|
|
|
|
virtual ~CoordinatesArrayHandleBase() = default;
|
|
|
|
|
|
|
|
VTKM_CONT virtual vtkm::Id GetNumberOfValues() const = 0;
|
|
|
|
|
|
|
|
VTKM_CONT virtual Portal GetPortalControl() = 0;
|
|
|
|
VTKM_CONT virtual PortalConst GetPortalConstControl() = 0;
|
|
|
|
VTKM_CONT virtual void Allocate(vtkm::Id numberOfValues) = 0;
|
|
|
|
VTKM_CONT virtual void Shrink(vtkm::Id numberOfValues) = 0;
|
|
|
|
VTKM_CONT virtual void ReleaseResources() = 0;
|
2018-05-24 14:36:23 +00:00
|
|
|
VTKM_CONT virtual void ReleaseResourcesExecution() = 0;
|
2017-12-12 15:15:20 +00:00
|
|
|
|
|
|
|
VTKM_CONT virtual PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) = 0;
|
|
|
|
VTKM_CONT virtual Portal PrepareForOutput(vtkm::Id numberOfValues,
|
|
|
|
vtkm::cont::DeviceAdapterId deviceId) = 0;
|
|
|
|
VTKM_CONT virtual Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleArrayWrapper : public CoordinatesArrayHandleBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_CONT explicit CoordinatesArrayHandleArrayWrapper(const ArrayHandleType& array)
|
|
|
|
: Array(array)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT const ArrayHandleType& GetArray() const { return this->Array; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
ArrayHandleType Array;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename ArrayHandleType, typename DeviceList>
|
|
|
|
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandle
|
|
|
|
: public CoordinatesArrayHandleArrayWrapper<ArrayHandleType>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static_assert(std::is_same<DeviceList, vtkm::cont::DeviceAdapterListTagCommon>::value, "error");
|
|
|
|
|
|
|
|
using Portal = CoordinatesArrayHandleBase::Portal;
|
|
|
|
using PortalConst = CoordinatesArrayHandleBase::PortalConst;
|
|
|
|
|
|
|
|
VTKM_CONT explicit CoordinatesArrayHandle(const ArrayHandleType& array)
|
|
|
|
: CoordinatesArrayHandleArrayWrapper<ArrayHandleType>(array)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); }
|
|
|
|
|
|
|
|
VTKM_CONT Portal GetPortalControl() override
|
|
|
|
{
|
|
|
|
this->ControlPortal.SetPortal(this->Array.GetPortalControl());
|
|
|
|
return Portal(this->GetNumberOfValues(), &this->ControlPortal);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT PortalConst GetPortalConstControl() override
|
|
|
|
{
|
|
|
|
this->ControlConstPortal.SetPortal(this->Array.GetPortalConstControl());
|
|
|
|
return PortalConst(this->GetNumberOfValues(), &this->ControlConstPortal);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT void Allocate(vtkm::Id numberOfValues) override
|
|
|
|
{
|
|
|
|
this->Array.Allocate(numberOfValues);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT void Shrink(vtkm::Id numberOfValues) override { this->Array.Shrink(numberOfValues); }
|
|
|
|
|
|
|
|
VTKM_CONT void ReleaseResources() override { this->Array.ReleaseResources(); }
|
|
|
|
|
2018-05-24 14:36:23 +00:00
|
|
|
VTKM_CONT void ReleaseResourcesExecution() override { this->Array.ReleaseResourcesExecution(); }
|
|
|
|
|
2017-12-12 15:15:20 +00:00
|
|
|
VTKM_CONT PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) override
|
|
|
|
{
|
2018-08-08 18:53:28 +00:00
|
|
|
|
2017-12-12 15:15:20 +00:00
|
|
|
PortalConst portal;
|
2018-08-08 18:53:28 +00:00
|
|
|
bool success = vtkm::cont::TryExecuteOnDevice(
|
|
|
|
deviceId, PrepareForInputFunctor(), DeviceList(), this, portal);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId);
|
|
|
|
}
|
2017-12-12 15:15:20 +00:00
|
|
|
return portal;
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT Portal PrepareForOutput(vtkm::Id numberOfValues,
|
|
|
|
vtkm::cont::DeviceAdapterId deviceId) override
|
|
|
|
{
|
|
|
|
Portal portal;
|
2018-08-08 18:53:28 +00:00
|
|
|
bool success = vtkm::cont::TryExecuteOnDevice(
|
|
|
|
deviceId, PrepareForOutputFunctor(), DeviceList(), this, numberOfValues, portal);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId);
|
|
|
|
}
|
2017-12-12 15:15:20 +00:00
|
|
|
return portal;
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) override
|
|
|
|
{
|
|
|
|
Portal portal;
|
2018-08-08 18:53:28 +00:00
|
|
|
bool success = vtkm::cont::TryExecuteOnDevice(
|
|
|
|
deviceId, PrepareForInPlaceFunctor(), DeviceList(), this, portal);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId);
|
|
|
|
}
|
2017-12-12 15:15:20 +00:00
|
|
|
return portal;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct PrepareForInputFunctor
|
|
|
|
{
|
|
|
|
template <typename DeviceAdapter>
|
2018-08-08 18:53:28 +00:00
|
|
|
VTKM_CONT bool operator()(DeviceAdapter device,
|
2017-12-12 15:15:20 +00:00
|
|
|
CoordinatesArrayHandle* instance,
|
|
|
|
PortalConst& ret) const
|
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
auto portal = instance->Array.PrepareForInput(device);
|
2017-12-12 15:15:20 +00:00
|
|
|
instance->DevicePortalHandle.Reset(new CoordinatesPortalConst<decltype(portal)>(portal),
|
|
|
|
true,
|
|
|
|
vtkm::ListTagBase<DeviceAdapter>());
|
|
|
|
ret = PortalConst(portal.GetNumberOfValues(),
|
2018-07-25 15:11:05 +00:00
|
|
|
instance->DevicePortalHandle.PrepareForExecution(device));
|
2018-08-08 18:53:28 +00:00
|
|
|
return true;
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrepareForOutputFunctor
|
|
|
|
{
|
|
|
|
template <typename DeviceAdapter>
|
2018-08-08 18:53:28 +00:00
|
|
|
VTKM_CONT bool operator()(DeviceAdapter device,
|
2017-12-12 15:15:20 +00:00
|
|
|
CoordinatesArrayHandle* instance,
|
|
|
|
vtkm::Id numberOfValues,
|
|
|
|
Portal& ret) const
|
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
auto portal = instance->Array.PrepareForOutput(numberOfValues, device);
|
2017-12-12 15:15:20 +00:00
|
|
|
instance->DevicePortalHandle.Reset(
|
|
|
|
new CoordinatesPortal<decltype(portal)>(portal), true, vtkm::ListTagBase<DeviceAdapter>());
|
2018-07-25 15:11:05 +00:00
|
|
|
ret = Portal(numberOfValues, instance->DevicePortalHandle.PrepareForExecution(device));
|
2018-08-08 18:53:28 +00:00
|
|
|
return true;
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrepareForInPlaceFunctor
|
|
|
|
{
|
|
|
|
template <typename DeviceAdapter>
|
2018-08-08 18:53:28 +00:00
|
|
|
VTKM_CONT bool operator()(DeviceAdapter device,
|
2018-07-25 15:11:05 +00:00
|
|
|
CoordinatesArrayHandle* instance,
|
|
|
|
Portal& ret) const
|
2017-12-12 15:15:20 +00:00
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
auto portal = instance->Array.PrepareForInPlace(device);
|
2017-12-12 15:15:20 +00:00
|
|
|
instance->DevicePortalHandle.Reset(
|
|
|
|
new CoordinatesPortal<decltype(portal)>(portal), true, vtkm::ListTagBase<DeviceAdapter>());
|
|
|
|
ret = Portal(instance->Array.GetNumberOfValues(),
|
2018-07-25 15:11:05 +00:00
|
|
|
instance->DevicePortalHandle.PrepareForExecution(device));
|
2018-08-08 18:53:28 +00:00
|
|
|
return true;
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
CoordinatesPortal<typename ArrayHandleType::PortalControl> ControlPortal;
|
|
|
|
CoordinatesPortalConst<typename ArrayHandleType::PortalConstControl> ControlConstPortal;
|
|
|
|
vtkm::cont::VirtualObjectHandle<CoordinatesPortalBase> DevicePortalHandle;
|
|
|
|
};
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
struct VTKM_ALWAYS_EXPORT StorageTagVirtualCoordinates
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
2018-09-12 14:51:52 +00:00
|
|
|
class VTKM_ALWAYS_EXPORT Storage<vtkm::Vec<vtkm::FloatDefault, 3>, StorageTagVirtualCoordinates>
|
2017-12-12 15:15:20 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
|
|
|
|
using PortalType = CoordinatesArrayHandleBase::Portal;
|
|
|
|
using PortalConstType = CoordinatesArrayHandleBase::PortalConst;
|
|
|
|
|
|
|
|
VTKM_CONT Storage() = default;
|
|
|
|
|
|
|
|
template <typename ArrayHandleType, typename DeviceList>
|
|
|
|
VTKM_CONT explicit Storage(const ArrayHandleType& array, DeviceList)
|
|
|
|
: Array(new CoordinatesArrayHandle<ArrayHandleType, DeviceList>(array))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT PortalType GetPortal() { return this->Array->GetPortalControl(); }
|
|
|
|
|
|
|
|
VTKM_CONT PortalConstType GetPortalConst() const { return this->Array->GetPortalConstControl(); }
|
|
|
|
|
|
|
|
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); }
|
|
|
|
|
|
|
|
VTKM_CONT void Allocate(vtkm::Id numberOfValues) { this->Array->Allocate(numberOfValues); }
|
|
|
|
|
|
|
|
VTKM_CONT void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); }
|
|
|
|
|
|
|
|
VTKM_CONT void ReleaseResources() { this->Array->ReleaseResources(); }
|
|
|
|
|
|
|
|
VTKM_CONT CoordinatesArrayHandleBase* GetVirtualArray() const { return this->Array.get(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::shared_ptr<CoordinatesArrayHandleBase> Array;
|
|
|
|
};
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
template <typename DeviceAdapter>
|
2018-09-12 14:51:52 +00:00
|
|
|
class VTKM_ALWAYS_EXPORT
|
|
|
|
ArrayTransfer<vtkm::Vec<vtkm::FloatDefault, 3>, StorageTagVirtualCoordinates, DeviceAdapter>
|
2017-12-12 15:15:20 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
|
|
|
|
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTagVirtualCoordinates>;
|
|
|
|
|
|
|
|
using PortalControl = typename StorageType::PortalType;
|
|
|
|
using PortalConstControl = typename StorageType::PortalConstType;
|
|
|
|
using PortalExecution = CoordinatesArrayHandleBase::Portal;
|
|
|
|
using PortalConstExecution = CoordinatesArrayHandleBase::PortalConst;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
ArrayTransfer(StorageType* storage)
|
|
|
|
: Array(storage->GetVirtualArray())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); }
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
PortalConstExecution PrepareForInput(bool)
|
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
return this->Array->PrepareForInput(DeviceAdapter());
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
PortalExecution PrepareForInPlace(bool)
|
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
return this->Array->PrepareForInPlace(DeviceAdapter());
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
|
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
return this->Array->PrepareForOutput(numberOfValues, DeviceAdapter());
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
void RetrieveOutputData(StorageType*) const
|
|
|
|
{
|
|
|
|
// Implementation of this method should be unnecessary.
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); }
|
|
|
|
|
2018-05-24 14:36:23 +00:00
|
|
|
// ArrayTransfer should only be capable of releasing resources in the execution
|
|
|
|
// environment
|
2017-12-12 15:15:20 +00:00
|
|
|
VTKM_CONT
|
2018-05-24 14:36:23 +00:00
|
|
|
void ReleaseResources() { this->Array->ReleaseResourcesExecution(); }
|
2017-12-12 15:15:20 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
CoordinatesArrayHandleBase* Array;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // internal
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates
|
|
|
|
: public ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>, internal::StorageTagVirtualCoordinates>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTKM_ARRAY_HANDLE_SUBCLASS_NT(
|
|
|
|
ArrayHandleVirtualCoordinates,
|
|
|
|
(ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>, internal::StorageTagVirtualCoordinates>));
|
|
|
|
|
|
|
|
template <typename StorageTag, typename DeviceList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
|
|
|
explicit ArrayHandleVirtualCoordinates(
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>, StorageTag>& array,
|
|
|
|
DeviceList devices = DeviceList())
|
|
|
|
: Superclass(typename Superclass::StorageType(array, devices))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename StorageTag, typename DeviceList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
|
|
|
|
explicit ArrayHandleVirtualCoordinates(
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>, StorageTag>& array,
|
|
|
|
DeviceList devices = DeviceList())
|
|
|
|
: Superclass(typename Superclass::StorageType(array, devices))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
2018-01-25 16:02:52 +00:00
|
|
|
bool IsType() const
|
2017-12-12 15:15:20 +00:00
|
|
|
{
|
|
|
|
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
bool IsSameType(const ArrayHandleType&) const
|
|
|
|
{
|
|
|
|
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
const ArrayHandleType Cast() const
|
|
|
|
{
|
|
|
|
auto wrapper = this->GetArrayHandleWrapper<ArrayHandleType>();
|
|
|
|
if (!wrapper)
|
|
|
|
{
|
2018-08-30 17:29:36 +00:00
|
|
|
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
|
2017-12-12 15:15:20 +00:00
|
|
|
throw vtkm::cont::ErrorBadType("dynamic cast failed");
|
|
|
|
}
|
2018-08-30 17:29:36 +00:00
|
|
|
VTKM_LOG_CAST_SUCC(*this, wrapper->GetArray());
|
2017-12-12 15:15:20 +00:00
|
|
|
return ArrayHandleType(wrapper->GetArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
struct WrapperType
|
|
|
|
{
|
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
|
|
|
|
|
|
|
using ValueType = typename ArrayHandleType::ValueType;
|
|
|
|
using StorageTag = typename ArrayHandleType::StorageTag;
|
|
|
|
using BaseArrayHandleType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
|
|
|
|
using Type = internal::CoordinatesArrayHandleArrayWrapper<BaseArrayHandleType>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
VTKM_CONT const typename WrapperType<ArrayHandleType>::Type* GetArrayHandleWrapper() const
|
|
|
|
{
|
|
|
|
auto va = this->GetStorage().GetVirtualArray();
|
|
|
|
return dynamic_cast<const typename WrapperType<ArrayHandleType>::Type*>(va);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Functor, typename... Args>
|
|
|
|
void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
|
|
|
|
Functor&& f,
|
|
|
|
Args&&... args)
|
|
|
|
{
|
2018-01-25 16:02:52 +00:00
|
|
|
if (coords.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
|
2017-12-12 15:15:20 +00:00
|
|
|
{
|
|
|
|
f(coords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>(), std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
f(coords, std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Functor, typename... Args>
|
|
|
|
void CastAndCall(const typename vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& coords,
|
|
|
|
Functor&& f,
|
|
|
|
Args&&... args)
|
|
|
|
{
|
|
|
|
CastAndCall(static_cast<const vtkm::cont::ArrayHandleVirtualCoordinates&>(coords),
|
|
|
|
std::forward<Functor>(f),
|
|
|
|
std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // vtkm::cont
|
|
|
|
|
|
|
|
#ifdef VTKM_CUDA
|
|
|
|
|
|
|
|
// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer
|
2018-06-14 20:49:11 +00:00
|
|
|
// to be instantiated in a consistent order among all the translation units of an
|
2017-12-12 15:15:20 +00:00
|
|
|
// executable. Failing to do so results in random crashes and incorrect results.
|
|
|
|
// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for
|
|
|
|
// all the portal types here.
|
|
|
|
|
|
|
|
#include <vtkm/cont/cuda/internal/VirtualObjectTransferCuda.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
2018-05-23 19:45:26 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
2017-12-12 15:15:20 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
|
|
|
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
|
|
|
struct CudaPortalTypes
|
|
|
|
{
|
|
|
|
using PortalConst = typename ArrayHandleType::template ExecutionTypes<
|
|
|
|
vtkm::cont::DeviceAdapterTagCuda>::PortalConst;
|
|
|
|
using Portal =
|
|
|
|
typename ArrayHandleType::template ExecutionTypes<vtkm::cont::DeviceAdapterTagCuda>::Portal;
|
|
|
|
};
|
|
|
|
|
|
|
|
using CudaPortalsBasicF32 = CudaPortalTypes<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>;
|
|
|
|
using CudaPortalsBasicF64 = CudaPortalTypes<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>>>;
|
|
|
|
using CudaPortalsUniformPointCoordinates =
|
|
|
|
CudaPortalTypes<vtkm::cont::ArrayHandleUniformPointCoordinates>;
|
|
|
|
using CudaPortalsRectilinearCoords = CudaPortalTypes<
|
|
|
|
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>;
|
2018-05-23 19:45:26 +00:00
|
|
|
using CudaPortalsCompositeCoords = CudaPortalTypes<
|
|
|
|
vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>;
|
2017-12-12 15:15:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // vtkm::cont::internal
|
|
|
|
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst<
|
|
|
|
vtkm::cont::internal::CudaPortalsBasicF32::PortalConst>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
|
|
|
vtkm::cont::internal::CoordinatesPortal<vtkm::cont::internal::CudaPortalsBasicF32::Portal>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst<
|
|
|
|
vtkm::cont::internal::CudaPortalsBasicF64::PortalConst>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
|
|
|
vtkm::cont::internal::CoordinatesPortal<vtkm::cont::internal::CudaPortalsBasicF64::Portal>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
|
|
|
vtkm::cont::internal::CoordinatesPortalConst<
|
|
|
|
vtkm::cont::internal::CudaPortalsUniformPointCoordinates::PortalConst>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
|
|
|
vtkm::cont::internal::CoordinatesPortal<
|
|
|
|
vtkm::cont::internal::CudaPortalsUniformPointCoordinates::Portal>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
|
|
|
vtkm::cont::internal::CoordinatesPortalConst<
|
|
|
|
vtkm::cont::internal::CudaPortalsRectilinearCoords::PortalConst>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal<
|
|
|
|
vtkm::cont::internal::CudaPortalsRectilinearCoords::Portal>);
|
2018-05-23 19:45:26 +00:00
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
|
|
|
|
vtkm::cont::internal::CoordinatesPortalConst<
|
|
|
|
vtkm::cont::internal::CudaPortalsCompositeCoords::PortalConst>);
|
|
|
|
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal<
|
|
|
|
vtkm::cont::internal::CudaPortalsCompositeCoords::Portal>);
|
2017-12-12 15:15:20 +00:00
|
|
|
|
|
|
|
#endif // VTKM_CUDA
|
|
|
|
|
2018-06-08 15:56:40 +00:00
|
|
|
//=============================================================================
|
|
|
|
// Specializations of serialization related classes
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
|
|
|
|
{
|
|
|
|
static VTKM_CONT const std::string Get() { return "AH_VirtualCoordinates"; }
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct TypeString<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>,
|
|
|
|
vtkm::cont::internal::StorageTagVirtualCoordinates>>
|
|
|
|
: TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} // vtkm::cont
|
|
|
|
|
|
|
|
namespace diy
|
|
|
|
{
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct Serialization<vtkm::cont::ArrayHandleVirtualCoordinates>
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
using Type = vtkm::cont::ArrayHandleVirtualCoordinates;
|
|
|
|
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
|
|
|
|
|
|
|
using BasicCoordsType = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>>;
|
|
|
|
using RectilinearCoordsArrayType =
|
|
|
|
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
|
|
|
{
|
|
|
|
const auto& virtArray = static_cast<const vtkm::cont::ArrayHandleVirtualCoordinates&>(obj);
|
|
|
|
if (virtArray.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
|
|
|
|
{
|
|
|
|
auto array = virtArray.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
|
|
|
|
diy::save(bb, vtkm::cont::TypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>::Get());
|
|
|
|
diy::save(bb, array);
|
|
|
|
}
|
|
|
|
else if (virtArray.IsType<RectilinearCoordsArrayType>())
|
|
|
|
{
|
|
|
|
auto array = virtArray.Cast<RectilinearCoordsArrayType>();
|
|
|
|
diy::save(bb, vtkm::cont::TypeString<RectilinearCoordsArrayType>::Get());
|
|
|
|
diy::save(bb, array);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
diy::save(bb, vtkm::cont::TypeString<BasicCoordsType>::Get());
|
|
|
|
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, virtArray);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
|
|
|
{
|
|
|
|
std::string typeString;
|
|
|
|
diy::load(bb, typeString);
|
|
|
|
|
|
|
|
if (typeString == vtkm::cont::TypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>::Get())
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandleUniformPointCoordinates array;
|
|
|
|
diy::load(bb, array);
|
|
|
|
obj = vtkm::cont::ArrayHandleVirtualCoordinates(array);
|
|
|
|
}
|
|
|
|
else if (typeString == vtkm::cont::TypeString<RectilinearCoordsArrayType>::Get())
|
|
|
|
{
|
|
|
|
RectilinearCoordsArrayType array;
|
|
|
|
diy::load(bb, array);
|
|
|
|
obj = vtkm::cont::ArrayHandleVirtualCoordinates(array);
|
|
|
|
}
|
|
|
|
else if (typeString == vtkm::cont::TypeString<BasicCoordsType>::Get())
|
|
|
|
{
|
|
|
|
BasicCoordsType array;
|
|
|
|
diy::load(bb, array);
|
|
|
|
obj = vtkm::cont::ArrayHandleVirtualCoordinates(array);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadType(
|
|
|
|
"Error deserializing ArrayHandleVirtualCoordinates. TypeString: " + typeString);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct Serialization<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>,
|
|
|
|
vtkm::cont::internal::StorageTagVirtualCoordinates>>
|
|
|
|
: Serialization<vtkm::cont::ArrayHandleVirtualCoordinates>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
} // diy
|
|
|
|
|
2017-12-12 15:15:20 +00:00
|
|
|
#endif // vtk_m_cont_ArrayHandleVirtualCoordinates_h
|