SourceXtractorPlusPlus  0.11
Please provide a description of the project.
BenchBackgroundConvolution.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"
35 #include "SEUtils/IsClose.h"
36 
37 #if BOOST_VERSION < 105600
38 #include <boost/units/detail/utility.hpp>
39 using boost::units::detail::demangle;
40 #else
41 using boost::core::demangle;
42 #endif
43 
44 namespace po = boost::program_options;
45 namespace timer = boost::timer;
46 using namespace SourceXtractor;
47 
48 static Elements::Logging logger = Elements::Logging::getLogger("BenchBackgroundConvolution");
49 
51 private:
54 
55 public:
56 
57  po::options_description defineSpecificProgramOptions() override {
58  po::options_description options{};
59  options.add_options()
60  ("image-start", po::value<int>()->default_value(100), "Image start size")
61  ("image-step-size", po::value<int>()->default_value(3), "Image step size")
62  ("image-nsteps", po::value<int>()->default_value(1), "Number of steps for the image")
63  ("kernel-start", po::value<int>()->default_value(3), "Kernel start size")
64  ("kernel-step-size", po::value<int>()->default_value(4), "Kernel step size")
65  ("kernel-nsteps", po::value<int>()->default_value(2), "Number of steps for the kernel")
66  ("repeat", po::value<int>()->default_value(5), "Repeat")
67  ("measures", po::value<int>()->default_value(10), "Number of measures");
68  return options;
69  }
70 
72  auto img = VectorImage<SeFloat>::create(size, size);
73  for (int x = 0; x < size; ++x) {
74  for (int y = 0; y < size; ++y) {
75  img->setValue(x, y, random_dist(random_generator));
76  }
77  }
78  return img;
79  }
80 
82 
83  auto img_start = args["image-start"].as<int>();
84  auto img_step_size = args["image-step-size"].as<int>();
85  auto img_nsteps = args["image-nsteps"].as<int>();
86  auto krn_start = args["kernel-start"].as<int>();
87  auto krn_step_size = args["kernel-step-size"].as<int>();
88  auto krn_nsteps = args["kernel-nsteps"].as<int>();
89  auto repeat = args["repeat"].as<int>();
90  auto measures = args["measures"].as<int>();
91 
92  std::cout << "Image,Kernel,Implementation,Time" << std::endl;
93 
94  for (int img_step = 0; img_step < img_nsteps; ++img_step) {
95  auto img_size = img_start + img_step * img_step_size;
96  auto image = generateImage(img_size);
97  auto variance = generateImage(img_size);
98 
99  for (int krn_step = 0; krn_step < krn_nsteps; ++krn_step) {
100  auto krn_size = krn_start + krn_step * krn_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  logger.info() << "Timing Direct implementation";
108  auto direct_result = benchmark<BgConvolutionImageSource>(image, variance, kernel, repeat, measures);
109 
110  logger.info() << "Timing DFT implementation";
111  auto dft_result = benchmark<BgDFTConvolutionImageSource>(image, variance, kernel, repeat, measures);
112 
113  logger.info() << "Comparing results";
114  verifyResults(direct_result, dft_result);
115  }
116  }
117 
118  return Elements::ExitCode::OK;
119  }
120 
121  template<typename BackgroundConvolution>
124  std::shared_ptr<VectorImage<SeFloat>>& kernel, int repeat, int measures) {
125  auto conv_name = demangle(typeid(BackgroundConvolution).name());
126 
127  auto bg_convolution = std::make_shared<BackgroundConvolution>(image, variance, 0.5, kernel);
128 
130 
131  for (int m = 0; m < measures; ++m) {
132  logger.info() << conv_name << " " << m + 1 << "/" << measures;
133  timer::cpu_timer timer;
134  timer.stop();
135 
136  for (int r = 0; r < repeat; ++r) {
137  timer.start();
138  result = bg_convolution->getImageTile(0, 0, image->getWidth(), image->getHeight())->getImage();
139  timer.stop();
140  }
141 
142  std::cout << image->getWidth() << ',' << kernel->getWidth() << ",\"" << conv_name << "\"," << timer.elapsed().wall
143  << std::endl;
144  }
145 
146  return result;
147  }
148 
150  bool all_equal = true;
151  for (int x = 0; x < a->getWidth(); ++x) {
152  for (int y = 0; y < a->getHeight(); ++y) {
153  auto av = a->getValue(x, y);
154  auto bv = b->getValue(x, y);
155  if (!isClose(av, bv, 1e-3, 1e-3)) {
156  logger.info() << "Mismatch at " << x << ',' << y << ": "
157  << av << " != " << bv;
158  all_equal = false;
159  }
160  }
161  }
162  if (all_equal) {
163  logger.info() << "All elements are equal!";
164  } else {
165  logger.warn() << "Convoluted images are not equal!";
166  }
167  }
168 };
169 
std::default_random_engine random_generator
static Elements::Logging logger
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
constexpr double e
T endl(T... args)
void info(const std::string &logMessage)
bool isClose(double a, double b, double atol=1e-8, double rtol=1e-5)
Definition: IsClose.h:28
STL class.
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
void verifyResults(std::shared_ptr< VectorImage< SeFloat >> a, std::shared_ptr< VectorImage< SeFloat >> b)
constexpr double m
Image implementation which keeps the pixel values in memory.
Definition: VectorImage.h:53
#define MAIN_FOR(ELEMENTS_PROGRAM_NAME)
static std::shared_ptr< VectorImage< T > > create(Args &&... args)
Definition: VectorImage.h:89
void warn(const std::string &logMessage)
std::shared_ptr< VectorImage< SeFloat > > generateImage(int size)
Elements::ExitCode mainMethod(std::map< std::string, po::variable_value > &args) override
po::options_description defineSpecificProgramOptions() override
std::shared_ptr< VectorImage< SeFloat > > benchmark(std::shared_ptr< VectorImage< SeFloat >> &image, std::shared_ptr< VectorImage< SeFloat >> &variance, std::shared_ptr< VectorImage< SeFloat >> &kernel, int repeat, int measures)
static Logging getLogger(const std::string &name="")