HEBench
hebench_simple_set_intersection.h
Go to the documentation of this file.
1 
2 // Copyright (C) 2021 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef _HEBench_Harness_DataGenerator_DotProduct_H_0596d40a3cce4b108a81595c50eb286d
6 #define _HEBench_Harness_DataGenerator_DotProduct_H_0596d40a3cce4b108a81595c50eb286d
7 
8 #include <algorithm>
9 #include <array>
10 #include <memory>
11 #include <random>
12 #include <utility>
13 #include <vector>
14 
15 #include "hebench/modules/general/include/hebench_math_utils.h"
16 #include "hebench/modules/general/include/nocopy.h"
17 #include "hebench/modules/logging/include/logging.h"
18 
20 
23 
24 namespace hebench {
25 namespace TestHarness {
27 
29 {
30 public:
31  DISABLE_COPY(BenchmarkDescriptorCategory)
32  DISABLE_MOVE(BenchmarkDescriptorCategory)
33 private:
34  IL_DECLARE_CLASS_NAME(DotProduct::BenchmarkDescriptorCategory)
35 public:
36  static constexpr const char *BaseWorkloadName = "Simple Set Intersection";
37  static constexpr std::uint64_t WorkloadParameterCount = 3; // number of parameters for this workload
38  static constexpr std::uint64_t OpParameterCount = 2; // number of parameters for this operation
39  static constexpr std::uint64_t OpResultCount = 1; // number of outputs for this operation
41 
42  static std::array<std::uint64_t, BenchmarkDescriptorCategory::WorkloadParameterCount> fetchSetSize(const std::vector<hebench::APIBridge::WorkloadParam> &w_params);
43 
44 public:
46  ~BenchmarkDescriptorCategory() override = default;
47 
48 protected:
50  const std::vector<hebench::APIBridge::WorkloadParam> &w_params) const override;
52  const Engine &engine,
53  const BenchmarkDescription::Backend &backend_desc,
54  const BenchmarkDescription::Configuration &config) const override;
55 };
56 
58 {
59 public:
60  DISABLE_COPY(DataLoader)
61  DISABLE_MOVE(DataLoader)
62 private:
63  IL_DECLARE_CLASS_NAME(DotProduct::DataLoader)
64 
65 public:
66  typedef std::shared_ptr<DataLoader> Ptr;
67 
68  static DataLoader::Ptr create(std::uint64_t set_size_x,
69  std::uint64_t set_size_y,
70  std::uint64_t batch_size_x,
71  std::uint64_t batch_size_y,
72  std::uint64_t element_size_k,
74  static DataLoader::Ptr create(std::uint64_t set_size_x,
75  std::uint64_t set_size_y,
76  std::uint64_t batch_size_x,
77  std::uint64_t batch_size_y,
78  std::uint64_t element_size_k,
80  const std::string &dataset_filename);
81 
82  ~DataLoader() override {}
83 
84 protected:
85  void computeResult(std::vector<hebench::APIBridge::NativeDataBuffer *> &result,
86  const std::uint64_t *param_data_pack_indices,
87  hebench::APIBridge::DataType data_type) override;
88 
89 private:
90  static constexpr std::size_t InputDim0 = BenchmarkDescriptorCategory::OpParameterCount;
91  static constexpr std::size_t OutputDim0 = BenchmarkDescriptorCategory::OpResultCount;
92  std::uint64_t m_set_size_x;
93  std::uint64_t m_set_size_y;
94  std::uint64_t m_element_size_k;
95 
96  DataLoader();
97  void init(std::uint64_t set_size_x,
98  std::uint64_t set_size_y,
99  std::uint64_t batch_size_x,
100  std::uint64_t batch_size_y,
101  std::uint64_t element_size_k,
102  hebench::APIBridge::DataType data_type);
103  void init(std::uint64_t set_size_x,
104  std::uint64_t set_size_y,
105  std::uint64_t batch_size_x,
106  std::uint64_t batch_size_y,
107  std::uint64_t element_size_k,
109  const std::string &dataset_filename);
110 };
111 
112 template <typename T>
124 typename std::enable_if<std::is_integral<T>::value
125  || std::is_floating_point<T>::value,
126  std::vector<std::pair<bool, std::uint64_t>>>::type
127 almostEqualSet(const T *X, const T *Y,
128  std::uint64_t n, std::uint64_t m, std::uint64_t k,
129  double pct = 0.05);
130 
131 template <typename T>
142 typename std::enable_if<std::is_integral<T>::value
143  || std::is_floating_point<T>::value,
144  bool>::type
145 isMemberOf(const T *dataset, const T *value, std::size_t n, std::size_t k,
146  double pct = 0.05);
147 
148 bool validateResult(IDataLoader::Ptr dataset,
149  const std::uint64_t *param_data_pack_indices,
150  const std::vector<hebench::APIBridge::NativeDataBuffer *> &p_outputs,
151  std::uint64_t k_count,
152  hebench::APIBridge::DataType data_type);
153 
154 // Simple Set Intersection inline impl.
155 
156 template <typename T>
157 typename std::enable_if<std::is_integral<T>::value
158  || std::is_floating_point<T>::value,
159  bool>::type
160 isMemberOf(const T *dataset, const T *value, std::size_t n, std::size_t k,
161  double pct)
162 {
163  bool retval = false;
164  for (size_t i = 0; !retval && i < n; ++i)
165  {
166  std::uint64_t members = 0;
167  bool flag = true;
168  for (size_t j = 0; flag && j < k; ++j)
169  {
170  flag = hebench::Utilities::Math::almostEqual(dataset[(i * k) + j], value[j], pct);
171  if (flag)
172  {
173  ++members;
174  }
175  }
176  retval = members == k;
177  }
178  return retval;
179 }
180 
181 template <typename T>
182 typename std::enable_if<std::is_integral<T>::value
183  || std::is_floating_point<T>::value,
184  std::vector<std::pair<bool, std::uint64_t>>>::type
185 almostEqualSet(const T *X, const T *Y,
186  std::uint64_t n, std::uint64_t m, std::uint64_t k,
187  double pct)
188 {
189  std::vector<std::pair<bool, std::uint64_t>> retval;
190  retval.reserve(n + m);
191  if (X != Y)
192  {
193  if (!X)
194  {
195  // X has no elements
196  for (std::uint64_t i = 0; i < m; ++i)
197  retval.push_back(std::pair(false, i));
198  } // end if
199  else if (!Y)
200  {
201  // Y has no elements
202  for (std::uint64_t i = 0; i < n; ++i)
203  retval.push_back(std::pair(true, i));
204  } // end else if
205  else
206  {
207  // check if X c Y
208  for (std::uint64_t i = 0; i < n; ++i)
209  {
210  if (!isMemberOf(Y, X + (i * k), m, k, pct))
211  retval.push_back(std::pair(true, i));
212  } // end for
213  // check if Y c X
214  for (std::uint64_t i = 0; i < m; ++i)
215  {
216  if (!isMemberOf(X, Y + (i * k), n, k, pct))
217  retval.push_back(std::pair(false, i));
218  } // end for
219  // if retval.empty(), then X == Y
220  } // end else
221  } // end if
222  return retval;
223 }
224 
225 } // namespace SimpleSetIntersection
226 } // namespace TestHarness
227 } // namespace hebench
228 
229 #endif // defined _HEBench_Harness_DataGenerator_DotProduct_H_0596d40a3cce4b108a81595c50eb286d
std::shared_ptr< IDataLoader > Ptr
Provides boilerplate implementation to common methods of interface IBenchmarkDescription and implemen...
Bundles values that need to be filled by a workload during completeWorkloadDescription().
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)
static hebench::APIBridge::WorkloadParamType::WorkloadParamType WorkloadParameterType[WorkloadParameterCount]
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...
void computeResult(std::vector< hebench::APIBridge::NativeDataBuffer * > &result, const std::uint64_t *param_data_pack_indices, hebench::APIBridge::DataType data_type) override
Computes result of the operation on the input data given the of the input sample.
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)
WorkloadParamType
Defines the possible data types for a workload flexible parameter.
Definition: types.h:303
DataType
Defines data types for a workload.
Definition: types.h:379
@ SimpleSetIntersection
Definition: types.h:268
Defines a benchmark test.
Definition: types.h:527
std::enable_if< std::is_integral< T >::value||std::is_floating_point< T >::value, bool >::type isMemberOf(const T *dataset, const T *value, std::size_t n, std::size_t k, double pct=0.05)
Finds whether values in two arrays are within a certain percentage of each other.
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)
std::enable_if< std::is_integral< T >::value||std::is_floating_point< T >::value, std::vector< std::pair< bool, std::uint64_t > > >::type almostEqualSet(const T *X, const T *Y, std::uint64_t n, std::uint64_t m, std::uint64_t k, double pct=0.05)
Finds whether values in two arrays are within a certain percentage of each other.