HEBench
hebench_engine.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 <cassert>
6 #include <cstring>
7 #include <sstream>
8 
10 #include "hebench/modules/general/include/error.h"
11 
12 #include "include/hebench_engine.h"
13 
14 namespace hebench {
15 namespace TestHarness {
16 
18 {
19  std::vector<char> ch_retval;
20  std::uint64_t n = hebench::APIBridge::getErrorDescription(m_handle, err_code, nullptr, 0);
21  if (n <= 0)
22  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving error message from backend."));
23  ch_retval.resize(n);
24  if (hebench::APIBridge::getErrorDescription(m_handle, err_code, ch_retval.data(), ch_retval.size()) <= 0)
25  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving error message from backend."));
26  return ch_retval.data();
27 }
28 
30 {
31  std::vector<char> ch_retval;
32  std::uint64_t n = hebench::APIBridge::getLastErrorDescription(m_handle, nullptr, 0);
33  if (n <= 0)
34  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving last error message from backend."));
35  ch_retval.resize(n);
36  if (hebench::APIBridge::getLastErrorDescription(m_handle, ch_retval.data(), ch_retval.size()) <= 0)
37  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving last error message from backend."));
38  return ch_retval.data();
39 }
40 
41 void Engine::validateRetCode(hebench::APIBridge::ErrorCode err_code, bool last_error) const
42 {
43  if (err_code != HEBENCH_ECODE_SUCCESS)
44  {
45  std::stringstream ss;
46  ss << getErrorDescription(err_code);
47  if (last_error)
48  {
49  std::string s = getLastErrorDescription();
50  if (!s.empty())
51  ss << std::endl
52  << s;
53  } // end if
54  throw hebench::Common::ErrorException(ss.str(), err_code);
55  } // end if
56 }
57 
58 Engine::Ptr Engine::create(const std::vector<std::int8_t> &data)
59 {
60  Engine::Ptr retval = Engine::Ptr(new Engine());
61  retval->init(data);
62  return retval;
63 }
64 
65 Engine::Engine()
66 {
67  std::memset(&m_handle, 0, sizeof(m_handle));
68 }
69 
70 void Engine::init(const std::vector<std::int8_t> &data)
71 {
72  std::stringstream ss;
73 
74  // initialize backend engine
76  if (data.empty())
77  err_code = hebench::APIBridge::initEngine(&m_handle, nullptr, 0);
78  else
79  err_code = hebench::APIBridge::initEngine(&m_handle, data.data(), data.size() * sizeof(std::int8_t));
80  if (err_code != HEBENCH_ECODE_SUCCESS)
81  {
82  try
83  {
84  std::string s = getErrorDescription(err_code);
85  ss = std::stringstream(s);
86  ss << s;
88  if (!s.empty())
89  ss << std::endl
90  << s;
91  }
92  catch (...)
93  {
94  ss = std::stringstream(IL_LOG_MSG_CLASS("Error initializing backend engine."));
95  }
96  throw hebench::Common::ErrorException(ss.str(), err_code);
97  } // end if
98 
99  // register benchmarks from backend
100  std::uint64_t count;
102  m_h_bench_desc.resize(count);
103  validateRetCode(hebench::APIBridge::subscribeBenchmarks(m_handle, m_h_bench_desc.data(), m_h_bench_desc.size()));
104 }
105 
107 {
108  // destroy handles for benchmark descriptors
109  for (const hebench::APIBridge::Handle &h : m_h_bench_desc)
111  // destroy handle for the engine
113 }
114 
116 {
117  std::vector<char> ch_retval;
118  std::uint64_t n = hebench::APIBridge::getSchemeName(this->handle(), s, nullptr, 0);
119  if (n <= 0)
120  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving scheme name."));
121  ch_retval.resize(n);
123  ch_retval.data(), ch_retval.size())
124  <= 0)
125  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving scheme name."));
126  return ch_retval.data();
127 }
128 
131 {
132  std::vector<char> ch_retval;
133  std::uint64_t n = hebench::APIBridge::getSchemeSecurityName(this->handle(),
134  s,
135  sec,
136  nullptr, 0);
137  if (n <= 0)
138  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving security name."));
139  ch_retval.resize(n);
141  s,
142  sec,
143  ch_retval.data(), ch_retval.size())
144  <= 0)
145  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving security name."));
146  return ch_retval.data();
147 }
148 
150  const std::vector<hebench::APIBridge::WorkloadParam> &w_params) const
151 {
152  std::vector<char> ch_retval;
153  const hebench::APIBridge::WorkloadParams hebench_w_params = { const_cast<hebench::APIBridge::WorkloadParam *>(w_params.data()), w_params.size() };
154  const hebench::APIBridge::WorkloadParams *p_w_params = w_params.empty() ? nullptr : &hebench_w_params;
155  std::uint64_t n = hebench::APIBridge::getBenchmarkDescriptionEx(this->handle(), h_bench_desc, p_w_params,
156  nullptr, 0);
157  if (n <= 0)
158  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving extra description."));
159  ch_retval.resize(n);
160  n = hebench::APIBridge::getBenchmarkDescriptionEx(this->handle(), h_bench_desc, p_w_params,
161  ch_retval.data(), ch_retval.size());
162  if (n <= 0)
163  throw std::runtime_error(IL_LOG_MSG_CLASS("Unexpected error retrieving extra description."));
164  return ch_retval.data();
165 }
166 
168 {
169  if (!m_last_benchmark.expired())
170  throw std::logic_error(IL_LOG_MSG_CLASS("A benchmark already exists. Cannot create more than one benchmark at a time."));
171 
172  IBenchmark::Ptr p_retval = BenchmarkFactory::createBenchmark(this->shared_from_this(), p_token, out_report);
173  m_last_benchmark = p_retval; // keep track of this benchmark
174  return p_retval;
175 }
176 
178  const BenchmarkDescription::Configuration &config) const
179 {
180  if (index >= m_h_bench_desc.size())
181  throw std::out_of_range(IL_LOG_MSG_CLASS("Total benchmarks: " + std::to_string(m_h_bench_desc.size()) + ". Invalid 'index' out of range: " + std::to_string(index) + "."));
182 
184 
185  BenchmarkDescription::Backend backend_desc;
186  backend_desc.m_backend_description.m_index = index;
187  backend_desc.m_backend_description.m_handle = m_h_bench_desc[index];
189  m_h_bench_desc[index],
190  &backend_desc.m_backend_description.m_descriptor,
191  nullptr, 0));
192 
193  retval = BenchmarkFactory::matchBenchmarkDescriptor(*this, backend_desc, config);
194 
195  return retval;
196 }
197 
199  const hebench::APIBridge::BenchmarkDescriptor &completed_descriptor)
200 {
201  hebench::APIBridge::BenchmarkDescriptor &output = backend_description.m_backend_description.m_descriptor;
202  if (output.workload != completed_descriptor.workload
203  || output.data_type != completed_descriptor.data_type
204  || output.category != completed_descriptor.category
205  || output.cipher_param_mask != completed_descriptor.cipher_param_mask
206  || output.scheme != completed_descriptor.scheme
207  || output.security != completed_descriptor.security
208  || output.other != completed_descriptor.other)
209  throw std::runtime_error(IL_LOG_MSG_CLASS("Completed benchmark descriptor differs from backend specification."));
210 
211  output.cat_params = completed_descriptor.cat_params;
212 }
213 
214 std::vector<std::vector<hebench::APIBridge::WorkloadParam>>
215 Engine::getDefaultWorkloadParams(std::size_t index) const
216 {
217  if (index >= m_h_bench_desc.size())
218  throw std::out_of_range(IL_LOG_MSG_CLASS("Total benchmarks: " + std::to_string(m_h_bench_desc.size()) + ". Invalid 'index' out of range: " + std::to_string(index) + "."));
219 
220  std::uint64_t param_count, default_count;
222  m_h_bench_desc[index],
223  &param_count,
224  &default_count));
225  std::vector<std::vector<hebench::APIBridge::WorkloadParam>> retval(default_count);
226  if (!retval.empty())
227  {
228  std::vector<hebench::APIBridge::WorkloadParams> wps(retval.size());
229  for (std::size_t i = 0; i < retval.size(); ++i)
230  {
231  retval[i].resize(param_count);
232  wps[i].count = retval[i].size();
233  wps[i].params = retval[i].data();
234  } // end for
237  m_h_bench_desc[index],
238  &tmp_bd,
239  wps.data(),
240  wps.size()));
241  } // end if
242 
243  return retval;
244 }
245 
246 } // namespace TestHarness
247 } // 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 Engine::Ptr create(const std::vector< std::int8_t > &data)
Creates a new backend engine.
std::string getSecurityName(hebench::APIBridge::Scheme s, hebench::APIBridge::Security sec) const
IBenchmarkDescriptor::DescriptionToken::Ptr describeBenchmark(std::size_t index, const BenchmarkDescription::Configuration &config) const
Describes a benchmark workload that matches the specified description from the benchmarks registered ...
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...
std::shared_ptr< Engine > Ptr
std::vector< std::vector< hebench::APIBridge::WorkloadParam > > getDefaultWorkloadParams(std::size_t index) const
Retrieves the list of default parameters for a workload as specified by the backend.
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 getErrorDescription(hebench::APIBridge::ErrorCode err_code) const
std::string getLastErrorDescription() const
std::string getSchemeName(hebench::APIBridge::Scheme s) const
IBenchmark::Ptr createBenchmark(IBenchmarkDescriptor::DescriptionToken::Ptr p_token, hebench::Utilities::TimingReportEx &out_report)
Creates the the benchmark workload represented by the specified token.
std::shared_ptr< IBenchmark > Ptr
std::uint64_t getSchemeName(Handle h_engine, Scheme s, char *p_name, std::uint64_t size)
Retrieves the name of a specified scheme ID from the backend.
Security security
Security for the scheme.
Definition: types.h:536
std::uint64_t getSchemeSecurityName(Handle h_engine, Scheme s, Security sec, char *p_name, std::uint64_t size)
Retrieves the name of the specified security for the scheme ID from the backend.
std::uint64_t getErrorDescription(Handle h_engine, ErrorCode code, char *p_description, std::uint64_t size)
Retrieves the general error description of an error code.
ErrorCode destroyHandle(Handle h)
Releases resources held by the specified handle.
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
std::int32_t Scheme
Open-ended homomorphic encryption scheme ID.
Definition: types.h:406
ErrorCode describeBenchmark(Handle h_engine, Handle h_bench_desc, BenchmarkDescriptor *p_bench_desc, WorkloadParams *p_default_params, std::uint64_t default_count)
Retrieves the concrete description for a benchmark registered by backend.
std::int32_t Security
Open-ended homomorphic encryption scheme security ID.
Definition: types.h:412
std::uint64_t size
Size of underlying data.
Definition: types.h:564
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
ErrorCode initEngine(Handle *h_engine, const int8_t *p_buffer, uint64_t size)
Initializes the backend engine.
Workload workload
Workload for the benchmark.
Definition: types.h:529
Scheme scheme
Scheme for the benchmark.
Definition: types.h:535
std::uint64_t getLastErrorDescription(Handle h_engine, char *p_description, std::uint64_t size)
Retrieves the detailed description of the last error that occurred during an operation on the engine.
std::uint64_t getBenchmarkDescriptionEx(Handle h_engine, Handle h_bench_desc, const hebench::APIBridge::WorkloadParams *p_w_params, char *p_description, std::uint64_t size)
Retrieves backend specific text description for a benchmark descriptor.
ErrorCode subscribeBenchmarksCount(Handle h_engine, std::uint64_t *p_count)
Retrieves the number of benchmarks for which the backend is registering to perform.
ErrorCode subscribeBenchmarks(Handle h_engine, Handle *p_h_bench_descs, std::uint64_t count)
Retrieves handles to the benchmark descriptions for which the backend is registering to perform.
Defines a benchmark test.
Definition: types.h:527
Defines a single workload parameter.
Definition: types.h:318
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)
#define HEBENCH_ECODE_SUCCESS
Function call succeeded without error.
Definition: types.h:39