QUDA  v1.1.0
A library for QCD on GPUs
su3_test.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <time.h>
4 #include <math.h>
5 #include <string.h>
6 
7 #include <util_quda.h>
8 #include <host_utils.h>
9 #include <command_line_params.h>
10 #include <dslash_reference.h>
11 #include <misc.h>
12 
13 #include <comm_quda.h>
14 
15 // In a typical application, quda.h is the only QUDA header required.
16 #include <quda.h>
17 
18 #define MAX(a,b) ((a)>(b)?(a):(b))
19 
21 {
22  printfQuda("running the following test:\n");
23 
24  printfQuda("prec sloppy_prec link_recon sloppy_link_recon S_dimension T_dimension\n");
25  printfQuda("%s %s %s %s %d/%d/%d %d\n", get_prec_str(prec),
27  tdim);
28  switch (test_type) {
29  case 0:
30  printfQuda("\nAPE smearing\n");
31  printfQuda(" - rho %f\n", ape_smear_rho);
32  printfQuda(" - smearing steps %d\n", smear_steps);
33  printfQuda(" - Measurement interval %d\n", measurement_interval);
34  break;
35  case 1:
36  printfQuda("\nStout smearing\n");
37  printfQuda(" - rho %f\n", stout_smear_rho);
38  printfQuda(" - smearing steps %d\n", smear_steps);
39  printfQuda(" - Measurement interval %d\n", measurement_interval);
40  break;
41  case 2:
42  printfQuda("\nOver-Improved Stout smearing\n");
43  printfQuda(" - rho %f\n", stout_smear_rho);
44  printfQuda(" - epsilon %f\n", stout_smear_epsilon);
45  printfQuda(" - smearing steps %d\n", smear_steps);
46  printfQuda(" - Measurement interval %d\n", measurement_interval);
47  break;
48  case 3:
49  printfQuda("\nWilson Flow\n");
50  printfQuda(" - epsilon %f\n", wflow_epsilon);
51  printfQuda(" - Wilson flow steps %d\n", wflow_steps);
52  printfQuda(" - Wilson flow type %s\n", wflow_type == QUDA_WFLOW_TYPE_WILSON ? "Wilson" : "Symanzik");
53  printfQuda(" - Measurement interval %d\n", measurement_interval);
54  break;
55  default: errorQuda("Undefined test type %d given", test_type);
56  }
57 
58  printfQuda("Grid partition info: X Y Z T\n");
59  printfQuda(" %d %d %d %d\n", dimPartitioned(0), dimPartitioned(1), dimPartitioned(2),
60  dimPartitioned(3));
61  return;
62 }
63 
65 
66  gauge_param.X[0] = xdim;
67  gauge_param.X[1] = ydim;
68  gauge_param.X[2] = zdim;
69  gauge_param.X[3] = tdim;
70 
75 
77 
80 
83 
85 
86  gauge_param.ga_pad = 0;
87  // For multi-GPU, ga_pad must be large enough to store a time-slice
88 #ifdef MULTI_GPU
89  int x_face_size = gauge_param.X[1]*gauge_param.X[2]*gauge_param.X[3]/2;
90  int y_face_size = gauge_param.X[0]*gauge_param.X[2]*gauge_param.X[3]/2;
91  int z_face_size = gauge_param.X[0]*gauge_param.X[1]*gauge_param.X[3]/2;
92  int t_face_size = gauge_param.X[0]*gauge_param.X[1]*gauge_param.X[2]/2;
93  int pad_size =MAX(x_face_size, y_face_size);
94  pad_size = MAX(pad_size, z_face_size);
95  pad_size = MAX(pad_size, t_face_size);
96  gauge_param.ga_pad = pad_size;
97 #endif
98 }
99 
100 int main(int argc, char **argv)
101 {
102 
103  auto app = make_app();
105  CLI::TransformPairs<int> test_type_map {{"APE", 0}, {"Stout", 1}, {"Over-Improved Stout", 2}, {"Wilson Flow", 3}};
106  app->add_option("--test", test_type, "Test method")->transform(CLI::CheckedTransformer(test_type_map));
107 
108  try {
109  app->parse(argc, argv);
110  } catch (const CLI::ParseError &e) {
111  return app->exit(e);
112  }
113 
114  // initialize QMP/MPI, QUDA comms grid and RNG (host_utils.cpp)
115  initComms(argc, argv, gridsize_from_cmdline);
116 
119  prec_sloppy = prec;
122 
125 
126  void *gauge[4], *new_gauge[4];
127 
128  for (int dir = 0; dir < 4; dir++) {
129  gauge[dir] = malloc(V * gauge_site_size * host_gauge_data_type_size);
130  new_gauge[dir] = malloc(V * gauge_site_size * host_gauge_data_type_size);
131  }
132 
134 
136 
137  // call srand() with a rank-dependent seed
138  initRand();
139 
140  constructHostGaugeField(gauge, gauge_param, argc, argv);
141  // Load the gauge field to the device
142  loadGaugeQuda((void *)gauge, &gauge_param);
143  saveGaugeQuda(new_gauge, &gauge_param);
144 
145  double plaq[3];
146  plaqQuda(plaq);
147  printfQuda("Computed plaquette gauge precise is %.16e (spatial = %.16e, temporal = %.16e)\n", plaq[0], plaq[1],
148  plaq[2]);
149 
150 #ifdef GPU_GAUGE_TOOLS
151 
152  // All user inputs now defined
154 
155  // Topological charge and gauge energy
156  double q_charge_check = 0.0;
157  // Size of floating point data
158  size_t data_size = prec == QUDA_DOUBLE_PRECISION ? sizeof(double) : sizeof(float);
159  size_t array_size = V * data_size;
160  void *qDensity = malloc(array_size);
161  // start the timer
162  double time0 = -((double)clock());
164  param.compute_qcharge = QUDA_BOOLEAN_TRUE;
165  param.compute_qcharge_density = QUDA_BOOLEAN_TRUE;
166  param.qcharge_density = qDensity;
167 
169 
170  // stop the timer
171  time0 += clock();
172  time0 /= CLOCKS_PER_SEC;
173  printfQuda("Computed Etot, Es, Et, Q is\n%.16e %.16e, %.16e %.16e\nDone in %g secs\n", param.energy[0],
174  param.energy[1], param.energy[2], param.qcharge, time0);
175 
176  // Ensure host array sums to return value
177  if (prec == QUDA_DOUBLE_PRECISION) {
178  for (int i = 0; i < V; i++) q_charge_check += ((double *)qDensity)[i];
179  } else {
180  for (int i = 0; i < V; i++) q_charge_check += ((float *)qDensity)[i];
181  }
182 
183  // Q charge Reduction and normalisation
184  comm_allreduce(&q_charge_check);
185 
186  printfQuda("GPU value %e and host density sum %e. Q charge deviation: %e\n", param.qcharge, q_charge_check,
187  param.qcharge - q_charge_check);
188 
189  // Gauge Smearing Routines
190  //---------------------------------------------------------------------------
191  // Stout smearing should be equivalent to APE smearing
192  // on D dimensional lattices for rho = alpha/2*(D-1).
193  // Typical APE values are aplha=0.6, rho=0.1 for Stout.
194  switch (test_type) {
195  case 0:
196  // APE
197  // start the timer
198  time0 = -((double)clock());
200  // stop the timer
201  time0 += clock();
202  time0 /= CLOCKS_PER_SEC;
203  printfQuda("Total time for APE = %g secs\n", time0);
204  break;
205  case 1:
206  // STOUT
207  // start the timer
208  time0 = -((double)clock());
210  // stop the timer
211  time0 += clock();
212  time0 /= CLOCKS_PER_SEC;
213  printfQuda("Total time for STOUT = %g secs\n", time0);
214  break;
215 
216  // Topological charge routines
217  //---------------------------------------------------------------------------
218  case 2:
219  // Over-Improved STOUT
220  // start the timer
221  time0 = -((double)clock());
223  // stop the timer
224  time0 += clock();
225  time0 /= CLOCKS_PER_SEC;
226  printfQuda("Total time for Over Improved STOUT = %g secs\n", time0);
227  break;
228  case 3:
229  // Wilson Flow
230  // Start the timer
231  time0 = -((double)clock());
233  // stop the timer
234  time0 += clock();
235  time0 /= CLOCKS_PER_SEC;
236  printfQuda("Total time for Wilson Flow = %g secs\n", time0);
237  break;
238  default: errorQuda("Undefined test type %d given", test_type);
239  }
240 
241 #else
242  printfQuda("Skipping other gauge tests since gauge tools have not been compiled\n");
243 #endif
244 
245  if (verify_results) check_gauge(gauge, new_gauge, 1e-3, gauge_param.cpu_prec);
246 
247  freeGaugeQuda();
248  endQuda();
249 
250  // release memory
251  for (int dir = 0; dir < 4; dir++) {
252  free(gauge[dir]);
253  free(new_gauge[dir]);
254  }
255 
256  finalizeComms();
257  return 0;
258 }
void comm_allreduce(double *data)
QudaWFlowType wflow_type
double stout_smear_epsilon
QudaReconstructType link_recon_sloppy
std::shared_ptr< QUDAApp > make_app(std::string app_description, std::string app_name)
QudaReconstructType link_recon
int test_type
double anisotropy
int device_ordinal
QudaVerbosity verbosity
int & ydim
double stout_smear_rho
bool verify_results
double wflow_epsilon
int smear_steps
int wflow_steps
int & zdim
int measurement_interval
double ape_smear_rho
QudaPrecision prec
void add_su3_option_group(std::shared_ptr< QUDAApp > quda_app)
int & tdim
int & xdim
std::array< int, 4 > gridsize_from_cmdline
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_BOOLEAN_TRUE
Definition: enum_quda.h:461
@ QUDA_RECONSTRUCT_INVALID
Definition: enum_quda.h:76
@ QUDA_PERIODIC_T
Definition: enum_quda.h:57
@ QUDA_GAUGE_FIXED_NO
Definition: enum_quda.h:80
@ QUDA_DOUBLE_PRECISION
Definition: enum_quda.h:65
@ QUDA_INVALID_PRECISION
Definition: enum_quda.h:66
@ QUDA_QDP_GAUGE_ORDER
Definition: enum_quda.h:44
@ QUDA_WILSON_LINKS
Definition: enum_quda.h:30
@ QUDA_WFLOW_TYPE_WILSON
Definition: enum_quda.h:549
#define gauge_site_size
Definition: face_gauge.cpp:34
size_t host_gauge_data_type_size
Definition: host_utils.cpp:65
int dimPartitioned(int dim)
Definition: host_utils.cpp:376
QudaPrecision & cuda_prec
Definition: host_utils.cpp:58
void initComms(int argc, char **argv, std::array< int, 4 > &commDims)
Definition: host_utils.cpp:255
QudaPrecision & cuda_prec_sloppy
Definition: host_utils.cpp:59
void finalizeComms()
Definition: host_utils.cpp:292
QudaPrecision & cpu_prec
Definition: host_utils.cpp:57
void constructHostGaugeField(void **gauge, QudaGaugeParam &gauge_param, int argc, char **argv)
Definition: host_utils.cpp:166
void check_gauge(void **oldG, void **newG, double epsilon, QudaPrecision precision)
void initRand()
Definition: host_utils.cpp:302
const char * get_prec_str(QudaPrecision prec)
Definition: misc.cpp:26
const char * get_recon_str(QudaReconstructType recon)
Definition: misc.cpp:68
QudaGaugeParam param
Definition: pack_test.cpp:18
Main header file for the QUDA library.
void plaqQuda(double plaq[3])
void performAPEnStep(unsigned int n_steps, double alpha, int meas_interval)
QudaGaugeParam newQudaGaugeParam(void)
void freeGaugeQuda(void)
void initQuda(int device)
QudaGaugeObservableParam newQudaGaugeObservableParam(void)
void loadGaugeQuda(void *h_gauge, QudaGaugeParam *param)
void saveGaugeQuda(void *h_gauge, QudaGaugeParam *param)
void performWFlownStep(unsigned int n_steps, double step_size, int meas_interval, QudaWFlowType wflow_type)
void endQuda(void)
void gaugeObservablesQuda(QudaGaugeObservableParam *param)
Calculates a variety of gauge-field observables. If a smeared gauge field is presently loaded (in gau...
void performSTOUTnStep(unsigned int n_steps, double rho, int meas_interval)
void performOvrImpSTOUTnStep(unsigned int n_steps, double rho, double epsilon, int meas_interval)
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
int main(int argc, char **argv)
Definition: su3_test.cpp:100
void display_test_info()
Definition: su3_test.cpp:20
void setGaugeParam(QudaGaugeParam &gauge_param)
Definition: su3_test.cpp:64
#define MAX(a, b)
Definition: su3_test.cpp:18
#define printfQuda(...)
Definition: util_quda.h:114
void setVerbosity(QudaVerbosity verbosity)
Definition: util_quda.cpp:25
#define errorQuda(...)
Definition: util_quda.h:120