vtk-m/vtkm/cont/arg/testing/UnitTestTransportWholeArray.cxx
Kenneth Moreland 2ac8456b5e Add WholeArray* ControlSignature tags
The WholeArrayIn, WholeArrayInOut, and WholeArrayOut ControlSignature
tags behave similarly to using an ExecObject tag with an
ExecutionWholeArray or ExecutionWholeArrayConst object. However, the
WholeArray* tags can simplify some implementations in two ways. First,
it allows you to specify more precisely what data is passed in. You have
to pass in an ArrayHandle or else an error will occur (as opposed to be
able to pass in any type of execution object). Second, this allows you
to easily pass in arrays stored in DynamicArrayHandle objects. The
Invoke mechanism will automatically find the appropriate static class.
This cannot be done easily with ExecutionWholeArray.
2015-12-07 09:52:29 -07:00

164 lines
5.0 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/arg/TransportTagWholeArrayIn.h>
#include <vtkm/cont/arg/TransportTagWholeArrayInOut.h>
#include <vtkm/cont/arg/TransportTagWholeArrayOut.h>
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
namespace {
static const vtkm::Id ARRAY_SIZE = 10;
#define OFFSET 10
template<typename PortalType>
struct TestOutKernel : public vtkm::exec::FunctorBase
{
PortalType Portal;
VTKM_EXEC_EXPORT
void operator()(vtkm::Id index) const
{
if (this->Portal.GetNumberOfValues() != ARRAY_SIZE)
{
this->RaiseError("Out whole array has wrong size.");
}
typedef typename PortalType::ValueType ValueType;
this->Portal.Set(index, TestValue(index, ValueType()));
}
};
template<typename PortalType>
struct TestInKernel : public vtkm::exec::FunctorBase
{
PortalType Portal;
VTKM_EXEC_EXPORT
void operator()(vtkm::Id index) const
{
if (this->Portal.GetNumberOfValues() != ARRAY_SIZE)
{
this->RaiseError("In whole array has wrong size.");
}
typedef typename PortalType::ValueType ValueType;
if (!test_equal(this->Portal.Get(index), TestValue(index, ValueType())))
{
this->RaiseError("Got bad execution object.");
}
}
};
template<typename PortalType>
struct TestInOutKernel : public vtkm::exec::FunctorBase
{
PortalType Portal;
VTKM_EXEC_EXPORT
void operator()(vtkm::Id index) const
{
if (this->Portal.GetNumberOfValues() != ARRAY_SIZE)
{
this->RaiseError("In/Out whole array has wrong size.");
}
typedef typename PortalType::ValueType ValueType;
this->Portal.Set(index, this->Portal.Get(index) + ValueType(OFFSET));
}
};
template<typename Device>
struct TryWholeArrayType
{
template<typename T>
void operator()(T) const
{
typedef vtkm::cont::ArrayHandle<T> ArrayHandleType;
typedef vtkm::cont::arg::Transport<
vtkm::cont::arg::TransportTagWholeArrayIn, ArrayHandleType, Device>
InTransportType;
typedef vtkm::cont::arg::Transport<
vtkm::cont::arg::TransportTagWholeArrayInOut, ArrayHandleType, Device>
InOutTransportType;
typedef vtkm::cont::arg::Transport<
vtkm::cont::arg::TransportTagWholeArrayOut, ArrayHandleType, Device>
OutTransportType;
ArrayHandleType array;
array.Allocate(ARRAY_SIZE);
std::cout << "Check Transport WholeArrayOut" << std::endl;
TestOutKernel<typename OutTransportType::ExecObjectType> outKernel;
outKernel.Portal = OutTransportType()(array, -1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(outKernel, ARRAY_SIZE);
CheckPortal(array.GetPortalConstControl());
std::cout << "Check Transport WholeArrayIn" << std::endl;
TestInKernel<typename InTransportType::ExecObjectType> inKernel;
inKernel.Portal = InTransportType()(array, -1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inKernel, ARRAY_SIZE);
std::cout << "Check Transport WholeArrayInOut" << std::endl;
TestInOutKernel<typename InOutTransportType::ExecObjectType> inOutKernel;
inOutKernel.Portal = InOutTransportType()(array, -1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inOutKernel, ARRAY_SIZE);
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
"Array size wrong?");
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
T expectedValue = TestValue(index, T()) + T(OFFSET);
T retrievedValue = array.GetPortalConstControl().Get(index);
VTKM_TEST_ASSERT(test_equal(expectedValue, retrievedValue),
"In/Out array not set correctly.");
}
}
};
template<typename Device>
void TryArrayOutTransport(Device)
{
vtkm::testing::Testing::TryTypes(TryWholeArrayType<Device>(),
vtkm::TypeListTagCommon());
}
void TestWholeArrayTransport()
{
std::cout << "Trying WholeArray transport." << std::endl;
TryArrayOutTransport(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
}
} // Anonymous namespace
int UnitTestTransportWholeArray(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestWholeArrayTransport);
}