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 }