Optimized Belief Propagation (CPU and GPU)
RunBpOnStereoSet.h
Go to the documentation of this file.
1 /*
2 Copyright (C) 2024 Scott Grauer-Gray
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
28 #ifndef RUNBPSTEREOSET_H_
29 #define RUNBPSTEREOSET_H_
30 
31 #include <array>
32 #include <string>
33 #include <unordered_map>
34 #include <memory>
35 #include <optional>
36 #include <ranges>
39 #include "RunEval/RunData.h"
49 #include "ParallelParamsBp.h"
50 #include "ProcessBp.h"
51 
52 namespace beliefprop {
53 
59 {
60  std::chrono::duration<double> run_time;
63 };
64 
74 template <RunData_t T, unsigned int DISP_VALS, run_environment::AccSetting ACCELERATION>
75 struct BpOnDevice {
76  const std::unique_ptr<SmoothImage>& smooth_image;
77  const std::unique_ptr<ProcessBp<T, DISP_VALS, ACCELERATION>>& run_bp_stereo;
78  const std::unique_ptr<MemoryManagement<T>>& mem_management_bp_run;
79  const std::unique_ptr<MemoryManagement<float>>& mem_management_images;
80 };
81 
82 };
83 
92 template <RunData_t T, unsigned int DISP_VALS, run_environment::AccSetting ACCELERATION>
94 public:
101  virtual std::string BpRunDescription() const = 0;
102 
111  virtual std::optional<beliefprop::BpRunOutput> operator()(
112  const std::array<std::string, 2>& ref_test_image_path,
113  const beliefprop::BpSettings& alg_settings,
114  const ParallelParams& parallel_params) const = 0;
115 
116 protected:
128  std::optional<beliefprop::BpRunOutput> ProcessStereoSet(
129  const std::array<std::string, 2>& ref_test_image_path,
130  const beliefprop::BpSettings& alg_settings,
131  const beliefprop::BpOnDevice<T, DISP_VALS, ACCELERATION>& run_bp_on_device) const;
132 };
133 
134 //protected function to set up, run, and evaluate bp processing on target
135 //device using pointers to acceleration-specific smooth image,
136 //process BP, and memory management child class objects
137 template<RunData_t T, unsigned int DISP_VALS, run_environment::AccSetting ACCELERATION>
139  const std::array<std::string, 2>& ref_test_image_path,
140  const beliefprop::BpSettings& alg_settings,
141  const beliefprop::BpOnDevice<T, DISP_VALS, ACCELERATION>& run_bp_on_device) const
142 {
143  //retrieve the images as well as the width and height
144  const std::array<BpImage<unsigned int>, 2> input_images{
145  BpImage<unsigned int>(ref_test_image_path[0]),
146  BpImage<unsigned int>(ref_test_image_path[1])};
147  const std::array<unsigned int, 2> width_height_images{
148  input_images[0].Width(),
149  input_images[0].Height()};
150 
151  //get total number of pixels in input images
152  const unsigned int tot_num_pixels_images{
153  width_height_images[0] * width_height_images[1]};
154 
155  //initialize structures for timing data
156  std::unordered_map<beliefprop::Runtime_Type, std::array<timingType, 2>>
157  runtime_start_end_timings;
158  DetailedTimings detailed_bp_timings(beliefprop::kTimingNames);
159 
160  //initialize output disparity map
161  DisparityMap<float> output_disparity_map(width_height_images);
162 
163  //allocate data for bp processing on target device ahead of runs if option selected
164  T* bp_data{nullptr};
165  T* bp_proc_store{nullptr};
167  //allocate memory on device for bp processing
168  const std::size_t num_data =
170  width_height_images,
171  alg_settings.num_disp_vals,
172  alg_settings.num_levels,
173  ACCELERATION);
174  bp_data =
175  run_bp_on_device.mem_management_bp_run->AllocateAlignedMemoryOnDevice(
176  10*num_data,
177  ACCELERATION);
178  if (run_bp_on_device.run_bp_stereo->ErrorCheck(__FILE__, __LINE__) !=
179  run_eval::Status::kNoError) { return {}; }
180 
181  BpLevel<T> bottom_bp_level(width_height_images, 0, 0, ACCELERATION);
182  const std::size_t total_data_bottom_level =
183  bottom_bp_level.NumDataInBpArrays(alg_settings.num_disp_vals);
184  bp_proc_store =
185  run_bp_on_device.mem_management_bp_run->AllocateAlignedMemoryOnDevice(
186  total_data_bottom_level,
187  ACCELERATION);
188  if (run_bp_on_device.run_bp_stereo->ErrorCheck(__FILE__, __LINE__) !=
189  run_eval::Status::kNoError) { return {}; }
190  }
191 
192  //run bp processing for specified number of runs
193  const unsigned int num_evaluation_runs{
195  for (unsigned int num_run = 0;
196  num_run < num_evaluation_runs;
197  num_run++)
198  {
199  //allocate the device memory to store and x and y smoothed images
200  std::array<float*, 2> smoothed_images{
201  run_bp_on_device.mem_management_images->AllocateMemoryOnDevice(
202  tot_num_pixels_images),
203  run_bp_on_device.mem_management_images->AllocateMemoryOnDevice(
204  tot_num_pixels_images)};
205 
206  if (run_bp_on_device.run_bp_stereo->ErrorCheck(__FILE__, __LINE__) !=
208  {
209  //return std::optional object with no value indicating error in run
210  return {};
211  }
212 
213  //set start timer for specified runtime segments at time before smoothing images
214  runtime_start_end_timings[beliefprop::Runtime_Type::kSmoothing][0] =
215  std::chrono::system_clock::now();
216  runtime_start_end_timings[beliefprop::Runtime_Type::kTotalNoTransfer][0] =
217  std::chrono::system_clock::now();
218  runtime_start_end_timings[beliefprop::Runtime_Type::kTotalWithTransfer][0] =
219  std::chrono::system_clock::now();
220 
221  //first smooth the images using the Gaussian filter with the given smoothing sigma value
222  //smoothed images are stored on the target device
223  for (unsigned int i = 0; i < 2; i++) {
224  (*(run_bp_on_device.smooth_image))(
225  input_images[i],
226  alg_settings.smoothing_sigma,
227  smoothed_images[i]);
228  if (run_bp_on_device.run_bp_stereo->ErrorCheck(__FILE__, __LINE__) !=
230  {
231  //return std::optional object with no value indicating error in run
232  return {};
233  }
234  }
235 
236  //end timer for image smoothing and add to image smoothing timings
237  runtime_start_end_timings[beliefprop::Runtime_Type::kSmoothing][1] =
238  std::chrono::system_clock::now();
239 
240  //get and store time point at start of bp processing
241  runtime_start_end_timings[beliefprop::Runtime_Type::kTotalBp][0] =
242  std::chrono::system_clock::now();
243 
244  //run belief propagation on device as specified by input pointer to
245  //ProcessBp object run_bp_stereo
246  //returns detailed timings for bp run
247  auto bp_stereo_output =
248  (*(run_bp_on_device.run_bp_stereo))(
249  smoothed_images,
250  alg_settings,
251  width_height_images,
252  bp_data,
253  bp_proc_store,
254  run_bp_on_device.mem_management_bp_run);
255  if (!bp_stereo_output) {
256  //return std::optional object with no value if null output indicating
257  //error in run
258  return {};
259  }
260 
261  //get references to disparity map and run timings from bp output
262  const auto& [bp_disparity_map, bp_run_timings] = *bp_stereo_output;
263 
264  //get and store end timepoint of bp run for computation of total runtime
265  runtime_start_end_timings[beliefprop::Runtime_Type::kTotalBp][1] =
266  std::chrono::system_clock::now();
267  runtime_start_end_timings[beliefprop::Runtime_Type::kTotalNoTransfer][1] =
268  std::chrono::system_clock::now();
269 
270  //transfer the disparity map estimation on the device to the host for
271  //output
272  run_bp_on_device.mem_management_images->TransferDataFromDeviceToHost(
273  output_disparity_map.PointerToPixelsStart(),
274  bp_disparity_map,
275  tot_num_pixels_images);
276 
277  //compute timings for each portion of interest and add to vector timings
278  runtime_start_end_timings[beliefprop::Runtime_Type::kTotalWithTransfer][1] =
279  std::chrono::system_clock::now();
280 
281  //retrieve the duration for each segment and add to bp timings
282  std::ranges::for_each(runtime_start_end_timings,
283  [&detailed_bp_timings](const auto& current_runtime_name_timing) {
284  detailed_bp_timings.AddTiming(
285  current_runtime_name_timing.first,
286  current_runtime_name_timing.second[1] - current_runtime_name_timing.second[0]);
287  });
288 
289  //add bp timings from current run to overall timings
290  detailed_bp_timings.AddToCurrentTimings(bp_run_timings);
291 
292  //free the space allocated to the resulting disparity map and smoothed
293  //images on the computation device
294  run_bp_on_device.mem_management_images->FreeMemoryOnDevice(bp_disparity_map);
295  for (auto& smoothed_image : smoothed_images) {
296  run_bp_on_device.mem_management_images->FreeMemoryOnDevice(smoothed_image);
297  }
298  }
299 
300  //free data for bp processing on target device if this memory
301  //management set to be done outside of runs
303  run_bp_on_device.mem_management_bp_run->FreeAlignedMemoryOnDevice(bp_data);
304  run_bp_on_device.mem_management_bp_run->FreeAlignedMemoryOnDevice(bp_proc_store);
305  }
306 
307  //construct RunData object with bp input and timing info
308  RunData run_data;
309  run_data.AddDataWHeader(
310  std::string(beliefprop::kImageWidthHeader),
311  width_height_images[0]);
312  run_data.AddDataWHeader(
313  std::string(beliefprop::kImageHeightHeader),
314  width_height_images[1]);
315  run_data.AddDataWHeader(
316  std::string(beliefprop::kNumEvalRuns),
317  num_evaluation_runs);
318  run_data.AppendData(detailed_bp_timings.AsRunData());
319 
320  //construct and return beliefprop::BpRunOutput object inside of std::optional
321  //object
322  return {beliefprop::BpRunOutput{
323  detailed_bp_timings.MedianTiming(
325  std::move(output_disparity_map),
326  std::move(run_data)}};
327 }
328 
329 #endif /* RUNBPSTEREOSET_H_ */
File with namespace for enums, constants, structures, and functions specific to belief propagation pr...
Header file that contains information about the stereo sets used for evaluation of the bp implementat...
Declares class to define images that are used in bp processing.
Constants for timing belief propagation implementation.
Declares class to store timings of one or more segments taken during the run(s) of an implementation ...
Declares child class of BpImage to define disparity map image that is output from bp processing.
Declares class for memory management with functions defined for standard memory allocation using CPU ...
Declares child class of ParallelParams to store and process parallelization parameters to use in each...
Declares abstract class to run belief propagation on target device. Some of the class functions need ...
Declares class to store headers with data corresponding to current program run and evaluation.
Contains namespace with enums and constants for implementation run evaluation.
Declares and defines structure that stores settings for current implementation run as well as functio...
Define constraints for data type in processing.
Declares class for smoothing the images before running BP.
Class to define images that are used in bp processing.
Definition: BpImage.h:56
unsigned int Width() const
Definition: BpImage.h:105
T * PointerToPixelsStart() const
Definition: BpImage.h:85
Class to store and retrieve properties of a bp processing level including a data type specified as a ...
Definition: BpLevel.h:60
std::size_t NumDataInBpArrays(unsigned int num_disparity_values) const
Get the amount of data in each BP array (data cost/messages for each checkerboard) at the current lev...
Definition: BpLevel.h:231
static std::size_t TotalDataForAlignedMemoryAllLevels(const std::array< unsigned int, 2 > &width_height_bottom_level, unsigned int num_possible_disparities, unsigned int num_levels, run_environment::AccSetting acceleration)
Static function to get count of total data needed for bp processing at all levels.
Definition: BpLevel.h:282
Class to store timings of one or more segments taken during the run(s) of an implementation or across...
std::chrono::duration< double > MedianTiming(const T run_segment_index) const
Get median timing for a specified segment that may have been run multiple times.
void AddToCurrentTimings(const DetailedTimings &in_detailed_timings)
Add instance of DetailedTimings to current DetailedTimings.
RunData AsRunData() const
Return current timing data as a RunData object for evaluation.
void AddTiming(const T timing_segment, const std::chrono::duration< double > &segment_time)
Add timing by segment index.
Abstract class for holding and processing parallelization parameters. Child class(es) specific to im...
Abstract class to set up and run belief propagation on target device using specified acceleration.
std::optional< beliefprop::BpRunOutput > ProcessStereoSet(const std::array< std::string, 2 > &ref_test_image_path, const beliefprop::BpSettings &alg_settings, const beliefprop::BpOnDevice< T, DISP_VALS, ACCELERATION > &run_bp_on_device) const
Protected function to set up, run, and evaluate bp processing on target device using pointers to acce...
virtual std::string BpRunDescription() const =0
Pure virtual function to return run description corresponding to target acceleration.
virtual std::optional< beliefprop::BpRunOutput > operator()(const std::array< std::string, 2 > &ref_test_image_path, const beliefprop::BpSettings &alg_settings, const ParallelParams &parallel_params) const =0
Pure virtual operator() overload that must be defined in child class.
Class to store headers with data corresponding to current program run and evaluation.
Definition: RunData.h:42
void AppendData(const RunData &rundata)
Append current RunData with input RunData.
Definition: RunData.cpp:99
void AddDataWHeader(const std::string &header, const std::string &data)
Add string data with header describing added data.
Definition: RunData.cpp:49
Namespace for enums, constants, structures, and functions specific to belief propagation processing.
constexpr bool kAllocateFreeBpMemoryOutsideRuns
Definition: BpRunUtils.h:115
constexpr std::string_view kNumEvalRuns
Header for number of evaluation runs (can differ across stereo sets)
const std::unordered_map< Runtime_Type, std::string_view > kTimingNames
Mapping of runtime segment enum to header describing timing of the segment.
constexpr std::string_view kImageWidthHeader
unsigned int NumBpStereoRuns(unsigned int disparity_vals)
Get number of stereo runs when evaluating implementation Perform less stereo runs if greater number o...
Definition: BpRunUtils.h:91
constexpr std::string_view kImageHeightHeader
Structure with pointers to objects containing functions for smoothing images, processing bp,...
const std::unique_ptr< MemoryManagement< float > > & mem_management_images
const std::unique_ptr< ProcessBp< T, DISP_VALS, ACCELERATION > > & run_bp_stereo
const std::unique_ptr< MemoryManagement< T > > & mem_management_bp_run
const std::unique_ptr< SmoothImage > & smooth_image
Structure with output disparity map, runtime, and other evaluation data.
std::chrono::duration< double > run_time
DisparityMap< float > out_disparity_map
Structure to store the belief propagation settings including the number of levels and iterations.
Definition: BpSettings.h:87
unsigned int num_disp_vals
Number of disparity values must be set for each stereo set.
Definition: BpSettings.h:101
unsigned int num_levels
Definition: BpSettings.h:89