44 #include <boost/program_options.hpp>
45 #include <boost/timer/timer.hpp>
57 #if BOOST_VERSION < 105600
58 #include <boost/units/detail/utility.hpp>
59 using boost::units::detail::demangle;
61 using boost::core::demangle;
64 namespace po = boost::program_options;
65 namespace timer = boost::timer;
78 po::options_description options{};
80 (
"image-start", po::value<int>()->default_value(100),
"Image start size")
81 (
"kernel-start", po::value<int>()->default_value(3),
"Kernel start size")
82 (
"step-size", po::value<int>()->default_value(4),
"Step size")
83 (
"image-nsteps", po::value<int>()->default_value(1),
"Number of steps for the image")
84 (
"kernel-nsteps", po::value<int>()->default_value(2),
"Number of steps for the kernel")
85 (
"repeat", po::value<int>()->default_value(5),
"Repeat")
86 (
"measures", po::value<int>()->default_value(10),
"Number of measures");
92 for (
int x = 0;
x < size; ++
x) {
93 for (
int y = 0;
y < size; ++
y) {
94 img->setValue(
x,
y, random_dist(random_generator));
102 auto img_start = args[
"image-start"].as<
int>();
103 auto krn_start = args[
"kernel-start"].as<
int>();
104 auto step_size = args[
"step-size"].as<
int>();
105 auto img_nsteps = args[
"image-nsteps"].as<
int>();
106 auto krn_nsteps = args[
"kernel-nsteps"].as<
int>();
107 auto repeat = args[
"repeat"].as<
int>();
108 auto measures = args[
"measures"].as<
int>();
112 for (
int img_step = 0; img_step < img_nsteps; ++img_step) {
113 auto img_size = img_start + img_step * step_size;
114 auto image = generateImage(img_size);
116 for (
int krn_step = 0; krn_step < krn_nsteps; ++krn_step) {
117 auto krn_size = krn_start + krn_step * step_size;
119 logger.
info() <<
"Using an image of " << img_size <<
"x" << img_size;
120 logger.
info() <<
"Using a kernel of " << krn_size <<
"x" << krn_size;
122 auto kernel = generateImage(krn_size);
125 logger.
info() <<
"Timing OpenCV implementation";
126 auto opencv_result = benchmark<OpenCVConvolution>(image, kernel, repeat, measures);
129 if (krn_size <= 10 || img_size <= 20) {
130 logger.
info() <<
"Timing Direct implementation";
131 auto direct_result = benchmark<DirectConvolution<SeFloat>>(image, kernel, repeat, measures);
134 logger.
info() <<
"Compare OpenCV vs Direct Result";
135 verifyResults(opencv_result, direct_result);
140 auto dft_result = benchmark<DFTConvolution<SeFloat>>(image, kernel, repeat, measures);
143 logger.
info() <<
"Compare OpenCV vs DFT Result";
144 verifyResults(opencv_result, dft_result);
152 template<
typename Convolution>
155 int repeat,
int measures) {
156 auto conv_name = demangle(
typeid(Convolution).name());
158 Convolution convolution(kernel);
162 for (
int m = 0;
m < measures; ++
m) {
163 logger.
info() << conv_name <<
" " <<
m+1 <<
"/" << measures;
164 timer::cpu_timer timer;
167 for (
int r = 0; r < repeat; ++r) {
170 convolution.convolve(copied);
174 std::cout << image->getWidth() <<
',' << kernel->getWidth() <<
",\"" << conv_name <<
"\"," << timer.elapsed().wall <<
std::endl;
181 bool all_equal =
true;
182 for (
int x = 0;
x < a->getWidth(); ++
x) {
183 for (
int y = 0;
y < a->getHeight(); ++
y) {
184 auto av = a->getValue(
x,
y);
185 auto bv = b->getValue(
x,
y);
187 logger.
info() <<
"Mismatch at " <<
x <<
',' <<
y <<
": "
188 << av <<
" != " << bv;
197 logger.
warn() <<
"Convoluted images are not equal!";