HEBench
hebench_ibenchmark.cpp
Go to the documentation of this file.
1 
2 // Copyright (C) 2021 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include <algorithm>
6 #include <bitset>
7 #include <cctype>
8 #include <cstring>
9 #include <filesystem>
10 #include <iomanip>
11 #include <iostream>
12 #include <sstream>
13 #include <stdexcept>
14 #include <string>
15 
16 #include "hebench/modules/logging/include/logging.h"
17 #include "hebench/modules/timer/include/timer.h"
18 
19 #include "hebench/api_bridge/api.h"
20 #include "include/hebench_engine.h"
23 
24 namespace hebench {
25 namespace TestHarness {
26 
29  const BenchmarkDescription::Description &text_desc) const
30 {
31  return DescriptionToken::Ptr(new DescriptionToken(*const_cast<IBenchmarkDescriptor *>(this),
32  backend_desc,
33  config,
34  text_desc,
35  m_key_creation));
36 }
37 
38 //-----------------------------------
39 // class PartialBenchmarkDescription
40 //-----------------------------------
41 
42 bool PartialBenchmarkDescriptor::m_b_force_config_value = true;
43 
45 {
46 }
47 
49 {
50 }
51 
52 std::unordered_set<std::size_t> PartialBenchmarkDescriptor::getCipherParamPositions(std::uint32_t cipher_param_mask)
53 {
54  std::unordered_set<std::size_t> retval;
55  std::bitset<sizeof(decltype(cipher_param_mask)) * 8> cipher_param_bits(cipher_param_mask);
56  for (std::size_t i = 0; i < cipher_param_bits.size(); ++i)
57  if (cipher_param_bits.test(i))
58  retval.insert(i);
59  return retval;
60 }
61 
63 {
64  std::string retval;
65 
66  switch (category)
67  {
69  retval = "Latency";
70  break;
71 
73  retval = "Offline";
74  break;
75 
76  default:
77  throw std::invalid_argument(IL_LOG_MSG_CLASS("Unknown category: " + std::to_string(static_cast<int>(category)) + "."));
78  break;
79  } // end switch
80 
81  return retval;
82 }
83 
85 {
86  std::string retval;
87 
88  switch (data_type)
89  {
91  retval = "Int32";
92  break;
93 
95  retval = "Int64";
96  break;
97 
99  retval = "Float32";
100  break;
101 
103  retval = "Float64";
104  break;
105 
106  default:
107  throw std::invalid_argument(IL_LOG_MSG_CLASS("Unknown data type: " + std::to_string(static_cast<int>(data_type)) + "."));
108  break;
109  } // end switch
110 
111  return retval;
112 }
113 
114 std::uint64_t PartialBenchmarkDescriptor::computeSampleSizes(std::uint64_t *sample_sizes,
115  std::size_t param_count,
116  const std::vector<std::uint64_t> &default_sample_sizes,
117  const hebench::APIBridge::BenchmarkDescriptor &bench_desc,
118  std::uint64_t default_sample_size_fallback,
119  bool force_config)
120 {
122  throw std::invalid_argument(IL_LOG_MSG_CLASS("Invalid category. Only \"Offline\" category is supported."));
123  if (default_sample_size_fallback < 1)
124  throw std::invalid_argument(IL_LOG_MSG_CLASS("Default sample size fallback must be a positive value."));
125 
126  std::uint64_t result_batch_size = 1;
127  for (std::size_t param_i = 0; param_i < param_count; ++param_i)
128  {
129  if (force_config)
130  {
131  // force config sample sizes
132  std::uint64_t sample_size = default_sample_sizes.size() > param_i ?
133  default_sample_sizes[param_i] :
134  0UL;
135  // config sample size requested default value:
136  if (sample_size == 0)
137  sample_size = bench_desc.cat_params.offline.data_count[param_i] != 0 ?
138  // use backend default
139  bench_desc.cat_params.offline.data_count[param_i] :
140  // backend requested definition default
141  default_sample_size_fallback;
142 
143  sample_sizes[param_i] = sample_size;
144  } // end if
145  else
146  {
147  // respect backend sample sizes
148  std::uint64_t default_sample_size =
149  default_sample_sizes.size() > param_i && default_sample_sizes[param_i] > 0 ?
150  default_sample_sizes[param_i] :
151  default_sample_size_fallback;
152  sample_sizes[param_i] = (bench_desc.cat_params.offline.data_count[param_i] == 0 ?
153  // backend requested flexible sizes (use config or definition default)
154  default_sample_size :
155  // backend set its own sample sizes
156  bench_desc.cat_params.offline.data_count[param_i]);
157  } // end else
158  result_batch_size *= sample_sizes[param_i];
159  } // end for
160  return result_batch_size;
161 }
162 
164  const BenchmarkDescription::Backend &backend_desc,
165  const BenchmarkDescription::Configuration &config) const
166 {
168 
169  const auto &w_params = config.w_params;
170  std::uint64_t w_params_count, other;
171  engine.validateRetCode(hebench::APIBridge::getWorkloadParamsDetails(engine.handle(), backend_desc.handle, &w_params_count, &other));
172  if (w_params_count != w_params.size())
173  {
174  std::stringstream ss;
175  ss << "Invalid number of workload arguments. Expected " << w_params_count << ", but " << w_params.size() << " received.";
176  throw std::runtime_error(IL_LOG_MSG_CLASS(ss.str()));
177  } // end if
178 
179  if (matchBenchmarkDescriptor(backend_desc.descriptor, w_params))
180  {
181  // complete the benchmark specification
182  BenchmarkDescription::Backend final_backend_desc;
184  BenchmarkDescription::Description text_description;
185  describe(final_backend_desc, final_config, text_description,
186  engine, backend_desc, config);
187  retval = createToken(final_backend_desc, final_config, text_description);
188  } // end if
189 
190  return retval;
191 }
192 
194  const hebench::APIBridge::BenchmarkDescriptor &in_descriptor,
196  bool force_config)
197 {
198  if (force_config)
199  {
200  out_descriptor.cat_params.min_test_time_ms =
201  config.default_min_test_time_ms == 0 ?
202  in_descriptor.cat_params.min_test_time_ms :
204  } // end if
205  else
206  {
207  out_descriptor.cat_params.min_test_time_ms =
208  in_descriptor.cat_params.min_test_time_ms != 0 ?
209  in_descriptor.cat_params.min_test_time_ms :
211  } // end else
212 }
213 
214 void PartialBenchmarkDescriptor::describe(BenchmarkDescription::Backend &concrete_backend_desc,
215  BenchmarkDescription::Configuration &concrete_config,
217  const Engine &engine,
218  const BenchmarkDescription::Backend &backend_desc,
219  const BenchmarkDescription::Configuration &config) const
220 {
221  hebench::APIBridge::Handle h_bench_desc = backend_desc.handle;
222  const std::vector<hebench::APIBridge::WorkloadParam> &w_params = config.w_params;
223 
224  // obtain the values for the description that are specific to the workload
225  WorkloadDescriptionOutput completed_description;
226  std::memset(&completed_description.concrete_descriptor, 0, sizeof(completed_description.concrete_descriptor));
227  // The final BenchmarkDescriptor object will complete the description and
228  // record finalized parameters during this call.
229  // The cat_params finalization occurs inside:
230  // PartialBenchmarkDescriptor::computeSampleSizes() which is called by all offline
231  // benchmarks to complete.
232  completeWorkloadDescription(completed_description,
233  engine, backend_desc, config);
234 
235  const hebench::APIBridge::BenchmarkDescriptor &bench_desc = completed_description.concrete_descriptor;
236 
237  std::stringstream ss;
238  std::filesystem::path ss_path;
239 
240  std::string &s_workload_base_name = completed_description.workload_base_name;
241  std::string &s_workload_name = completed_description.workload_name;
242  std::string s_path_workload_name;
243  std::string s_scheme_name = engine.getSchemeName(bench_desc.scheme);
244  std::string s_security_name = engine.getSecurityName(bench_desc.scheme, bench_desc.security);
245 
246  // generate path
247  ss = std::stringstream();
248  if (!s_workload_base_name.empty())
249  {
250  ss << s_workload_base_name << "_";
251  }
252  else
253  {
254  s_workload_base_name = std::to_string(static_cast<int>(bench_desc.workload));
255  }
256  ss << std::to_string(static_cast<int>(bench_desc.workload));
257  s_path_workload_name = hebench::Utilities::convertToDirectoryName(ss.str());
258  ss_path = s_path_workload_name;
259  ss = std::stringstream();
260  ss << "wp";
261  for (std::size_t i = 0; i < w_params.size(); ++i)
262  {
263  ss << "_";
264  switch (w_params[i].data_type)
265  {
267  ss << w_params[i].u_param;
268  break;
269 
271  ss << w_params[i].f_param;
272  break;
273 
274  default:
275  ss << w_params[i].i_param;
276  break;
277  } // end switch
278  } // end for
279  ss_path /= hebench::Utilities::convertToDirectoryName(ss.str()); // workload params
282 
283  ss = std::stringstream();
284  ss << bench_desc.cat_params.min_test_time_ms << "ms";
285  std::size_t max_non_zero = HEBENCH_MAX_CATEGORY_PARAMS;
286  while (max_non_zero > 0 && bench_desc.cat_params.reserved[max_non_zero - 1] == 0)
287  --max_non_zero;
288  if (max_non_zero > 0)
289  {
290  for (std::size_t i = 0; i < max_non_zero; ++i)
291  ss << "_" << bench_desc.cat_params.reserved[i];
292  } // end if
293  else
294  ss << "_default";
295 
296  ss_path /= ss.str();
297  // cipher/plain parameters
298  ss = std::stringstream();
299  std::unordered_set<std::size_t> cipher_param_pos =
301  if (cipher_param_pos.empty())
302  ss << "all_plain";
303  else if (cipher_param_pos.size() >= sizeof(std::uint32_t) * 8)
304  ss << "all_cipher";
305  else
306  {
307  std::size_t max_elem = *std::max_element(cipher_param_pos.begin(), cipher_param_pos.end());
308  for (std::size_t i = 0; i <= max_elem; ++i)
309  ss << (cipher_param_pos.count(i) > 0 ? 'c' : 'p');
310  } // end else
311  std::string pt_ct_str = ss.str();
312  ss_path /= pt_ct_str;
313  ss_path /= hebench::Utilities::convertToDirectoryName(s_scheme_name);
314  ss_path /= hebench::Utilities::convertToDirectoryName(s_security_name);
315  ss_path /= std::to_string(bench_desc.other);
316  // generate header
317  ss = std::stringstream();
318  ss << "Specifications," << std::endl
319  << ", Encryption, " << std::endl
320  << ", , Scheme, " << s_scheme_name << std::endl
321  << ", , Security, " << s_security_name << std::endl
322  << ", Extra, " << bench_desc.other << std::endl;
323  std::string s_tmp = engine.getExtraDescription(h_bench_desc, w_params);
324  if (!s_tmp.empty())
325  ss << s_tmp;
326  ss << std::endl
327  << std::endl
328  << ", Category, " << PartialBenchmarkDescriptor::getCategoryName(bench_desc.category) << std::endl
329  << ", , Minimum test time requested (ms), " << bench_desc.cat_params.min_test_time_ms << std::endl;
330  switch (bench_desc.category)
331  {
333  ss << ", , Warmup iterations, " << bench_desc.cat_params.latency.warmup_iterations_count << std::endl;
334  break;
335 
337  {
338  ss << ", , Parameter, Samples requested" << std::endl;
339 
340  bool all_params_zero = true;
341  for (std::size_t i = 0; i < HEBENCH_MAX_OP_PARAMS; ++i)
342  {
343  if (bench_desc.cat_params.offline.data_count[i] != 0)
344  {
345  all_params_zero = false;
346  ss << ", , " << i << ", " << bench_desc.cat_params.offline.data_count[i] << std::endl;
347  } // end if
348  } // end if
349  if (all_params_zero)
350  ss << ", , All, 0" << std::endl;
351  }
352  break;
353 
354  default:
355  throw std::invalid_argument(IL_LOG_MSG_CLASS("Unsupported benchmark category: " + std::to_string(bench_desc.category) + "."));
356  break;
357  } // end switch
358 
359  ss << std::endl
360  << ", Workload, " << s_workload_name << std::endl
361  << ", , Data type, " << PartialBenchmarkDescriptor::getDataTypeName(bench_desc.data_type) << std::endl
362  << ", , Encrypted op parameters (index)";
363  if (cipher_param_pos.empty())
364  ss << ", None" << std::endl;
365  else if (cipher_param_pos.size() >= sizeof(std::uint32_t) * 8)
366  ss << ", All" << std::endl;
367  else
368  {
369  // output the indices of the encrypted parameters
370  std::vector<std::size_t> cipher_params(cipher_param_pos.begin(), cipher_param_pos.end());
371  std::sort(cipher_params.begin(), cipher_params.end());
372  for (auto param_index : cipher_params)
373  ss << ", " << param_index;
374  ss << std::endl;
375  } // end else
376 
377  // append the extra header received from the workload
378  ss << completed_description.workload_header;
379 
380  // return the generated description
381 
382  // make sure we have default sample sizes for every operation parameter
383 
384  // These are for description purposes only. Behavior must be changed by the
385  // completeWorkloadDescription() function call above.
386 
387  concrete_backend_desc = backend_desc;
388  Engine::completeBenchmarkDescriptor(concrete_backend_desc, completed_description.concrete_descriptor);
389  concrete_backend_desc.operation_params_count = completed_description.operation_params_count;
390 
391  concrete_config = config;
392  concrete_config.default_sample_sizes.resize(concrete_backend_desc.operation_params_count, 0);
393 
394  description.workload = static_cast<std::int64_t>(bench_desc.workload);
395  description.workload_name = completed_description.workload_base_name;
398  description.scheme = engine.getSchemeName(bench_desc.scheme);
399  description.security = engine.getSecurityName(bench_desc.scheme, bench_desc.security);
400  description.cipher_flags = pt_ct_str;
401  description.other = std::to_string(completed_description.concrete_descriptor.other);
402  description.header = ss.str();
403  description.path = ss_path;
404  if (config.b_single_path_report)
405  // replace path separator by hyphens when requested
406  std::replace(description.path.begin(), description.path.end(),
408 }
409 
410 //void PartialBenchmarkDescriptor::describe(const Engine &engine,
411 // BenchmarkDescription::Backend &backend_desc,
412 // BenchmarkDescription::Configuration &config,
413 // BenchmarkDescription::Description &description) const
414 //{
415 // hebench::APIBridge::Handle h_bench_desc = backend_desc.handle;
416 // const std::vector<hebench::APIBridge::WorkloadParam> &w_params = config.w_params;
417 
418 // // obtain the values for the description that are specific to the workload
419 // WorkloadDescriptionOutput completed_description;
420 // std::memset(&completed_description.concrete_descriptor, 0, sizeof(completed_description.concrete_descriptor));
421 // completeWorkloadDescription(completed_description,
422 // engine, backend_desc, config);
429 
430 // const hebench::APIBridge::BenchmarkDescriptor &bench_desc = completed_description.concrete_descriptor;
431 
432 // std::stringstream ss;
433 // std::filesystem::path ss_path;
434 
435 // std::string &s_workload_base_name = completed_description.workload_base_name;
436 // std::string &s_workload_name = completed_description.workload_name;
437 // std::string s_path_workload_name;
438 // std::string s_scheme_name = engine.getSchemeName(bench_desc.scheme);
439 // std::string s_security_name = engine.getSecurityName(bench_desc.scheme, bench_desc.security);
440 
441 // // generate path
442 // ss = std::stringstream();
443 // if (!s_workload_base_name.empty())
444 // {
445 // ss << s_workload_base_name << "_";
446 // }
447 // else
448 // {
449 // s_workload_base_name = std::to_string(static_cast<int>(bench_desc.workload));
450 // }
451 // ss << std::to_string(static_cast<int>(bench_desc.workload));
452 // s_path_workload_name = hebench::Utilities::convertToDirectoryName(ss.str());
453 // ss_path = s_path_workload_name;
454 // ss = std::stringstream();
455 // ss << "wp";
456 // for (std::size_t i = 0; i < w_params.size(); ++i)
457 // {
458 // ss << "_";
459 // switch (w_params[i].data_type)
460 // {
461 // case hebench::APIBridge::WorkloadParamType::UInt64:
462 // ss << w_params[i].u_param;
463 // break;
464 
465 // case hebench::APIBridge::WorkloadParamType::Float64:
466 // ss << w_params[i].f_param;
467 // break;
468 
469 // default:
470 // ss << w_params[i].i_param;
471 // break;
472 // } // end switch
473 // } // end for
474 // ss_path /= hebench::Utilities::convertToDirectoryName(ss.str()); // workload params
475 // ss_path /= hebench::Utilities::convertToDirectoryName(PartialBenchmarkDescriptor::getCategoryName(bench_desc.category));
476 // ss_path /= hebench::Utilities::convertToDirectoryName(PartialBenchmarkDescriptor::getDataTypeName(bench_desc.data_type));
477 
478 // ss = std::stringstream();
479 // ss << bench_desc.cat_params.min_test_time_ms << "ms";
480 // std::size_t max_non_zero = HEBENCH_MAX_CATEGORY_PARAMS;
481 // while (max_non_zero > 0 && bench_desc.cat_params.reserved[max_non_zero - 1] == 0)
482 // --max_non_zero;
483 // if (max_non_zero > 0)
484 // {
485 // for (std::size_t i = 0; i < max_non_zero; ++i)
486 // ss << "_" << bench_desc.cat_params.reserved[i];
487 // } // end if
488 // else
489 // ss << "_default";
490 
491 // ss_path /= ss.str();
492 // // cipher/plain parameters
493 // ss = std::stringstream();
494 // std::unordered_set<std::size_t> cipher_param_pos =
495 // PartialBenchmarkDescriptor::getCipherParamPositions(bench_desc.cipher_param_mask);
496 // if (cipher_param_pos.empty())
497 // ss << "all_plain";
498 // else if (cipher_param_pos.size() >= sizeof(std::uint32_t) * 8)
499 // ss << "all_cipher";
500 // else
501 // {
502 // std::size_t max_elem = *std::max_element(cipher_param_pos.begin(), cipher_param_pos.end());
503 // for (std::size_t i = 0; i <= max_elem; ++i)
504 // ss << (cipher_param_pos.count(i) > 0 ? 'c' : 'p');
505 // } // end else
506 // std::string pt_ct_str = ss.str();
507 // ss_path /= pt_ct_str;
508 // ss_path /= hebench::Utilities::convertToDirectoryName(s_scheme_name);
509 // ss_path /= hebench::Utilities::convertToDirectoryName(s_security_name);
510 // ss_path /= std::to_string(bench_desc.other);
511 // // generate header
512 // ss = std::stringstream();
513 // ss << "Specifications," << std::endl
514 // << ", Encryption, " << std::endl
515 // << ", , Scheme, " << s_scheme_name << std::endl
516 // << ", , Security, " << s_security_name << std::endl
517 // << ", Extra, " << bench_desc.other << std::endl;
518 // std::string s_tmp = engine.getExtraDescription(h_bench_desc, w_params);
519 // if (!s_tmp.empty())
520 // ss << s_tmp;
521 // ss << std::endl
522 // << std::endl
523 // << ", Category, " << PartialBenchmarkDescriptor::getCategoryName(bench_desc.category) << std::endl
524 // << ", , Minimum test time requested (ms), " << bench_desc.cat_params.min_test_time_ms << std::endl;
525 // switch (bench_desc.category)
526 // {
527 // case hebench::APIBridge::Category::Latency:
528 // ss << ", , Warmup iterations, " << bench_desc.cat_params.latency.warmup_iterations_count << std::endl;
529 // break;
530 
531 // case hebench::APIBridge::Category::Offline:
532 // {
533 // ss << ", , Parameter, Samples requested" << std::endl;
534 
535 // bool all_params_zero = true;
536 // for (std::size_t i = 0; i < HEBENCH_MAX_OP_PARAMS; ++i)
537 // {
538 // if (bench_desc.cat_params.offline.data_count[i] != 0)
539 // {
540 // all_params_zero = false;
541 // ss << ", , " << i << ", " << bench_desc.cat_params.offline.data_count[i] << std::endl;
542 // } // end if
543 // } // end if
544 // if (all_params_zero)
545 // ss << ", , All, 0" << std::endl;
546 // }
547 // break;
548 
549 // default:
550 // throw std::invalid_argument(IL_LOG_MSG_CLASS("Unsupported benchmark category: " + std::to_string(bench_desc.category) + "."));
551 // break;
552 // } // end switch
553 
554 // ss << std::endl
555 // << ", Workload, " << s_workload_name << std::endl
556 // << ", , Data type, " << PartialBenchmarkDescriptor::getDataTypeName(bench_desc.data_type) << std::endl
557 // << ", , Encrypted op parameters (index)";
558 // if (cipher_param_pos.empty())
559 // ss << ", None" << std::endl;
560 // else if (cipher_param_pos.size() >= sizeof(std::uint32_t) * 8)
561 // ss << ", All" << std::endl;
562 // else
563 // {
564 // // output the indices of the encrypted parameters
565 // std::vector<std::size_t> cipher_params(cipher_param_pos.begin(), cipher_param_pos.end());
566 // std::sort(cipher_params.begin(), cipher_params.end());
567 // for (auto param_index : cipher_params)
568 // ss << ", " << param_index;
569 // ss << std::endl;
570 // } // end else
571 
572 // // append the extra header received from the workload
573 // ss << completed_description.workload_header;
574 
575 // // return the generated description
576 
577 // // make sure we have default sample sizes for every operation parameter
578 // Engine::completeBenchmarkDescriptor(backend_desc, completed_description.concrete_descriptor);
579 // backend_desc.operation_params_count = completed_description.operation_params_count;
580 // config.default_sample_sizes.resize(backend_desc.operation_params_count, 0);
581 
582 // description.workload = static_cast<std::int64_t>(bench_desc.workload);
583 // description.workload_name = completed_description.workload_base_name;
584 // description.data_type = PartialBenchmarkDescriptor::getDataTypeName(bench_desc.data_type);
585 // description.category = PartialBenchmarkDescriptor::getCategoryName(bench_desc.category);
586 // description.scheme = engine.getSchemeName(bench_desc.scheme);
587 // description.security = engine.getSecurityName(bench_desc.scheme, bench_desc.security);
588 // description.cipher_flags = pt_ct_str;
589 // description.other = std::to_string(completed_description.concrete_descriptor.other);
590 // description.header = ss.str();
591 // description.path = ss_path;
592 // if (config.b_single_path_report)
593 // // replace path separator by hyphens when requested
594 // std::replace(description.path.begin(), description.path.end(),
595 // hebench::TestHarness::separator, hebench::TestHarness::hyphen);
596 //}
597 
598 //------------------------
599 // class PartialBenchmark
600 //------------------------
601 
602 PartialBenchmark::PartialBenchmark(std::shared_ptr<Engine> p_engine,
603  const IBenchmarkDescriptor::DescriptionToken &description_token) :
604  m_current_event_id(0),
605  m_b_constructed(false),
606  m_b_initialized(false)
607 {
608  if (!p_engine)
609  throw std::invalid_argument(IL_LOG_MSG_CLASS("Invalid null argument 'p_engine'."));
610 
611  m_p_engine = p_engine; // this prevents engine from being destroyed while this object exists
612  std::memset(&m_handle, 0, sizeof(m_handle));
613 
614  internalInit(description_token);
615 
616  m_b_constructed = true;
617 }
618 
620 {
621  // destroy benchmark handle
623  // decouple from engine
624  m_p_engine.reset(); // this object no longer prevents engine from being destroyed
625 }
626 
627 void PartialBenchmark::internalInit(const IBenchmarkDescriptor::DescriptionToken &description_token)
628 {
629  // cache description info about this benchmark
630  m_backend_desc = description_token.getBackendDescription();
631  m_config = description_token.getBenchmarkConfiguration();
632  m_text_description = description_token.getDescription();
633 }
634 
636 {
637  m_b_initialized = true;
638 }
639 
641 {
642  hebench::Common::EventTimer timer;
643  hebench::Common::TimingReportEvent::Ptr p_timing_event;
644  std::stringstream ss;
645 
647  params.count = m_config.w_params.size();
648  params.params = m_config.w_params.data();
649 
650  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log("Creating backend benchmark...") << std::endl;
651  timer.start();
653  this->getBackendDescription().handle,
654  m_config.w_params.empty() ? nullptr : &params,
655  &m_handle));
656  p_timing_event = timer.stop<DefaultTimeInterval>(getEventIDNext(), 1, nullptr);
657  out_report.addEvent<DefaultTimeInterval>(p_timing_event, std::string("Creation"));
658  hebench::Logging::GlobalLogger::log("OK");
659  std::cout << IOS_MSG_OK << std::endl;
660 
661  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log("Initializing backend benchmark...") << std::endl;
662  timer.start();
664  p_timing_event = timer.stop<DefaultTimeInterval>(getEventIDNext(), 1, nullptr);
665  out_report.addEvent<DefaultTimeInterval>(p_timing_event, std::string("Initialization"));
666  hebench::Logging::GlobalLogger::log("OK");
667  std::cout << IOS_MSG_OK << std::endl;
668 }
669 
671 {
672  if (!m_b_constructed || !m_b_initialized)
673  throw std::runtime_error(IL_LOG_MSG_CLASS("Initialization incomplete. All initialization stages must be called: init(), initBackend(), postInit()."));
674 }
675 
677 {
678  m_p_engine->validateRetCode(err_code, last_error);
679 }
680 
681 } // namespace TestHarness
682 } // namespace hebench
const hebench::APIBridge::BenchmarkDescriptor & descriptor
Benchmark backend descriptor, as retrieved by backend, corresponding to the registration handle h_des...
std::size_t & operation_params_count
Number of operation parameters for the specified workload.
const hebench::APIBridge::Handle & handle
Handle to the benchmark description as registered by backend.
std::vector< std::uint64_t > default_sample_sizes
Default sample size for each operation parameter.
std::vector< hebench::APIBridge::WorkloadParam > w_params
Set of arguments for workload parameters.
std::uint64_t default_min_test_time_ms
Default minimum test time in milliseconds.
bool b_single_path_report
Defines if the workload report will be created in a single-level directory.
std::string getSecurityName(hebench::APIBridge::Scheme s, hebench::APIBridge::Security sec) const
static void completeBenchmarkDescriptor(hebench::TestHarness::BenchmarkDescription::Backend &backend_description, const hebench::APIBridge::BenchmarkDescriptor &completed_descriptor)
Grants a guarded write access to hebench::TestHarness::BenchmarkDescription::Backend::m_descriptor::c...
const hebench::APIBridge::Handle & handle() const
std::string getExtraDescription(hebench::APIBridge::Handle h_bench_desc, const std::vector< hebench::APIBridge::WorkloadParam > &w_params) const
void validateRetCode(hebench::APIBridge::ErrorCode err_code, bool last_error=true) const
std::string getSchemeName(hebench::APIBridge::Scheme s) const
Token returned by a successful call to IBenchmarkDescriptor::matchBenchmarkDescriptor().
const BenchmarkDescription::Backend & getBackendDescription() const
const BenchmarkDescription::Description & getDescription() const
const BenchmarkDescription::Configuration & getBenchmarkConfiguration() const
Base interface for Benchmark Descriptors.
DescriptionToken::Ptr createToken(const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config, const BenchmarkDescription::Description &text_desc) const
Creates a DescriptionToken object associated to this IBenchmarkDescription object using the specified...
static std::unordered_set< std::size_t > getCipherParamPositions(std::uint32_t cipher_param_mask)
static std::string getDataTypeName(hebench::APIBridge::DataType data_type)
virtual void completeWorkloadDescription(WorkloadDescriptionOutput &output, const Engine &engine, const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config) const =0
Completes the description for the matched benchmark.
static void completeCategoryParams(hebench::APIBridge::BenchmarkDescriptor &out_descriptor, const hebench::APIBridge::BenchmarkDescriptor &in_descriptor, const BenchmarkDescription::Configuration &config, bool force_config)
Completes common elements of category parameters in a descriptor using the specified configuration.
static std::string getCategoryName(hebench::APIBridge::Category category)
static std::uint64_t computeSampleSizes(std::uint64_t *sample_sizes, std::size_t param_count, const std::vector< std::uint64_t > &config_sample_sizes, const hebench::APIBridge::BenchmarkDescriptor &bench_desc, std::uint64_t default_sample_size_fallback, bool force_config)
Extracts the batch sizes for a workload from a specified HEBench API benchmark descriptor.
DescriptionToken::Ptr matchDescriptor(const Engine &engine, const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config) const override final
Implementation of IBenchmarkDescriptor::matchDescriptor().
virtual bool matchBenchmarkDescriptor(const hebench::APIBridge::BenchmarkDescriptor &bench_desc, const std::vector< hebench::APIBridge::WorkloadParam > &w_params) const =0
Determines if the represented benchmark can perform the workload described by a specified HEBench ben...
const BenchmarkDescription::Backend & getBackendDescription() const
Allows read-only access to this benchmark backend description.
virtual void postInit()
Called automatically during initialization after the backend has been initialized.
std::uint32_t getEventIDNext()
Returns the next available event ID.
void validateRetCode(hebench::APIBridge::ErrorCode err_code, bool last_error=true) const
Validates whether the specified HEBench API return code represents a success or error.
void checkInitializationState(const FriendPrivateKey &) const
Used to check that initialization steps have been completed successfully.
PartialBenchmark(std::shared_ptr< Engine > p_engine, const IBenchmarkDescriptor::DescriptionToken &description_token)
void initBackend(hebench::Utilities::TimingReportEx &out_report, const FriendPrivateKey &)
Initializes backend benchmark.
void addEvent(hebench::Common::TimingReportEvent::Ptr p_event)
#define IOS_MSG_INFO
#define IOS_MSG_OK
@ Float64
64 bits IEEE 754 standard floating point real numbers.
Definition: types.h:306
@ Int64
64 bits signed integers.
Definition: types.h:304
@ UInt64
64 bits unsigned integers.
Definition: types.h:305
Security security
Security for the scheme.
Definition: types.h:536
ErrorCode destroyHandle(Handle h)
Releases resources held by the specified handle.
DataType
Defines data types for a workload.
Definition: types.h:379
@ Float32
32 bits IEEE 754 standard floating point real numbers.
Definition: types.h:382
@ Int32
32 bits signed integers.
Definition: types.h:380
Category
Defines all possible categories for each workload.
Definition: types.h:391
std::uint64_t count
Number of workload parameters.
Definition: types.h:371
std::uint64_t min_test_time_ms
Specifies the minimum time, in milliseconds, to run the test.
Definition: types.h:447
std::uint32_t cipher_param_mask
Input mask to define which operation parameters for the computation are plain text or cipher text.
Definition: types.h:533
DataType data_type
Data type for the workload.
Definition: types.h:530
CategoryParams cat_params
Parameters for the category.
Definition: types.h:532
ErrorCode initBenchmark(Handle h_benchmark, const BenchmarkDescriptor *p_concrete_desc)
Allows the benchmark to perform initialization steps based on the finalized, concrete description.
ErrorCode createBenchmark(Handle h_engine, Handle h_bench_desc, const WorkloadParams *p_params, Handle *h_benchmark)
Instantiates a benchmark on the backend.
WorkloadParam * params
Parameters for the workload.
Definition: types.h:367
ErrorCode getWorkloadParamsDetails(Handle h_engine, Handle h_bench_desc, std::uint64_t *p_param_count, std::uint64_t *p_default_count)
Retrieves details about the flexible parameters supported by this workload.
std::int64_t other
Backend specific extra parameter.
Definition: types.h:537
Category category
Category for the benchmark.
Definition: types.h:531
std::int32_t ErrorCode
Return value for API bridge functions.
Definition: types.h:34
Workload workload
Workload for the benchmark.
Definition: types.h:529
Scheme scheme
Scheme for the benchmark.
Definition: types.h:535
Defines a benchmark test.
Definition: types.h:527
Specifies the parameters for a workload.
Definition: types.h:363
Structure to contain flexible data.
Definition: types.h:552
std::string to_string(const std::string_view &s)
std::string other
Other value used to uniquely identify benchmark implementations.
std::string scheme
Human-readable friendly name of the benchmark scheme.
std::string cipher_flags
Human-readable friendly name of the benchmark cipher parameters.
std::int64_t workload
Workload ID as given by hebench::APIBridge::Workload.
std::string workload_name
Human-readable friendly name of the benchmark workload.
std::string path
A string uniquely representing the benchmark descriptor that can be used as a relative directory path...
std::string category
Human-readable friendly name of the benchmark category.
std::string header
CSV formatted header for this benchmark. This will be the header pre-pended to the report containing ...
std::string data_type
Human-readable friendly name of the benchmark input/output data type.
std::string security
Human-readable friendly name of the benchmark security.
std::string convertToDirectoryName(const std::string &s, bool to_lowercase=true)
Converts a string to directory name friendly.
#define HEBENCH_MAX_CATEGORY_PARAMS
Maximum number of parameters for Category benchmark descriptor.
Definition: types.h:65
#define HEBENCH_MAX_OP_PARAMS
Maximum number of parameters supported by an operation.
Definition: types.h:63