Make Rectilinear and Regular builder tests faster

Previously UnitTestDataSetBuilderRectilinear and
UnitTestDataSetBuilderRegular did an exhaustive test of all possible
grid sizes within a certain amount of dimensions and with some number of
ways to build point arrays. This created hundreds of thousands of cases
that were checked, and it was running a long time. At best it wasted
time and at worst ctest reported the test as timed out.

It is not really necessary to perform an exhaustive test. The tests are
changed to do 10 trials using random values for dimensions and fill
methods.
This commit is contained in:
Kenneth Moreland 2016-01-14 15:15:19 -07:00
parent e0184e6648
commit 427f3cf57d
2 changed files with 234 additions and 101 deletions

@ -28,10 +28,20 @@
#include <vtkm/cont/testing/Testing.h> #include <vtkm/cont/testing/Testing.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/static_assert.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <time.h>
#include <vector> #include <vector>
namespace DataSetBuilderRectilinearNamespace { namespace DataSetBuilderRectilinearNamespace {
boost::mt19937 g_RandomGenerator;
typedef vtkm::cont::DeviceAdapterAlgorithm<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DFA; typedef vtkm::cont::DeviceAdapterAlgorithm<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DFA;
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter; typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
@ -76,111 +86,130 @@ void ValidateDataSet(const vtkm::cont::DataSet &ds,
} }
template <typename T> template <typename T>
void FillArray(std::vector<T> &arr, std::size_t sz, int fillMethod) void FillArray(std::vector<T> &arr,
vtkm::Id size,
vtkm::IdComponent fillMethod)
{ {
arr.resize(sz); arr.resize(static_cast<std::size_t>(size));
for (size_t i = 0; i < sz; i++) for (size_t i = 0; i < static_cast<std::size_t>(size); i++)
{ {
T xi; T xi;
switch (fillMethod) switch (fillMethod)
{ {
case 0: xi = static_cast<T>(i); break; case 0: xi = static_cast<T>(i); break;
case 1: xi = static_cast<T>(i) / static_cast<vtkm::Float32>(sz-1); break; case 1: xi = static_cast<T>(i) / static_cast<vtkm::Float32>(size-1); break;
case 2: xi = static_cast<T>(i*2); break; case 2: xi = static_cast<T>(i*2); break;
case 3: xi = static_cast<T>(i*0.1f); break; case 3: xi = static_cast<T>(i*0.1f); break;
case 4: xi = static_cast<T>(i*i); break; case 4: xi = static_cast<T>(i*i); break;
}
arr[i] = xi;
} }
arr[i] = xi;
}
} }
template <typename T> template <typename T>
void void
RectilinearTests() RectilinearTests()
{ {
vtkm::cont::DataSetBuilderRectilinear dsb; const vtkm::Id NUM_TRIALS = 10;
vtkm::cont::DataSet ds; const vtkm::Id MAX_DIM_SIZE = 20;
const vtkm::Id NUM_FILL_METHODS = 5;
std::size_t nx = 15, ny = 15, nz = 15; vtkm::cont::DataSetBuilderRectilinear dataSetBuilder;
int nm = 5; vtkm::cont::DataSet dataSet;
std::vector<T> xvals, yvals, zvals;
for (std::size_t i = 2; i < nx; i++) boost::random::uniform_int_distribution<vtkm::Id>
randomDim(2, MAX_DIM_SIZE);
boost::random::uniform_int_distribution<vtkm::IdComponent>
randomFill(0, NUM_FILL_METHODS-1);
for (vtkm::Id trial = 0; trial < NUM_TRIALS; trial++)
{ {
for (std::size_t j = 2; j < ny; j++) std::cout << "Trial " << trial << std::endl;
{
for (int mx = 0; mx < nm; mx++)
{
for (int my = 0; my < nm; my++)
{
//Do the 2D cases.
vtkm::Id np = static_cast<vtkm::Id>(i*j);
vtkm::Id nc = static_cast<vtkm::Id>((i-1)*(j-1));
FillArray(xvals, i, mx);
FillArray(yvals, j, my);
vtkm::Float64 bounds[6] = {xvals[0], xvals[i-1], vtkm::Id3 dimensions(randomDim(g_RandomGenerator),
yvals[0], yvals[j-1], randomDim(g_RandomGenerator),
0.0, 0.0}; randomDim(g_RandomGenerator));
//Test std::vector std::cout << "Dimensions: " << dimensions << std::endl;
ds = dsb.Create(xvals, yvals);
ValidateDataSet(ds, 2, np, nc, bounds);
//Test T * vtkm::IdComponent fillMethodX = randomFill(g_RandomGenerator);
ds = dsb.Create(static_cast<vtkm::Id>(i), vtkm::IdComponent fillMethodY = randomFill(g_RandomGenerator);
static_cast<vtkm::Id>(j), vtkm::IdComponent fillMethodZ = randomFill(g_RandomGenerator);
&xvals[0], std::cout << "Fill methods: ["
&yvals[0]); << fillMethodX << ","
ValidateDataSet(ds, 2, np, nc, bounds); << fillMethodY << ","
<< fillMethodZ << "]" << std::endl;
//Test ArrayHandle std::vector<T> xCoordinates;
ds = dsb.Create(vtkm::cont::make_ArrayHandle(xvals), std::vector<T> yCoordinates;
vtkm::cont::make_ArrayHandle(yvals)); std::vector<T> zCoordinates;
ValidateDataSet(ds, 2, np, nc, bounds); FillArray(xCoordinates, dimensions[0], fillMethodX);
FillArray(yCoordinates, dimensions[1], fillMethodY);
FillArray(zCoordinates, dimensions[2], fillMethodZ);
//Do the 3D cases. std::cout << "2D cases" << std::endl;
for (std::size_t k = 2; k < nz; k++) vtkm::Id numPoints = dimensions[0]*dimensions[1];
{ vtkm::Id numCells = (dimensions[0]-1)*(dimensions[1]-1);
for (int mz = 0; mz < nm; mz++) vtkm::Float64 bounds[6] = {
{ xCoordinates.front(), xCoordinates.back(),
np = static_cast<vtkm::Id>(i*j*k); yCoordinates.front(), yCoordinates.back(),
nc = static_cast<vtkm::Id>((i-1)*(j-1)*(k-1)); 0.0, 0.0
FillArray(zvals, k, mz); };
bounds[4] = zvals[0];
bounds[5] = zvals[k-1];
//Test std::vector std::cout << " Create with std::vector" << std::endl;
ds = dsb.Create(xvals, yvals, zvals); dataSet = dataSetBuilder.Create(xCoordinates, yCoordinates);
ValidateDataSet(ds, 3, np, nc, bounds); ValidateDataSet(dataSet, 2, numPoints, numCells, bounds);
//Test T * std::cout << " Create with C array" << std::endl;
ds = dsb.Create(static_cast<vtkm::Id>(i), dataSet = dataSetBuilder.Create(dimensions[0],
static_cast<vtkm::Id>(j), dimensions[1],
static_cast<vtkm::Id>(k), &xCoordinates.front(),
&xvals[0], &yCoordinates.front());
&yvals[0], ValidateDataSet(dataSet, 2, numPoints, numCells, bounds);
&zvals[0]);
ValidateDataSet(ds, 3, np, nc, bounds);
//Test ArrayHandle std::cout << " Create with ArrayHandle" << std::endl;
ds = dsb.Create(vtkm::cont::make_ArrayHandle(xvals), dataSet = dataSetBuilder.Create(vtkm::cont::make_ArrayHandle(xCoordinates),
vtkm::cont::make_ArrayHandle(yvals), vtkm::cont::make_ArrayHandle(yCoordinates));
vtkm::cont::make_ArrayHandle(zvals)); ValidateDataSet(dataSet, 2, numPoints, numCells, bounds);
ValidateDataSet(ds, 3, np, nc, bounds);
} std::cout << "3D cases" << std::endl;
} numPoints *= dimensions[2];
} numCells *= dimensions[2]-1;
} bounds[4] = zCoordinates.front();
} bounds[5] = zCoordinates.back();
std::cout << " Create with std::vector" << std::endl;
dataSet = dataSetBuilder.Create(xCoordinates, yCoordinates, zCoordinates);
ValidateDataSet(dataSet, 3, numPoints, numCells, bounds);
std::cout << " Create with C array" << std::endl;
dataSet = dataSetBuilder.Create(dimensions[0],
dimensions[1],
dimensions[2],
&xCoordinates.front(),
&yCoordinates.front(),
&zCoordinates.front());
ValidateDataSet(dataSet, 3, numPoints, numCells, bounds);
std::cout << " Create with ArrayHandle" << std::endl;
dataSet = dataSetBuilder.Create(vtkm::cont::make_ArrayHandle(xCoordinates),
vtkm::cont::make_ArrayHandle(yCoordinates),
vtkm::cont::make_ArrayHandle(zCoordinates));
ValidateDataSet(dataSet, 3, numPoints, numCells, bounds);
} }
} }
void void
TestDataSetBuilderRectilinear() TestDataSetBuilderRectilinear()
{ {
RectilinearTests<vtkm::Float32>(); vtkm::UInt32 seed = static_cast<vtkm::UInt32>(time(NULL));
RectilinearTests<vtkm::Float64>(); std::cout << "Seed: " << seed << std::endl;
g_RandomGenerator.seed(seed);
std::cout << "======== Float32 ==========================" << std::endl;
RectilinearTests<vtkm::Float32>();
std::cout << "======== Float64 ==========================" << std::endl;
RectilinearTests<vtkm::Float64>();
} }
} // namespace DataSetBuilderRectilinearNamespace } // namespace DataSetBuilderRectilinearNamespace

@ -28,10 +28,20 @@
#include <vtkm/cont/testing/Testing.h> #include <vtkm/cont/testing/Testing.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/static_assert.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <time.h>
#include <vector> #include <vector>
namespace DataSetBuilderRegularNamespace { namespace DataSetBuilderRegularNamespace {
boost::mt19937 g_RandomGenerator;
typedef vtkm::cont::DeviceAdapterAlgorithm<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DFA; typedef vtkm::cont::DeviceAdapterAlgorithm<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DFA;
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter; typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
@ -57,8 +67,8 @@ void ValidateDataSet(const vtkm::cont::DataSet &ds,
vtkm::Float64 res[6]; vtkm::Float64 res[6];
ds.GetCoordinateSystem().GetBounds(res, DeviceAdapter()); ds.GetCoordinateSystem().GetBounds(res, DeviceAdapter());
VTKM_TEST_ASSERT(test_equal(bounds[0], res[0]) && test_equal(bounds[1], res[1]) && VTKM_TEST_ASSERT(test_equal(bounds[0], res[0]) && test_equal(bounds[1], res[1]) &&
test_equal(bounds[2], res[2]) && test_equal(bounds[3], res[3]) && test_equal(bounds[2], res[2]) && test_equal(bounds[3], res[3]) &&
test_equal(bounds[4], res[4]) && test_equal(bounds[5], res[5]), test_equal(bounds[4], res[4]) && test_equal(bounds[5], res[5]),
"Bounds of coordinates do not match"); "Bounds of coordinates do not match");
if (dim == 2) if (dim == 2)
@ -76,28 +86,115 @@ void ValidateDataSet(const vtkm::cont::DataSet &ds,
VTKM_TEST_ASSERT(shape == vtkm::CELL_SHAPE_HEXAHEDRON, "Wrong element type"); VTKM_TEST_ASSERT(shape == vtkm::CELL_SHAPE_HEXAHEDRON, "Wrong element type");
} }
} }
template <typename T>
void FillMethod(int method, vtkm::Id n, T &o, T &s,
vtkm::Float64 &b0, vtkm::Float64 &b1)
{
switch (method)
{
case 0 : o = 0; s = 1; break;
case 1 : o = 0; s = static_cast<T>(1.0/n); break;
case 2 : o = 0; s = 2; break;
case 3 : o = static_cast<T>(-(n-1)); s = 1; break;
case 4 : o = static_cast<T>(2.780941); s = static_cast<T>(182.381901); break;
}
b0 = static_cast<vtkm::Float64>(o); template <typename T>
b1 = static_cast<vtkm::Float64>(o + (n-1)*s); void FillMethod(vtkm::IdComponent method,
vtkm::Id dimensionSize,
T &origin,
T &spacing,
vtkm::Float64 &boundsMin,
vtkm::Float64 &boundsMax)
{
switch (method)
{
case 0:
origin = 0;
spacing = 1;
break;
case 1:
origin = 0;
spacing = static_cast<T>(1.0/dimensionSize);
break;
case 2:
origin = 0;
spacing = 2;
break;
case 3:
origin = static_cast<T>(-(dimensionSize-1));
spacing = 1;
break;
case 4:
origin = static_cast<T>(2.780941);
spacing = static_cast<T>(182.381901);
break;
}
boundsMin = static_cast<vtkm::Float64>(origin);
boundsMax = static_cast<vtkm::Float64>(origin + (dimensionSize-1)*spacing);
} }
template <typename T> template <typename T>
void void
RegularTests() RegularTests()
{ {
const vtkm::Id NUM_TRIALS = 10;
const vtkm::Id MAX_DIM_SIZE = 20;
const vtkm::Id NUM_FILL_METHODS = 5;
vtkm::cont::DataSetBuilderRegular dataSetBuilder;
vtkm::cont::DataSet dataSet;
boost::random::uniform_int_distribution<vtkm::Id>
randomDim(2, MAX_DIM_SIZE);
boost::random::uniform_int_distribution<vtkm::IdComponent>
randomFill(0, NUM_FILL_METHODS-1);
for (vtkm::Id trial = 0; trial < NUM_TRIALS; trial++)
{
std::cout << "Trial " << trial << std::endl;
vtkm::Id3 dimensions(randomDim(g_RandomGenerator),
randomDim(g_RandomGenerator),
randomDim(g_RandomGenerator));
std::cout << "Dimensions: " << dimensions << std::endl;
vtkm::IdComponent fillMethodX = randomFill(g_RandomGenerator);
vtkm::IdComponent fillMethodY = randomFill(g_RandomGenerator);
vtkm::IdComponent fillMethodZ = randomFill(g_RandomGenerator);
std::cout << "Fill methods: ["
<< fillMethodX << ","
<< fillMethodY << ","
<< fillMethodZ << "]" << std::endl;
vtkm::Vec<T,3> origin;
vtkm::Vec<T,3> spacing;
vtkm::Float64 bounds[6];
FillMethod(fillMethodX,
dimensions[0],
origin[0],
spacing[0],
bounds[0],
bounds[1]);
FillMethod(fillMethodY,
dimensions[1],
origin[1],
spacing[1],
bounds[2],
bounds[3]);
FillMethod(fillMethodZ,
dimensions[2],
origin[2],
spacing[2],
bounds[4],
bounds[5]);
std::cout << "3D case" << std::endl;
vtkm::Id numPoints = dimensions[0]*dimensions[1]*dimensions[2];
vtkm::Id numCells = (dimensions[0]-1)*(dimensions[1]-1)*(dimensions[2]-1);
dataSet = dataSetBuilder.Create(dimensions, origin, spacing);
ValidateDataSet(dataSet, 3, numPoints, numCells, bounds);
std::cout << "2D case" << std::endl;
numPoints = dimensions[0]*dimensions[1];
numCells = (dimensions[0]-1)*(dimensions[1]-1);
bounds[4] = bounds[5] = 0.0;
dataSet = dataSetBuilder.Create(vtkm::Id2(dimensions[0], dimensions[1]),
vtkm::Vec<T,2>(origin[0], origin[1]),
vtkm::Vec<T,2>(spacing[0], spacing[1]));
ValidateDataSet(dataSet, 2, numPoints, numCells, bounds);
}
#if 0
vtkm::cont::DataSetBuilderRegular dsb; vtkm::cont::DataSetBuilderRegular dsb;
vtkm::cont::DataSet ds; vtkm::cont::DataSet ds;
@ -119,7 +216,7 @@ RegularTests()
FillMethod(mj, dims2[1], oj, sj, bounds[2],bounds[3]); FillMethod(mj, dims2[1], oj, sj, bounds[2],bounds[3]);
bounds[4] = bounds[5] = 0; bounds[4] = bounds[5] = 0;
vtkm::Vec<T,2> o2(oi,oj), sp2(si,sj); vtkm::Vec<T,2> o2(oi,oj), sp2(si,sj);
ds = dsb.Create(dims2, o2, sp2); ds = dsb.Create(dims2, o2, sp2);
ValidateDataSet(ds, 2, np, nc, bounds); ValidateDataSet(ds, 2, np, nc, bounds);
@ -129,7 +226,7 @@ RegularTests()
{ {
np = i*j*k; np = i*j*k;
nc = (i-1)*(j-1)*(k-1); nc = (i-1)*(j-1)*(k-1);
vtkm::Id3 dims3(i,j,k); vtkm::Id3 dims3(i,j,k);
T ok, sk; T ok, sk;
FillMethod(mk, dims3[2], ok, sk, bounds[4],bounds[5]); FillMethod(mk, dims3[2], ok, sk, bounds[4],bounds[5]);
@ -138,13 +235,20 @@ RegularTests()
ValidateDataSet(ds, 3, np, nc, bounds); ValidateDataSet(ds, 3, np, nc, bounds);
} }
} }
#endif
} }
void void
TestDataSetBuilderRegular() TestDataSetBuilderRegular()
{ {
RegularTests<vtkm::Float32>(); vtkm::UInt32 seed = static_cast<vtkm::UInt32>(time(NULL));
RegularTests<vtkm::Float64>(); std::cout << "Seed: " << seed << std::endl;
g_RandomGenerator.seed(seed);
std::cout << "======== Float32 ==========================" << std::endl;
RegularTests<vtkm::Float32>();
std::cout << "======== Float64 ==========================" << std::endl;
RegularTests<vtkm::Float64>();
} }
} // namespace DataSetBuilderRegularNamespace } // namespace DataSetBuilderRegularNamespace