00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <sys/stat.h>
00026 #include <sys/types.h>
00027
00028 #if defined(__APPLE__)
00029 #include <OpenCL/cl.h>
00030 #else
00031 #include <CL/cl.h>
00032 #endif
00033
00034 #if defined(VMDOPENCL)
00035 #include "Inform.h"
00036 #endif
00037
00038 int vmd_cl_print_platform_info(void) {
00039 cl_int clerr;
00040 cl_uint numplatforms;
00041 cl_platform_id *platformlist;
00042 clerr=clGetPlatformIDs(0, NULL, &numplatforms);
00043 platformlist = (cl_platform_id *) malloc(sizeof(cl_platform_id)*numplatforms);
00044 clerr=clGetPlatformIDs(numplatforms, platformlist, NULL);
00045
00046 cl_uint i;
00047 for (i=0; i<numplatforms; i++) {
00048 char platname[80];
00049 clerr=clGetPlatformInfo(platformlist[i], CL_PLATFORM_NAME,
00050 sizeof(platname), (void *) platname, NULL);
00051
00052 char platprofile[80];
00053 clerr=clGetPlatformInfo(platformlist[i], CL_PLATFORM_PROFILE,
00054 sizeof(platprofile), (void *) platprofile, NULL);
00055
00056 #if 0
00057 char platvendor[80];
00058 clerr=clGetPlatformInfo(platformlist[i], CL_PLATFORM_VENDOR,
00059 sizeof(platvendor), (void *) platvendor, NULL);
00060 #endif
00061
00062 cl_uint numdevs;
00063 clerr=clGetDeviceIDs(platformlist[i], CL_DEVICE_TYPE_ALL,
00064 0, NULL, &numdevs);
00065
00066 char platforminfo[4096];
00067 #if !defined(VMDOPENCL)
00068 printf("OpenCL Platform[%d]: %s, %s Devices: %u\n",
00069 i, platname, platprofile, numdevs);
00070 #else
00071 sprintf(platforminfo, "OpenCL Platform[%d]: %s, %s Devices: %u\n",
00072 i, platname, platprofile, numdevs);
00073 msgInfo << platforminfo << sendmsg;
00074 #endif
00075
00076 int j;
00077 cl_device_id *devices = new cl_device_id[numdevs];
00078 clerr = clGetDeviceIDs(platformlist[i], CL_DEVICE_TYPE_ALL,
00079 numdevs, devices, NULL);
00080 for (j=0; j<numdevs; j++) {
00081 char outstr[1024];
00082 size_t rsz;
00083 cl_uint clockratemhz, computeunits;
00084 cl_ulong globalmemsz;
00085 cl_char long_device_name[1024] = {0};
00086 cl_char device_name[1024] = {0};
00087 cl_device_id dev = devices[j];
00088
00089 clerr |= clGetDeviceInfo(dev, CL_DEVICE_NAME, sizeof(long_device_name),
00090 long_device_name, &rsz);
00091 clerr |= clGetDeviceInfo(dev, CL_DEVICE_MAX_CLOCK_FREQUENCY,
00092 sizeof(clockratemhz), &clockratemhz, &rsz);
00093 clerr |= clGetDeviceInfo(dev, CL_DEVICE_MAX_COMPUTE_UNITS,
00094 sizeof(computeunits), &computeunits, &rsz);
00095 clerr |= clGetDeviceInfo(dev, CL_DEVICE_GLOBAL_MEM_SIZE,
00096 sizeof(globalmemsz), &globalmemsz, &rsz);
00097
00098 if (clerr == CL_SUCCESS) {
00099
00100 int len = strlen((const char *) long_device_name);
00101 int k,l;
00102 for (k=0,l=0; k<len; k++) {
00103 if (long_device_name[k] != ' ') {
00104 device_name[l] = long_device_name[k];
00105 l++;
00106 continue;
00107 }
00108
00109 device_name[l] = long_device_name[k];
00110 l++;
00111 while (k < len) {
00112 if (long_device_name[k+1] == ' ')
00113 k++;
00114 else
00115 break;
00116 }
00117 }
00118
00119
00120 sprintf(outstr, "[%d] %-40s %2d CU @ %.2f GHz",
00121 j, device_name, computeunits, clockratemhz / 1000.0);
00122 msgInfo << outstr;
00123
00124
00125 int gpumemmb = globalmemsz / (1024 * 1024);
00126 if (gpumemmb < 1000)
00127 sprintf(outstr, ", %4dMB RAM", gpumemmb);
00128 else if (gpumemmb < 10240)
00129 sprintf(outstr, ", %.1fGB RAM", gpumemmb / 1024.0);
00130 else
00131 sprintf(outstr, ", %dGB RAM", gpumemmb / 1024);
00132
00133 msgInfo << outstr;
00134
00135
00136
00137
00138 msgInfo << sendmsg;
00139 } else {
00140 sprintf(outstr, " [%d] Error during OpenCL device query!", j);
00141 msgInfo << outstr << sendmsg;
00142
00143 clerr = CL_SUCCESS;
00144 }
00145 }
00146
00147 delete [] devices;
00148 }
00149
00150 free(platformlist);
00151
00152 return 0;
00153 }
00154
00155
00156 cl_platform_id vmd_cl_get_platform_index(int i) {
00157 cl_int clerr;
00158 cl_uint numplatforms;
00159 cl_platform_id *platformlist;
00160 cl_platform_id plat;
00161 clerr=clGetPlatformIDs(0, NULL, &numplatforms);
00162 if (i >= (int) numplatforms)
00163 return NULL;
00164
00165 platformlist = (cl_platform_id *) malloc(sizeof(cl_platform_id)*numplatforms);
00166 clerr=clGetPlatformIDs(numplatforms, platformlist, NULL);
00167 if (clerr != CL_SUCCESS) {
00168 free(platformlist);
00169 return NULL;
00170 }
00171
00172 plat=platformlist[i];
00173 free(platformlist);
00174
00175 return plat;
00176 }
00177
00178
00179 int vmd_cl_context_num_devices(cl_context clctx) {
00180 size_t parmsz;
00181 cl_int clerr = clGetContextInfo(clctx, CL_CONTEXT_DEVICES, 0, NULL, &parmsz);
00182 if (clerr != CL_SUCCESS)
00183 return 0;
00184
00185 return (int) (parmsz / sizeof(size_t));
00186 }
00187
00188
00189 cl_command_queue vmd_cl_create_command_queue(cl_context clctx, int dev) {
00190 size_t parmsz;
00191 cl_int clerr = clGetContextInfo(clctx, CL_CONTEXT_DEVICES, 0, NULL, &parmsz);
00192 if (clerr != CL_SUCCESS)
00193 return NULL;
00194
00195 cl_device_id* cldevs = (cl_device_id *) malloc(parmsz);
00196 clerr = clGetContextInfo(clctx, CL_CONTEXT_DEVICES, parmsz, cldevs, NULL);
00197 if (clerr != CL_SUCCESS)
00198 return NULL;
00199
00200 cl_command_queue clcmdq = clCreateCommandQueue(clctx, cldevs[dev], 0, &clerr);
00201 free(cldevs);
00202 if (clerr != CL_SUCCESS)
00203 return NULL;
00204
00205 return clcmdq;
00206 }
00207
00208
00209 cl_kernel vmd_cl_compile_kernel(cl_context clctx, const char *kernname,
00210 const char *srctext, const char *flags,
00211 cl_int *clerr, int verbose) {
00212 char buildlog[8192];
00213 cl_program clpgm = NULL;
00214 cl_kernel clkern = NULL;
00215
00216 clpgm = clCreateProgramWithSource(clctx, 1, &srctext, NULL, clerr);
00217 if (clerr != CL_SUCCESS) {
00218 if (verbose)
00219 printf("Failed to compile OpenCL kernel: '%s'\n", kernname);
00220 return NULL;
00221 }
00222 *clerr = clBuildProgram(clpgm, 0, NULL, flags, NULL, NULL);
00223
00224 #if 1
00225 if (verbose) {
00226 memset(buildlog, 0, sizeof(buildlog));
00227
00228 size_t parmsz;
00229 *clerr |= clGetContextInfo(clctx, CL_CONTEXT_DEVICES, 0, NULL, &parmsz);
00230
00231 cl_device_id* cldevs = (cl_device_id *) malloc(parmsz);
00232 *clerr |= clGetContextInfo(clctx, CL_CONTEXT_DEVICES, parmsz, cldevs, NULL);
00233
00234 size_t len=0;
00235 *clerr = clGetProgramBuildInfo(clpgm, cldevs[0], CL_PROGRAM_BUILD_LOG, sizeof(buildlog), buildlog, &len);
00236 if (len > 1) {
00237 printf("OpenCL kernel compilation log:\n");
00238 printf(" '%s'\n", buildlog);
00239 }
00240 }
00241 #endif
00242
00243 clkern = clCreateKernel(clpgm, kernname, clerr);
00244 if (clerr != CL_SUCCESS) {
00245 if (verbose)
00246 printf("Failed to create OpenCL kernel: '%s'\n", kernname);
00247 return NULL;
00248 }
00249
00250 return clkern;
00251 }
00252
00253
00254 cl_kernel vmd_cl_compile_kernel_file(cl_context clctx, const char *kernname,
00255 const char *filename, const char *flags,
00256 cl_int *clerr, int verbose) {
00257 FILE *ifp;
00258 char *src;
00259 struct stat statbuf;
00260 cl_kernel clkern = NULL;
00261
00262 if ((ifp = fopen(filename, "r")) == NULL)
00263 return NULL;
00264
00265 stat(filename, &statbuf);
00266 src = (char *) calloc(1, statbuf.st_size + 1);
00267 fread(src, statbuf.st_size, 1, ifp);
00268 src[statbuf.st_size] = '\0';
00269 clkern = vmd_cl_compile_kernel(clctx, kernname, src, flags, clerr, verbose);
00270 free(src);
00271
00272 return clkern;
00273 }
00274
00275
00276