vtk-m/vtkm/cont/testing/TestingFancyArrayHandles.h
Kenneth Moreland 2b05487398 Add ExecutionAndControlObjectBase
This is a subclass of ExecutionObject and a superset of its
functionality. In addition to having a PrepareForExecution method, it
also has a PrepareForControl method that gets an object appropriate for
the control environment. This is helpful for situations where you need
code to work in both environments, such as the functor in an
ArrayHandleTransform.

Also added several runtime checks for execution objects and execution
and cotnrol objects.
2018-09-08 11:54:28 -06:00

1389 lines
51 KiB
C++

//=============================================================================
//
// 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 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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_cont_testing_TestingFancyArrayHandles_h
#define vtk_m_cont_testing_TestingFancyArrayHandles_h
#include <vtkm/VecTraits.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayHandleConcatenate.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleDiscard.h>
#include <vtkm/cont/ArrayHandleGroupVec.h>
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
#include <vtkm/cont/ArrayHandleImplicit.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace fancy_array_detail
{
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));
}
};
template <typename ValueType>
struct ValueSquared
{
template <typename U>
VTKM_EXEC_CONT ValueType operator()(U u) const
{
return vtkm::Dot(u, u);
}
};
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 InverseValueScale
{
InverseValueScale()
: InverseFactor(1.0)
{
}
InverseValueScale(vtkm::Float64 factor)
: InverseFactor(1.0 / 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->InverseFactor;
Traits::SetComponent(result, i, static_cast<ComponentType>(ri));
}
return result;
}
private:
vtkm::Float64 InverseFactor;
};
template <typename ValueType>
struct VirtualTransformFunctorBase : public vtkm::VirtualObjectBase
{
VirtualTransformFunctorBase() = default;
VTKM_EXEC_CONT
virtual ValueType operator()(const ValueType& v) const = 0;
};
template <typename ValueType, typename FunctorType>
struct VirtualTransformFunctor : VirtualTransformFunctorBase<ValueType>
{
FunctorType Functor;
VTKM_CONT
VirtualTransformFunctor(const FunctorType& functor)
: Functor(functor)
{
}
VTKM_EXEC_CONT
ValueType operator()(const ValueType& v) const override { return this->Functor(v); }
};
template <typename ValueType>
struct TransformExecObject : public vtkm::cont::ExecutionAndControlObjectBase
{
vtkm::cont::VirtualObjectHandle<VirtualTransformFunctorBase<ValueType>> VirtualFunctor;
VTKM_CONT TransformExecObject() = default;
template <typename FunctorType>
VTKM_CONT TransformExecObject(const FunctorType& functor)
{
// Need to make sure the serial device is supported, since that is what is used on the
// control side.
vtkm::cont::ScopedGlobalRuntimeDeviceTracker scopedTracker;
vtkm::cont::GetGlobalRuntimeDeviceTracker().ResetDevice(vtkm::cont::DeviceAdapterTagSerial());
this->VirtualFunctor.Reset(new VirtualTransformFunctor<ValueType, FunctorType>(functor));
}
struct FunctorWrapper
{
const VirtualTransformFunctorBase<ValueType>* FunctorPointer;
FunctorWrapper() = default;
VTKM_CONT
FunctorWrapper(const VirtualTransformFunctorBase<ValueType>* functorPointer)
: FunctorPointer(functorPointer)
{
}
template <typename InValueType>
VTKM_EXEC ValueType operator()(const InValueType& value) const
{
return (*this->FunctorPointer)(value);
}
};
template <typename DeviceAdapterTag>
VTKM_CONT FunctorWrapper PrepareForExecution(DeviceAdapterTag device) const
{
return FunctorWrapper(this->VirtualFunctor.PrepareForExecution(device));
}
VTKM_CONT FunctorWrapper PrepareForControl() const
{
return FunctorWrapper(this->VirtualFunctor.Get());
}
};
}
namespace vtkm
{
namespace cont
{
namespace testing
{
/// This class has a single static member, Run, that tests that all Fancy Array
/// Handles work with the given DeviceAdapter
///
template <class DeviceAdapterTag>
struct TestingFancyArrayHandles
{
private:
static const int ARRAY_SIZE = 10;
public:
struct PassThrough : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn<>, FieldOut<>);
using ExecutionSignature = _2(_1);
template <class ValueType>
VTKM_EXEC ValueType operator()(const ValueType& inValue) const
{
return inValue;
}
};
struct InplaceFunctorPair : public 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;
}
};
#ifndef VTKM_CUDA
private:
#endif
struct TestCompositeAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const ValueType value = TestValue(13, ValueType());
std::vector<ValueType> compositeData(ARRAY_SIZE, value);
vtkm::cont::ArrayHandle<ValueType> compositeInput =
vtkm::cont::make_ArrayHandle(compositeData);
auto composite =
vtkm::cont::make_ArrayHandleCompositeVector(compositeInput, compositeInput, compositeInput);
vtkm::cont::printSummary_ArrayHandle(composite, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<vtkm::Vec<ValueType, 3>> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(composite, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
const vtkm::Vec<ValueType, 3> result_v = result.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, vtkm::Vec<ValueType, 3>(value)),
"CompositeVector Handle Failed");
const vtkm::Vec<ValueType, 3> result_c = composite.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_c, vtkm::Vec<ValueType, 3>(value)),
"CompositeVector Handle Failed");
}
}
};
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::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(constant, result);
vtkm::cont::printSummary_ArrayHandle(constant, std::cout);
std::cout << std::endl;
//verify that the control portal works
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType control_value = constant.GetPortalConstControl().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");
}
}
};
struct TestCountingAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
const vtkm::Id length = ARRAY_SIZE;
//need to initialize the start value or else vectors will have
//random values to start
ComponentType component_value(0);
const ValueType start = ValueType(component_value);
vtkm::cont::ArrayHandleCounting<ValueType> counting =
vtkm::cont::make_ArrayHandleCounting(start, ValueType(1), length);
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(counting, result);
vtkm::cont::printSummary_ArrayHandle(counting, std::cout);
std::cout << std::endl;
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType correct_value = ValueType(component_value);
const ValueType control_value = counting.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Counting Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value), "Counting Handle Control Failed");
component_value = ComponentType(component_value + ComponentType(1));
}
}
};
struct TestImplicitAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const vtkm::Id length = ARRAY_SIZE;
using FunctorType = ::fancy_array_detail::IndexSquared<ValueType>;
FunctorType functor;
vtkm::cont::ArrayHandleImplicit<FunctorType> implicit =
vtkm::cont::make_ArrayHandleImplicit(functor, length);
vtkm::cont::printSummary_ArrayHandle(implicit, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(implicit, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType correct_value = functor(i);
const ValueType control_value = implicit.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Implicit Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value), "Implicit Handle Failed");
}
}
};
struct TestConcatenateAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const vtkm::Id length = ARRAY_SIZE;
using FunctorType = ::fancy_array_detail::IndexSquared<ValueType>;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
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 < length; start_pos += length / 4)
{
vtkm::Id implicitLen = length - 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(static_cast<ComponentType>(i)));
basicVec.push_back(ValueType(ComponentType(i)));
}
BasicArrayType basic = vtkm::cont::make_ArrayHandle(basicVec);
// concatenate two arrays together
ConcatenateType concatenate = vtkm::cont::make_ArrayHandleConcatenate(implicit, basic);
vtkm::cont::printSummary_ArrayHandle(concatenate, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(concatenate, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
ValueType correct_value;
if (i < implicitLen)
correct_value = implicit.GetPortalConstControl().Get(i);
else
correct_value = basic.GetPortalConstControl().Get(i - implicitLen);
const ValueType control_value = concatenate.GetPortalConstControl().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");
}
}
}
};
struct TestPermutationAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const vtkm::Id length = ARRAY_SIZE;
using FunctorType = ::fancy_array_detail::IndexSquared<ValueType>;
using KeyHandleType = vtkm::cont::ArrayHandleCounting<vtkm::Id>;
using ValueHandleType = vtkm::cont::ArrayHandleImplicit<FunctorType>;
using PermutationHandleType =
vtkm::cont::ArrayHandlePermutation<KeyHandleType, ValueHandleType>;
FunctorType functor;
for (vtkm::Id start_pos = 0; start_pos < length; start_pos += length / 4)
{
const vtkm::Id counting_length = length - start_pos;
KeyHandleType counting =
vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(start_pos, 1, counting_length);
ValueHandleType implicit = vtkm::cont::make_ArrayHandleImplicit(functor, length);
PermutationHandleType permutation =
vtkm::cont::make_ArrayHandlePermutation(counting, implicit);
vtkm::cont::printSummary_ArrayHandle(permutation, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(permutation, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < counting_length; ++i)
{
const vtkm::Id value_index = i;
const vtkm::Id key_index = start_pos + i;
const ValueType result_v = result.GetPortalConstControl().Get(value_index);
const ValueType correct_value = implicit.GetPortalConstControl().Get(key_index);
const ValueType control_value = permutation.GetPortalConstControl().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");
}
}
}
};
struct TestViewAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const vtkm::Id length = ARRAY_SIZE;
using FunctorType = ::fancy_array_detail::IndexSquared<ValueType>;
using ValueHandleType = vtkm::cont::ArrayHandleImplicit<FunctorType>;
using ViewHandleType = vtkm::cont::ArrayHandleView<ValueHandleType>;
FunctorType functor;
for (vtkm::Id start_pos = 0; start_pos < length; start_pos += length / 4)
{
const vtkm::Id counting_length = length - start_pos;
ValueHandleType implicit = vtkm::cont::make_ArrayHandleImplicit(functor, length);
ViewHandleType view =
vtkm::cont::make_ArrayHandleView(implicit, start_pos, counting_length);
vtkm::cont::printSummary_ArrayHandle(view, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(view, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < counting_length; ++i)
{
const vtkm::Id value_index = i;
const vtkm::Id key_index = start_pos + i;
const ValueType result_v = result.GetPortalConstControl().Get(value_index);
const ValueType correct_value = implicit.GetPortalConstControl().Get(key_index);
const ValueType control_value = view.GetPortalConstControl().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");
}
}
}
};
struct TestTransformAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using FunctorType = fancy_array_detail::ValueScale;
const vtkm::Id length = ARRAY_SIZE;
FunctorType functor(2.0);
vtkm::cont::ArrayHandle<ValueType> input;
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandle<ValueType>, FunctorType>
transformed = vtkm::cont::make_ArrayHandleTransform(input, functor);
input.Allocate(length);
SetPortal(input.GetPortalControl());
vtkm::cont::printSummary_ArrayHandle(transformed, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(transformed, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType correct_value = functor(TestValue(i, ValueType()));
const ValueType control_value = transformed.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Transform Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value), "Transform Handle Control Failed");
}
}
};
struct TestTransformVirtualAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using FunctorType = fancy_array_detail::ValueScale;
using VirtualFunctorType = fancy_array_detail::TransformExecObject<ValueType>;
const vtkm::Id length = ARRAY_SIZE;
FunctorType functor(2.0);
VirtualFunctorType virtualFunctor(functor);
vtkm::cont::ArrayHandle<ValueType> input;
auto transformed = vtkm::cont::make_ArrayHandleTransform(input, virtualFunctor);
input.Allocate(length);
SetPortal(input.GetPortalControl());
vtkm::cont::printSummary_ArrayHandle(transformed, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<ValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(transformed, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType correct_value = functor(TestValue(i, ValueType()));
const ValueType control_value = transformed.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Transform Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value), "Transform Handle Control Failed");
}
}
};
struct TestCountingTransformAsInput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
using OutputValueType = ComponentType;
using FunctorType = fancy_array_detail::ValueSquared<OutputValueType>;
vtkm::Id length = ARRAY_SIZE;
FunctorType functor;
//need to initialize the start value or else vectors will have
//random values to start
ComponentType component_value(0);
const ValueType start = ValueType(component_value);
vtkm::cont::ArrayHandleCounting<ValueType> counting(start, ValueType(1), length);
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleCounting<ValueType>, FunctorType>
countingTransformed = vtkm::cont::make_ArrayHandleTransform(counting, functor);
vtkm::cont::printSummary_ArrayHandle(countingTransformed, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<OutputValueType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(countingTransformed, result);
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const OutputValueType result_v = result.GetPortalConstControl().Get(i);
const OutputValueType correct_value = functor(ValueType(component_value));
const OutputValueType control_value = countingTransformed.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Transform Counting Handle Failed");
VTKM_TEST_ASSERT(test_equal(result_v, control_value),
"Transform Counting Handle Control Failed");
component_value = ComponentType(component_value + ComponentType(1));
}
}
};
struct TestCastAsInput
{
template <typename CastToType>
VTKM_CONT void operator()(CastToType vtkmNotUsed(type)) const
{
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;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(castArray, result);
vtkm::cont::printSummary_ArrayHandle(castArray, std::cout);
std::cout << std::endl;
// verify results
vtkm::Id length = ARRAY_SIZE;
for (vtkm::Id i = 0; i < length; ++i)
{
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) ==
static_cast<CastToType>(input.GetPortalConstControl().Get(i)),
"Casting ArrayHandle Failed");
}
}
};
template <vtkm::IdComponent NUM_COMPONENTS>
struct TestGroupVecAsInput
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
using ValueType = vtkm::Vec<ComponentType, NUM_COMPONENTS>;
ComponentType testValues[ARRAY_SIZE * NUM_COMPONENTS];
for (vtkm::Id index = 0; index < ARRAY_SIZE * NUM_COMPONENTS; ++index)
{
testValues[index] = TestValue(index, ComponentType());
}
vtkm::cont::ArrayHandle<ComponentType> baseArray =
vtkm::cont::make_ArrayHandle(testValues, ARRAY_SIZE * NUM_COMPONENTS);
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::printSummary_ArrayHandle(groupArray, std::cout);
std::cout << std::endl;
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;
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
{
const ValueType result = resultArray.GetPortalConstControl().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++;
}
}
}
};
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.GetPortalControl());
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::cont::printSummary_ArrayHandle(groupArray, std::cout);
std::cout << std::endl;
vtkm::cont::printSummary_ArrayHandle(resultArray, std::cout);
std::cout << std::endl;
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;
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 = resultArray.GetPortalConstControl().Get(totalIndex);
VTKM_TEST_ASSERT(test_equal(result, expectedValue[componentIndex]),
"Result array got wrong value.");
totalIndex++;
}
}
}
};
// 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<>);
using ExecutionSignature = void(_1, WorkIndex);
template <typename InputType>
VTKM_EXEC void operator()(const InputType& input, vtkm::Id workIndex) const
{
using ComponentType = typename InputType::ComponentType;
vtkm::IdComponent expectedSize = static_cast<vtkm::IdComponent>(workIndex + 1);
if (expectedSize != input.GetNumberOfComponents())
{
this->RaiseError("Got unexpected number of components.");
}
vtkm::Id valueIndex = workIndex * (workIndex + 1) / 2;
for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++)
{
ComponentType expectedValue = TestValue(valueIndex, ComponentType());
if (expectedValue != input[componentIndex])
{
this->RaiseError("Got bad value in GroupVariableInputWorklet.");
}
valueIndex++;
}
}
};
struct TestGroupVecVariableAsInput
{
template <typename ComponentType>
VTKM_CONT void operator()(ComponentType) const
{
vtkm::Id sourceArraySize;
vtkm::cont::ArrayHandleCounting<vtkm::IdComponent> numComponentsArray(1, 1, ARRAY_SIZE);
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray =
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize);
vtkm::cont::ArrayHandle<ComponentType> sourceArray;
sourceArray.Allocate(sourceArraySize);
SetPortal(sourceArray.GetPortalControl());
vtkm::cont::printSummary_ArrayHandle(
vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray), std::cout);
std::cout << std::endl;
vtkm::worklet::DispatcherMapField<GroupVariableInputWorklet> dispatcher;
dispatcher.Invoke(vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray));
}
};
// 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 + 1);
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::ArrayHandleCounting<vtkm::IdComponent> numComponentsArray(1, 1, ARRAY_SIZE);
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets(
numComponentsArray, sourceArraySize, DeviceAdapterTag());
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));
vtkm::cont::printSummary_ArrayHandle(
vtkm::cont::make_ArrayHandleGroupVecVariable(sourceArray, offsetsArray), std::cout);
std::cout << std::endl;
vtkm::cont::printSummary_ArrayHandle(sourceArray, std::cout);
std::cout << std::endl;
CheckPortal(sourceArray.GetPortalConstControl());
}
};
struct TestZipAsInput
{
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::cont::ArrayHandle<ValueType> values =
vtkm::cont::make_ArrayHandle(testValues, ARRAY_SIZE);
vtkm::cont::ArrayHandleZip<vtkm::cont::ArrayHandle<KeyType>,
vtkm::cont::ArrayHandle<ValueType>>
zip = vtkm::cont::make_ArrayHandleZip(keys, values);
vtkm::cont::printSummary_ArrayHandle(zip, std::cout);
std::cout << std::endl;
vtkm::cont::ArrayHandle<PairType> result;
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(zip, result);
//verify that the control portal works
for (int i = 0; i < ARRAY_SIZE; ++i)
{
const PairType result_v = result.GetPortalConstControl().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");
}
}
};
struct TestDiscardAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using DiscardHandleType = vtkm::cont::ArrayHandleDiscard<ValueType>;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
using Portal = typename vtkm::cont::ArrayHandle<ValueType>::PortalControl;
const vtkm::Id length = ARRAY_SIZE;
vtkm::cont::ArrayHandle<ValueType> input;
input.Allocate(length);
Portal inputPortal = input.GetPortalControl();
for (vtkm::Id i = 0; i < length; ++i)
{
inputPortal.Set(i, ValueType(ComponentType(i)));
}
DiscardHandleType discard;
discard.Allocate(length);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(input, discard);
// No output to verify since none is stored in memory. Just checking that
// this compiles/runs without errors.
}
};
struct TestPermutationAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const vtkm::Id length = ARRAY_SIZE;
using KeyHandleType = vtkm::cont::ArrayHandleCounting<vtkm::Id>;
using ValueHandleType = vtkm::cont::ArrayHandle<ValueType>;
using PermutationHandleType =
vtkm::cont::ArrayHandlePermutation<KeyHandleType, ValueHandleType>;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
vtkm::cont::ArrayHandle<ValueType> input;
using Portal = typename vtkm::cont::ArrayHandle<ValueType>::PortalControl;
input.Allocate(length);
Portal inputPortal = input.GetPortalControl();
for (vtkm::Id i = 0; i < length; ++i)
{
inputPortal.Set(i, ValueType(ComponentType(i)));
}
ValueHandleType values;
values.Allocate(length * 2);
KeyHandleType counting = vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(length, 1, length);
PermutationHandleType permutation = vtkm::cont::make_ArrayHandlePermutation(counting, values);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(input, permutation);
vtkm::cont::printSummary_ArrayHandle(permutation, std::cout);
std::cout << std::endl;
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = permutation.GetPortalConstControl().Get(i);
const ValueType correct_value = ValueType(ComponentType(i));
VTKM_TEST_ASSERT(test_equal(result_v, correct_value),
"Permutation Handle Failed As Output");
}
}
};
struct TestViewAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
const vtkm::Id length = ARRAY_SIZE;
using ValueHandleType = vtkm::cont::ArrayHandle<ValueType>;
using ViewHandleType = vtkm::cont::ArrayHandleView<ValueHandleType>;
using ComponentType = typename vtkm::VecTraits<ValueType>::ComponentType;
vtkm::cont::ArrayHandle<ValueType> input;
using Portal = typename vtkm::cont::ArrayHandle<ValueType>::PortalControl;
input.Allocate(length);
Portal inputPortal = input.GetPortalControl();
for (vtkm::Id i = 0; i < length; ++i)
{
inputPortal.Set(i, ValueType(ComponentType(i)));
}
ValueHandleType values;
values.Allocate(length * 2);
ViewHandleType view = vtkm::cont::make_ArrayHandleView(values, length, length);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(input, view);
vtkm::cont::printSummary_ArrayHandle(view, std::cout);
std::cout << std::endl;
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = view.GetPortalConstControl().Get(i);
const ValueType correct_value = ValueType(ComponentType(i));
VTKM_TEST_ASSERT(test_equal(result_v, correct_value),
"Permutation Handle Failed As Output");
}
}
};
struct TestTransformAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using FunctorType = fancy_array_detail::ValueScale;
using InverseFunctorType = fancy_array_detail::InverseValueScale;
const vtkm::Id length = ARRAY_SIZE;
FunctorType functor(2.0);
InverseFunctorType inverseFunctor(2.0);
vtkm::cont::ArrayHandle<ValueType> input;
input.Allocate(length);
SetPortal(input.GetPortalControl());
vtkm::cont::ArrayHandle<ValueType> output;
auto transformed = vtkm::cont::make_ArrayHandleTransform(output, functor, inverseFunctor);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(input, transformed);
vtkm::cont::printSummary_ArrayHandle(transformed, std::cout);
std::cout << std::endl;
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = output.GetPortalConstControl().Get(i);
const ValueType correct_value = inverseFunctor(TestValue(i, ValueType()));
const ValueType control_value = transformed.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Transform Handle Failed");
VTKM_TEST_ASSERT(test_equal(functor(result_v), control_value),
"Transform Handle Control Failed");
}
}
};
struct TestTransformVirtualAsOutput
{
template <typename ValueType>
VTKM_CONT void operator()(const ValueType vtkmNotUsed(v)) const
{
using FunctorType = fancy_array_detail::ValueScale;
using InverseFunctorType = fancy_array_detail::InverseValueScale;
using VirtualFunctorType = fancy_array_detail::TransformExecObject<ValueType>;
const vtkm::Id length = ARRAY_SIZE;
FunctorType functor(2.0);
InverseFunctorType inverseFunctor(2.0);
VirtualFunctorType virtualFunctor(functor);
VirtualFunctorType virtualInverseFunctor(inverseFunctor);
vtkm::cont::ArrayHandle<ValueType> input;
input.Allocate(length);
SetPortal(input.GetPortalControl());
vtkm::cont::ArrayHandle<ValueType> output;
auto transformed =
vtkm::cont::make_ArrayHandleTransform(output, virtualFunctor, virtualInverseFunctor);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(input, transformed);
vtkm::cont::printSummary_ArrayHandle(transformed, std::cout);
std::cout << std::endl;
//verify that the control portal works
for (vtkm::Id i = 0; i < length; ++i)
{
const ValueType result_v = output.GetPortalConstControl().Get(i);
const ValueType correct_value = inverseFunctor(TestValue(i, ValueType()));
const ValueType control_value = transformed.GetPortalConstControl().Get(i);
VTKM_TEST_ASSERT(test_equal(result_v, correct_value), "Transform Handle Failed");
VTKM_TEST_ASSERT(test_equal(functor(result_v), control_value),
"Transform Handle Control Failed");
}
}
};
struct TestZipAsOutput
{
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::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);
vtkm::worklet::DispatcherMapField<PassThrough> dispatcher;
dispatcher.Invoke(input, result_zip);
vtkm::cont::printSummary_ArrayHandle(result_zip, std::cout);
std::cout << std::endl;
//now the two arrays we have zipped should have data inside them
for (int i = 0; i < ARRAY_SIZE; ++i)
{
const KeyType result_key = result_keys.GetPortalConstControl().Get(i);
const ValueType result_value = result_values.GetPortalConstControl().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");
}
}
};
struct TestZipAsInPlace
{
template <typename ValueType>
VTKM_CONT void operator()(ValueType) const
{
vtkm::cont::ArrayHandle<ValueType> inputValues;
inputValues.Allocate(ARRAY_SIZE);
SetPortal(inputValues.GetPortalControl());
vtkm::cont::ArrayHandle<ValueType> outputValues;
outputValues.Allocate(ARRAY_SIZE);
vtkm::worklet::DispatcherMapField<InplaceFunctorPair> dispatcher;
dispatcher.Invoke(vtkm::cont::make_ArrayHandleZip(inputValues, outputValues));
vtkm::cont::printSummary_ArrayHandle(outputValues, std::cout);
std::cout << std::endl;
CheckPortal(outputValues.GetPortalConstControl());
}
};
struct ScalarTypesToTest : vtkm::ListTagBase<vtkm::UInt8, vtkm::FloatDefault>
{
};
struct ZipTypesToTest
: vtkm::ListTagBase<vtkm::Pair<vtkm::UInt8, vtkm::Id>,
vtkm::Pair<vtkm::Float64, vtkm::Vec<vtkm::UInt8, 4>>,
vtkm::Pair<vtkm::Vec<vtkm::Float32, 3>, vtkm::Vec<vtkm::Int8, 4>>>
{
};
struct HandleTypesToTest : vtkm::ListTagBase<vtkm::Id,
vtkm::Vec<vtkm::Int32, 2>,
vtkm::FloatDefault,
vtkm::Vec<vtkm::Float64, 3>>
{
};
struct CastTypesToTest : vtkm::ListTagBase<vtkm::Int32, vtkm::UInt32>
{
};
struct TestAll
{
VTKM_CONT void operator()() const
{
std::cout << "Doing FancyArrayHandle tests" << std::endl;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleCompositeVector as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestCompositeAsInput(), ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleConstant as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestConstantAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleCounting as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestCountingAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleImplicit as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestImplicitAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandlePermutation as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestPermutationAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleView as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestViewAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleTransform as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestTransformAsInput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleTransform with virtual as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestTransformVirtualAsInput(),
HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleTransform with Counting as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestCountingTransformAsInput(),
HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleCast as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestCastAsInput(), CastTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<3> as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecAsInput<3>(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<4> as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecAsInput<4>(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<2> as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecAsOutput<2>(), ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVec<3> as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecAsOutput<3>(), ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVecVariable as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecVariableAsInput(),
ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleGroupVecVariable as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestGroupVecVariableAsOutput(),
ScalarTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleZip as Input" << std::endl;
vtkm::testing::Testing::TryTypes(TestingFancyArrayHandles<DeviceAdapterTag>::TestZipAsInput(),
ZipTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandlePermutation as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestPermutationAsOutput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleView as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestViewAsOutput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleTransform as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestTransformAsOutput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleTransform with virtual as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestTransformVirtualAsOutput(),
HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleDiscard as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestDiscardAsOutput(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleZip as Output" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestZipAsOutput(), ZipTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleZip as In Place" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestZipAsInPlace(), HandleTypesToTest());
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing ArrayHandleConcatenate as Input" << std::endl;
vtkm::testing::Testing::TryTypes(
TestingFancyArrayHandles<DeviceAdapterTag>::TestConcatenateAsInput(), HandleTypesToTest());
}
};
public:
/// Run a suite of tests to check to see if a DeviceAdapter properly supports
/// all the fancy array handles that vtkm supports. Returns an
/// error code that can be returned from the main function of a test.
///
static VTKM_CONT int Run()
{
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(DeviceAdapterTag());
return vtkm::cont::testing::Testing::Run(TestAll());
}
};
}
}
} // namespace vtkm::cont::testing
#endif //vtk_m_cont_testing_TestingFancyArrayHandles_h