PURIFY
Next-generation radio interferometric imaging
measurement_operator_mpi.cc
Go to the documentation of this file.
1 #include <chrono>
2 #include <sstream>
3 #include <benchmark/benchmark.h>
4 #include "benchmarks/utilities.h"
5 #include "purify/directories.h"
6 #include "purify/operators.h"
7 #include <sopt/imaging_padmm.h>
8 #include <sopt/mpi/communicator.h>
9 #include <sopt/mpi/session.h>
10 #include <sopt/wavelets.h>
11 
12 using namespace purify;
13 
14 // ----------------- Degrid operator constructor fixture -----------------------//
15 
16 class DegridOperatorCtorFixturePar : public ::benchmark::Fixture {
17  public:
18  void SetUp(const ::benchmark::State &state) {
19  // Keep count of the benchmark repetitions
20 
21  m_counter++;
22 
23  m_imsizex = state.range(0);
24  m_imsizey = state.range(0);
25 
26  // Generating random uv(w) coverage
27  bool newMeasurements = b_utilities::updateMeasurements(state.range(1), m_uv_data, m_world);
28 
29  // Data needed for the creation of the measurement operator
30  const t_real FoV = 1; // deg
31  m_cellsize = FoV / m_imsizex * 60. * 60.;
32  m_w_term = false;
33  }
34 
35  void TearDown(const ::benchmark::State &state) {}
36 
37  t_uint m_counter;
38  sopt::mpi::Communicator m_world;
39  t_uint m_imsizex;
40  t_uint m_imsizey;
42  t_real m_cellsize;
43  bool m_w_term;
44 };
45 
46 // -------------- Constructor benchmarks -------------------------//
47 
48 BENCHMARK_DEFINE_F(DegridOperatorCtorFixturePar, Distr)(benchmark::State &state) {
49  // benchmark the creation of the distributed measurement operator
50  if ((m_counter % 10) == 1) {
51  auto sky_measurements = measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
52  m_world, m_uv_data, m_imsizey, m_imsizex, m_cellsize, m_cellsize, 2, kernels::kernel::kb,
53  state.range(2), state.range(2), m_w_term);
54  }
55  while (state.KeepRunning()) {
56  auto start = std::chrono::high_resolution_clock::now();
57  auto sky_measurements = measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
58  m_world, m_uv_data, m_imsizey, m_imsizex, m_cellsize, m_cellsize, 2, kernels::kernel::kb,
59  state.range(2), state.range(2), m_w_term);
60  auto end = std::chrono::high_resolution_clock::now();
61  state.SetIterationTime(b_utilities::duration(start, end, m_world));
62  }
63 
64  state.SetBytesProcessed(int64_t(state.iterations()) * (state.range(1) + m_imsizex * m_imsizey) *
65  sizeof(t_complex));
66 }
67 
68 BENCHMARK_DEFINE_F(DegridOperatorCtorFixturePar, MPI)(benchmark::State &state) {
69  // benchmark the creation of the distributed MPI measurement operator
70  if ((m_counter % 10) == 1) {
71  auto sky_measurements = measurementoperator::init_degrid_operator_2d_mpi<Vector<t_complex>>(
72  m_world, m_uv_data, m_imsizey, m_imsizex, m_cellsize, m_cellsize, 2, kernels::kernel::kb,
73  state.range(2), state.range(2), m_w_term);
74  }
75  while (state.KeepRunning()) {
76  auto start = std::chrono::high_resolution_clock::now();
77  auto sky_measurements = measurementoperator::init_degrid_operator_2d_mpi<Vector<t_complex>>(
78  m_world, m_uv_data, m_imsizey, m_imsizex, m_cellsize, m_cellsize, 2, kernels::kernel::kb,
79  state.range(2), state.range(2), m_w_term);
80  auto end = std::chrono::high_resolution_clock::now();
81  state.SetIterationTime(b_utilities::duration(start, end, m_world));
82  }
83 
84  state.SetBytesProcessed(int64_t(state.iterations()) * (state.range(1) + m_imsizex * m_imsizey) *
85  sizeof(t_complex));
86 }
87 
88 // ----------------- Application fixtures -----------------------//
89 
90 class DegridOperatorFixturePar : public ::benchmark::Fixture {
91  public:
92  void SetUp(const ::benchmark::State &state) {
93  // Reading image from file and create temporary image
94  bool newImage = updateImage(state.range(0));
95 
96  // Generating random uv(w) coverage
97  // bool newMeasurements = m_uv_data.size() != state.range(1);
98  bool newMeasurements = b_utilities::updateMeasurements(state.range(1), m_uv_data, m_world);
99 
100  // Create measurement operators
101  bool newKernel = m_kernel != state.range(2);
102  if (newImage || newMeasurements || newKernel) {
103  const t_real FoV = 1; // deg
104  const t_real cellsize = FoV / m_imsizex * 60. * 60.;
105  const bool w_term = false;
106  m_kernel = state.range(2);
107  m_degridOperator = measurementOperator(cellsize, w_term);
108  }
109  }
110 
111  void TearDown(const ::benchmark::State &state) {}
112 
113  virtual bool updateImage(t_uint newSize) = 0;
114  virtual std::shared_ptr<sopt::LinearTransform<Vector<t_complex>> const> measurementOperator(
115  t_real cellsize, bool w_term) = 0;
116 
117  sopt::mpi::Communicator m_world;
118  t_uint m_kernel;
119 
120  t_uint m_imsizex;
121  t_uint m_imsizey;
122 
124 
125  std::shared_ptr<sopt::LinearTransform<Vector<t_complex>> const> m_degridOperator;
126 };
127 
129  public:
130  virtual bool updateImage(t_uint newSize) {
131  return b_utilities::updateImage(newSize, m_image, m_imsizex, m_imsizey);
132  }
133 
134  Image<t_complex> m_image;
135 };
136 
138  public:
139  virtual bool updateImage(t_uint newSize) {
140  return b_utilities::updateEmptyImage(newSize, m_image, m_imsizex, m_imsizey);
141  }
142 
143  Vector<t_complex> m_image;
144 };
145 
147  public:
148  virtual std::shared_ptr<sopt::LinearTransform<Vector<t_complex>> const> measurementOperator(
149  t_real cellsize, bool w_term) {
150  return measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
151  m_world, m_uv_data, m_imsizey, m_imsizex, cellsize, cellsize, 2, kernels::kernel::kb,
152  m_kernel, m_kernel, w_term);
153  }
154 };
155 
157  public:
158  virtual std::shared_ptr<sopt::LinearTransform<Vector<t_complex>> const> measurementOperator(
159  t_real cellsize, bool w_term) {
160  return measurementoperator::init_degrid_operator_2d_mpi<Vector<t_complex>>(
161  m_world, m_uv_data, m_imsizey, m_imsizex, cellsize, cellsize, 2, kernels::kernel::kb,
162  m_kernel, m_kernel, w_term);
163  }
164 };
165 
167  public:
168  virtual std::shared_ptr<sopt::LinearTransform<Vector<t_complex>> const> measurementOperator(
169  t_real cellsize, bool w_term) {
170  return measurementoperator::init_degrid_operator_2d<Vector<t_complex>>(
171  m_world, m_uv_data, m_imsizey, m_imsizex, cellsize, cellsize, 2, kernels::kernel::kb,
172  m_kernel, m_kernel, w_term);
173  }
174 };
175 
177  public:
178  virtual std::shared_ptr<sopt::LinearTransform<Vector<t_complex>> const> measurementOperator(
179  t_real cellsize, bool w_term) {
180  return measurementoperator::init_degrid_operator_2d_mpi<Vector<t_complex>>(
181  m_world, m_uv_data, m_imsizey, m_imsizex, cellsize, cellsize, 2, kernels::kernel::kb,
182  m_kernel, m_kernel, w_term);
183  }
184 };
185 
186 // ----------------- Application benchmarks -----------------------//
187 
188 BENCHMARK_DEFINE_F(DegridOperatorDirectFixtureDistr, Apply)(benchmark::State &state) {
189  // Benchmark the application of the distributed operator
190  while (state.KeepRunning()) {
191  auto start = std::chrono::high_resolution_clock::now();
192  m_uv_data.vis = (*m_degridOperator) * Image<t_complex>::Map(m_image.data(), m_image.size(), 1);
193  auto end = std::chrono::high_resolution_clock::now();
194  state.SetIterationTime(b_utilities::duration(start, end, m_world));
195  }
196 
197  state.SetBytesProcessed(int64_t(state.iterations()) * (state.range(1) + m_imsizey * m_imsizex) *
198  sizeof(t_complex));
199 }
200 
201 BENCHMARK_DEFINE_F(DegridOperatorAdjointFixtureDistr, Apply)(benchmark::State &state) {
202  // Benchmark the application of the adjoint distributed operator
203  while (state.KeepRunning()) {
204  auto start = std::chrono::high_resolution_clock::now();
205  m_image = m_degridOperator->adjoint() * m_uv_data.vis;
206  auto end = std::chrono::high_resolution_clock::now();
207  state.SetIterationTime(b_utilities::duration(start, end, m_world));
208  }
209 
210  state.SetBytesProcessed(int64_t(state.iterations()) * (state.range(1) + m_imsizey * m_imsizex) *
211  sizeof(t_complex));
212 }
213 
214 BENCHMARK_DEFINE_F(DegridOperatorDirectFixtureMPI, Apply)(benchmark::State &state) {
215  // Benchmark the application of the distributed MPI operator
216  while (state.KeepRunning()) {
217  auto start = std::chrono::high_resolution_clock::now();
218  m_uv_data.vis = (*m_degridOperator) * Image<t_complex>::Map(m_image.data(), m_image.size(), 1);
219  auto end = std::chrono::high_resolution_clock::now();
220  state.SetIterationTime(b_utilities::duration(start, end, m_world));
221  }
222 
223  state.SetBytesProcessed(int64_t(state.iterations()) * (state.range(1) + m_imsizey * m_imsizex) *
224  sizeof(t_complex));
225 }
226 
227 BENCHMARK_DEFINE_F(DegridOperatorAdjointFixtureMPI, Apply)(benchmark::State &state) {
228  // Benchmark the application of the adjoint distributed MPI operator
229  while (state.KeepRunning()) {
230  auto start = std::chrono::high_resolution_clock::now();
231  m_image = m_degridOperator->adjoint() * m_uv_data.vis;
232  auto end = std::chrono::high_resolution_clock::now();
233  state.SetIterationTime(b_utilities::duration(start, end, m_world));
234  }
235 
236  state.SetBytesProcessed(int64_t(state.iterations()) * (state.range(1) + m_imsizey * m_imsizex) *
237  sizeof(t_complex));
238 }
239 
240 // -------------- Register benchmarks -------------------------//
241 /*
242 BENCHMARK_REGISTER_F(DegridOperatorCtorFixturePar, Distr)
243  //->Apply(b_utilities::Arguments)
244  ->Args({1024, 1000000, 4})
245  ->Args({1024, 10000000, 4})
246  ->UseManualTime()
247  ->Repetitions(10)
248  //->ReportAggregatesOnly(true)
249  ->Unit(benchmark::kMillisecond);
250 BENCHMARK_REGISTER_F(DegridOperatorCtorFixturePar, MPI)
251  //->Apply(b_utilities::Arguments)
252  ->Args({1024, 1000000, 4})
253  ->Args({1024, 10000000, 4})
254  ->UseManualTime()
255  ->Repetitions(10)
256  //->ReportAggregatesOnly(true)
257  ->Unit(benchmark::kMillisecond);
258  */
259 
260 BENCHMARK_REGISTER_F(DegridOperatorDirectFixtureDistr, Apply)
261  //->Apply(b_utilities::Arguments)
262  ->Args({1024, static_cast<t_int>(1e6), 4})
263  ->Args({1024, static_cast<t_int>(1e7), 4})
264  ->UseManualTime()
265  ->MinTime(10.0)
266  ->MinWarmUpTime(5.0)
267  ->Repetitions(3)
268  //->ReportAggregatesOnly(true)
269  ->Unit(benchmark::kMillisecond);
270 
271 BENCHMARK_REGISTER_F(DegridOperatorAdjointFixtureDistr, Apply)
272  //->Apply(b_utilities::Arguments)
273  ->Args({1024, static_cast<t_int>(1e6), 4})
274  ->Args({1024, static_cast<t_int>(1e7), 4})
275  ->UseManualTime()
276  ->MinTime(10.0)
277  ->MinWarmUpTime(5.0)
278  ->Repetitions(3)
279  //->ReportAggregatesOnly(true)
280  ->Unit(benchmark::kMillisecond);
281 
282 BENCHMARK_REGISTER_F(DegridOperatorDirectFixtureMPI, Apply)
283  //->Apply(b_utilities::Arguments)
284  ->Args({1024, static_cast<t_int>(1e6), 4})
285  ->Args({1024, static_cast<t_int>(1e7), 4})
286  ->UseManualTime()
287  ->MinTime(10.0)
288  ->MinWarmUpTime(5.0)
289  ->Repetitions(3)
290  //->ReportAggregatesOnly(true)
291  ->Unit(benchmark::kMillisecond);
292 
293 BENCHMARK_REGISTER_F(DegridOperatorAdjointFixtureMPI, Apply)
294  //->Apply(b_utilities::Arguments)
295  ->Args({1024, static_cast<t_int>(1e6), 4})
296  ->Args({1024, static_cast<t_int>(1e7), 4})
297  ->UseManualTime()
298  ->MinTime(10.0)
299  ->MinWarmUpTime(5.0)
300  ->Repetitions(3)
301  //->ReportAggregatesOnly(true)
302  ->Unit(benchmark::kMillisecond);
virtual std::shared_ptr< sopt::LinearTransform< Vector< t_complex > > const > measurementOperator(t_real cellsize, bool w_term)
virtual std::shared_ptr< sopt::LinearTransform< Vector< t_complex > > const > measurementOperator(t_real cellsize, bool w_term)
virtual bool updateImage(t_uint newSize)
void SetUp(const ::benchmark::State &state)
void TearDown(const ::benchmark::State &state)
virtual std::shared_ptr< sopt::LinearTransform< Vector< t_complex > > const > measurementOperator(t_real cellsize, bool w_term)
virtual std::shared_ptr< sopt::LinearTransform< Vector< t_complex > > const > measurementOperator(t_real cellsize, bool w_term)
virtual bool updateImage(t_uint newSize)
void TearDown(const ::benchmark::State &state)
sopt::mpi::Communicator m_world
virtual std::shared_ptr< sopt::LinearTransform< Vector< t_complex > > const > measurementOperator(t_real cellsize, bool w_term)=0
void SetUp(const ::benchmark::State &state)
std::shared_ptr< sopt::LinearTransform< Vector< t_complex > > const > m_degridOperator
virtual bool updateImage(t_uint newSize)=0
Args({1024, static_cast< t_int >(1e6), 4}) -> Args({1024, static_cast< t_int >(1e7), 4}) ->UseManualTime() ->MinTime(10.0) ->MinWarmUpTime(5.0) ->Repetitions(3) ->Unit(benchmark::kMillisecond)
BENCHMARK_DEFINE_F(DegridOperatorCtorFixturePar, Distr)(benchmark
bool updateMeasurements(t_uint newSize, utilities::vis_params &data)
Definition: utilities.cc:54
bool updateImage(t_uint newSize, Image< t_complex > &image, t_uint &sizex, t_uint &sizey)
Definition: utilities.cc:32
bool updateEmptyImage(t_uint newSize, Vector< t_complex > &image, t_uint &sizex, t_uint &sizey)
Definition: utilities.cc:44
double duration(std::chrono::high_resolution_clock::time_point start, std::chrono::high_resolution_clock::time_point end)
Definition: utilities.cc:26