QUDA  v1.1.0
A library for QCD on GPUs
eigensolve_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 #include <algorithm>
7 
8 #include <host_utils.h>
9 #include <command_line_params.h>
10 #include "misc.h"
11 
12 // In a typical application, quda.h is the only QUDA header required.
13 #include <quda.h>
14 
15 namespace quda
16 {
17  extern void setTransferGPU(bool);
18 }
19 
21 {
22  printfQuda("running the following test:\n");
23 
24  printfQuda("prec sloppy_prec link_recon sloppy_link_recon S_dimension T_dimension Ls_dimension\n");
25  printfQuda("%s %s %s %s %d/%d/%d %d %d\n", get_prec_str(prec),
27  tdim, Lsdim);
28 
29  printfQuda("\n Eigensolver parameters\n");
30  printfQuda(" - solver mode %s\n", get_eig_type_str(eig_type));
31  printfQuda(" - spectrum requested %s\n", get_eig_spectrum_str(eig_spectrum));
32  if (eig_type == QUDA_EIG_BLK_TR_LANCZOS) printfQuda(" - eigenvector block size %d\n", eig_block_size);
33  printfQuda(" - number of eigenvectors requested %d\n", eig_n_conv);
34  printfQuda(" - size of eigenvector search space %d\n", eig_n_ev);
35  printfQuda(" - size of Krylov space %d\n", eig_n_kr);
36  printfQuda(" - solver tolerance %e\n", eig_tol);
37  printfQuda(" - convergence required (%s)\n", eig_require_convergence ? "true" : "false");
38  if (eig_compute_svd) {
39  printfQuda(" - Operator: MdagM. Will compute SVD of M\n");
40  printfQuda(" - ***********************************************************\n");
41  printfQuda(" - **** Overriding any previous choices of operator type. ****\n");
42  printfQuda(" - **** SVD demands normal operator, will use MdagM ****\n");
43  printfQuda(" - ***********************************************************\n");
44  } else {
45  printfQuda(" - Operator: daggered (%s) , norm-op (%s)\n", eig_use_dagger ? "true" : "false",
46  eig_use_normop ? "true" : "false");
47  }
48  if (eig_use_poly_acc) {
49  printfQuda(" - Chebyshev polynomial degree %d\n", eig_poly_deg);
50  printfQuda(" - Chebyshev polynomial minumum %e\n", eig_amin);
51  if (eig_amax <= 0)
52  printfQuda(" - Chebyshev polynomial maximum will be computed\n");
53  else
54  printfQuda(" - Chebyshev polynomial maximum %e\n\n", eig_amax);
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  return;
60 }
61 
62 int main(int argc, char **argv)
63 {
64  // Parse command line options
65  auto app = make_app();
67  try {
68  app->parse(argc, argv);
69  } catch (const CLI::ParseError &e) {
70  return app->exit(e);
71  }
72 
73  // Set values for precisions via the command line.
75 
76  // initialize QMP/MPI, QUDA comms grid and RNG (host_utils.cpp)
77  initComms(argc, argv, gridsize_from_cmdline);
78 
79  // Only these fermions are supported in this file
84  printfQuda("dslash_type %d not supported\n", dslash_type);
85  exit(0);
86  }
87 
90 
91  // Though no inversions are performed, the inv_param
92  // structure contains all the information we need to
93  // construct the dirac operator. We encapsualte the
94  // inv_param structure inside the eig_param structure
95  // to avoid any confusion
96  QudaInvertParam eig_inv_param = newQudaInvertParam();
97  setInvertParam(eig_inv_param);
98  // Specific changes to the invert param for the eigensolver
99  // QUDA's device routines require UKQCD gamma basis. QUDA will
100  // automatically rotate from this basis on the host, to UKQCD
101  // on the device, and back to this basis upon completion.
103 
104  eig_inv_param.solve_type
106  QudaEigParam eig_param = newQudaEigParam();
107  // Place Invert param inside Eig param
108  eig_param.invert_param = &eig_inv_param;
109  setEigParam(eig_param);
110 
111  // Initialize the QUDA library
114 
115  // Set some dimension parameters
118  dw_setDims(gauge_param.X, eig_inv_param.Ls);
119  } else {
121  }
122 
123  // Allocate host side memory for the gauge field.
124  void *gauge[4];
125  for (int dir = 0; dir < 4; dir++) gauge[dir] = malloc(V * gauge_site_size * host_gauge_data_type_size);
126  constructHostGaugeField(gauge, gauge_param, argc, argv);
127  // Load the gauge field to the device
128  loadGaugeQuda((void *)gauge, &gauge_param);
129 
130  // Allocate host side memory for clover terms if needed.
131  void *clover = 0, *clover_inv = 0;
133  clover = malloc(V * clover_site_size * host_clover_data_type_size);
134  clover_inv = malloc(V * clover_site_size * host_spinor_data_type_size);
135  constructHostCloverField(clover, clover_inv, eig_inv_param);
136  // Load the clover terms to the device
137  loadCloverQuda(clover, clover_inv, &eig_inv_param);
138  }
139 
140  // QUDA eigensolver test BEGIN
141  //----------------------------------------------------------------------------
142  // Host side arrays to store the eigenpairs computed by QUDA
143  void **host_evecs = (void **)malloc(eig_n_conv * sizeof(void *));
144  for (int i = 0; i < eig_n_conv; i++) {
145  host_evecs[i] = (void *)malloc(V * eig_inv_param.Ls * spinor_site_size * eig_inv_param.cpu_prec);
146  }
147  double _Complex *host_evals = (double _Complex *)malloc(eig_param.n_ev * sizeof(double _Complex));
148 
149  // This function returns the host_evecs and host_evals pointers, populated with the
150  // requested data, at the requested prec. All the information needed to perfom the
151  // solve is in the eig_param container. If eig_param.arpack_check == true and
152  // precision is double, the routine will use ARPACK rather than the GPU.
153  struct timeval start, end;
154  gettimeofday(&start, NULL);
155  if (eig_param.arpack_check && !(eig_inv_param.cpu_prec == QUDA_DOUBLE_PRECISION)) {
156  errorQuda("ARPACK check only available in double precision");
157  }
158 
159  eigensolveQuda(host_evecs, host_evals, &eig_param);
160  gettimeofday(&end, NULL);
161  double time = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6;
162  printfQuda("Time for %s solution = %f\n", eig_param.arpack_check ? "ARPACK" : "QUDA", time);
163  // QUDA eigensolver test COMPLETE
164  //----------------------------------------------------------------------------
165 
166  // Clean up memory allocations
167  for (int i = 0; i < eig_n_conv; i++) free(host_evecs[i]);
168  free(host_evecs);
169  free(host_evals);
170 
171  freeGaugeQuda();
172  for (int dir = 0; dir < 4; dir++) free(gauge[dir]);
173 
175  freeCloverQuda();
176  if (clover) free(clover);
177  if (clover_inv) free(clover_inv);
178  }
179 
180  // finalize the QUDA library
181  endQuda();
182  finalizeComms();
183 
184  return 0;
185 }
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 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
int Lsdim
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
void end(void)
QudaGaugeParam gauge_param
Definition: covdev_test.cpp:26
int main(int argc, char **argv)
void display_test_info()
@ QUDA_WILSON_DSLASH
Definition: enum_quda.h:90
@ QUDA_TWISTED_CLOVER_DSLASH
Definition: enum_quda.h:100
@ QUDA_MOBIUS_DWF_DSLASH
Definition: enum_quda.h:95
@ QUDA_CLOVER_WILSON_DSLASH
Definition: enum_quda.h:91
@ QUDA_TWISTED_MASS_DSLASH
Definition: enum_quda.h:99
@ QUDA_DOMAIN_WALL_DSLASH
Definition: enum_quda.h:93
@ QUDA_DOMAIN_WALL_4D_DSLASH
Definition: enum_quda.h:94
@ QUDA_DEGRAND_ROSSI_GAMMA_BASIS
Definition: enum_quda.h:368
@ QUDA_EIG_BLK_TR_LANCZOS
Definition: enum_quda.h:138
@ QUDA_MAT_SOLUTION
Definition: enum_quda.h:157
@ QUDA_DOUBLE_PRECISION
Definition: enum_quda.h:65
@ QUDA_DIRECT_SOLVE
Definition: enum_quda.h:167
@ QUDA_DIRECT_PC_SOLVE
Definition: enum_quda.h:169
#define gauge_site_size
Definition: face_gauge.cpp:34
void constructHostCloverField(void *clover, void *clover_inv, QudaInvertParam &inv_param)
Definition: host_utils.cpp:186
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
size_t host_spinor_data_type_size
Definition: host_utils.cpp:66
void finalizeComms()
Definition: host_utils.cpp:292
size_t host_clover_data_type_size
Definition: host_utils.cpp:67
void dw_setDims(int *X, const int L5)
Definition: host_utils.cpp:353
void setQudaPrecisions()
Definition: host_utils.cpp:69
void constructHostGaugeField(void **gauge, QudaGaugeParam &gauge_param, int argc, char **argv)
Definition: host_utils.cpp:166
#define clover_site_size
Definition: host_utils.h:11
void setWilsonGaugeParam(QudaGaugeParam &gauge_param)
Definition: set_params.cpp:37
void setEigParam(QudaEigParam &eig_param)
Definition: set_params.cpp:263
#define spinor_site_size
Definition: host_utils.h:9
void setInvertParam(QudaInvertParam &invertParam, QudaInvertArgs_t &inv_args, int external_precision, int quda_precision, double kappa, double reliable_delta)
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_eig_type_str(QudaEigType type)
Definition: misc.cpp:171
const char * get_recon_str(QudaReconstructType recon)
Definition: misc.cpp:68
void start()
Start profiling.
Definition: device.cpp:226
void setTransferGPU(bool)
Main header file for the QUDA library.
QudaGaugeParam newQudaGaugeParam(void)
void eigensolveQuda(void **h_evecs, double_complex *h_evals, QudaEigParam *param)
void freeGaugeQuda(void)
void initQuda(int device)
void loadGaugeQuda(void *h_gauge, QudaGaugeParam *param)
void loadCloverQuda(void *h_clover, void *h_clovinv, QudaInvertParam *inv_param)
void freeCloverQuda(void)
QudaInvertParam newQudaInvertParam(void)
QudaEigParam newQudaEigParam(void)
void endQuda(void)
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
QudaSolveType solve_type
Definition: quda.h:229
QudaSolutionType solution_type
Definition: quda.h:228
QudaPrecision cpu_prec
Definition: quda.h:237
QudaGammaBasis gamma_basis
Definition: quda.h:246
#define printfQuda(...)
Definition: util_quda.h:114
#define errorQuda(...)
Definition: util_quda.h:120