ATLAS Offline Software
Loading...
Searching...
No Matches
dSFMTEngine.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "CLHEP/Random/Random.h"
7#include "CLHEP/Random/engineIDulong.h"
9#include <cstring>
10#include <sstream>
11#include <cmath> // for ldexp()
12#include <stdlib.h> // for abs(int)
13
14extern "C" {
15#include "dSFMT.h"
16}
17
18// Let the thread-safety checker know that dsfmt functions are ok.
19namespace {
20int wrap_init_gen_rand ATLAS_NOT_THREAD_SAFE (dsfmt_t* dsfmt, long seed)
21{
22 dsfmt_init_gen_rand (dsfmt, seed);
23 return 0;
24}
25int wrap_init_by_array ATLAS_NOT_THREAD_SAFE (dsfmt_t* dsfmt,
26 const uint32_t* seeds,
27 int key_length)
28{
29 uint32_t* seeds_nc ATLAS_THREAD_SAFE = const_cast<uint32_t*> (seeds);
30 dsfmt_init_by_array (dsfmt, seeds_nc, key_length);
31 return 0;
32}
33}
34
35using namespace std;
36
37namespace CLHEP {
38
39static const int MarkerLen = 64; // Enough room to hold a begin or end marker.
40
41std::string dSFMTEngine::name() const {return "dSFMTEngine";}
42
43std::atomic<int> dSFMTEngine::numEngines = 0;
44
45const unsigned int VECTOR_STATE_SIZE = 2 + (DSFMT_N + 1)*4;
46
48{
49 init_dsfmt();
50
51 int engineNum = numEngines++;
52 int cycle = abs(int(engineNum/maxIndex));
53 int curIndex = abs(int(engineNum%maxIndex));
54 long mask = ((cycle & 0x007fffff) << 8);
55 long seedlist[2];
56 HepRandom::getTheTableSeeds( seedlist, curIndex );
57 seedlist[0] = (seedlist[0])^mask;
58 seedlist[1] = 0;
59 setSeeds( seedlist, engineNum );
60 for( int i=0; i < 2000; ++i ) dSFMTEngine::flat(); // Warm up just a bit
61}
62
64{
65 init_dsfmt();
66
67 dSFMTEngine::setSeed( seed , 0);
68 for( int i=0; i < 2000; ++i ) dSFMTEngine::flat(); // Warm up just a bit
69}
70
71dSFMTEngine::dSFMTEngine(const long * seeds):m_dsfmt(0)
72{
73 init_dsfmt();
74
75 dSFMTEngine::setSeeds( seeds, 0 );
76 for( int i=0; i < 2000; ++i ) dSFMTEngine::flat(); // Warm up just a bit
77}
78
80{
81 int err=posix_memalign((void**)&m_dsfmt,16,sizeof(dsfmt_t));
82 if(err!=0) {
83 std::stringstream errstring;
84 errstring << "dSFMTEngine::init_dsfmt() : could not allocate memory for dsfmt data structure, error=" << err;
85 throw std::runtime_error(errstring.str());
86 }
87 //cout<<"dSFMTEngine::init_dsfmt() ptr="<<m_dsfmt<<endl;
88}
89
91{
92 if(m_dsfmt) {
93 free(m_dsfmt);
94 m_dsfmt=0;
95 }
96}
97
99{
100 init_dsfmt();
101
102 *this = p;
103}
104
106 if( this != &p ) {
107 *m_dsfmt=*p.m_dsfmt;
108 }
109 return *this;
110}
111
113 double ret ATLAS_THREAD_SAFE = dsfmt_genrand_close_open(m_dsfmt);
114 return ret;
115}
116
117void dSFMTEngine::flatArray( const int size, double *vect ) {
118 for( int i=0; i < size; ++i) vect[i] = flat();
119}
120
121void dSFMTEngine::setSeed(long seed, int) {
122 //std::cout<<"dSFMTEngine::setSeed seed="<<seed<<endl;
123 int dum ATLAS_THREAD_SAFE [[maybe_unused]] = wrap_init_gen_rand(m_dsfmt,seed);
124}
125
126void dSFMTEngine::setSeeds(const uint32_t *seeds, int) {
127 //std::cout<<"dSFMTEngine::setSeeds"<<endl;
128 if (*seeds) {
129 int i = 0;
130 const int numBuff=DSFMT_N;
131 while (i < numBuff && seeds[i]) {
132 //cout<<" seed "<<i<<" = "<<seeds[i]<<endl;
133 ++i;
134 }
135 int dum ATLAS_THREAD_SAFE [[maybe_unused]] = wrap_init_by_array(m_dsfmt,seeds,i);
136 } else {
137 setSeed(1234567);
138 }
139}
140
141void dSFMTEngine::setSeeds(const long *seeds, int) {
142 //std::cout<<"dSFMTEngine::setSeeds"<<endl;
143 if (*seeds) {
144 int i = 0;
145 const int numBuff=DSFMT_N;
146 uint32_t buf[numBuff]{};
147 while (i < numBuff && seeds[i]) {
148 buf[i]=seeds[i];
149 ++i;
150 }
151 int dum ATLAS_THREAD_SAFE [[maybe_unused]] = wrap_init_by_array(m_dsfmt,buf,i);
152 } else {
153 setSeed(1234567);
154 }
155}
156
157void dSFMTEngine::saveStatus( const char filename[] ) const
158{
159 std::ofstream outFile( filename, std::ios::out ) ;
160 if (!outFile.bad()) {
161 outFile << m_dsfmt->idx << std::endl;
162 for (int i=0; i<DSFMT_N + 1; ++i) outFile <<std::setprecision(20)
163 << m_dsfmt->status[i].u32[0] << " " << m_dsfmt->status[i].u32[1] << " "
164 << m_dsfmt->status[i].u32[2] << " " << m_dsfmt->status[i].u32[3] << " ";
165 outFile << std::endl;
166 }
167}
168
169void dSFMTEngine::restoreStatus( const char filename[] )
170{
171 std::ifstream inFile( filename, std::ios::in);
172 if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
173 std::cerr << " -- Engine state remains unchanged\n";
174 return;
175 }
176
177 if (!inFile.bad() && !inFile.eof()) {
178 inFile >> m_dsfmt->idx;
179 for (int i=0; i<DSFMT_N + 1; ++i) inFile >> m_dsfmt->status[i].u32[0] >> m_dsfmt->status[i].u32[1]
180 >> m_dsfmt->status[i].u32[2] >> m_dsfmt->status[i].u32[3];
181 }
182}
183
185{
186 std::cout << "\n";
187 std::cout << "--------- dSFMT engine status ---------\n";
188 int pr = std::cout.precision();
189 std::cout.precision(20);
190 std::cout << " Current index = " << m_dsfmt->idx << "\n";
191 std::cout << " Array status[] = \n";
192 for (int i=0; i<DSFMT_N + 1; ++i) {
193 std::cout << m_dsfmt->status[i].u32[0] << " " << m_dsfmt->status[i].u32[1] << " "
194 << m_dsfmt->status[i].u32[2] << " " << m_dsfmt->status[i].u32[3] << "\n";
195 }
196 std::cout << "----------------------------------------" << std::endl;
197 std::cout.precision(pr);
198}
199
200dSFMTEngine::operator float() {
201 return (float)flat();
202}
203
204dSFMTEngine::operator unsigned int() {
205 return dsfmt_genrand_uint32(m_dsfmt);
206}
207
208std::ostream & dSFMTEngine::put ( std::ostream& os ) const
209{
210 char beginMarker[] = "dSFMTEngine-begin";
211 char endMarker[] = "dSFMTEngine-end";
212
213 int pr = os.precision(20);
214 os << " " << beginMarker << " ";
215 os << m_dsfmt->idx << " ";
216 for (int i=0; i<DSFMT_N + 1; ++i) {
217 os << m_dsfmt->status[i].u32[0] << "\n";
218 os << m_dsfmt->status[i].u32[1] << "\n";
219 os << m_dsfmt->status[i].u32[2] << "\n";
220 os << m_dsfmt->status[i].u32[3] << "\n";
221 }
222 os << endMarker << "\n";
223 os.precision(pr);
224 return os;
225}
226
227std::vector<unsigned long> dSFMTEngine::put () const {
228 std::vector<unsigned long> v;
229 v.push_back (engineIDulong<dSFMTEngine>());
230 v.push_back(m_dsfmt->idx);
231 for (int i=0; i<DSFMT_N + 1; ++i) {
232 v.push_back(static_cast<unsigned long>(m_dsfmt->status[i].u32[0]));
233 v.push_back(static_cast<unsigned long>(m_dsfmt->status[i].u32[1]));
234 v.push_back(static_cast<unsigned long>(m_dsfmt->status[i].u32[2]));
235 v.push_back(static_cast<unsigned long>(m_dsfmt->status[i].u32[3]));
236 }
237 return v;
238}
239
240std::istream & dSFMTEngine::get ( std::istream& is )
241{
242 char beginMarker [MarkerLen];
243 is >> std::ws;
244 is.width(MarkerLen); // causes the next read to the char* to be <=
245 // that many bytes, INCLUDING A TERMINATION \0
246 // (Stroustrup, section 21.3.2)
247 is >> beginMarker;
248 if (strcmp(beginMarker,"dSFMTEngine-begin")) {
249 is.clear(std::ios::badbit | is.rdstate());
250 std::cerr << "\nInput stream mispositioned or"
251 << "\ndSFMTEngine state description missing or"
252 << "\nwrong engine type found." << std::endl;
253 return is;
254 }
255 return getState(is);
256}
257
258std::string dSFMTEngine::beginTag ( ) {
259 return "dSFMTEngine-begin";
260}
261
262std::istream & dSFMTEngine::getState ( std::istream& is )
263{
264 char endMarker [MarkerLen];
265 is >> m_dsfmt->idx;
266
267 for (int i=0; i<DSFMT_N + 1; ++i) {
268 is >> m_dsfmt->status[i].u32[0] ;
269 is >> m_dsfmt->status[i].u32[1] ;
270 is >> m_dsfmt->status[i].u32[2] ;
271 is >> m_dsfmt->status[i].u32[3] ;
272 }
273
274 is >> std::ws;
275 is.width(MarkerLen);
276 is >> endMarker;
277 if (strcmp(endMarker,"dSFMTEngine-end")) {
278 is.clear(std::ios::badbit | is.rdstate());
279 std::cerr << "\ndSFMTEngine state description incomplete."
280 << "\nInput stream is probably mispositioned now." << std::endl;
281 return is;
282 }
283 return is;
284}
285
286bool dSFMTEngine::get (const std::vector<unsigned long> & v) {
287 if ((v[0] & 0xffffffffUL) != engineIDulong<dSFMTEngine>()) {
288 std::cerr <<
289 "\ndSFMTEngine get:state vector has wrong ID word - state unchanged\n";
290 return false;
291 }
292 return getState(v);
293}
294
295bool dSFMTEngine::getState (const std::vector<unsigned long> & v) {
296 if (v.size() != VECTOR_STATE_SIZE ) {
297 std::cerr <<
298 "\ndSFMTEngine get:state vector has wrong length - state unchanged\n";
299 return false;
300 }
301
302 m_dsfmt->idx=v[1];
303 for (int i=0; i<DSFMT_N + 1; ++i) {
304 m_dsfmt->status[i].u32[0]=v[2+i*4+0];
305 m_dsfmt->status[i].u32[1]=v[2+i*4+1];
306 m_dsfmt->status[i].u32[2]=v[2+i*4+2];
307 m_dsfmt->status[i].u32[3]=v[2+i*4+3];
308 }
309
310 return true;
311}
312
313} // namespace CLHEP
314
double cycle(double a, double b)
Define macros for attributes used to control the static checker.
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
#define ATLAS_THREAD_SAFE
virtual std::string name() const override
virtual std::istream & get(std::istream &is) override
static std::atomic< int > numEngines
Definition dSFMTEngine.h:90
void setSeeds(const uint32_t *seeds, int k=0)
static std::string engineName()
Definition dSFMTEngine.h:80
static constexpr int maxIndex
Definition dSFMTEngine.h:91
static std::string beginTag()
virtual void setSeed(long seed, int k=0) override
virtual void showStatus() const override
dSFMTEngine & operator=(const dSFMTEngine &p)
virtual void saveStatus(const char filename[]="MTwist.conf") const override
virtual void flatArray(const int size, double *vect) override
virtual double flat() override
virtual std::vector< unsigned long > put() const override
virtual std::istream & getState(std::istream &is) override
virtual void restoreStatus(const char filename[]="MTwist.conf") override
const unsigned int VECTOR_STATE_SIZE
static const int MarkerLen
STL namespace.
setEventNumber uint32_t