HEBench
hebench_genericwl_o.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 <bitset>
6 #include <cassert>
7 #include <cstring>
8 #include <iomanip>
9 #include <iostream>
10 #include <sstream>
11 #include <stdexcept>
12 #include <utility>
13 
14 #include "hebench/modules/timer/include/timer.h"
15 
16 #include "hebench/api_bridge/api.h"
17 #include "hebench/modules/general/include/hebench_math_utils.h"
18 #include "include/hebench_engine.h"
19 
20 #include "../include/hebench_genericwl_o.h"
21 
22 namespace hebench {
23 namespace TestHarness {
24 namespace GenericWL {
25 namespace Offline {
26 
27 //----------------------------
28 // class BenchmarkDescription
29 //----------------------------
30 
31 bool BenchmarkDescriptor::m_b_registered = // register the benchmark with the factory
32  hebench::TestHarness::BenchmarkFactory::registerSupportedBenchmark(std::make_shared<BenchmarkDescriptor>());
33 
35  const std::vector<hebench::APIBridge::WorkloadParam> &w_params) const
36 {
37  assert(m_b_registered);
38 
39  // return true if benchmark is supported
40 
41  bool retval =
44 
45  return retval;
46 }
47 
49  const Engine &engine,
50  const BenchmarkDescription::Backend &backend_desc,
51  const BenchmarkDescription::Configuration &config) const
52 {
53  // finish describing workload
54  assert(DefaultBatchSize == 1);
55 
56  BenchmarkDescriptorCategory::completeWorkloadDescription(output, engine, backend_desc, config);
57 
58  auto op_info = fetchIOVectorSizes(config.w_params);
59  const std::vector<std::uint64_t> &input_sizes = op_info.first;
60  const std::vector<std::uint64_t> &output_sizes = op_info.second;
61 
62  assert(input_sizes.size() == output.operation_params_count);
63 
64  // finish benchmark header description
65 
66  std::stringstream ss;
67  std::uint64_t *batch_sizes = output.concrete_descriptor.cat_params.offline.data_count;
68  std::uint64_t sample_size_fallback =
69  config.fallback_default_sample_size > 0 ?
72  std::uint64_t result_batch_size =
75  config.default_sample_sizes,
76  backend_desc.descriptor,
77  sample_size_fallback,
79  // complete header with workload specifics
80  ss << ", , (C[0]";
81  for (std::size_t i = 1; i < output_sizes.size(); ++i)
82  ss << "; C[" << i << "]";
83  ss << ") = op(V[0]";
84  for (std::size_t i = 1; i < input_sizes.size(); ++i)
85  ss << "; V[" << i << "]";
86  ss << ")" << std::endl
87  << ", , , Elements, Batch size" << std::endl;
88  for (std::size_t i = 0; i < output.operation_params_count; ++i)
89  {
90  ss << ", , V[" << i << "], " << input_sizes[i] << ", " << batch_sizes[i] << std::endl;
91  } // end for
92  for (std::size_t i = 0; i < output_sizes.size(); ++i)
93  {
94  ss << ", , C[" << i << "], " << output_sizes[i] << ", " << result_batch_size << std::endl;
95  } // end for
96 
97  output.workload_header = ss.str();
98 }
99 
101  const DescriptionToken &description_token)
102 {
103  assert(m_b_registered);
104  Benchmark *retval = nullptr;
105 
106  try
107  {
108  retval = new Benchmark(p_engine, description_token);
109  }
110  catch (...)
111  {
112  if (retval)
113  delete retval;
114  throw;
115  }
116 
117  return retval;
118 }
119 
121 {
122  assert(m_b_registered);
123  if (p_bench)
124  delete p_bench;
125 }
126 
127 //-----------------
128 // class Benchmark
129 //-----------------
130 
131 Benchmark::Benchmark(std::shared_ptr<Engine> p_engine,
132  const IBenchmarkDescriptor::DescriptionToken &description_token) :
133  BenchmarkOffline(p_engine, description_token),
134  m_op_input_count(0),
135  m_op_output_count(0)
136 {
137 }
138 
140 {
141  hebench::Common::EventTimer timer;
142  hebench::Common::TimingReportEvent::Ptr p_timing_event;
143  std::vector<std::uint64_t> batch_sizes;
144  std::stringstream ss;
146  const std::vector<std::uint64_t> &input_sizes = op_info.first;
147  const std::vector<std::uint64_t> &output_sizes = op_info.second;
148 
149  m_op_input_count = input_sizes.size();
150  m_op_output_count = output_sizes.size();
151  batch_sizes.resize(m_op_input_count);
152 
153  std::uint64_t sample_size_fallback =
157  BenchmarkDescriptor::computeSampleSizes(batch_sizes.data(),
158  batch_sizes.size(),
159  this->getBenchmarkConfiguration().default_sample_sizes,
160  this->getBackendDescription().descriptor,
161  sample_size_fallback,
163 
164  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log("Preparing workload.") << std::endl;
165 
166  if (this->getBenchmarkConfiguration().dataset_filename.empty())
167  // cannot generate data for generic workload
168  throw std::invalid_argument(IL_LOG_MSG_CLASS("Dataset file is required for generic workload benchmarking, but none was provided."));
169 
170  ss = std::stringstream();
171  ss << "Loading data from external dataset: " << std::endl
172  << "\"" << this->getBenchmarkConfiguration().dataset_filename << "\"";
173  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
174  timer.start();
175  // load vectors for input and ground truth from file
176  m_data = DataLoader::create(input_sizes,
177  batch_sizes,
178  output_sizes,
179  this->getBackendDescription().descriptor.data_type,
180  this->getBenchmarkConfiguration().dataset_filename);
181  p_timing_event = timer.stop<std::milli>();
182 
183  ss = std::stringstream();
184  ss << "Total data loaded: " << m_data->getTotalDataLoaded() << " bytes";
185  std::cout << IOS_MSG_DONE << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
186  ss = std::stringstream();
187  ss << "Elapsed wall time: " << p_timing_event->elapsedWallTime<std::milli>() << " ms";
188  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
189  ss = std::stringstream();
190  ss << "Elapsed CPU time: " << p_timing_event->elapsedCPUTime<std::milli>() << " ms";
191  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
192 }
193 
195  const std::uint64_t *param_data_pack_indices,
196  const std::vector<hebench::APIBridge::NativeDataBuffer *> &outputs,
197  hebench::APIBridge::DataType data_type) const
198 {
199  assert(dataset->getParameterCount() == m_op_input_count
200  && dataset->getResultCount() == m_op_output_count);
201 
202  return BenchmarkOffline::validateResult(dataset, param_data_pack_indices, outputs, data_type);
203 }
204 
205 } // namespace Offline
206 } // namespace GenericWL
207 } // namespace TestHarness
208 } // namespace hebench
const hebench::APIBridge::BenchmarkDescriptor & descriptor
Benchmark backend descriptor, as retrieved by backend, corresponding to the registration handle h_des...
std::uint64_t fallback_default_sample_size
Default sample size to be used if a specific size is not specified in the default_sample_sizes collec...
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::string dataset_filename
File containing data for the benchmark. If empty string, benchmarks that can auto generate the datase...
static bool registerSupportedBenchmark(std::shared_ptr< IBenchmarkDescriptor > p_desc_obj)
Registers a benchmark description object that represents one of the supported workloads.
Base class for workload benchmarks in the offline category.
void completeWorkloadDescription(WorkloadDescriptionOutput &output, const Engine &engine, const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config) const override
Completes the description for the matched benchmark.
static std::pair< std::vector< std::uint64_t >, std::vector< std::uint64_t > > fetchIOVectorSizes(const std::vector< hebench::APIBridge::WorkloadParam > &w_params)
Retrieves details about the input parameters and results of the generic operation based on the specif...
bool matchBenchmarkDescriptor(const hebench::APIBridge::BenchmarkDescriptor &bench_desc, const std::vector< hebench::APIBridge::WorkloadParam > &w_params) const override
Determines if the represented benchmark can perform the workload described by a specified HEBench ben...
static DataLoader::Ptr create(const std::vector< std::uint64_t > &input_sizes, const std::vector< std::uint64_t > &max_batch_sizes, const std::vector< std::uint64_t > &output_sizes, hebench::APIBridge::DataType data_type, const std::string &dataset_filename)
void destroyBenchmark(hebench::TestHarness::PartialBenchmark *p_bench) override
Destroys an object returned by createBenchmark().
void completeWorkloadDescription(WorkloadDescriptionOutput &output, const Engine &engine, const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config) const override
Completes the description for the matched benchmark.
bool matchBenchmarkDescriptor(const hebench::APIBridge::BenchmarkDescriptor &bench_desc, const std::vector< hebench::APIBridge::WorkloadParam > &w_params) const override
Determines if the represented benchmark can perform the workload described by a specified HEBench ben...
hebench::TestHarness::PartialBenchmark * createBenchmark(std::shared_ptr< Engine > p_engine, const DescriptionToken &description_token) override
Creates the represented IBenchmark object that can perform the workload specified by the HEBench benc...
void init() override
Initializes the partial benchmark members.
bool validateResult(IDataLoader::Ptr dataset, const std::uint64_t *param_data_pack_indices, const std::vector< hebench::APIBridge::NativeDataBuffer * > &p_outputs, hebench::APIBridge::DataType data_type) const override
Validates the result of an operation against the ground truth.
Token returned by a successful call to IBenchmarkDescriptor::matchBenchmarkDescriptor().
std::shared_ptr< IDataLoader > Ptr
virtual bool validateResult(IDataLoader::Ptr dataset, const std::uint64_t *param_data_pack_indices, const std::vector< hebench::APIBridge::NativeDataBuffer * > &outputs, hebench::APIBridge::DataType data_type) const
Validates the result of an operation against the ground truth.
std::string workload_header
Workload specific information to be added to the report header.
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.
static bool getForceConfigValues()
Specifies whether frontend will override backend descriptors using configuration data or not.
std::size_t operation_params_count
Number of parameters for the represented workload operation.
hebench::APIBridge::BenchmarkDescriptor concrete_descriptor
Benchmark descriptor completed with concrete values assigned to configurable fields.
Bundles values that need to be filled by a workload during completeWorkloadDescription().
const BenchmarkDescription::Backend & getBackendDescription() const
Allows read-only access to this benchmark backend description.
const BenchmarkDescription::Configuration & getBenchmarkConfiguration() const
Allows read-only access to this benchmark configuration.
#define IOS_MSG_DONE
#define IOS_MSG_INFO
DataType
Defines data types for a workload.
Definition: types.h:379
CategoryParams cat_params
Parameters for the category.
Definition: types.h:532
Category category
Category for the benchmark.
Definition: types.h:531
Defines a benchmark test.
Definition: types.h:527