QUDA  v1.1.0
A library for QCD on GPUs
staggered_eigensolve_test.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 // QUDA headers
7 #include <quda.h>
8 
9 // External headers
10 #include <misc.h>
11 #include <host_utils.h>
12 #include <command_line_params.h>
13 #include <dslash_reference.h>
14 #include <staggered_gauge_utils.h>
15 #include <llfat_utils.h>
16 #include <qio_field.h>
17 
18 #define MAX(a, b) ((a) > (b) ? (a) : (b))
19 
21 {
22  printfQuda("running the following test:\n");
23  printfQuda("prec sloppy_prec link_recon sloppy_link_recon test_type S_dimension T_dimension\n");
24  printfQuda("%s %s %s %s %s %d/%d/%d %d \n", get_prec_str(prec),
27 
28  printfQuda("\n Eigensolver parameters\n");
29  printfQuda(" - solver mode %s\n", get_eig_type_str(eig_type));
30  printfQuda(" - spectrum requested %s\n", get_eig_spectrum_str(eig_spectrum));
31  if (eig_type == QUDA_EIG_BLK_TR_LANCZOS) printfQuda(" - eigenvector block size %d\n", eig_block_size);
32  printfQuda(" - number of eigenvectors requested %d\n", eig_n_conv);
33  printfQuda(" - size of eigenvector search space %d\n", eig_n_ev);
34  printfQuda(" - size of Krylov space %d\n", eig_n_kr);
35  printfQuda(" - solver tolerance %e\n", eig_tol);
36  printfQuda(" - convergence required (%s)\n", eig_require_convergence ? "true" : "false");
37  if (eig_compute_svd) {
38  printfQuda(" - Operator: MdagM. Will compute SVD of M\n");
39  printfQuda(" - ***********************************************************\n");
40  printfQuda(" - **** Overriding any previous choices of operator type. ****\n");
41  printfQuda(" - **** SVD demands normal operator, will use MdagM ****\n");
42  printfQuda(" - ***********************************************************\n");
43  } else {
44  printfQuda(" - Operator: daggered (%s) , norm-op (%s)\n", eig_use_dagger ? "true" : "false",
45  eig_use_normop ? "true" : "false");
46  }
47  if (eig_use_poly_acc) {
48  printfQuda(" - Chebyshev polynomial degree %d\n", eig_poly_deg);
49  printfQuda(" - Chebyshev polynomial minumum %e\n", eig_amin);
50  if (eig_amax < 0)
51  printfQuda(" - Chebyshev polynomial maximum will be computed\n");
52  else
53  printfQuda(" - Chebyshev polynomial maximum %e\n\n", eig_amax);
54  }
55 
56  printfQuda("Grid partition info: X Y Z T\n");
57  printfQuda(" %d %d %d %d\n", dimPartitioned(0), dimPartitioned(1), dimPartitioned(2),
58  dimPartitioned(3));
59 }
60 
61 int main(int argc, char **argv)
62 {
63  // Set a default
65 
66  auto app = make_app();
68  CLI::TransformPairs<int> test_type_map {{"full", 0}, {"even", 3}, {"odd", 4}};
69  app->add_option("--test", test_type, "Test method")->transform(CLI::CheckedTransformer(test_type_map));
70 
71  try {
72  app->parse(argc, argv);
73  } catch (const CLI::ParseError &e) {
74  return app->exit(e);
75  }
76 
77  // initialize QMP/MPI, QUDA comms grid and RNG (host_utils.cpp)
78  initComms(argc, argv, gridsize_from_cmdline);
79 
80  // Set values for precisions via the command line.
82 
83  // Only these fermions are supported in this file. Ensure a reasonable default,
84  // ensure that the default is improved staggered
86  printfQuda("dslash_type %s not supported, defaulting to %s\n", get_dslash_str(dslash_type),
89  }
90 
92 
94 
95  // Set QUDA internal parameters
98  // Though no inversions are performed, the inv_param
99  // structure contains all the information we need to
100  // construct the dirac operator. We encapsualte the
101  // inv_param structure inside the eig_param structure
102  // to avoid any confusion
103  QudaInvertParam eig_inv_param = newQudaInvertParam();
104  setStaggeredInvertParam(eig_inv_param);
105  QudaEigParam eig_param = newQudaEigParam();
106  setEigParam(eig_param);
107  // We encapsulate the eigensolver parameters inside the invert parameter structure
108  eig_param.invert_param = &eig_inv_param;
109 
110  if (eig_param.arpack_check && !(prec == QUDA_DOUBLE_PRECISION)) {
111  errorQuda("ARPACK check only available in double precision");
112  }
113 
115 
117  dw_setDims(gauge_param.X, 1); // so we can use 5-d indexing from dwf
118 
119  // Staggered Gauge construct START
120  //-----------------------------------------------------------------------------------
121  void *qdp_inlink[4] = {nullptr, nullptr, nullptr, nullptr};
122  void *qdp_fatlink[4] = {nullptr, nullptr, nullptr, nullptr};
123  void *qdp_longlink[4] = {nullptr, nullptr, nullptr, nullptr};
124  void *milc_fatlink = nullptr;
125  void *milc_longlink = nullptr;
126 
127  for (int dir = 0; dir < 4; dir++) {
128  qdp_inlink[dir] = malloc(V * gauge_site_size * host_gauge_data_type_size);
129  qdp_fatlink[dir] = malloc(V * gauge_site_size * host_gauge_data_type_size);
130  qdp_longlink[dir] = malloc(V * gauge_site_size * host_gauge_data_type_size);
131  }
132  milc_fatlink = malloc(4 * V * gauge_site_size * host_gauge_data_type_size);
133  milc_longlink = malloc(4 * V * gauge_site_size * host_gauge_data_type_size);
134 
135  constructStaggeredHostGaugeField(qdp_inlink, qdp_longlink, qdp_fatlink, gauge_param, argc, argv);
136 
137  // Compute plaquette. Routine is aware that the gauge fields already have the phases on them.
138  double plaq[3];
140  printfQuda("Computed plaquette is %e (spatial = %e, temporal = %e)\n", plaq[0], plaq[1], plaq[2]);
141 
143  // Compute fat link plaquette
145  printfQuda("Computed fat link plaquette is %e (spatial = %e, temporal = %e)\n", plaq[0], plaq[1], plaq[2]);
146  }
147 
148  // Reorder gauge fields to MILC order
150  reorderQDPtoMILC(milc_longlink, qdp_longlink, V, gauge_site_size, gauge_param.cpu_prec, gauge_param.cpu_prec);
151 
152  loadFatLongGaugeQuda(milc_fatlink, milc_longlink, gauge_param);
153 
154  // Staggered Gauge construct END
155  //-----------------------------------------------------------------------------------
156 
157  // Host side arrays to store the eigenpairs computed by QUDA
158  void **host_evecs = (void **)malloc(eig_n_conv * sizeof(void *));
159  for (int i = 0; i < eig_n_conv; i++) {
160  host_evecs[i] = (void *)malloc(V * stag_spinor_site_size * eig_inv_param.cpu_prec);
161  }
162  double _Complex *host_evals = (double _Complex *)malloc(eig_param.n_ev * sizeof(double _Complex));
163 
164  double time = 0.0;
165 
166  // QUDA eigensolver test
167  //----------------------------------------------------------------------------
168  switch (test_type) {
169  case 0: // full parity solution
170  case 3: // even
171  case 4: // odd
172  // This function returns the host_evecs and host_evals pointers, populated with
173  // the requested data, at the requested prec. All the information needed to
174  // perfom the solve is in the eig_param container.
175  // If eig_param.arpack_check == true and precision is double, the routine will
176  // use ARPACK rather than the GPU.
177 
178  time = -((double)clock());
179  eigensolveQuda(host_evecs, host_evals, &eig_param);
180  time += (double)clock();
181 
182  printfQuda("Time for %s solution = %f\n", eig_param.arpack_check ? "ARPACK" : "QUDA", time / CLOCKS_PER_SEC);
183  break;
184 
185  default: errorQuda("Unsupported test type");
186 
187  } // switch
188 
189  // Deallocate host memory
190  for (int i = 0; i < eig_n_conv; i++) free(host_evecs[i]);
191  free(host_evecs);
192  free(host_evals);
193 
194  // Clean up gauge fields.
195  for (int dir = 0; dir < 4; dir++) {
196  if (qdp_inlink[dir] != nullptr) {
197  free(qdp_inlink[dir]);
198  qdp_inlink[dir] = nullptr;
199  }
200  if (qdp_fatlink[dir] != nullptr) {
201  free(qdp_fatlink[dir]);
202  qdp_fatlink[dir] = nullptr;
203  }
204  if (qdp_longlink[dir] != nullptr) {
205  free(qdp_longlink[dir]);
206  qdp_longlink[dir] = nullptr;
207  }
208  }
209  if (milc_fatlink != nullptr) {
210  free(milc_fatlink);
211  milc_fatlink = nullptr;
212  }
213  if (milc_longlink != nullptr) {
214  free(milc_longlink);
215  milc_longlink = nullptr;
216  }
217 
218  endQuda();
219  finalizeComms();
220 }
QudaSolveType solve_type
int eig_poly_deg
QudaEigType eig_type
QudaReconstructType link_recon_sloppy
int eig_n_ev
std::shared_ptr< QUDAApp > make_app(std::string app_description, std::string app_name)
double eig_tol
QudaReconstructType link_recon
int test_type
int device_ordinal
bool eig_compute_svd
int & ydim
bool eig_use_poly_acc
int eig_block_size
double eig_amax
bool eig_use_dagger
int & zdim
QudaDslashType dslash_type
bool eig_use_normop
int eig_n_kr
void add_eigen_option_group(std::shared_ptr< QUDAApp > quda_app)
int eig_n_conv
QudaEigSpectrumType eig_spectrum
QudaPrecision prec
bool eig_require_convergence
int & tdim
int & xdim
double eig_amin
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_STAGGERED_DSLASH
Definition: enum_quda.h:97
@ QUDA_ASQTAD_DSLASH
Definition: enum_quda.h:98
@ QUDA_LAPLACE_DSLASH
Definition: enum_quda.h:101
@ QUDA_EIG_BLK_TR_LANCZOS
Definition: enum_quda.h:138
@ QUDA_DOUBLE_PRECISION
Definition: enum_quda.h:65
@ QUDA_INVALID_SOLVE
Definition: enum_quda.h:175
#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
void initComms(int argc, char **argv, std::array< int, 4 > &commDims)
Definition: host_utils.cpp:255
void finalizeComms()
Definition: host_utils.cpp:292
void dw_setDims(int *X, const int L5)
Definition: host_utils.cpp:353
void setQudaPrecisions()
Definition: host_utils.cpp:69
void setQudaStaggeredEigTestParams()
void setStaggeredInvertParam(QudaInvertParam &inv_param)
Definition: set_params.cpp:868
#define stag_spinor_site_size
Definition: host_utils.h:10
void reorderQDPtoMILC(void *milc_out, void **qdp_in, int V, int siteSize, QudaPrecision out_precision, QudaPrecision in_precision)
void setEigParam(QudaEigParam &eig_param)
Definition: set_params.cpp:263
void setStaggeredGaugeParam(QudaGaugeParam &gauge_param)
Definition: set_params.cpp:69
void constructStaggeredHostGaugeField(void **qdp_inlink, void **qdp_longlink, void **qdp_fatlink, QudaGaugeParam &gauge_param, int argc, char **argv)
void loadFatLongGaugeQuda(QudaInvertParam *inv_param, QudaGaugeParam *gauge_param, void *milc_fatlinks, void *milc_longlinks)
const char * get_prec_str(QudaPrecision prec)
Definition: misc.cpp:26
const char * get_eig_spectrum_str(QudaEigSpectrumType type)
Definition: misc.cpp:154
const char * get_dslash_str(QudaDslashType type)
Definition: misc.cpp:118
const char * get_eig_type_str(QudaEigType type)
Definition: misc.cpp:171
const char * get_staggered_test_type(int t)
Definition: misc.cpp:101
const char * get_recon_str(QudaReconstructType recon)
Definition: misc.cpp:68
Main header file for the QUDA library.
QudaGaugeParam newQudaGaugeParam(void)
void eigensolveQuda(void **h_evecs, double_complex *h_evals, QudaEigParam *param)
void initQuda(int device)
QudaInvertParam newQudaInvertParam(void)
QudaEigParam newQudaEigParam(void)
void endQuda(void)
int main(int argc, char **argv)
void display_test_info()
void computeStaggeredPlaquetteQDPOrder(void **qdp_link, double plaq[3], const QudaGaugeParam &gauge_param_in, const QudaDslashType dslash_type)
QudaBoolean arpack_check
Definition: quda.h:492
int n_ev
Definition: quda.h:469
QudaInvertParam * invert_param
Definition: quda.h:413
int X[4]
Definition: quda.h:35
QudaPrecision cpu_prec
Definition: quda.h:46
QudaPrecision cpu_prec
Definition: quda.h:237
#define printfQuda(...)
Definition: util_quda.h:114
#define errorQuda(...)
Definition: util_quda.h:120