22 const std::string RandomNumbers_SFMT::class_name =
"RandomNumbers:SFMT";
24 #ifdef ENABLE_SFMT_JUMP
25 static const NTL::GF2X ch_poly = sfmt_characteristic_polynomial();
29 RandomNumbers_SFMT::RandomNumbers_SFMT(
const int s)
32 sfmt_init_gen_rand(&m_state, s);
37 void RandomNumbers_SFMT::reset(
unsigned long seed)
40 sfmt_init_gen_rand(&m_state, seed);
45 double RandomNumbers_SFMT::get()
47 return sfmt_genrand_res53(&m_state);
52 void RandomNumbers_SFMT::get_block(
double *v,
const size_t n)
54 for (
size_t i = 0; i < n; ++i) {
61 #ifdef ENABLE_SFMT_JUMP
63 void RandomNumbers_SFMT::uniform_lex_global(
Field& f)
65 return generate_global_jump<RandomNumbers::rand_uniform>(f);
70 void RandomNumbers_SFMT::gauss_lex_global(
Field& f)
72 if (f.
nin() % 2 == 0) {
73 return generate_global_jump<RandomNumbers::rand_gauss_even>(f);
75 return generate_global_jump<RandomNumbers::rand_gauss_odd>(f);
81 template<
typename InnerGenerator>
82 void RandomNumbers_SFMT::generate_global_jump(
Field& f)
84 InnerGenerator fill(f,
this);
86 const int Nin = f.
nin();
87 const int Nvol = f.
nvol();
88 const int Nex = f.
nex();
91 vout.
detailed(m_vl,
"%s: single node. no need to consider division.\n", class_name.c_str());
93 for (
int j = 0; j < Nex; ++j) {
94 for (
int isite = 0; isite < Nvol; ++isite) {
100 vout.
crucial(m_vl,
"Error at %s::%s: Nvol mismatch.\n", class_name.c_str(), __func__);
105 sfmt_t rng_state = m_state;
125 vout.
detailed(m_vl,
"L = { %2d, %2d, %2d, %2d }, Lvol = %d\n", Lx, Ly, Lz, Lt, Lvol);
126 vout.
detailed(m_vl,
"N = { %2d, %2d, %2d, %2d }, Nvol = %d\n", Nx, Ny, Nz, Nt, Nvol);
127 vout.
detailed(m_vl,
"G = { %2d, %2d, %2d, %2d }, NPE = %d\n", Gx, Gy, Gz, Gt, NPE);
136 size_t block_size = fill.block_size();
139 sfmt_calculate_jump_polynomial(jump_y, block_size * (Lx - Nx), ch_poly);
141 sfmt_calculate_jump_polynomial(jump_z, block_size * (Lx * (Ly - Ny)), ch_poly);
143 sfmt_calculate_jump_polynomial(jump_t, block_size * (Lx * Ly * (Lz - Nz)), ch_poly);
145 sfmt_calculate_jump_polynomial(jump_w, block_size * (Lx * Ly * Lz * (Lt - Nt)), ch_poly);
147 #define calc_global_index(x, y, z, t) \
148 (x) + Lx * ((y) + Ly * ((z) + Lz * (t)))
150 #define calc_local_index(x, y, z, t) \
151 (x) + Nx * ((y) + Ny * ((z) + Nz * (t)))
162 int global_index = calc_global_index(Nx * gx, Ny * gy, Nz * gz, Nt * gt);
165 sfmt_jump(&m_state, block_size * global_index, ch_poly);
168 double *p = f.
ptr(0);
170 for (
int j = 0; j < Nex; ++j) {
171 for (
int t = 0; t < Nt; ++t) {
172 for (
int z = 0; z < Nz; ++z) {
173 for (
int y = 0; y < Ny; ++y) {
174 for (
int x = 0; x < Nx; ++x) {
180 sfmt_jump_by_polynomial(&m_state, jump_y);
184 sfmt_jump_by_polynomial(&m_state, jump_z);
188 sfmt_jump_by_polynomial(&m_state, jump_t);
192 sfmt_jump_by_polynomial(&m_state, jump_w);
197 sfmt_jump(&m_state, block_size * Lvol * Nex, ch_poly);
200 #undef calc_global_index
201 #undef calc_local_index
220 void RandomNumbers_SFMT::write_file(
const std::string& filename)
222 vout.
detailed(m_vl,
"%s: save random number state to file %s\n", class_name.c_str(), filename.c_str());
225 std::ofstream out_file(filename.c_str());
228 vout.
crucial(m_vl,
"Error at %s: unable to open output file.\n", class_name.c_str());
232 for (
int i = 0; i < SFMT_N; ++i) {
233 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[0] <<
" ";
234 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[1] <<
" ";
235 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[2] <<
" ";
236 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[3] <<
" ";
237 out_file << std::endl;
240 out_file << std::dec << m_state.idx << std::endl;
248 void RandomNumbers_SFMT::read_file(
const std::string& filename)
250 vout.
detailed(m_vl,
"%s: read random number state from file %s\n", class_name.c_str(), filename.c_str());
253 std::ifstream in_file(filename.c_str());
256 vout.
crucial(m_vl,
"Error at %s: unable to open output file.\n", class_name.c_str());
260 for (
int i = 0; i < SFMT_N; ++i) {
261 in_file >> std::hex >> m_state.state[i].u[0];
262 in_file >> std::hex >> m_state.state[i].u[1];
263 in_file >> std::hex >> m_state.state[i].u[2];
264 in_file >> std::hex >> m_state.state[i].u[3];
267 in_file >> std::dec >> m_state.idx;
278 #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.
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.