ECCE @ EIC Software
Reference for
ECCE @ EIC
simulation and reconstruction software on GitHub
Home page
Related Pages
Modules
Namespaces
Classes
Files
External Links
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
G4UniformRandPool.cc
Go to the documentation of this file.
Or view
the newest version in sPHENIX GitHub for file G4UniformRandPool.cc
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 "
globals.hh
"
35
#include "
G4Threading.hh
"
36
#include "
G4AutoDelete.hh
"
37
38
#include <climits>
39
#include <stdlib.h>
40
#include <algorithm>
41
#include <cstring>
42
43
// Not aligned memory
44
//
45
void
create_pool
(
G4double
*&
buffer
,
G4int
ps
)
46
{
47
buffer =
new
G4double
[
ps
];
48
}
49
50
void
destroy_pool
(
G4double
*&
buffer
)
51
{
52
delete
[]
buffer
;
53
}
54
55
#if defined(WIN32)
56
// No bother with WIN
57
void
create_pool_align
(
G4double
*&
buffer
,
G4int
ps
)
58
{
59
create_pool
(buffer,ps);
60
}
61
void
destroy_pool_align
(
G4double
*&
buffer
)
62
{
63
destroy_pool
(buffer);
64
}
65
66
#else
67
68
// Align memory pools
69
// Assumption is: static_assert(sizeof(G4double)*CHAR_BIT==64)
70
//
71
void
create_pool_align
(
G4double
*&
buffer
,
G4int
ps
)
72
{
73
// POSIX standard way
74
G4int
errcode = posix_memalign( (
void
**) &buffer ,
75
sizeof
(
G4double
)*CHAR_BIT,
76
ps*
sizeof
(
G4double
));
77
if
( errcode != 0 )
78
{
79
G4Exception
(
"G4UniformRandPool::create_pool_align()"
,
80
"InvalidCondition"
,
FatalException
,
81
"Cannot allocate aligned buffer"
);
82
return
;
83
}
84
return
;
85
}
86
87
void
destroy_pool_align
(
G4double
*&
buffer
)
88
{
89
free(buffer);
90
}
91
#endif
92
93
G4UniformRandPool::G4UniformRandPool
()
94
: size(
G4UNIFORMRANDPOOL_DEFAULT_POOLSIZE
),
buffer
(0), currentIdx(0)
95
{
96
if
(
sizeof
(
G4double
)*CHAR_BIT==64 )
97
{
98
create_pool_align
(
buffer
,
size
);
99
}
100
else
101
{
102
create_pool
(
buffer
,
size
);
103
}
104
Fill
(
size
);
105
}
106
107
G4UniformRandPool::G4UniformRandPool
(
G4int
siz )
108
: size(siz),
buffer
(0), currentIdx(0)
109
{
110
if
(
sizeof
(
G4double
)*CHAR_BIT==64 )
111
{
112
create_pool_align
(
buffer
,
size
);
113
}
114
else
115
{
116
create_pool
(
buffer
,
size
);
117
}
118
Fill
(
size
);
119
120
}
121
122
G4UniformRandPool::~G4UniformRandPool
()
123
{
124
if
(
sizeof
(
G4double
)*CHAR_BIT==64 )
125
{
126
destroy_pool_align
(
buffer
);
127
}
128
else
129
{
130
destroy_pool
(
buffer
);
131
}
132
}
133
134
void
G4UniformRandPool::Resize
(
/*PoolSize_t*/
G4int
newSize )
135
{
136
if
( newSize !=
size
)
137
{
138
destroy_pool
(
buffer
);
139
create_pool
(
buffer
,newSize);
140
size
=newSize;
141
currentIdx
= 0;
142
}
143
currentIdx
= 0;
144
}
145
146
void
G4UniformRandPool::Fill
(
G4int
howmany )
147
{
148
assert(howmany>0 && howmany <=
size
);
149
150
// Fill buffer with random numbers
151
//
152
G4Random::getTheEngine()->flatArray(howmany,
buffer
);
153
currentIdx
= 0;
154
}
155
156
void
G4UniformRandPool::GetMany
(
G4double
* rnds ,
G4int
howmany )
157
{
158
assert(rnds!=0 && howmany>0);
159
160
// if ( howmany <= 0 ) return;
161
// We generate at max "size" numbers at once, and
162
// We do not want to use recursive calls (expensive).
163
// We need to deal with the case howmany>size
164
// So:
165
// how many times I need to get "size" numbers?
166
167
const
G4int
maxcycles = howmany/
size
;
168
169
// This is the rest
170
//
171
const
G4int
peel = howmany%
size
;
172
assert(peel<
size
);
173
174
// Ok from now on I will get random numbers in group of "size"
175
// Note that if howmany<size maxcycles == 0
176
//
177
G4int
cycle = 0;
178
179
// Consider the case howmany>size, then maxcycles>=1
180
// and we will request at least "size" rng, so
181
// let's start with a fresh buffer of numbers if needed
182
//
183
if
( maxcycles>0 &&
currentIdx
>0 )
184
{
185
assert(
currentIdx
<=
size
);
186
Fill
(
currentIdx
);
//<size?currentIdx:size);
187
}
188
for
( ; cycle < maxcycles ; ++cycle )
189
{
190
// We can use memcpy of std::copy, it turns out that the two are basically
191
// performance-wise equivalent (expected), since in my tests memcpy is a
192
// little bit faster, I use that
193
//
194
memcpy(rnds+(cycle*
size
),
buffer
,
sizeof
(
G4double
)*size );
195
// std::copy(buffer,buffer+size,rnds+(cycle*size));
196
197
// Get a new set of numbers
198
//
199
Fill
(size);
// Now currentIdx is 0 again
200
}
201
202
// If maxcycles>0 last think we did was to call Fill(size)
203
// so currentIdx == 0
204
// and it is guaranteed that peel<size, we have enough fresh random numbers
205
// but if maxcycles==0 currentIdx can be whatever, let's make sure we have
206
// enough fresh numbers
207
//
208
if
(
currentIdx
+ peel >=
size
)
209
{
210
Fill
(
currentIdx
<
size
?
currentIdx
:
size
);
211
}
212
memcpy(rnds+(cycle*
size
) ,
buffer
+
currentIdx
,
sizeof
(
G4double
)*peel );
213
// std::copy(buffer+currentIdx,buffer+(currentIdx+peel), rnds+(cycle*size));
214
215
// Advance index, we are done
216
//
217
currentIdx
+=peel;
218
assert(
currentIdx
<=size);
219
}
220
221
// Static interfaces implementing CLHEP methods
222
223
namespace
224
{
225
G4ThreadLocal
G4UniformRandPool
* rndpool = 0;
226
}
227
228
G4double
G4UniformRandPool::flat
()
229
{
230
if
( rndpool == 0 )
231
{
232
rndpool =
new
G4UniformRandPool
;
233
G4AutoDelete::Register
(rndpool);
234
}
235
return
rndpool->GetOne();
236
}
237
238
void
G4UniformRandPool::flatArray
(
G4int
howmany,
G4double
*rnds)
239
{
240
if
( rndpool == 0 )
241
{
242
rndpool =
new
G4UniformRandPool
;
243
G4AutoDelete::Register
(rndpool);
244
}
245
rndpool->GetMany(rnds,(
unsigned
int
)howmany);
246
}
geant4
tree
geant4-10.6-release
source
global
HEPRandom
src
G4UniformRandPool.cc
Built by
Jin Huang
. updated:
Wed Jun 29 2022 17:25:21
using
1.8.2 with
ECCE GitHub integration