QUDA  v1.1.0
A library for QCD on GPUs
heatbath_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 <gauge_field.h>
7 
8 #include <comm_quda.h>
9 #include <host_utils.h>
10 #include <command_line_params.h>
11 #include <gauge_tools.h>
12 #include "misc.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 #define MAX(a,b) ((a)>(b)?(a):(b))
21 #define DABS(a) ((a)<(0.)?(-(a)):(a))
22 
23 namespace quda {
24  extern void setTransferGPU(bool);
25 }
26 
27 // Local helper functions
28 //------------------------------------------------------------------------------------
30 {
31  using namespace quda;
32  const double unitarize_eps = 1e-14;
33  const double max_error = 1e-10;
34  const int reunit_allow_svd = 1;
35  const int reunit_svd_only = 0;
36  const double svd_rel_error = 1e-6;
37  const double svd_abs_error = 1e-6;
38  setUnitarizeLinksConstants(unitarize_eps, max_error, reunit_allow_svd, reunit_svd_only, svd_rel_error, svd_abs_error);
39 }
40 
42 {
43  printfQuda("running the following test:\n");
44 
45  printfQuda("prec sloppy_prec link_recon sloppy_link_recon S_dimension T_dimension Ls_dimension\n");
46  printfQuda("%s %s %s %s %d/%d/%d %d %d\n", get_prec_str(prec),
48  tdim, Lsdim);
49 
50  printfQuda("Grid partition info: X Y Z T\n");
51  printfQuda(" %d %d %d %d\n", dimPartitioned(0), dimPartitioned(1), dimPartitioned(2),
52  dimPartitioned(3));
53 }
54 
55 int main(int argc, char **argv)
56 {
57  // command line options
58  auto app = make_app();
59  try {
60  app->parse(argc, argv);
61  } catch (const CLI::ParseError &e) {
62  return app->exit(e);
63  }
64 
67 
68  // initialize QMP/MPI, QUDA comms grid and RNG (host_utils.cpp)
69  initComms(argc, argv, gridsize_from_cmdline);
70 
71  // call srand() with a rank-dependent seed
72  initRand();
73 
75 
76  // initialize the QUDA library
78 
79  // *** QUDA parameters begin here.
80 
83 
84  // *** Everything between here and the timer is application specific.
86 
87  void *load_gauge[4];
88  // Allocate space on the host (always best to allocate and free in the same scope)
89  for (int dir = 0; dir < 4; dir++) { load_gauge[dir] = malloc(V * gauge_site_size * gauge_param.cpu_prec); }
90  constructHostGaugeField(load_gauge, gauge_param, argc, argv);
91  // Load the gauge field to the device
92  loadGaugeQuda((void *)load_gauge, &gauge_param);
93 
94  int *num_failures_h = (int *)mapped_malloc(sizeof(int));
95  int *num_failures_d = (int *)get_mapped_device_pointer(num_failures_h);
96  *num_failures_h = 0;
97 
98  // start the timer
99  double time0 = -((double)clock());
100 
101  {
102  using namespace quda;
104  gParam.pad = 0;
110  cudaGaugeField *gauge = new cudaGaugeField(gParam);
111 
112  int pad = 0;
113  int y[4];
114  int R[4] = {0,0,0,0};
115  for(int dir=0; dir<4; ++dir) if(comm_dim_partitioned(dir)) R[dir] = 2;
116  for(int dir=0; dir<4; ++dir) y[dir] = gauge_param.X[dir] + 2 * R[dir];
117  GaugeFieldParam gParamEx(y, prec, link_recon,
119  gParamEx.create = QUDA_ZERO_FIELD_CREATE;
120  gParamEx.order = gParam.order;
121  gParamEx.siteSubset = QUDA_FULL_SITE_SUBSET;
122  gParamEx.t_boundary = gParam.t_boundary;
123  gParamEx.nFace = 1;
124  for(int dir=0; dir<4; ++dir) gParamEx.r[dir] = R[dir];
125  cudaGaugeField *gaugeEx = new cudaGaugeField(gParamEx);
126  // CURAND random generator initialization
127  RNG *randstates = new RNG(*gauge, 1234);
128  randstates->Init();
129 
130  int nsteps = heatbath_num_steps;
131  int nwarm = heatbath_warmup_steps;
132  int nhbsteps = heatbath_num_heatbath_per_step;
133  int novrsteps = heatbath_num_overrelax_per_step;
134  bool coldstart = heatbath_coldstart;
135  double beta_value = heatbath_beta_value;
136 
137  printfQuda("Starting heatbath for beta = %f from a %s start\n", beta_value, strcmp(latfile,"") ? "loaded" : (coldstart ? "cold" : "hot"));
138  printfQuda(" %d Heatbath hits and %d overrelaxation hits per step\n", nhbsteps, novrsteps);
139  printfQuda(" %d Warmup steps\n", nwarm);
140  printfQuda(" %d Measurement steps\n", nsteps);
141 
142  if (strcmp(latfile, "")) { // Copy in loaded gauge field
143 
144  printfQuda("Loading the gauge field in %s\n", latfile);
145 
146  loadGaugeQuda(load_gauge, &gauge_param);
147  // Get pointer to internal resident gauge field
150  InitGaugeField(*gaugeEx);
152  delete extendedGaugeResident;
153 
154  } else if (link_recon != QUDA_RECONSTRUCT_8 && coldstart) {
155  InitGaugeField( *gaugeEx);
156  } else {
157  InitGaugeField( *gaugeEx, *randstates );
158  }
159 
160  // copy into regular field
161  copyExtendedGauge(*gauge, *gaugeEx, QUDA_CUDA_FIELD_LOCATION);
162 
163  // load the gauge field from gauge
164  gauge_param.gauge_order = gauge->Order();
166 
167  loadGaugeQuda(gauge->Gauge_p(), &gauge_param);
168 
170  param.compute_plaquette = QUDA_BOOLEAN_TRUE;
171  param.compute_qcharge = QUDA_BOOLEAN_TRUE;
172 
174  printfQuda("Initial gauge field plaquette = %e topological charge = %e\n", param.plaquette[0], param.qcharge);
175 
176  // Reunitarization setup
178 
179  // Do a warmup if requested
180  if (nwarm > 0) {
181  for (int step = 1; step <= nwarm; ++step) {
182  Monte(*gaugeEx, *randstates, beta_value, nhbsteps, novrsteps);
183 
184  quda::unitarizeLinks(*gaugeEx, num_failures_d);
185  if (*num_failures_h > 0) errorQuda("Error in the unitarization\n");
186  }
187  }
188 
189  // copy into regular field
190  copyExtendedGauge(*gauge, *gaugeEx, QUDA_CUDA_FIELD_LOCATION);
191 
192  // load the gauge field from gauge
193  gauge_param.gauge_order = gauge->Order();
195 
196  loadGaugeQuda(gauge->Gauge_p(), &gauge_param);
198  printfQuda("step=0 plaquette = %e topological charge = %e\n", param.plaquette[0], param.qcharge);
199 
200  freeGaugeQuda();
201 
202  for(int step=1; step<=nsteps; ++step){
203  Monte( *gaugeEx, *randstates, beta_value, nhbsteps, novrsteps);
204 
205  //Reunitarize gauge links...
206  quda::unitarizeLinks(*gaugeEx, num_failures_d);
207  if (*num_failures_h > 0) errorQuda("Error in the unitarization\n");
208 
209  // copy into regular field
210  copyExtendedGauge(*gauge, *gaugeEx, QUDA_CUDA_FIELD_LOCATION);
211 
212  loadGaugeQuda(gauge->Gauge_p(), &gauge_param);
214  printfQuda("step=%d plaquette = %e topological charge = %e\n", step, param.plaquette[0], param.qcharge);
215 
216  freeGaugeQuda();
217  }
218 
219  // Save if output string is specified
220  if (strcmp(gauge_outfile,"")) {
221 
222  printfQuda("Saving the gauge field to file %s\n", gauge_outfile);
223 
226 
227  void *cpu_gauge[4];
228  for (int dir = 0; dir < 4; dir++) { cpu_gauge[dir] = malloc(V * gauge_site_size * gauge_param.cpu_prec); }
229 
230  // copy into regular field
231  copyExtendedGauge(*gauge, *gaugeEx, QUDA_CUDA_FIELD_LOCATION);
232 
233  saveGaugeFieldQuda((void*)cpu_gauge, (void*)gauge, &gauge_param);
234 
235  write_gauge_field(gauge_outfile, cpu_gauge, gauge_param.cpu_prec, gauge_param.X, 0, (char**)0);
236 
237  for (int dir = 0; dir<4; dir++) free(cpu_gauge[dir]);
238  } else {
239  printfQuda("No output file specified.\n");
240  }
241 
242  delete gauge;
243  delete gaugeEx;
244  //Release all temporary memory used for data exchange between GPUs in multi-GPU mode
246 
247  randstates->Release();
248  delete randstates;
249  }
250 
251  // stop the timer
252  time0 += clock();
253  time0 /= CLOCKS_PER_SEC;
254 
255  // printfQuda("\nDone: %i iter / %g secs = %g Gflops, total time = %g secs\n",
256  // inv_param.iter, inv_param.secs, inv_param.gflops/inv_param.secs, time0);
257  printfQuda("\nDone, total time = %g secs\n", time0);
258 
259  host_free(num_failures_h);
260 
261  freeGaugeQuda();
262 
263  // finalize the QUDA library
264  endQuda();
265 
266  // finalize the communications layer
267  finalizeComms();
268 
269  for (int dir = 0; dir<4; dir++) free(load_gauge[dir]);
270 
271  return 0;
272 }
QudaGaugeFieldOrder Order() const
Definition: gauge_field.h:287
Class declaration to initialize and hold CURAND RNG states.
Definition: random_quda.h:23
void Release()
void Init()
int comm_dim_partitioned(int dim)
int heatbath_num_steps
QudaReconstructType link_recon_sloppy
std::shared_ptr< QUDAApp > make_app(std::string app_description, std::string app_name)
bool heatbath_coldstart
QudaReconstructType link_recon
int device_ordinal
int & ydim
char gauge_outfile[256]
char latfile[256]
int & zdim
int heatbath_num_heatbath_per_step
QudaPrecision prec
double heatbath_beta_value
int heatbath_num_overrelax_per_step
int Lsdim
int & tdim
int & xdim
std::array< int, 4 > gridsize_from_cmdline
int heatbath_warmup_steps
QudaPrecision prec_sloppy
int V
Definition: host_utils.cpp:37
void setDims(int *)
Definition: host_utils.cpp:315
QudaGaugeParam gauge_param
Definition: covdev_test.cpp:26
@ QUDA_CUDA_FIELD_LOCATION
Definition: enum_quda.h:326
@ QUDA_FULL_SITE_SUBSET
Definition: enum_quda.h:333
@ QUDA_BOOLEAN_TRUE
Definition: enum_quda.h:461
@ QUDA_RECONSTRUCT_INVALID
Definition: enum_quda.h:76
@ QUDA_RECONSTRUCT_8
Definition: enum_quda.h:72
@ 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_INVALID_PRECISION
Definition: enum_quda.h:66
@ QUDA_ZERO_FIELD_CREATE
Definition: enum_quda.h:361
@ QUDA_NULL_FIELD_CREATE
Definition: enum_quda.h:360
#define gauge_site_size
Definition: face_gauge.cpp:34
int main(int argc, char **argv)
void setReunitarizationConsts()
void display_test_info()
GaugeFieldParam gParam
int dimPartitioned(int dim)
Definition: host_utils.cpp:376
void initComms(int argc, char **argv, std::array< int, 4 > &commDims)
Definition: host_utils.cpp:255
void finalizeComms()
Definition: host_utils.cpp:292
void constructHostGaugeField(void **gauge, QudaGaugeParam &gauge_param, int argc, char **argv)
Definition: host_utils.cpp:166
void initRand()
Definition: host_utils.cpp:302
void setWilsonGaugeParam(QudaGaugeParam &gauge_param)
Definition: set_params.cpp:37
cudaGaugeField * extendedGaugeResident
#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
const char * get_prec_str(QudaPrecision prec)
Definition: misc.cpp:26
const char * get_recon_str(QudaReconstructType recon)
Definition: misc.cpp:68
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)
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 PGaugeExchangeFree()
Release all allocated memory used to exchange data between nodes.
void unitarizeLinks(GaugeField &outfield, const GaugeField &infield, int *fails)
void setTransferGPU(bool)
void copyExtendedGauge(GaugeField &out, const GaugeField &in, QudaFieldLocation location, void *Out=0, void *In=0)
QudaGaugeParam param
Definition: pack_test.cpp:18
void write_gauge_field(const char *filename, void *gauge[], QudaPrecision prec, const int *X, int argc, char *argv[])
Definition: qio_field.h:18
Main header file for the QUDA library.
QudaGaugeParam newQudaGaugeParam(void)
void saveGaugeFieldQuda(void *outGauge, void *inGauge, QudaGaugeParam *param)
void freeGaugeQuda(void)
void initQuda(int device)
QudaGaugeObservableParam newQudaGaugeObservableParam(void)
void loadGaugeQuda(void *h_gauge, QudaGaugeParam *param)
void endQuda(void)
void copyExtendedResidentGaugeQuda(void *resident_gauge, QudaFieldLocation loc)
void gaugeObservablesQuda(QudaGaugeObservableParam *param)
Calculates a variety of gauge-field observables. If a smeared gauge field is presently loaded (in gau...
QudaReconstructType reconstruct
Definition: quda.h:49
QudaLinkType type
Definition: quda.h:41
QudaFieldLocation location
Definition: quda.h:33
QudaGaugeFieldOrder gauge_order
Definition: quda.h:42
int X[4]
Definition: quda.h:35
QudaPrecision cpu_prec
Definition: quda.h:46
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
#define errorQuda(...)
Definition: util_quda.h:120