|
QUDA v0.3.2
A library for QCD on GPUs
|
00001 #include <stdlib.h> 00002 #include <stdio.h> 00003 #include <time.h> 00004 #include <math.h> 00005 00006 #include <test_util.h> 00007 #include <blas_reference.h> 00008 #include <domain_wall_dslash_reference.h> 00009 00010 // In a typical application, quda.h is the only QUDA header required. 00011 #include <quda.h> 00012 00013 int main(int argc, char **argv) 00014 { 00015 // set QUDA parameters 00016 00017 int device = 0; // CUDA device number 00018 00019 QudaPrecision cpu_prec = QUDA_DOUBLE_PRECISION; 00020 QudaPrecision cuda_prec = QUDA_SINGLE_PRECISION; 00021 QudaPrecision cuda_prec_sloppy = QUDA_HALF_PRECISION; 00022 00023 QudaGaugeParam gauge_param = newQudaGaugeParam(); 00024 QudaInvertParam inv_param = newQudaInvertParam(); 00025 00026 gauge_param.X[0] = 12; 00027 gauge_param.X[1] = 12; 00028 gauge_param.X[2] = 12; 00029 gauge_param.X[3] = 12; 00030 inv_param.Ls = 16; 00031 00032 gauge_param.anisotropy = 1.0; 00033 gauge_param.type = QUDA_WILSON_LINKS; 00034 gauge_param.gauge_order = QUDA_QDP_GAUGE_ORDER; 00035 gauge_param.t_boundary = QUDA_ANTI_PERIODIC_T; 00036 00037 gauge_param.cpu_prec = cpu_prec; 00038 gauge_param.cuda_prec = cuda_prec; 00039 gauge_param.reconstruct = QUDA_RECONSTRUCT_12; 00040 gauge_param.cuda_prec_sloppy = cuda_prec_sloppy; 00041 gauge_param.reconstruct_sloppy = QUDA_RECONSTRUCT_12; 00042 gauge_param.gauge_fix = QUDA_GAUGE_FIXED_NO; 00043 00044 inv_param.dslash_type = QUDA_DOMAIN_WALL_DSLASH; 00045 inv_param.inv_type = QUDA_CG_INVERTER; 00046 00047 inv_param.mass = 0.01; 00048 inv_param.m5 = -1.5; 00049 double kappa5 = 0.5/(5 + inv_param.m5); 00050 00051 inv_param.tol = 5e-8; 00052 inv_param.maxiter = 1000; 00053 inv_param.reliable_delta = 0.1; 00054 00055 inv_param.solution_type = QUDA_MAT_SOLUTION; 00056 inv_param.solve_type = QUDA_NORMEQ_PC_SOLVE; 00057 inv_param.matpc_type = QUDA_MATPC_EVEN_EVEN; 00058 inv_param.dagger = QUDA_DAG_NO; 00059 inv_param.mass_normalization = QUDA_KAPPA_NORMALIZATION; 00060 00061 inv_param.cpu_prec = cpu_prec; 00062 inv_param.cuda_prec = cuda_prec; 00063 inv_param.cuda_prec_sloppy = cuda_prec_sloppy; 00064 inv_param.preserve_source = QUDA_PRESERVE_SOURCE_NO; 00065 inv_param.dirac_order = QUDA_DIRAC_ORDER; 00066 00067 gauge_param.ga_pad = 0; // 24*24*24; 00068 inv_param.sp_pad = 0; // 24*24*24; 00069 inv_param.cl_pad = 0; // 24*24*24; 00070 00071 inv_param.verbosity = QUDA_VERBOSE; 00072 00073 // Everything between here and the call to initQuda() is application-specific. 00074 00075 // set parameters for the reference Dslash, and prepare fields to be loaded 00076 setDims(gauge_param.X, inv_param.Ls); 00077 00078 size_t gSize = (gauge_param.cpu_prec == QUDA_DOUBLE_PRECISION) ? sizeof(double) : sizeof(float); 00079 size_t sSize = (inv_param.cpu_prec == QUDA_DOUBLE_PRECISION) ? sizeof(double) : sizeof(float); 00080 00081 void *gauge[4]; 00082 00083 for (int dir = 0; dir < 4; dir++) { 00084 gauge[dir] = malloc(V*gaugeSiteSize*gSize); 00085 } 00086 construct_gauge_field(gauge, 1, gauge_param.cpu_prec, &gauge_param); 00087 00088 void *spinorIn = malloc(V*spinorSiteSize*sSize*inv_param.Ls); 00089 void *spinorOut = malloc(V*spinorSiteSize*sSize*inv_param.Ls); 00090 void *spinorCheck = malloc(V*spinorSiteSize*sSize*inv_param.Ls); 00091 00092 // create a point source at 0 00093 if (inv_param.cpu_prec == QUDA_SINGLE_PRECISION) *((float*)spinorIn) = 1.0; 00094 else *((double*)spinorIn) = 1.0; 00095 00096 // start the timer 00097 double time0 = -((double)clock()); 00098 00099 // initialize the QUDA library 00100 initQuda(device); 00101 00102 // load the gauge field 00103 loadGaugeQuda((void*)gauge, &gauge_param); 00104 00105 // perform the inversion 00106 invertQuda(spinorOut, spinorIn, &inv_param); 00107 00108 // stop the timer 00109 time0 += clock(); 00110 time0 /= CLOCKS_PER_SEC; 00111 00112 printf("Device memory used:\n Spinor: %f GiB\n Gauge: %f GiB\n", 00113 inv_param.spinorGiB, gauge_param.gaugeGiB); 00114 printf("\nDone: %i iter / %g secs = %g Gflops, total time = %g secs\n", 00115 inv_param.iter, inv_param.secs, inv_param.gflops/inv_param.secs, time0); 00116 00117 if (inv_param.solution_type == QUDA_MAT_SOLUTION) { 00118 mat(spinorCheck, gauge, spinorOut, kappa5, 0, inv_param.cpu_prec, 00119 gauge_param.cpu_prec, inv_param.mass); 00120 if (inv_param.mass_normalization == QUDA_MASS_NORMALIZATION) 00121 ax(0.5/kappa5, spinorCheck, V*spinorSiteSize, inv_param.cpu_prec); 00122 } else if(inv_param.solution_type == QUDA_MATPC_SOLUTION) { 00123 matpc(spinorCheck, gauge, spinorOut, kappa5, inv_param.matpc_type, 0, 00124 inv_param.cpu_prec, gauge_param.cpu_prec, inv_param.mass); 00125 if (inv_param.mass_normalization == QUDA_MASS_NORMALIZATION) 00126 ax(0.25/(kappa5*kappa5), spinorCheck, V*spinorSiteSize, inv_param.cpu_prec); 00127 } 00128 00129 mxpy(spinorIn, spinorCheck, V*spinorSiteSize, inv_param.cpu_prec); 00130 double nrm2 = norm_2(spinorCheck, V*spinorSiteSize, inv_param.cpu_prec); 00131 double src2 = norm_2(spinorIn, V*spinorSiteSize, inv_param.cpu_prec); 00132 printf("Relative residual: requested = %g, actual = %g\n", inv_param.tol, sqrt(nrm2/src2)); 00133 00134 // finalize the QUDA library 00135 endQuda(); 00136 00137 return 0; 00138 }
1.7.3