00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #include "msmpot_cuda.h"
00019 
00020 #define OK  MSMPOT_SUCCESS
00021 
00022 MsmpotCuda *Msmpot_cuda_create(void) {
00023   MsmpotCuda *mc = (MsmpotCuda *) calloc(1, sizeof(MsmpotCuda));
00024   return mc;
00025 }
00026 
00027 
00028 void Msmpot_cuda_destroy(MsmpotCuda *mc) {
00029   Msmpot_cuda_cleanup(mc);
00030   free(mc);
00031 }
00032 
00033 
00034 void Msmpot_cuda_cleanup(MsmpotCuda *mc) {
00035   REPORT("Cleaning up CUDA lattice cutoff part.");
00036   Msmpot_cuda_cleanup_latcut(mc);
00037   REPORT("Cleaning up CUDA short-range part.");
00038   Msmpot_cuda_cleanup_shortrng(mc);
00039 
00040 }
00041 
00042 
00043 
00044 
00045 static int set_device(MsmpotCuda *, int devnum);
00046 
00047 
00048 int Msmpot_cuda_setup(MsmpotCuda *mc, Msmpot *msm) {
00049   int rc;  
00050   int is_cuda_optional = msm->cuda_optional;
00051 
00052   int devnum = 0;  
00053 
00054   mc->msmpot = msm;  
00055 
00056   msm->use_cuda_shortrng = 0;  
00057   msm->use_cuda_latcut = 0;
00058 
00059 #if 0
00060   if (msm->isperiodic) {  
00061     REPORT("CUDA version does not support periodic boundaries.");
00062     if (is_cuda_optional) {
00063       REPORT("Falling back on CPU for computation.");
00064       return OK;
00065     }
00066     return ERROR(MSMPOT_ERROR_CUDA_SUPPORT);
00067   }
00068 #endif
00069 
00070 #if 0
00071   err = list_devices(mc);
00072   if (OK == err) err = set_device(mc, msm->devlist[0]);
00073                        
00074   if (OK == err) mc->devnum = msm->devlist[0];   
00075   else  if (msm->cuda_optional && err != MSMPOT_ERROR_MALLOC) {
00076     return ERRMSG(OK, "falling back on CPU for computation");
00077   }
00078   else return ERROR(err);
00079 #endif
00080 
00081   rc = set_device(mc, devnum);     
00082   if (rc != OK) {
00083     if (is_cuda_optional) {
00084       REPORT("Unable to setup CUDA device, fall back on CPU.");
00085       return OK;                   
00086     }
00087     else return ERROR(rc);         
00088   }
00089   REPORT("Setup CUDA device.");
00090 
00091   rc = Msmpot_cuda_setup_shortrng(mc);
00092   if (OK == rc) {
00093     REPORT("Setup CUDA short-range part.");
00094     msm->use_cuda_shortrng = 1;    
00095   }
00096   else if ( ! is_cuda_optional) return ERROR(rc);  
00097   else REPORT("Unable to setup CUDA short-range part, fall back on CPU.");
00098 
00099   rc = Msmpot_cuda_setup_latcut(mc);
00100   if (OK == rc) {
00101     REPORT("Setup CUDA lattice cutoff part.");
00102     msm->use_cuda_latcut = 1;          
00103   }
00104   else if ( ! is_cuda_optional) return ERROR(rc);  
00105   else REPORT("Unable to setup CUDA lattice cutoff part, fall back on CPU.");
00106 
00107   return OK;
00108 }
00109 
00110 
00111 #if 0
00112 int list_devices(MsmpotCuda *mc) {
00113   void *v;
00114   int ndevs, i;
00115 
00116   if (mc->dev) return real_devices(mc);  
00117 
00118   cudaGetDeviceCount(&ndevs);
00119   if (ndevs < 1) return ERROR(MSMPOT_ERROR_CUDA_DEVREQ);
00120 
00121   v = realloc(mc->dev, ndevs * sizeof(struct cudaDeviceProp));
00122   if (NULL == v) return ERROR(MSMPOT_ERROR_MALLOC);
00123   mc->dev = (struct cudaDeviceProp *) v;
00124   mc->ndevs = ndevs;
00125 
00126   for (i = 0;  i < ndevs;  i++) {
00127     cudaError_t cuerr = cudaGetDeviceProperties(mc->dev + i, i);
00128     if (cuerr != cudaSuccess) return ERROR(MSMPOT_ERROR_CUDA_DEVREQ);
00129   }
00130   return real_devices(mc);
00131 }
00132 
00133 
00134 
00135 int real_devices(MsmpotCuda *mc) {
00136   const int ndevs = mc->ndevs;
00137   int i;
00138 
00139   for (i = 0;  i < ndevs;  i++) {
00140     if (9999 == mc->dev[i].major && 9999 == mc->dev[i].minor) {
00141       return ERROR(MSMPOT_ERROR_CUDA_DEVREQ);  
00142     }
00143   }
00144   return OK;
00145 }
00146 #endif
00147 
00148 
00149 int set_device(MsmpotCuda *mc, int devnum) {
00150   cudaError_t cuerr = cudaSetDevice(devnum);
00151   if (cuerr != cudaSuccess) {
00152 #if CUDART_VERSION >= 2010
00153     cuerr = cudaGetLastError(); 
00154     if (cuerr != cudaErrorSetOnActiveProcess) {
00155       return ERROR(MSMPOT_ERROR_CUDA_DEVREQ);
00156     }
00157 #else
00158     cudaGetLastError(); 
00159                         
00160 #endif
00161   }
00162   return OK;
00163 }