CORSIKA  @c8_version@
The framework to simulate particle cascades for astroparticle physics
Stream.hpp
1 /*
2  * (c) Copyright 2021 CORSIKA Project, corsika-project@lists.kit.edu
3  *
4  * This software is distributed under the terms of the GNU General Public
5  * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
6  * the license.
7  */
8 
9 /*
10  * Stream.hpp
11  *
12  * Created on: 23/02/2021
13  * Author: Antonio Augusto Alves Junior
14  */
15 
16 #pragma once
17 
18 #include <stdint.h>
19 
20 #include "detail/tbb/iterators.h"
21 #include "detail/Engine.hpp"
22 #include "detail/functors/EngineCaller.hpp"
23 
24 namespace random_iterator {
25 
27  typedef detail::philox philox;
29  typedef detail::threefry threefry;
31  typedef detail::squares3_128 squares3_128;
33  typedef detail::squares4_128 squares4_128;
35  typedef detail::squares3_64 squares3_64;
37  typedef detail::squares4_64 squares4_64;
38 
39 #if RANDOM_ITERATOR_R123_USE_AES_NI
40  typedef detail::ars ars;
42 #endif
43 
107  template <typename DistibutionType, typename EngineType>
108  class Stream {
109  typedef detail::EngineCaller<DistibutionType, EngineType> caller_type;
110  typedef random_iterator_tbb::counting_iterator<typename EngineType::advance_type>
111  counting_iterator;
112 
113  public:
114  typedef EngineType engine_type;
115  typedef typename engine_type::state_type state_type;
116  typedef typename engine_type::seed_type seed_type;
117  typedef typename engine_type::advance_type advance_type;
118  typedef typename engine_type::init_type init_type;
119 
120  typedef DistibutionType distribution_type;
121  typedef typename distribution_type::result_type result_type;
122 
123  typedef random_iterator_tbb::transform_iterator<caller_type, counting_iterator>
124  iterator;
125 
126  Stream() = delete;
127 
135  Stream(distribution_type const& distribution, seed_type seed, uint32_t stream = 0)
136  : distribution_(distribution)
137  , engine_(seed, stream)
138  , seed_(seed)
139  , stream_(stream) {}
140 
146  Stream(Stream<DistibutionType, EngineType> const& other)
147  : distribution_(other.getDistribution())
148  , engine_(other.getEngine())
149  , seed_(other.getSeed())
150  , stream_(other.getStream()) {}
151 
156  inline iterator begin() const {
157 
158  counting_iterator first(0);
159  caller_type caller(distribution_, seed_, stream_);
160 
161  return iterator(first, caller);
162  }
163 
168  inline iterator end() const {
169 
170  counting_iterator last(std::numeric_limits<advance_type>::max());
171  caller_type caller(distribution_, seed_, stream_);
172 
173  return iterator(last, caller);
174  }
175 
182  inline result_type operator[](advance_type n) const {
183 
184  caller_type caller(distribution_, seed_, stream_);
185 
186  return caller(n);
187  }
188 
195  inline result_type operator()(void) { return distribution_(engine_); }
196 
202  inline distribution_type getDistribution() const { return distribution_; }
203 
209  inline void setDistribution(distribution_type dist) { distribution_ = dist; }
210 
216  inline engine_type getEngine() const { return engine_; }
217 
223  inline void setEngine(engine_type engine) { engine_ = engine; }
224 
230  inline const seed_type& getSeed() const { return seed_; }
231 
237  inline void setSeed(const seed_type& seed) { seed_ = seed; }
238 
244  inline uint32_t getStream() const { return stream_; }
245 
251  inline void setStream(uint32_t stream) { stream_ = stream; }
252 
253  friend inline std::ostream& operator<<(
254  std::ostream& os, const Stream<DistibutionType, EngineType>& be) {
255  return os << "engine: " << be.getEngine() << " stream: " << be.getStream()
256  << " distribution: " << be.getDistribution();
257  }
258 
259  private:
260  distribution_type distribution_;
261  engine_type engine_;
262  seed_type seed_;
263  uint32_t stream_;
264  };
265 
274  template <typename DistibutionType, typename EngineType>
275  Stream<DistibutionType, EngineType> make_stream(DistibutionType const& dist,
276  EngineType eng, uint32_t stream) {
277 
278  return Stream<DistibutionType, EngineType>(dist, eng.getSeed(), stream);
279  }
280 
281 } // namespace random_iterator
std::ostream & operator<<(std::ostream &, corsika::Code)
Code output operator.