22 #ifdef USE_FACTORY_AUTOREGISTER
24 bool init = RandomNumbers_SFMT::register_factory();
29 const std::string RandomNumbers_SFMT::class_name =
"RandomNumbers:SFMT";
31 #ifdef ENABLE_SFMT_JUMP
32 static const NTL::GF2X ch_poly = sfmt_characteristic_polynomial();
36 RandomNumbers_SFMT::RandomNumbers_SFMT(
const int s)
39 sfmt_init_gen_rand(&m_state, s);
44 void RandomNumbers_SFMT::reset(
const unsigned long seed)
47 sfmt_init_gen_rand(&m_state, seed);
52 double RandomNumbers_SFMT::get()
54 return sfmt_genrand_res53(&m_state);
59 void RandomNumbers_SFMT::get_block(
double *v,
const size_t n)
61 for (
size_t i = 0; i < n; ++i) {
68 #ifdef ENABLE_SFMT_JUMP
70 void RandomNumbers_SFMT::uniform_lex_global(
Field& f)
72 return generate_global_jump<RandomNumbers::rand_uniform>(f);
77 void RandomNumbers_SFMT::gauss_lex_global(
Field& f)
79 if (f.
nin() % 2 == 0) {
80 return generate_global_jump<RandomNumbers::rand_gauss_even>(f);
82 return generate_global_jump<RandomNumbers::rand_gauss_odd>(f);
88 template<
typename InnerGenerator>
89 void RandomNumbers_SFMT::generate_global_jump(
Field& f)
91 InnerGenerator fill(f,
this);
93 const int Nin = f.
nin();
94 const int Nvol = f.
nvol();
95 const int Nex = f.
nex();
98 vout.
detailed(m_vl,
"%s: single node. no need to consider division.\n", class_name.c_str());
100 for (
int j = 0; j < Nex; ++j) {
101 for (
int isite = 0; isite < Nvol; ++isite) {
107 vout.
crucial(m_vl,
"Error at %s::%s: Nvol mismatch.\n", class_name.c_str(), __func__);
112 sfmt_t rng_state = m_state;
132 vout.
detailed(m_vl,
"Lxyzt = { %d, %d, %d, %d }, Lvol = %ld\n", Lx, Ly, Lz, Lt, Lvol);
133 vout.
detailed(m_vl,
"Nxyxt = { %d, %d, %d, %d }, Nvol = %d\n", Nx, Ny, Nz, Nt, Nvol);
134 vout.
detailed(m_vl,
"NPE_xyzt = { %d, %d, %d, %d }, NPE = %d\n", NPE_x, NPE_y, NPE_z, NPE_t, NPE);
143 const size_t block_size = fill.block_size();
146 sfmt_calculate_jump_polynomial(jump_y, block_size * (Lx - Nx), ch_poly);
148 sfmt_calculate_jump_polynomial(jump_z, block_size * (Lx * (Ly - Ny)), ch_poly);
150 sfmt_calculate_jump_polynomial(jump_t, block_size * (Lx * Ly * (Lz - Nz)), ch_poly);
152 sfmt_calculate_jump_polynomial(jump_w, block_size * (Lx * Ly * Lz * (Lt - Nt)), ch_poly);
154 #define calc_global_index(x, y, z, t) \
155 (x) + Lx * ((y) + Ly * ((z) + Lz * (t)))
157 #define calc_local_index(x, y, z, t) \
158 (x) + Nx * ((y) + Ny * ((z) + Nz * (t)))
169 const int global_index = calc_global_index(Nx * ipe_x, Ny * ipe_y, Nz * ipe_z, Nt * ipe_t);
172 sfmt_jump(&m_state, block_size * global_index, ch_poly);
175 double *p = f.
ptr(0);
177 for (
int j = 0; j < Nex; ++j) {
178 for (
int t = 0; t < Nt; ++t) {
179 for (
int z = 0; z < Nz; ++z) {
180 for (
int y = 0; y < Ny; ++y) {
181 for (
int x = 0; x < Nx; ++x) {
187 sfmt_jump_by_polynomial(&m_state, jump_y);
191 sfmt_jump_by_polynomial(&m_state, jump_z);
195 sfmt_jump_by_polynomial(&m_state, jump_t);
199 sfmt_jump_by_polynomial(&m_state, jump_w);
204 sfmt_jump(&m_state, block_size * Lvol * Nex, ch_poly);
207 #undef calc_global_index
208 #undef calc_local_index
229 void RandomNumbers_SFMT::write_file(
const std::string& filename)
231 vout.
detailed(m_vl,
"%s: save random number state to file %s\n", class_name.c_str(), filename.c_str());
234 std::ofstream out_file(filename.c_str());
237 vout.
crucial(m_vl,
"Error at %s: unable to open output file.\n", class_name.c_str());
241 for (
int i = 0; i < SFMT_N; ++i) {
242 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[0] <<
" ";
243 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[1] <<
" ";
244 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[2] <<
" ";
245 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[3] <<
" ";
246 out_file << std::endl;
249 out_file << std::dec << m_state.idx << std::endl;
257 void RandomNumbers_SFMT::read_file(
const std::string& filename)
259 vout.
detailed(m_vl,
"%s: read random number state from file %s\n", class_name.c_str(), filename.c_str());
262 std::ifstream in_file(filename.c_str());
265 vout.
crucial(m_vl,
"Error at %s: unable to open output file.\n", class_name.c_str());
269 for (
int i = 0; i < SFMT_N; ++i) {
270 in_file >> std::hex >> m_state.state[i].u[0];
271 in_file >> std::hex >> m_state.state[i].u[1];
272 in_file >> std::hex >> m_state.state[i].u[2];
273 in_file >> std::hex >> m_state.state[i].u[3];
276 in_file >> std::dec >> m_state.idx;
287 #endif // USE_SFMTLIB
void detailed(const char *format,...)
static int npe(const int dir)
logical grid extent
const double * ptr(const int jin, const int site, const int jex) const
static int self()
rank within small world.
Container of Field-type object.
static int broadcast(size_t size, void *data, int sender)
static int ipe(const int dir)
logical coordinate of current proc.
long long_t
definition of long for Bridge++
void crucial(const char *format,...)
static int size()
size of small world.
static bool is_primary()
check if the present node is primary in small communicator.