HEBench
hebench_benchmark_factory.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 <cassert>
8 #include <filesystem>
9 #include <sstream>
10 
11 #include "hebench/api_bridge/api.h"
12 
14 
15 namespace hebench {
16 namespace TestHarness {
17 
18 //------------------------
19 // class BenchmarkFactory
20 //------------------------
21 
22 IBenchmark::Ptr BenchmarkFactory::createBenchmark(std::shared_ptr<Engine> p_engine,
25 {
26  if (!p_engine)
27  throw std::invalid_argument(IL_LOG_MSG_CLASS("Invalid null pointer \"p_engine\"."));
28  if (!p_token)
29  throw std::invalid_argument(IL_LOG_MSG_CLASS("Invalid null pointer \"p_token\"."));
30  if (!p_token->getDescriptor())
31  throw std::invalid_argument(IL_LOG_MSG_CLASS("Invalid benchmark token \"p_token\" with null descriptor."));
32 
33  std::vector<std::shared_ptr<IBenchmarkDescriptor>> &registered_benchmarks = getRegisteredBenchmarks();
34  // make sure that the token matches to a descriptor that is registered
35  IBenchmarkDescriptor *p_tmp = p_token->getDescriptor();
36  auto found_it = std::find_if(registered_benchmarks.begin(), registered_benchmarks.end(),
37  [p_tmp](std::shared_ptr<IBenchmarkDescriptor> p) -> bool { return p_tmp == p.get(); });
38  if (found_it == registered_benchmarks.end() || !*found_it)
39  throw std::invalid_argument(IL_LOG_MSG_CLASS("Benchmark token \"p_token\" descriptor is invalid: not found in registered benchmark descriptors."));
40  std::shared_ptr<IBenchmarkDescriptor> p_bd = *found_it; // this ensures that we are keeping the smart pointer around until after destruction.
41  PartialBenchmark *p_retval = p_bd->createBenchmark(p_engine, *p_token);
42  if (!p_retval)
43  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error creating benchmark."));
44  try
45  {
46  // perform initialization of the benchmark
47  const PartialBenchmark::FriendPrivateKey key;
48  p_retval->init();
49  p_retval->initBackend(out_report, key);
50  p_retval->postInit();
51  p_retval->checkInitializationState(key);
52  }
53  catch (...)
54  {
55  try
56  {
57  p_bd->destroyBenchmark(p_retval);
58  }
59  catch (...)
60  {
61  // ignore any exceptions on destruction
62  }
63  throw;
64  }
65  return IBenchmark::Ptr(p_retval,
66  [p_bd](IBenchmark *p) { if (p) p_bd->destroyBenchmark(reinterpret_cast<PartialBenchmark *>(p)); });
67 }
68 
69 std::vector<std::shared_ptr<IBenchmarkDescriptor>> &BenchmarkFactory::getRegisteredBenchmarks()
70 {
71  // ensures that the static member always exists during static initialization
72  static std::vector<std::shared_ptr<IBenchmarkDescriptor>> registered_benchmarks;
73  return registered_benchmarks;
74 }
75 
77  const BenchmarkDescription::Backend &backend_desc,
79 {
81 
82  std::vector<std::shared_ptr<IBenchmarkDescriptor>> &registered_benchmarks =
83  getRegisteredBenchmarks();
84  for (std::size_t i = 0; !retval && i < registered_benchmarks.size(); ++i)
85  retval = registered_benchmarks[i]->matchDescriptor(engine, backend_desc, config);
86 
87  return retval;
88 }
89 
90 bool BenchmarkFactory::registerSupportedBenchmark(std::shared_ptr<IBenchmarkDescriptor> p_desc_obj)
91 {
92  bool retval = false;
93  try
94  {
95  if (p_desc_obj)
96  {
97  getRegisteredBenchmarks().push_back(p_desc_obj);
98  retval = true;
99  } // end if
100  }
101  catch (...)
102  {
103  retval = false;
104  }
105  return retval;
106 }
107 
108 } // namespace TestHarness
109 } // namespace hebench
static IBenchmarkDescriptor::DescriptionToken::Ptr matchBenchmarkDescriptor(const Engine &engine, const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config)
Returns a token representing a benchmark that can perform the described workload with specified param...
static bool registerSupportedBenchmark(std::shared_ptr< IBenchmarkDescriptor > p_desc_obj)
Registers a benchmark description object that represents one of the supported workloads.
std::shared_ptr< IBenchmark > Ptr