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

OpenCLUtils.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 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: OpenCLUtils.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.14 $      $Date: 2019/01/17 21:38:55 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   OpenCL utility functions for use in VMD
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         // clean up device name string (some contain lots of spaces)
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         // list primary GPU device attributes
00120         sprintf(outstr, "[%d] %-40s %2d CU @ %.2f GHz",
00121                 j, device_name, computeunits, clockratemhz / 1000.0);
00122         msgInfo << outstr;
00123 
00124         // list memory capacity
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         // list optional hardware features and configuration attributes here...
00136         // XXX not implemented yet...
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 

Generated on Wed Apr 24 02:42:45 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002