mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Simplify ArrayHandleSwizzle
As we update the `ArrayHandle`s to the new buffer style, simplify `ArrayHandleSwizzle` by implementing it on top of `ArrayHandleTransform`. Also, introduce some C++11 template concepts to handle variable arguments better. In this conversion, some features have been removed. Previously if the swizzle dropped some components, you were still allowed to write to the array. This would be an in place write that would only update the passed components. This feature has been removed and if any components are dropped, the array becomes read only. If all components are swizzled, then the array becomes writable (through templating). Another lost feature is that the swizzle map is no longer checked for correctness. The array handle just assumes that the indices are correct. It should be noted that it does not look like `ArrayHandleSwizzle` is actually used anywhere. If it is not used by any customers, we may want to consider deprecating the class.
This commit is contained in:
parent
2b6c0df780
commit
35ca89531c
@ -10,365 +10,202 @@
|
||||
#ifndef vtk_m_cont_ArrayHandleSwizzle_h
|
||||
#define vtk_m_cont_ArrayHandleSwizzle_h
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkmstd/integer_sequence.h>
|
||||
|
||||
#include <sstream>
|
||||
namespace vtkm
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
class SwizzleFunctor
|
||||
{
|
||||
using InTraits = vtkm::VecTraits<InType>;
|
||||
using InComponentType = typename InTraits::ComponentType;
|
||||
static constexpr vtkm::IdComponent NUM_IN_COMPONENTS = InTraits::NUM_COMPONENTS;
|
||||
|
||||
using OutTraits = vtkm::VecTraits<OutType>;
|
||||
using OutComponentType = typename OutTraits::ComponentType;
|
||||
static constexpr vtkm::IdComponent NUM_OUT_COMPONENTS = OutTraits::NUM_COMPONENTS;
|
||||
|
||||
template <vtkm::IdComponent... Is>
|
||||
using IndexSequence = vtkmstd::integer_sequence<vtkm::IdComponent, Is...>;
|
||||
using IndexList = vtkmstd::make_integer_sequence<vtkm::IdComponent, NUM_OUT_COMPONENTS>;
|
||||
|
||||
public:
|
||||
using MapType = vtkm::Vec<vtkm::IdComponent, NUM_OUT_COMPONENTS>;
|
||||
|
||||
VTKM_CONT SwizzleFunctor(const MapType& map)
|
||||
: Map(map)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT SwizzleFunctor() = default;
|
||||
|
||||
VTKM_EXEC_CONT OutType operator()(const InType& vec) const
|
||||
{
|
||||
return this->Swizzle(vec, IndexList{});
|
||||
}
|
||||
|
||||
VTKM_CONT static MapType InitMap() { return IndexListAsMap(IndexList{}); }
|
||||
|
||||
private:
|
||||
template <vtkm::IdComponent... Is>
|
||||
VTKM_CONT static MapType IndexListAsMap(IndexSequence<Is...>)
|
||||
{
|
||||
return { Is... };
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent... Is>
|
||||
VTKM_EXEC_CONT OutType Swizzle(const InType& vec, IndexSequence<Is...>) const
|
||||
{
|
||||
return { InTraits::GetComponent(vec, this->Map[Is])... };
|
||||
}
|
||||
|
||||
MapType Map = InitMap();
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename InType, typename OutType, typename Invertible>
|
||||
struct GetInverseSwizzleImpl;
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct GetInverseSwizzleImpl<InType, OutType, std::true_type>
|
||||
{
|
||||
using Type = vtkm::internal::SwizzleFunctor<OutType, InType>;
|
||||
template <typename ForwardMapType>
|
||||
VTKM_CONT static Type Value(const ForwardMapType& forwardMap)
|
||||
{
|
||||
// Note that when reversing the map, if the forwardMap repeats any indices, then
|
||||
// the map is not 1:1 and is not invertible. We cannot check that at compile time.
|
||||
// In this case, results can become unpredictible.
|
||||
using InverseMapType = typename Type::MapType;
|
||||
InverseMapType inverseMap = Type::InitMap();
|
||||
for (vtkm::IdComponent inIndex = 0; inIndex < ForwardMapType::NUM_COMPONENTS; ++inIndex)
|
||||
{
|
||||
inverseMap[forwardMap[inIndex]] = inIndex;
|
||||
}
|
||||
|
||||
return Type(inverseMap);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
struct GetInverseSwizzleImpl<InType, OutType, std::false_type>
|
||||
{
|
||||
using Type = vtkm::cont::internal::NullFunctorType;
|
||||
template <typename ForwardMapType>
|
||||
VTKM_CONT static Type Value(const ForwardMapType&)
|
||||
{
|
||||
return Type{};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
using SwizzleInvertible = std::integral_constant<bool,
|
||||
vtkm::VecTraits<InType>::NUM_COMPONENTS ==
|
||||
vtkm::VecTraits<OutType>::NUM_COMPONENTS>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
VTKM_CONT vtkm::internal::SwizzleFunctor<InType, OutType> GetSwizzleFunctor(
|
||||
const typename vtkm::internal::SwizzleFunctor<InType, OutType>::MapType& forwardMap)
|
||||
{
|
||||
return vtkm::internal::SwizzleFunctor<InType, OutType>(forwardMap);
|
||||
}
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
using InverseSwizzleType = typename detail::
|
||||
GetInverseSwizzleImpl<InType, OutType, detail::SwizzleInvertible<InType, OutType>>::Type;
|
||||
|
||||
template <typename InType, typename OutType>
|
||||
VTKM_CONT InverseSwizzleType<InType, OutType> GetInverseSwizzleFunctor(
|
||||
const typename vtkm::internal::SwizzleFunctor<InType, OutType>::MapType& forwardMap)
|
||||
{
|
||||
return detail::
|
||||
GetInverseSwizzleImpl<InType, OutType, detail::SwizzleInvertible<InType, OutType>>::Value(
|
||||
forwardMap);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::internal
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename InVecType, vtkm::IdComponent OutVecSize>
|
||||
struct ResizeVectorType
|
||||
namespace detail
|
||||
{
|
||||
private:
|
||||
using ComponentType = typename vtkm::VecTraits<InVecType>::ComponentType;
|
||||
|
||||
public:
|
||||
using Type = vtkm::Vec<ComponentType, OutVecSize>;
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutVecSize>
|
||||
class StorageTagSwizzle
|
||||
{
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutputSize>
|
||||
struct ArrayHandleSwizzleTraits;
|
||||
|
||||
template <typename V, vtkm::IdComponent C, typename S, vtkm::IdComponent OutSize>
|
||||
struct ArrayHandleSwizzleTraits<vtkm::cont::ArrayHandle<vtkm::Vec<V, C>, S>, OutSize>
|
||||
{
|
||||
using ComponentType = V;
|
||||
static constexpr vtkm::IdComponent InVecSize = C;
|
||||
static constexpr vtkm::IdComponent OutVecSize = OutSize;
|
||||
|
||||
VTKM_STATIC_ASSERT(OutVecSize <= InVecSize);
|
||||
static constexpr bool AllCompsUsed = (InVecSize == OutVecSize);
|
||||
|
||||
using InValueType = vtkm::Vec<ComponentType, InVecSize>;
|
||||
using OutValueType = vtkm::Vec<ComponentType, OutVecSize>;
|
||||
|
||||
using InStorageTag = S;
|
||||
using InArrayHandleType = vtkm::cont::ArrayHandle<InValueType, InStorageTag>;
|
||||
|
||||
using OutStorageTag = vtkm::cont::StorageTagSwizzle<InArrayHandleType, OutVecSize>;
|
||||
using OutArrayHandleType = vtkm::cont::ArrayHandle<OutValueType, OutStorageTag>;
|
||||
|
||||
using InStorageType = vtkm::cont::internal::Storage<InValueType, InStorageTag>;
|
||||
using OutStorageType = vtkm::cont::internal::Storage<OutValueType, OutStorageTag>;
|
||||
|
||||
using MapType = vtkm::Vec<vtkm::IdComponent, OutVecSize>;
|
||||
|
||||
VTKM_CONT
|
||||
static void ValidateMap(const MapType& map)
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < OutVecSize; ++i)
|
||||
{
|
||||
if (map[i] < 0 || map[i] >= InVecSize)
|
||||
{
|
||||
std::ostringstream error;
|
||||
error << "Invalid swizzle map: Element " << i << " (" << map[i]
|
||||
<< ") outside valid range [0, " << InVecSize << ").";
|
||||
throw vtkm::cont::ErrorBadValue(error.str());
|
||||
}
|
||||
for (vtkm::IdComponent j = i + 1; j < OutVecSize; ++j)
|
||||
{
|
||||
if (map[i] == map[j])
|
||||
{
|
||||
std::ostringstream error;
|
||||
error << "Invalid swizzle map: Repeated element (" << map[i] << ")"
|
||||
<< " at indices " << i << " and " << j << ".";
|
||||
throw vtkm::cont::ErrorBadValue(error.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
static void Swizzle(const InValueType& in, OutValueType& out, const MapType& map)
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < OutSize; ++i)
|
||||
{
|
||||
out[i] = in[map[i]];
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
static void UnSwizzle(const OutValueType& out, InValueType& in, const MapType& map)
|
||||
{
|
||||
for (vtkm::IdComponent i = 0; i < OutSize; ++i)
|
||||
{
|
||||
in[map[i]] = out[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PortalType, typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalSwizzle
|
||||
{
|
||||
using Traits = internal::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
using Writable = vtkm::internal::PortalSupportsSets<PortalType>;
|
||||
|
||||
public:
|
||||
using MapType = typename Traits::MapType;
|
||||
using ValueType = typename Traits::OutValueType;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalSwizzle()
|
||||
: Portal()
|
||||
, Map()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalSwizzle(const PortalType& portal, const MapType& map)
|
||||
: Portal(portal)
|
||||
, Map(map)
|
||||
{
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
VTKM_EXEC_CONT ArrayPortalSwizzle(const ArrayPortalSwizzle& src)
|
||||
: Portal(src.GetPortal())
|
||||
, Map(src.GetMap())
|
||||
{
|
||||
}
|
||||
|
||||
ArrayPortalSwizzle& operator=(const ArrayPortalSwizzle& src) = default;
|
||||
ArrayPortalSwizzle& operator=(ArrayPortalSwizzle&& src) = default;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues(); }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ValueType Get(vtkm::Id index) const
|
||||
{
|
||||
ValueType result;
|
||||
Traits::Swizzle(this->Portal.Get(index), result, this->Map);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
if (Traits::AllCompsUsed)
|
||||
{ // No need to prefetch the value, all values overwritten
|
||||
typename Traits::InValueType tmp;
|
||||
Traits::UnSwizzle(value, tmp, this->Map);
|
||||
this->Portal.Set(index, tmp);
|
||||
}
|
||||
else
|
||||
{ // Not all values used -- need to initialize the vector
|
||||
typename Traits::InValueType tmp = this->Portal.Get(index);
|
||||
Traits::UnSwizzle(value, tmp, this->Map);
|
||||
this->Portal.Set(index, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const PortalType& GetPortal() const { return this->Portal; }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const MapType& GetMap() const { return this->Map; }
|
||||
|
||||
private:
|
||||
PortalType Portal;
|
||||
MapType Map;
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
class Storage<typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>>
|
||||
struct ArrayHandleSwizzleTraits
|
||||
{
|
||||
using Traits = internal::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
|
||||
public:
|
||||
using PortalType =
|
||||
ArrayPortalSwizzle<typename ArrayHandleType::WritePortalType, ArrayHandleType, OutSize>;
|
||||
using PortalConstType =
|
||||
ArrayPortalSwizzle<typename ArrayHandleType::ReadPortalType, ArrayHandleType, OutSize>;
|
||||
using MapType = typename Traits::MapType;
|
||||
using ValueType = typename Traits::OutValueType;
|
||||
using InType = typename ArrayHandleType::ValueType;
|
||||
using OutType = vtkm::Vec<typename vtkm::VecTraits<InType>::ComponentType, OutSize>;
|
||||
using SwizzleFunctor = vtkm::internal::SwizzleFunctor<InType, OutType>;
|
||||
using InverseSwizzleFunctor = vtkm::internal::InverseSwizzleType<InType, OutType>;
|
||||
using MapType = typename SwizzleFunctor::MapType;
|
||||
|
||||
VTKM_CONT
|
||||
Storage()
|
||||
: Valid(false)
|
||||
static SwizzleFunctor GetFunctor(const MapType& forwardMap)
|
||||
{
|
||||
return vtkm::internal::GetSwizzleFunctor<InType, OutType>(forwardMap);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
Storage(const ArrayHandleType& array, const MapType& map)
|
||||
: Array(array)
|
||||
, Map(map)
|
||||
, Valid(true)
|
||||
static InverseSwizzleFunctor GetInverseFunctor(const MapType& forwardMap)
|
||||
{
|
||||
Traits::ValidateMap(this->Map);
|
||||
return vtkm::internal::GetInverseSwizzleFunctor<InType, OutType>(forwardMap);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalConstType GetPortalConst() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return PortalConstType(this->Array.ReadPortal(), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalType GetPortal()
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return PortalType(this->Array.WritePortal(), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfValues() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->Array.GetNumberOfValues();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Allocate(vtkm::Id numberOfValues)
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
this->Array.Allocate(numberOfValues);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Shrink(vtkm::Id numberOfValues)
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
this->Array.Shrink(numberOfValues);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void ReleaseResources()
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
this->Array.ReleaseResources();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const ArrayHandleType& GetArray() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->Array;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const MapType& GetMap() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->Map;
|
||||
}
|
||||
|
||||
private:
|
||||
ArrayHandleType Array;
|
||||
MapType Map;
|
||||
bool Valid;
|
||||
using Superclass =
|
||||
vtkm::cont::ArrayHandleTransform<ArrayHandleType, SwizzleFunctor, InverseSwizzleFunctor>;
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize, typename DeviceTag>
|
||||
class ArrayTransfer<typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>,
|
||||
DeviceTag>
|
||||
{
|
||||
using InExecTypes = typename ArrayHandleType::template ExecutionTypes<DeviceTag>;
|
||||
using Traits = ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
using StorageType = typename Traits::OutStorageType;
|
||||
using MapType = typename Traits::MapType;
|
||||
|
||||
template <typename InPortalT>
|
||||
using OutExecType = ArrayPortalSwizzle<InPortalT, ArrayHandleType, OutSize>;
|
||||
|
||||
public:
|
||||
using ValueType = typename Traits::OutValueType;
|
||||
using PortalControl = typename StorageType::PortalType;
|
||||
using PortalConstControl = typename StorageType::PortalConstType;
|
||||
using PortalExecution = OutExecType<typename InExecTypes::Portal>;
|
||||
using PortalConstExecution = OutExecType<typename InExecTypes::PortalConst>;
|
||||
|
||||
VTKM_CONT
|
||||
ArrayTransfer(StorageType* storage)
|
||||
: Array(storage->GetArray())
|
||||
, Map(storage->GetMap())
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
|
||||
|
||||
VTKM_CONT
|
||||
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
|
||||
{
|
||||
return PortalConstExecution(this->Array.PrepareForInput(DeviceTag(), token), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token)
|
||||
{
|
||||
return PortalExecution(this->Array.PrepareForInPlace(DeviceTag(), token), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token)
|
||||
{
|
||||
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, DeviceTag(), token),
|
||||
this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
|
||||
{
|
||||
// Implementation of this method should be unnecessary. The internal
|
||||
// array handle should automatically retrieve the output data as
|
||||
// necessary.
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Shrink(vtkm::Id numberOfValues) { this->Array.Shrink(numberOfValues); }
|
||||
|
||||
VTKM_CONT
|
||||
void ReleaseResources() { this->Array.ReleaseResourcesExecution(); }
|
||||
|
||||
|
||||
private:
|
||||
ArrayHandleType Array;
|
||||
MapType Map;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Swizzle the components of the values in an `ArrayHandle`.
|
||||
///
|
||||
/// Given an `ArrayHandle` with `Vec` values, `ArrayHandleSwizzle` allows you to
|
||||
/// reorder the components of all the `Vec` values. This reordering is done in place,
|
||||
/// so the array does not have to be duplicated.
|
||||
///
|
||||
/// The resulting array does not have to contain all of the components of the input.
|
||||
/// For example, you could use `ArrayHandleSwizzle` to drop one of the components of
|
||||
/// each vector. However, if you do that, then the swizzled array is read-only. If
|
||||
/// there is a 1:1 map from input components to output components, writing to the
|
||||
/// array will be enabled.
|
||||
///
|
||||
/// The swizzle map given to `ArrayHandleSwizzle` must comprise valid component indices
|
||||
/// (between 0 and number of components - 1). Also, the component indices should not
|
||||
/// be repeated, particularly if you expect to write to the array. These conditions are
|
||||
/// not checked.
|
||||
///
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
class ArrayHandleSwizzle
|
||||
: public ArrayHandle<
|
||||
typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>>
|
||||
: public detail::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>::Superclass
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
|
||||
using Traits = detail::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
|
||||
public:
|
||||
using SwizzleTraits = internal::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
using StorageType = typename SwizzleTraits::OutStorageType;
|
||||
using MapType = typename SwizzleTraits::MapType;
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleSwizzle,
|
||||
(ArrayHandleSwizzle<ArrayHandleType, OutSize>),
|
||||
(typename Traits::Superclass));
|
||||
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(
|
||||
ArrayHandleSwizzle,
|
||||
(ArrayHandleSwizzle<ArrayHandleType, OutSize>),
|
||||
(ArrayHandle<typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>>));
|
||||
using MapType = typename Traits::MapType;
|
||||
|
||||
VTKM_CONT
|
||||
ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map)
|
||||
: Superclass(StorageType(array, map))
|
||||
VTKM_CONT ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map)
|
||||
: Superclass(array, Traits::GetFunctor(map), Traits::GetInverseFunctor(map))
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -400,22 +237,20 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename AH, vtkm::IdComponent NComps>
|
||||
struct SerializableTypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
|
||||
template <typename InType, typename OutType>
|
||||
struct SerializableTypeString<vtkm::internal::SwizzleFunctor<InType, OutType>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_Swizzle<" + SerializableTypeString<AH>::Get() + "," + std::to_string(NComps) + ">";
|
||||
static std::string name = "Swizzle<" + SerializableTypeString<InType>::Get() + "," +
|
||||
SerializableTypeString<OutType>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH, vtkm::IdComponent NComps>
|
||||
struct SerializableTypeString<vtkm::cont::ArrayHandle<
|
||||
vtkm::Vec<typename vtkm::VecTraits<typename AH::ValueType>::ComponentType, NComps>,
|
||||
vtkm::cont::StorageTagSwizzle<AH, NComps>>>
|
||||
: SerializableTypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
|
||||
struct SerializableTypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
|
||||
: SerializableTypeString<typename vtkm::cont::ArrayHandleSwizzle<AH, NComps>::Superclass>
|
||||
{
|
||||
};
|
||||
}
|
||||
@ -426,34 +261,7 @@ namespace mangled_diy_namespace
|
||||
|
||||
template <typename AH, vtkm::IdComponent NComps>
|
||||
struct Serialization<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleSwizzle<AH, NComps>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
auto storage = obj.GetStorage();
|
||||
vtkmdiy::save(bb, storage.GetArray());
|
||||
vtkmdiy::save(bb, storage.GetMap());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
AH array;
|
||||
vtkmdiy::load(bb, array);
|
||||
vtkm::Vec<vtkm::IdComponent, NComps> map;
|
||||
vtkmdiy::load(bb, map);
|
||||
obj = vtkm::cont::make_ArrayHandleSwizzle(array, map);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH, vtkm::IdComponent NComps>
|
||||
struct Serialization<vtkm::cont::ArrayHandle<
|
||||
vtkm::Vec<typename vtkm::VecTraits<typename AH::ValueType>::ComponentType, NComps>,
|
||||
vtkm::cont::StorageTagSwizzle<AH, NComps>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
|
||||
: Serialization<typename vtkm::cont::ArrayHandleSwizzle<AH, NComps>::Superclass>
|
||||
{
|
||||
};
|
||||
|
||||
|
@ -662,7 +662,9 @@ private:
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
ArrayHandleTransform(const ArrayHandleType& handle, const FunctorType& functor = FunctorType())
|
||||
ArrayHandleTransform(const ArrayHandleType& handle,
|
||||
const FunctorType& functor = FunctorType{},
|
||||
internal::NullFunctorType = internal::NullFunctorType{})
|
||||
: Superclass(StorageType(handle, functor))
|
||||
{
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ namespace
|
||||
template <typename ValueType>
|
||||
struct SwizzleTests
|
||||
{
|
||||
using SwizzleInputArrayType = vtkm::cont::ArrayHandle<vtkm::Vec<ValueType, 4>>;
|
||||
static constexpr vtkm::IdComponent InSize = 4;
|
||||
using SwizzleInputArrayType = vtkm::cont::ArrayHandle<vtkm::Vec<ValueType, InSize>>;
|
||||
|
||||
template <vtkm::IdComponent OutSize>
|
||||
using SwizzleArrayType = vtkm::cont::ArrayHandleSwizzle<SwizzleInputArrayType, OutSize>;
|
||||
@ -69,20 +70,6 @@ struct SwizzleTests
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void SanityCheck(const MapType<OutSize>& map) const
|
||||
{
|
||||
using Swizzle = SwizzleArrayType<OutSize>;
|
||||
using Traits = typename Swizzle::SwizzleTraits;
|
||||
|
||||
VTKM_TEST_ASSERT(Traits::OutVecSize ==
|
||||
vtkm::VecTraits<typename Swizzle::ValueType>::NUM_COMPONENTS,
|
||||
"Traits::OutVecSize invalid.");
|
||||
VTKM_TEST_ASSERT(
|
||||
VTKM_PASS_COMMAS(std::is_same<typename Traits::ComponentType, ValueType>::value),
|
||||
"Traits::ComponentType invalid.");
|
||||
VTKM_TEST_ASSERT(
|
||||
VTKM_PASS_COMMAS(
|
||||
std::is_same<typename Traits::OutValueType, vtkm::Vec<ValueType, OutSize>>::value),
|
||||
"Traits::OutValueType invalid.");
|
||||
|
||||
SwizzleInputArrayType input = this->BuildSwizzleInputArray();
|
||||
auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map);
|
||||
|
||||
@ -93,8 +80,6 @@ struct SwizzleTests
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void ReadTest(const MapType<OutSize>& map) const
|
||||
{
|
||||
using Traits = typename SwizzleArrayType<OutSize>::SwizzleTraits;
|
||||
|
||||
// Test that the expected values are read from an Swizzle array.
|
||||
SwizzleInputArrayType input = this->BuildSwizzleInputArray();
|
||||
auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map);
|
||||
@ -103,7 +88,7 @@ struct SwizzleTests
|
||||
this->ValidateReadTest(swizzle, map);
|
||||
|
||||
// Copy the extracted array in the execution environment to test reading:
|
||||
vtkm::cont::ArrayHandle<typename Traits::OutValueType> execCopy;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<ValueType, OutSize>> execCopy;
|
||||
Algo::Copy(swizzle, execCopy);
|
||||
this->ValidateReadTest(execCopy, map);
|
||||
}
|
||||
@ -111,9 +96,8 @@ struct SwizzleTests
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
void ValidateReadTest(ArrayHandleType testArray, const MapType<OutSize>& map) const
|
||||
{
|
||||
using Traits = typename SwizzleArrayType<OutSize>::SwizzleTraits;
|
||||
using ReferenceVectorType = typename ReferenceArrayType::ValueType;
|
||||
using SwizzleVectorType = typename Traits::OutValueType;
|
||||
using SwizzleVectorType = vtkm::Vec<ValueType, OutSize>;
|
||||
|
||||
VTKM_TEST_ASSERT(map.GetNumberOfComponents() ==
|
||||
vtkm::VecTraits<SwizzleVectorType>::NUM_COMPONENTS,
|
||||
@ -171,7 +155,7 @@ struct SwizzleTests
|
||||
|
||||
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void WriteTest(const MapType<OutSize>& map) const
|
||||
void WriteTest(const MapType<OutSize>& map, std::true_type) const
|
||||
{
|
||||
// Control test:
|
||||
{
|
||||
@ -201,6 +185,18 @@ struct SwizzleTests
|
||||
}
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void WriteTest(const MapType<OutSize>&, std::false_type) const
|
||||
{
|
||||
// Array is not writable
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void WriteTest(const MapType<OutSize>& map) const
|
||||
{
|
||||
this->WriteTest(map, std::integral_constant<bool, OutSize == InSize>{});
|
||||
}
|
||||
|
||||
// Check that the swizzled components are twice the reference value.
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void ValidateWriteTestArray(SwizzleInputArrayType testArray, const MapType<OutSize>& map) const
|
||||
@ -318,59 +314,9 @@ void TestArrayHandleSwizzle()
|
||||
vtkm::testing::Testing::TryTypes(ArgToTemplateType(), TestTypes());
|
||||
}
|
||||
|
||||
void TestComponentMapValidator()
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id4> dummy;
|
||||
|
||||
// Repeat components:
|
||||
bool error = false;
|
||||
try
|
||||
{
|
||||
vtkm::cont::make_ArrayHandleSwizzle(dummy, 0, 1, 2, 1);
|
||||
error = true;
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadValue& e)
|
||||
{
|
||||
std::cout << "Caught expected exception 1: " << e.what() << "\n";
|
||||
}
|
||||
VTKM_TEST_ASSERT(!error, "Repeat components allowed.");
|
||||
|
||||
try
|
||||
{
|
||||
vtkm::cont::make_ArrayHandleSwizzle(dummy, 0, 1, 2, -1);
|
||||
error = true;
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadValue& e)
|
||||
{
|
||||
std::cout << "Caught expected exception 2: " << e.what() << "\n";
|
||||
}
|
||||
VTKM_TEST_ASSERT(!error, "Negative components allowed.");
|
||||
|
||||
try
|
||||
{
|
||||
vtkm::cont::make_ArrayHandleSwizzle(dummy, 0, 1, 2, 5);
|
||||
error = true;
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadValue& e)
|
||||
{
|
||||
std::cout << "Caught expected exception 3: " << e.what() << "\n";
|
||||
}
|
||||
VTKM_TEST_ASSERT(!error, "Invalid component allowed.");
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
|
||||
int UnitTestArrayHandleSwizzle(int argc, char* argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
TestComponentMapValidator();
|
||||
}
|
||||
catch (vtkm::cont::Error& e)
|
||||
{
|
||||
std::cerr << "Error: " << e.what() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return vtkm::cont::testing::Testing::Run(TestArrayHandleSwizzle, argc, argv);
|
||||
}
|
||||
|
@ -336,6 +336,22 @@ struct TestArrayHandleReverse
|
||||
}
|
||||
};
|
||||
|
||||
struct TestArrayHandleSwizzle
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(T) const
|
||||
{
|
||||
constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<T>::NUM_COMPONENTS;
|
||||
vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> map;
|
||||
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
|
||||
{
|
||||
map[i] = NUM_COMPONENTS - (i + 1);
|
||||
}
|
||||
auto array = vtkm::cont::make_ArrayHandleSwizzle(RandomArrayHandle<T>::Make(ArraySize), map);
|
||||
RunTest(array);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates MakeRandomArrayHandleUniformPointCoordinates()
|
||||
{
|
||||
@ -393,6 +409,9 @@ void TestArrayHandleSerialization()
|
||||
std::cout << "Testing ArrayHandleReverse\n";
|
||||
vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList());
|
||||
|
||||
std::cout << "Testing ArrayHandleSwizzle\n";
|
||||
vtkm::testing::Testing::TryTypes(TestArrayHandleSwizzle(), TestTypesList());
|
||||
|
||||
std::cout << "Testing ArrayHandleUniformPointCoordinates\n";
|
||||
TestArrayHandleUniformPointCoordinates();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user