Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/vis12/src/lib/cl-target/clinfo.c
ViewVC logotype

Annotation of /branches/vis12/src/lib/cl-target/clinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2075 - (view) (download) (as text)

1 : jhr 1671 /*! \file clinfo.c
2 :     *
3 :     * \author John Reppy
4 :     *
5 :     * \brief This file contains functions that can be used to determine properties of the
6 :     * host machine's OpenCL support.
7 :     */
8 :    
9 :     /*
10 :     * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
11 :     * All rights reserved.
12 :     */
13 :    
14 : jhr 2075 #include "Diderot/clinfo.h"
15 : jhr 1671 #include <stdio.h>
16 :     #include <string.h>
17 :     #include <stdlib.h>
18 :    
19 :     #define MAX_PLATFORMS 16
20 :    
21 : jhr 2075 static bool GetDevices (unsigned int platIdx, PlatformInfo_t *plat);
22 : jhr 1671
23 :     #define CHECK(call) do { \
24 :     cl_int __sts = call; \
25 :     if (__sts != CL_SUCCESS) { \
26 :     fprintf(stderr, "error %d at %s:%d\n", __sts, __FILE__, __LINE__); \
27 :     exit (1); \
28 :     } \
29 :     } while (0)
30 :    
31 : jhr 2075 //! Checked memory allocation
32 :     STATIC_INLINE void *CheckedAlloc (size_t szb)
33 :     {
34 :     void *p = malloc(szb);
35 :     if (p == 0) {
36 :     fprintf (stderr, "fatal error: unable to allocate %d bytes of memory\n", (int)szb);
37 :     exit (1);
38 :     }
39 :     return p;
40 :     }
41 : jhr 1671
42 : jhr 2075 #define NEW(ty) (ty *)CheckedAlloc(sizeof(ty))
43 :     #define NEWVEC(ty,n) (ty *)CheckedAlloc(sizeof(ty) * (n))
44 :     #define NEWSTR(s) strcpy((char *)CheckedAlloc(strlen(s)+1), s)
45 :     #define FREE(p) do { if (p != 0) free(p); } while(0)
46 :    
47 :     CLInfo_t *Diderot_GetCLInfo ()
48 : jhr 1671 {
49 :     cl_platform_id platformIDs[MAX_PLATFORMS];
50 :     char buf[512];
51 :    
52 :     // get platform info
53 :     // get number of OpenCL platforms
54 :     cl_uint numPlatforms;
55 :     CHECK(clGetPlatformIDs (MAX_PLATFORMS, platformIDs, &numPlatforms));
56 :    
57 :     PlatformInfo_t *plats = NEWVEC(PlatformInfo_t, numPlatforms);
58 : jhr 2075 for (unsigned int i = 0; i < numPlatforms; i++) {
59 : jhr 1671 clGetPlatformInfo (platformIDs[i], CL_PLATFORM_NAME, sizeof(buf), buf, 0);
60 :     plats[i].name = NEWSTR(buf);
61 :     plats[i].id = platformIDs[i];
62 :     // get OpenCL version info
63 :     clGetPlatformInfo (platformIDs[i], CL_PLATFORM_VERSION, sizeof(buf), buf, 0);
64 :     // get extension info
65 :     // FIXME: TODO
66 :     // get device info
67 : jhr 2075 if (! GetDevices (i, &(plats[i]))) {
68 : jhr 1671 // free storage
69 : jhr 2075 for (unsigned int j = 0; j <= i; j++) {
70 : jhr 1671 free (plats[i].name);
71 :     }
72 :     free (plats);
73 :     }
74 :     }
75 :    
76 :     CLInfo_t *info = NEW(CLInfo_t);
77 :     info->numPlatforms = numPlatforms;
78 :     info->platforms = plats;
79 :    
80 :     return info;
81 :    
82 :     }
83 :    
84 :     static char *GetStringInfo (cl_device_id dev, cl_device_info param)
85 :     {
86 :     char buf[1024];
87 :     CHECK(clGetDeviceInfo (dev, param, sizeof(buf), buf, 0));
88 :     return NEWSTR(buf);
89 :     }
90 :    
91 : jhr 2075 static bool GetDevices (unsigned int platIdx, PlatformInfo_t *plat)
92 : jhr 1671 {
93 :     cl_uint numDevs;
94 :     char buf[512];
95 :    
96 :     // get number of devices for the platform
97 :     clGetDeviceIDs (plat->id, CL_DEVICE_TYPE_ALL, 0, 0, &numDevs);
98 :    
99 :     if (numDevs == 0) {
100 :     plat->numDevices = 0;
101 :     plat->devices = 0;
102 :     return false;
103 :     }
104 :    
105 :     plat->numDevices = numDevs;
106 :     plat->devices = NEWVEC(DeviceInfo_t, numDevs);
107 :    
108 :     cl_device_id *devices = NEWVEC(cl_device_id, numDevs);
109 :     CHECK(clGetDeviceIDs (plat->id, CL_DEVICE_TYPE_ALL, numDevs, devices, 0));
110 :    
111 : jhr 2075 for (unsigned int i = 0; i < numDevs; i++) {
112 : jhr 1671 DeviceInfo_t *dev = &(plat->devices[i]);
113 : jhr 2075 dev->index[0] = platIdx;
114 :     dev->index[1] = i;
115 : jhr 1671 dev->name = GetStringInfo(devices[i], CL_DEVICE_NAME);
116 :     dev->vendor = GetStringInfo(devices[i], CL_DEVICE_VENDOR);
117 :     dev->id = devices[i];
118 :     CHECK(clGetDeviceInfo (
119 :     devices[i], CL_DEVICE_VERSION, sizeof(buf), buf, 0));
120 :     if (sscanf (buf, "OpenCL %d.%d", &(dev->majorVersion), &(dev->minorVersion)) != 2) {
121 :     fprintf(stderr, "error scanning version string: \"%s\"\n", buf);
122 :     exit (1);
123 :     }
124 :     CHECK(clGetDeviceInfo (
125 :     devices[i], CL_DEVICE_TYPE, sizeof(cl_device_type), &(dev->ty), 0));
126 :     CHECK(clGetDeviceInfo (
127 :     devices[i], CL_DEVICE_AVAILABLE, sizeof(cl_bool), &(dev->isAvail), 0));
128 :     CHECK(clGetDeviceInfo (
129 :     devices[i], CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &(dev->addrBits), 0));
130 :     CHECK(clGetDeviceInfo (
131 :     devices[i], CL_DEVICE_ENDIAN_LITTLE, sizeof(cl_bool), &(dev->littleEndian), 0));
132 :     CHECK(clGetDeviceInfo (
133 :     devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &(dev->numCUs), 0));
134 :     CHECK(clGetDeviceInfo (
135 :     devices[i], CL_DEVICE_MAX_CONSTANT_ARGS, sizeof(cl_uint), &(dev->maxConstArgs), 0));
136 :     CHECK(clGetDeviceInfo (
137 :     devices[i], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(cl_uint), &(dev->maxWIDims), 0));
138 :     CHECK(clGetDeviceInfo (
139 :     devices[i], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &(dev->maxWGSize), 0));
140 :     size_t szb = sizeof(size_t) * dev->maxWIDims;
141 :     dev->maxWISize = (size_t *) CheckedAlloc (szb);
142 :     CHECK(clGetDeviceInfo (devices[i], CL_DEVICE_MAX_WORK_ITEM_SIZES, szb, dev->maxWISize, 0));
143 :     CHECK(clGetDeviceInfo (
144 :     devices[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &(dev->globalMemSzb), 0));
145 :     CHECK(clGetDeviceInfo (
146 :     devices[i], CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &(dev->localMemSzb), 0));
147 :     CHECK(clGetDeviceInfo (
148 :     devices[i], CL_DEVICE_MAX_PARAMETER_SIZE, sizeof(size_t), &(dev->maxParamSzb), 0));
149 :     CHECK(clGetDeviceInfo (
150 :     devices[i], CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(cl_ulong), &(dev->maxConstBufSzb), 0));
151 :     CHECK(clGetDeviceInfo (
152 :     devices[i], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &(dev->maxAllocSzb), 0));
153 :     cl_bool imagesSupported;
154 :     CHECK(clGetDeviceInfo (
155 :     devices[i], CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &imagesSupported, 0));
156 :     if (imagesSupported) {
157 :     CHECK(clGetDeviceInfo (
158 :     devices[i], CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &(dev->maxImg2D[0]), 0));
159 :     CHECK(clGetDeviceInfo (
160 :     devices[i], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &(dev->maxImg2D[1]), 0));
161 :     CHECK(clGetDeviceInfo (
162 :     devices[i], CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &(dev->maxImg3D[0]), 0));
163 :     CHECK(clGetDeviceInfo (
164 :     devices[i], CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &(dev->maxImg3D[1]), 0));
165 :     CHECK(clGetDeviceInfo (
166 :     devices[i], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &(dev->maxImg3D[2]), 0));
167 :     }
168 :     else {
169 :     dev->maxImg2D[0] = dev->maxImg2D[1] = 0;
170 :     dev->maxImg3D[0] = dev->maxImg3D[1] = dev->maxImg3D[2] = 0;
171 :     }
172 :     CHECK(clGetDeviceInfo (
173 :     devices[i], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &(dev->charWid), 0));
174 :     CHECK(clGetDeviceInfo (
175 :     devices[i], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &(dev->shortWid), 0));
176 :     CHECK(clGetDeviceInfo (
177 :     devices[i], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &(dev->intWid), 0));
178 :     CHECK(clGetDeviceInfo (
179 :     devices[i], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &(dev->longWid), 0));
180 :     CHECK(clGetDeviceInfo (
181 :     devices[i], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &(dev->floatWid), 0));
182 :     CHECK(clGetDeviceInfo (
183 :     devices[i], CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &(dev->doubleWid), 0));
184 :     // determine the compute-unit width
185 :     if (isCPUDevice(dev))
186 :     dev->cuWidth = 1;
187 :     else if (isGPUDevice(dev))
188 :     if (strcasecmp("AMD", dev->vendor) == 0)
189 :     dev->cuWidth = 64; // an AMD wavefront is 64-wide
190 :     else if (strcasecmp("NVIDIA", dev->vendor) == 0)
191 :     dev->cuWidth = 32; // an NVIDIA warp is 32-wide
192 :     else
193 :     dev->cuWidth = 32; // FIXME: not sure what this should be?
194 :     else
195 :     dev->cuWidth = 1; // FIXME: not sure what this should be?
196 :    
197 :     }
198 :    
199 :     free(devices);
200 :    
201 :     return true;
202 :     }
203 :    
204 : jhr 2075 /*! \brief return the device with the given index.
205 :     */
206 :     DeviceInfo_t *Diderot_GetDeviceByIndex (CLInfo_t *clinfo, unsigned int platIdx, unsigned int devIdx)
207 : jhr 1671 {
208 : jhr 2075 if ((clinfo == 0)
209 :     || (clinfo->numPlatforms <= platIdx)
210 :     || (clinfo->platforms[platIdx].numDevices <= devIdx))
211 :     return 0;
212 :     else
213 :     return &(clinfo->platforms[platIdx].devices[devIdx]);
214 :     }
215 :    
216 :     void Diderot_PrintCLInfo (FILE *outS, CLInfo_t *clinfo)
217 :     {
218 : jhr 1671 if (clinfo->numPlatforms == 0) {
219 :     fprintf(outS, "No OpenCL platforms\n");
220 :     return;
221 :     }
222 :    
223 :     fprintf(outS, "OpenCL profile:\n");
224 : jhr 2075 for (unsigned int i = 0; i < clinfo->numPlatforms; i++) {
225 : jhr 1671 PlatformInfo_t *plat = &(clinfo->platforms[i]);
226 :     fprintf (outS, " Platform %d (%s)\n", i, plat->name);
227 : jhr 2075 for (unsigned int j = 0; j < plat->numDevices; j++) {
228 : jhr 1671 DeviceInfo_t *dev = &(plat->devices[j]);
229 :     if (dev->isAvail)
230 :     fprintf (outS, " Device %d.%d (%s):\n", i, j, dev->name);
231 :     else
232 :     fprintf (outS, " Device %d.%d (%s): **UNAVAILABLE**\n", i, j, dev->name);
233 :     fprintf (outS, " Vendor: %s\n", dev->vendor);
234 :     fprintf (outS, " OpenCL version: %d.%d\n",
235 :     dev->majorVersion, dev->minorVersion);
236 :     fprintf (outS, " Type: ");
237 :     if (isCPUDevice(dev)) fprintf (outS, " CPU");
238 :     if (isGPUDevice(dev)) fprintf (outS, " GPU");
239 :     if (dev->ty & CL_DEVICE_TYPE_ACCELERATOR) fprintf (outS, " ACCELERATOR");
240 :     if (dev->ty & CL_DEVICE_TYPE_DEFAULT) fprintf (outS, " DEFAULT");
241 :     fprintf (outS, "\n");
242 :     fprintf (outS, " Address size: %d\n", dev->addrBits);
243 :     fprintf (outS, " Endianess: %s\n", dev->littleEndian ? "LITTLE" : "BIG");
244 :     fprintf (outS, " Num. compute units: %d", dev->numCUs);
245 :     if (dev->cuWidth > 1)
246 :     fprintf (outS, " * %d\n", dev->cuWidth);
247 :     else
248 :     fprintf (outS, "\n");
249 :     fprintf (outS, " Max. dimensions: %d\n", dev->maxWIDims);
250 :     fprintf (outS, " Max. work group size: %ld\n", (long)(dev->maxWGSize));
251 :     fprintf (outS, " Max. work items: ");
252 :     for (int k = 0; k < dev->maxWIDims; k++)
253 :     fprintf (outS, "%s%ld", (k > 0) ? " x " : "", (long)(dev->maxWISize[k]));
254 :     fprintf (outS, "\n");
255 :     fprintf (outS, " Global memory size: %ld\n", (long)(dev->globalMemSzb));
256 :     fprintf (outS, " Local memory size: %ld\n", (long)(dev->localMemSzb));
257 :     fprintf (outS, " Max. parameter size: %ld\n", (long)(dev->maxParamSzb));
258 :     fprintf (outS, " Max. allocation size: %ld\n", (long)(dev->maxAllocSzb));
259 :     fprintf (outS, " Max. const. buffer size: %ld\n", (long)(dev->maxConstBufSzb));
260 :     fprintf (outS, " Max. const. arguments: %d\n", dev->maxConstArgs);
261 :     fprintf (outS, " Max. 2D image size: %ld x %ld\n",
262 :     (long)(dev->maxImg2D[0]), (long)(dev->maxImg2D[1]));
263 :     fprintf (outS, " Max. 3D image size: %ld x %ld x %ld\n",
264 :     (long)(dev->maxImg3D[0]), (long)(dev->maxImg3D[1]), (long)(dev->maxImg3D[2]));
265 :     fprintf (outS, " Prefered vector width: char%d, short%d, int%d, long%d\n",
266 :     dev->charWid, dev->shortWid, dev->intWid, dev->longWid);
267 :     fprintf (outS, " float%d", dev->floatWid);
268 :     if (dev->doubleWid > 0)
269 :     fprintf (outS, ", double%d\n", dev->doubleWid);
270 :     else
271 :     fprintf (outS, "\n");
272 :     }
273 :     }
274 :    
275 :     }
276 : jhr 2075
277 :     DeviceInfo_t *Diderot_DefaultCLDevice (CLInfo_t *clinfo)
278 :     {
279 :     if ((clinfo == 0) || (clinfo->numPlatforms == 0))
280 :     return 0;
281 :    
282 :     // we pick the first GPU device that we find
283 :     for (unsigned int i = 0; i < clinfo->numPlatforms; i++) {
284 :     PlatformInfo_t *plat = &(clinfo->platforms[i]);
285 :     for (unsigned int j = 0; j < plat->numDevices; j++) {
286 :     if (isGPUDevice(&(plat->devices[j])))
287 :     return &(plat->devices[j]);
288 :     }
289 :     }
290 :    
291 :     // otherwise we pick a CPU device
292 :     for (unsigned int i = 0; i < clinfo->numPlatforms; i++) {
293 :     PlatformInfo_t *plat = &(clinfo->platforms[i]);
294 :     for (unsigned int j = 0; j < plat->numDevices; j++) {
295 :     if (isCPUDevice(&(plat->devices[j])))
296 :     return &(plat->devices[j]);
297 :     }
298 :     }
299 :    
300 :     // otherwise return 0
301 :     return 0;
302 :    
303 :     }

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0