1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#include <vigra/blockwise_convolution.hxx>
#include <vigra/blockwise_convolution.hxx>
#include <vigra/multi_convolution.hxx>
#include <vigra/unittest.hxx>
#include <vigra/multi_blocking.hxx>
#include <vigra/multi_blockwise.hxx>
#include <iostream>
#include "utils.hxx"
using namespace std;
using namespace vigra;
struct BlockwiseConvolutionTest
{
void simpleTest()
{
typedef MultiArray<2, double> Array;
typedef Array::difference_type Shape;
Shape shape(40);
Shape block_shape(2);
Array data(shape);
fillRandom(data.begin(), data.end(), 2000);
Kernel1D<double> kernel;
kernel.initAveraging(3, 2);
Array correct_output(shape);
separableConvolveMultiArray(data, correct_output, kernel);
Array tested_output(shape);
separableConvolveBlockwise(data, tested_output, kernel, block_shape);
shouldEqualSequenceTolerance(correct_output.begin(), correct_output.end(), tested_output.begin(), 1e-14);
}
void chunkedTest()
{
static const int N = 3;
typedef MultiArray<3, int> NormalArray;
typedef ChunkedArrayLazy<3, int> ChunkedArray;
typedef NormalArray::difference_type Shape;
Shape shape(40);
NormalArray data(shape);
fillRandom(data.begin(), data.end(), 2000);
ChunkedArray chunked_data(shape);
chunked_data.commitSubarray(Shape(0), data);
Kernel1D<double> kernel;
kernel.initAveraging(3, 2);
vector<Kernel1D<double> > kernels(N, kernel);
separableConvolveMultiArray(data, data, kernels.begin()); // data now contains output
separableConvolveBlockwise(chunked_data, chunked_data, kernels.begin());
NormalArray checked_out_data(shape);
chunked_data.checkoutSubarray(Shape(0), checked_out_data);
for(int i = 0; i != data.size(); ++i)
{
shouldEqual(data[i], checked_out_data[i]);
}
}
void testParallel()
{
double sigma = 1.0;
BlockwiseConvolutionOptions<2> opt;
TinyVector<double, 2> sigmaV(sigma, sigma);
opt.setStdDev(sigmaV);
opt.blockShape(TinyVector<int, 2>(5,7));
opt.numThreads(ParallelOptions::Nice);
std::cout << "running testParallel() with " << opt.getNumThreads() << " threads." << std::endl;
typedef MultiArray<2, double> Array;
typedef Array::difference_type Shape;
// random array
Shape shape(200,200);
Array data(shape);
fillRandom(data.begin(), data.end(), 2000);
// blockwise
Array resB(shape);
gaussianSmoothMultiArray(data, resB, opt);
// sequential
Array res(shape);
gaussianSmoothMultiArray(data, res, sigma);
shouldEqualSequenceTolerance(
res.begin(),
res.end(),
resB.begin(),
1e-14
);
}
};
struct BlockwiseConvolutionTestSuite
: public test_suite
{
BlockwiseConvolutionTestSuite()
: test_suite("blockwise convolution test")
{
add(testCase(&BlockwiseConvolutionTest::simpleTest));
add(testCase(&BlockwiseConvolutionTest::chunkedTest));
add(testCase(&BlockwiseConvolutionTest::testParallel));
}
};
int main(int argc, char** argv)
{
BlockwiseConvolutionTestSuite test;
int failed = test.run(testsToBeExecuted(argc, argv));
cout << test.report() << endl;
return failed != 0;
}
|