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 double RandomNumbers_SFMT::get()
39 return sfmt_genrand_res53(&m_state);
44 void RandomNumbers_SFMT::get_block(
double *v,
const size_t n)
46 for (
size_t i = 0; i < n; ++i) {
53 #ifdef ENABLE_SFMT_JUMP
55 void RandomNumbers_SFMT::uniform_lex_global(
Field& f)
57 return generate_global_jump<RandomNumbers::rand_uniform>(f);
62 void RandomNumbers_SFMT::gauss_lex_global(
Field& f)
64 if (f.
nin() % 2 == 0) {
65 return generate_global_jump<RandomNumbers::rand_gauss_even>(f);
67 return generate_global_jump<RandomNumbers::rand_gauss_odd>(f);
73 template<
typename InnerGenerator>
74 void RandomNumbers_SFMT::generate_global_jump(
Field& f)
76 InnerGenerator fill(f,
this);
78 const int Nin = f.
nin();
79 const int Nvol = f.
nvol();
80 const int Nex = f.
nex();
83 vout.
detailed(m_vl,
"%s: single node. no need to consider division.\n", class_name.c_str());
85 for (
int j = 0; j < Nex; ++j) {
86 for (
int isite = 0; isite < Nvol; ++isite) {
92 vout.
crucial(m_vl,
"%s: %s: Nvol mismatch.\n", class_name.c_str(), __func__);
97 sfmt_t rng_state = m_state;
117 vout.
detailed(m_vl,
"L = { %2d, %2d, %2d, %2d }, Lvol = %d\n", Lx, Ly, Lz, Lt, Lvol);
118 vout.
detailed(m_vl,
"N = { %2d, %2d, %2d, %2d }, Nvol = %d\n", Nx, Ny, Nz, Nt, Nvol);
119 vout.
detailed(m_vl,
"G = { %2d, %2d, %2d, %2d }, NPE = %d\n", Gx, Gy, Gz, Gt, NPE);
128 size_t block_size = fill.block_size();
131 sfmt_calculate_jump_polynomial(jump_y, block_size * (Lx - Nx), ch_poly);
133 sfmt_calculate_jump_polynomial(jump_z, block_size * (Lx * (Ly - Ny)), ch_poly);
135 sfmt_calculate_jump_polynomial(jump_t, block_size * (Lx * Ly * (Lz - Nz)), ch_poly);
137 sfmt_calculate_jump_polynomial(jump_w, block_size * (Lx * Ly * Lz * (Lt - Nt)), ch_poly);
139 #define __global_index(x, y, z, t) \
140 (x) + Lx * ((y) + Ly * ((z) + Lz * (t)))
142 #define __local_index(x, y, z, t) \
143 (x) + Nx * ((y) + Ny * ((z) + Nz * (t)))
154 int global_index = __global_index(Nx * gx, Ny * gy, Nz * gz, Nt * gt);
157 sfmt_jump(&m_state, block_size * global_index, ch_poly);
160 double *p = f.
ptr(0);
162 for (
int j = 0; j < Nex; ++j) {
163 for (
int t = 0; t < Nt; ++t) {
164 for (
int z = 0; z < Nz; ++z) {
165 for (
int y = 0; y < Ny; ++y) {
166 for (
int x = 0; x < Nx; ++x) {
172 sfmt_jump_by_polynomial(&m_state, jump_y);
176 sfmt_jump_by_polynomial(&m_state, jump_z);
180 sfmt_jump_by_polynomial(&m_state, jump_t);
184 sfmt_jump_by_polynomial(&m_state, jump_w);
189 sfmt_jump(&m_state, block_size * Lvol * Nex, ch_poly);
192 #undef __global_index
200 void RandomNumbers_SFMT::gauss_lex_global(
Field& f)
203 vout.
detailed(m_vl,
"%s: single node. no need to consider division.\n", class_name.c_str());
205 double *p = f.
ptr(0);
207 for (
size_t i = 0, n = f.
size(); i < n; ++i) {
208 *p++ = sfmt_genrand_res53(&m_state);
214 vout.
crucial(m_vl,
"%s: %s yet unimplemented.\n", class_name.c_str(), __func__);
237 void RandomNumbers_SFMT::writefile(
const std::string& filename)
239 vout.
detailed(m_vl,
"%s: save random number state to file %s\n", class_name.c_str(), filename.c_str());
242 std::ofstream out_file(filename.c_str());
245 vout.
crucial(m_vl,
"%s: error: unable to open output file.\n", class_name.c_str());
249 for (
int i = 0; i < SFMT_N; ++i) {
250 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[0] <<
" ";
251 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[1] <<
" ";
252 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[2] <<
" ";
253 out_file << std::setw(8) << std::setfill(
'0') << std::hex << m_state.state[i].u[3] <<
" ";
254 out_file << std::endl;
257 out_file << std::dec << m_state.idx << std::endl;
265 void RandomNumbers_SFMT::readfile(
const std::string& filename)
267 vout.
detailed(m_vl,
"%s: read random number state from file %s\n", class_name.c_str(), filename.c_str());
270 std::ifstream in_file(filename.c_str());
273 vout.
crucial(m_vl,
"%s: error: unable to open output file.\n", class_name.c_str());
277 for (
int i = 0; i < SFMT_N; ++i) {
278 in_file >> std::hex >> m_state.state[i].u[0];
279 in_file >> std::hex >> m_state.state[i].u[1];
280 in_file >> std::hex >> m_state.state[i].u[2];
281 in_file >> std::hex >> m_state.state[i].u[3];
284 in_file >> std::dec >> m_state.idx;
295 #endif // USE_SFMTLIB
void detailed(const char *format,...)
static int npe(const int dir)
logical grid extent
static int self()
rank within small world.
double * ptr(const int jin, const int site, const int jex)
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.