mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 09:59:12 +00:00
243 lines
7.0 KiB
C++
243 lines
7.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.
|
|
//============================================================================
|
|
|
|
#include <vtkm/BinaryOperators.h>
|
|
#include <vtkm/cont/Algorithm.h>
|
|
|
|
#include <vtkm/TypeTraits.h>
|
|
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
|
|
namespace
|
|
{
|
|
// The goal of this unit test is not to verify the correctness
|
|
// of the various algorithms. Since Algorithm is a header, we
|
|
// need to ensure we instantiate each algorithm in a source
|
|
// file to verify compilation.
|
|
//
|
|
static constexpr vtkm::Id ARRAY_SIZE = 10;
|
|
|
|
void FillTest()
|
|
{
|
|
vtkm::cont::BitField bits;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> array;
|
|
|
|
bits.Allocate(ARRAY_SIZE);
|
|
array.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::cont::Algorithm::Fill(bits, true);
|
|
vtkm::cont::Algorithm::Fill(bits, true, 5);
|
|
vtkm::cont::Algorithm::Fill(bits, vtkm::UInt8(0xab));
|
|
vtkm::cont::Algorithm::Fill(bits, vtkm::UInt8(0xab), 5);
|
|
vtkm::cont::Algorithm::Fill(array, vtkm::Id(5));
|
|
vtkm::cont::Algorithm::Fill(array, vtkm::Id(5), 5);
|
|
}
|
|
|
|
void CopyTest()
|
|
{
|
|
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> output;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> stencil;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
|
output.Allocate(ARRAY_SIZE);
|
|
stencil.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::cont::Algorithm::Copy(input, output);
|
|
vtkm::cont::Algorithm::CopyIf(input, stencil, output);
|
|
vtkm::cont::Algorithm::CopyIf(input, stencil, output, vtkm::LogicalNot());
|
|
vtkm::cont::Algorithm::CopySubRange(input, 2, 1, output);
|
|
}
|
|
|
|
void BoundsTest()
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> output;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> values;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
|
output.Allocate(ARRAY_SIZE);
|
|
values.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::cont::Algorithm::LowerBounds(input, values, output);
|
|
vtkm::cont::Algorithm::LowerBounds(input, values, output, vtkm::Sum());
|
|
vtkm::cont::Algorithm::LowerBounds(input, values);
|
|
|
|
vtkm::cont::Algorithm::UpperBounds(input, values, output);
|
|
vtkm::cont::Algorithm::UpperBounds(input, values, output, vtkm::Sum());
|
|
vtkm::cont::Algorithm::UpperBounds(input, values);
|
|
}
|
|
|
|
void ReduceTest()
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> keys;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> keysOut;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> valsOut;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
|
keys.Allocate(ARRAY_SIZE);
|
|
keysOut.Allocate(ARRAY_SIZE);
|
|
valsOut.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::Id result;
|
|
result = vtkm::cont::Algorithm::Reduce(input, vtkm::Id(0));
|
|
result = vtkm::cont::Algorithm::Reduce(input, vtkm::Id(0), vtkm::Maximum());
|
|
vtkm::cont::Algorithm::ReduceByKey(keys, input, keysOut, valsOut, vtkm::Maximum());
|
|
(void)result;
|
|
}
|
|
|
|
void ScanTest()
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> output;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> keys;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
|
output.Allocate(ARRAY_SIZE);
|
|
keys.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::Id out;
|
|
out = vtkm::cont::Algorithm::ScanInclusive(input, output);
|
|
out = vtkm::cont::Algorithm::ScanInclusive(input, output, vtkm::Maximum());
|
|
vtkm::cont::Algorithm::ScanInclusiveByKey(keys, input, output, vtkm::Maximum());
|
|
vtkm::cont::Algorithm::ScanInclusiveByKey(keys, input, output);
|
|
out = vtkm::cont::Algorithm::ScanExclusive(input, output, vtkm::Maximum(), vtkm::Id(0));
|
|
vtkm::cont::Algorithm::ScanExclusiveByKey(keys, input, output, vtkm::Id(0), vtkm::Maximum());
|
|
vtkm::cont::Algorithm::ScanExclusiveByKey(keys, input, output);
|
|
vtkm::cont::Algorithm::ScanExtended(input, output);
|
|
vtkm::cont::Algorithm::ScanExtended(input, output, vtkm::Maximum(), vtkm::Id(0));
|
|
(void)out;
|
|
}
|
|
|
|
struct DummyFunctor : public vtkm::exec::FunctorBase
|
|
{
|
|
template <typename IdType>
|
|
VTKM_EXEC void operator()(IdType) const
|
|
{
|
|
}
|
|
};
|
|
|
|
void ScheduleTest()
|
|
{
|
|
vtkm::cont::Algorithm::Schedule(DummyFunctor(), vtkm::Id(1));
|
|
vtkm::Id3 id3(1, 1, 1);
|
|
vtkm::cont::Algorithm::Schedule(DummyFunctor(), id3);
|
|
}
|
|
|
|
struct CompFunctor
|
|
{
|
|
template <typename T>
|
|
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
|
|
{
|
|
return x < y;
|
|
}
|
|
};
|
|
|
|
struct CompExecObject : vtkm::cont::ExecutionObjectBase
|
|
{
|
|
template <typename Device>
|
|
VTKM_CONT CompFunctor PrepareForExecution(Device, vtkm::cont::Token&)
|
|
{
|
|
return CompFunctor();
|
|
}
|
|
};
|
|
|
|
void SortTest()
|
|
{
|
|
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> keys;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
|
keys.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::cont::Algorithm::Sort(input);
|
|
vtkm::cont::Algorithm::Sort(input, CompFunctor());
|
|
vtkm::cont::Algorithm::Sort(input, CompExecObject());
|
|
vtkm::cont::Algorithm::SortByKey(keys, input);
|
|
vtkm::cont::Algorithm::SortByKey(keys, input, CompFunctor());
|
|
vtkm::cont::Algorithm::SortByKey(keys, input, CompExecObject());
|
|
}
|
|
|
|
void SynchronizeTest()
|
|
{
|
|
vtkm::cont::Algorithm::Synchronize();
|
|
}
|
|
|
|
template <typename ArrayHandle1T, typename ArrayHandle2T>
|
|
void AssertArrayHandlesEqual(const ArrayHandle1T& ah1, const ArrayHandle2T& ah2)
|
|
{
|
|
VTKM_ASSERT(ah1.GetNumberOfValues() == ah2.GetNumberOfValues());
|
|
auto rp1 = ah1.ReadPortal();
|
|
auto rp2 = ah2.ReadPortal();
|
|
|
|
for (vtkm::Id i = 0; i < ah1.GetNumberOfValues(); ++i)
|
|
{
|
|
VTKM_ASSERT(rp1.Get(i) == rp2.Get(i));
|
|
}
|
|
}
|
|
|
|
void TransformTest()
|
|
{
|
|
auto transformInput = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 3, 5, 7, 9, 11, 13, 15 });
|
|
auto transformInputOutput =
|
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 2, 4, 8, 10, 12, 14, 16 });
|
|
auto transformExpectedResult =
|
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 5, 9, 15, 19, 23, 27, 31 });
|
|
|
|
// Test simple call on two different arrays
|
|
std::cout << "Testing Transform for summing arrays" << std::endl;
|
|
vtkm::cont::ArrayHandle<vtkm::Id> transformOutput;
|
|
vtkm::cont::Algorithm::Transform(
|
|
transformInput, transformInputOutput, transformOutput, vtkm::Sum{});
|
|
AssertArrayHandlesEqual(transformOutput, transformExpectedResult);
|
|
|
|
// Test using an array as both input and output
|
|
std::cout << "Testing Transform with array for both input and output" << std::endl;
|
|
vtkm::cont::Algorithm::Transform(
|
|
transformInputOutput, transformInput, transformInputOutput, vtkm::Sum{});
|
|
AssertArrayHandlesEqual(transformInputOutput, transformExpectedResult);
|
|
}
|
|
|
|
void UniqueTest()
|
|
{
|
|
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
|
|
|
vtkm::cont::Algorithm::Unique(input);
|
|
vtkm::cont::Algorithm::Unique(input, CompFunctor());
|
|
vtkm::cont::Algorithm::Unique(input, CompExecObject());
|
|
}
|
|
|
|
void TestAll()
|
|
{
|
|
FillTest();
|
|
CopyTest();
|
|
BoundsTest();
|
|
ReduceTest();
|
|
ScanTest();
|
|
ScheduleTest();
|
|
SortTest();
|
|
SynchronizeTest();
|
|
TransformTest();
|
|
UniqueTest();
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
int UnitTestAlgorithm(int argc, char* argv[])
|
|
{
|
|
return vtkm::cont::testing::Testing::Run(TestAll, argc, argv);
|
|
}
|