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

SCM Repository

[diderot] View of /branches/pure-cfg/src/lib/cl-target/clinfo.c
ViewVC logotype

View of /branches/pure-cfg/src/lib/cl-target/clinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1379 - (download) (as text) (annotate)
Thu Jun 23 14:48:07 2011 UTC (7 years, 11 months ago) by jhr
File size: 7849 byte(s)
  Improved OpenCL info and added mechanism to print the OpenCL profile
/*! \file clinfo.c
 *
 * \author John Reppy
 *
 * \brief This file contains functions that can be used to determine properties of the
 * host machine's OpenCL support.
 */

/*
 * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 */

#include "clinfo.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_PLATFORMS	16

static bool GetDevices (PlatformInfo_t *plat);

STATIC_INLINE void *alloc (size_t szb)
{
    void *p = malloc(szb);
    if (p == 0) {
        fprintf (stderr, "fatal error: unable to allocate %d bytes of memory\n", (int)szb);
        exit (1);
    }
    return p;
}

#define NEW(ty)         (ty *)alloc(sizeof(ty))
#define NEWVEC(ty,n)    (ty *)alloc(sizeof(ty) * (n))
#define NEWSTR(s)       strcpy((char *)alloc(strlen(s)+1), s)

#define CHECK(call)     do {                                                    \
        cl_int __sts = call;                                                    \
        if (__sts != CL_SUCCESS) {                                              \
            fprintf(stderr, "error %d at %s:%d\n", __sts, __FILE__, __LINE__);  \
            exit (1);                                                           \
        }                                                                       \
    } while (0)


CLInfo_t *GetCLInfo ()
{
    cl_platform_id	platformIDs[MAX_PLATFORMS];
    char                buf[512];

  // get platform info
  // get number of OpenCL platforms
    cl_uint numPlatforms;
    CHECK(clGetPlatformIDs (MAX_PLATFORMS, platformIDs, &numPlatforms));

    PlatformInfo_t *plats = NEWVEC(PlatformInfo_t, numPlatforms);
    for (int i = 0;  i < numPlatforms;  i++) {
        clGetPlatformInfo (platformIDs[i], CL_PLATFORM_NAME, sizeof(buf), buf, 0);
        plats[i].name = NEWSTR(buf);
        plats[i].id = platformIDs[i];
      // get OpenCL version info
        clGetPlatformInfo (platformIDs[i], CL_PLATFORM_VERSION, sizeof(buf), buf, 0);
// FIXME: parser version info
      // get extension info
// FIXME: TODO
      // get device info
        if (! GetDevices (&(plats[i]))) {
          // free storage
            for (int j = 0;  j <= i;  j++) {
                free (plats[i].name);
            }
            free (plats);
        }
    }

    CLInfo_t *info = NEW(CLInfo_t);
    info->numPlatforms = numPlatforms;
    info->platforms = plats;

    return info;

}

static bool GetDevices (PlatformInfo_t *plat)
{
    cl_uint             numDevs;
    char                buf[512];

  // get number of devices for the platform
    clGetDeviceIDs (plat->id, CL_DEVICE_TYPE_ALL, 0, 0, &numDevs);

    if (numDevs == 0) {
        plat->numDevices = 0;
        plat->devices = 0;
        return false;
    }

    plat->numDevices = numDevs;
    plat->devices = NEWVEC(DeviceInfo_t, numDevs);
    
    cl_device_id *devices = NEWVEC(cl_device_id, numDevs);
    CHECK(clGetDeviceIDs (plat->id, CL_DEVICE_TYPE_ALL, numDevs, devices, 0));

    for (int i = 0;  i < numDevs;  i++) {
        DeviceInfo_t *dev = &(plat->devices[i]);
        CHECK(clGetDeviceInfo (devices[i], CL_DEVICE_NAME, sizeof(buf), buf, 0));
        dev->name = NEWSTR(buf);
        dev->id = devices[i];
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_TYPE, sizeof(cl_device_type), &(dev->ty), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_AVAILABLE, sizeof(cl_bool), &(dev->isAvail), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &(dev->addrBits), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_ENDIAN_LITTLE, sizeof(cl_bool), &(dev->littleEndian), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &(dev->numCUs), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(cl_uint), &(dev->maxWIDims), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &(dev->maxWGSize), 0));
        size_t szb = sizeof(size_t) * dev->maxWIDims;
        dev->maxWISize = (size_t *) alloc (szb);
        CHECK(clGetDeviceInfo (devices[i], CL_DEVICE_MAX_WORK_ITEM_SIZES, szb, dev->maxWISize, 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &(dev->globalMemSzb), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &(dev->localMemSzb), 0));
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &(dev->maxAllocSzb), 0));
        cl_bool imagesSupported;
        CHECK(clGetDeviceInfo (
            devices[i], CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &imagesSupported, 0));
        if (imagesSupported) {
            CHECK(clGetDeviceInfo (
                devices[i], CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &(dev->maxImg2D[0]), 0));
            CHECK(clGetDeviceInfo (
                devices[i], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &(dev->maxImg2D[1]), 0));
            CHECK(clGetDeviceInfo (
                devices[i], CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &(dev->maxImg3D[0]), 0));
            CHECK(clGetDeviceInfo (
                devices[i], CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &(dev->maxImg3D[1]), 0));
            CHECK(clGetDeviceInfo (
                devices[i], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &(dev->maxImg3D[2]), 0));
        }
        else {
            dev->maxImg2D[0] = dev->maxImg2D[1] = 0;
            dev->maxImg3D[0] = dev->maxImg3D[1] = dev->maxImg3D[2] = 0;
        }
    }

    free(devices);

    return true;
}

void PrintCLInfo (FILE *outS, CLInfo_t *clinfo)
{
    if (clinfo->numPlatforms == 0) {
        fprintf(outS, "No OpenCL platforms\n");
        return;
    }

    fprintf(outS, "OpenCL profile:\n");
    for (int i = 0;  i < clinfo->numPlatforms;  i++) {
        PlatformInfo_t *plat = &(clinfo->platforms[i]);
        fprintf (outS, "  Platform %d (%s)\n", i, plat->name);
        for (int j = 0;  j < plat->numDevices;  j++) {
            DeviceInfo_t *dev = &(plat->devices[j]);
            if (dev->isAvail)
                fprintf (outS, "    Device %d.%d (%s):\n", i, j, dev->name);
            else
                fprintf (outS, "    Device %d.%d (%s): **UNAVAILABLE**\n", i, j, dev->name);
            fprintf (outS, "      Type:                 %s\n",
                isGPUDevice(dev) ? "GPU" : isCPUDevice(dev) ? "CPU" : "UNKNOWN");
            fprintf (outS, "      Address size:         %d\n", dev->addrBits);
            fprintf (outS, "      Endianess:            %s\n", dev->littleEndian ? "LITTLE" : "BIG");
            fprintf (outS, "      Num. compute units:   %d\n", dev->numCUs);
            fprintf (outS, "      Max. dimensions:      %d\n", dev->maxWIDims);
            fprintf (outS, "      Max. work group size: %ld\n", (long)(dev->maxWGSize));
            fprintf (outS, "      Max. work items:      ");
            for (int k = 0;  k < dev->maxWIDims;  k++)
                fprintf (outS, "%s%ld", (k > 0) ? " x " : "", (long)(dev->maxWISize[k]));
            fprintf (outS, "\n");
            fprintf (outS, "      Global memory size:   %ld\n", (long)(dev->globalMemSzb));
            fprintf (outS, "      Local memory size:    %ld\n", (long)(dev->localMemSzb));
            fprintf (outS, "      Max. allocation size: %ld\n", (long)(dev->maxAllocSzb));
            fprintf (outS, "      Max. 2D image size:   %ld x %ld\n",
                (long)(dev->maxImg2D[0]), (long)(dev->maxImg2D[1]));
            fprintf (outS, "      Max. 3D image size:   %ld x %ld x %ld\n",
                (long)(dev->maxImg3D[0]), (long)(dev->maxImg3D[1]), (long)(dev->maxImg3D[2]));
        }
    }

}

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