16 #include "hebench/modules/logging/include/logging.h" 
   17 #include "hebench/modules/timer/include/timer.h" 
   25 namespace TestHarness {
 
   42 bool PartialBenchmarkDescriptor::m_b_force_config_value = 
true;
 
   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))
 
   77         throw std::invalid_argument(IL_LOG_MSG_CLASS(
"Unknown category: " + 
std::to_string(
static_cast<int>(category)) + 
"."));
 
  107         throw std::invalid_argument(IL_LOG_MSG_CLASS(
"Unknown data type: " + 
std::to_string(
static_cast<int>(data_type)) + 
"."));
 
  115                                                              std::size_t param_count,
 
  116                                                              const std::vector<std::uint64_t> &default_sample_sizes,
 
  118                                                              std::uint64_t default_sample_size_fallback,
 
  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."));
 
  126     std::uint64_t result_batch_size = 1;
 
  127     for (std::size_t param_i = 0; param_i < param_count; ++param_i)
 
  132             std::uint64_t sample_size = default_sample_sizes.size() > param_i ?
 
  133                                             default_sample_sizes[param_i] :
 
  136             if (sample_size == 0)
 
  137                 sample_size = bench_desc.
cat_params.offline.data_count[param_i] != 0 ?
 
  139                                   bench_desc.
cat_params.offline.data_count[param_i] :
 
  141                                   default_sample_size_fallback;
 
  143             sample_sizes[param_i] = sample_size;
 
  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 ?
 
  154                                          default_sample_size :
 
  156                                          bench_desc.
cat_params.offline.data_count[param_i]);
 
  158         result_batch_size *= sample_sizes[param_i];
 
  160     return result_batch_size;
 
  169     const auto &w_params = config.
w_params;
 
  170     std::uint64_t w_params_count, other;
 
  172     if (w_params_count != w_params.size())
 
  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()));
 
  185         describe(final_backend_desc, final_config, text_description,
 
  186                  engine, backend_desc, config);
 
  187         retval = 
createToken(final_backend_desc, final_config, text_description);
 
  222     const std::vector<hebench::APIBridge::WorkloadParam> &w_params = config.
w_params;
 
  225     WorkloadDescriptionOutput completed_description;
 
  226     std::memset(&completed_description.concrete_descriptor, 0, 
sizeof(completed_description.concrete_descriptor));
 
  233                                 engine, backend_desc, config);
 
  237     std::stringstream ss;
 
  238     std::filesystem::path ss_path;
 
  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;
 
  247     ss = std::stringstream();
 
  248     if (!s_workload_base_name.empty())
 
  250         ss << s_workload_base_name << 
"_";
 
  256     ss << std::to_string(static_cast<int>(bench_desc.
workload));
 
  258     ss_path              = s_path_workload_name;
 
  259     ss                   = std::stringstream();
 
  261     for (std::size_t i = 0; i < w_params.size(); ++i)
 
  264         switch (w_params[i].data_type)
 
  267             ss << w_params[i].u_param;
 
  271             ss << w_params[i].f_param;
 
  275             ss << w_params[i].i_param;
 
  283     ss = std::stringstream();
 
  286     while (max_non_zero > 0 && bench_desc.
cat_params.reserved[max_non_zero - 1] == 0)
 
  288     if (max_non_zero > 0)
 
  290         for (std::size_t i = 0; i < max_non_zero; ++i)
 
  291             ss << 
"_" << bench_desc.
cat_params.reserved[i];
 
  298     ss = std::stringstream();
 
  299     std::unordered_set<std::size_t> cipher_param_pos =
 
  301     if (cipher_param_pos.empty())
 
  303     else if (cipher_param_pos.size() >= 
sizeof(std::uint32_t) * 8)
 
  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');
 
  311     std::string pt_ct_str = ss.str();
 
  312     ss_path /= pt_ct_str;
 
  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;
 
  333         ss << 
", , Warmup iterations, " << bench_desc.
cat_params.latency.warmup_iterations_count << std::endl;
 
  338         ss << 
", , Parameter, Samples requested" << std::endl;
 
  340         bool all_params_zero = 
true;
 
  343             if (bench_desc.
cat_params.offline.data_count[i] != 0)
 
  345                 all_params_zero = 
false;
 
  346                 ss << 
", , " << i << 
", " << bench_desc.
cat_params.offline.data_count[i] << std::endl;
 
  350             ss << 
", , All, 0" << std::endl;
 
  355         throw std::invalid_argument(IL_LOG_MSG_CLASS(
"Unsupported benchmark category: " + 
std::to_string(bench_desc.
category) + 
"."));
 
  360        << 
", Workload, " << s_workload_name << 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;
 
  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;
 
  378     ss << completed_description.workload_header;
 
  387     concrete_backend_desc = backend_desc;
 
  391     concrete_config = config;
 
  395     description.
workload_name = completed_description.workload_base_name;
 
  402     description.
header        = ss.str();
 
  403     description.
path          = ss_path;
 
  406         std::replace(description.
path.begin(), description.
path.end(),
 
  604     m_current_event_id(0),
 
  605     m_b_constructed(false),
 
  606     m_b_initialized(false)
 
  609         throw std::invalid_argument(IL_LOG_MSG_CLASS(
"Invalid null argument 'p_engine'."));
 
  611     m_p_engine = p_engine; 
 
  612     std::memset(&m_handle, 0, 
sizeof(m_handle));
 
  614     internalInit(description_token);
 
  616     m_b_constructed = 
true;
 
  637     m_b_initialized = 
true;
 
  642     hebench::Common::EventTimer timer;
 
  643     hebench::Common::TimingReportEvent::Ptr p_timing_event;
 
  644     std::stringstream ss;
 
  650     std::cout << 
IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(
"Creating backend benchmark...") << std::endl;
 
  653                                                         this->getBackendDescription().handle,
 
  654                                                         m_config.
w_params.empty() ? 
nullptr : ¶ms,
 
  658     hebench::Logging::GlobalLogger::log(
"OK");
 
  661     std::cout << 
IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(
"Initializing backend benchmark...") << std::endl;
 
  666     hebench::Logging::GlobalLogger::log(
"OK");
 
  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()."));
 
  678     m_p_engine->validateRetCode(err_code, last_error);
 
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.
 
Specifies a benchmark configuration.
 
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
 
std::shared_ptr< DescriptionToken > Ptr
 
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.
 
PartialBenchmarkDescriptor()
 
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.
 
~PartialBenchmarkDescriptor() override
 
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.
 
~PartialBenchmark() override
 
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)
 
@ Float64
64 bits IEEE 754 standard floating point real numbers.
 
@ Int64
64 bits signed integers.
 
@ UInt64
64 bits unsigned integers.
 
Security security
Security for the scheme.
 
ErrorCode destroyHandle(Handle h)
Releases resources held by the specified handle.
 
DataType
Defines data types for a workload.
 
@ Float32
32 bits IEEE 754 standard floating point real numbers.
 
@ Int32
32 bits signed integers.
 
Category
Defines all possible categories for each workload.
 
std::uint64_t count
Number of workload parameters.
 
std::uint64_t min_test_time_ms
Specifies the minimum time, in milliseconds, to run the test.
 
std::uint32_t cipher_param_mask
Input mask to define which operation parameters for the computation are plain text or cipher text.
 
DataType data_type
Data type for the workload.
 
CategoryParams cat_params
Parameters for the category.
 
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.
 
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.
 
Category category
Category for the benchmark.
 
std::int32_t ErrorCode
Return value for API bridge functions.
 
Workload workload
Workload for the benchmark.
 
Scheme scheme
Scheme for the benchmark.
 
Defines a benchmark test.
 
Specifies the parameters for a workload.
 
Structure to contain flexible data.
 
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::micro DefaultTimeInterval
 
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.
 
#define HEBENCH_MAX_OP_PARAMS
Maximum number of parameters supported by an operation.