Optimized Belief Propagation (CPU and GPU)
EvaluateImpResults.cpp
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 
27 #include <sstream>
28 #include <numeric>
29 #include <fstream>
30 #include <algorithm>
31 #include "EvaluateAcrossRuns.h"
32 #include "RunResultsSpeedups.h"
33 #include "EvaluateImpResults.h"
34 
35 //evaluate results for implementation runs on multiple inputs with all the runs
36 //having the same data type and acceleration method
37 //return run data with speedup from evaluation of implementation runs using
38 //multiple inputs with runs having the same data type and acceleration method
39 std::pair<MultRunData, std::vector<RunSpeedupAvgMedian>>
41  const MultRunData& run_results,
42  const run_environment::RunImpSettings& run_imp_settings,
43  size_t data_size) const
44 {
45  //store whether or not parallel parameters optimized in run
46  const bool p_params_optimized{
47  (!(run_imp_settings.p_params_default_alt_options.second.empty()))};
48 
49  //initialize and add speedup results over baseline data if available for
50  //current input
51  auto run_imp_opt_results = run_results;
52  const auto speedup_over_baseline =
53  GetSpeedupOverBaseline(
54  run_imp_settings,
55  run_imp_opt_results,
56  data_size);
57  const auto speedup_over_baseline_subsets =
58  GetSpeedupOverBaselineSubsets(
59  run_imp_settings,
60  run_imp_opt_results,
61  data_size);
62 
63  //initialize implementation run speedups
64  std::vector<RunSpeedupAvgMedian> run_imp_speedups;
65  run_imp_speedups.insert(run_imp_speedups.cend(),
66  speedup_over_baseline.cbegin(),
67  speedup_over_baseline.cend());
68  run_imp_speedups.insert(run_imp_speedups.cend(),
69  speedup_over_baseline_subsets.cbegin(),
70  speedup_over_baseline_subsets.cend());
71 
72  //compute and add speedup info for using optimized parallel parameters
73  //compared to default parallel parameters
74  if (p_params_optimized) {
75  const std::string speedup_header_optimized_p_params =
76  std::string(run_eval::kSpeedupOptParParamsHeader) + " - " +
77  std::string(run_environment::kDataSizeToNameMap.at(data_size));
78  const auto opt_p_params_speedups =
79  GetAvgMedSpeedupOptPParams(
80  run_imp_opt_results,
81  speedup_header_optimized_p_params,
82  run_imp_settings.subset_desc_input_sig);
83  run_imp_speedups.insert(
84  run_imp_speedups.end(),
85  opt_p_params_speedups.begin(),
86  opt_p_params_speedups.end());
87  }
88 
89  //compute and add speedup info for using templated loop iteration counts
90  //compared to loop iteration counts not being known at compile time
91  if (run_imp_settings.templated_iters_setting ==
93  {
94  const std::string speedup_header_loop_iters_templated =
95  std::string(run_eval::kSpeedupLoopItersCountTemplate) + " - " +
96  std::string(run_environment::kDataSizeToNameMap.at(data_size));
97  const auto speedups_templated_iters = GetAvgMedSpeedupLoopItersInTemplate(
98  run_imp_opt_results, speedup_header_loop_iters_templated,
99  run_imp_settings);
100  run_imp_speedups.insert(
101  run_imp_speedups.end(),
102  speedups_templated_iters.begin(),
103  speedups_templated_iters.end());
104  }
105 
106  //return run data with speedup from evaluation of implementation runs using
107  //multiple inputs with runs having the same data type and acceleration method
108  return {run_imp_opt_results, run_imp_speedups};
109 }
110 
111 //get speedups across all runs
112 std::vector<RunSpeedupAvgMedian> EvaluateImpResults::SpeedupsAllRuns(
113  MultRunData& run_results,
114  const run_environment::RunImpSettings& run_imp_settings) const
115 {
116  //store whether or not parallel parameters optimized in run
117  const bool p_params_optimized{
118  (!(run_imp_settings.p_params_default_alt_options.second.empty()))};
119 
120  //initialize vector for speedups across all runs
121  std::vector<RunSpeedupAvgMedian> speedups_all_runs;
122 
123  //get and add speedups over baseline runtimes for all runs
124  if (run_imp_settings.baseline_runtimes_path_desc)
125  {
126  const auto speedup_over_baseline = GetAvgMedSpeedupOverBaseline(
127  run_results, run_eval::kAllRunsStr,
128  *run_imp_settings.baseline_runtimes_path_desc);
129  speedups_all_runs.insert(
130  speedups_all_runs.cend(),
131  speedup_over_baseline.cbegin(),
132  speedup_over_baseline.cend());
133  }
134 
135  //get and add speedup for using optimized parallel parameters
136  //compared to default for all runs
137  if (p_params_optimized) {
138  const auto opt_p_params_speedups =
139  GetAvgMedSpeedupOptPParams(
140  run_results,
141  std::string(run_eval::kSpeedupOptParParamsHeader) + " - " +
142  std::string(run_eval::kAllRunsStr),
143  run_imp_settings.subset_desc_input_sig);
144  speedups_all_runs.insert(
145  speedups_all_runs.end(),
146  opt_p_params_speedups.begin(),
147  opt_p_params_speedups.end());
148  }
149 
150  //get and add speedup when using templated loop iteration count
151  //where loop iteration count is known at compile time for all runs
152  if (run_imp_settings.templated_iters_setting ==
154  {
155  const auto speedups_templated_iters = GetAvgMedSpeedupLoopItersInTemplate(
156  run_results,
157  std::string(run_eval::kSpeedupLoopItersCountTemplate) + " - " +
158  std::string(run_eval::kAllRunsStr),
159  run_imp_settings);
160  speedups_all_runs.insert(
161  speedups_all_runs.end(),
162  speedups_templated_iters.begin(),
163  speedups_templated_iters.end());
164  }
165 
166  //return speedups across all runs
167  return speedups_all_runs;
168 }
169 
170 //evaluate results for all implementation runs on multiple inputs with the runs
171 //potentially having different data types and acceleration methods and
172 //write run result and speedup outputs to files
174  const std::unordered_map<size_t, MultRunDataWSpeedupByAcc>&
175  run_results_mult_runs,
176  const run_environment::RunImpSettings& run_imp_settings,
177  run_environment::AccSetting opt_imp_acc) const
178 {
179  //initialize optimized multi-run results from input run result
180  //run results must be writable since speedup results get added to runs and
181  //optimized run results may be adjusted if faster runs found in alternative
182  //implementations compared to expected fastest implementation
183  std::unordered_map<size_t, MultRunDataWSpeedupByAcc> run_result_mult_runs_opt =
184  run_results_mult_runs;
185 
186  //write run results with each acceleration
187  for (const auto& [acc, run_results_w_speedups] : run_result_mult_runs_opt.begin()->second) {
188  //generate combined run results for each acceleration across data types
189  MultRunData run_results_acc;
190  for (const auto& [data_size, run_results_w_speedups_by_acc] : run_results_mult_runs) {
191  run_results_acc.insert(
192  run_results_w_speedups_by_acc.at(acc).first.begin(),
193  run_results_w_speedups_by_acc.at(acc).first.end());
194  }
195 
196  //write run results for acceleration
197  WriteRunResultsForAcc(
198  run_results_acc,
199  acc,
200  run_imp_settings);
201  }
202 
203  //check if setting is to run alternate optimized implementations and run and
204  //evaluate alternate optimized implementations if that's the case
205  std::unordered_map<size_t, std::vector<RunSpeedupAvgMedian>> alt_imp_speedup;
206  if (run_imp_settings.run_alt_optimized_imps) {
207  //get speedup/slowdown using alternate accelerations and update optimized
208  //run result for input with result using alternate acceleration if it is
209  //faster than result with "optimal" acceleration for specific input
210  for (const size_t data_size : run_imp_settings.datatypes_eval_sizes)
211  {
212  //get alternate acceleration speedups and optimized run results where
213  //fastest acceleration run results are replaced with alternate
214  //acceleration if it is faster
215  const auto [alt_acc_speedup, opt_run_results] = GetAltAccelSpeedups(
216  run_result_mult_runs_opt.at(data_size),
217  run_imp_settings, data_size,
218  opt_imp_acc);
219 
220  //if speedup output for alternate acceleration is generated,
221  //add alternate acceleration speedups for current data size and
222  //update optimized acceleration run results with results from alternate
223  //accelerations evaluation where run data for each input is set to
224  //fastest of all evaluated accelerations
225  if (!(alt_acc_speedup.empty())) {
226  //add alternate acceleration speedups for current data size
227  alt_imp_speedup.insert({data_size, alt_acc_speedup});
228 
229  //update optimized acceleration run results
230  run_result_mult_runs_opt.at(data_size).at(opt_imp_acc).first =
231  opt_run_results;
232  }
233  }
234  }
235 
236  //get speedup/slowdown using alternate datatype (double or half) compared
237  //with float
238  //needs to be run after alternate acceleration since run results can be
239  //updated with faster runs from alternate accelerations
240  std::vector<RunSpeedupAvgMedian> speedups_alt_datatypes;
241  for (const size_t data_size : run_imp_settings.datatypes_eval_sizes)
242  {
243  if ((data_size != sizeof(float)) &&
244  (run_result_mult_runs_opt.contains(sizeof(float))))
245  {
246  //get speedup or slowdown using alternate data type (double or half)
247  //compared with float and add to run speedups
248  const auto alt_datatype_speedups = GetAvgMedSpeedupBaseVsTarget(
249  run_result_mult_runs_opt.at(sizeof(float)).at(opt_imp_acc).first,
250  run_result_mult_runs_opt.at(data_size).at(opt_imp_acc).first,
251  (data_size > sizeof(float)) ?
255  run_imp_settings.subset_desc_input_sig);
256  speedups_alt_datatypes.insert(
257  speedups_alt_datatypes.begin(),
258  alt_datatype_speedups.begin(),
259  alt_datatype_speedups.end());
260  }
261  }
262 
263  //initialize overall results to first data size results using fastest
264  //acceleration and add results using alternate datatypes to it
265  const size_t first_datatype_size =
266  run_imp_settings.datatypes_eval_sizes.front();
267  auto [run_results, run_speedups] =
268  run_result_mult_runs_opt.at(first_datatype_size).at(opt_imp_acc);
269 
270  //go through each datatype and add speedups to overall speedup results
271  for (const auto run_datatype_size : run_imp_settings.datatypes_eval_sizes) {
272  //add speedup data from alternate acceleration runs and speedup results from
273  //double and half precision runs to speedup results
274  if (run_datatype_size == first_datatype_size) {
275  if (alt_imp_speedup.contains(run_datatype_size)) {
276  run_speedups.insert(run_speedups.cend(),
277  alt_imp_speedup.at(run_datatype_size).cbegin(),
278  alt_imp_speedup.at(run_datatype_size).cend());
279  }
280  }
281  else {
282  run_speedups.insert(run_speedups.cend(),
283  run_result_mult_runs_opt.at(run_datatype_size).at(opt_imp_acc).second.cbegin(),
284  run_result_mult_runs_opt.at(run_datatype_size).at(opt_imp_acc).second.cend());
285  if (alt_imp_speedup.contains(run_datatype_size)) {
286  run_speedups.insert(run_speedups.cend(),
287  alt_imp_speedup.at(run_datatype_size).cbegin(),
288  alt_imp_speedup.at(run_datatype_size).cend());
289  }
290  }
291  }
292 
293  //go through alternate datatypes and add run results for datatype to overall
294  //run results
295  for (const auto run_datatype_size : run_imp_settings.datatypes_eval_sizes) {
296  if (run_datatype_size != first_datatype_size) {
297  run_results.insert(
298  run_result_mult_runs_opt.at(run_datatype_size).at(opt_imp_acc).first.cbegin(),
299  run_result_mult_runs_opt.at(run_datatype_size).at(opt_imp_acc).first.cend());
300  }
301  }
302 
303  //compute and add speedups for all runs across all data types
304  const auto speedups_all_runs =
305  SpeedupsAllRuns(run_results, run_imp_settings);
306  run_speedups.insert(
307  run_speedups.cend(),
308  speedups_all_runs.cbegin(),
309  speedups_all_runs.cend());
310 
311  //speedups for alternate data types added at end of to overall speedups so
312  //they are final speedups displayed in speedups list
313  run_speedups.insert(
314  run_speedups.cend(),
315  speedups_alt_datatypes.cbegin(),
316  speedups_alt_datatypes.cend());
317 
318  //write output corresponding to results and run_speedups for all data types
319  WriteRunOutput({run_results, run_speedups}, run_imp_settings, opt_imp_acc);
320 }
321 
322 //Write run results corresponding to runs using a specific acceleration to a
323 //file with the acceleration setting as part of the file name
324 void EvaluateImpResults::WriteRunResultsForAcc(
325  const MultRunData& run_results,
326  run_environment::AccSetting acceleration_setting,
327  const run_environment::RunImpSettings& run_imp_settings) const
328 {
329  //get run implementation results file path
330  const auto imp_results_fp = GetImpResultsPath();
331 
332  //generate directory for results if not already created
333  if (!(std::filesystem::is_directory(
335  {
336  std::filesystem::create_directory(
338  }
339 
340  //get file path for results with fastest acceleration
341  const auto path_acc_results =
342  imp_results_fp /
344  std::filesystem::path(run_imp_settings.run_name +
345  std::string(run_eval::kRunResultsDescFileName) + "_" +
346  std::string(run_environment::AccelerationString(acceleration_setting)) +
347  std::string(run_eval::kCsvFileExtension));
348 
349  //initialize output file stream for results
350  std::ofstream out_results_str(path_acc_results);
351 
352  //get iterator to first run with success
353  //run_result corresponds to a std::optional object that contains run data if
354  //run successful and returns false if no data (indicating run not successful)
355  const auto first_success_run_iter =
356  std::ranges::find_if(run_results,
357  [](const auto& run_result) { return run_result.second.has_value(); } );
358 
359  //get headers from first successful run and write headers to top of output
360  //files
361  auto headers_in_order = first_success_run_iter->second->at(
363 
364  //go through remaining runs and add headers that aren't already there
365  for (const auto& [_, run_sig_data] : run_results) {
366  if (run_sig_data) {
367  for (const auto& curr_header : run_sig_data->at(
369  {
370  if (auto header_iter = std::ranges::find(headers_in_order,
371  curr_header);
372  header_iter == headers_in_order.cend())
373  {
374  headers_in_order.push_back(curr_header);
375  }
376  }
377  }
378  }
379 
380  //write each results header in order in first row of results string
381  //for each results set and then write newline to go to next line
382  for (const auto& curr_header : headers_in_order) {
383  out_results_str << curr_header << ',';
384  }
385  out_results_str << std::endl;
386 
387  //write output for run on each input with each data type
388  //write data for optimized parallel parameters
389  for (const auto& [_, run_sig_data] : run_results) {
390  //if run not successful only have single set of output data from run
391  //don't write data if no data for run
392  if (run_sig_data) {
393  for (const auto& curr_header : headers_in_order) {
394  if (run_sig_data->at(run_environment::ParallelParamsSetting::kOptimized).IsData(curr_header))
395  {
396  out_results_str <<
397  run_sig_data->at(run_environment::ParallelParamsSetting::kOptimized).GetDataAsStr(curr_header);
398  }
399  out_results_str << ',';
400  }
401  out_results_str << std::endl;
402  }
403  }
404 
405  std::cout << "Run results for using "
406  << run_environment::AccelerationString(acceleration_setting)
407  << " acceleration written to " << path_acc_results << std::endl;
408 
409  //close output file stream
410  out_results_str.close();
411 }
412 
413 //write current run results and speedup data to files
414 //that can be read to evaluate results across runs
415 void EvaluateImpResults::WriteRunOutput(
416  const std::pair<MultRunData, std::vector<RunSpeedupAvgMedian>>&
417  run_results_w_speedups,
418  const run_environment::RunImpSettings& run_imp_settings,
419  run_environment::AccSetting acceleration_setting) const
420 {
421  //get references to run results and speedups
422  const auto& [run_results, speedup_headers_w_data] = run_results_w_speedups;
423 
424  //store whether or not parallel parameters optimized in run
425  const bool p_params_optimized{
426  (!(run_imp_settings.p_params_default_alt_options.second.empty()))};
427 
428  //get iterator to first run with success
429  //run_result corresponds to a std::optional object that contains run data if
430  //run successful and returns false if no data (indicating run not successful)
431  const auto first_success_run_iter =
432  std::ranges::find_if(run_results,
433  [](const auto& run_result) { return run_result.second.has_value(); } );
434 
435  //check if there was at least one successful run
436  if (first_success_run_iter != run_results.cend())
437  {
438  //initialize parallel params setting enum and set of parallel params
439  //settings that are enabled in run
440  const auto& parallel_param_settings =
441  p_params_optimized ?
442  std::set<run_environment::ParallelParamsSetting>{
445  std::set<run_environment::ParallelParamsSetting>{
447 
448  //get headers from first successful run and write headers to top of output
449  //files
450  auto headers_in_order = first_success_run_iter->second->at(
452 
453  //get vector of speedup headers to use for evaluation across runs
454  //and also for run results
455  std::vector<std::string> speedup_headers;
456  for (const auto& [speedup_header, _] : speedup_headers_w_data) {
457  speedup_headers.push_back(speedup_header);
458  }
459 
460  //delete any speedup headers already in headers_in_order
461  //since they will be added in order to end of vector
462  for (const auto& speedup_header : speedup_headers) {
463  if (auto speedup_header_iter = std::ranges::find(headers_in_order,
464  speedup_header);
465  speedup_header_iter != headers_in_order.cend())
466  {
467  headers_in_order.erase(speedup_header_iter);
468  }
469  }
470 
471  //add speedup headers to the end of headers in order
472  headers_in_order.insert(
473  headers_in_order.cend(),
474  speedup_headers.cbegin(),
475  speedup_headers.cend());
476 
477  //initialize map of ostringstreams for run data using default and
478  //optimized parallel parameters
479  std::map<run_environment::ParallelParamsSetting, std::ostringstream>
480  run_data_sstr;
481  for (const auto& p_param_setting : parallel_param_settings) {
482  run_data_sstr.insert({p_param_setting, std::ostringstream()});
483  }
484 
485  //write each results header in order in first row of results string
486  //for each results set and then write newline to go to next line
487  for (const auto& curr_header : headers_in_order) {
488  for (const auto& p_param_setting : parallel_param_settings) {
489  run_data_sstr.at(p_param_setting) << curr_header << ',';
490  }
491  }
492  for (const auto& p_param_setting : parallel_param_settings) {
493  run_data_sstr.at(p_param_setting) << std::endl;
494  }
495 
496  //write output for run on each input with each data type
497  //write data for default parallel parameters and for optimized parallel
498  //parameters
499  for (const auto& p_param_setting : parallel_param_settings) {
500  for (const auto& [_, run_sig_data] : run_results) {
501  //if run not successful only have single set of output data from run
502  //don't write data if no data for run
503  if (run_sig_data) {
504  for (const auto& curr_header : headers_in_order) {
505  if (run_sig_data->at(p_param_setting).IsData(curr_header))
506  {
507  run_data_sstr.at(p_param_setting) <<
508  run_sig_data->at(p_param_setting).GetDataAsStr(curr_header);
509  }
510  run_data_sstr.at(p_param_setting) << ',';
511  }
512  run_data_sstr.at(p_param_setting) << std::endl;
513  }
514  }
515  }
516 
517  //write run results strings to output streams corresponding to results files
518  //two results files contain run results (with and without optimized
519  //parallel parameters), one results file contains speedup results, and another
520  //contains run results followed by speedups
521 
522  //get run implementation results file path
523  const auto imp_results_fp = GetImpResultsPath();
524 
525  //initialize mapping from output results type to file path where each
526  //results type is saved
527  std::map<run_eval::OutResults, const std::filesystem::path> output_file_paths;
528 
529  //create any results directories if needed
530  //and generate file paths for each output results type
531  for (const auto& [out_results_type, file_info] : run_eval::kOutResultsFileInfo) {
532  if (!(std::filesystem::is_directory(imp_results_fp / file_info.dir_path))) {
533  std::filesystem::create_directory(imp_results_fp / file_info.dir_path);
534  }
535  output_file_paths.insert(
536  {out_results_type,
537  imp_results_fp / file_info.dir_path /
538  std::filesystem::path(run_imp_settings.run_name + "_" +
539  std::string(file_info.desc_file_name) +
540  std::string(run_eval::kCsvFileExtension))});
541  }
542 
543  //write run results with and without optimized parallel parameters to files
544  //if run without optimized parallel parameters then results with default
545  //parallel parameters also written to optimized parallel parameters file
546  std::map<run_eval::OutResults, std::ofstream> results_stream;
547  for (const auto& [out_results_type, file_path] : output_file_paths) {
548  results_stream.insert(
549  {out_results_type,
550  std::ofstream(file_path)});
551  }
552 
553  //write run results file with default parallel params
554  results_stream.at(run_eval::OutResults::kDefaultPParams) <<
555  run_data_sstr.at(run_environment::ParallelParamsSetting::kDefault).str();
556  if (p_params_optimized) {
557  //write run results with optimized parallel params to optimized
558  //run results file stream
559  results_stream.at(run_eval::OutResults::kOptPParams) <<
560  run_data_sstr.at(
562  //write optimized run results to ostringstream for output containing run
563  //results and speedups
564  results_stream.at(run_eval::OutResults::kOptWSpeedups) <<
565  run_data_sstr.at(
567  }
568  else {
569  //write results with default parallel parameters to optimized results
570  //file stream if parallel parameters not optimized in run
571  results_stream.at(run_eval::OutResults::kOptPParams) <<
572  run_data_sstr.at(
574  results_stream.at(run_eval::OutResults::kOptWSpeedups) <<
575  run_data_sstr.at(
577  }
578 
579  //generate speedup results with headers on top row and write to
580  //"speedup" results stream
581  results_stream.at(run_eval::OutResults::kSpeedups) << ',';
582  //speedup headers for each computed speedup in top row
583  for (const auto& [speedup_header, _] : speedup_headers_w_data) {
584  results_stream.at(run_eval::OutResults::kSpeedups) << speedup_header
585  << ',';
586  }
587  //average and median speedup results corresponding to speedup headers in
588  //next two rows
589  for (const auto& [middle_val_desc, middle_val_enum] :
590  {std::pair<std::string_view, run_eval::MiddleValData>{
591  "Average Speedup", run_eval::MiddleValData::kAverage},
592  std::pair<std::string_view, run_eval::MiddleValData>{
593  "Median Speedup", run_eval::MiddleValData::kMedian}})
594  {
595  results_stream.at(run_eval::OutResults::kSpeedups) << std::endl <<
596  middle_val_desc << ',';
597  for (const auto& [_, speedup_data] : speedup_headers_w_data) {
598  if (speedup_data.contains(middle_val_enum)) {
599  results_stream.at(run_eval::OutResults::kSpeedups) <<
600  speedup_data.at(middle_val_enum) << ',';
601  }
602  else {
603  results_stream.at(run_eval::OutResults::kSpeedups) << ',';
604  }
605  }
606  }
607 
608  //generate speedup results with headers on left side
609  //and add to results stream for run results with speedups
610  results_stream.at(run_eval::OutResults::kOptWSpeedups) << std::endl <<
611  "Speedup Results,Average Speedup,Median Speedup" << std::endl;
612  for (const auto& [speedup_header, speedup_data] : speedup_headers_w_data) {
613  results_stream.at(run_eval::OutResults::kOptWSpeedups) << speedup_header;
614  if ((speedup_data.contains(run_eval::MiddleValData::kAverage)) &&
615  (speedup_data.at(run_eval::MiddleValData::kAverage) > 0)) {
616  results_stream.at(run_eval::OutResults::kOptWSpeedups) << ',' <<
617  speedup_data.at(run_eval::MiddleValData::kAverage) << ',' <<
618  speedup_data.at(run_eval::MiddleValData::kMedian);
619  }
620  else {
621  results_stream.at(run_eval::OutResults::kOptWSpeedups) << ",,";
622  }
623  results_stream.at(run_eval::OutResults::kOptWSpeedups) << std::endl;
624  }
625 
626  //close streams for writing to results files since file writing is done
627  for (auto& [_, curr_results_stream] : results_stream) {
628  curr_results_stream.close();
629  }
630 
631  //print location of output evaluation files to standard output
632  for (const auto& [out_results_type, out_results_desc_str] :
634  {
635  std::cout << out_results_desc_str << " in " <<
636  output_file_paths.at(out_results_type) << std::endl;
637  }
638 
639  //run evaluation across current and previous runs across architectures
640  //using run results and speedups saved from previous runs along with
641  //current run results
642  EvaluateAcrossRuns().operator()(
643  imp_results_fp,
644  GetCombResultsTopText(),
645  GetInputParamsShow());
646  }
647  else {
648  std::cout << "Error, no runs completed successfully" << std::endl;
649  }
650 }
651 
652 //process results for runs with alternate acceleration from optimal
653 //acceleration and get speedup for each run and overall when using optimal
654 //acceleration compared to alternate accelerations as well as optimized run
655 //results where fastest acceleration result is replaced by alternate
656 //acceleration result if it is faster
657 std::pair<std::vector<RunSpeedupAvgMedian>, MultRunData>
658 EvaluateImpResults::GetAltAccelSpeedups(
659  MultRunDataWSpeedupByAcc& run_imp_results_by_acc_setting,
660  const run_environment::RunImpSettings& run_imp_settings,
661  size_t data_type_size,
662  run_environment::AccSetting fastest_acc) const
663 {
664  if (run_imp_results_by_acc_setting.size() == 1) {
665  //no alternate run results
666  //return empty vector for speedup results
667  //return run implementation results that are the same as input
668  return {{}, run_imp_results_by_acc_setting.at(fastest_acc).first};
669  }
670  else {
671  //initialize optimized run results to "fastest" acceleration results
672  //results get replaced by alternate acceleration result if alternate
673  //acceleration is faster
674  auto run_imp_opt_results =
675  run_imp_results_by_acc_setting.at(fastest_acc).first;
676 
677  //initialize speedup/slowdown using alternate acceleration
678  std::vector<RunSpeedupAvgMedian> alt_acc_speedups;
679  for (auto& [acc_setting, acc_results] : run_imp_results_by_acc_setting) {
680  if (acc_setting != fastest_acc) {
681  //get speedup/slowdown using alternate acceleration compared to
682  //"fastest" acceleration and store in speedup results
683  alt_acc_speedups.push_back(
684  GetAvgMedSpeedupBaseVsTarget(
685  acc_results.first,
686  run_imp_results_by_acc_setting.at(fastest_acc).first,
687  std::string(run_eval::kAltAccToSpeedupDesc.at(acc_setting)) +
688  " - " + std::string(run_environment::kDataSizeToNameMap.at(
689  data_type_size)),
691 
692  //process optimized results using alternate acceleration
693  //go through each result and replace optimized run data with alternate
694  //implementation run data if alternate implementation run is faster
695  for (auto& [run_input_sig, opt_sig_run_results] : run_imp_opt_results)
696  {
697  if (opt_sig_run_results && acc_results.first.at(run_input_sig))
698  {
699  //get runtime of current optimized run and alternate acceleration
700  //run
701  //if alternate acceleration run is faster, replace the optimized
702  //result for run with alternate acceleration run
703  const double opt_result_time =
704  *opt_sig_run_results->at(
706  GetDataAsDouble(run_eval::kOptimizedRuntimeHeader);
707  const double alt_acc_result_time =
708  *acc_results.first.at(run_input_sig)->at(
710  GetDataAsDouble(run_eval::kOptimizedRuntimeHeader);
711  if (alt_acc_result_time < opt_result_time) {
712  //set optimized run results to alternate acceleration results if
713  //it is faster
714  opt_sig_run_results = acc_results.first.at(run_input_sig);
715  }
716  }
717  }
718  }
719  }
720  return {alt_acc_speedups, run_imp_opt_results};
721  }
722 }
723 
724 //get speedup over baseline data if data available
725 std::vector<RunSpeedupAvgMedian> EvaluateImpResults::GetSpeedupOverBaseline(
726  const run_environment::RunImpSettings& run_imp_settings,
727  MultRunData& run_data_all_runs,
728  size_t data_type_size) const
729 {
730  //initialize speedup results
731  std::vector<RunSpeedupAvgMedian> speedup_results;
732 
733  //get speedup over baseline runtimes if available
734  if (run_imp_settings.baseline_runtimes_path_desc)
735  {
736  const auto speedup_over_baseline = GetAvgMedSpeedupOverBaseline(
737  run_data_all_runs,
738  run_environment::kDataSizeToNameMap.at(data_type_size),
739  *run_imp_settings.baseline_runtimes_path_desc);
740  speedup_results.insert(
741  speedup_results.cend(),
742  speedup_over_baseline.cbegin(),
743  speedup_over_baseline.cend());
744  }
745 
746  return speedup_results;
747 }
748 
749 //get speedup over baseline run for subsets of smallest and largest sets
750 //if data available
751 std::vector<RunSpeedupAvgMedian>
752 EvaluateImpResults::GetSpeedupOverBaselineSubsets(
753  const run_environment::RunImpSettings& run_imp_settings,
754  MultRunData& run_data_all_runs,
755  size_t data_type_size) const
756 {
757  if (run_imp_settings.baseline_runtimes_path_desc)
758  {
759  return GetAvgMedSpeedupOverBaselineSubsets(
760  run_data_all_runs,
761  run_environment::kDataSizeToNameMap.at(data_type_size),
762  *run_imp_settings.baseline_runtimes_path_desc,
763  run_imp_settings.subset_desc_input_sig);
764  }
765  //return empty vector if doesn't match settings to get speedup over baseline
766  //for subsets
767  return std::vector<RunSpeedupAvgMedian>();
768 }
769 
770 //get baseline runtime data (assumed to be available)
771 //key for runtime data in results is different to retrieve optimized runtime
772 //compared to single thread runtime for baseline run
773 std::pair<std::string, std::map<InputSignature, std::string>>
774 EvaluateImpResults::GetBaselineRuntimeData(
775  const std::array<std::string_view, 2>& baseline_runtimes_path_desc,
776  std::string_view key_runtime_data) const
777 {
778  RunResultsSpeedups baseline_run_results(baseline_runtimes_path_desc.at(0));
779  return std::pair<std::string, std::map<InputSignature, std::string>>{
780  std::string(baseline_runtimes_path_desc.at(1)),
781  baseline_run_results.InputsToKeyVal(key_runtime_data)};
782 }
783 
784 //get average and median speedup from vector of speedup values
785 RunSpeedupAvgMedian::second_type EvaluateImpResults::GetAvgMedSpeedup(
786  const std::vector<double>& speedups_vect) const
787 {
788  const double average_speedup =
789  std::accumulate(
790  speedups_vect.cbegin(),
791  speedups_vect.cend(),
792  0.0) /
793  (double)speedups_vect.size();
794  auto speedups_vect_sorted = speedups_vect;
795  std::ranges::sort(speedups_vect_sorted);
796  const double median_speedup =
797  ((speedups_vect_sorted.size() % 2) == 0) ?
798  ((speedups_vect_sorted.at((speedups_vect_sorted.size() / 2) - 1) +
799  speedups_vect_sorted.at(speedups_vect_sorted.size() / 2)) / 2.0) :
800  speedups_vect_sorted.at(speedups_vect_sorted.size() / 2);
801  return {{run_eval::MiddleValData::kAverage, average_speedup},
802  {run_eval::MiddleValData::kMedian, median_speedup}};
803 }
804 
805 //get average and median speedup of specified subset(s) of runs compared to
806 //baseline data from file
807 std::vector<RunSpeedupAvgMedian>
808 EvaluateImpResults::GetAvgMedSpeedupOverBaselineSubsets(
809  MultRunData& run_results,
810  std::string_view data_type_str,
811  const std::array<std::string_view, 2>& baseline_runtimes_path_desc,
812  const std::vector<std::pair<
813  std::string, std::vector<InputSignature>>>& subset_desc_input_sig) const
814 {
815  //get speedup over baseline for specified subsets of optimized runs
816  std::vector<RunSpeedupAvgMedian> speedup_data;
817 
818  //get baseline name and mapping of runtimes to input signatures
819  //auto baseline_runtime_data =
820  const auto [baseline_name, baseline_runtimes_to_sig] =
821  GetBaselineRuntimeData(
822  baseline_runtimes_path_desc,
824 
825  //retrieve speedup data for subsets of optimized runs over corresponding
826  //run in baseline data
827  //go through each specified subset of runs and compute average and median
828  //speedup compared to baseline for each subset
829  for (const auto& [subset_desc, subset_inputs] : subset_desc_input_sig)
830  {
831  //speedup vector is empty at start of processing of each subset
832  std::vector<double> speedups_vect;
833 
834  //get header corresponding to current subset
835  const std::string speedup_header = "Speedup relative to " +
836  std::string(baseline_name) + " - " + std::string(data_type_str) +
837  " on " + std::string(subset_desc);
838 
839  //go through each input signature of current subset
840  for (const auto& subset_input_signature : subset_inputs)
841  {
842  //go through each run output and compute speedup for each run that
843  //matches subset input signature
844  for (auto& [run_sig, run_sig_results] : run_results)
845  {
846  //check if results present for current run signature
847  if (run_sig_results)
848  {
849  //check if run signature corresponds to subset signature and retrieve
850  //and process speedup compared to baseline if that's the case
851  if (run_sig.EqualsUsingAny(subset_input_signature)) {
852  speedups_vect.push_back(
853  std::stod(baseline_runtimes_to_sig.at(run_sig)) /
854  *run_sig_results->at(
856  GetDataAsDouble(run_eval::kOptimizedRuntimeHeader));
857  for (auto& [_, run_data] : *run_sig_results) {
858  run_data.AddDataWHeader(
859  std::string(speedup_header),
860  speedups_vect.back());
861  }
862  }
863  }
864  }
865  }
866  if (!(speedups_vect.empty())) {
867  speedup_data.push_back(
868  {speedup_header, GetAvgMedSpeedup(speedups_vect)});
869  }
870  }
871 
872  //return vector of average and median speedups for specified subsets of runs
873  //compared to baseline
874  return speedup_data;
875 }
876 
877 //get average and median speedup of current runs compared to baseline data from file
878 std::vector<RunSpeedupAvgMedian> EvaluateImpResults::GetAvgMedSpeedupOverBaseline(
879  MultRunData& run_results,
880  std::string_view data_type_str,
881  const std::array<std::string_view, 2>& baseline_runtimes_path_desc) const
882 {
883  //define the start of the speedup info and runtime header in run data
884  //that is being compared for optimized and single thread implementations
885  const std::array<std::string_view, 2> baseline_opt_start_info_runtime_header{
886  "Speedup relative to",
888  const std::array<std::string_view, 2> baseline_s_thread_start_info_runtime_header{
889  "Single-Thread (Orig Imp) speedup relative to",
891 
892  //vector for speedup data over baseline for optimized and single thread
893  //implementations
894  std::vector<RunSpeedupAvgMedian> speedup_data;
895 
896  //get speedup of current run compared to baseline optimized and
897  //single thread implementations where first iteration is baseline optimized
898  //and second iteration is baseline single thread
899  for (const auto& start_info_runtime_header :
900  {baseline_opt_start_info_runtime_header,
901  baseline_s_thread_start_info_runtime_header})
902  {
903  //get baseline run data for runs according to current runtime header
904  const auto [baseline_name, baseline_runtimes_to_sig] =
905  GetBaselineRuntimeData(
906  baseline_runtimes_path_desc,
907  start_info_runtime_header.at(1));
908  const std::string speedup_header =
909  std::string(start_info_runtime_header.at(0)) +
910  " " + baseline_name + " - " + std::string(data_type_str);
911  std::vector<double> speedups_vect;
912  for (auto& [run_sig, run_sig_results] : run_results)
913  {
914  //compute speedup for each run compared to baseline runtime and add
915  //to vector of speedups as well as to run data
916  if (run_sig_results && (baseline_runtimes_to_sig.contains(run_sig)))
917  {
918  //get current run runtime for input signature
919  const auto runtime_input_sig = *run_sig_results->at(
921  start_info_runtime_header.at(1));
922 
923  //get runtime of baseline run for input signature
924  const auto baseline_runtime =
925  std::stod(baseline_runtimes_to_sig.at(run_sig));
926 
927  //compute speedup of current run and add to vector of speedups
928  //and also to run data for current run using input signature
929  speedups_vect.push_back(baseline_runtime / runtime_input_sig);
930  for (auto& [_, run_data] : *run_sig_results) {
931  run_data.AddDataWHeader(speedup_header, speedups_vect.back());
932  }
933  }
934  }
935  if (!(speedups_vect.empty())) {
936  //get average and median speedups across all runs compared to
937  //baseline runtimes
938  speedup_data.push_back(
939  {speedup_header, GetAvgMedSpeedup(speedups_vect)});
940  }
941  }
942 
943  return speedup_data;
944 }
945 
946 //get average and median speedup using optimized parallel parameters compared to default parallel parameters
947 //and also add speedup for each run using optimized parallel parameters compared to each run with default
948 //parallel parameters
949 std::vector<RunSpeedupAvgMedian> EvaluateImpResults::GetAvgMedSpeedupOptPParams(
950  MultRunData& run_results, std::string_view speedup_header,
951  const std::optional<std::vector<std::pair<std::string, std::vector<InputSignature>>>>& eval_subsets) const
952 {
953  //initialize speedup evaluations
954  std::vector<RunSpeedupAvgMedian> speedups_base_v_target;
955 
956  //initialize evaluation sets to evaluate to set of all runs
957  std::vector<std::pair<std::string, std::vector<InputSignature>>> eval_sets
958  {std::make_pair(
959  std::string(), std::vector<InputSignature>{InputSignature({}, {}, {})})};
960 
961  //add subsets specified in input parameter to subsets to evaluate
962  if (eval_subsets) {
963  eval_sets.insert(
964  eval_sets.end(), eval_subsets->begin(), eval_subsets->end());
965  }
966 
967  //go through each specified subset of runs and compute average and median
968  //speedup compared to baseline for each subset
969  for (const auto& [subset_desc, subset_inputs] : eval_sets)
970  {
971  //initialize vector of speedups across runs
972  std::vector<double> speedups_vect;
973 
974  //get header corresponding to current subset
975  const std::string speedup_header_set =
976  (subset_desc.size() == 0) ?
977  std::string(speedup_header) :
978  std::string(speedup_header) + " on " + std::string(subset_desc);
979 
980  for (auto& [input_sig, sig_run_results] : run_results)
981  {
982  //check if any subset input signature matches current input signature
983  //and there are valid results for input signature
984  if (std::ranges::any_of(
985  subset_inputs,
986  [&input_sig](const auto& subset_sig) {
987  return input_sig.EqualsUsingAny(subset_sig);}) &&
988  sig_run_results)
989  {
990  //compute speedup of run using optimized parallel parameters compared to
991  //default parallel parameters and add to vector of speedups for all runs
992  speedups_vect.push_back(
993  (*(sig_run_results->at(
996  (*(sig_run_results->at(
999 
1000  //add speedup for run to data for run in run results
1001  sig_run_results->at(
1003  std::string(speedup_header), speedups_vect.back());
1004  sig_run_results->at(
1006  std::string(speedup_header), speedups_vect.back());
1007  }
1008  }
1009  if (!(speedups_vect.empty())) {
1010  //compute average and median speedup when using parallel parameters
1011  //across runs from vector containing speedups of every run
1012  speedups_base_v_target.push_back({RunSpeedupAvgMedian::first_type(speedup_header_set), GetAvgMedSpeedup(speedups_vect)});
1013  speedups_vect.clear();
1014  }
1015  }
1016 
1017  return speedups_base_v_target;
1018 }
1019 
1020 //get average and median speedup between base and target runtime data and also add
1021 //speedup for each target runtime data run as compared to corresponding base run
1022 //across all runs and also on selected subsets if specified
1023 std::vector<RunSpeedupAvgMedian> EvaluateImpResults::GetAvgMedSpeedupBaseVsTarget(
1024  MultRunData& run_results_base,
1025  MultRunData& run_results_target,
1026  std::string_view speedup_header,
1027  BaseTargetDiff base_target_diff,
1028  const std::optional<std::vector<std::pair<std::string, std::vector<InputSignature>>>>& eval_subsets) const
1029 {
1030  //initialize speedup evaluations
1031  std::vector<RunSpeedupAvgMedian> speedups_base_v_target;
1032 
1033  //initialize evaluation sets to evaluate to set of all runs
1034  std::vector<std::pair<std::string, std::vector<InputSignature>>> eval_sets
1035  {std::make_pair(
1036  std::string(), std::vector<InputSignature>{InputSignature({}, {}, {})})};
1037 
1038  //add subsets specified in input parameter to subsets to evaluate
1039  if (eval_subsets) {
1040  eval_sets.insert(
1041  eval_sets.end(), eval_subsets->begin(), eval_subsets->end());
1042  }
1043 
1044  //go through each specified subset of runs and compute average and median
1045  //speedup compared to baseline for each subset
1046  for (const auto& [subset_desc, subset_inputs] : eval_sets)
1047  {
1048  //initialize empty vector where speedups will be added
1049  //for evaluation subset
1050  std::vector<double> speedups_vect;
1051 
1052  //get header corresponding to current subset
1053  const std::string speedup_header_set =
1054  (subset_desc.size() == 0) ?
1055  std::string(speedup_header) :
1056  std::string(speedup_header) + " on " + std::string(subset_desc);
1057 
1058  //go through all base runtime data and compute speedups
1059  for (auto& [input_sig_base, sig_run_results_base] : run_results_base)
1060  {
1061  //check if any subset input signature matches current input signature in
1062  //base runtime data
1063  if (std::ranges::any_of(
1064  subset_inputs,
1065  [&input_sig_base](const auto& subset_sig) {
1066  return input_sig_base.EqualsUsingAny(subset_sig);
1067  }))
1068  {
1069  InputSignature base_in_sig_adjusted(input_sig_base);
1070  //go through all target runtime data and find speedup for data
1071  //that corresponds with current base runtime data
1072  for (auto& [input_sig_target, sig_run_results_target] : run_results_target)
1073  {
1074  InputSignature target_in_sig_adjusted(input_sig_target);
1075  if (base_target_diff == BaseTargetDiff::kDiffDatatype) {
1076  //remove datatype from input signature if different datatype
1077  //between base and target output
1078  base_in_sig_adjusted.RemoveDatatypeSetting();
1079  target_in_sig_adjusted.RemoveDatatypeSetting();
1080  }
1081  else if (base_target_diff == BaseTargetDiff::kDiffTemplatedSetting) {
1082  //remove templated setting from input signature if different template
1083  //setting between base and target output
1084  base_in_sig_adjusted.RemoveTemplatedLoopIterSetting();
1085  target_in_sig_adjusted.RemoveTemplatedLoopIterSetting();
1086  }
1087  if (base_in_sig_adjusted == target_in_sig_adjusted) {
1088  //compute speedup between corresponding base and target data and
1089  //add it to vector of speedups across all data
1090  if (sig_run_results_base &&
1091  sig_run_results_target)
1092  {
1093  speedups_vect.push_back(
1094  *sig_run_results_base->at(
1097  *sig_run_results_target->at(
1100 
1101  //add speedup data to corresponding base and target data
1102  sig_run_results_base->at(
1104  std::string(speedup_header), speedups_vect.back());
1105  sig_run_results_target->at(
1107  std::string(speedup_header), speedups_vect.back());
1108  }
1109  }
1110  }
1111  }
1112  }
1113  if (!(speedups_vect.empty())) {
1114  //get average and median speedup from speedup vector with all speedup
1115  //data and add to subset speedups
1116  speedups_base_v_target.push_back(
1117  {RunSpeedupAvgMedian::first_type(speedup_header_set), GetAvgMedSpeedup(speedups_vect)});
1118  speedups_vect.clear();
1119  }
1120  }
1121 
1122  return speedups_base_v_target;
1123 }
1124 
1125 //get average and median speedup when loop iterations are given at compile time as template value
1126 //and also add speedup for each run with templated loop iterations as compared to same run without
1127 //templated loop iterations
1128 std::vector<RunSpeedupAvgMedian> EvaluateImpResults::GetAvgMedSpeedupLoopItersInTemplate(
1129  MultRunData& run_results,
1130  std::string_view speedup_header,
1131  const run_environment::RunImpSettings& run_imp_settings) const
1132 {
1133  //get all data entries corresponding to templated loop iterations and not templated loop iterations
1134  //in separate structures
1135  std::array<MultRunData, 2> templated_non_templated_loops_data;
1136  for (const auto data_index : {0, 1}) {
1137  std::ranges::copy_if(run_results,
1138  std::inserter(templated_non_templated_loops_data[data_index],
1139  templated_non_templated_loops_data[data_index].end()),
1140  [data_index](const auto& input_sig_run_results) {
1141  if (input_sig_run_results.first.TemplatedLoopIters()) {
1142  //data index 0 -> return true if templated loop iters
1143  //data index 1 -> return true if not templated loop iters
1144  if (data_index == 0) {
1145  return *input_sig_run_results.first.TemplatedLoopIters();
1146  }
1147  if (data_index == 1) {
1148  return (!(*input_sig_run_results.first.TemplatedLoopIters()));
1149  }
1150  else {
1151  return false;
1152  }
1153  }
1154  else {
1155  return false;
1156  }
1157  });
1158  }
1159 
1160  //get specific subset to evaluate in addition to evaluation across all runs
1161  //remove any subsets with templated loop iteration count specified since that's
1162  //what's being evaluated here
1163  auto subsets_eval = run_imp_settings.subset_desc_input_sig;
1164  std::erase_if(subsets_eval, [](const auto& subset_desc_sigs)
1165  {
1166  return std::ranges::any_of(
1167  subset_desc_sigs.second, [](const auto& input_sig)
1168  {
1169  return input_sig.TemplatedLoopIters().has_value();
1170  });
1171  });
1172 
1173  //get speedup using templated loop iteration counts with non-templated loop
1174  //iters being base data and templated loop iterations counts being target data
1175  const std::vector<RunSpeedupAvgMedian> speedups_header_data =
1176  GetAvgMedSpeedupBaseVsTarget(
1177  templated_non_templated_loops_data[1],
1178  templated_non_templated_loops_data[0],
1179  speedup_header,
1181  subsets_eval);
1182 
1183  //update run output data with templated and non templated data results
1184  //after processing for speedup
1185  //reason is that speedup data added to each data entry showing speedup
1186  //compared to corresponding data with or without templated loops
1187  for (const auto& run_data_updated : templated_non_templated_loops_data) {
1188  for (const auto& curr_run_data : run_data_updated) {
1189  run_results.at(curr_run_data.first) = curr_run_data.second;
1190  }
1191  }
1192 
1193  //return speedup data with header
1194  return speedups_header_data;
1195 }
Declares class with operator function to evaluate implementation runs across multiple architectures....
std::unordered_map< run_environment::AccSetting, std::pair< MultRunData, std::vector< RunSpeedupAvgMedian > >> MultRunDataWSpeedupByAcc
Mapping of acceleration setting to run and speedup data.
std::map< InputSignature, std::optional< std::map< run_environment::ParallelParamsSetting, RunData > >> MultRunData
Alias mapping input signature to run data for each parallel parameters setting Run data is null if r...
Declares class with operator function to evaluate implementations of the same algorithm across differ...
BaseTargetDiff
Enum to define difference between "base" and "target" result sets when evaluating speedup.
Declares class to load and store run results data including speedups from evaluation.
Class with operator function to evaluate implementation runs across multiple architectures....
void EvalAllResultsWriteOutput(const std::unordered_map< size_t, MultRunDataWSpeedupByAcc > &run_results_mult_runs, const run_environment::RunImpSettings &run_imp_settings, run_environment::AccSetting opt_imp_acc) const
Evaluate results for all implementation runs on multiple inputs with the runs potentially having diff...
std::pair< MultRunData, std::vector< RunSpeedupAvgMedian > > EvalResultsSingDataTypeAcc(const MultRunData &run_results, const run_environment::RunImpSettings &run_imp_settings, size_t data_size) const
Evaluate results for implementation runs on multiple inputs with all the runs having the same data ty...
Class defines input signature for evaluation run that contains evaluation set number,...
Class to load and store run results data including speedups from evaluation.
constexpr std::string_view AccelerationString()
Get string corresponding to acceleration method at compile time.
AccSetting
Enum for acceleration setting.
const std::map< std::size_t, std::string_view > kDataSizeToNameMap
Mapping from data size to data type string.
const std::map< run_environment::AccSetting, const std::string_view > kAltAccToSpeedupDesc
constexpr std::string_view kImpResultsRunDataAccFolderName
constexpr std::string_view kSingleThreadRuntimeHeader
const std::map< OutResults, const std::string_view > kOutResultsDesc
constexpr std::string_view kAllRunsStr
Constant for "all runs" string.
constexpr std::string_view kCsvFileExtension
constexpr std::string_view kSpeedupDoubleHeader
constexpr std::string_view kRunResultsDescFileName
constexpr std::string_view kOptimizedRuntimeHeader
const std::map< OutResults, const OutFileInfo > kOutResultsFileInfo
constexpr std::string_view kSpeedupHalfHeader
constexpr std::string_view kSpeedupOptParParamsHeader
constexpr std::string_view kSpeedupLoopItersCountTemplate
Structure that stores settings for current implementation run.
Definition: RunSettings.h:84
TemplatedItersSetting templated_iters_setting
Definition: RunSettings.h:86
std::optional< std::array< std::string_view, 2 > > baseline_runtimes_path_desc
Definition: RunSettings.h:93
std::vector< unsigned int > datatypes_eval_sizes
Definition: RunSettings.h:85
std::pair< std::array< unsigned int, 2 >, std::set< std::array< unsigned int, 2 > > > p_params_default_alt_options
Definition: RunSettings.h:89
std::vector< std::pair< std::string, std::vector< InputSignature > > > subset_desc_input_sig
Definition: RunSettings.h:95