2020-08-05 03:16:29 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
|
|
|
//
|
|
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
|
|
//============================================================================
|
|
|
|
|
2020-08-05 12:42:33 +00:00
|
|
|
#include <vtkm/cont/UncertainArrayHandle.h>
|
2020-08-05 03:16:29 +00:00
|
|
|
#include <vtkm/cont/UnknownArrayHandle.h>
|
|
|
|
|
2023-04-19 17:14:05 +00:00
|
|
|
#include <vtkm/cont/ArrayCopy.h>
|
2020-09-14 14:39:27 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleCast.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
|
|
|
#include <vtkm/cont/ArrayHandleMultiplexer.h>
|
2023-02-08 22:16:49 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleRuntimeVec.h>
|
2020-09-14 14:39:27 +00:00
|
|
|
|
2020-08-05 03:16:29 +00:00
|
|
|
#include <vtkm/TypeTraits.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
// Make an "unusual" type to use in the test. This is simply a type that
|
|
|
|
// is sure not to be declared elsewhere.
|
|
|
|
struct UnusualType
|
|
|
|
{
|
|
|
|
using T = vtkm::Id;
|
|
|
|
T X;
|
|
|
|
UnusualType() = default;
|
|
|
|
UnusualType(T x)
|
|
|
|
: X(x)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
UnusualType& operator=(T x)
|
|
|
|
{
|
|
|
|
this->X = x;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
operator T() const { return this->X; }
|
|
|
|
};
|
|
|
|
|
|
|
|
const vtkm::Id ARRAY_SIZE = 10;
|
|
|
|
|
|
|
|
struct CheckFunctor
|
|
|
|
{
|
|
|
|
template <typename T, typename S>
|
|
|
|
static void CheckArray(const vtkm::cont::ArrayHandle<T, S>& array)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size.");
|
|
|
|
CheckPortal(array.ReadPortal());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename S>
|
|
|
|
static void CheckArray(const vtkm::cont::ArrayHandle<UnusualType, S>& array)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size.");
|
|
|
|
auto portal = array.ReadPortal();
|
|
|
|
for (vtkm::Id index = 0; index < array.GetNumberOfValues(); ++index)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(index) == TestValue(index, UnusualType::T{}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename S>
|
|
|
|
void operator()(const vtkm::cont::ArrayHandle<T, S>& array, bool& called) const
|
|
|
|
{
|
|
|
|
called = true;
|
2021-08-04 13:59:48 +00:00
|
|
|
std::cout << " Checking for array type " << vtkm::cont::TypeToString<T>() << " with storage "
|
|
|
|
<< vtkm::cont::TypeToString<S>() << std::endl;
|
2020-08-05 03:16:29 +00:00
|
|
|
|
|
|
|
CheckArray(array);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void BasicUnknownArrayChecks(const vtkm::cont::UnknownArrayHandle& array,
|
|
|
|
vtkm::IdComponent numComponents)
|
|
|
|
{
|
2021-08-04 13:59:48 +00:00
|
|
|
std::cout << " Checking an UnknownArrayHandle containing " << array.GetArrayTypeName()
|
|
|
|
<< std::endl;
|
2020-08-05 03:16:29 +00:00
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
|
|
|
|
"Dynamic array reports unexpected size.");
|
2020-12-16 00:22:03 +00:00
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfComponentsFlat() == numComponents,
|
2020-08-05 03:16:29 +00:00
|
|
|
"Dynamic array reports unexpected number of components.");
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckUnknownArrayDefaults(const vtkm::cont::UnknownArrayHandle& array,
|
|
|
|
vtkm::IdComponent numComponents)
|
|
|
|
{
|
|
|
|
BasicUnknownArrayChecks(array, numComponents);
|
|
|
|
|
|
|
|
std::cout << " CastAndCall with default types" << std::endl;
|
|
|
|
bool called = false;
|
2020-08-05 12:42:33 +00:00
|
|
|
vtkm::cont::CastAndCall(array, CheckFunctor(), called);
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TypeList, typename StorageList>
|
|
|
|
void CheckUnknownArray(const vtkm::cont::UnknownArrayHandle& array, vtkm::IdComponent numComponents)
|
|
|
|
{
|
|
|
|
VTKM_IS_LIST(TypeList);
|
|
|
|
VTKM_IS_LIST(StorageList);
|
|
|
|
|
|
|
|
BasicUnknownArrayChecks(array, numComponents);
|
|
|
|
|
|
|
|
std::cout << " CastAndCall with given types" << std::endl;
|
|
|
|
bool called = false;
|
|
|
|
array.CastAndCallForTypes<TypeList, StorageList>(CheckFunctor{}, called);
|
2020-08-05 12:42:33 +00:00
|
|
|
VTKM_TEST_ASSERT(
|
|
|
|
called, "The functor was never called (and apparently a bad value exception not thrown).");
|
2020-08-05 03:16:29 +00:00
|
|
|
|
2020-08-05 12:42:33 +00:00
|
|
|
std::cout << " Check CastAndCall again with UncertainArrayHandle" << std::endl;
|
|
|
|
called = false;
|
|
|
|
vtkm::cont::CastAndCall(array.ResetTypes<TypeList, StorageList>(), CheckFunctor{}, called);
|
2020-08-05 03:16:29 +00:00
|
|
|
VTKM_TEST_ASSERT(
|
|
|
|
called, "The functor was never called (and apparently a bad value exception not thrown).");
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
vtkm::cont::ArrayHandle<T> CreateArray(T)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<T> array;
|
|
|
|
array.Allocate(ARRAY_SIZE);
|
|
|
|
SetPortal(array.WritePortal());
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<UnusualType> CreateArray(UnusualType)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<UnusualType> array;
|
|
|
|
array.Allocate(ARRAY_SIZE);
|
|
|
|
auto portal = array.WritePortal();
|
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
|
|
|
{
|
|
|
|
portal.Set(index, TestValue(index, UnusualType::T{}));
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
vtkm::cont::UnknownArrayHandle CreateArrayUnknown(T t)
|
|
|
|
{
|
|
|
|
return vtkm::cont::UnknownArrayHandle(CreateArray(t));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
2020-09-03 15:04:05 +00:00
|
|
|
void CheckAsArrayHandle(const ArrayHandleType& array)
|
2020-08-05 03:16:29 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
2020-09-03 15:04:05 +00:00
|
|
|
using T = typename ArrayHandleType::ValueType;
|
2020-08-05 03:16:29 +00:00
|
|
|
|
|
|
|
vtkm::cont::UnknownArrayHandle arrayUnknown = array;
|
|
|
|
VTKM_TEST_ASSERT(!arrayUnknown.IsType<vtkm::cont::ArrayHandle<UnusualType>>(),
|
|
|
|
"Dynamic array reporting is wrong type.");
|
|
|
|
|
2020-09-03 15:04:05 +00:00
|
|
|
{
|
|
|
|
std::cout << " Normal get ArrayHandle" << std::endl;
|
|
|
|
ArrayHandleType retreivedArray1;
|
|
|
|
arrayUnknown.AsArrayHandle(retreivedArray1);
|
|
|
|
VTKM_TEST_ASSERT(arrayUnknown.CanConvert<ArrayHandleType>(), "Did not query handle correctly.");
|
|
|
|
VTKM_TEST_ASSERT(array == retreivedArray1, "Did not get back same array.");
|
|
|
|
|
|
|
|
ArrayHandleType retreivedArray2 = arrayUnknown.AsArrayHandle<ArrayHandleType>();
|
|
|
|
VTKM_TEST_ASSERT(array == retreivedArray2, "Did not get back same array.");
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << " Put in cast array, get actual array" << std::endl;
|
|
|
|
auto castArray = vtkm::cont::make_ArrayHandleCast<vtkm::Float64>(array);
|
|
|
|
vtkm::cont::UnknownArrayHandle arrayUnknown2(castArray);
|
|
|
|
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>());
|
|
|
|
ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle<ArrayHandleType>();
|
|
|
|
VTKM_TEST_ASSERT(array == retrievedArray);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << " Get array as cast" << std::endl;
|
|
|
|
vtkm::cont::ArrayHandleCast<vtkm::Float64, ArrayHandleType> castArray;
|
|
|
|
arrayUnknown.AsArrayHandle(castArray);
|
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(array.ReadPortal(), castArray.ReadPortal()));
|
|
|
|
}
|
2020-08-05 03:16:29 +00:00
|
|
|
|
2020-09-03 15:04:05 +00:00
|
|
|
{
|
|
|
|
std::cout << " Put in multiplexer, get actual array" << std::endl;
|
|
|
|
vtkm::cont::UnknownArrayHandle arrayUnknown2 = vtkm::cont::ArrayHandleMultiplexer<
|
|
|
|
ArrayHandleType,
|
|
|
|
vtkm::cont::ArrayHandleConstant<typename ArrayHandleType::ValueType>>(array);
|
|
|
|
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>(),
|
|
|
|
"Putting in multiplexer did not pull out array.");
|
|
|
|
}
|
2020-08-05 03:16:29 +00:00
|
|
|
|
2020-09-03 15:04:05 +00:00
|
|
|
{
|
|
|
|
std::cout << " Make sure multiplex array prefers direct array (1st arg)" << std::endl;
|
|
|
|
using MultiplexerType =
|
|
|
|
vtkm::cont::ArrayHandleMultiplexer<ArrayHandleType,
|
|
|
|
vtkm::cont::ArrayHandleCast<T, ArrayHandleType>>;
|
|
|
|
MultiplexerType multiplexArray = arrayUnknown.AsArrayHandle<MultiplexerType>();
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_TEST_ASSERT(multiplexArray.GetArrayHandleVariant().GetIndex() == 0);
|
2020-09-03 15:04:05 +00:00
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), array.ReadPortal()));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << " Make sure multiplex array prefers direct array (2nd arg)" << std::endl;
|
|
|
|
using MultiplexerType =
|
|
|
|
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandleCast<T, vtkm::cont::ArrayHandle<T>>,
|
|
|
|
ArrayHandleType>;
|
|
|
|
MultiplexerType multiplexArray = arrayUnknown.AsArrayHandle<MultiplexerType>();
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
2020-11-23 19:16:47 +00:00
|
|
|
VTKM_TEST_ASSERT(multiplexArray.GetArrayHandleVariant().GetIndex() == 1);
|
2020-09-03 15:04:05 +00:00
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), array.ReadPortal()));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << " Make sure adding arrays follows nesting of special arrays" << std::endl;
|
|
|
|
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandle<vtkm::Int64>,
|
|
|
|
vtkm::cont::ArrayHandleCast<vtkm::Int64, ArrayHandleType>>
|
|
|
|
multiplexer(vtkm::cont::make_ArrayHandleCast<vtkm::Int64>(array));
|
|
|
|
auto crazyArray = vtkm::cont::make_ArrayHandleCast<vtkm::Float64>(multiplexer);
|
|
|
|
vtkm::cont::UnknownArrayHandle arrayUnknown2(crazyArray);
|
|
|
|
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>());
|
|
|
|
ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle<ArrayHandleType>();
|
|
|
|
VTKM_TEST_ASSERT(array == retrievedArray);
|
|
|
|
}
|
2020-09-14 14:39:27 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << " Try adding arrays with variable amounts of components" << std::endl;
|
|
|
|
// There might be some limited functionality, but you should still be able
|
|
|
|
// to get arrays in and out.
|
|
|
|
|
|
|
|
// Note, this is a bad way to implement this array. You should something like
|
|
|
|
// ArrayHandleGroupVec instead.
|
|
|
|
using VariableVecArrayType =
|
|
|
|
vtkm::cont::ArrayHandleGroupVecVariable<ArrayHandleType,
|
|
|
|
vtkm::cont::ArrayHandleCounting<vtkm::Id>>;
|
|
|
|
VariableVecArrayType inArray = vtkm::cont::make_ArrayHandleGroupVecVariable(
|
|
|
|
array, vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 2, ARRAY_SIZE / 2 + 1));
|
|
|
|
VTKM_TEST_ASSERT(inArray.GetNumberOfValues() == ARRAY_SIZE / 2);
|
|
|
|
vtkm::cont::UnknownArrayHandle arrayUnknown2 = inArray;
|
|
|
|
VTKM_TEST_ASSERT(arrayUnknown2.IsType<VariableVecArrayType>());
|
|
|
|
VariableVecArrayType retrievedArray = arrayUnknown2.AsArrayHandle<VariableVecArrayType>();
|
|
|
|
VTKM_TEST_ASSERT(retrievedArray == inArray);
|
|
|
|
}
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// A vtkm::Vec if NumComps > 1, otherwise a scalar
|
|
|
|
template <typename T, vtkm::IdComponent NumComps>
|
|
|
|
using VecOrScalar = typename std::conditional<(NumComps > 1), vtkm::Vec<T, NumComps>, T>::type;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TryNewInstance(vtkm::cont::UnknownArrayHandle originalArray)
|
|
|
|
{
|
|
|
|
// This check should already have been performed by caller, but just in case.
|
|
|
|
CheckUnknownArray<vtkm::List<T>, VTKM_DEFAULT_STORAGE_LIST>(originalArray,
|
|
|
|
vtkm::VecTraits<T>::NUM_COMPONENTS);
|
|
|
|
|
|
|
|
std::cout << "Create new instance of array." << std::endl;
|
|
|
|
vtkm::cont::UnknownArrayHandle newArray = originalArray.NewInstance();
|
|
|
|
|
|
|
|
std::cout << "Get a static instance of the new array (which checks the type)." << std::endl;
|
|
|
|
vtkm::cont::ArrayHandle<T> staticArray;
|
|
|
|
newArray.AsArrayHandle(staticArray);
|
|
|
|
|
|
|
|
std::cout << "Fill the new array with invalid values and make sure the original" << std::endl
|
|
|
|
<< "is uneffected." << std::endl;
|
|
|
|
staticArray.Allocate(ARRAY_SIZE);
|
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
|
|
|
{
|
|
|
|
staticArray.WritePortal().Set(index, TestValue(index + 100, T()));
|
|
|
|
}
|
|
|
|
CheckUnknownArray<vtkm::List<T>, VTKM_DEFAULT_STORAGE_LIST>(originalArray,
|
|
|
|
vtkm::VecTraits<T>::NUM_COMPONENTS);
|
|
|
|
|
|
|
|
std::cout << "Set the new static array to expected values and make sure the new" << std::endl
|
|
|
|
<< "dynamic array points to the same new values." << std::endl;
|
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
|
|
|
{
|
|
|
|
staticArray.WritePortal().Set(index, TestValue(index, T()));
|
|
|
|
}
|
|
|
|
CheckUnknownArray<vtkm::List<T>, VTKM_DEFAULT_STORAGE_LIST>(newArray,
|
|
|
|
vtkm::VecTraits<T>::NUM_COMPONENTS);
|
2021-02-01 17:24:13 +00:00
|
|
|
|
|
|
|
std::cout << "Get a new instance as a float array and make sure the type is as expected."
|
|
|
|
<< std::endl;
|
|
|
|
vtkm::cont::UnknownArrayHandle floatArray = originalArray.NewInstanceFloatBasic();
|
|
|
|
vtkm::cont::ArrayHandle<
|
|
|
|
typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::FloatDefault>>
|
|
|
|
staticFloatArray;
|
|
|
|
floatArray.AsArrayHandle(staticFloatArray);
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TryAsMultiplexer(vtkm::cont::UnknownArrayHandle sourceArray)
|
|
|
|
{
|
|
|
|
auto originalArray = sourceArray.AsArrayHandle<vtkm::cont::ArrayHandle<T>>();
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << "Get multiplex array through direct type." << std::endl;
|
|
|
|
using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandle<T>,
|
|
|
|
vtkm::cont::ArrayHandleConstant<T>>;
|
|
|
|
VTKM_TEST_ASSERT(sourceArray.CanConvert<MultiplexerType>());
|
|
|
|
MultiplexerType multiplexArray = sourceArray.AsArrayHandle<MultiplexerType>();
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal()));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << "Get multiplex array through cast type." << std::endl;
|
|
|
|
using CastT = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::Float64>;
|
|
|
|
using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer<
|
|
|
|
vtkm::cont::ArrayHandle<CastT>,
|
|
|
|
vtkm::cont::ArrayHandleCast<CastT, vtkm::cont::ArrayHandle<T>>>;
|
|
|
|
VTKM_TEST_ASSERT(sourceArray.CanConvert<MultiplexerType>());
|
|
|
|
MultiplexerType multiplexArray = sourceArray.AsArrayHandle<MultiplexerType>();
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal()));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Maybe we should support this, but right now we don't
|
|
|
|
{
|
|
|
|
std::cout << "Make sure multiplex array prefers direct array (1st arg)" << std::endl;
|
|
|
|
using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer<
|
|
|
|
vtkm::cont::ArrayHandle<T>,
|
|
|
|
vtkm::cont::ArrayHandleCast<T, vtkm::cont::ArrayHandle<T>>>;
|
|
|
|
MultiplexerType multiplexArray = sourceArray.AsArrayHandle<MultiplexerType>();
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 0);
|
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal()));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::cout << "Make sure multiplex array prefers direct array (2nd arg)" << std::endl;
|
|
|
|
using MultiplexerType =
|
|
|
|
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandleCast<T, vtkm::cont::ArrayHandle<T>>,
|
|
|
|
vtkm::cont::ArrayHandle<T>>;
|
|
|
|
MultiplexerType multiplexArray = sourceArray.AsArrayHandle<MultiplexerType>();
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
|
|
|
VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 1);
|
|
|
|
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal()));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-01-18 20:27:57 +00:00
|
|
|
struct SimpleRecombineCopy
|
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
void operator()(const vtkm::cont::ArrayHandleRecombineVec<T>& inputArray,
|
|
|
|
const vtkm::cont::UnknownArrayHandle& output) const
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandleRecombineVec<T> outputArray =
|
|
|
|
output.ExtractArrayFromComponents<T>(vtkm::CopyFlag::Off);
|
|
|
|
vtkm::Id size = inputArray.GetNumberOfValues();
|
|
|
|
outputArray.Allocate(size);
|
|
|
|
auto inputPortal = inputArray.ReadPortal();
|
|
|
|
auto outputPortal = outputArray.WritePortal();
|
|
|
|
|
|
|
|
for (vtkm::Id index = 0; index < size; ++index)
|
|
|
|
{
|
|
|
|
outputPortal.Set(index, inputPortal.Get(index));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void TryExtractArray(const vtkm::cont::UnknownArrayHandle& originalArray)
|
|
|
|
{
|
|
|
|
// This check should already have been performed by caller, but just in case.
|
|
|
|
CheckUnknownArray<vtkm::List<T>, VTKM_DEFAULT_STORAGE_LIST>(originalArray,
|
|
|
|
vtkm::VecTraits<T>::NUM_COMPONENTS);
|
|
|
|
|
|
|
|
std::cout << "Create new instance of array." << std::endl;
|
|
|
|
vtkm::cont::UnknownArrayHandle newArray = originalArray.NewInstanceBasic();
|
|
|
|
|
|
|
|
std::cout << "Do CastAndCallWithExtractedArray." << std::endl;
|
|
|
|
originalArray.CastAndCallWithExtractedArray(SimpleRecombineCopy{}, newArray);
|
|
|
|
|
|
|
|
CheckUnknownArray<vtkm::List<T>, VTKM_DEFAULT_STORAGE_LIST>(newArray,
|
|
|
|
vtkm::VecTraits<T>::NUM_COMPONENTS);
|
|
|
|
}
|
|
|
|
|
2020-08-05 03:16:29 +00:00
|
|
|
template <typename T>
|
|
|
|
void TryDefaultType()
|
|
|
|
{
|
|
|
|
vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(T{});
|
|
|
|
|
|
|
|
CheckUnknownArrayDefaults(array, vtkm::VecTraits<T>::NUM_COMPONENTS);
|
|
|
|
|
|
|
|
TryNewInstance<T>(array);
|
|
|
|
|
|
|
|
TryAsMultiplexer<T>(array);
|
2023-01-18 20:27:57 +00:00
|
|
|
|
|
|
|
TryExtractArray<T>(array);
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct TryBasicVTKmType
|
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
void operator()(T) const
|
|
|
|
{
|
|
|
|
vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(T());
|
|
|
|
|
2021-08-04 13:59:48 +00:00
|
|
|
VTKM_TEST_ASSERT(array.GetValueTypeName() == vtkm::cont::TypeToString<T>());
|
|
|
|
VTKM_TEST_ASSERT(array.GetStorageTypeName() ==
|
|
|
|
vtkm::cont::TypeToString<vtkm::cont::StorageTagBasic>());
|
|
|
|
|
2020-08-05 03:16:29 +00:00
|
|
|
CheckUnknownArray<vtkm::TypeListAll, VTKM_DEFAULT_STORAGE_LIST>(
|
|
|
|
array, vtkm::VecTraits<T>::NUM_COMPONENTS);
|
|
|
|
|
|
|
|
TryNewInstance<T>(array);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void TryUnusualType()
|
|
|
|
{
|
|
|
|
// A string is an unlikely type to be declared elsewhere in VTK-m.
|
|
|
|
vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(UnusualType{});
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
CheckUnknownArray<VTKM_DEFAULT_TYPE_LIST, VTKM_DEFAULT_STORAGE_LIST>(array, 1);
|
|
|
|
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
|
|
|
|
}
|
2021-08-04 13:59:48 +00:00
|
|
|
catch (vtkm::cont::ErrorBadType&)
|
2020-08-05 03:16:29 +00:00
|
|
|
{
|
|
|
|
std::cout << " Caught exception for unrecognized type." << std::endl;
|
|
|
|
}
|
|
|
|
CheckUnknownArray<vtkm::List<UnusualType>, VTKM_DEFAULT_STORAGE_LIST>(array, 1);
|
|
|
|
std::cout << " Found type when type list was reset." << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ArrayHandleType>
|
2020-09-03 15:04:05 +00:00
|
|
|
void TryAsArrayHandle(const ArrayHandleType& array)
|
2020-08-05 03:16:29 +00:00
|
|
|
{
|
2020-09-03 15:04:05 +00:00
|
|
|
CheckAsArrayHandle(array);
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
2020-09-03 15:04:05 +00:00
|
|
|
void TryAsArrayHandle()
|
2020-08-05 03:16:29 +00:00
|
|
|
{
|
|
|
|
std::cout << " Normal array handle." << std::endl;
|
|
|
|
vtkm::Id buffer[ARRAY_SIZE];
|
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
|
|
|
{
|
|
|
|
buffer[index] = TestValue(index, vtkm::Id());
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> array =
|
|
|
|
vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, vtkm::CopyFlag::On);
|
2020-09-03 15:04:05 +00:00
|
|
|
TryAsArrayHandle(array);
|
2020-08-05 03:16:29 +00:00
|
|
|
|
|
|
|
std::cout << " Constant array handle." << std::endl;
|
2020-09-03 15:04:05 +00:00
|
|
|
TryAsArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE));
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
2021-01-05 16:55:44 +00:00
|
|
|
struct CheckExtractedArray
|
|
|
|
{
|
|
|
|
template <typename ExtractedArray, typename OriginalArray>
|
|
|
|
void operator()(const ExtractedArray& extractedArray, const OriginalArray& originalArray) const
|
|
|
|
{
|
|
|
|
using ValueType = typename OriginalArray::ValueType;
|
|
|
|
using FlatVec = vtkm::VecFlat<ValueType>;
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(extractedArray.GetNumberOfComponents() == FlatVec::NUM_COMPONENTS);
|
|
|
|
auto originalPortal = originalArray.ReadPortal();
|
|
|
|
auto extractedPortal = extractedArray.ReadPortal();
|
|
|
|
for (vtkm::Id valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
|
|
|
|
{
|
|
|
|
FlatVec originalData = originalPortal.Get(valueIndex);
|
|
|
|
auto extractedData = extractedPortal.Get(valueIndex);
|
|
|
|
VTKM_TEST_ASSERT(test_equal(originalData, extractedData));
|
|
|
|
}
|
2023-11-07 21:58:31 +00:00
|
|
|
|
|
|
|
// Make sure an extracted array stuffed back into an UnknownArrayHandle works.
|
|
|
|
// This can happen when working with an extracted array that is passed to functions
|
|
|
|
// that are implemented with UnknownArrayHandle.
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownArray{ extractedArray };
|
|
|
|
|
|
|
|
using ComponentType =
|
|
|
|
typename vtkm::VecTraits<typename ExtractedArray::ValueType>::BaseComponentType;
|
|
|
|
vtkm::cont::UnknownArrayHandle newBasic = unknownArray.NewInstanceBasic();
|
|
|
|
newBasic.AsArrayHandle<vtkm::cont::ArrayHandleRuntimeVec<ComponentType>>();
|
|
|
|
vtkm::cont::UnknownArrayHandle newFloat = unknownArray.NewInstanceFloatBasic();
|
|
|
|
newFloat.AsArrayHandle<vtkm::cont::ArrayHandleRuntimeVec<vtkm::FloatDefault>>();
|
2021-01-05 16:55:44 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
template <typename ArrayHandleType>
|
|
|
|
void TryExtractComponent()
|
|
|
|
{
|
|
|
|
using ValueType = typename ArrayHandleType::ValueType;
|
|
|
|
using FlatVec = vtkm::VecFlat<ValueType>;
|
|
|
|
using ComponentType = typename FlatVec::ComponentType;
|
|
|
|
|
|
|
|
ArrayHandleType originalArray;
|
|
|
|
originalArray.Allocate(ARRAY_SIZE);
|
|
|
|
SetPortal(originalArray.WritePortal());
|
|
|
|
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownArray(originalArray);
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(unknownArray.GetNumberOfComponentsFlat() == FlatVec::NUM_COMPONENTS);
|
|
|
|
|
2021-01-05 16:55:44 +00:00
|
|
|
CheckExtractedArray{}(unknownArray.ExtractArrayFromComponents<ComponentType>(), originalArray);
|
|
|
|
|
|
|
|
unknownArray.CastAndCallWithExtractedArray(CheckExtractedArray{}, originalArray);
|
2020-12-16 00:22:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TryExtractComponent()
|
|
|
|
{
|
|
|
|
std::cout << " Scalar array." << std::endl;
|
|
|
|
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::FloatDefault>>();
|
|
|
|
|
2021-01-05 16:55:44 +00:00
|
|
|
std::cout << " Equivalent scalar." << std::endl;
|
|
|
|
TryExtractComponent<vtkm::cont::ArrayHandle<VTKM_UNUSED_INT_TYPE>>();
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
std::cout << " Basic Vec." << std::endl;
|
|
|
|
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::Id3>>();
|
|
|
|
|
|
|
|
std::cout << " Vec of Vecs." << std::endl;
|
|
|
|
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Vec2f, 3>>>();
|
|
|
|
|
|
|
|
std::cout << " Vec of Vecs of Vecs." << std::endl;
|
|
|
|
TryExtractComponent<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Vec<vtkm::Id4, 3>, 2>>>();
|
|
|
|
}
|
|
|
|
|
2020-08-05 03:16:29 +00:00
|
|
|
void TrySetCastArray()
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> knownArray = CreateArray(vtkm::Id{});
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownArray(
|
|
|
|
vtkm::cont::make_ArrayHandleCast<vtkm::Float32>(knownArray));
|
|
|
|
|
|
|
|
// The unknownArray should actually hold the original knownArray type even though we gave it
|
|
|
|
// a cast array.
|
|
|
|
CheckUnknownArray<vtkm::List<vtkm::Id>, vtkm::List<VTKM_DEFAULT_STORAGE_TAG>>(unknownArray, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TrySetMultiplexerArray()
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> knownArray = CreateArray(vtkm::Id{});
|
|
|
|
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandle<vtkm::Id>,
|
|
|
|
vtkm::cont::ArrayHandleConstant<vtkm::Id>>
|
|
|
|
multiplexerArray(knownArray);
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownArray(multiplexerArray);
|
|
|
|
|
|
|
|
// The unknownArray should actually hold the original knownArray type even though we gave it
|
|
|
|
// a multiplexer array.
|
|
|
|
CheckUnknownArray<vtkm::List<vtkm::Id>, vtkm::List<VTKM_DEFAULT_STORAGE_TAG>>(unknownArray, 1);
|
|
|
|
}
|
|
|
|
|
2023-05-16 18:36:47 +00:00
|
|
|
template <typename T, typename BasicComponentType = typename vtkm::VecFlat<T>::ComponentType>
|
2023-02-08 22:16:49 +00:00
|
|
|
void TryConvertRuntimeVec()
|
|
|
|
{
|
|
|
|
using BasicArrayType = vtkm::cont::ArrayHandle<T>;
|
|
|
|
constexpr vtkm::IdComponent numFlatComponents = vtkm::VecFlat<T>::NUM_COMPONENTS;
|
|
|
|
using RuntimeArrayType = vtkm::cont::ArrayHandleRuntimeVec<BasicComponentType>;
|
|
|
|
|
|
|
|
std::cout << " Get basic array as ArrayHandleRuntimeVec" << std::endl;
|
|
|
|
BasicArrayType inputArray;
|
|
|
|
inputArray.Allocate(ARRAY_SIZE);
|
|
|
|
SetPortal(inputArray.WritePortal());
|
|
|
|
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownWithBasic{ inputArray };
|
|
|
|
VTKM_TEST_ASSERT(unknownWithBasic.GetNumberOfComponentsFlat() == numFlatComponents);
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(unknownWithBasic.CanConvert<RuntimeArrayType>());
|
|
|
|
RuntimeArrayType runtimeArray = unknownWithBasic.AsArrayHandle<RuntimeArrayType>();
|
|
|
|
|
|
|
|
// Hack to convert the array handle to a flat array to make it easy to check the runtime array
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::VecFlat<T>> flatInput{ inputArray.GetBuffers() };
|
|
|
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(flatInput, runtimeArray));
|
|
|
|
|
|
|
|
std::cout << " Get ArrayHandleRuntimeVec as basic array" << std::endl;
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownWithRuntimeVec{ runtimeArray };
|
|
|
|
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() == numFlatComponents);
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(unknownWithRuntimeVec.CanConvert<RuntimeArrayType>());
|
|
|
|
VTKM_TEST_ASSERT(unknownWithRuntimeVec.CanConvert<BasicArrayType>());
|
|
|
|
BasicArrayType outputArray = unknownWithRuntimeVec.AsArrayHandle<BasicArrayType>();
|
|
|
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, outputArray));
|
2023-04-19 17:14:05 +00:00
|
|
|
|
|
|
|
std::cout << " Copy ArrayHandleRuntimeVec to a new instance" << std::endl;
|
|
|
|
vtkm::cont::UnknownArrayHandle unknownCopy = unknownWithRuntimeVec.NewInstance();
|
|
|
|
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
|
|
|
|
unknownCopy.GetNumberOfComponentsFlat());
|
|
|
|
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
|
|
|
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
|
|
|
|
|
|
|
|
std::cout << " Copy ArrayHandleRuntimeVec as basic array" << std::endl;
|
|
|
|
unknownCopy = unknownWithRuntimeVec.NewInstanceBasic();
|
|
|
|
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
|
|
|
|
unknownCopy.GetNumberOfComponentsFlat());
|
|
|
|
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
|
|
|
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
|
|
|
|
|
|
|
|
std::cout << " Copy ArrayHandleRuntimeVec to float array" << std::endl;
|
|
|
|
unknownCopy = unknownWithRuntimeVec.NewInstanceFloatBasic();
|
|
|
|
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
|
|
|
|
unknownCopy.GetNumberOfComponentsFlat());
|
|
|
|
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
|
|
|
|
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
|
2023-02-08 22:16:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TryConvertRuntimeVec()
|
|
|
|
{
|
|
|
|
std::cout << " Scalar array." << std::endl;
|
|
|
|
TryConvertRuntimeVec<vtkm::FloatDefault>();
|
|
|
|
|
|
|
|
std::cout << " Equivalent scalar." << std::endl;
|
|
|
|
TryConvertRuntimeVec<VTKM_UNUSED_INT_TYPE>();
|
|
|
|
|
|
|
|
std::cout << " Basic Vec." << std::endl;
|
|
|
|
TryConvertRuntimeVec<vtkm::Id3>();
|
|
|
|
|
|
|
|
std::cout << " Vec of Vecs." << std::endl;
|
|
|
|
TryConvertRuntimeVec<vtkm::Vec<vtkm::Vec2f, 3>>();
|
|
|
|
|
|
|
|
std::cout << " Vec of Vecs of Vecs." << std::endl;
|
|
|
|
TryConvertRuntimeVec<vtkm::Vec<vtkm::Vec<vtkm::Id4, 3>, 2>>();
|
2023-05-16 18:36:47 +00:00
|
|
|
|
|
|
|
std::cout << " Compatible but different C types." << std::endl;
|
|
|
|
if (sizeof(int) == sizeof(long))
|
|
|
|
{
|
|
|
|
TryConvertRuntimeVec<vtkm::Vec<int, 4>, long>();
|
|
|
|
}
|
|
|
|
else // assuming sizeof(long long) == sizeof(long)
|
|
|
|
{
|
|
|
|
TryConvertRuntimeVec<vtkm::Vec<long long, 4>, long>();
|
|
|
|
}
|
2023-02-08 22:16:49 +00:00
|
|
|
}
|
|
|
|
|
2020-08-05 03:16:29 +00:00
|
|
|
struct DefaultTypeFunctor
|
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
void operator()(T) const
|
|
|
|
{
|
|
|
|
TryDefaultType<T>();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void TestUnknownArrayHandle()
|
|
|
|
{
|
|
|
|
std::cout << "Try common types with default type lists." << std::endl;
|
|
|
|
vtkm::testing::Testing::TryTypes(DefaultTypeFunctor{}, VTKM_DEFAULT_TYPE_LIST{});
|
|
|
|
|
|
|
|
std::cout << "Try exemplar VTK-m types." << std::endl;
|
|
|
|
vtkm::testing::Testing::TryTypes(TryBasicVTKmType{});
|
|
|
|
|
|
|
|
std::cout << "Try unusual type." << std::endl;
|
|
|
|
TryUnusualType();
|
|
|
|
|
2020-09-03 15:04:05 +00:00
|
|
|
std::cout << "Try AsArrayHandle" << std::endl;
|
|
|
|
TryAsArrayHandle();
|
2020-08-05 03:16:29 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
std::cout << "Try ExtractComponent" << std::endl;
|
|
|
|
TryExtractComponent();
|
|
|
|
|
2020-08-05 03:16:29 +00:00
|
|
|
std::cout << "Try setting ArrayHandleCast" << std::endl;
|
|
|
|
TrySetCastArray();
|
|
|
|
|
|
|
|
std::cout << "Try setting ArrayHandleMultiplexer" << std::endl;
|
|
|
|
TrySetMultiplexerArray();
|
2023-02-08 22:16:49 +00:00
|
|
|
|
|
|
|
std::cout << "Try converting between ArrayHandleRuntimeVec and basic array" << std::endl;
|
|
|
|
TryConvertRuntimeVec();
|
2020-08-05 03:16:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
int UnitTestUnknownArrayHandle(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
return vtkm::cont::testing::Testing::Run(TestUnknownArrayHandle, argc, argv);
|
|
|
|
}
|