Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

msmpot_cuda.cu

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 2008-2009 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: msmpot_cuda.cu,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.3 $      $Date: 2010/06/03 20:07:09 $
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 //  free(mc->dev);
00040 }
00041 
00042 
00043 //static int list_devices(MsmpotCuda *);
00044 //static int real_devices(MsmpotCuda *);
00045 static int set_device(MsmpotCuda *, int devnum);
00046 
00047 
00048 int Msmpot_cuda_setup(MsmpotCuda *mc, Msmpot *msm) {
00049   int rc;  // return code from setup calls
00050   int is_cuda_optional = msm->cuda_optional;
00051 
00052   int devnum = 0;  // XXX use device 0 for now
00053 
00054   mc->msmpot = msm;  // handle back to Msmpot data
00055 
00056   msm->use_cuda_shortrng = 0;  // be pessimistic
00057   msm->use_cuda_latcut = 0;
00058 
00059 #if 0
00060   if (msm->isperiodic) {  // XXX can't use CUDA
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                        // for now, use first device given by user
00074   if (OK == err) mc->devnum = msm->devlist[0];   // set device number
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);     // attempt to use device
00082   if (rc != OK) {
00083     if (is_cuda_optional) {
00084       REPORT("Unable to setup CUDA device, fall back on CPU.");
00085       return OK;                   // fall back on CPU
00086     }
00087     else return ERROR(rc);         // can't keep going without CUDA
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;    // use CUDA for shortrng
00095   }
00096   else if ( ! is_cuda_optional) return ERROR(rc);  // can't keep going
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;          // use CUDA for latcut
00103   }
00104   else if ( ! is_cuda_optional) return ERROR(rc);  // can't keep going
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);  // we already have device list
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 // verify CUDA devices are real rather than emulation mode
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);  // emulation mode
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(); // query last error and reset error state
00154     if (cuerr != cudaErrorSetOnActiveProcess) {
00155       return ERROR(MSMPOT_ERROR_CUDA_DEVREQ);
00156     }
00157 #else
00158     cudaGetLastError(); // just ignore and reset error state, since older CUDA
00159                         // revs don't have a cudaErrorSetOnActiveProcess enum
00160 #endif
00161   }
00162   return OK;
00163 }

Generated on Thu Apr 18 02:44:57 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002