mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Created ArrayHandleCompositeVector.
This derived array handle creates an array of vectors whose components come from other arrays of vectors. In either case ArrayHandleCompositeVector handles scalars as vectors of size 1.
This commit is contained in:
parent
3f2099fe76
commit
261157ed22
716
vtkm/cont/ArrayHandleCompositeVector.h
Normal file
716
vtkm/cont/ArrayHandleCompositeVector.h
Normal file
@ -0,0 +1,716 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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_ArrayHandleCompositeVector_h
|
||||||
|
#define vtk_m_ArrayHandleCompositeVector_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/ErrorControlBadValue.h>
|
||||||
|
#include <vtkm/cont/ErrorControlInternal.h>
|
||||||
|
|
||||||
|
#include <vtkm/VectorTraits.h>
|
||||||
|
|
||||||
|
#include <vtkm/internal/FunctionInterface.h>
|
||||||
|
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
struct CompositeVectorSwizzleFunctor
|
||||||
|
{
|
||||||
|
static const int NUM_COMPONENTS =
|
||||||
|
vtkm::VectorTraits<ValueType>::NUM_COMPONENTS;
|
||||||
|
typedef vtkm::Tuple<int, NUM_COMPONENTS> ComponentMapType;
|
||||||
|
|
||||||
|
// Caution! This is a reference.
|
||||||
|
const ComponentMapType &SourceComponents;
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
CompositeVectorSwizzleFunctor(const ComponentMapType &sourceComponents)
|
||||||
|
: SourceComponents(sourceComponents) { }
|
||||||
|
|
||||||
|
// Currently only supporting 1-4 components.
|
||||||
|
template<typename T1>
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ValueType operator()(const T1 &p1) const {
|
||||||
|
return ValueType(
|
||||||
|
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ValueType operator()(const T1 &p1, const T2 &p2) const {
|
||||||
|
return ValueType(
|
||||||
|
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
|
||||||
|
vtkm::VectorTraits<T2>::GetComponent(p2, this->SourceComponents[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3>
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ValueType operator()(const T1 &p1, const T2 &p2, const T3 &p3) const {
|
||||||
|
return ValueType(
|
||||||
|
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
|
||||||
|
vtkm::VectorTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
|
||||||
|
vtkm::VectorTraits<T3>::GetComponent(p3, this->SourceComponents[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4>
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ValueType operator()(const T1 &p1,
|
||||||
|
const T2 &p2,
|
||||||
|
const T3 &p3,
|
||||||
|
const T4 &p4) const {
|
||||||
|
return ValueType(
|
||||||
|
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
|
||||||
|
vtkm::VectorTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
|
||||||
|
vtkm::VectorTraits<T3>::GetComponent(p3, this->SourceComponents[2]),
|
||||||
|
vtkm::VectorTraits<T4>::GetComponent(p4, this->SourceComponents[3]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ReturnValueType>
|
||||||
|
struct CompositeVectorPullValueFunctor
|
||||||
|
{
|
||||||
|
vtkm::Id Index;
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
CompositeVectorPullValueFunctor(vtkm::Id index) : Index(index) { }
|
||||||
|
|
||||||
|
// This form is to pull values out of array arguments.
|
||||||
|
template<typename PortalType>
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
typename PortalType::ValueType operator()(const PortalType &portal) const {
|
||||||
|
return portal.Get(this->Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This form is an identity to pass the return value back.
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
const ReturnValueType &operator()(const ReturnValueType &value) const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompositeVectorArrayToPortalCont {
|
||||||
|
template<typename ArrayHandleType>
|
||||||
|
struct ReturnType {
|
||||||
|
typedef typename ArrayHandleType::PortalConstControl type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ArrayHandleType>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
typename ReturnType<ArrayHandleType>::type
|
||||||
|
operator()(const ArrayHandleType &array) const {
|
||||||
|
return array.GetPortalConstControl();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DeviceAdapterTag>
|
||||||
|
struct CompositeVectorArrayToPortalExec {
|
||||||
|
template<typename ArrayHandleType>
|
||||||
|
struct ReturnType {
|
||||||
|
typedef typename ArrayHandleType::template ExecutionTypes<
|
||||||
|
DeviceAdapterTag>::PortalConst type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ArrayHandleType>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
typename ReturnType<ArrayHandleType>::type
|
||||||
|
operator()(const ArrayHandleType &array) const {
|
||||||
|
return array.PrepareForInput(DeviceAdapterTag());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CheckArraySizeFunctor {
|
||||||
|
vtkm::Id ExpectedSize;
|
||||||
|
CheckArraySizeFunctor(vtkm::Id expectedSize) : ExpectedSize(expectedSize) { }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void operator()(const T &a) const {
|
||||||
|
if (a.GetNumberOfValues() != this->ExpectedSize)
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"All input arrays to ArrayHandleCompositeVector must be the same size.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// \brief A portal that gets values from components of other portals.
|
||||||
|
///
|
||||||
|
/// This is the portal used within ArrayHandleCompositeVector.
|
||||||
|
///
|
||||||
|
template<typename SignatureWithPortals>
|
||||||
|
class ArrayPortalCompositeVector
|
||||||
|
{
|
||||||
|
typedef vtkm::internal::FunctionInterface<SignatureWithPortals> PortalTypes;
|
||||||
|
typedef vtkm::Tuple<int, PortalTypes::ARITY> ComponentMapType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename PortalTypes::ResultType ValueType;
|
||||||
|
static const int NUM_COMPONENTS =
|
||||||
|
vtkm::VectorTraits<ValueType>::NUM_COMPONENTS;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(NUM_COMPONENTS == PortalTypes::ARITY);
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ArrayPortalCompositeVector() { }
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayPortalCompositeVector(
|
||||||
|
const PortalTypes portals,
|
||||||
|
vtkm::Tuple<int, NUM_COMPONENTS> sourceComponents)
|
||||||
|
: Portals(portals), SourceComponents(sourceComponents) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
vtkm::Id GetNumberOfValues() const {
|
||||||
|
return this->Portals.template GetParameter<1>().GetNumberOfValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
ValueType Get(vtkm::Id index) const {
|
||||||
|
// This might be inefficient because we are copying all the portals only
|
||||||
|
// because they are coupled with the return value.
|
||||||
|
PortalTypes localPortals = this->Portals;
|
||||||
|
localPortals.InvokeExec(
|
||||||
|
detail::CompositeVectorSwizzleFunctor<ValueType>(this->SourceComponents),
|
||||||
|
detail::CompositeVectorPullValueFunctor<ValueType>(index));
|
||||||
|
return localPortals.GetReturnValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PortalTypes Portals;
|
||||||
|
ComponentMapType SourceComponents;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief A "portal" that holds arrays to get components from.
|
||||||
|
///
|
||||||
|
/// This class takes place as the control-side portal within an
|
||||||
|
/// ArrayHandleCompositeVector. This is an incomplete implementation, so you
|
||||||
|
/// really can't use it to get values. However, between this and the
|
||||||
|
/// specialization ArrayTransfer, it's enough to get values to the execution
|
||||||
|
/// environment.
|
||||||
|
///
|
||||||
|
template<typename SignatureWithArrays>
|
||||||
|
class ArrayPortalCompositeVectorCont
|
||||||
|
{
|
||||||
|
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
|
||||||
|
FunctionInterfaceArrays;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename FunctionInterfaceArrays::ResultType ValueType;
|
||||||
|
static const int NUM_COMPONENTS =
|
||||||
|
vtkm::VectorTraits<ValueType>::NUM_COMPONENTS;
|
||||||
|
typedef vtkm::Tuple<int, NUM_COMPONENTS> ComponentMapType;
|
||||||
|
|
||||||
|
// If you get a compile error here, it means you probably tried to create
|
||||||
|
// an ArrayHandleCompositeVector with a return type of a vector with a
|
||||||
|
// different number of components than the number of arrays given.
|
||||||
|
BOOST_STATIC_ASSERT(NUM_COMPONENTS == FunctionInterfaceArrays::ARITY);
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayPortalCompositeVectorCont() : NumberOfValues(0) { }
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayPortalCompositeVectorCont(
|
||||||
|
const FunctionInterfaceArrays &arrays,
|
||||||
|
const ComponentMapType &vtkmNotUsed(sourceComponents))
|
||||||
|
: NumberOfValues(arrays.template GetParameter<1>().GetNumberOfValues()) { }
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
vtkm::Id GetNumberOfValues() const {
|
||||||
|
return this->NumberOfValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ValueType Get(vtkm::Id vtkmNotUsed(index)) const {
|
||||||
|
throw vtkm::cont::ErrorControlInternal("Not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void Set(vtkm::Id vtkmNotUsed(index), ValueType vtkmNotUsed(value)) {
|
||||||
|
throw vtkm::cont::ErrorControlInternal("Not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a viable type, but there is no implementation.
|
||||||
|
typedef ValueType *IteratorType;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
IteratorType GetIteratorBegin() const {
|
||||||
|
throw vtkm::cont::ErrorControlInternal("Not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
IteratorType GetIteratorEnd() const {
|
||||||
|
throw vtkm::cont::ErrorControlInternal("Not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
vtkm::Id NumberOfValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename SignatureWithArrays>
|
||||||
|
struct ArrayContainerControlTagCompositeVector { };
|
||||||
|
|
||||||
|
/// A convenience class that provides a typedef to the appropriate tag for
|
||||||
|
/// a counting array container.
|
||||||
|
template<typename SignatureWithArrays>
|
||||||
|
struct ArrayHandleCompositeVectorTraits
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::internal::ArrayContainerControlTagCompositeVector<
|
||||||
|
SignatureWithArrays> Tag;
|
||||||
|
typedef typename vtkm::internal::FunctionInterface<SignatureWithArrays>::ResultType
|
||||||
|
ValueType;
|
||||||
|
typedef vtkm::cont::internal::ArrayContainerControl<
|
||||||
|
ValueType, Tag> ContainerType;
|
||||||
|
};
|
||||||
|
|
||||||
|
// It may seem weird that this specialization throws an exception for
|
||||||
|
// everything, but that is because all the functionality is handled in the
|
||||||
|
// ArrayTransfer class.
|
||||||
|
template<typename SignatureWithArrays>
|
||||||
|
class ArrayContainerControl<
|
||||||
|
typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
|
||||||
|
vtkm::cont::internal::ArrayContainerControlTagCompositeVector<SignatureWithArrays> >
|
||||||
|
{
|
||||||
|
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
|
||||||
|
FunctionInterfaceWithArrays;
|
||||||
|
static const int NUM_COMPONENTS = FunctionInterfaceWithArrays::ARITY;
|
||||||
|
typedef vtkm::Tuple<int, NUM_COMPONENTS> ComponentMapType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef ArrayPortalCompositeVectorCont<SignatureWithArrays> PortalType;
|
||||||
|
typedef PortalType PortalConstType;
|
||||||
|
typedef typename PortalType::ValueType ValueType;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayContainerControl() : Valid(false) { }
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayContainerControl(const FunctionInterfaceWithArrays &arrays,
|
||||||
|
const ComponentMapType &sourceComponents)
|
||||||
|
: Arrays(arrays), SourceComponents(sourceComponents), Valid(true)
|
||||||
|
{
|
||||||
|
arrays.ForEachCont(
|
||||||
|
detail::CheckArraySizeFunctor(this->GetNumberOfValues()));
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
PortalType GetPortal() {
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays are read only.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
PortalConstType GetPortalConst() const {
|
||||||
|
if (!this->Valid)
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
|
||||||
|
}
|
||||||
|
return PortalConstType(this->Arrays, this->SourceComponents);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
vtkm::Id GetNumberOfValues() const {
|
||||||
|
if (!this->Valid)
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
|
||||||
|
}
|
||||||
|
return this->Arrays.template GetParameter<1>().GetNumberOfValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues)) {
|
||||||
|
throw vtkm::cont::ErrorControlInternal(
|
||||||
|
|
||||||
|
"The allocate method for the composite vector control array "
|
||||||
|
"container should never have been called. The allocate is generally "
|
||||||
|
"only called by the execution array manager, and the array transfer "
|
||||||
|
"for the transform container should prevent the execution array "
|
||||||
|
"manager from being directly used.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues)) {
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays are read-only.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void ReleaseResources() {
|
||||||
|
if (this->Valid)
|
||||||
|
{
|
||||||
|
// TODO: Implement this.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
const FunctionInterfaceWithArrays &GetArrays() const {
|
||||||
|
VTKM_ASSERT_CONT(this->Valid);
|
||||||
|
return this->Arrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
const ComponentMapType &GetSourceComponents() const {
|
||||||
|
VTKM_ASSERT_CONT(this->Valid);
|
||||||
|
return this->SourceComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FunctionInterfaceWithArrays Arrays;
|
||||||
|
ComponentMapType SourceComponents;
|
||||||
|
bool Valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename SignatureWithArrays, typename DeviceAdapterTag>
|
||||||
|
class ArrayTransfer<
|
||||||
|
typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
|
||||||
|
vtkm::cont::internal::ArrayContainerControlTagCompositeVector<SignatureWithArrays>,
|
||||||
|
DeviceAdapterTag>
|
||||||
|
{
|
||||||
|
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
|
||||||
|
|
||||||
|
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ContainerType
|
||||||
|
ContainerType;
|
||||||
|
|
||||||
|
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
|
||||||
|
FunctionWithArrays;
|
||||||
|
typedef typename FunctionWithArrays::template StaticTransformType<
|
||||||
|
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag> >::type
|
||||||
|
FunctionWithPortals;
|
||||||
|
typedef typename FunctionWithPortals::Signature SignatureWithPortals;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType
|
||||||
|
ValueType;
|
||||||
|
|
||||||
|
// These are not currently fully implemented.
|
||||||
|
typedef typename ContainerType::PortalType PortalControl;
|
||||||
|
typedef typename ContainerType::PortalConstType PortalConstControl;
|
||||||
|
|
||||||
|
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalExecution;
|
||||||
|
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalConstExecution;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayTransfer() : ContainerValid(false) { }
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
vtkm::Id GetNumberOfValues() const {
|
||||||
|
VTKM_ASSERT_CONT(this->ContainerValid);
|
||||||
|
return this->Container.GetNumberOfValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void LoadDataForInput(PortalConstControl vtkmNotUsed(contPortal))
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlInternal(
|
||||||
|
"ArrayHandleCompositeVector in a bad state. "
|
||||||
|
"There must be a UserArray set, but how did that happen?");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void LoadDataForInput(const ContainerType &controlArray)
|
||||||
|
{
|
||||||
|
this->Container = controlArray;
|
||||||
|
this->ContainerValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void LoadDataForInPlace(ContainerType &vtkmNotUsed(controlArray))
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays cannot be used for output or in place.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void AllocateArrayForOutput(ContainerType &vtkmNotUsed(controlArray),
|
||||||
|
vtkm::Id vtkmNotUsed(numberOfValues))
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays cannot be used for output.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void RetrieveOutputData(ContainerType &vtkmNotUsed(controlArray)) const
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays cannot be used for output.");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename IteratorTypeControl>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void CopyInto(IteratorTypeControl vtkmNotUsed(dest)) const
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlInternal(
|
||||||
|
"CopyInto not implemented for composite vector arrays.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays cannot be resized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
PortalExecution GetPortalExecution()
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorControlBadValue(
|
||||||
|
"Composite vector arrays are read-only. (Get the const portal.)");
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
PortalConstExecution GetPortalConstExecution() const
|
||||||
|
{
|
||||||
|
VTKM_ASSERT_CONT(this->ContainerValid);
|
||||||
|
return
|
||||||
|
PortalConstExecution(
|
||||||
|
this->Container.GetArrays().StaticTransformCont(
|
||||||
|
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>()),
|
||||||
|
this->Container.GetSourceComponents());
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void ReleaseResources() {
|
||||||
|
this->Container.ReleaseResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ContainerValid;
|
||||||
|
ContainerType Container;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// \brief An \c ArrayHandle that combines components from other arrays.
|
||||||
|
///
|
||||||
|
/// \c ArrayHandleCompositeVector is a specialization of \c ArrayHandle that
|
||||||
|
/// derives its content from other arrays. It takes up to 4 other \c
|
||||||
|
/// ArrayHandle objects and mimics an array that contains vectors with
|
||||||
|
/// components that come from these delegate arrays.
|
||||||
|
///
|
||||||
|
/// The easiest way to create and type an \c ArrayHandleCompositeVector is
|
||||||
|
/// to use the \c make_ArrayHandleCompositeVector functions.
|
||||||
|
///
|
||||||
|
template<typename Signature>
|
||||||
|
class ArrayHandleCompositeVector
|
||||||
|
: public vtkm::cont::ArrayHandle<
|
||||||
|
typename internal::ArrayHandleCompositeVectorTraits<Signature>::ValueType,
|
||||||
|
typename internal::ArrayHandleCompositeVectorTraits<Signature>::Tag>
|
||||||
|
{
|
||||||
|
typedef typename internal::ArrayHandleCompositeVectorTraits<Signature>::ContainerType
|
||||||
|
ArrayContainerControlType;
|
||||||
|
typedef typename internal::ArrayPortalCompositeVectorCont<Signature>::ComponentMapType
|
||||||
|
ComponentMapType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef vtkm::cont::ArrayHandle<
|
||||||
|
typename internal::ArrayHandleCompositeVectorTraits<Signature>::ValueType,
|
||||||
|
typename internal::ArrayHandleCompositeVectorTraits<Signature>::Tag>
|
||||||
|
Superclass;
|
||||||
|
typedef typename Superclass::ValueType ValueType;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector() : Superclass() { }
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector(
|
||||||
|
const vtkm::internal::FunctionInterface<Signature> &arrays,
|
||||||
|
const ComponentMapType &sourceComponents)
|
||||||
|
: Superclass(ArrayContainerControlType(arrays, sourceComponents))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// Template constructors for passing in types. You'll get weird compile
|
||||||
|
/// errors if the argument types do not actually match the types in the
|
||||||
|
/// signature.
|
||||||
|
///
|
||||||
|
template<typename ArrayHandleType1>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
|
||||||
|
int sourceComponent1)
|
||||||
|
: Superclass(ArrayContainerControlType(
|
||||||
|
vtkm::internal::make_FunctionInterface<ValueType>(array1),
|
||||||
|
ComponentMapType(sourceComponent1)))
|
||||||
|
{ }
|
||||||
|
template<typename ArrayHandleType1,
|
||||||
|
typename ArrayHandleType2>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
|
||||||
|
int sourceComponent1,
|
||||||
|
const ArrayHandleType2 &array2,
|
||||||
|
int sourceComponent2)
|
||||||
|
: Superclass(ArrayContainerControlType(
|
||||||
|
vtkm::internal::make_FunctionInterface<ValueType>(
|
||||||
|
array1, array2),
|
||||||
|
ComponentMapType(sourceComponent1,
|
||||||
|
sourceComponent2)))
|
||||||
|
{ }
|
||||||
|
template<typename ArrayHandleType1,
|
||||||
|
typename ArrayHandleType2,
|
||||||
|
typename ArrayHandleType3>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
|
||||||
|
int sourceComponent1,
|
||||||
|
const ArrayHandleType2 &array2,
|
||||||
|
int sourceComponent2,
|
||||||
|
const ArrayHandleType3 &array3,
|
||||||
|
int sourceComponent3)
|
||||||
|
: Superclass(ArrayContainerControlType(
|
||||||
|
vtkm::internal::make_FunctionInterface<ValueType>(
|
||||||
|
array1, array2, array3),
|
||||||
|
ComponentMapType(sourceComponent1,
|
||||||
|
sourceComponent2,
|
||||||
|
sourceComponent3)))
|
||||||
|
{ }
|
||||||
|
template<typename ArrayHandleType1,
|
||||||
|
typename ArrayHandleType2,
|
||||||
|
typename ArrayHandleType3,
|
||||||
|
typename ArrayHandleType4>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
|
||||||
|
int sourceComponent1,
|
||||||
|
const ArrayHandleType2 &array2,
|
||||||
|
int sourceComponent2,
|
||||||
|
const ArrayHandleType3 &array3,
|
||||||
|
int sourceComponent3,
|
||||||
|
const ArrayHandleType4 &array4,
|
||||||
|
int sourceComponent4)
|
||||||
|
: Superclass(ArrayContainerControlType(
|
||||||
|
vtkm::internal::make_FunctionInterface<ValueType>(
|
||||||
|
array1, array2, array3, array4),
|
||||||
|
ComponentMapType(sourceComponent1,
|
||||||
|
sourceComponent2,
|
||||||
|
sourceComponent3,
|
||||||
|
sourceComponent4)))
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Create a composite vector array from other arrays.
|
||||||
|
///
|
||||||
|
template<typename ValueType1, typename Container1>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector<
|
||||||
|
typename vtkm::VectorTraits<ValueType1>::ComponentType(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>)>
|
||||||
|
make_ArrayHandleCompositeVector(
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
|
||||||
|
int sourceComponent1)
|
||||||
|
{
|
||||||
|
return ArrayHandleCompositeVector<
|
||||||
|
typename vtkm::VectorTraits<ValueType1>::ComponentType(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>)>(array1,
|
||||||
|
sourceComponent1);
|
||||||
|
}
|
||||||
|
template<typename ValueType1, typename Container1,
|
||||||
|
typename ValueType2, typename Container2>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector<
|
||||||
|
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,2>(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType2,Container2>)>
|
||||||
|
make_ArrayHandleCompositeVector(
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
|
||||||
|
int sourceComponent1,
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
|
||||||
|
int sourceComponent2)
|
||||||
|
{
|
||||||
|
return ArrayHandleCompositeVector<
|
||||||
|
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,2>(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType2,Container2>)>(array1,
|
||||||
|
sourceComponent1,
|
||||||
|
array2,
|
||||||
|
sourceComponent2);
|
||||||
|
}
|
||||||
|
template<typename ValueType1, typename Container1,
|
||||||
|
typename ValueType2, typename Container2,
|
||||||
|
typename ValueType3, typename Container3>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector<
|
||||||
|
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,3>(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType3,Container3>)>
|
||||||
|
make_ArrayHandleCompositeVector(
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
|
||||||
|
int sourceComponent1,
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
|
||||||
|
int sourceComponent2,
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType3,Container3> &array3,
|
||||||
|
int sourceComponent3)
|
||||||
|
{
|
||||||
|
return ArrayHandleCompositeVector<
|
||||||
|
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,3>(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType3,Container3>)>(array1,
|
||||||
|
sourceComponent1,
|
||||||
|
array2,
|
||||||
|
sourceComponent2,
|
||||||
|
array3,
|
||||||
|
sourceComponent3);
|
||||||
|
}
|
||||||
|
template<typename ValueType1, typename Container1,
|
||||||
|
typename ValueType2, typename Container2,
|
||||||
|
typename ValueType3, typename Container3,
|
||||||
|
typename ValueType4, typename Container4>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ArrayHandleCompositeVector<
|
||||||
|
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,4>(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType3,Container3>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType4,Container4>)>
|
||||||
|
make_ArrayHandleCompositeVector(
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
|
||||||
|
int sourceComponent1,
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
|
||||||
|
int sourceComponent2,
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType3,Container3> &array3,
|
||||||
|
int sourceComponent3,
|
||||||
|
const vtkm::cont::ArrayHandle<ValueType4,Container4> &array4,
|
||||||
|
int sourceComponent4)
|
||||||
|
{
|
||||||
|
return ArrayHandleCompositeVector<
|
||||||
|
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,4>(
|
||||||
|
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType3,Container3>,
|
||||||
|
vtkm::cont::ArrayHandle<ValueType4,Container4>)>(array1,
|
||||||
|
sourceComponent1,
|
||||||
|
array2,
|
||||||
|
sourceComponent2,
|
||||||
|
array3,
|
||||||
|
sourceComponent3,
|
||||||
|
array4,
|
||||||
|
sourceComponent4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
#endif //vtk_m_ArrayHandleCompositeVector_h
|
@ -25,6 +25,7 @@ set(headers
|
|||||||
ArrayContainerControlBasic.h
|
ArrayContainerControlBasic.h
|
||||||
ArrayContainerControlImplicit.h
|
ArrayContainerControlImplicit.h
|
||||||
ArrayHandle.h
|
ArrayHandle.h
|
||||||
|
ArrayHandleCompositeVector.h
|
||||||
ArrayHandleCounting.h
|
ArrayHandleCounting.h
|
||||||
ArrayHandleUniformPointCoordinates.h
|
ArrayHandleUniformPointCoordinates.h
|
||||||
ArrayPortal.h
|
ArrayPortal.h
|
||||||
|
@ -29,6 +29,7 @@ set(unit_tests
|
|||||||
UnitTestArrayContainerControlBasic.cxx
|
UnitTestArrayContainerControlBasic.cxx
|
||||||
UnitTestArrayContainerControlImplicit.cxx
|
UnitTestArrayContainerControlImplicit.cxx
|
||||||
UnitTestArrayHandle.cxx
|
UnitTestArrayHandle.cxx
|
||||||
|
UnitTestArrayHandleCompositeVector.cxx
|
||||||
UnitTestArrayHandleCounting.cxx
|
UnitTestArrayHandleCounting.cxx
|
||||||
UnitTestArrayHandleUniformPointCoordinates.cxx
|
UnitTestArrayHandleUniformPointCoordinates.cxx
|
||||||
UnitTestContTesting.cxx
|
UnitTestContTesting.cxx
|
||||||
|
313
vtkm/cont/testing/UnitTestArrayHandleCompositeVector.cxx
Normal file
313
vtkm/cont/testing/UnitTestArrayHandleCompositeVector.cxx
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
// Make sure ArrayHandleCompositeVector does not rely on default container or
|
||||||
|
// device adapter.
|
||||||
|
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_ERROR
|
||||||
|
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||||
|
|
||||||
|
#include <vtkm/VectorTraits.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayContainerControlBasic.h>
|
||||||
|
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const vtkm::Id ARRAY_SIZE = 10;
|
||||||
|
|
||||||
|
typedef vtkm::cont::ArrayContainerControlTagBasic Container;
|
||||||
|
|
||||||
|
vtkm::Scalar TestValue(vtkm::Id index, int inComponentIndex, int inArrayId)
|
||||||
|
{
|
||||||
|
return index + vtkm::Scalar(0.1)*inComponentIndex + vtkm::Scalar(0.01)*inArrayId;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
vtkm::cont::ArrayHandle<ValueType, Container>
|
||||||
|
MakeInputArray(int arrayId)
|
||||||
|
{
|
||||||
|
typedef vtkm::VectorTraits<ValueType> VTraits;
|
||||||
|
|
||||||
|
// Create a buffer with valid test values.
|
||||||
|
ValueType buffer[ARRAY_SIZE];
|
||||||
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
||||||
|
{
|
||||||
|
for (int componentIndex = 0;
|
||||||
|
componentIndex < VTraits::NUM_COMPONENTS;
|
||||||
|
componentIndex++)
|
||||||
|
{
|
||||||
|
VTraits::SetComponent(buffer[index],
|
||||||
|
componentIndex,
|
||||||
|
TestValue(index, componentIndex, arrayId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an array handle that points to this buffer.
|
||||||
|
typedef vtkm::cont::ArrayHandle<ValueType, Container> ArrayHandleType;
|
||||||
|
ArrayHandleType bufferHandle =
|
||||||
|
vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, Container());
|
||||||
|
|
||||||
|
// When this function returns, the array is going to go out of scope, which
|
||||||
|
// will invalidate the array handle we just created. So copy to a new buffer
|
||||||
|
// that will stick around after we return.
|
||||||
|
ArrayHandleType copyHandle;
|
||||||
|
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagSerial>::Copy(
|
||||||
|
bufferHandle, copyHandle);
|
||||||
|
|
||||||
|
return copyHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename C>
|
||||||
|
void CheckArray(const vtkm::cont::ArrayHandle<ValueType,C> &outArray,
|
||||||
|
const int *inComponents,
|
||||||
|
const int *inArrayIds)
|
||||||
|
{
|
||||||
|
// ArrayHandleCompositeVector currently does not implement the ability to
|
||||||
|
// get to values on the control side, so copy to an array that is accessible.
|
||||||
|
typedef vtkm::cont::ArrayHandle<ValueType, Container> ArrayHandleType;
|
||||||
|
ArrayHandleType arrayCopy;
|
||||||
|
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagSerial>::Copy(
|
||||||
|
outArray, arrayCopy);
|
||||||
|
|
||||||
|
typename ArrayHandleType::PortalConstControl portal =
|
||||||
|
arrayCopy.GetPortalConstControl();
|
||||||
|
typedef vtkm::VectorTraits<ValueType> VTraits;
|
||||||
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
||||||
|
{
|
||||||
|
ValueType retreivedValue = portal.Get(index);
|
||||||
|
for (int componentIndex = 0;
|
||||||
|
componentIndex < VTraits::NUM_COMPONENTS;
|
||||||
|
componentIndex++)
|
||||||
|
{
|
||||||
|
vtkm::Scalar retrievedComponent =
|
||||||
|
VTraits::GetComponent(retreivedValue, componentIndex);
|
||||||
|
vtkm::Scalar expectedComponent = TestValue(index,
|
||||||
|
inComponents[componentIndex],
|
||||||
|
inArrayIds[componentIndex]);
|
||||||
|
VTKM_TEST_ASSERT(retrievedComponent == expectedComponent,
|
||||||
|
"Got bad value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int inComponents>
|
||||||
|
void TryScalarArray()
|
||||||
|
{
|
||||||
|
std::cout << "Creating a scalar array from one of "
|
||||||
|
<< inComponents << " components." << std::endl;
|
||||||
|
|
||||||
|
typedef vtkm::Tuple<vtkm::Scalar,inComponents> InValueType;
|
||||||
|
typedef vtkm::cont::ArrayHandle<InValueType, Container> InArrayType;
|
||||||
|
int inArrayId = 0;
|
||||||
|
InArrayType inArray = MakeInputArray<InValueType>(inArrayId);
|
||||||
|
|
||||||
|
typedef vtkm::cont::ArrayHandleCompositeVector<vtkm::Scalar(InArrayType)>
|
||||||
|
OutArrayType;
|
||||||
|
for (int inComponentIndex = 0;
|
||||||
|
inComponentIndex < inComponents;
|
||||||
|
inComponentIndex++)
|
||||||
|
{
|
||||||
|
OutArrayType outArray =
|
||||||
|
vtkm::cont::make_ArrayHandleCompositeVector(inArray, inComponentIndex);
|
||||||
|
CheckArray(outArray, &inComponentIndex, &inArrayId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3, typename T4>
|
||||||
|
void TryVector4(vtkm::cont::ArrayHandle<T1,Container> array1,
|
||||||
|
vtkm::cont::ArrayHandle<T2,Container> array2,
|
||||||
|
vtkm::cont::ArrayHandle<T3,Container> array3,
|
||||||
|
vtkm::cont::ArrayHandle<T4,Container> array4)
|
||||||
|
{
|
||||||
|
int arrayIds[4] = {0, 1, 2, 3};
|
||||||
|
int inComponents[4];
|
||||||
|
|
||||||
|
for (inComponents[0] = 0;
|
||||||
|
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
|
||||||
|
inComponents[0]++)
|
||||||
|
{
|
||||||
|
for (inComponents[1] = 0;
|
||||||
|
inComponents[1] < vtkm::VectorTraits<T2>::NUM_COMPONENTS;
|
||||||
|
inComponents[1]++)
|
||||||
|
{
|
||||||
|
for (inComponents[2] = 0;
|
||||||
|
inComponents[2] < vtkm::VectorTraits<T3>::NUM_COMPONENTS;
|
||||||
|
inComponents[2]++)
|
||||||
|
{
|
||||||
|
for (inComponents[3] = 0;
|
||||||
|
inComponents[3] < vtkm::VectorTraits<T4>::NUM_COMPONENTS;
|
||||||
|
inComponents[3]++)
|
||||||
|
{
|
||||||
|
CheckArray(
|
||||||
|
vtkm::cont::make_ArrayHandleCompositeVector(
|
||||||
|
array1, inComponents[0],
|
||||||
|
array2, inComponents[1],
|
||||||
|
array3, inComponents[2],
|
||||||
|
array4, inComponents[3]),
|
||||||
|
inComponents,
|
||||||
|
arrayIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3>
|
||||||
|
void TryVector3(vtkm::cont::ArrayHandle<T1,Container> array1,
|
||||||
|
vtkm::cont::ArrayHandle<T2,Container> array2,
|
||||||
|
vtkm::cont::ArrayHandle<T3,Container> array3)
|
||||||
|
{
|
||||||
|
int arrayIds[3] = {0, 1, 2};
|
||||||
|
int inComponents[3];
|
||||||
|
|
||||||
|
for (inComponents[0] = 0;
|
||||||
|
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
|
||||||
|
inComponents[0]++)
|
||||||
|
{
|
||||||
|
for (inComponents[1] = 0;
|
||||||
|
inComponents[1] < vtkm::VectorTraits<T2>::NUM_COMPONENTS;
|
||||||
|
inComponents[1]++)
|
||||||
|
{
|
||||||
|
for (inComponents[2] = 0;
|
||||||
|
inComponents[2] < vtkm::VectorTraits<T3>::NUM_COMPONENTS;
|
||||||
|
inComponents[2]++)
|
||||||
|
{
|
||||||
|
CheckArray(
|
||||||
|
vtkm::cont::make_ArrayHandleCompositeVector(
|
||||||
|
array1, inComponents[0],
|
||||||
|
array2, inComponents[1],
|
||||||
|
array3, inComponents[2]),
|
||||||
|
inComponents,
|
||||||
|
arrayIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << " Fourth component from Scalar." << std::endl;
|
||||||
|
TryVector4(array1, array2, array3, MakeInputArray<vtkm::Scalar>(3));
|
||||||
|
std::cout << " Fourth component from Vector4." << std::endl;
|
||||||
|
TryVector4(array1, array2, array3, MakeInputArray<vtkm::Vector4>(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
void TryVector2(vtkm::cont::ArrayHandle<T1,Container> array1,
|
||||||
|
vtkm::cont::ArrayHandle<T2,Container> array2)
|
||||||
|
{
|
||||||
|
int arrayIds[2] = {0, 1};
|
||||||
|
int inComponents[2];
|
||||||
|
|
||||||
|
for (inComponents[0] = 0;
|
||||||
|
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
|
||||||
|
inComponents[0]++)
|
||||||
|
{
|
||||||
|
for (inComponents[1] = 0;
|
||||||
|
inComponents[1] < vtkm::VectorTraits<T2>::NUM_COMPONENTS;
|
||||||
|
inComponents[1]++)
|
||||||
|
{
|
||||||
|
CheckArray(
|
||||||
|
vtkm::cont::make_ArrayHandleCompositeVector(
|
||||||
|
array1, inComponents[0],
|
||||||
|
array2, inComponents[1]),
|
||||||
|
inComponents,
|
||||||
|
arrayIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << " Third component from Scalar." << std::endl;
|
||||||
|
TryVector3(array1, array2, MakeInputArray<vtkm::Scalar>(2));
|
||||||
|
std::cout << " Third component from Vector2." << std::endl;
|
||||||
|
TryVector3(array1, array2, MakeInputArray<vtkm::Vector2>(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1>
|
||||||
|
void TryVector1(vtkm::cont::ArrayHandle<T1,Container> array1)
|
||||||
|
{
|
||||||
|
int arrayIds[1] = {0};
|
||||||
|
int inComponents[1];
|
||||||
|
|
||||||
|
for (inComponents[0] = 0;
|
||||||
|
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
|
||||||
|
inComponents[0]++)
|
||||||
|
{
|
||||||
|
CheckArray(
|
||||||
|
vtkm::cont::make_ArrayHandleCompositeVector(array1, inComponents[0]),
|
||||||
|
inComponents,
|
||||||
|
arrayIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << " Second component from Scalar." << std::endl;
|
||||||
|
TryVector2(array1, MakeInputArray<vtkm::Scalar>(1));
|
||||||
|
std::cout << " Second component from Vector4." << std::endl;
|
||||||
|
TryVector2(array1, MakeInputArray<vtkm::Vector4>(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TryVector()
|
||||||
|
{
|
||||||
|
std::cout << "Trying many permutations of composite vectors." << std::endl;
|
||||||
|
|
||||||
|
std::cout << " First component from Scalar." << std::endl;
|
||||||
|
TryVector1(MakeInputArray<vtkm::Scalar>(0));
|
||||||
|
std::cout << " First component from Vector3." << std::endl;
|
||||||
|
TryVector1(MakeInputArray<vtkm::Vector3>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestBadArrayLengths() {
|
||||||
|
std::cout << "Checking behavior when size of input arrays do not agree."
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
typedef vtkm::cont::ArrayHandle<vtkm::Id, Container> InArrayType;
|
||||||
|
InArrayType longInArray = MakeInputArray<vtkm::Id>(0);
|
||||||
|
InArrayType shortInArray = MakeInputArray<vtkm::Id>(1);
|
||||||
|
shortInArray.Shrink(ARRAY_SIZE/2);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
vtkm::cont::make_ArrayHandleCompositeVector(longInArray,0, shortInArray,0);
|
||||||
|
VTKM_TEST_FAIL("Did not get exception like expected.");
|
||||||
|
}
|
||||||
|
catch (vtkm::cont::ErrorControlBadValue error)
|
||||||
|
{
|
||||||
|
std::cout << "Got expected error: " << std::endl
|
||||||
|
<< error.GetMessage() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCompositeVector() {
|
||||||
|
TryScalarArray<2>();
|
||||||
|
TryScalarArray<3>();
|
||||||
|
TryScalarArray<4>();
|
||||||
|
|
||||||
|
TryVector();
|
||||||
|
|
||||||
|
TestBadArrayLengths();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
int UnitTestArrayHandleCompositeVector(int, char *[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(TestCompositeVector);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user