QUDA v0.4.0
A library for QCD on GPUs
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <iostream> 00004 00005 #include <quda_internal.h> 00006 #include <gauge_field.h> 00007 #include <util_quda.h> 00008 00009 #include <test_util.h> 00010 #include <wilson_dslash_reference.h> 00011 00012 #include <color_spinor_field.h> 00013 #include <blas_quda.h> 00014 00015 QudaGaugeParam param; 00016 cudaColorSpinorField *cudaSpinor; 00017 00018 void *qdpCpuGauge_p[4]; 00019 void *cpsCpuGauge_p; 00020 cpuColorSpinorField *spinor, *spinor2; 00021 00022 ColorSpinorParam csParam; 00023 00024 float kappa = 1.0; 00025 int ODD_BIT = 0; 00026 int DAGGER_BIT = 0; 00027 00028 // where is the packing / unpacking taking place 00029 //most orders are CPU only currently 00030 const QudaFieldLocation location = QUDA_CPU_FIELD_LOCATION; 00031 00032 void init() { 00033 00034 param.cpu_prec = QUDA_SINGLE_PRECISION; 00035 param.cuda_prec = QUDA_HALF_PRECISION; 00036 param.reconstruct = QUDA_RECONSTRUCT_8; 00037 param.cuda_prec_sloppy = param.cuda_prec; 00038 param.reconstruct_sloppy = param.reconstruct; 00039 00040 param.X[0] = 4; 00041 param.X[1] = 4; 00042 param.X[2] = 4; 00043 param.X[3] = 4; 00044 param.ga_pad = 0; 00045 setDims(param.X); 00046 00047 param.anisotropy = 2.3; 00048 param.t_boundary = QUDA_ANTI_PERIODIC_T; 00049 param.gauge_fix = QUDA_GAUGE_FIXED_NO; 00050 00051 // construct input fields 00052 for (int dir = 0; dir < 4; dir++) { 00053 qdpCpuGauge_p[dir] = malloc(V*gaugeSiteSize*param.cpu_prec); 00054 } 00055 cpsCpuGauge_p = malloc(4*V*gaugeSiteSize*param.cpu_prec); 00056 00057 csParam.fieldLocation = QUDA_CPU_FIELD_LOCATION; 00058 csParam.nColor = 3; 00059 csParam.nSpin = 4; 00060 csParam.nDim = 4; 00061 for (int d=0; d<4; d++) csParam.x[d] = param.X[d]; 00062 csParam.precision = QUDA_SINGLE_PRECISION; 00063 csParam.pad = 0; 00064 csParam.siteSubset = QUDA_PARITY_SITE_SUBSET; 00065 csParam.siteOrder = QUDA_EVEN_ODD_SITE_ORDER; 00066 csParam.fieldOrder = QUDA_SPACE_SPIN_COLOR_FIELD_ORDER; 00067 csParam.gammaBasis = QUDA_DEGRAND_ROSSI_GAMMA_BASIS; 00068 csParam.create = QUDA_NULL_FIELD_CREATE; 00069 00070 spinor = new cpuColorSpinorField(csParam); 00071 spinor2 = new cpuColorSpinorField(csParam); 00072 00073 spinor->Source(QUDA_RANDOM_SOURCE); 00074 00075 initQuda(0); 00076 00077 csParam.fieldLocation = QUDA_CUDA_FIELD_LOCATION; 00078 csParam.fieldOrder = QUDA_FLOAT4_FIELD_ORDER; 00079 csParam.gammaBasis = QUDA_UKQCD_GAMMA_BASIS; 00080 csParam.pad = 0; 00081 csParam.precision = QUDA_HALF_PRECISION; 00082 00083 cudaSpinor = new cudaColorSpinorField(csParam); 00084 } 00085 00086 void end() { 00087 // release memory 00088 delete cudaSpinor; 00089 delete spinor2; 00090 delete spinor; 00091 00092 for (int dir = 0; dir < 4; dir++) free(qdpCpuGauge_p[dir]); 00093 free(cpsCpuGauge_p); 00094 endQuda(); 00095 } 00096 00097 void packTest() { 00098 00099 float spinorGiB = (float)Vh*spinorSiteSize*param.cuda_prec / (1 << 30); 00100 printf("\nSpinor mem: %.3f GiB\n", spinorGiB); 00101 printf("Gauge mem: %.3f GiB\n", param.gaugeGiB); 00102 00103 printf("Sending fields to GPU...\n"); fflush(stdout); 00104 00105 { 00106 param.gauge_order = QUDA_CPS_WILSON_GAUGE_ORDER; 00107 00108 GaugeFieldParam cpsParam(cpsCpuGauge_p, param); 00109 cpuGaugeField cpsCpuGauge(cpsParam); 00110 cpsParam.create = QUDA_NULL_FIELD_CREATE; 00111 cpsParam.precision = param.cuda_prec; 00112 cpsParam.reconstruct = param.reconstruct; 00113 cpsParam.pad = param.ga_pad; 00114 cpsParam.order = (cpsParam.precision == QUDA_DOUBLE_PRECISION || 00115 cpsParam.reconstruct == QUDA_RECONSTRUCT_NO ) ? 00116 QUDA_FLOAT2_GAUGE_ORDER : QUDA_FLOAT4_GAUGE_ORDER; 00117 cudaGaugeField cudaCpsGauge(cpsParam); 00118 00119 stopwatchStart(); 00120 cudaCpsGauge.loadCPUField(cpsCpuGauge, location); 00121 double cpsGtime = stopwatchReadSeconds(); 00122 printf("CPS Gauge send time = %e seconds\n", cpsGtime); 00123 00124 stopwatchStart(); 00125 cudaCpsGauge.saveCPUField(cpsCpuGauge, location); 00126 double cpsGRtime = stopwatchReadSeconds(); 00127 printf("CPS Gauge restore time = %e seconds\n", cpsGRtime); 00128 } 00129 00130 { 00131 param.gauge_order = QUDA_QDP_GAUGE_ORDER; 00132 00133 GaugeFieldParam qdpParam(qdpCpuGauge_p, param); 00134 cpuGaugeField qdpCpuGauge(qdpParam); 00135 qdpParam.create = QUDA_NULL_FIELD_CREATE; 00136 qdpParam.precision = param.cuda_prec; 00137 qdpParam.reconstruct = param.reconstruct; 00138 qdpParam.pad = param.ga_pad; 00139 qdpParam.order = (qdpParam.precision == QUDA_DOUBLE_PRECISION || 00140 qdpParam.reconstruct == QUDA_RECONSTRUCT_NO ) ? 00141 QUDA_FLOAT2_GAUGE_ORDER : QUDA_FLOAT4_GAUGE_ORDER; 00142 cudaGaugeField cudaQdpGauge(qdpParam); 00143 00144 stopwatchStart(); 00145 cudaQdpGauge.loadCPUField(qdpCpuGauge, location); 00146 double qdpGtime = stopwatchReadSeconds(); 00147 printf("QDP Gauge send time = %e seconds\n", qdpGtime); 00148 00149 stopwatchStart(); 00150 cudaQdpGauge.saveCPUField(qdpCpuGauge, location); 00151 double qdpGRtime = stopwatchReadSeconds(); 00152 printf("QDP Gauge restore time = %e seconds\n", qdpGRtime); 00153 } 00154 00155 stopwatchStart(); 00156 *cudaSpinor = *spinor; 00157 double sSendTime = stopwatchReadSeconds(); 00158 printf("Spinor send time = %e seconds\n", sSendTime); 00159 00160 stopwatchStart(); 00161 *spinor2 = *cudaSpinor; 00162 double sRecTime = stopwatchReadSeconds(); 00163 printf("Spinor receive time = %e seconds\n", sRecTime); 00164 00165 std::cout << "Norm check: CPU = " << norm2(*spinor) << 00166 ", CUDA = " << norm2(*cudaSpinor) << 00167 ", CPU = " << norm2(*spinor2) << std::endl; 00168 00169 cpuColorSpinorField::Compare(*spinor, *spinor2, 1); 00170 00171 } 00172 00173 int main(int argc, char **argv) { 00174 init(); 00175 packTest(); 00176 end(); 00177 } 00178