openPMD-api
RandomDatasetFiller.hpp
1 /* Copyright 2018-2021 Franz Poeschel
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #pragma once
23 
24 #include "openPMD/Dataset.hpp"
25 #include "openPMD/benchmark/mpi/DatasetFiller.hpp"
26 #include <memory>
27 #include <random>
28 
29 namespace openPMD
30 {
31 template <typename Distr, typename T = typename Distr::result_type>
33 {
34 
35 private:
36  Distr distr;
37  std::default_random_engine engine;
38  std::shared_ptr<T> buffered;
39 
40 public:
41  using resultType = T;
42 
43  explicit RandomDatasetFiller(
44  Distr distribution, Extent::value_type numOfItems = 0)
45  : DatasetFiller<T>(numOfItems), distr(distribution)
46  {}
47 
48  std::shared_ptr<T> produceData() override
49  {
50  if (this->buffered)
51  {
52  return buffered;
53  }
54  auto res = std::shared_ptr<T>{
55  new T[this->m_numberOfItems], [](T *d) { delete[] d; }};
56  auto ptr = res.get();
57  for (typename Extent::value_type i = 0; i < this->m_numberOfItems; i++)
58  {
59  ptr[i] = this->distr(this->engine);
60  }
61  return res;
62  }
63 
75  template <typename X = Distr>
77  Extent::value_type numberOfItems,
78  typename X::result_type lower,
79  typename X::result_type upper)
80  {
81  return RandomDatasetFiller<X>(X(lower, upper), numberOfItems);
82  }
83 
84  void setSeed(std::default_random_engine::result_type seed)
85  {
86  this->engine = std::default_random_engine(seed);
87  }
88 
89  void randomSeed()
90  {
91  std::random_device rd;
92  this->engine = std::default_random_engine(rd());
93  }
94 
99  void bufferMode()
100  {
101  if (!this->buffered)
102  {
103  this->buffered = this->produceData();
104  }
105  }
106 
107  void setNumberOfItems(Extent::value_type numItems) override
108  {
109  this->m_numberOfItems = numItems;
110  if (this->buffered)
111  {
112  this->buffered.reset();
113  this->buffered = this->produceData();
114  }
115  }
116 };
117 
118 } // namespace openPMD
An abstract class to create one iteration of data per thread.
Definition: DatasetFiller.hpp:35
static RandomDatasetFiller< X, T > makeRandomDatasetFiller(Extent::value_type numberOfItems, typename X::result_type lower, typename X::result_type upper)
Definition: RandomDatasetFiller.hpp:76
Definition: RandomDatasetFiller.hpp:32
std::shared_ptr< T > produceData() override
Create a shared pointer of m_numberOfItems items of type T.
Definition: RandomDatasetFiller.hpp:48
void setNumberOfItems(Extent::value_type numItems) override
Set number of items to be produced.
Definition: RandomDatasetFiller.hpp:107
Public definitions of openPMD-api.
void bufferMode()
Activate buffer mode.
Definition: RandomDatasetFiller.hpp:99