29#ifndef GRID_LATTICE_RNG_H
30#define GRID_LATTICE_RNG_H
35#include <Grid/sitmo_rng/sitmo_prng_engine.hpp>
39#define RNG_FAST_DISCARD
41#undef RNG_FAST_DISCARD
56 assert(lowerdims >= 0);
57 for(
int d=0;d<lowerdims;d++){
63 for(
int d=0;d<lowerdims;d++){
67 for(
int d=0;d<rngdims;d++){
89 for(
int d=0;d<lowerdims;d++) assert(fine->
_processors[d]==1);
103template<
class scalar,
class distribution,
class generator>
108template<
class distribution,
class generator>
115template<
class distribution,
class generator>
128 typedef std::ranlux48 RngEngine;
129 typedef uint64_t RngStateType;
130 static const int RngStateCount = 15;
133 typedef std::mt19937 RngEngine;
134 typedef uint32_t RngStateType;
135 static const int RngStateCount = std::mt19937::state_size;
138 typedef sitmo::prng_engine RngEngine;
139 typedef uint64_t RngStateType;
140 static const int RngStateCount = 13;
144 std::vector<std::uniform_real_distribution<RealD> >
_uniform;
145 std::vector<std::normal_distribution<RealD> >
_gaussian;
146 std::vector<std::discrete_distribution<int32_t> >
_bernoulli;
147 std::vector<std::uniform_int_distribution<uint32_t> >
_uid;
152#ifdef RNG_FAST_DISCARD
153 static void Skip(RngEngine &eng,uint64_t site)
171 const int shift = 30;
176 volatile uint64_t skip = site;
180 assert((skip >> shift)==site);
191 std::vector<uint32_t> newseed;
192 std::uniform_int_distribution<uint32_t> uid;
193 return Reseed(eng,newseed,uid);
195 static RngEngine
Reseed(RngEngine &eng,std::vector<uint32_t> & newseed,
196 std::uniform_int_distribution<uint32_t> &uid)
200 newseed.resize(reseeds);
201 for(
int i=0;i<reseeds;i++){
202 newseed[i] = uid(eng);
204 std::seed_seq sseq(newseed.begin(),newseed.end());
205 return RngEngine(sseq);
208 void GetState(std::vector<RngStateType> & saved,RngEngine &eng) {
209 saved.resize(RngStateCount);
210 std::stringstream ss;
213 for(
int i=0;i<RngStateCount;i++){
217 void GetState(std::vector<RngStateType> & saved,
int gen) {
220 void SetState(std::vector<RngStateType> & saved,RngEngine &eng){
221 assert(saved.size()==RngStateCount);
222 std::stringstream ss;
223 for(
int i=0;i<RngStateCount;i++){
229 void SetState(std::vector<RngStateType> & saved,
int gen){
238 template<
class source>
void Seed(source &src,
int gen)
249 _uniform.resize(1,std::uniform_real_distribution<RealD>{0,1});
250 _gaussian.resize(1,std::normal_distribution<RealD>(0.0,1.0) );
251 _bernoulli.resize(1,std::discrete_distribution<int32_t>{1,1});
252 _uid.resize(1,std::uniform_int_distribution<uint32_t>() );
255 template <
class sobj,
class distribution>
inline void fill(sobj &l,std::vector<distribution> &dist){
264 for(
int idx=0;idx<words;idx++){
272 template <
class distribution>
inline void fill(
ComplexF &l,std::vector<distribution> &dist){
277 template <
class distribution>
inline void fill(
ComplexD &l,std::vector<distribution> &dist){
282 template <
class distribution>
inline void fill(
RealF &l,std::vector<distribution> &dist){
287 template <
class distribution>
inline void fill(
RealD &l,std::vector<distribution> &dist){
293 template <
class distribution>
inline void fill(
vComplexF &l,std::vector<distribution> &dist){
301 template <
class distribution>
inline void fill(
vComplexD &l,std::vector<distribution> &dist){
309 template <
class distribution>
inline void fill(
vRealF &l,std::vector<distribution> &dist){
317 template <
class distribution>
inline void fill(
vRealD &l,std::vector<distribution> &dist){
328 std::seed_seq src(seeds.begin(),seeds.end());
333 std::vector<int> seeds;
334 std::stringstream sha;
336 for(
int i=0;i<seeds.size();i++) {
337 sha << std::hex << seeds[i];
339 std::cout <<
GridLogMessage <<
"Intialising serial RNG with unique string '"
340 << s <<
"'" << std::endl;
341 std::cout <<
GridLogMessage <<
"Seed SHA256: " << sha.str() << std::endl;
355 return is*
_grid->oSites()+os;
363 _uniform.resize(
_vol,std::uniform_real_distribution<RealD>{0,1});
364 _gaussian.resize(
_vol,std::normal_distribution<RealD>(0.0,1.0) );
366 _uid.resize(
_vol,std::uniform_int_distribution<uint32_t>() );
368 template <
class vobj,
class distribution>
inline void fill(
Lattice<vobj> &l,std::vector<distribution> &dist)
376 typedef typename vobj::scalar_object scalar_object;
378 typedef typename vobj::vector_type vector_type;
380 double inner_time_counter =
usecond();
383 int Nsimd =
_grid->Nsimd();
384 int osites =
_grid->oSites();
385 int words =
sizeof(scalar_object) /
sizeof(
scalar_type);
390 for (
int m = 0; m < multiplicity; m++) {
392 int sm = multiplicity * ss + m;
394 for (
int si = 0; si < Nsimd; si++) {
399 for (
int idx = 0; idx < words; idx++)
412 std::vector<int> seeds;
414 std::cout <<
GridLogMessage <<
"Intialising parallel RNG with unique string '"
415 << s <<
"'" << std::endl;
424 std::seed_seq source(seeds.begin(),seeds.end());
426 RngEngine master_engine(source);
428#ifdef RNG_FAST_DISCARD
445 _grid->LocalIndexToLocalCoor(lidx,lcoor);
446 pcoor=_grid->ThisProcessorCoor();
447 _grid->ProcessorCoorLocalCoorToGlobalCoor(pcoor,lcoor,gcoor);
448 _grid->GlobalCoorToGlobalIndex(gcoor,gidx);
450 _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor);
452 assert(rank == _grid->ThisRank() );
454 int l_idx=generator_idx(o_idx,i_idx);
455 _generators[l_idx] = master_engine;
457 Skip(_generators[l_idx],l_idx);
459 Skip(_generators[l_idx],gidx);
471 std::vector<RngEngine> seeders(Nproc);
473 for(
int p=0;p<Nproc;p++){
474 seeders[p] =
Reseed(master_engine);
476 master_engine = seeders[me];
482 std::vector<RngEngine> seeders(Nthread);
483 for(
int t=0;t<Nthread;t++){
484 seeders[t] =
Reseed(master_engine);
489 std::vector<uint32_t> newseeds;
490 std::uniform_int_distribution<uint32_t> uid;
491 for(
int l=0;l<
_grid->lSites();l++) {
492 if ( (l%Nthread)==t ) {
514 int rank,o_idx,i_idx;
516 _grid->GlobalIndexToGlobalCoor(gsite,gcoor);
517 _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor);
521 if( rank ==
_grid->ThisRank() ){
526 _grid->Broadcast(rank,(
void *)&the_number,
sizeof(the_number));
AcceleratorVector< int, MaxDims > Coordinate
Grid_simd< complex< float >, SIMD_Ftype > vComplexF
Grid_simd< float, SIMD_Ftype > vRealF
Grid_simd< complex< double >, SIMD_Dtype > vComplexD
Grid_simd< double, SIMD_Dtype > vRealD
void gaussian(GridParallelRNG &rng, Lattice< vobj > &l)
int RNGfillable(GridBase *coarse, GridBase *fine)
void fillScalar(scalar &s, distribution &dist, generator &gen)
void bernoulli(GridParallelRNG &rng, Lattice< vobj > &l)
int RNGfillable_general(GridBase *coarse, GridBase *fine)
void random(GridParallelRNG &rng, Lattice< vobj > &l)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
#define autoView(l_v, l, mode)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
std::complex< RealF > ComplexF
std::complex< RealD > ComplexD
static void generator(int lieIndex, iGroupMatrix< cplx > &ta, GroupName::Sp)
#define thread_for(i, num,...)
static void BroadcastWorld(int root, void *data, int bytes)
unsigned long _ndimension
static std::vector< int > sha256_seeds(const std::string &s)
static std::string sha256_string(const std::vector< T > &hash)
uint32_t GlobalU01(int gsite)
int generator_idx(int os, int is)
void SeedFixedIntegers(const std::vector< int > &seeds, int britney=0)
GridParallelRNG(GridBase *grid)
void fill(Lattice< vobj > &l, std::vector< distribution > &dist)
GridBase * Grid(void) const
void SeedUniqueString(const std::string &s)
void SetEngine(RngEngine &Eng, int gen)
void GetState(std::vector< RngStateType > &saved, int gen)
std::vector< std::discrete_distribution< int32_t > > _bernoulli
std::vector< RngEngine > _generators
std::vector< std::uniform_int_distribution< uint32_t > > _uid
void GetState(std::vector< RngStateType > &saved, RngEngine &eng)
void SetState(std::vector< RngStateType > &saved, RngEngine &eng)
static RngEngine Reseed(RngEngine &eng)
void SetState(std::vector< RngStateType > &saved, int gen)
std::vector< std::uniform_real_distribution< RealD > > _uniform
void GetEngine(RngEngine &Eng, int gen)
void Seed(source &src, int gen)
std::vector< std::normal_distribution< RealD > > _gaussian
static RngEngine Reseed(RngEngine &eng, std::vector< uint32_t > &newseed, std::uniform_int_distribution< uint32_t > &uid)
void fill(ComplexF &l, std::vector< distribution > &dist)
void fill(vComplexF &l, std::vector< distribution > &dist)
void fill(ComplexD &l, std::vector< distribution > &dist)
void fill(vRealD &l, std::vector< distribution > &dist)
void SeedUniqueString(const std::string &s)
void fill(RealF &l, std::vector< distribution > &dist)
void fill(vComplexD &l, std::vector< distribution > &dist)
void SeedFixedIntegers(const std::vector< int > &seeds)
void fill(RealD &l, std::vector< distribution > &dist)
void fill(vRealF &l, std::vector< distribution > &dist)
void fill(sobj &l, std::vector< distribution > &dist)
static accelerator_inline constexpr int Nsimd(void)
accelerator_inline int Checkerboard(void) const
GridBase * Grid(void) const