CHROMA
distillution_noise.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Support for distillution - random time-slices and quark line noises
3  */
4 
6 #include "util/ferm/crc48.h"
7 #include "qdp_rannyu.h"
8 
9 namespace Chroma
10 {
11  namespace
12  {
13  //! Error output
14  StandardOutputStream& operator<<(StandardOutputStream& os, const multi1d<int>& d)
15  {
16  if (d.size() > 0)
17  {
18  os << d[0];
19 
20  for(int i=1; i < d.size(); ++i)
21  os << " " << d[i];
22  }
23 
24  return os;
25  }
26 
27 
28  //---------------------------------------------------------------------
29  //! Convert a hash to a rannyu seed
30  multi1d<int> hashToSeed(const CRC48::CRC48_t& hash)
31  {
32  multi1d<int> seed(4);
33 
34  // The CRC48 is six units of 8-bits. Pack this into four 12-bit units
35  // First pack two-sets of 8-bits into 16-bit units
36  unsigned int h01 = hash.crc[0] | (hash.crc[1] << 8);
37  unsigned int h23 = hash.crc[2] | (hash.crc[3] << 8);
38  unsigned int h45 = hash.crc[4] | (hash.crc[5] << 8);
39 
40  seed[0] = h01 & 0xfff; // use first 12
41  h01 >>= 12; // now only have 4 bits
42  h23 <<= 4; // bump up by 4 bits
43  h23 |= h01; // now have 20 bits
44  seed[1] = h23 & 0xfff; // use first 12
45  h23 >>= 12; // now only have 8 bits
46  h45 <<= 8; // bump up by 8 bits
47  h45 |= h23; // now have 24 bits
48  seed[2] = h45 & 0xfff; // used first 12 bits
49  seed[3] = (h45 >> 12); // use remaining 12 bits
50 
51  return seed;
52  }
53 
54 
55  //---------------------------------------------------------------------
56  //! Convert a std::string to a rannyu seed
57  multi1d<int> stringToSeed(const std::string& output)
58  {
59  CRC48::CRC48_t crc;
60 
61  CRC48::initCRC48(crc);
62  CRC48::calcCRC48(crc, output.c_str(), output.length());
63 
64  return hashToSeed(crc);
65  }
66 
67 
68  //---------------------------------------------------------------------
69  // Z(N)-rng
70  Complex z4rng(RANNYU::RNGState_t& rng)
71  {
72  RANNYU::random(rng);
73 
74  Real twopiN = 0.25 * Chroma::twopi;
75  Real theta = twopiN * floor(4*rng.ran);
76 
77  return cmplx(cos(theta),sin(theta));
78  }
79 
80  } // end namespace
81 
82 
83 
84  //---------------------------------------------------------------------
85  // Lattice origin
86  DistillutionNoise::DistillutionNoise(const std::string& ensemble_, const std::string& sequence_label_, int decay_dir_) :
87  ensemble(ensemble_), seqno(sequence_label_), decay_dir(decay_dir_)
88  {
89  if (decay_dir != Nd-1)
90  {
91  QDPIO::cerr << __func__ << ": only support decay_dir = Nd-1\n";
92  QDP_abort(1);
93  }
94 
95  // Use the ensemble and seqno to make a unique seed. This will be used to form the origin.
96  BinaryBufferWriter bin;
97  write(bin, ensemble);
98  write(bin, seqno);
99 
100  // Use the no-side-effect version of the RNG with input state, and output random num.
101  RANNYU::RNGState_t rng;
102  rng.seed = stringToSeed(bin.str());
103  RANNYU::random(rng);
104 
105  // Throw out the first few RNG's
106  for(int i=0; i < 10; ++i)
107  RANNYU::random(rng);
108 
109  // Make a new origin
110  int Lt = Layout::lattSize()[decay_dir];
111  t_origin = int(Lt * rng.ran) % Lt; // The mod makes sure the RNG cannot be 1.000
112  }
113 
114  //---------------------------------------------------------------------
115  //! Convenience - get shifted time
116  /*!< Returns the shifted time taking account of periodicity */
118  {
119  return (t_slice + t_origin) % Layout::lattSize()[decay_dir];
120 // return t_slice;
121  }
122 
123 
124  //---------------------------------------------------------------------
125  //! Return the RN-s needed for this line
126  multi2d<Complex> DistillutionNoise::getRNG(const DistQuarkLines_t& info) const
127  {
128  // Use tags to make a unique
129  BinaryBufferWriter bin;
130  write(bin, ensemble);
131  write(bin, seqno);
132  write(bin, info.quark_line);
133  write(bin, (info.annih) ? 1 : 0);
134  write(bin, info.mass);
135 
136  // Use the no-side-effect version of the RNG with input state, and output random num.
137  RANNYU::RNGState_t rng;
138  rng.seed = stringToSeed(bin.str());
139 
140  // Throw out the first few RNG's
141  for(int i=0; i < 20; ++i)
142  RANNYU::random(rng);
143 
144  // Loop over the time and vectors to produce the full random numbers
145  int Lt = Layout::lattSize()[decay_dir];
146 
147  multi2d<Complex> eta(Lt, info.num_vecs);
148 
149  for(int t=0; t < Lt; ++t)
150  {
151  for(int i=0; i < info.num_vecs; ++i)
152  {
153  eta(t,i) = z4rng(rng);
154  }
155  }
156 
157  return eta;
158  }
159 
160 
161 } // end namespace Chroma
virtual int getTime(int t_slice) const
Convenience - get shifted time.
DistillutionNoise(const std::string &ensemble, const std::string &sequence_label, int decay_dir)
Default constructor.
virtual multi2d< Complex > getRNG(const DistQuarkLines_t &info) const
Return the RN-s needed for this line.
48-bit CRC
Support for distillution - random time-slices and quark line noises.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
int t
Definition: meslate.cc:37
int t_slice
Definition: meslate.cc:23
Nd
Definition: meslate.cc:74
void initCRC48(CRC48_t &acc)
Definition: crc48.cc:87
void calcCRC48(CRC48_t &acc, const void *dataPtr, int count)
Definition: crc48.cc:94
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
QDP::StandardOutputStream & operator<<(QDP::StandardOutputStream &s, const multi1d< int > &d)
Definition: npr_vertex_w.cc:12
int i
Definition: pbg5p_w.cc:55
const Real twopi
Definition: chromabase.h:55
LatticeFermion eta
Definition: mespbg5p_w.cc:37
DComplex d
Definition: invbicg.cc:99
static QOP_info_t info
::std::string string
Definition: gtest.h:1979
CRCBASETYPE crc[CRCARRAYSIZE]
Definition: crc48.h:87
Keys for lattice noise.