HEBench
hebench_simple_set_intersection_l.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_simple_set_intersection_l.h"
21 
22 namespace hebench {
23 namespace TestHarness {
24 namespace SimpleSetIntersection {
25 namespace Latency {
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  return retval;
45 }
46 
48  const Engine &engine,
49  const BenchmarkDescription::Backend &backend_desc,
50  const BenchmarkDescription::Configuration &config) const
51 {
52  assert(OpParameterCount == 2);
53  assert(DefaultBatchSize == 1);
54 
55  BenchmarkDescriptorCategory::completeWorkloadDescription(output, engine, backend_desc, config);
56 
57  assert(OpParameterCount == output.operation_params_count);
58 
59  // finish benchmark header description
60 
61  std::stringstream ss;
62  std::uint64_t batch_sizes[OpParameterCount];
63  auto set_size = fetchSetSize(config.w_params);
64 
65  ss = std::stringstream();
66 
67  // Assuming that there could be a set containing the other
68  std::uint64_t result_set_size = std::min(set_size.at(0), set_size.at(1));
69  std::uint64_t result_batch_size = 1;
70  for (std::size_t param_i = 0; param_i < OpParameterCount; ++param_i)
71  {
72  batch_sizes[param_i] = DefaultBatchSize;
73  result_batch_size *= batch_sizes[param_i];
74  } // end for
75  // complete header with workload specifics
76  ss << ", , Z = Intersect(X, Y)" << std::endl
77  << ", , , Items in set, Batch size, Elements per item" << std::endl;
78 
79  ss << ", , X, " << set_size.at(0) << ", " << batch_sizes[0] << ", " << set_size.at(2) << std::endl;
80 
81  ss << ", , Y, " << set_size.at(1) << ", " << batch_sizes[1] << ", " << set_size.at(2) << std::endl;
82 
83  ss << ", , Z, " << result_set_size << ", " << result_batch_size << ", " << set_size.at(2) << std::endl;
84 
85  output.workload_header = ss.str();
86 }
87 
89  const DescriptionToken &description_token)
90 {
91  assert(m_b_registered);
92  Benchmark *retval = nullptr;
93 
94  try
95  {
96  retval = new Benchmark(p_engine, description_token);
97  }
98  catch (...)
99  {
100  if (retval)
101  delete retval;
102  throw;
103  }
104 
105  return retval;
106 }
107 
109 {
110  assert(m_b_registered);
111  if (p_bench)
112  delete p_bench;
113 }
114 
115 //-----------------
116 // class Benchmark
117 //-----------------
118 
119 Benchmark::Benchmark(std::shared_ptr<Engine> p_engine,
120  const IBenchmarkDescriptor::DescriptionToken &description_token) :
121  BenchmarkLatency(p_engine, description_token)
122 {
123 }
124 
126 {
127  hebench::Common::EventTimer timer;
128  hebench::Common::TimingReportEvent::Ptr p_timing_event;
129  std::uint64_t batch_sizes[BenchmarkDescriptor::OpParameterCount];
130  std::stringstream ss;
131 
132  auto set_size = BenchmarkDescriptor::fetchSetSize(this->getBenchmarkConfiguration().w_params);
133  for (std::size_t param_i = 0; param_i < BenchmarkDescriptor::OpParameterCount; ++param_i)
134  batch_sizes[param_i] = BenchmarkDescriptor::DefaultBatchSize;
135 
136  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log("Preparing workload.") << std::endl;
137 
138  // setting k count for it to be used to validate the results
139  m_k_count = set_size.at(2);
140 
141  timer.start();
142 
143  if (this->getBenchmarkConfiguration().dataset_filename.empty())
144  {
145  // generates random vectors for input and generates (computes) ground truth
146  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log("Generating data...") << std::endl;
147  m_data = DataLoader::create(set_size.at(0), set_size.at(1), // |X|, |Y|
148  batch_sizes[0], batch_sizes[1],
149  m_k_count,
150  this->getBackendDescription().descriptor.data_type);
151  } // end if
152  else
153  {
154  std::stringstream ss;
155  ss << "Loading data from external dataset: " << std::endl
156  << "\"" << this->getBenchmarkConfiguration().dataset_filename << "\"";
157  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
158  // load vectors for input and ground truth from file
159  m_data = DataLoader::create(set_size.at(0), set_size.at(1), // |X|, |Y|
160  batch_sizes[0], batch_sizes[1],
161  m_k_count,
162  this->getBackendDescription().descriptor.data_type,
163  this->getBenchmarkConfiguration().dataset_filename);
164  } // end else
165  p_timing_event = timer.stop<std::milli>();
166 
167  ss = std::stringstream();
168  ss << "Total data loaded: " << m_data->getTotalDataLoaded() << " bytes";
169  std::cout << IOS_MSG_DONE << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
170  ss = std::stringstream();
171  ss << "Elapsed wall time: " << p_timing_event->elapsedWallTime<std::milli>() << " ms";
172  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
173  ss = std::stringstream();
174  ss << "Elapsed CPU time: " << p_timing_event->elapsedCPUTime<std::milli>() << " ms";
175  std::cout << IOS_MSG_INFO << hebench::Logging::GlobalLogger::log(ss.str()) << std::endl;
176 }
177 
179  const std::uint64_t *param_data_pack_indices,
180  const std::vector<hebench::APIBridge::NativeDataBuffer *> &outputs,
181  hebench::APIBridge::DataType data_type) const
182 {
183 
184  assert(dataset->getParameterCount() == BenchmarkDescriptorCategory::OpParameterCount
185  && dataset->getResultCount() == BenchmarkDescriptorCategory::OpResultCount);
186 
188  param_data_pack_indices,
189  outputs,
190  m_k_count,
191  data_type);
192 }
193 
194 } // namespace Latency
195 } // namespace SimpleSetIntersection
196 } // namespace TestHarness
197 } // namespace hebench
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 latency category.
Token returned by a successful call to IBenchmarkDescriptor::matchBenchmarkDescriptor().
std::shared_ptr< IDataLoader > Ptr
std::string workload_header
Workload specific information to be added to the report header.
std::size_t operation_params_count
Number of parameters for the represented workload operation.
Bundles values that need to be filled by a workload during completeWorkloadDescription().
const BenchmarkDescription::Configuration & getBenchmarkConfiguration() const
Allows read-only access to this benchmark configuration.
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::array< std::uint64_t, BenchmarkDescriptorCategory::WorkloadParameterCount > fetchSetSize(const std::vector< hebench::APIBridge::WorkloadParam > &w_params)
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(std::uint64_t set_size_x, std::uint64_t set_size_y, std::uint64_t batch_size_x, std::uint64_t batch_size_y, std::uint64_t element_size_k, hebench::APIBridge::DataType data_type)
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 completeWorkloadDescription(WorkloadDescriptionOutput &output, const Engine &engine, const BenchmarkDescription::Backend &backend_desc, const BenchmarkDescription::Configuration &config) const override
Completes the description for the matched benchmark.
void destroyBenchmark(hebench::TestHarness::PartialBenchmark *p_bench) override
Destroys an object returned by createBenchmark().
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...
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.
void init() override
Initializes the partial benchmark members.
#define IOS_MSG_DONE
#define IOS_MSG_INFO
DataType
Defines data types for a workload.
Definition: types.h:379
Category category
Category for the benchmark.
Definition: types.h:531
@ SimpleSetIntersection
Definition: types.h:268
Defines a benchmark test.
Definition: types.h:527
bool validateResult(IDataLoader::Ptr dataset, const std::uint64_t *param_data_pack_indices, const std::vector< hebench::APIBridge::NativeDataBuffer * > &p_outputs, std::uint64_t k_count, hebench::APIBridge::DataType data_type)