mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Make Swizzle and ExtractComponent array parameters runtime vars.
This commit is contained in:
parent
193447078f
commit
3159b376b3
@ -32,7 +32,7 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename PortalType, vtkm::IdComponent Component>
|
||||
template <typename PortalType>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalExtractComponent
|
||||
{
|
||||
public:
|
||||
@ -40,24 +40,24 @@ public:
|
||||
using Traits = vtkm::VecTraits<VectorType>;
|
||||
using ValueType = typename Traits::ComponentType;
|
||||
|
||||
static constexpr vtkm::IdComponent COMPONENT = Component;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalExtractComponent()
|
||||
: Portal()
|
||||
, Component(0)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalExtractComponent(const PortalType& portal)
|
||||
ArrayPortalExtractComponent(const PortalType& portal, vtkm::IdComponent component)
|
||||
: Portal(portal)
|
||||
, Component(component)
|
||||
{
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
VTKM_EXEC_CONT ArrayPortalExtractComponent(
|
||||
const ArrayPortalExtractComponent<PortalType, Component>& src)
|
||||
: Portal(src.GetPortal())
|
||||
VTKM_EXEC_CONT ArrayPortalExtractComponent(const ArrayPortalExtractComponent<PortalType>& src)
|
||||
: Portal(src.Portal)
|
||||
, Component(src.Component)
|
||||
{
|
||||
}
|
||||
|
||||
@ -67,14 +67,14 @@ public:
|
||||
VTKM_EXEC_CONT
|
||||
ValueType Get(vtkm::Id index) const
|
||||
{
|
||||
return Traits::GetComponent(this->Portal.Get(index), Component);
|
||||
return Traits::GetComponent(this->Portal.Get(index), this->Component);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
VectorType vec = this->Portal.Get(index);
|
||||
Traits::SetComponent(vec, Component, value);
|
||||
Traits::SetComponent(vec, this->Component, value);
|
||||
this->Portal.Set(index, vec);
|
||||
}
|
||||
|
||||
@ -83,39 +83,40 @@ public:
|
||||
|
||||
private:
|
||||
PortalType Portal;
|
||||
vtkm::IdComponent Component;
|
||||
}; // class ArrayPortalExtractComponent
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent Component>
|
||||
template <typename ArrayHandleType>
|
||||
class StorageTagExtractComponent
|
||||
{
|
||||
static constexpr vtkm::IdComponent COMPONENT = Component;
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent Component>
|
||||
template <typename ArrayHandleType>
|
||||
class Storage<typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType,
|
||||
StorageTagExtractComponent<ArrayHandleType, Component>>
|
||||
StorageTagExtractComponent<ArrayHandleType>>
|
||||
{
|
||||
public:
|
||||
using PortalType =
|
||||
ArrayPortalExtractComponent<typename ArrayHandleType::PortalControl, Component>;
|
||||
using PortalConstType =
|
||||
ArrayPortalExtractComponent<typename ArrayHandleType::PortalConstControl, Component>;
|
||||
using PortalType = ArrayPortalExtractComponent<typename ArrayHandleType::PortalControl>;
|
||||
using PortalConstType = ArrayPortalExtractComponent<typename ArrayHandleType::PortalConstControl>;
|
||||
using ValueType = typename PortalType::ValueType;
|
||||
|
||||
VTKM_CONT
|
||||
Storage()
|
||||
: Valid(false)
|
||||
: Array()
|
||||
, Component(0)
|
||||
, Valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
Storage(const ArrayHandleType& array)
|
||||
Storage(const ArrayHandleType& array, vtkm::IdComponent component)
|
||||
: Array(array)
|
||||
, Component(component)
|
||||
, Valid(true)
|
||||
{
|
||||
}
|
||||
@ -124,14 +125,14 @@ public:
|
||||
PortalConstType GetPortalConst() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return PortalConstType(this->Array.GetPortalConstControl());
|
||||
return PortalConstType(this->Array.GetPortalConstControl(), this->Component);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalType GetPortal()
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return PortalType(this->Array.GetPortalControl());
|
||||
return PortalType(this->Array.GetPortalControl(), this->Component);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -169,21 +170,29 @@ public:
|
||||
return this->Array;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::IdComponent GetComponent() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->Component;
|
||||
}
|
||||
|
||||
private:
|
||||
ArrayHandleType Array;
|
||||
vtkm::IdComponent Component;
|
||||
bool Valid;
|
||||
}; // class Storage
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent Component, typename Device>
|
||||
template <typename ArrayHandleType, typename Device>
|
||||
class ArrayTransfer<typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType,
|
||||
StorageTagExtractComponent<ArrayHandleType, Component>,
|
||||
StorageTagExtractComponent<ArrayHandleType>,
|
||||
Device>
|
||||
{
|
||||
public:
|
||||
using ValueType = typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType;
|
||||
|
||||
private:
|
||||
using StorageTag = StorageTagExtractComponent<ArrayHandleType, Component>;
|
||||
using StorageTag = StorageTagExtractComponent<ArrayHandleType>;
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
using ArrayValueType = typename ArrayHandleType::ValueType;
|
||||
using ArrayStorageTag = typename ArrayHandleType::StorageTag;
|
||||
@ -195,13 +204,13 @@ public:
|
||||
using PortalConstControl = typename StorageType::PortalConstType;
|
||||
|
||||
using ExecutionTypes = typename ArrayHandleType::template ExecutionTypes<Device>;
|
||||
using PortalExecution = ArrayPortalExtractComponent<typename ExecutionTypes::Portal, Component>;
|
||||
using PortalConstExecution =
|
||||
ArrayPortalExtractComponent<typename ExecutionTypes::PortalConst, Component>;
|
||||
using PortalExecution = ArrayPortalExtractComponent<typename ExecutionTypes::Portal>;
|
||||
using PortalConstExecution = ArrayPortalExtractComponent<typename ExecutionTypes::PortalConst>;
|
||||
|
||||
VTKM_CONT
|
||||
ArrayTransfer(StorageType* storage)
|
||||
: Array(storage->GetArray())
|
||||
, Component(storage->GetComponent())
|
||||
{
|
||||
}
|
||||
|
||||
@ -211,19 +220,19 @@ public:
|
||||
VTKM_CONT
|
||||
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return PortalConstExecution(this->Array.PrepareForInput(Device()));
|
||||
return PortalConstExecution(this->Array.PrepareForInput(Device()), this->Component);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return PortalExecution(this->Array.PrepareForInPlace(Device()));
|
||||
return PortalExecution(this->Array.PrepareForInPlace(Device()), this->Component);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
|
||||
{
|
||||
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device()));
|
||||
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device()), this->Component);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -242,6 +251,7 @@ public:
|
||||
|
||||
private:
|
||||
ArrayHandleType Array;
|
||||
vtkm::IdComponent Component;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -263,40 +273,39 @@ namespace cont
|
||||
/// the index array and reads or writes to the specified component, leave all
|
||||
/// other components unmodified. This is done on the fly rather than creating a
|
||||
/// copy of the array.
|
||||
template <typename ArrayHandleType, vtkm::IdComponent Component>
|
||||
template <typename ArrayHandleType>
|
||||
class ArrayHandleExtractComponent
|
||||
: public vtkm::cont::ArrayHandle<
|
||||
typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType,
|
||||
StorageTagExtractComponent<ArrayHandleType, Component>>
|
||||
StorageTagExtractComponent<ArrayHandleType>>
|
||||
{
|
||||
public:
|
||||
static constexpr vtkm::IdComponent COMPONENT = Component;
|
||||
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(
|
||||
ArrayHandleExtractComponent,
|
||||
(ArrayHandleExtractComponent<ArrayHandleType, Component>),
|
||||
(ArrayHandleExtractComponent<ArrayHandleType>),
|
||||
(vtkm::cont::ArrayHandle<
|
||||
typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::ComponentType,
|
||||
StorageTagExtractComponent<ArrayHandleType, Component>>));
|
||||
StorageTagExtractComponent<ArrayHandleType>>));
|
||||
|
||||
protected:
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
ArrayHandleExtractComponent(const ArrayHandleType& array)
|
||||
: Superclass(StorageType(array))
|
||||
ArrayHandleExtractComponent(const ArrayHandleType& array, vtkm::IdComponent component)
|
||||
: Superclass(StorageType(array, component))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// make_ArrayHandleExtractComponent is convenience function to generate an
|
||||
/// ArrayHandleExtractComponent.
|
||||
template <vtkm::IdComponent Component, typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleExtractComponent<ArrayHandleType, Component> make_ArrayHandleExtractComponent(
|
||||
const ArrayHandleType& array)
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleExtractComponent<ArrayHandleType> make_ArrayHandleExtractComponent(
|
||||
const ArrayHandleType& array,
|
||||
vtkm::IdComponent component)
|
||||
{
|
||||
return ArrayHandleExtractComponent<ArrayHandleType, Component>(array);
|
||||
return ArrayHandleExtractComponent<ArrayHandleType>(array, component);
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -22,235 +22,136 @@
|
||||
#ifndef vtk_m_cont_ArrayHandleSwizzle_h
|
||||
#define vtk_m_cont_ArrayHandleSwizzle_h
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
#include <array>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
|
||||
template <typename InVecType, vtkm::IdComponent OutVecSize>
|
||||
struct ResizeVectorType
|
||||
{
|
||||
|
||||
// If TestValue appears more than once in ComponentMap, IsUnique will be false,
|
||||
// but true if TestValue is unique.
|
||||
template <vtkm::IdComponent TestValue, vtkm::IdComponent... ComponentMap>
|
||||
struct ComponentIsUnique;
|
||||
|
||||
// Terminal case:
|
||||
template <vtkm::IdComponent TestValue, vtkm::IdComponent Head>
|
||||
struct ComponentIsUnique<TestValue, Head>
|
||||
{
|
||||
static const bool IsUnique = TestValue != Head;
|
||||
};
|
||||
|
||||
// Recursive case:
|
||||
template <vtkm::IdComponent TestValue, vtkm::IdComponent Head, vtkm::IdComponent... Tail>
|
||||
struct ComponentIsUnique<TestValue, Head, Tail...>
|
||||
{
|
||||
using Next = ComponentIsUnique<TestValue, Tail...>;
|
||||
static const bool IsUnique = TestValue != Head && Next::IsUnique;
|
||||
};
|
||||
|
||||
// Validate the component map.
|
||||
// All elements must be (1) unique, (2) >= 0, and (3) < InputSize
|
||||
template <vtkm::IdComponent InputSize, vtkm::IdComponent... ComponentMap>
|
||||
struct ValidateComponentMap;
|
||||
|
||||
// Terminal impl:
|
||||
template <vtkm::IdComponent InputSize, vtkm::IdComponent Head>
|
||||
struct ValidateComponentMap<InputSize, Head>
|
||||
{
|
||||
static constexpr bool Valid = Head >= 0 && Head < InputSize;
|
||||
};
|
||||
|
||||
// Recursive impl:
|
||||
template <vtkm::IdComponent InputSize, vtkm::IdComponent Head, vtkm::IdComponent... Tail>
|
||||
struct ValidateComponentMap<InputSize, Head, Tail...>
|
||||
{
|
||||
using Next = ValidateComponentMap<InputSize, Tail...>;
|
||||
static constexpr bool IsUnique = ComponentIsUnique<Head, Tail...>::IsUnique;
|
||||
static constexpr bool Valid = Head >= 0 && Head < InputSize && IsUnique && Next::Valid;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/// This class collects metadata for an ArrayHandleSwizzle.
|
||||
template <typename InputValueType, vtkm::IdComponent... ComponentMap>
|
||||
struct ArrayHandleSwizzleTraits
|
||||
{
|
||||
/// The number of elements in the ComponentMap.
|
||||
static constexpr vtkm::IdComponent COUNT =
|
||||
static_cast<vtkm::IdComponent>(sizeof...(ComponentMap));
|
||||
VTKM_STATIC_ASSERT_MSG(COUNT > 0, "Invalid ComponentMap: Cannot swizzle zero components.");
|
||||
|
||||
/// A std::array containing the ComponentMap for runtime querying.
|
||||
using RuntimeComponentMapType = std::array<vtkm::IdComponent, COUNT>;
|
||||
static constexpr RuntimeComponentMapType GenerateRuntimeComponentMap()
|
||||
{
|
||||
return RuntimeComponentMapType{ { ComponentMap... } };
|
||||
}
|
||||
|
||||
/// The ValueType of the ArrayHandleSwizzle's internal ArrayHandle.
|
||||
using InputType = InputValueType;
|
||||
|
||||
/// The VecTraits for InputType.
|
||||
using InputTraits = VecTraits<InputType>;
|
||||
|
||||
using Validator = internal::ValidateComponentMap<InputTraits::NUM_COMPONENTS, ComponentMap...>;
|
||||
VTKM_STATIC_ASSERT_MSG(Validator::Valid,
|
||||
"Invalid ComponentMap: Ids in ComponentMap must be unique, positive, and "
|
||||
"less than the number of input components.");
|
||||
|
||||
/// The ComponentType of the ArrayHandleSwizzle.
|
||||
using ComponentType = typename InputTraits::ComponentType;
|
||||
|
||||
/// The ValueType of the ArrayHandleSwizzle.
|
||||
using OutputType = vtkm::Vec<ComponentType, COUNT>;
|
||||
|
||||
// The VecTraits for OutputType.
|
||||
using OutputTraits = VecTraits<OutputType>;
|
||||
|
||||
/// If true, we use all components in the input vector. If false, we'll need
|
||||
/// to make sure to preserve existing values on write.
|
||||
static constexpr bool ALL_COMPS_USED = InputTraits::NUM_COMPONENTS == COUNT;
|
||||
|
||||
private:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent... Map>
|
||||
struct GetImpl;
|
||||
|
||||
// Terminal case:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head>
|
||||
struct GetImpl<OutputIndex, Head>
|
||||
{
|
||||
constexpr vtkm::IdComponent operator()() const { return OutputIndex == 0 ? Head : -1; }
|
||||
};
|
||||
|
||||
// Recursive case:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head, vtkm::IdComponent... Tail>
|
||||
struct GetImpl<OutputIndex, Head, Tail...>
|
||||
{
|
||||
using Next = GetImpl<OutputIndex - 1, Tail...>;
|
||||
|
||||
constexpr vtkm::IdComponent operator()() const { return OutputIndex == 0 ? Head : Next()(); }
|
||||
};
|
||||
using ComponentType = typename vtkm::VecTraits<InVecType>::ComponentType;
|
||||
|
||||
public:
|
||||
/// Get the component from ComponentMap at the specified index as a
|
||||
/// compile-time constant:
|
||||
template <vtkm::IdComponent OutputIndex>
|
||||
static constexpr vtkm::IdComponent Get()
|
||||
{
|
||||
return GetImpl<OutputIndex, ComponentMap...>()();
|
||||
}
|
||||
using Type = vtkm::Vec<ComponentType, OutVecSize>;
|
||||
};
|
||||
|
||||
private:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent... Map>
|
||||
struct SwizzleImpl;
|
||||
|
||||
// Terminal case:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head>
|
||||
struct SwizzleImpl<OutputIndex, Head>
|
||||
{
|
||||
static constexpr vtkm::IdComponent InputIndex = Head;
|
||||
|
||||
void operator()(const InputType& in, OutputType& out) const
|
||||
{
|
||||
OutputTraits::SetComponent(out, OutputIndex, InputTraits::GetComponent(in, InputIndex));
|
||||
}
|
||||
};
|
||||
|
||||
// Recursive case:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head, vtkm::IdComponent... Tail>
|
||||
struct SwizzleImpl<OutputIndex, Head, Tail...>
|
||||
{
|
||||
using Next = SwizzleImpl<OutputIndex + 1, Tail...>;
|
||||
static constexpr vtkm::IdComponent InputIndex = Head;
|
||||
|
||||
void operator()(const InputType& in, OutputType& out) const
|
||||
{
|
||||
OutputTraits::SetComponent(out, OutputIndex, InputTraits::GetComponent(in, InputIndex));
|
||||
Next()(in, out);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/// Swizzle the input type into the output type.
|
||||
static void Swizzle(const InputType& in, OutputType& out)
|
||||
{
|
||||
SwizzleImpl<0, ComponentMap...>()(in, out);
|
||||
}
|
||||
|
||||
// UnSwizzle output type --> input type
|
||||
private:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent... Map>
|
||||
struct UnSwizzleImpl;
|
||||
|
||||
// Terminal case:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head>
|
||||
struct UnSwizzleImpl<OutputIndex, Head>
|
||||
{
|
||||
static constexpr vtkm::IdComponent InputIndex = Head;
|
||||
|
||||
void operator()(const OutputType& out, InputType& in) const
|
||||
{
|
||||
InputTraits::SetComponent(in, InputIndex, OutputTraits::GetComponent(out, OutputIndex));
|
||||
}
|
||||
};
|
||||
|
||||
// Recursive case:
|
||||
template <vtkm::IdComponent OutputIndex, vtkm::IdComponent Head, vtkm::IdComponent... Tail>
|
||||
struct UnSwizzleImpl<OutputIndex, Head, Tail...>
|
||||
{
|
||||
using Next = UnSwizzleImpl<OutputIndex + 1, Tail...>;
|
||||
static constexpr vtkm::IdComponent InputIndex = Head;
|
||||
|
||||
void operator()(const OutputType& out, InputType& in) const
|
||||
{
|
||||
InputTraits::SetComponent(in, InputIndex, OutputTraits::GetComponent(out, OutputIndex));
|
||||
Next()(out, in);
|
||||
}
|
||||
};
|
||||
|
||||
// Entry point:
|
||||
public:
|
||||
/// Unswizzle the output type back into the input type.
|
||||
/// @warning If the entire vector is not used, there may be uninitialized
|
||||
/// data in the resulting InputType vector. See ALL_COMPS_USED flag.
|
||||
static void UnSwizzle(const OutputType& out, InputType& in)
|
||||
{
|
||||
UnSwizzleImpl<0, ComponentMap...>()(out, in);
|
||||
}
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutVecSize>
|
||||
class StorageTagSwizzle
|
||||
{
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename PortalType, vtkm::IdComponent... ComponentMap>
|
||||
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 = ArrayHandleSwizzleTraits<typename PortalType::ValueType, ComponentMap...>;
|
||||
using Traits = internal::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
|
||||
public:
|
||||
using ValueType = typename Traits::OutputType;
|
||||
using MapType = typename Traits::MapType;
|
||||
using ValueType = typename Traits::OutValueType;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalSwizzle()
|
||||
: Portal()
|
||||
, Map()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArrayPortalSwizzle(const PortalType& portal)
|
||||
ArrayPortalSwizzle(const PortalType& portal, const MapType& map)
|
||||
: Portal(portal)
|
||||
, Map(map)
|
||||
{
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
VTKM_EXEC_CONT ArrayPortalSwizzle(const ArrayPortalSwizzle<PortalType, ComponentMap...>& src)
|
||||
VTKM_EXEC_CONT ArrayPortalSwizzle(const ArrayPortalSwizzle& src)
|
||||
: Portal(src.GetPortal())
|
||||
, Map(src.GetMap())
|
||||
{
|
||||
}
|
||||
|
||||
@ -260,70 +161,52 @@ public:
|
||||
VTKM_EXEC_CONT
|
||||
ValueType Get(vtkm::Id index) const
|
||||
{
|
||||
typename Traits::OutputType result;
|
||||
Traits::Swizzle(this->Portal.Get(index), result);
|
||||
ValueType result;
|
||||
Traits::Swizzle(this->Portal.Get(index), result, this->Map);
|
||||
return result;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
SetImpl<!Traits::ALL_COMPS_USED>(this->Portal)(index, value);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// If NeedsRead is true, we need to initialize the InputType vector we write
|
||||
// with the current values at @a index to avoid overwriting unused components.
|
||||
template <bool NeedsRead>
|
||||
struct SetImpl
|
||||
{
|
||||
const PortalType& Portal;
|
||||
|
||||
SetImpl(const PortalType& portal)
|
||||
: Portal(portal)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const vtkm::Id& index, const ValueType& value)
|
||||
{
|
||||
typename Traits::InputType in;
|
||||
if (NeedsRead)
|
||||
{
|
||||
in = this->Portal.Get(index);
|
||||
}
|
||||
Traits::UnSwizzle(value, in);
|
||||
this->Portal.Set(index, in);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
const PortalType& GetPortal() const { return this->Portal; }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const MapType& GetMap() const { return this->Map; }
|
||||
|
||||
private:
|
||||
PortalType Portal;
|
||||
}; // class ArrayPortalSwizzle
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent... ComponentMap>
|
||||
class StorageTagSwizzle
|
||||
{
|
||||
MapType Map;
|
||||
};
|
||||
|
||||
namespace internal
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
class Storage<typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>>
|
||||
{
|
||||
using Traits = internal::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent... ComponentMap>
|
||||
class Storage<typename ArrayHandleSwizzleTraits<typename ArrayHandleType::ValueType,
|
||||
ComponentMap...>::OutputType,
|
||||
StorageTagSwizzle<ArrayHandleType, ComponentMap...>>
|
||||
{
|
||||
public:
|
||||
using PortalType = ArrayPortalSwizzle<typename ArrayHandleType::PortalControl, ComponentMap...>;
|
||||
using PortalType =
|
||||
ArrayPortalSwizzle<typename ArrayHandleType::PortalControl, ArrayHandleType, OutSize>;
|
||||
using PortalConstType =
|
||||
ArrayPortalSwizzle<typename ArrayHandleType::PortalConstControl, ComponentMap...>;
|
||||
using ValueType = typename PortalType::ValueType;
|
||||
ArrayPortalSwizzle<typename ArrayHandleType::PortalConstControl, ArrayHandleType, OutSize>;
|
||||
using MapType = typename Traits::MapType;
|
||||
using ValueType = typename Traits::OutValueType;
|
||||
|
||||
VTKM_CONT
|
||||
Storage()
|
||||
@ -332,24 +215,26 @@ public:
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
Storage(const ArrayHandleType& array)
|
||||
Storage(const ArrayHandleType& array, const MapType& map)
|
||||
: Array(array)
|
||||
, Map(map)
|
||||
, Valid(true)
|
||||
{
|
||||
Traits::ValidateMap(this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalConstType GetPortalConst() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return PortalConstType(this->Array.GetPortalConstControl());
|
||||
return PortalConstType(this->Array.GetPortalConstControl(), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalType GetPortal()
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return PortalType(this->Array.GetPortalControl());
|
||||
return PortalType(this->Array.GetPortalControl(), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -387,39 +272,43 @@ public:
|
||||
return this->Array;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const MapType& GetMap() const
|
||||
{
|
||||
VTKM_ASSERT(this->Valid);
|
||||
return this->Map;
|
||||
}
|
||||
|
||||
private:
|
||||
ArrayHandleType Array;
|
||||
MapType Map;
|
||||
bool Valid;
|
||||
}; // class Storage
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType, vtkm::IdComponent... ComponentMap, typename Device>
|
||||
class ArrayTransfer<typename ArrayHandleSwizzleTraits<typename ArrayHandleType::ValueType,
|
||||
ComponentMap...>::OutputType,
|
||||
StorageTagSwizzle<ArrayHandleType, ComponentMap...>,
|
||||
Device>
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize, typename DeviceTag>
|
||||
class ArrayTransfer<typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>,
|
||||
DeviceTag>
|
||||
{
|
||||
using ArrayExecutionTypes = typename ArrayHandleType::template ExecutionTypes<Device>;
|
||||
using StorageTag = StorageTagSwizzle<ArrayHandleType, ComponentMap...>;
|
||||
|
||||
public:
|
||||
using SwizzleTraits =
|
||||
ArrayHandleSwizzleTraits<typename ArrayHandleType::ValueType, ComponentMap...>;
|
||||
using ValueType = typename SwizzleTraits::OutputType;
|
||||
|
||||
private:
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
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 = ArrayPortalSwizzle<typename ArrayExecutionTypes::Portal, ComponentMap...>;
|
||||
using PortalConstExecution =
|
||||
ArrayPortalSwizzle<typename ArrayExecutionTypes::PortalConst, ComponentMap...>;
|
||||
using PortalExecution = OutExecType<typename InExecTypes::Portal>;
|
||||
using PortalConstExecution = OutExecType<typename InExecTypes::PortalConst>;
|
||||
|
||||
VTKM_CONT
|
||||
ArrayTransfer(StorageType* storage)
|
||||
: Array(storage->GetArray())
|
||||
, Map(storage->GetMap())
|
||||
{
|
||||
}
|
||||
|
||||
@ -429,19 +318,19 @@ public:
|
||||
VTKM_CONT
|
||||
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return PortalConstExecution(this->Array.PrepareForInput(Device()));
|
||||
return PortalConstExecution(this->Array.PrepareForInput(DeviceTag()), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
|
||||
{
|
||||
return PortalExecution(this->Array.PrepareForInPlace(Device()));
|
||||
return PortalExecution(this->Array.PrepareForInPlace(DeviceTag()), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
|
||||
{
|
||||
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, Device()));
|
||||
return PortalExecution(this->Array.PrepareForOutput(numberOfValues, DeviceTag()), this->Map);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -458,64 +347,44 @@ public:
|
||||
VTKM_CONT
|
||||
void ReleaseResources() { this->Array.ReleaseResourcesExecution(); }
|
||||
|
||||
|
||||
private:
|
||||
ArrayHandleType Array;
|
||||
MapType Map;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::internal
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
} // end namespace internal
|
||||
|
||||
/// \brief A fancy ArrayHandle that rearranges and/or removes components of an
|
||||
/// ArrayHandle with a vtkm::Vec ValueType.
|
||||
///
|
||||
/// ArrayHandleSwizzle is a specialization of ArrayHandle. It takes an
|
||||
/// input ArrayHandle with a vtkm::Vec ValueType and a compile-time component
|
||||
/// map and uses this information to create a new array consisting of the
|
||||
/// specified components of the input ArrayHandle in the specified order. So for
|
||||
/// a given index i, ArrayHandleSwizzle looks up the i-th vtkm::Vec in
|
||||
/// the index array and reads or writes to the specified components, leaving all
|
||||
/// other components unmodified. This is done on the fly rather than creating a
|
||||
/// copy of the array.
|
||||
template <typename ArrayHandleType, vtkm::IdComponent... ComponentMap>
|
||||
class ArrayHandleSwizzle : public vtkm::cont::ArrayHandle<
|
||||
typename ArrayHandleSwizzleTraits<typename ArrayHandleType::ValueType,
|
||||
ComponentMap...>::OutputType,
|
||||
StorageTagSwizzle<ArrayHandleType, ComponentMap...>>
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
class ArrayHandleSwizzle
|
||||
: public ArrayHandle<
|
||||
typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<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, ComponentMap...>),
|
||||
(vtkm::cont::ArrayHandle<typename ArrayHandleSwizzleTraits<typename ArrayHandleType::ValueType,
|
||||
ComponentMap...>::OutputType,
|
||||
StorageTagSwizzle<ArrayHandleType, ComponentMap...>>));
|
||||
(ArrayHandleSwizzle<ArrayHandleType, OutSize>),
|
||||
(ArrayHandle<typename ResizeVectorType<typename ArrayHandleType::ValueType, OutSize>::Type,
|
||||
vtkm::cont::StorageTagSwizzle<ArrayHandleType, OutSize>>));
|
||||
|
||||
using SwizzleTraits =
|
||||
ArrayHandleSwizzleTraits<typename ArrayHandleType::ValueType, ComponentMap...>;
|
||||
|
||||
protected:
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
ArrayHandleSwizzle(const ArrayHandleType& array)
|
||||
: Superclass(StorageType(array))
|
||||
ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map)
|
||||
: Superclass(StorageType(array, map))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// make_ArrayHandleSwizzle is convenience function to generate an
|
||||
/// ArrayHandleSwizzle.
|
||||
template <vtkm::IdComponent... ComponentMap, typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleSwizzle<ArrayHandleType, ComponentMap...> make_ArrayHandleSwizzle(
|
||||
const ArrayHandleType& array)
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
VTKM_CONT ArrayHandleSwizzle<ArrayHandleType, OutSize> make_ArrayHandleSwizzle(
|
||||
const ArrayHandleType& array,
|
||||
const vtkm::Vec<vtkm::IdComponent, OutSize>& map)
|
||||
{
|
||||
return ArrayHandleSwizzle<ArrayHandleType, ComponentMap...>(array);
|
||||
return ArrayHandleSwizzle<ArrayHandleType, OutSize>(array, map);
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -415,7 +415,7 @@ private:
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T, StorageTagBasic> a1;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageTagBasic> tmp;
|
||||
auto a2 = vtkm::cont::make_ArrayHandleExtractComponent<1>(tmp);
|
||||
auto a2 = vtkm::cont::make_ArrayHandleExtractComponent(tmp, 1);
|
||||
|
||||
VTKM_TEST_ASSERT(a1 != a2, "Arrays with different storage type compared equal.");
|
||||
VTKM_TEST_ASSERT(!(a1 == a2), "Arrays with different storage type compared equal.");
|
||||
@ -434,7 +434,7 @@ private:
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T, StorageTagBasic> a1;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<typename OtherType<T>::Type, 3>, StorageTagBasic> tmp;
|
||||
auto a2 = vtkm::cont::make_ArrayHandleExtractComponent<1>(tmp);
|
||||
auto a2 = vtkm::cont::make_ArrayHandleExtractComponent(tmp, 1);
|
||||
|
||||
VTKM_TEST_ASSERT(a1 != a2, "Arrays with different storage and value type compared equal.");
|
||||
VTKM_TEST_ASSERT(!(a1 == a2),
|
||||
|
@ -36,8 +36,7 @@ template <typename ValueType>
|
||||
struct ExtractComponentTests
|
||||
{
|
||||
using InputArray = vtkm::cont::ArrayHandle<vtkm::Vec<ValueType, 4>>;
|
||||
template <vtkm::IdComponent Component>
|
||||
using ExtractArray = vtkm::cont::ArrayHandleExtractComponent<InputArray, Component>;
|
||||
using ExtractArray = vtkm::cont::ArrayHandleExtractComponent<InputArray>;
|
||||
using ReferenceComponentArray = vtkm::cont::ArrayHandleCounting<ValueType>;
|
||||
using ReferenceCompositeArray =
|
||||
typename vtkm::cont::ArrayHandleCompositeVectorType<ReferenceComponentArray,
|
||||
@ -70,36 +69,32 @@ struct ExtractComponentTests
|
||||
return result;
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent Component>
|
||||
void SanityCheck() const
|
||||
void SanityCheck(vtkm::IdComponent component) const
|
||||
{
|
||||
InputArray composite = this->BuildInputArray();
|
||||
ExtractArray<Component> extract =
|
||||
vtkm::cont::make_ArrayHandleExtractComponent<Component>(composite);
|
||||
ExtractArray extract(composite, component);
|
||||
|
||||
VTKM_TEST_ASSERT(composite.GetNumberOfValues() == extract.GetNumberOfValues(),
|
||||
"Number of values in copied ExtractComponent array does not match input.");
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent Component>
|
||||
void ReadTestComponentExtraction() const
|
||||
void ReadTestComponentExtraction(vtkm::IdComponent component) const
|
||||
{
|
||||
// Test that the expected values are read from an ExtractComponent array.
|
||||
InputArray composite = this->BuildInputArray();
|
||||
ExtractArray<Component> extract =
|
||||
vtkm::cont::make_ArrayHandleExtractComponent<Component>(composite);
|
||||
ExtractArray extract(composite, component);
|
||||
|
||||
// Test reading the data back in the control env:
|
||||
this->ValidateReadTestArray<Component>(extract);
|
||||
this->ValidateReadTestArray(extract, component);
|
||||
|
||||
// Copy the extract array in the execution environment to test reading:
|
||||
vtkm::cont::ArrayHandle<ValueType> execCopy;
|
||||
Algo::Copy(extract, execCopy);
|
||||
this->ValidateReadTestArray<Component>(execCopy);
|
||||
this->ValidateReadTestArray(execCopy, component);
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent Component, typename ArrayHandleType>
|
||||
void ValidateReadTestArray(ArrayHandleType testArray) const
|
||||
template <typename ArrayHandleType>
|
||||
void ValidateReadTestArray(ArrayHandleType testArray, vtkm::IdComponent component) const
|
||||
{
|
||||
using RefVectorType = typename ReferenceCompositeArray::ValueType;
|
||||
using Traits = vtkm::VecTraits<RefVectorType>;
|
||||
@ -113,13 +108,13 @@ struct ExtractComponentTests
|
||||
for (vtkm::Id i = 0; i < testPortal.GetNumberOfValues(); ++i)
|
||||
{
|
||||
VTKM_TEST_ASSERT(
|
||||
test_equal(testPortal.Get(i), Traits::GetComponent(refPortal.Get(i), Component), 0.),
|
||||
test_equal(testPortal.Get(i), Traits::GetComponent(refPortal.Get(i), component), 0.),
|
||||
"Value mismatch in read test.");
|
||||
}
|
||||
}
|
||||
|
||||
// Doubles the specified component (reading from RefVectorType).
|
||||
template <typename PortalType, typename RefPortalType, vtkm::IdComponent Component>
|
||||
template <typename PortalType, typename RefPortalType>
|
||||
struct WriteTestFunctor : vtkm::exec::FunctorBase
|
||||
{
|
||||
using RefVectorType = typename RefPortalType::ValueType;
|
||||
@ -127,63 +122,64 @@ struct ExtractComponentTests
|
||||
|
||||
PortalType Portal;
|
||||
RefPortalType RefPortal;
|
||||
vtkm::IdComponent Component;
|
||||
|
||||
VTKM_CONT
|
||||
WriteTestFunctor(const PortalType& portal, const RefPortalType& ref)
|
||||
WriteTestFunctor(const PortalType& portal,
|
||||
const RefPortalType& ref,
|
||||
vtkm::IdComponent component)
|
||||
: Portal(portal)
|
||||
, RefPortal(ref)
|
||||
, Component(component)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void operator()(vtkm::Id index) const
|
||||
{
|
||||
this->Portal.Set(index, Traits::GetComponent(this->RefPortal.Get(index), Component) * 2);
|
||||
this->Portal.Set(index,
|
||||
Traits::GetComponent(this->RefPortal.Get(index), this->Component) * 2);
|
||||
}
|
||||
};
|
||||
|
||||
template <vtkm::IdComponent Component>
|
||||
void WriteTestComponentExtraction() const
|
||||
void WriteTestComponentExtraction(vtkm::IdComponent component) const
|
||||
{
|
||||
// Control test:
|
||||
{
|
||||
InputArray composite = this->BuildInputArray();
|
||||
ExtractArray<Component> extract =
|
||||
vtkm::cont::make_ArrayHandleExtractComponent<Component>(composite);
|
||||
ExtractArray extract(composite, component);
|
||||
|
||||
WriteTestFunctor<typename ExtractArray<Component>::PortalControl,
|
||||
typename ReferenceCompositeArray::PortalConstControl,
|
||||
Component>
|
||||
functor(extract.GetPortalControl(), this->RefComposite.GetPortalConstControl());
|
||||
WriteTestFunctor<typename ExtractArray::PortalControl,
|
||||
typename ReferenceCompositeArray::PortalConstControl>
|
||||
functor(extract.GetPortalControl(), this->RefComposite.GetPortalConstControl(), component);
|
||||
|
||||
for (vtkm::Id i = 0; i < extract.GetNumberOfValues(); ++i)
|
||||
{
|
||||
functor(i);
|
||||
}
|
||||
|
||||
this->ValidateWriteTestArray<Component>(composite);
|
||||
this->ValidateWriteTestArray(composite, component);
|
||||
}
|
||||
|
||||
// Exec test:
|
||||
{
|
||||
InputArray composite = this->BuildInputArray();
|
||||
ExtractArray<Component> extract =
|
||||
vtkm::cont::make_ArrayHandleExtractComponent<Component>(composite);
|
||||
ExtractArray extract(composite, component);
|
||||
|
||||
using Portal = typename ExtractArray<Component>::template ExecutionTypes<DeviceTag>::Portal;
|
||||
using Portal = typename ExtractArray::template ExecutionTypes<DeviceTag>::Portal;
|
||||
using RefPortal =
|
||||
typename ReferenceCompositeArray::template ExecutionTypes<DeviceTag>::PortalConst;
|
||||
|
||||
WriteTestFunctor<Portal, RefPortal, Component> functor(
|
||||
extract.PrepareForInPlace(DeviceTag()), this->RefComposite.PrepareForInput(DeviceTag()));
|
||||
WriteTestFunctor<Portal, RefPortal> functor(extract.PrepareForInPlace(DeviceTag()),
|
||||
this->RefComposite.PrepareForInput(DeviceTag()),
|
||||
component);
|
||||
|
||||
Algo::Schedule(functor, extract.GetNumberOfValues());
|
||||
this->ValidateWriteTestArray<Component>(composite);
|
||||
this->ValidateWriteTestArray(composite, component);
|
||||
}
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent Component>
|
||||
void ValidateWriteTestArray(InputArray testArray) const
|
||||
void ValidateWriteTestArray(InputArray testArray, vtkm::IdComponent component) const
|
||||
{
|
||||
using VectorType = typename ReferenceCompositeArray::ValueType;
|
||||
using Traits = vtkm::VecTraits<VectorType>;
|
||||
@ -199,28 +195,27 @@ struct ExtractComponentTests
|
||||
{
|
||||
auto value = portal.Get(i);
|
||||
auto refValue = refPortal.Get(i);
|
||||
Traits::SetComponent(refValue, Component, Traits::GetComponent(refValue, Component) * 2);
|
||||
Traits::SetComponent(refValue, component, Traits::GetComponent(refValue, component) * 2);
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(refValue, value, 0.), "Value mismatch in write test.");
|
||||
}
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent Component>
|
||||
void TestComponent() const
|
||||
void TestComponent(vtkm::IdComponent component) const
|
||||
{
|
||||
this->SanityCheck<Component>();
|
||||
this->ReadTestComponentExtraction<Component>();
|
||||
this->WriteTestComponentExtraction<Component>();
|
||||
this->SanityCheck(component);
|
||||
this->ReadTestComponentExtraction(component);
|
||||
this->WriteTestComponentExtraction(component);
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
this->ConstructReferenceArray();
|
||||
|
||||
this->TestComponent<0>();
|
||||
this->TestComponent<1>();
|
||||
this->TestComponent<2>();
|
||||
this->TestComponent<3>();
|
||||
this->TestComponent(0);
|
||||
this->TestComponent(1);
|
||||
this->TestComponent(2);
|
||||
this->TestComponent(3);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -39,8 +39,8 @@ struct SwizzleTests
|
||||
{
|
||||
using SwizzleInputArrayType = vtkm::cont::ArrayHandle<vtkm::Vec<ValueType, 4>>;
|
||||
|
||||
template <vtkm::IdComponent... ComponentMap>
|
||||
using SwizzleArrayType = vtkm::cont::ArrayHandleSwizzle<SwizzleInputArrayType, ComponentMap...>;
|
||||
template <vtkm::IdComponent OutSize>
|
||||
using SwizzleArrayType = vtkm::cont::ArrayHandleSwizzle<SwizzleInputArrayType, OutSize>;
|
||||
|
||||
using ReferenceComponentArrayType = vtkm::cont::ArrayHandleCounting<ValueType>;
|
||||
using ReferenceArrayType =
|
||||
@ -49,6 +49,9 @@ struct SwizzleTests
|
||||
ReferenceComponentArrayType,
|
||||
ReferenceComponentArrayType>::type;
|
||||
|
||||
template <vtkm::IdComponent Size>
|
||||
using MapType = vtkm::Vec<vtkm::IdComponent, Size>;
|
||||
|
||||
using DeviceTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
|
||||
using Algo = vtkm::cont::DeviceAdapterAlgorithm<DeviceTag>;
|
||||
|
||||
@ -78,62 +81,57 @@ struct SwizzleTests
|
||||
return result;
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent... ComponentMap>
|
||||
void SanityCheck() const
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void SanityCheck(const MapType<OutSize>& map) const
|
||||
{
|
||||
using Swizzle = SwizzleArrayType<ComponentMap...>;
|
||||
using Swizzle = SwizzleArrayType<OutSize>;
|
||||
using Traits = typename Swizzle::SwizzleTraits;
|
||||
|
||||
VTKM_TEST_ASSERT(Traits::COUNT == vtkm::VecTraits<typename Swizzle::ValueType>::NUM_COMPONENTS,
|
||||
"Traits::COUNT invalid.");
|
||||
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::OutputType,
|
||||
vtkm::Vec<ValueType, static_cast<vtkm::IdComponent>(sizeof...(ComponentMap))>>::value),
|
||||
"Traits::OutputType invalid.");
|
||||
std::is_same<typename Traits::OutValueType, vtkm::Vec<ValueType, OutSize>>::value),
|
||||
"Traits::OutValueType invalid.");
|
||||
|
||||
SwizzleInputArrayType input = this->BuildSwizzleInputArray();
|
||||
SwizzleArrayType<ComponentMap...> swizzle =
|
||||
vtkm::cont::make_ArrayHandleSwizzle<ComponentMap...>(input);
|
||||
auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map);
|
||||
|
||||
VTKM_TEST_ASSERT(input.GetNumberOfValues() == swizzle.GetNumberOfValues(),
|
||||
"Number of values in copied Swizzle array does not match input.");
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent... ComponentMap>
|
||||
void ReadTest() const
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void ReadTest(const MapType<OutSize>& map) const
|
||||
{
|
||||
using Traits = typename SwizzleArrayType<ComponentMap...>::SwizzleTraits;
|
||||
using Traits = typename SwizzleArrayType<OutSize>::SwizzleTraits;
|
||||
|
||||
// Test that the expected values are read from an Swizzle array.
|
||||
SwizzleInputArrayType input = this->BuildSwizzleInputArray();
|
||||
SwizzleArrayType<ComponentMap...> swizzle =
|
||||
vtkm::cont::make_ArrayHandleSwizzle<ComponentMap...>(input);
|
||||
auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map);
|
||||
|
||||
// Test reading the data back in the control env:
|
||||
this->ValidateReadTest<ComponentMap...>(swizzle);
|
||||
this->ValidateReadTest(swizzle, map);
|
||||
|
||||
// Copy the extract array in the execution environment to test reading:
|
||||
vtkm::cont::ArrayHandle<typename Traits::OutputType> execCopy;
|
||||
// Copy the extracted array in the execution environment to test reading:
|
||||
vtkm::cont::ArrayHandle<typename Traits::OutValueType> execCopy;
|
||||
Algo::Copy(swizzle, execCopy);
|
||||
this->ValidateReadTest<ComponentMap...>(execCopy);
|
||||
this->ValidateReadTest(execCopy, map);
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent... ComponentMap, typename ArrayHandleType>
|
||||
void ValidateReadTest(ArrayHandleType testArray) const
|
||||
template <typename ArrayHandleType, vtkm::IdComponent OutSize>
|
||||
void ValidateReadTest(ArrayHandleType testArray, const MapType<OutSize>& map) const
|
||||
{
|
||||
using Traits = typename SwizzleArrayType<ComponentMap...>::SwizzleTraits;
|
||||
using MapType = typename Traits::RuntimeComponentMapType;
|
||||
const MapType map = Traits::GenerateRuntimeComponentMap();
|
||||
|
||||
using Traits = typename SwizzleArrayType<OutSize>::SwizzleTraits;
|
||||
using ReferenceVectorType = typename ReferenceArrayType::ValueType;
|
||||
using SwizzleVectorType = typename Traits::OutputType;
|
||||
using SwizzleVectorType = typename Traits::OutValueType;
|
||||
|
||||
VTKM_TEST_ASSERT(map.size() == vtkm::VecTraits<SwizzleVectorType>::NUM_COMPONENTS,
|
||||
VTKM_TEST_ASSERT(map.GetNumberOfComponents() ==
|
||||
vtkm::VecTraits<SwizzleVectorType>::NUM_COMPONENTS,
|
||||
"Unexpected runtime component map size.");
|
||||
VTKM_TEST_ASSERT(testArray.GetNumberOfValues() == this->RefArray.GetNumberOfValues(),
|
||||
"Number of values incorrect in Read test.");
|
||||
@ -147,9 +145,9 @@ struct SwizzleTests
|
||||
ReferenceVectorType refVec = refPortal.Get(i);
|
||||
|
||||
// Manually swizzle the reference vector using the runtime map information:
|
||||
for (size_t j = 0; j < map.size(); ++j)
|
||||
for (vtkm::IdComponent j = 0; j < map.GetNumberOfComponents(); ++j)
|
||||
{
|
||||
refVecSwizzle[static_cast<vtkm::IdComponent>(j)] = refVec[map[j]];
|
||||
refVecSwizzle[j] = refVec[map[j]];
|
||||
}
|
||||
|
||||
VTKM_TEST_ASSERT(test_equal(refVecSwizzle, testPortal.Get(i), 0.),
|
||||
@ -173,16 +171,15 @@ struct SwizzleTests
|
||||
void operator()(vtkm::Id index) const { this->Portal.Set(index, this->Portal.Get(index) * 2.); }
|
||||
};
|
||||
|
||||
template <vtkm::IdComponent... ComponentMap>
|
||||
void WriteTest() const
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void WriteTest(const MapType<OutSize>& map) const
|
||||
{
|
||||
// Control test:
|
||||
{
|
||||
SwizzleInputArrayType input = this->BuildSwizzleInputArray();
|
||||
SwizzleArrayType<ComponentMap...> swizzle =
|
||||
vtkm::cont::make_ArrayHandleSwizzle<ComponentMap...>(input);
|
||||
auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map);
|
||||
|
||||
WriteTestFunctor<typename SwizzleArrayType<ComponentMap...>::PortalControl> functor(
|
||||
WriteTestFunctor<typename SwizzleArrayType<OutSize>::PortalControl> functor(
|
||||
swizzle.GetPortalControl());
|
||||
|
||||
for (vtkm::Id i = 0; i < swizzle.GetNumberOfValues(); ++i)
|
||||
@ -190,33 +187,27 @@ struct SwizzleTests
|
||||
functor(i);
|
||||
}
|
||||
|
||||
this->ValidateWriteTestArray<ComponentMap...>(input);
|
||||
this->ValidateWriteTestArray(input, map);
|
||||
}
|
||||
|
||||
// Exec test:
|
||||
{
|
||||
SwizzleInputArrayType input = this->BuildSwizzleInputArray();
|
||||
SwizzleArrayType<ComponentMap...> swizzle =
|
||||
vtkm::cont::make_ArrayHandleSwizzle<ComponentMap...>(input);
|
||||
auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map);
|
||||
|
||||
using Portal =
|
||||
typename SwizzleArrayType<ComponentMap...>::template ExecutionTypes<DeviceTag>::Portal;
|
||||
using Portal = typename SwizzleArrayType<OutSize>::template ExecutionTypes<DeviceTag>::Portal;
|
||||
|
||||
WriteTestFunctor<Portal> functor(swizzle.PrepareForInPlace(DeviceTag()));
|
||||
|
||||
Algo::Schedule(functor, swizzle.GetNumberOfValues());
|
||||
this->ValidateWriteTestArray<ComponentMap...>(input);
|
||||
this->ValidateWriteTestArray(input, map);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the swizzled components are twice the reference value.
|
||||
template <vtkm::IdComponent... ComponentMap>
|
||||
void ValidateWriteTestArray(SwizzleInputArrayType testArray) const
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void ValidateWriteTestArray(SwizzleInputArrayType testArray, const MapType<OutSize>& map) const
|
||||
{
|
||||
using Traits = typename SwizzleArrayType<ComponentMap...>::SwizzleTraits;
|
||||
using MapType = typename Traits::RuntimeComponentMapType;
|
||||
const MapType map = Traits::GenerateRuntimeComponentMap();
|
||||
|
||||
auto refPortal = this->RefArray.GetPortalConstControl();
|
||||
auto portal = testArray.GetPortalConstControl();
|
||||
|
||||
@ -230,7 +221,7 @@ struct SwizzleTests
|
||||
|
||||
// Double all of the components that appear in the map to replicate the
|
||||
// test result:
|
||||
for (size_t j = 0; j < map.size(); ++j)
|
||||
for (vtkm::IdComponent j = 0; j < map.GetNumberOfComponents(); ++j)
|
||||
{
|
||||
refValue[map[j]] *= 2;
|
||||
}
|
||||
@ -239,96 +230,78 @@ struct SwizzleTests
|
||||
}
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent... ComponentMap>
|
||||
void TestSwizzle() const
|
||||
template <vtkm::IdComponent OutSize>
|
||||
void TestSwizzle(const MapType<OutSize>& map) const
|
||||
{
|
||||
this->SanityCheck<ComponentMap...>();
|
||||
this->ReadTest<ComponentMap...>();
|
||||
this->WriteTest<ComponentMap...>();
|
||||
this->SanityCheck(map);
|
||||
this->ReadTest(map);
|
||||
this->WriteTest(map);
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
this->ConstructReferenceArray();
|
||||
|
||||
// Enable for full test. We normally test a reduced set of component maps
|
||||
// to keep compile times/sizes down:
|
||||
#if 0
|
||||
this->TestSwizzle<0, 1>();
|
||||
this->TestSwizzle<0, 2>();
|
||||
this->TestSwizzle<0, 3>();
|
||||
this->TestSwizzle<1, 0>();
|
||||
this->TestSwizzle<1, 2>();
|
||||
this->TestSwizzle<1, 3>();
|
||||
this->TestSwizzle<2, 0>();
|
||||
this->TestSwizzle<2, 1>();
|
||||
this->TestSwizzle<2, 3>();
|
||||
this->TestSwizzle<3, 0>();
|
||||
this->TestSwizzle<3, 1>();
|
||||
this->TestSwizzle<3, 2>();
|
||||
this->TestSwizzle<0, 1, 2>();
|
||||
this->TestSwizzle<0, 1, 3>();
|
||||
this->TestSwizzle<0, 2, 1>();
|
||||
this->TestSwizzle<0, 2, 3>();
|
||||
this->TestSwizzle<0, 3, 1>();
|
||||
this->TestSwizzle<0, 3, 2>();
|
||||
this->TestSwizzle<1, 0, 2>();
|
||||
this->TestSwizzle<1, 0, 3>();
|
||||
this->TestSwizzle<1, 2, 0>();
|
||||
this->TestSwizzle<1, 2, 3>();
|
||||
this->TestSwizzle<1, 3, 0>();
|
||||
this->TestSwizzle<1, 3, 2>();
|
||||
this->TestSwizzle<2, 0, 1>();
|
||||
this->TestSwizzle<2, 0, 3>();
|
||||
this->TestSwizzle<2, 1, 0>();
|
||||
this->TestSwizzle<2, 1, 3>();
|
||||
this->TestSwizzle<2, 3, 0>();
|
||||
this->TestSwizzle<2, 3, 1>();
|
||||
this->TestSwizzle<3, 0, 1>();
|
||||
this->TestSwizzle<3, 0, 2>();
|
||||
this->TestSwizzle<3, 1, 0>();
|
||||
this->TestSwizzle<3, 1, 2>();
|
||||
this->TestSwizzle<3, 2, 0>();
|
||||
this->TestSwizzle<3, 2, 1>();
|
||||
this->TestSwizzle<0, 1, 2, 3>();
|
||||
this->TestSwizzle<0, 1, 3, 2>();
|
||||
this->TestSwizzle<0, 2, 1, 3>();
|
||||
this->TestSwizzle<0, 2, 3, 1>();
|
||||
this->TestSwizzle<0, 3, 1, 2>();
|
||||
this->TestSwizzle<0, 3, 2, 1>();
|
||||
this->TestSwizzle<1, 0, 2, 3>();
|
||||
this->TestSwizzle<1, 0, 3, 2>();
|
||||
this->TestSwizzle<1, 2, 0, 3>();
|
||||
this->TestSwizzle<1, 2, 3, 0>();
|
||||
this->TestSwizzle<1, 3, 0, 2>();
|
||||
this->TestSwizzle<1, 3, 2, 0>();
|
||||
this->TestSwizzle<2, 0, 1, 3>();
|
||||
this->TestSwizzle<2, 0, 3, 1>();
|
||||
this->TestSwizzle<2, 1, 0, 3>();
|
||||
this->TestSwizzle<2, 1, 3, 0>();
|
||||
this->TestSwizzle<2, 3, 0, 1>();
|
||||
this->TestSwizzle<2, 3, 1, 0>();
|
||||
this->TestSwizzle<3, 0, 1, 2>();
|
||||
this->TestSwizzle<3, 0, 2, 1>();
|
||||
this->TestSwizzle<3, 1, 0, 2>();
|
||||
this->TestSwizzle<3, 1, 2, 0>();
|
||||
this->TestSwizzle<3, 2, 0, 1>();
|
||||
this->TestSwizzle<3, 2, 1, 0>();
|
||||
#else
|
||||
this->TestSwizzle<0, 1>();
|
||||
this->TestSwizzle<1, 0>();
|
||||
this->TestSwizzle<2, 3>();
|
||||
this->TestSwizzle<3, 2>();
|
||||
this->TestSwizzle<0, 1, 2>();
|
||||
this->TestSwizzle<0, 3, 1>();
|
||||
this->TestSwizzle<2, 0, 3>();
|
||||
this->TestSwizzle<3, 2, 1>();
|
||||
this->TestSwizzle<0, 1, 2, 3>();
|
||||
this->TestSwizzle<1, 3, 2, 0>();
|
||||
this->TestSwizzle<2, 0, 1, 3>();
|
||||
this->TestSwizzle<3, 1, 0, 2>();
|
||||
this->TestSwizzle<3, 2, 1, 0>();
|
||||
#endif
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 1, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 1, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 2, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 2, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 3, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 3, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 0, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 0, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 2, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 2, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 3, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 3, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 0, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 0, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 1, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 1, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 3, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 3, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 0, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 0, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 1, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 1, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 2, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 2, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 1, 2, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 1, 3, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 2, 1, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 2, 3, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 3, 1, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(0, 3, 2, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 0, 2, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 0, 3, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 2, 0, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 2, 3, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 3, 0, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(1, 3, 2, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 0, 1, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 0, 3, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 1, 0, 3));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 1, 3, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 3, 0, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(2, 3, 1, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 0, 1, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 0, 2, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 1, 0, 2));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 1, 2, 0));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 2, 0, 1));
|
||||
this->TestSwizzle(vtkm::make_Vec(3, 2, 1, 0));
|
||||
}
|
||||
};
|
||||
|
||||
@ -347,38 +320,44 @@ void TestArrayHandleSwizzle()
|
||||
vtkm::testing::Testing::TryTypes(ArgToTemplateType(), TestTypes());
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent InputSize, vtkm::IdComponent... ComponentMap>
|
||||
using Validator = vtkm::cont::internal::ValidateComponentMap<InputSize, ComponentMap...>;
|
||||
|
||||
void TestComponentMapValidator()
|
||||
{
|
||||
using RepeatComps = Validator<5, 0, 3, 2, 3, 1, 4>;
|
||||
VTKM_TEST_ASSERT(!RepeatComps::Valid, "Repeat components allowed.");
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> dummy;
|
||||
|
||||
using NegativeComps = Validator<5, 0, 4, -3, 1, 2>;
|
||||
VTKM_TEST_ASSERT(!NegativeComps::Valid, "Negative components allowed.");
|
||||
// Repeat components:
|
||||
bool error = false;
|
||||
try
|
||||
{
|
||||
vtkm::cont::make_ArrayHandleSwizzle(dummy, vtkm::make_Vec(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.");
|
||||
|
||||
using OutOfBoundsComps = Validator<5, 0, 2, 3, 5>;
|
||||
VTKM_TEST_ASSERT(!OutOfBoundsComps::Valid, "Out-of-bounds components allowed.");
|
||||
}
|
||||
try
|
||||
{
|
||||
vtkm::cont::make_ArrayHandleSwizzle(dummy, vtkm::make_Vec(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.");
|
||||
|
||||
void TestRuntimeComponentMapGenerator()
|
||||
{
|
||||
// Dummy input vector type. Only concerned with the component map:
|
||||
using Dummy = vtkm::Vec<char, 7>;
|
||||
|
||||
using Traits = vtkm::cont::ArrayHandleSwizzleTraits<Dummy, 3, 2, 4, 1, 6, 0>;
|
||||
using MapType = Traits::RuntimeComponentMapType;
|
||||
|
||||
const MapType map = Traits::GenerateRuntimeComponentMap();
|
||||
|
||||
VTKM_TEST_ASSERT(map.size() == 6, "Invalid map size.");
|
||||
VTKM_TEST_ASSERT(map[0] == 3, "Invalid map entry.");
|
||||
VTKM_TEST_ASSERT(map[1] == 2, "Invalid map entry.");
|
||||
VTKM_TEST_ASSERT(map[2] == 4, "Invalid map entry.");
|
||||
VTKM_TEST_ASSERT(map[3] == 1, "Invalid map entry.");
|
||||
VTKM_TEST_ASSERT(map[4] == 6, "Invalid map entry.");
|
||||
VTKM_TEST_ASSERT(map[5] == 0, "Invalid map entry.");
|
||||
try
|
||||
{
|
||||
vtkm::cont::make_ArrayHandleSwizzle(dummy, vtkm::make_Vec(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
|
||||
@ -388,7 +367,6 @@ int UnitTestArrayHandleSwizzle(int, char* [])
|
||||
try
|
||||
{
|
||||
TestComponentMapValidator();
|
||||
TestRuntimeComponentMapGenerator();
|
||||
}
|
||||
catch (vtkm::cont::Error& e)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user