HEBench
datagen_helper.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 <algorithm>
6 #include <cassert>
7 #include <chrono>
8 #include <iostream>
9 #include <stdexcept>
10 
11 #include "../include/datagen_helper.h"
13 
14 namespace hebench {
15 namespace TestHarness {
16 
17 std::mutex DataGeneratorHelper::m_mtx_rand;
18 
19 //-------------------------
20 // class DataLoaderCompute
21 //-------------------------
22 
23 IDataLoader::ResultDataPtr DataLoaderCompute::getResultFor(const std::uint64_t *param_data_pack_indices)
24 {
25  if (!this->isInitialized())
26  throw std::logic_error(IL_LOG_MSG_CLASS("Not initialized."));
27 
28  ResultDataPtr p_retval;
29 
30  if (this->hasResults())
31  {
32  p_retval = PartialDataLoader::getResultFor(param_data_pack_indices);
33  } // end if
34  else
35  {
36  std::uint64_t r_i = getResultIndex(param_data_pack_indices);
37  std::shared_ptr<std::vector<std::shared_ptr<hebench::APIBridge::DataPack>>> p_tmp_packs =
38  std::make_shared<std::vector<std::shared_ptr<hebench::APIBridge::DataPack>>>(getResultTempDataPacks());
39  std::vector<std::shared_ptr<hebench::APIBridge::DataPack>> &tmp_packs = *p_tmp_packs;
40  // point to the `NativeDataBuffer`s to contain the result
41  std::vector<hebench::APIBridge::NativeDataBuffer *> result(tmp_packs.size());
42  for (std::size_t result_component_i = 0; result_component_i < result.size(); ++result_component_i)
43  {
44  assert(tmp_packs[result_component_i]
45  && tmp_packs[result_component_i]->buffer_count > 0
46  && tmp_packs[result_component_i]->p_buffers
47  && tmp_packs[result_component_i]->p_buffers[0].p
48  && tmp_packs[result_component_i]->p_buffers[0].size > 0);
49  result[result_component_i] = &(tmp_packs[result_component_i]->p_buffers[0]);
50  } // end for
51  // compute result and store in the pre-allocated buffers
52  computeResult(result, param_data_pack_indices, getDataType());
53 
54  p_retval = ResultDataPtr(new ResultData());
55  p_retval->result.assign(result.begin(), result.end()); // pointers to pre-allocated data
56  p_retval->sample_index = r_i;
57  p_retval->reserved0 = p_tmp_packs; // pre-allocated data as a RAII
58  } // end if
59 
60  return p_retval;
61 }
62 
63 //---------------------------
64 // class DataGeneratorHelper
65 //---------------------------
66 
67 template <class T>
68 inline void DataGeneratorHelper::generateRandomVectorU(T *result, std::uint64_t elem_count,
69  T min_val, T max_val)
70 {
71  std::uniform_real_distribution<double> rnd(min_val, max_val);
72  for (std::uint64_t i = 0; i < elem_count; ++i)
73  {
74  std::lock_guard<std::mutex> lock(m_mtx_rand);
75  result[i] = static_cast<T>(rnd(hebench::Utilities::RandomGenerator::get()));
76  } // end for
77 }
78 
79 template <class T>
80 inline void DataGeneratorHelper::generateRandomVectorN(T *result, std::uint64_t elem_count,
81  T mean, T stddev)
82 {
83  std::normal_distribution<double> rnd(mean, stddev);
84  for (std::uint64_t i = 0; i < elem_count; ++i)
85  {
86  std::lock_guard<std::mutex> lock(m_mtx_rand);
87  result[i] = static_cast<T>(rnd(hebench::Utilities::RandomGenerator::get()));
88  } // end for
89 }
90 
92  void *result, std::uint64_t elem_count,
93  double min_val, double max_val)
94 {
95  switch (data_type)
96  {
98  generateRandomVectorU<std::int32_t>(reinterpret_cast<std::int32_t *>(result), elem_count,
99  static_cast<std::int32_t>(min_val), static_cast<std::int32_t>(max_val));
100  break;
101 
103  generateRandomVectorU<std::int64_t>(reinterpret_cast<std::int64_t *>(result), elem_count,
104  static_cast<std::int64_t>(min_val), static_cast<std::int64_t>(max_val));
105  break;
106 
108  generateRandomVectorU<float>(reinterpret_cast<float *>(result), elem_count,
109  static_cast<float>(min_val), static_cast<float>(max_val));
110  break;
111 
113  generateRandomVectorU<double>(reinterpret_cast<double *>(result), elem_count,
114  static_cast<double>(min_val), static_cast<double>(max_val));
115  break;
116 
117  default:
118  throw std::invalid_argument(IL_LOG_MSG_CLASS("Unknown data type."));
119  break;
120  } // end switch
121 }
122 
124  void *result, std::uint64_t elem_count,
125  double mean, double stddev)
126 {
127  switch (data_type)
128  {
130  generateRandomVectorN<std::int32_t>(reinterpret_cast<std::int32_t *>(result), elem_count,
131  static_cast<std::int32_t>(mean), static_cast<std::int32_t>(stddev));
132  break;
133 
135  generateRandomVectorN<std::int64_t>(reinterpret_cast<std::int64_t *>(result), elem_count,
136  static_cast<std::int64_t>(mean), static_cast<std::int64_t>(stddev));
137  break;
138 
140  generateRandomVectorN<float>(reinterpret_cast<float *>(result), elem_count,
141  static_cast<float>(mean), static_cast<float>(stddev));
142  break;
143 
145  generateRandomVectorN<double>(reinterpret_cast<double *>(result), elem_count,
146  static_cast<double>(mean), static_cast<double>(stddev));
147  break;
148 
149  default:
150  throw std::invalid_argument(IL_LOG_MSG_CLASS("Unknown data type."));
151  break;
152  } // end switch
153 }
154 
155 std::uint64_t DataGeneratorHelper::generateRandomIntU(std::uint64_t min_val, std::uint64_t max_val)
156 {
157  std::uniform_int_distribution<std::uint64_t> rnd(min_val, max_val);
159 }
160 
161 std::vector<std::uint64_t> DataGeneratorHelper::generateRandomIntersectionIndicesU(std::uint64_t elem_count, std::uint64_t indices_count)
162 {
163  std::vector<std::uint64_t> retval;
164 
165  if (indices_count <= 0)
166  indices_count = generateRandomIntU(0, elem_count - 1);
167 
168  retval.resize(elem_count);
169  std::iota(retval.begin(), retval.end(), 0);
170  std::shuffle(retval.begin(), retval.end(), hebench::Utilities::RandomGenerator::get());
171 
172  return std::vector<std::uint64_t>(retval.begin(), retval.begin() + indices_count);
173 }
174 
175 } // namespace TestHarness
176 } // namespace hebench
static std::vector< std::uint64_t > generateRandomIntersectionIndicesU(std::uint64_t elem_count, std::uint64_t indices_count=0)
Generates uniform random amount of indices.
static std::uint64_t generateRandomIntU(std::uint64_t min_val, std::uint64_t max_val)
static void generateRandomVectorN(hebench::APIBridge::DataType data_type, void *result, std::uint64_t elem_count, double mean, double stddev)
Generates normally distributed random data of the specified type.
static void generateRandomVectorU(hebench::APIBridge::DataType data_type, void *result, std::uint64_t elem_count, double min_val, double max_val)
Generates uniform random data of the specified type.
virtual void computeResult(std::vector< hebench::APIBridge::NativeDataBuffer * > &result, const std::uint64_t *param_data_pack_indices, hebench::APIBridge::DataType data_type)=0
Computes result of the operation on the input data given the of the input sample.
ResultDataPtr getResultFor(const std::uint64_t *param_data_pack_indices) override
getResultFor
std::shared_ptr< ResultData > ResultDataPtr
ResultDataPtr getResultFor(const std::uint64_t *param_data_pack_indices) override
getResultFor
bool hasResults() const
Retrieves whether buffers to contain output data have been allocated or not.
std::vector< std::shared_ptr< hebench::APIBridge::DataPack > > getResultTempDataPacks() const
Retrieves a pre-allocated result providing memory space to store a single operation result sample.
hebench::APIBridge::DataType getDataType() const
std::uint64_t getResultIndex(const std::uint64_t *param_data_pack_indices) const override
Computes the index of the result NativeDataBuffer given the indices of the input data.
@ Float64
64 bits IEEE 754 standard floating point real numbers.
Definition: types.h:306
@ Int64
64 bits signed integers.
Definition: types.h:304
DataType
Defines data types for a workload.
Definition: types.h:379
@ Float32
32 bits IEEE 754 standard floating point real numbers.
Definition: types.h:382
@ Int32
32 bits signed integers.
Definition: types.h:380