QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
unitarize_link_test.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/time.h>
5 
6  #include <cuda.h>
7 #include <cuda_runtime.h>
8 
9 #include "quda.h"
10 #include "gauge_field.h"
11 #include "test_util.h"
12 #include "llfat_reference.h"
13 #include "misc.h"
14 #include "util_quda.h"
15 #include "llfat_quda.h"
16 #include "fat_force_quda.h"
17 #include "hisq_links_quda.h"
18 #include "dslash_quda.h"
19 #include "ks_improved_force.h"
20 
21 #ifdef MULTI_GPU
22 #include "face_quda.h"
23 #include "comm_quda.h"
24 #endif
25 
26 #define TDIFF(a,b) (b.tv_sec - a.tv_sec + 0.000001*(b.tv_usec - a.tv_usec))
27 
28 using namespace quda;
29 
30 
31 extern void usage(char** argv);
32 
33 extern int device;
34 
35 static double unitarize_eps = 1e-6;
36 static bool reunit_allow_svd = true;
37 static bool reunit_svd_only = false;
38 static double svd_rel_error = 1e-4;
39 static double svd_abs_error = 1e-5;
40 static double max_allowed_error = 1e-11;
41 
42 extern int xdim, ydim, zdim, tdim;
43 extern int gridsize_from_cmdline[];
44 
46 extern QudaPrecision prec;
49 
50 static size_t gSize;
51 
52 
53 namespace quda {
54  namespace fatlink {
55  void initLatticeConstants(const LatticeField &lat, TimeProfile &profile);
56  }
57 }
58 
59  static int
60 unitarize_link_test()
61 {
62 
63  QudaGaugeParam qudaGaugeParam = newQudaGaugeParam();
64 
66 
67  cpu_prec = prec;
68  gSize = cpu_prec;
69  qudaGaugeParam.anisotropy = 1.0;
70 
71  qudaGaugeParam.X[0] = xdim;
72  qudaGaugeParam.X[1] = ydim;
73  qudaGaugeParam.X[2] = zdim;
74  qudaGaugeParam.X[3] = tdim;
75 
76  setDims(qudaGaugeParam.X);
77 
80 
81  qudaGaugeParam.cpu_prec = link_prec;
82  qudaGaugeParam.cuda_prec = link_prec;
83  qudaGaugeParam.reconstruct = link_recon;
84  qudaGaugeParam.type = QUDA_WILSON_LINKS;
85 
86 
87 
88  qudaGaugeParam.t_boundary = QUDA_PERIODIC_T;
89  qudaGaugeParam.anisotropy = 1.0;
90  qudaGaugeParam.cuda_prec_sloppy = prec;
91  qudaGaugeParam.reconstruct_sloppy = QUDA_RECONSTRUCT_NO;
92  qudaGaugeParam.gauge_fix = QUDA_GAUGE_FIXED_NO;
93  qudaGaugeParam.ga_pad = 0;
94  qudaGaugeParam.gaugeGiB = 0;
95 
96 
97  qudaGaugeParam.cpu_prec = cpu_prec;
98  qudaGaugeParam.cuda_prec = prec;
99  qudaGaugeParam.gauge_order = gauge_order;
100  qudaGaugeParam.type=QUDA_WILSON_LINKS;
101  qudaGaugeParam.reconstruct = link_recon;
105 
107 
108  GaugeFieldParam gParam(0, qudaGaugeParam);
109  gParam.pad = 0;
113 
114  gParam.pad = 0;
119  cudaGaugeField *cudaULink = new cudaGaugeField(gParam);
120 
122 
123  TimeProfile profile("dummy");
124 
125  quda::fatlink::initLatticeConstants(*cudaFatLink, profile);
126 
127  void* fatlink = (void*)malloc(4*V*gaugeSiteSize*gSize);
128  if(fatlink == NULL){
129  errorQuda("ERROR: allocating fatlink failed\n");
130  }
131 
132  void* sitelink[4];
133  for(int i=0;i < 4;i++){
134  cudaMallocHost((void**)&sitelink[i], V*gaugeSiteSize*gSize);
135  if(sitelink[i] == NULL){
136  errorQuda("ERROR; allocate sitelink[%d] failed\n", i);
137  }
138  }
139 
140  createSiteLinkCPU(sitelink, qudaGaugeParam.cpu_prec, 1);
141  void* inlink = (void*)malloc(4*V*gaugeSiteSize*gSize);
142 
143 
145  double* link = reinterpret_cast<double*>(inlink);
146  for(int dir=0; dir<4; ++dir){
147  double* slink = reinterpret_cast<double*>(sitelink[dir]);
148  for(int i=0; i<V; ++i){
149  for(int j=0; j<gaugeSiteSize; j++){
150  link[(i*4 + dir)*gaugeSiteSize + j] = slink[i*gaugeSiteSize + j];
151  }
152  }
153  }
154  }else if(prec == QUDA_SINGLE_PRECISION){
155  float* link = reinterpret_cast<float*>(inlink);
156  for(int dir=0; dir<4; ++dir){
157  float* slink = reinterpret_cast<float*>(sitelink[dir]);
158  for(int i=0; i<V; ++i){
159  for(int j=0; j<gaugeSiteSize; j++){
160  link[(i*4 + dir)*gaugeSiteSize + j] = slink[i*gaugeSiteSize + j];
161  }
162  }
163  }
164  }
165 
166 
167  double act_path_coeff[6];
168  act_path_coeff[0] = 0.625000;
169  act_path_coeff[1] = -0.058479;
170  act_path_coeff[2] = -0.087719;
171  act_path_coeff[3] = 0.030778;
172  act_path_coeff[4] = -0.007200;
173  act_path_coeff[5] = -0.123113;
174 
175 
176 
177  computeKSLinkQuda(fatlink, NULL, NULL, inlink, act_path_coeff, &qudaGaugeParam,
179 
180 
181  void* fatlink_2d[4];
182  for(int dir=0; dir<4; ++dir){
183  fatlink_2d[dir] = (char*)fatlink + dir*V*gaugeSiteSize*gSize;
184  }
185 
186 
188  gParam.gauge = fatlink_2d;
189  cpuGaugeField *cpuOutLink = new cpuGaugeField(gParam);
190 
191 
192 
193  cudaFatLink->loadCPUField(*cpuOutLink, QUDA_CPU_FIELD_LOCATION);
194 
195 
196 
197  setUnitarizeLinksConstants(unitarize_eps,
198  max_allowed_error,
199  reunit_allow_svd,
200  reunit_svd_only,
201  svd_rel_error,
202  svd_abs_error);
203 
205 
206  int* num_failures_dev;
207  if(cudaMalloc(&num_failures_dev, sizeof(int)) != cudaSuccess){
208  errorQuda("cudaMalloc failed for num_failures_dev\n");
209  }
210  cudaMemset(num_failures_dev, 0, sizeof(int));
211 
212  struct timeval t0, t1;
213 
214  gettimeofday(&t0,NULL);
215  unitarizeLinksCuda(qudaGaugeParam,*cudaFatLink, cudaULink, num_failures_dev);
216  cudaDeviceSynchronize();
217  gettimeofday(&t1,NULL);
218 
219  int num_failures=0;
220  cudaMemcpy(&num_failures, num_failures_dev, sizeof(int), cudaMemcpyDeviceToHost);
221 
222  delete cpuOutLink;
223  delete cudaFatLink;
224  delete cudaULink;
225  for(int dir=0; dir<4; ++dir) cudaFreeHost(sitelink[dir]);
226 
227  free(fatlink);
228 
229  cudaFree(num_failures_dev);
230 
231  free(inlink);
232 #ifdef MULTI_GPU
234 #endif
235  endQuda();
236 
237  printfQuda("Unitarization time: %g ms\n", TDIFF(t0,t1)*1000);
238  return num_failures;
239 }
240 
241  static void
243 {
244  printfQuda("running the following test:\n");
245 
246  printfQuda("link_precision link_reconstruct space_dimension T_dimension algorithm max allowed error\n");
247  printfQuda("%s %s %d/%d/%d/ %d %s %g \n",
249  get_recon_str(link_recon),
250  xdim, ydim, zdim, tdim,
251  get_unitarization_str(reunit_svd_only),
252  max_allowed_error);
253 
254 #ifdef MULTI_GPU
255  printfQuda("Grid partition info: X Y Z T\n");
256  printfQuda(" %d %d %d %d\n",
257  dimPartitioned(0),
258  dimPartitioned(1),
259  dimPartitioned(2),
260  dimPartitioned(3));
261 #endif
262 
263  return ;
264 
265 }
266 
267 
268  int
269 main(int argc, char **argv)
270 {
271  //default to 18 reconstruct, 8^3 x 8
272  link_recon = QUDA_RECONSTRUCT_NO;
273  xdim=ydim=zdim=tdim=8;
275 
276  int i;
277  for (i=1; i<argc; i++){
278  if(process_command_line_option(argc, argv, &i) == 0){
279  continue;
280  }
281 
282  fprintf(stderr, "ERROR: Invalid option:%s\n", argv[i]);
283  usage(argv);
284  }
285 
286  initComms(argc, argv, gridsize_from_cmdline);
287 
289  int num_failures = unitarize_link_test();
290  int num_procs = 1;
291 #ifdef MULTI_GPU
292  comm_allreduce_int(&num_failures);
293  num_procs = comm_size();
294 #endif
295 
296  printfQuda("Number of failures = %d\n", num_failures);
297  if(num_failures > 0){
298  printfQuda("Failure rate = %lf\n", num_failures/(4.0*V*num_procs));
299  printfQuda("You may want to increase the error tolerance or vary the unitarization parameters\n");
300  }else{
301  printfQuda("Unitarization successfull!\n");
302  }
303  finalizeComms();
304 
305  return EXIT_SUCCESS;
306 }
307 
308 
int dimPartitioned(int dim)
Definition: test_util.cpp:1577
QudaReconstructType reconstruct_sloppy
Definition: quda.h:46
double anisotropy
Definition: quda.h:31
void exchange_llfat_cleanup(void)
void endQuda(void)
enum QudaPrecision_s QudaPrecision
int V
Definition: test_util.cpp:29
int ga_pad
Definition: quda.h:53
QudaGaugeFixed gauge_fix
Definition: quda.h:51
void display_test_info()
Definition: blas_test.cu:56
QudaLinkType type
Definition: quda.h:35
#define errorQuda(...)
Definition: util_quda.h:73
void setUnitarizeLinksConstants(double unitarize_eps, double max_error, bool allow_svd, bool svd_only, double svd_rel_error, double svd_abs_error, bool check_unitarization=true)
void setDims(int *)
Definition: test_util.cpp:88
void computeKSLinkQuda(void *fatlink, void *longlink, void *ulink, void *inlink, double *path_coeff, QudaGaugeParam *param, QudaComputeFatMethod method)
int process_command_line_option(int argc, char **argv, int *idx)
Definition: test_util.cpp:1635
#define gaugeSiteSize
void finalizeComms()
Definition: test_util.cpp:65
QudaGaugeFieldOrder gauge_order
Definition: quda.h:36
const char * get_prec_str(QudaPrecision prec)
Definition: misc.cpp:658
void setFatLinkPadding(QudaComputeFatMethod method, QudaGaugeParam *param)
QudaPrecision cpu_prec
Definition: dslash_test.cpp:34
void setUnitarizeLinksPadding(int input_padding, int output_padding)
QudaPrecision link_prec
void createSiteLinkCPU(void **link, QudaPrecision precision, int phase)
Definition: test_util.cpp:1166
const char * get_unitarization_str(bool svd_only)
Definition: misc.cpp:684
int comm_size(void)
Definition: comm_mpi.cpp:86
void initQuda(int device)
cudaGaugeField * cudaFatLink
const char * get_recon_str(QudaReconstructType recon)
Definition: misc.cpp:724
int preserve_gauge
Definition: quda.h:62
QudaGaugeFieldOrder order
Definition: gauge_field.h:15
QudaPrecision cuda_prec_sloppy
Definition: quda.h:45
void loadCPUField(const cpuGaugeField &, const QudaFieldLocation &)
enum QudaGaugeFieldOrder_s QudaGaugeFieldOrder
QudaReconstructType reconstruct
Definition: quda.h:43
QudaPrecision cuda_prec
Definition: quda.h:42
int X[4]
Definition: quda.h:29
void unitarizeLinksCuda(const QudaGaugeParam &param, cudaGaugeField &infield, cudaGaugeField *outfield, int *num_failures)
QudaGhostExchange ghostExchange
Definition: gauge_field.h:40
double gaugeGiB
Definition: quda.h:60
GaugeFieldParam gParam
QudaGaugeFieldOrder gauge_order
enum QudaReconstructType_s QudaReconstructType
Main header file for the QUDA library.
QudaLinkType link_type
Definition: gauge_field.h:17
#define printfQuda(...)
Definition: util_quda.h:67
QudaTboundary t_boundary
Definition: quda.h:38
void comm_allreduce_int(int *data)
Definition: comm_mpi.cpp:225
QudaReconstructType reconstruct
Definition: gauge_field.h:14
QudaFieldCreate create
Definition: gauge_field.h:26
void initComms(int argc, char **argv, const int *commDims)
Definition: test_util.cpp:48
QudaPrecision cpu_prec
Definition: quda.h:40
QudaGaugeParam newQudaGaugeParam(void)
void * fatlink[4]