Geant4-11
G4UniformRandPool.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28// G4UniformRandPool implementation
29//
30// Author: A.Dotti (SLAC)
31// ------------------------------------------------------------
32
33#include "G4UniformRandPool.hh"
34#include "G4AutoDelete.hh"
35#include "G4Threading.hh"
36#include "globals.hh"
37
38#include <algorithm>
39#include <climits>
40#include <cstring>
41#include <stdlib.h>
42
43// Not aligned memory
44//
46
47void destroy_pool(G4double*& buffer) { delete[] buffer; }
48
49#if defined(WIN32)
50// No bother with WIN
53
54#else
55
56// Align memory pools
57// Assumption is: static_assert(sizeof(G4double)*CHAR_BIT==64)
58//
60{
61 // POSIX standard way
62 G4int errcode = posix_memalign((void**) &buffer, sizeof(G4double) * CHAR_BIT,
63 ps * sizeof(G4double));
64 if(errcode != 0)
65 {
66 G4Exception("G4UniformRandPool::create_pool_align()", "InvalidCondition",
67 FatalException, "Cannot allocate aligned buffer");
68 return;
69 }
70 return;
71}
72
74#endif
75
78 , buffer(0)
79 , currentIdx(0)
80{
81 if(sizeof(G4double) * CHAR_BIT == 64)
82 {
84 }
85 else
86 {
88 }
89 Fill(size);
90}
91
93 : size(siz)
94 , buffer(0)
95 , currentIdx(0)
96{
97 if(sizeof(G4double) * CHAR_BIT == 64)
98 {
100 }
101 else
102 {
104 }
105 Fill(size);
106}
107
109{
110 if(sizeof(G4double) * CHAR_BIT == 64)
111 {
113 }
114 else
115 {
117 }
118}
119
120void G4UniformRandPool::Resize(/*PoolSize_t*/ G4int newSize)
121{
122 if(newSize != size)
123 {
125 create_pool(buffer, newSize);
126 size = newSize;
127 currentIdx = 0;
128 }
129 currentIdx = 0;
130}
131
133{
134 assert(howmany > 0 && howmany <= size);
135
136 // Fill buffer with random numbers
137 //
138 G4Random::getTheEngine()->flatArray(howmany, buffer);
139 currentIdx = 0;
140}
141
143{
144 assert(rnds != 0 && howmany > 0);
145
146 // if ( howmany <= 0 ) return;
147 // We generate at max "size" numbers at once, and
148 // We do not want to use recursive calls (expensive).
149 // We need to deal with the case howmany>size
150 // So:
151 // how many times I need to get "size" numbers?
152
153 const G4int maxcycles = howmany / size;
154
155 // This is the rest
156 //
157 const G4int peel = howmany % size;
158 assert(peel < size);
159
160 // Ok from now on I will get random numbers in group of "size"
161 // Note that if howmany<size maxcycles == 0
162 //
163 G4int cycle = 0;
164
165 // Consider the case howmany>size, then maxcycles>=1
166 // and we will request at least "size" rng, so
167 // let's start with a fresh buffer of numbers if needed
168 //
169 if(maxcycles > 0 && currentIdx > 0)
170 {
171 assert(currentIdx <= size);
172 Fill(currentIdx); //<size?currentIdx:size);
173 }
174 for(; cycle < maxcycles; ++cycle)
175 {
176 // We can use memcpy of std::copy, it turns out that the two are basically
177 // performance-wise equivalent (expected), since in my tests memcpy is a
178 // little bit faster, I use that
179 //
180 memcpy(rnds + (cycle * size), buffer, sizeof(G4double) * size);
181 // std::copy(buffer,buffer+size,rnds+(cycle*size));
182
183 // Get a new set of numbers
184 //
185 Fill(size); // Now currentIdx is 0 again
186 }
187
188 // If maxcycles>0 last think we did was to call Fill(size)
189 // so currentIdx == 0
190 // and it is guaranteed that peel<size, we have enough fresh random numbers
191 // but if maxcycles==0 currentIdx can be whatever, let's make sure we have
192 // enough fresh numbers
193 //
194 if(currentIdx + peel >= size)
195 {
197 }
198 memcpy(rnds + (cycle * size), buffer + currentIdx, sizeof(G4double) * peel);
199 // std::copy(buffer+currentIdx,buffer+(currentIdx+peel), rnds+(cycle*size));
200
201 // Advance index, we are done
202 //
203 currentIdx += peel;
204 assert(currentIdx <= size);
205}
206
207// Static interfaces implementing CLHEP methods
208
209namespace
210{
212}
213
215{
216 if(rndpool == 0)
217 {
220 }
221 return rndpool->GetOne();
222}
223
225{
226 if(rndpool == 0)
227 {
230 }
231 rndpool->GetMany(rnds, (unsigned int) howmany);
232}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
static constexpr double ps
Definition: G4SIunits.hh:157
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
void create_pool(G4double *&buffer, G4int ps)
void destroy_pool_align(G4double *&buffer)
void create_pool_align(G4double *&buffer, G4int ps)
void destroy_pool(G4double *&buffer)
#define G4UNIFORMRANDPOOL_DEFAULT_POOLSIZE
void GetMany(G4double *rnds, G4int howMany)
static void flatArray(G4int howmany, G4double *rnds)
void Resize(G4int newSize)
void Fill(G4int howmany)
static G4double flat()
void Register(T *inst)
Definition: G4AutoDelete.hh:65
G4ThreadLocal G4UniformRandPool * rndpool
#define G4ThreadLocal
Definition: tls.hh:77
#define buffer
Definition: xmlparse.cc:628