QUDA  v1.1.0
A library for QCD on GPUs
gauge_alg_test.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include <quda.h>
6 #include <quda_internal.h>
7 #include <gauge_field.h>
8 
9 #include <comm_quda.h>
10 #include <host_utils.h>
11 #include <command_line_params.h>
12 #include <gauge_tools.h>
13 
14 #include <pgauge_monte.h>
15 #include <random_quda.h>
16 #include <unitarization_links.h>
17 
18 #include <qio_field.h>
19 
20 #include <gtest/gtest.h>
21 
22 using namespace quda;
23 
24 class GaugeAlgTest : public ::testing::Test {
25  protected:
27  const double unitarize_eps = 1e-14;
28  const double max_error = 1e-10;
29  const int reunit_allow_svd = 1;
30  const int reunit_svd_only = 0;
31  const double svd_rel_error = 1e-6;
32  const double svd_abs_error = 1e-6;
33  setUnitarizeLinksConstants(unitarize_eps, max_error,
34  reunit_allow_svd, reunit_svd_only,
35  svd_rel_error, svd_abs_error);
36 
37  }
38 
40  {
42  return true;
43  return false;
44  }
45 
46  bool comparePlaquette(double3 a, double3 b){
47  double a0,a1,a2;
48  a0 = std::abs(a.x - b.x);
49  a1 = std::abs(a.y - b.y);
50  a2 = std::abs(a.z - b.z);
51  double prec_val = 1.0e-5;
52  if (prec == QUDA_DOUBLE_PRECISION) prec_val = 1.0e-15;
53  if ((a0 < prec_val) && (a1 < prec_val) && (a2 < prec_val)) return true;
54  return false;
55  }
56 
57  bool CheckDeterminant(double2 detu){
58  double prec_val = 5e-8;
59  if (prec == QUDA_DOUBLE_PRECISION) prec_val = 1.0e-15;
60  if (std::abs(1.0 - detu.x) < prec_val && std::abs(detu.y) < prec_val) return true;
61  return false;
62  }
63 
64  virtual void SetUp() {
66 
68 
69  // Setup gauge container.
76 
79 
80  param.X[0] = xdim;
81  param.X[1] = ydim;
82  param.X[2] = zdim;
83  param.X[3] = tdim;
84  setDims(param.X);
85 
86  param.anisotropy = 1.0; //don't support anisotropy for now!!!!!!
89  param.ga_pad = 0;
90 
92  gParam.pad = 0;
98 
99 #ifdef MULTI_GPU
100  int y[4];
101  int R[4] = {0,0,0,0};
102  for(int dir=0; dir<4; ++dir) if(comm_dim_partitioned(dir)) R[dir] = 2;
103  for(int dir=0; dir<4; ++dir) y[dir] = param.X[dir] + 2 * R[dir];
104  int pad = 0;
105  GaugeFieldParam gParamEx(y, prec, link_recon,
107  gParamEx.create = QUDA_ZERO_FIELD_CREATE;
108  gParamEx.order = gParam.order;
109  gParamEx.siteSubset = QUDA_FULL_SITE_SUBSET;
110  gParamEx.t_boundary = gParam.t_boundary;
111  gParamEx.nFace = 1;
112  for(int dir=0; dir<4; ++dir) gParamEx.r[dir] = R[dir];
113  U = new cudaGaugeField(gParamEx);
114 #else
115  U = new cudaGaugeField(gParam);
116 #endif
117  // CURAND random generator initialization
118  randstates = new RNG(gParam, 1234);
119  randstates->Init();
120 
121  nsteps = 10;
122  nhbsteps = 4;
123  novrsteps = 4;
124  coldstart = false;
125  beta_value = 6.2;
126 
127  a0.Start(__func__, __FILE__, __LINE__);
128  a1.Start(__func__, __FILE__, __LINE__);
129 
130  int *num_failures_h = (int *)mapped_malloc(sizeof(int));
131  int *num_failures_d = (int *)get_mapped_device_pointer(num_failures_h);
132 
133  if (link_recon != QUDA_RECONSTRUCT_8 && coldstart)
134  InitGaugeField(*U);
135  else
136  InitGaugeField(*U, *randstates);
137 
138  // Reunitarization setup
139  SetReunitarizationConsts();
140  plaquette(*U);
141 
142  for(int step=1; step<=nsteps; ++step){
143  printfQuda("Step %d\n",step);
144  Monte(*U, *randstates, beta_value, nhbsteps, novrsteps);
145 
146  //Reunitarize gauge links...
147  *num_failures_h = 0;
148  unitarizeLinks(*U, num_failures_d);
150  if (*num_failures_h > 0) errorQuda("Error in the unitarization\n");
151 
152  plaquette(*U);
153  }
154  a1.Stop(__func__, __FILE__, __LINE__);
155 
156  printfQuda("Time Monte -> %.6f s\n", a1.Last());
157  plaq = plaquette(*U);
158  printfQuda("Plaq: %.16e, %.16e, %.16e\n", plaq.x, plaq.y, plaq.z);
159 
160  host_free(num_failures_h);
161  }
162 
163  virtual void TearDown() {
164  detu = getLinkDeterminant(*U);
165  double2 tru = getLinkTrace(*U);
166  printfQuda("Det: %.16e:%.16e\n", detu.x, detu.y);
167  printfQuda("Tr: %.16e:%.16e\n", tru.x/3.0, tru.y/3.0);
168 
169  delete U;
170  //Release all temporary memory used for data exchange between GPUs in multi-GPU mode
172 
173  a0.Stop(__func__, __FILE__, __LINE__);
174  printfQuda("Time -> %.6f s\n", a0.Last());
175  randstates->Release();
176  delete randstates;
177  }
178 
180 
181  Timer a0,a1;
182  double2 detu;
183  double3 plaq;
185  int nsteps;
186  int nhbsteps;
188  bool coldstart;
189  double beta_value;
191 
192 };
193 
194 TEST_F(GaugeAlgTest, Generation)
195 {
196  detu = getLinkDeterminant(*U);
197  plaq = plaquette(*U);
198  bool testgen = false;
199  //check plaquette value for beta = 6.2
200  if (plaq.x < 0.614 && plaq.x > 0.611 && plaq.y < 0.614 && plaq.y > 0.611) testgen = true;
201 
202  if (testgen) { ASSERT_TRUE(CheckDeterminant(detu)); }
203 }
204 
205 TEST_F(GaugeAlgTest, Landau_Overrelaxation)
206 {
207  const int reunit_interval = 10;
208  printfQuda("Landau gauge fixing with overrelaxation\n");
209  gaugeFixingOVR(*U, 4, 100, 10, 1.5, 0, reunit_interval, 1);
210  auto plaq_gf = plaquette(*U);
211  printfQuda("Plaq: %.16e, %.16e, %.16e\n", plaq_gf.x, plaq_gf.y, plaq_gf.z);
212  ASSERT_TRUE(comparePlaquette(plaq, plaq_gf));
213 }
214 
215 TEST_F(GaugeAlgTest, Coulomb_Overrelaxation)
216 {
217  const int reunit_interval = 10;
218  printfQuda("Coulomb gauge fixing with overrelaxation\n");
219  gaugeFixingOVR(*U, 3, 100, 10, 1.5, 0, reunit_interval, 1);
220  auto plaq_gf = plaquette(*U);
221  printfQuda("Plaq: %.16e, %.16e, %.16e\n", plaq_gf.x, plaq_gf.y, plaq_gf.z);
222  ASSERT_TRUE(comparePlaquette(plaq, plaq_gf));
223 }
224 
225 TEST_F(GaugeAlgTest, Landau_FFT)
226 {
227  if (!checkDimsPartitioned()) {
228  printfQuda("Landau gauge fixing with steepest descent method with FFTs\n");
229  gaugeFixingFFT(*U, 4, 100, 10, 0.08, 0, 0, 1);
230  auto plaq_gf = plaquette(*U);
231  printfQuda("Plaq: %.16e, %.16e, %.16e\n", plaq_gf.x, plaq_gf.y, plaq_gf.z);
232  ASSERT_TRUE(comparePlaquette(plaq, plaq_gf));
233  }
234 }
235 
236 TEST_F(GaugeAlgTest, Coulomb_FFT)
237 {
238  if (!checkDimsPartitioned()) {
239  printfQuda("Coulomb gauge fixing with steepest descent method with FFTs\n");
240  gaugeFixingFFT(*U, 3, 100, 10, 0.08, 0, 0, 1);
241  auto plaq_gf = plaquette(*U);
242  printfQuda("Plaq: %.16e, %.16e, %.16e\n", plaq_gf.x, plaq_gf.y, plaq_gf.z);
243  ASSERT_TRUE(comparePlaquette(plaq, plaq_gf));
244  }
245 }
246 
247 int main(int argc, char **argv)
248 {
249  // initalize google test, includes command line options
250  ::testing::InitGoogleTest(&argc, argv);
251  // return code for google test
252  int test_rc = 0;
253  xdim=ydim=zdim=tdim=32;
254 
255  // command line options
256  auto app = make_app();
257  try {
258  app->parse(argc, argv);
259  } catch (const CLI::ParseError &e) {
260  return app->exit(e);
261  }
262 
263  initComms(argc, argv, gridsize_from_cmdline);
264 
265  // Ensure gtest prints only from rank 0
267  if (comm_rank() != 0) { delete listeners.Release(listeners.default_result_printer()); }
268 
270  test_rc = RUN_ALL_TESTS();
271  endQuda();
272 
273  finalizeComms();
274 
275  return test_rc;
276 }
bool CheckDeterminant(double2 detu)
bool comparePlaquette(double3 a, double3 b)
bool checkDimsPartitioned()
void SetReunitarizationConsts()
cudaGaugeField * U
virtual void SetUp()
QudaGaugeParam param
virtual void TearDown()
Class declaration to initialize and hold CURAND RNG states.
Definition: random_quda.h:23
TestEventListener * Release(TestEventListener *listener)
TestEventListener * default_result_printer() const
Definition: gtest.h:1186
TestEventListeners & listeners()
static UnitTest * GetInstance()
int comm_rank(void)
int comm_dim_partitioned(int dim)
std::shared_ptr< QUDAApp > make_app(std::string app_description, std::string app_name)
QudaReconstructType link_recon
int device_ordinal
int & ydim
int & zdim
QudaPrecision prec
int & tdim
int & xdim
std::array< int, 4 > gridsize_from_cmdline
void setDims(int *)
Definition: host_utils.cpp:315
@ QUDA_VERBOSE
Definition: enum_quda.h:267
@ QUDA_FULL_SITE_SUBSET
Definition: enum_quda.h:333
@ QUDA_RECONSTRUCT_8
Definition: enum_quda.h:72
@ QUDA_PERIODIC_T
Definition: enum_quda.h:57
@ QUDA_VECTOR_GEOMETRY
Definition: enum_quda.h:501
@ QUDA_GHOST_EXCHANGE_EXTENDED
Definition: enum_quda.h:510
@ QUDA_GHOST_EXCHANGE_NO
Definition: enum_quda.h:508
@ QUDA_GAUGE_FIXED_NO
Definition: enum_quda.h:80
@ QUDA_DOUBLE_PRECISION
Definition: enum_quda.h:65
@ QUDA_MILC_GAUGE_ORDER
Definition: enum_quda.h:47
@ QUDA_ZERO_FIELD_CREATE
Definition: enum_quda.h:361
@ QUDA_NULL_FIELD_CREATE
Definition: enum_quda.h:360
@ QUDA_WILSON_LINKS
Definition: enum_quda.h:30
int main(int argc, char **argv)
TEST_F(GaugeAlgTest, Generation)
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: gtest.h:2468
#define ASSERT_TRUE(condition)
Definition: gtest.h:1964
GaugeFieldParam gParam
void initComms(int argc, char **argv, std::array< int, 4 > &commDims)
Definition: host_utils.cpp:255
void finalizeComms()
Definition: host_utils.cpp:292
#define get_mapped_device_pointer(ptr)
Definition: malloc_quda.h:116
#define host_free(ptr)
Definition: malloc_quda.h:115
#define mapped_malloc(size)
Definition: malloc_quda.h:108
double2 getLinkTrace(GaugeField &data)
Calculate the Trace.
void Monte(GaugeField &data, RNG &rngstate, double Beta, int nhb, int nover)
Perform heatbath and overrelaxation. Performs nhb heatbath steps followed by nover overrelaxation ste...
void setUnitarizeLinksConstants(double unitarize_eps, double max_error, bool allow_svd, bool svd_only, double svd_rel_error, double svd_abs_error)
double3 plaquette(const GaugeField &U)
Compute the plaquette of the gauge field.
void InitGaugeField(GaugeField &data)
Perform a cold start to the gauge field, identity SU(3) matrix, also fills the ghost links in multi-G...
void gaugeFixingFFT(GaugeField &data, const int gauge_dir, const int Nsteps, const int verbose_interval, const double alpha, const int autotune, const double tolerance, const int stopWtheta)
Gauge fixing with Steepest descent method with FFTs with support for single GPU only.
void PGaugeExchangeFree()
Release all allocated memory used to exchange data between nodes.
void gaugeFixingOVR(GaugeField &data, const int gauge_dir, const int Nsteps, const int verbose_interval, const double relax_boost, const double tolerance, const int reunit_interval, const int stopWtheta)
Gauge fixing with overrelaxation with support for single and multi GPU.
void unitarizeLinks(GaugeField &outfield, const GaugeField &infield, int *fails)
__host__ __device__ ValueType abs(ValueType x)
Definition: complex_quda.h:125
double2 getLinkDeterminant(GaugeField &data)
Calculate the Determinant.
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
QudaGaugeParam param
Definition: pack_test.cpp:18
Main header file for the QUDA library.
QudaGaugeParam newQudaGaugeParam(void)
void initQuda(int device)
void endQuda(void)
#define qudaDeviceSynchronize()
Definition: quda_api.h:250
double anisotropy
Definition: quda.h:37
QudaReconstructType reconstruct
Definition: quda.h:49
int ga_pad
Definition: quda.h:65
QudaLinkType type
Definition: quda.h:41
QudaPrecision cuda_prec_sloppy
Definition: quda.h:51
QudaReconstructType reconstruct_sloppy
Definition: quda.h:52
QudaGaugeFixed gauge_fix
Definition: quda.h:63
QudaGaugeFieldOrder gauge_order
Definition: quda.h:42
QudaPrecision cuda_prec
Definition: quda.h:48
int X[4]
Definition: quda.h:35
QudaPrecision cpu_prec
Definition: quda.h:46
QudaTboundary t_boundary
Definition: quda.h:44
QudaReconstructType reconstruct
Definition: gauge_field.h:50
QudaGaugeFieldOrder order
Definition: gauge_field.h:51
void setPrecision(QudaPrecision precision, bool force_native=false)
Helper function for setting the precision and corresponding field order for QUDA internal fields.
Definition: gauge_field.h:173
QudaLinkType link_type
Definition: gauge_field.h:53
QudaFieldCreate create
Definition: gauge_field.h:60
QudaTboundary t_boundary
Definition: gauge_field.h:54
QudaGhostExchange ghostExchange
Definition: lattice_field.h:77
QudaPrecision Precision() const
Definition: lattice_field.h:59
#define printfQuda(...)
Definition: util_quda.h:114
void setVerbosity(QudaVerbosity verbosity)
Definition: util_quda.cpp:25
#define errorQuda(...)
Definition: util_quda.h:120