SourceXtractorPlusPlus  0.11
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BenchConvolution.cpp
Go to the documentation of this file.
1 
24 #include <map>
25 #include <string>
26 
27 #include <boost/program_options.hpp>
28 #include <boost/timer/timer.hpp>
29 #include <random>
31 #include "ElementsKernel/Real.h"
32 #include "SEUtils/IsClose.h"
36 #ifdef WITH_OPENCV
38 #endif
39 
40 #if BOOST_VERSION < 105600
41 #include <boost/units/detail/utility.hpp>
42 using boost::units::detail::demangle;
43 #else
44 using boost::core::demangle;
45 #endif
46 
47 namespace po = boost::program_options;
48 namespace timer = boost::timer;
49 using namespace SourceXtractor;
50 
52 
54 private:
57 
58 public:
59 
60  po::options_description defineSpecificProgramOptions() override {
61  po::options_description options{};
62  options.add_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");
70  return options;
71  }
72 
74  auto img = VectorImage<SeFloat>::create(size, size);
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));
78  }
79  }
80  return img;
81  }
82 
84 
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>();
92 
93  std::cout << "Image,Kernel,Implementation,Time" << std::endl;
94 
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);
98 
99  for (int krn_step = 0; krn_step < krn_nsteps; ++krn_step) {
100  auto krn_size = krn_start + krn_step * step_size;
101 
102  logger.info() << "Using an image of " << img_size << "x" << img_size;
103  logger.info() << "Using a kernel of " << krn_size << "x" << krn_size;
104 
105  auto kernel = generateImage(krn_size);
106 
107 #ifdef WITH_OPENCV
108  logger.info() << "Timing OpenCV implementation";
109  auto opencv_result = benchmark<OpenCVConvolution>(image, kernel, repeat, measures);
110 #endif
111 
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);
115 
116 #ifdef WITH_OPENCV
117  logger.info() << "Compare OpenCV vs Direct Result";
118  verifyResults(opencv_result, direct_result);
119 #endif
120  }
121 
122  logger.info() << "Timing DFT implementation";
123  auto dft_result = benchmark<DFTConvolution<SeFloat>>(image, kernel, repeat, measures);
124 
125 #ifdef WITH_OPENCV
126  logger.info() << "Compare OpenCV vs DFT Result";
127  verifyResults(opencv_result, dft_result);
128 #endif
129  }
130  }
131 
132  return Elements::ExitCode::OK;
133  }
134 
135  template<typename Convolution>
138  int repeat, int measures) {
139  auto conv_name = demangle(typeid(Convolution).name());
140 
141  Convolution convolution(kernel);
142 
144 
145  for (int m = 0; m < measures; ++m) {
146  logger.info() << conv_name << " " << m+1 << "/" << measures;
147  timer::cpu_timer timer;
148  timer.stop();
149 
150  for (int r = 0; r < repeat; ++r) {
151  copied = VectorImage<SeFloat>::create(*image);
152  timer.start();
153  convolution.convolve(copied);
154  timer.stop();
155  }
156 
157  std::cout << image->getWidth() << ',' << kernel->getWidth() << ",\"" << conv_name << "\"," << timer.elapsed().wall << std::endl;
158  }
159 
160  return copied;
161  }
162 
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);
169  if (!isClose(av, bv)) {
170  logger.info() << "Mismatch at " << x << ',' << y << ": "
171  << av << " != " << bv;
172  all_equal = false;
173  }
174  }
175  }
176  if (all_equal) {
177  logger.info() << "All elements are equal!";
178  }
179  else {
180  logger.warn() << "Convoluted images are not equal!";
181  }
182  }
183 };
184 
186 
187 
188 
po::options_description defineSpecificProgramOptions() override
static Elements::Logging logger
std::shared_ptr< VectorImage< SeFloat > > generateImage(int size)
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
T endl(T...args)
void info(const std::string &logMessage)
static std::shared_ptr< VectorImage< T > > create(Args &&...args)
Definition: VectorImage.h:89
bool isClose(double a, double b, double atol=1e-8, double rtol=1e-5)
Definition: IsClose.h:28
STL class.
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
constexpr double m
Image implementation which keeps the pixel values in memory.
Definition: VectorImage.h:53
#define MAIN_FOR(ELEMENTS_PROGRAM_NAME)
void warn(const std::string &logMessage)
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)