Remove TestingFancyArrayHandles.h

This header file contained tests for a bunch of fancy array handles so
that they could be compiled for each device. These tests were bunched
together because they were replicated for each device implementation,
which was a hassle. However, having a bunch of tests crammed together is
problematic for a number of reasons.

The new testing no longer has a need to make a separate test for each
device. Thus, the tests for the individual devices are removed, and the
tests are split up and added to the basic vtkm_cont tests. In some
cases, individual tests already existed there as well (probably because
the developer did not see the test).
This commit is contained in:
Kenneth Moreland 2022-07-11 11:47:59 -06:00
parent 3a03c38ebf
commit 05bf2e4518
23 changed files with 1397 additions and 1881 deletions

@ -9,7 +9,6 @@
##============================================================================
set(unit_tests
UnitTestCudaArrayHandleFancy.cu
UnitTestCudaBitField.cu
UnitTestCudaCellLocatorRectilinearGrid.cu
UnitTestCudaCellLocatorTwoLevel.cu

@ -1,23 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/cuda/internal/testing/Testing.h>
#include <vtkm/cont/testing/TestingFancyArrayHandles.h>
int UnitTestCudaArrayHandleFancy(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
int result = vtkm::cont::testing::TestingFancyArrayHandles<vtkm::cont::DeviceAdapterTagCuda>::Run(
argc, argv);
return vtkm::cont::cuda::internal::Testing::CheckCudaBeforeExit(result);
}

@ -9,7 +9,6 @@
##============================================================================
set(unit_tests
UnitTestKokkosArrayHandleFancy.cxx
UnitTestKokkosBitField.cxx
UnitTestKokkosCellLocatorRectilinearGrid.cxx
UnitTestKokkosCellLocatorTwoLevel.cxx

@ -1,20 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/kokkos/DeviceAdapterKokkos.h>
#include <vtkm/cont/testing/TestingFancyArrayHandles.h>
int UnitTestKokkosArrayHandleFancy(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{});
return vtkm::cont::testing::TestingFancyArrayHandles<vtkm::cont::DeviceAdapterTagKokkos>::Run(
argc, argv);
}

@ -9,7 +9,6 @@
##============================================================================
set(unit_tests
UnitTestOpenMPArrayHandleFancy.cxx
UnitTestOpenMPBitField.cxx
UnitTestOpenMPCellLocatorRectilinearGrid.cxx
UnitTestOpenMPCellLocatorTwoLevel.cxx

@ -1,19 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/testing/TestingFancyArrayHandles.h>
int UnitTestOpenMPArrayHandleFancy(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{});
return vtkm::cont::testing::TestingFancyArrayHandles<vtkm::cont::DeviceAdapterTagOpenMP>::Run(
argc, argv);
}

@ -9,7 +9,6 @@
##============================================================================
set(unit_tests
UnitTestSerialArrayHandleFancy.cxx
UnitTestSerialBitField.cxx
UnitTestSerialCellLocatorRectilinearGrid.cxx
UnitTestSerialCellLocatorTwoLevel.cxx

@ -1,20 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/TestingFancyArrayHandles.h>
int UnitTestSerialArrayHandleFancy(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{});
return vtkm::cont::testing::TestingFancyArrayHandles<vtkm::cont::DeviceAdapterTagSerial>::Run(
argc, argv);
}

@ -9,7 +9,6 @@
##============================================================================
set(unit_tests
UnitTestTBBArrayHandleFancy.cxx
UnitTestTBBBitField.cxx
UnitTestTBBCellLocatorRectilinearGrid.cxx
UnitTestTBBCellLocatorTwoLevel.cxx

@ -1,20 +0,0 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/cont/testing/TestingFancyArrayHandles.h>
int UnitTestTBBArrayHandleFancy(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
return vtkm::cont::testing::TestingFancyArrayHandles<vtkm::cont::DeviceAdapterTagTBB>::Run(argc,
argv);
}

@ -20,7 +20,6 @@ set(headers
TestingDeviceAdapter.h
TestingDataSetExplicit.h
TestingDataSetSingleType.h
TestingFancyArrayHandles.h
TestingImplicitFunction.h
TestingPointLocatorSparseGrid.h
TestingRuntimeDeviceConfiguration.h
@ -33,10 +32,8 @@ set(unit_tests
UnitTestArrayGetValues.cxx
UnitTestArrayHandleCartesianProduct.cxx
UnitTestArrayHandleCompositeVector.cxx
UnitTestArrayHandleConcatenate.cxx
UnitTestArrayHandleCounting.cxx
UnitTestArrayHandleDiscard.cxx
UnitTestArrayHandleImplicit.cxx
UnitTestArrayHandleIndex.cxx
UnitTestArrayHandleOffsetsToNumComponents.cxx
UnitTestArrayHandleRandomUniformBits.cxx
@ -81,15 +78,25 @@ set(unit_tests_device
UnitTestAlgorithm.cxx
UnitTestArrayCopy.cxx
UnitTestArrayHandle.cxx
UnitTestArrayHandleConcatenate.cxx
UnitTestArrayHandleConstant.cxx
UnitTestArrayHandleCast.cxx
UnitTestArrayHandleDecorator.cxx
UnitTestArrayHandleExtractComponent.cxx
UnitTestArrayHandleGroupVec.cxx
UnitTestArrayHandleGroupVecVariable.cxx
UnitTestArrayHandleImplicit.cxx
UnitTestArrayHandleMultiplexer.cxx
UnitTestArrayHandlePermutation.cxx
UnitTestArrayHandleRandomStandardNormal.cxx
UnitTestArrayHandleRandomUniformReal.cxx
UnitTestArrayHandleRecombineVec.cxx
UnitTestArrayHandleSOA.cxx
UnitTestArrayHandleSwizzle.cxx
UnitTestArrayHandleTransform.cxx
UnitTestArrayHandleView.cxx
UnitTestArrayHandleXGCCoordinates.cxx
UnitTestArrayHandleZip.cxx
UnitTestArrayRangeCompute.cxx
UnitTestCellLocatorChooser.cxx
UnitTestCellLocatorGeneral.cxx

File diff suppressed because it is too large Load Diff

@ -0,0 +1,113 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct TestCastAsInput
{
template <typename CastToType>
VTKM_CONT void operator()(CastToType vtkmNotUsed(type)) const
{
vtkm::cont::Invoker invoke;
using InputArrayType = vtkm::cont::ArrayHandleIndex;
InputArrayType input(ARRAY_SIZE);
vtkm::cont::ArrayHandleCast<CastToType, InputArrayType> castArray =
vtkm::cont::make_ArrayHandleCast(input, CastToType());
vtkm::cont::ArrayHandle<CastToType> result;
invoke(PassThrough{}, castArray, result);
// verify results
vtkm::Id length = ARRAY_SIZE;
auto resultPortal = result.ReadPortal();
auto inputPortal = input.ReadPortal();
for (vtkm::Id i = 0; i < length; ++i)
{
VTKM_TEST_ASSERT(resultPortal.Get(i) == static_cast<CastToType>(inputPortal.Get(i)),
"Casting ArrayHandle Failed");
}
castArray.ReleaseResources();
}
};
struct TestCastAsOutput
{
template <typename CastFromType>
VTKM_CONT void operator()(CastFromType vtkmNotUsed(type)) const
{
vtkm::cont::Invoker invoke;
using InputArrayType = vtkm::cont::ArrayHandleIndex;
using ResultArrayType = vtkm::cont::ArrayHandle<CastFromType>;
InputArrayType input(ARRAY_SIZE);
ResultArrayType result;
vtkm::cont::ArrayHandleCast<vtkm::Id, ResultArrayType> castArray =
vtkm::cont::make_ArrayHandleCast<CastFromType>(result);
invoke(PassThrough{}, input, castArray);
// verify results
vtkm::Id length = ARRAY_SIZE;
auto inputPortal = input.ReadPortal();
auto resultPortal = result.ReadPortal();
for (vtkm::Id i = 0; i < length; ++i)
{
VTKM_TEST_ASSERT(inputPortal.Get(i) == static_cast<vtkm::Id>(resultPortal.Get(i)),
"Casting ArrayHandle Failed");
}
}
};
void Run()
{
using CastTypesToTest = vtkm::List<vtkm::Int32, vtkm::UInt32>;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleCast as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestCastAsInput(), CastTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleCast as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestCastAsOutput(), CastTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleCast(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -10,16 +10,101 @@
#include <vtkm/cont/ArrayHandleConcatenate.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 4;
constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename ValueType>
struct IndexSquared
{
VTKM_EXEC_CONT
ValueType operator()(vtkm::Id index) const
{
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
return ValueType(static_cast<ComponentType>(index * index));
}
};
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
VTKM_CONT void TestConcatInvoke()
{
using ValueType = vtkm::Id;
using FunctorType = IndexSquared<ValueType>;
using ValueHandleType = vtkm::cont::ArrayHandleImplicit<FunctorType>;
using BasicArrayType = vtkm::cont::ArrayHandle<ValueType>;
using ConcatenateType = vtkm::cont::ArrayHandleConcatenate<ValueHandleType, BasicArrayType>;
FunctorType functor;
for (vtkm::Id start_pos = 0; start_pos < ARRAY_SIZE; start_pos += ARRAY_SIZE / 4)
{
vtkm::Id implicitLen = ARRAY_SIZE - start_pos;
vtkm::Id basicLen = start_pos;
// make an implicit array
ValueHandleType implicit = vtkm::cont::make_ArrayHandleImplicit(functor, implicitLen);
// make a basic array
std::vector<ValueType> basicVec;
for (vtkm::Id i = 0; i < basicLen; i++)
{
basicVec.push_back(ValueType(i));
}
BasicArrayType basic = vtkm::cont::make_ArrayHandle(basicVec, vtkm::CopyFlag::Off);
// concatenate two arrays together
ConcatenateType concatenate = vtkm::cont::make_ArrayHandleConcatenate(implicit, basic);
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::cont::Invoker invoke;
invoke(PassThrough{}, concatenate, result);
//verify that the control portal works
auto resultPortal = result.ReadPortal();
auto implicitPortal = implicit.ReadPortal();
auto basicPortal = basic.ReadPortal();
auto concatPortal = concatenate.ReadPortal();
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
const ValueType result_v = resultPortal.Get(i);
ValueType correct_value;
if (i < implicitLen)
correct_value = implicitPortal.Get(i);
else
correct_value = basicPortal.Get(i - implicitLen);
const ValueType control_value = concatPortal.Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value),
"ArrayHandleConcatenate as Input Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value),
"ArrayHandleConcatenate as Input Failed");
}
concatenate.ReleaseResources();
}
}
void TestConcatOfConcat()
{
std::cout << "Test concat of concat" << std::endl;
vtkm::cont::ArrayHandleIndex array1(ARRAY_SIZE);
vtkm::cont::ArrayHandleIndex array2(2 * ARRAY_SIZE);
@ -56,6 +141,8 @@ void TestConcatOfConcat()
void TestConcatenateEmptyArray()
{
std::cout << "Test empty array" << std::endl;
std::vector<vtkm::Float64> vec;
for (vtkm::Id i = 0; i < ARRAY_SIZE; i++)
{
@ -80,6 +167,8 @@ void TestConcatenateEmptyArray()
void TestConcatenateFill()
{
std::cout << "Test fill" << std::endl;
using T = vtkm::FloatDefault;
vtkm::cont::ArrayHandle<T> array1;
vtkm::cont::ArrayHandle<T> array2;
@ -117,6 +206,7 @@ void TestConcatenateFill()
void TestArrayHandleConcatenate()
{
TestConcatInvoke();
TestConcatOfConcat();
TestConcatenateEmptyArray();
TestConcatenateFill();

@ -0,0 +1,82 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
using HandleTypesToTest = vtkm::List<vtkm::Id, vtkm::Vec2i_32, vtkm::FloatDefault, vtkm::Vec3f_64>;
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct TestConstantAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const ValueType value = TestValue(43, ValueType());
vtkm::cont::ArrayHandleConstant<ValueType> constant =
vtkm::cont::make_ArrayHandleConstant(value, ARRAY_SIZE);
VTKM_TEST_ASSERT(constant.GetValue() == value);
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::cont::Invoker invoke;
invoke(PassThrough{}, constant, result);
//verify that the control portal works
auto resultPortal = result.ReadPortal();
auto constantPortal = constant.ReadPortal();
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
const ValueType result_v = resultPortal.Get(i);
const ValueType control_value = constantPortal.Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, value), "Counting Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value), "Counting Handle Control Failed");
}
constant.ReleaseResources();
}
};
void Run()
{
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleConstant as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestConstantAsInput(), HandleTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleConstant(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -0,0 +1,150 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleGroupVec.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
struct PassThrough : vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
template <vtkm::IdComponent NUM_COMPONENTS>
struct TestGroupVecAsInput
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
using ValueType = vtkm::Vec<ComponentType, NUM_COMPONENTS>;
vtkm::cont::ArrayHandle<ComponentType> baseArray;
baseArray.Allocate(ARRAY_SIZE * NUM_COMPONENTS);
SetPortal(baseArray.WritePortal());
vtkm::cont::ArrayHandleGroupVec<vtkm::cont::ArrayHandle<ComponentType>, NUM_COMPONENTS>
groupArray(baseArray);
VTKM_TEST_ASSERT(groupArray.GetNumberOfValues() == ARRAY_SIZE,
"Group array reporting wrong array size.");
vtkm::cont::ArrayHandle<ValueType> resultArray;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(groupArray, resultArray);
VTKM_TEST_ASSERT(resultArray.GetNumberOfValues() == ARRAY_SIZE, "Got bad result array size.");
//verify that the control portal works
vtkm::Id totalIndex = 0;
auto resultPortal = resultArray.ReadPortal();
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
{
const ValueType result = resultPortal.Get(index);
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
const ComponentType expectedValue = TestValue(totalIndex, ComponentType());
VTKM_TEST_ASSERT(test_equal(result[componentIndex], expectedValue),
"Result array got wrong value.");
totalIndex++;
}
}
groupArray.ReleaseResources();
}
};
template <vtkm::IdComponent NUM_COMPONENTS>
struct TestGroupVecAsOutput
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
using ValueType = vtkm::Vec<ComponentType, NUM_COMPONENTS>;
vtkm::cont::ArrayHandle<ValueType> baseArray;
baseArray.Allocate(ARRAY_SIZE);
SetPortal(baseArray.WritePortal());
vtkm::cont::ArrayHandle<ComponentType> resultArray;
vtkm::cont::ArrayHandleGroupVec<vtkm::cont::ArrayHandle<ComponentType>, NUM_COMPONENTS>
groupArray(resultArray);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(baseArray, groupArray);
VTKM_TEST_ASSERT(groupArray.GetNumberOfValues() == ARRAY_SIZE,
"Group array reporting wrong array size.");
VTKM_TEST_ASSERT(resultArray.GetNumberOfValues() == ARRAY_SIZE * NUM_COMPONENTS,
"Got bad result array size.");
//verify that the control portal works
vtkm::Id totalIndex = 0;
auto resultPortal = resultArray.ReadPortal();
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
{
const ValueType expectedValue = TestValue(index, ValueType());
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
const ComponentType result = resultPortal.Get(totalIndex);
VTKM_TEST_ASSERT(test_equal(result, expectedValue[componentIndex]),
"Result array got wrong value.");
totalIndex++;
}
}
}
};
void Run()
{
using HandleTypesToTest =
vtkm::List<vtkm::Id, vtkm::Vec2i_32, vtkm::FloatDefault, vtkm::Vec3f_64>;
using ScalarTypesToTest = vtkm::List<vtkm::UInt8, vtkm::FloatDefault>;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<3> as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestGroupVecAsInput<3>(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<4> as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestGroupVecAsInput<4>(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<2> as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestGroupVecAsOutput<2>(), ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<3> as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestGroupVecAsOutput<3>(), ScalarTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleGroupVec(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -0,0 +1,155 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ConvertNumComponentsToOffsets.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
// GroupVecVariable is a bit strange because it supports values of different
// lengths, so a simple pass through worklet will not work. Use custom
// worklets.
struct GroupVariableInputWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, WorkIndex, _2);
template <typename InputType>
VTKM_EXEC void operator()(const InputType& input, vtkm::Id workIndex, vtkm::Id& dummyOut) const
{
using ComponentType = typename InputType::ComponentType;
vtkm::IdComponent expectedSize = static_cast<vtkm::IdComponent>(workIndex);
if (expectedSize != input.GetNumberOfComponents())
{
this->RaiseError("Got unexpected number of components.");
}
vtkm::Id valueIndex = workIndex * (workIndex - 1) / 2;
dummyOut = valueIndex;
for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++)
{
ComponentType expectedValue = TestValue(valueIndex, ComponentType());
if (vtkm::Abs(expectedValue - input[componentIndex]) > 0.000001)
{
this->RaiseError("Got bad value in GroupVariableInputWorklet.");
}
valueIndex++;
}
}
};
struct TestGroupVecVariableAsInput
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
vtkm::cont::Invoker invoke;
vtkm::Id sourceArraySize;
vtkm::cont::ArrayHandle<vtkm::Id> numComponentsArray;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray);
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize);
vtkm::cont::ArrayHandle<ComponentType> sourceArray;
sourceArray.Allocate(sourceArraySize);
SetPortal(sourceArray.WritePortal());
vtkm::cont::ArrayHandle<vtkm::Id> dummyArray;
auto groupVecArray = vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray);
invoke(GroupVariableInputWorklet{}, groupVecArray, dummyArray);
dummyArray.ReadPortal();
groupVecArray.ReleaseResources();
}
};
// GroupVecVariable is a bit strange because it supports values of different
// lengths, so a simple pass through worklet will not work. Use custom
// worklets.
struct GroupVariableOutputWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_2, WorkIndex);
template <typename OutputType>
VTKM_EXEC void operator()(OutputType& output, vtkm::Id workIndex) const
{
using ComponentType = typename OutputType::ComponentType;
vtkm::IdComponent expectedSize = static_cast<vtkm::IdComponent>(workIndex);
if (expectedSize != output.GetNumberOfComponents())
{
this->RaiseError("Got unexpected number of components.");
}
vtkm::Id valueIndex = workIndex * (workIndex - 1) / 2;
for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++)
{
output[componentIndex] = TestValue(valueIndex, ComponentType());
valueIndex++;
}
}
};
struct TestGroupVecVariableAsOutput
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
vtkm::Id sourceArraySize;
vtkm::cont::ArrayHandle<vtkm::Id> numComponentsArray;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray);
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize);
vtkm::cont::ArrayHandle<ComponentType> sourceArray;
sourceArray.Allocate(sourceArraySize);
vtkm::worklet::DispatcherMapField<GroupVariableOutputWorklet> dispatcher;
dispatcher.Invoke(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE),
vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray));
CheckPortal(sourceArray.ReadPortal());
}
};
void Run()
{
using ScalarTypesToTest = vtkm::List<vtkm::UInt8, vtkm::FloatDefault>;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVecVariable as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestGroupVecVariableAsInput(), ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVecVariable as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestGroupVecVariableAsOutput(), ScalarTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleGroupVecVariable(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -10,8 +10,11 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleImplicit.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/VecTraits.h>
#include <vtkm/cont/testing/Testing.h>
@ -32,6 +35,18 @@ struct IndexSquared
}
};
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct ImplicitTests
{
template <typename ValueType>
@ -44,7 +59,7 @@ struct ImplicitTests
ImplicitHandle implicit = vtkm::cont::make_ArrayHandleImplicit(functor, ARRAY_SIZE);
//verify that the control portal works
std::cout << "verify that the control portal works" << std::endl;
auto implicitPortal = implicit.ReadPortal();
for (int i = 0; i < ARRAY_SIZE; ++i)
{
@ -53,7 +68,7 @@ struct ImplicitTests
VTKM_TEST_ASSERT(v == correct_value, "Implicit Handle Failed");
}
//verify that the execution portal works
std::cout << "verify that the execution portal works" << std::endl;
vtkm::cont::Token token;
using Device = vtkm::cont::DeviceAdapterTagSerial;
using CEPortal = typename ImplicitHandle::ReadPortalType;
@ -64,6 +79,18 @@ struct ImplicitTests
const ValueType correct_value = functor(i);
VTKM_TEST_ASSERT(v == correct_value, "Implicit Handle Failed");
}
std::cout << "verify that the array handle works in a worklet on the device" << std::endl;
vtkm::cont::Invoker invoke;
vtkm::cont::ArrayHandle<ValueType> result;
invoke(PassThrough{}, implicit, result);
auto resultPortal = result.ReadPortal();
for (int i = 0; i < ARRAY_SIZE; ++i)
{
const ValueType value = resultPortal.Get(i);
const ValueType correctValue = functor(i);
VTKM_TEST_ASSERT(test_equal(value, correctValue));
}
}
};

@ -0,0 +1,109 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleRecombineVec.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
struct PassThrough : vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct TestRecombineVecAsInput
{
template <typename T>
VTKM_CONT void operator()(T) const
{
vtkm::cont::ArrayHandle<T> baseArray;
baseArray.Allocate(ARRAY_SIZE);
SetPortal(baseArray.WritePortal());
using VTraits = vtkm::VecTraits<T>;
vtkm::cont::ArrayHandleRecombineVec<typename VTraits::ComponentType> recombinedArray;
for (vtkm::IdComponent cIndex = 0; cIndex < VTraits::NUM_COMPONENTS; ++cIndex)
{
recombinedArray.AppendComponentArray(vtkm::cont::ArrayExtractComponent(baseArray, cIndex));
}
VTKM_TEST_ASSERT(recombinedArray.GetNumberOfComponents() == VTraits::NUM_COMPONENTS);
VTKM_TEST_ASSERT(recombinedArray.GetNumberOfValues() == ARRAY_SIZE);
vtkm::cont::ArrayHandle<T> outputArray;
vtkm::cont::Invoker invoke;
invoke(PassThrough{}, recombinedArray, outputArray);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(baseArray, outputArray));
}
};
struct TestRecombineVecAsOutput
{
template <typename T>
VTKM_CONT void operator()(T) const
{
vtkm::cont::ArrayHandle<T> baseArray;
baseArray.Allocate(ARRAY_SIZE);
SetPortal(baseArray.WritePortal());
vtkm::cont::ArrayHandle<T> outputArray;
outputArray.Allocate(ARRAY_SIZE); // Cannot resize after recombine
using VTraits = vtkm::VecTraits<T>;
vtkm::cont::ArrayHandleRecombineVec<typename VTraits::ComponentType> recombinedArray;
for (vtkm::IdComponent cIndex = 0; cIndex < VTraits::NUM_COMPONENTS; ++cIndex)
{
recombinedArray.AppendComponentArray(vtkm::cont::ArrayExtractComponent(outputArray, cIndex));
}
VTKM_TEST_ASSERT(recombinedArray.GetNumberOfComponents() == VTraits::NUM_COMPONENTS);
VTKM_TEST_ASSERT(recombinedArray.GetNumberOfValues() == ARRAY_SIZE);
vtkm::cont::Invoker invoke;
invoke(PassThrough{}, baseArray, recombinedArray);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(baseArray, outputArray));
}
};
void Run()
{
using HandleTypesToTest =
vtkm::List<vtkm::Id, vtkm::Vec2i_32, vtkm::FloatDefault, vtkm::Vec3f_64>;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleRecombineVec as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestRecombineVecAsInput(), HandleTypesToTest{});
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleRecombineVec as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestRecombineVecAsOutput(), HandleTypesToTest{});
}
} // anonymous namespace
int UnitTestArrayHandleRecombineVec(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -0,0 +1,235 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleSOA.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
using ScalarTypesToTest = vtkm::List<vtkm::UInt8, vtkm::FloatDefault>;
using VectorTypesToTest = vtkm::List<vtkm::Vec2i_8, vtkm::Vec3f_32>;
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct TestArrayPortalSOA
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
constexpr vtkm::IdComponent NUM_COMPONENTS = 4;
using ValueType = vtkm::Vec<ComponentType, NUM_COMPONENTS>;
using ComponentArrayType = vtkm::cont::ArrayHandle<ComponentType>;
using SOAPortalType =
vtkm::internal::ArrayPortalSOA<ValueType, typename ComponentArrayType::WritePortalType>;
std::cout << "Test SOA portal reflects data in component portals." << std::endl;
SOAPortalType soaPortalIn(ARRAY_SIZE);
std::array<vtkm::cont::ArrayHandle<ComponentType>, NUM_COMPONENTS> implArrays;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
{
vtkm::cont::ArrayHandle<ComponentType> array;
array.Allocate(ARRAY_SIZE);
auto portal = array.WritePortal();
for (vtkm::IdComponent valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
{
portal.Set(valueIndex, TestValue(valueIndex, ValueType{})[componentIndex]);
}
soaPortalIn.SetPortal(componentIndex, portal);
implArrays[static_cast<std::size_t>(componentIndex)] = array;
}
VTKM_TEST_ASSERT(soaPortalIn.GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(soaPortalIn);
std::cout << "Test data set in SOA portal gets set in component portals." << std::endl;
{
SOAPortalType soaPortalOut(ARRAY_SIZE);
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
{
vtkm::cont::ArrayHandle<ComponentType> array;
array.Allocate(ARRAY_SIZE);
auto portal = array.WritePortal();
soaPortalOut.SetPortal(componentIndex, portal);
implArrays[static_cast<std::size_t>(componentIndex)] = array;
}
SetPortal(soaPortalOut);
}
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
{
auto portal = implArrays[static_cast<size_t>(componentIndex)].ReadPortal();
for (vtkm::Id valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
{
ComponentType x = TestValue(valueIndex, ValueType{})[componentIndex];
VTKM_TEST_ASSERT(test_equal(x, portal.Get(valueIndex)));
}
}
}
};
struct TestSOAAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using VTraits = vtkm::VecTraits<ValueType>;
using ComponentType = typename VTraits::ComponentType;
constexpr vtkm::IdComponent NUM_COMPONENTS = VTraits::NUM_COMPONENTS;
{
vtkm::cont::ArrayHandleSOA<ValueType> soaArray;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
{
vtkm::cont::ArrayHandle<ComponentType> componentArray;
componentArray.Allocate(ARRAY_SIZE);
auto componentPortal = componentArray.WritePortal();
for (vtkm::Id valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
{
componentPortal.Set(
valueIndex, VTraits::GetComponent(TestValue(valueIndex, ValueType{}), componentIndex));
}
soaArray.SetArray(componentIndex, componentArray);
}
VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE);
VTKM_TEST_ASSERT(soaArray.ReadPortal().GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(soaArray.ReadPortal());
vtkm::cont::ArrayHandle<ValueType> basicArray;
vtkm::cont::ArrayCopyDevice(soaArray, basicArray);
VTKM_TEST_ASSERT(basicArray.GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(basicArray.ReadPortal());
}
{
// Check constructors
using Vec3 = vtkm::Vec<ComponentType, 3>;
std::vector<ComponentType> vector0;
std::vector<ComponentType> vector1;
std::vector<ComponentType> vector2;
for (vtkm::Id valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
{
Vec3 value = TestValue(valueIndex, Vec3{});
vector0.push_back(value[0]);
vector1.push_back(value[1]);
vector2.push_back(value[2]);
}
{
vtkm::cont::ArrayHandleSOA<Vec3> soaArray =
vtkm::cont::make_ArrayHandleSOA<Vec3>({ vector0, vector1, vector2 });
VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(soaArray.ReadPortal());
}
{
vtkm::cont::ArrayHandleSOA<Vec3> soaArray =
vtkm::cont::make_ArrayHandleSOA(vtkm::CopyFlag::Off, vector0, vector1, vector2);
VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(soaArray.ReadPortal());
// Make sure calling ReleaseResources does not result in error.
soaArray.ReleaseResources();
}
{
vtkm::cont::ArrayHandleSOA<Vec3> soaArray = vtkm::cont::make_ArrayHandleSOA<Vec3>(
{ vector0.data(), vector1.data(), vector2.data() }, ARRAY_SIZE, vtkm::CopyFlag::Off);
VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(soaArray.ReadPortal());
}
{
vtkm::cont::ArrayHandleSOA<Vec3> soaArray = vtkm::cont::make_ArrayHandleSOA(
ARRAY_SIZE, vtkm::CopyFlag::Off, vector0.data(), vector1.data(), vector2.data());
VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE);
CheckPortal(soaArray.ReadPortal());
}
}
}
};
struct TestSOAAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using VTraits = vtkm::VecTraits<ValueType>;
using ComponentType = typename VTraits::ComponentType;
constexpr vtkm::IdComponent NUM_COMPONENTS = VTraits::NUM_COMPONENTS;
vtkm::cont::ArrayHandle<ValueType> basicArray;
basicArray.Allocate(ARRAY_SIZE);
SetPortal(basicArray.WritePortal());
vtkm::cont::ArrayHandleSOA<ValueType> soaArray;
vtkm::cont::Invoker{}(PassThrough{}, basicArray, soaArray);
VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE);
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex)
{
vtkm::cont::ArrayHandle<ComponentType> componentArray = soaArray.GetArray(componentIndex);
auto componentPortal = componentArray.ReadPortal();
for (vtkm::Id valueIndex = 0; valueIndex < ARRAY_SIZE; ++valueIndex)
{
ComponentType expected =
VTraits::GetComponent(TestValue(valueIndex, ValueType{}), componentIndex);
ComponentType got = componentPortal.Get(valueIndex);
VTKM_TEST_ASSERT(test_equal(expected, got));
}
}
}
};
static void Run()
{
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayPortalSOA" << std::endl;
vtkm::testing::Testing::TryTypes(TestArrayPortalSOA(), ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleSOA as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestSOAAsInput(), VectorTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleSOA as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestSOAAsOutput(), VectorTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleSOA(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -75,6 +75,51 @@ VTKM_CONT void CheckControlPortals(const OriginalArrayHandleType& originalArray,
}
}
struct ValueScale
{
ValueScale()
: Factor(1.0)
{
}
ValueScale(vtkm::Float64 factor)
: Factor(factor)
{
}
template <typename ValueType>
VTKM_EXEC_CONT ValueType operator()(const ValueType& v) const
{
using Traits = vtkm::VecTraits<ValueType>;
using TTraits = vtkm::TypeTraits<ValueType>;
using ComponentType = typename Traits::ComponentType;
ValueType result = TTraits::ZeroInitialization();
for (vtkm::IdComponent i = 0; i < Traits::GetNumberOfComponents(v); ++i)
{
vtkm::Float64 vi = static_cast<vtkm::Float64>(Traits::GetComponent(v, i));
vtkm::Float64 ri = vi * this->Factor;
Traits::SetComponent(result, i, static_cast<ComponentType>(ri));
}
return result;
}
private:
vtkm::Float64 Factor;
};
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
template <typename InputValueType>
struct TransformTests
{
@ -107,19 +152,13 @@ struct TransformTests
std::cout << "Test a transform handle with a normal handle as the values" << std::endl;
//we are going to connect the two handles up, and than fill
//the values and make the transform sees the new values in the handle
//the values and make sure the transform sees the new values in the handle
vtkm::cont::ArrayHandle<InputValueType> input;
TransformHandle thandle(input, functor);
using Portal = typename vtkm::cont::ArrayHandle<InputValueType>::WritePortalType;
input.Allocate(ARRAY_SIZE);
{
Portal portal = input.WritePortal();
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
{
portal.Set(index, TestValue(index, InputValueType()));
}
}
SetPortal(input.WritePortal());
CheckControlPortals(input, thandle);
@ -139,6 +178,33 @@ struct TransformTests
std::cout << " Verify that the execution portal works" << std::endl;
invoke(CheckTransformWorklet{}, input, thandle);
std::cout << "Write to a transformed array with an inverse transform" << std::endl;
{
ValueScale scaleUp(2.0);
ValueScale scaleDown(1.0 / 2.0);
input.Allocate(ARRAY_SIZE);
SetPortal(input.WritePortal());
vtkm::cont::ArrayHandle<InputValueType> output;
auto transformed = vtkm::cont::make_ArrayHandleTransform(output, scaleUp, scaleDown);
invoke(PassThrough{}, input, transformed);
//verify that the control portal works
auto outputPortal = output.ReadPortal();
auto transformedPortal = transformed.ReadPortal();
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
const InputValueType result_v = outputPortal.Get(i);
const InputValueType correct_value = scaleDown(TestValue(i, InputValueType()));
const InputValueType control_value = transformedPortal.Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Transform Handle Failed");
VTKM_TEST_ASSERT(test_equal(scaleUp(result_v), control_value),
"Transform Handle Control Failed");
}
}
}
};

@ -0,0 +1,145 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename ValueType>
struct IndexSquared
{
VTKM_EXEC_CONT
ValueType operator()(vtkm::Id index) const
{
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
return ValueType(static_cast<ComponentType>(index * index));
}
};
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct TestViewAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using FunctorType = IndexSquared<ValueType>;
using ValueHandleType = vtkm::cont::ArrayHandleImplicit<FunctorType>;
using ViewHandleType = vtkm::cont::ArrayHandleView<ValueHandleType>;
FunctorType functor;
for (vtkm::Id start_pos = 0; start_pos < ARRAY_SIZE; start_pos += ARRAY_SIZE / 4)
{
const vtkm::Id counting_ARRAY_SIZE = ARRAY_SIZE - start_pos;
ValueHandleType implicit = vtkm::cont::make_ArrayHandleImplicit(functor, ARRAY_SIZE);
ViewHandleType view =
vtkm::cont::make_ArrayHandleView(implicit, start_pos, counting_ARRAY_SIZE);
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::cont::Invoker invoke;
invoke(PassThrough{}, view, result);
//verify that the control portal works
auto resultPortal = result.ReadPortal();
auto implicitPortal = implicit.ReadPortal();
auto viewPortal = view.ReadPortal();
for (vtkm::Id i = 0; i < counting_ARRAY_SIZE; ++i)
{
const vtkm::Id value_index = i;
const vtkm::Id key_index = start_pos + i;
const ValueType result_v = resultPortal.Get(value_index);
const ValueType correct_value = implicitPortal.Get(key_index);
const ValueType control_value = viewPortal.Get(value_index);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Implicit Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value), "Implicit Handle Failed");
}
view.ReleaseResources();
}
}
};
struct TestViewAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using ValueHandleType = vtkm::cont::ArrayHandle<ValueType>;
using ViewHandleType = vtkm::cont::ArrayHandleView<ValueHandleType>;
vtkm::cont::ArrayHandle<ValueType> input;
input.Allocate(ARRAY_SIZE);
SetPortal(input.WritePortal());
ValueHandleType values;
values.Allocate(ARRAY_SIZE * 2);
ViewHandleType view = vtkm::cont::make_ArrayHandleView(values, ARRAY_SIZE, ARRAY_SIZE);
vtkm::cont::Invoker invoke;
invoke(PassThrough{}, input, view);
//verify that the control portal works
CheckPortal(view.ReadPortal());
//verify that filling works
const ValueType expected = TestValue(20, ValueType{});
view.Fill(expected);
auto valuesPortal = values.ReadPortal();
for (vtkm::Id index = ARRAY_SIZE; index < 2 * ARRAY_SIZE; ++index)
{
VTKM_TEST_ASSERT(valuesPortal.Get(index) == expected);
}
}
};
void Run()
{
using HandleTypesToTest =
vtkm::List<vtkm::Id, vtkm::Vec2i_32, vtkm::FloatDefault, vtkm::Vec3f_64>;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleView as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestViewAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleView as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestViewAsOutput(), HandleTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleView(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}

@ -0,0 +1,204 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id ARRAY_SIZE = 10;
struct PassThrough : vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
template <typename InValue, typename OutValue>
VTKM_EXEC void operator()(const InValue& inValue, OutValue& outValue) const
{
outValue = inValue;
}
};
struct InplaceFunctorPair : vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldInOut);
using ExecutionSignature = void(_1);
template <typename T>
VTKM_EXEC void operator()(vtkm::Pair<T, T>& value) const
{
value.second = value.first;
}
};
struct TestZipAsInput
{
vtkm::cont::Invoker Invoke;
template <typename KeyType, typename ValueType>
VTKM_CONT void operator()(vtkm::Pair<KeyType, ValueType> vtkmNotUsed(pair)) const
{
using PairType = vtkm::Pair<KeyType, ValueType>;
using KeyComponentType = typename vtkm::VecTraits<KeyType>::ComponentType;
using ValueComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
KeyType testKeys[ARRAY_SIZE];
ValueType testValues[ARRAY_SIZE];
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
testKeys[i] = KeyType(static_cast<KeyComponentType>(ARRAY_SIZE - i));
testValues[i] = ValueType(static_cast<ValueComponentType>(i));
}
vtkm::cont::ArrayHandle<KeyType> keys =
vtkm::cont::make_ArrayHandle(testKeys, ARRAY_SIZE, vtkm::CopyFlag::Off);
vtkm::cont::ArrayHandle<ValueType> values =
vtkm::cont::make_ArrayHandle(testValues, ARRAY_SIZE, vtkm::CopyFlag::Off);
vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<KeyType>, vtkm::cont::ArrayHandle<ValueType>>
zip = vtkm::cont::make_ArrayHandleZip(keys, values);
vtkm::cont::ArrayHandle<PairType> result;
this->Invoke(PassThrough{}, zip, result);
//verify that the control portal works
auto resultPortal = result.ReadPortal();
for (int i = 0; i < ARRAY_SIZE; ++i)
{
const PairType result_v = resultPortal.Get(i);
const PairType correct_value(KeyType(static_cast<KeyComponentType>(ARRAY_SIZE - i)),
ValueType(static_cast<ValueComponentType>(i)));
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "ArrayHandleZip Failed as input");
}
zip.ReleaseResources();
}
};
struct TestZipAsOutput
{
vtkm::cont::Invoker Invoke;
template <typename KeyType, typename ValueType>
VTKM_CONT void operator()(vtkm::Pair<KeyType, ValueType> vtkmNotUsed(pair)) const
{
using PairType = vtkm::Pair<KeyType, ValueType>;
using KeyComponentType = typename vtkm::VecTraits<KeyType>::ComponentType;
using ValueComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
PairType testKeysAndValues[ARRAY_SIZE];
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
testKeysAndValues[i] = PairType(KeyType(static_cast<KeyComponentType>(ARRAY_SIZE - i)),
ValueType(static_cast<ValueComponentType>(i)));
}
vtkm::cont::ArrayHandle<PairType> input =
vtkm::cont::make_ArrayHandle(testKeysAndValues, ARRAY_SIZE, vtkm::CopyFlag::Off);
vtkm::cont::ArrayHandle<KeyType> result_keys;
vtkm::cont::ArrayHandle<ValueType> result_values;
vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<KeyType>, vtkm::cont::ArrayHandle<ValueType>>
result_zip = vtkm::cont::make_ArrayHandleZip(result_keys, result_values);
this->Invoke(PassThrough{}, input, result_zip);
//now the two arrays we have zipped should have data inside them
auto keysPortal = result_keys.ReadPortal();
auto valsPortal = result_values.ReadPortal();
for (int i = 0; i < ARRAY_SIZE; ++i)
{
const KeyType result_key = keysPortal.Get(i);
const ValueType result_value = valsPortal.Get(i);
VTKM_TEST_ASSERT(
test_equal(result_key, KeyType(static_cast<KeyComponentType>(ARRAY_SIZE - i))),
"ArrayHandleZip Failed as input for key");
VTKM_TEST_ASSERT(test_equal(result_value, ValueType(static_cast<ValueComponentType>(i))),
"ArrayHandleZip Failed as input for value");
}
// Test filling the zipped array.
vtkm::cont::printSummary_ArrayHandle(result_zip, std::cout, true);
PairType fillValue{ TestValue(1, KeyType{}), TestValue(2, ValueType{}) };
result_zip.Fill(fillValue, 1);
vtkm::cont::printSummary_ArrayHandle(result_zip, std::cout, true);
keysPortal = result_keys.ReadPortal();
valsPortal = result_values.ReadPortal();
// First entry should be the same.
VTKM_TEST_ASSERT(
test_equal(keysPortal.Get(0), KeyType(static_cast<KeyComponentType>(ARRAY_SIZE))));
VTKM_TEST_ASSERT(test_equal(valsPortal.Get(0), ValueType(static_cast<ValueComponentType>(0))));
// The rest should be fillValue
for (vtkm::Id index = 1; index < ARRAY_SIZE; ++index)
{
const KeyType result_key = keysPortal.Get(index);
const ValueType result_value = valsPortal.Get(index);
VTKM_TEST_ASSERT(test_equal(result_key, fillValue.first));
VTKM_TEST_ASSERT(test_equal(result_value, fillValue.second));
}
}
};
struct TestZipAsInPlace
{
vtkm::cont::Invoker Invoke;
template <typename ValueType>
VTKM_CONT void operator()(ValueType) const
{
vtkm::cont::ArrayHandle<ValueType> inputValues;
inputValues.Allocate(ARRAY_SIZE);
SetPortal(inputValues.WritePortal());
vtkm::cont::ArrayHandle<ValueType> outputValues;
outputValues.Allocate(ARRAY_SIZE);
this->Invoke(InplaceFunctorPair{}, vtkm::cont::make_ArrayHandleZip(inputValues, outputValues));
CheckPortal(outputValues.ReadPortal());
}
};
void Run()
{
using ZipTypesToTest = vtkm::List<vtkm::Pair<vtkm::UInt8, vtkm::Id>,
vtkm::Pair<vtkm::Float64, vtkm::Vec4ui_8>,
vtkm::Pair<vtkm::Vec3f_32, vtkm::Vec4i_8>>;
using HandleTypesToTest =
vtkm::List<vtkm::Id, vtkm::Vec2i_32, vtkm::FloatDefault, vtkm::Vec3f_64>;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleZip as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestZipAsInput(), ZipTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleZip as Output" << std::endl;
vtkm::testing::Testing::TryTypes(TestZipAsOutput(), ZipTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleZip as In Place" << std::endl;
vtkm::testing::Testing::TryTypes(TestZipAsInPlace(), HandleTypesToTest());
}
} // anonymous namespace
int UnitTestArrayHandleZip(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}