27 #include <boost/program_options.hpp>
28 #include <boost/timer/timer.hpp>
40 #if BOOST_VERSION < 105600
41 #include <boost/units/detail/utility.hpp>
42 using boost::units::detail::demangle;
44 using boost::core::demangle;
47 namespace po = boost::program_options;
48 namespace timer = boost::timer;
49 using namespace SourceXtractor;
61 po::options_description options{};
63 (
"image-start", po::value<int>()->default_value(100),
"Image start size")
64 (
"kernel-start", po::value<int>()->default_value(3),
"Kernel start size")
65 (
"step-size", po::value<int>()->default_value(4),
"Step size")
66 (
"image-nsteps", po::value<int>()->default_value(1),
"Number of steps for the image")
67 (
"kernel-nsteps", po::value<int>()->default_value(2),
"Number of steps for the kernel")
68 (
"repeat", po::value<int>()->default_value(5),
"Repeat")
69 (
"measures", po::value<int>()->default_value(10),
"Number of measures");
75 for (
int x = 0;
x < size; ++
x) {
76 for (
int y = 0;
y < size; ++
y) {
77 img->setValue(
x,
y, random_dist(random_generator));
85 auto img_start = args[
"image-start"].as<
int>();
86 auto krn_start = args[
"kernel-start"].as<
int>();
87 auto step_size = args[
"step-size"].as<
int>();
88 auto img_nsteps = args[
"image-nsteps"].as<
int>();
89 auto krn_nsteps = args[
"kernel-nsteps"].as<
int>();
90 auto repeat = args[
"repeat"].as<
int>();
91 auto measures = args[
"measures"].as<
int>();
95 for (
int img_step = 0; img_step < img_nsteps; ++img_step) {
96 auto img_size = img_start + img_step * step_size;
97 auto image = generateImage(img_size);
99 for (
int krn_step = 0; krn_step < krn_nsteps; ++krn_step) {
100 auto krn_size = krn_start + krn_step * step_size;
102 logger.info() <<
"Using an image of " << img_size <<
"x" << img_size;
103 logger.info() <<
"Using a kernel of " << krn_size <<
"x" << krn_size;
105 auto kernel = generateImage(krn_size);
108 logger.info() <<
"Timing OpenCV implementation";
109 auto opencv_result = benchmark<OpenCVConvolution>(image, kernel, repeat, measures);
112 if (krn_size <= 10 || img_size <= 20) {
113 logger.info() <<
"Timing Direct implementation";
114 auto direct_result = benchmark<DirectConvolution<SeFloat>>(image, kernel, repeat, measures);
117 logger.info() <<
"Compare OpenCV vs Direct Result";
118 verifyResults(opencv_result, direct_result);
122 logger.info() <<
"Timing DFT implementation";
123 auto dft_result = benchmark<DFTConvolution<SeFloat>>(image, kernel, repeat, measures);
126 logger.info() <<
"Compare OpenCV vs DFT Result";
127 verifyResults(opencv_result, dft_result);
135 template<
typename Convolution>
138 int repeat,
int measures) {
139 auto conv_name = demangle(
typeid(Convolution).name());
141 Convolution convolution(kernel);
145 for (
int m = 0;
m < measures; ++
m) {
146 logger.info() << conv_name <<
" " <<
m+1 <<
"/" << measures;
147 timer::cpu_timer timer;
150 for (
int r = 0; r < repeat; ++r) {
153 convolution.convolve(copied);
157 std::cout << image->getWidth() <<
',' << kernel->getWidth() <<
",\"" << conv_name <<
"\"," << timer.elapsed().wall <<
std::endl;
164 bool all_equal =
true;
165 for (
int x = 0;
x < a->getWidth(); ++
x) {
166 for (
int y = 0;
y < a->getHeight(); ++
y) {
167 auto av = a->getValue(
x,
y);
168 auto bv = b->getValue(
x,
y);
170 logger.info() <<
"Mismatch at " <<
x <<
',' <<
y <<
": "
171 << av <<
" != " << bv;
177 logger.info() <<
"All elements are equal!";
180 logger.warn() <<
"Convoluted images are not equal!";
po::options_description defineSpecificProgramOptions() override
std::shared_ptr< VectorImage< SeFloat > > generateImage(int size)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
std::shared_ptr< VectorImage< SeFloat > > benchmark(std::shared_ptr< VectorImage< SeFloat >> &image, std::shared_ptr< VectorImage< SeFloat >> &kernel, int repeat, int measures)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
#define MAIN_FOR(ELEMENTS_PROGRAM_NAME)
std::default_random_engine random_generator
Elements::ExitCode mainMethod(std::map< std::string, po::variable_value > &args) override
static Logging getLogger(const std::string &name="")
void verifyResults(std::shared_ptr< VectorImage< SeFloat >> a, std::shared_ptr< VectorImage< SeFloat >> b)