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