Results 1 to 2 of 2

Thread: C++ OpenCL helper object/function

  1. #1
    Junior Member
    Join Date
    Feb 2010
    Posts
    23

    C++ OpenCL helper object/function

    I'm not sure this is the correct forum, please move if it isn't.

    I have created this C++ helper object and function that I thought might be of use for anyone using the C++ bindings. Basically the helper queries for all of the platforms and devices in the system and filters them using specified criteria. The platform, device, context, and command queue for each device is placed in a vector array and returned for use in the calling program. My goal was to have an easy way to check and find only those devices that my program can use and have them in an easily accessible place. Right now the only filtering it does is on the device type (cl_device_type) and OpenCL version (CL_DEVICE_OPENCL_C_VERSION), but the function can be easily modified for more filters.

    My questions are, is this helpful, and I'm I doing this correctly (should probably have more error checking)? Any comments and help would be most appreciated.

    Here is the clInitDevices helper object/function (I use linux so that is what I tested it on, YMMV):
    Code :
    // Jason Grimes - 8/30/2010 University of Alaska, GINA program.
    // This class holds all of objects needed for OpenCL to communicate with a
    // device.
    class clDeviceList
      {
      public:
      clDeviceList() { }
      clDeviceList( cl::Platform* newPlatform, std::vector<cl::Device>* newDevice,
          cl_device_type nDevType ) :
          clPlatform( *newPlatform ),
          clDevice( *newDevice )
        {
        cl_context_properties clProperties[] =
          {
          CL_CONTEXT_PLATFORM,
          (cl_context_properties)clPlatform(),
          0, 0, 0
          };
     
        clContext = cl::Context( (cl_device_type)nDevType, clProperties, NULL,
            NULL, NULL );
        clQueue = cl::CommandQueue( clContext, clDevice[0], 0, NULL );
        }
     
      const cl::Platform &getPlatform() const { return clPlatform; }
      const std::vector<cl::Device> &getDevice() const { return clDevice; }
      const cl::Context &getContext() const { return clContext; }
      const cl::CommandQueue &getQueue() const { return clQueue; }
     
      private:
      cl::Platform clPlatform;               // Holds this OpenCL Platform
      std::vector<cl::Device> clDevice;      // Holds this OpenCL Device
      cl::Context clContext;                 // Holds this OpenCL Context
      cl::CommandQueue clQueue;              // Holds this OpenCL Command Queue
      };
     
    // A function to initialize OpenCL devices and to filter them by OpenCL 
    // version and device type. 
    std::vector<clDeviceList*> clInitDevices( cl_device_type nDevType,
          const std::string clVersionCompare )
      {
      std::vector<cl::Platform> clPlatforms;         // Platforms 
      std::vector<clDeviceList*> clDevices;          // OpenCL Devices
      cl::STRING_CLASS clVersion;                    // OpenCL version string
     
      // Get all platforms on the system
      cl::Platform::get( &clPlatforms );
     
      // Check each platform ...
      std::vector<cl::Device> clDeviceTemp;  // temp holding array
      for( unsigned int cnt=0; cnt < clPlatforms.size(); cnt++ )
        {
        // Process OpenCL platforms and devices, match to params 
        clPlatforms[cnt].getInfo( (cl_platform_info) CL_PLATFORM_VERSION,
           &clVersion );
     
        // Add compatable devices into devices vector
        try
          {
          clPlatforms[cnt].getDevices( (cl_device_type)nDevType, &clDeviceTemp );
          }
        catch( cl::Error error )
          {
          if( error.err() == -1 )
            std::cout << "Device not found" << std::endl;
          }
     
        for( unsigned int cnt2=0; cnt2 < clDeviceTemp.size(); cnt2++ )
          {
          std::vector<cl::Device> devtemp;  // Temp array will only have 1 entry
          devtemp.push_back( clDeviceTemp[cnt2] );
          devtemp[0].getInfo( (cl_device_info)CL_DEVICE_OPENCL_C_VERSION,
              &clVersion );
     
          if( clVersion.find( clVersionCompare ) != std::string::npos )
            clDevices.push_back( new clDeviceList( &clPlatforms[cnt],
                &devtemp, nDevType ));
          }
        }
      return clDevices;
      }

    Here is some example code that demonstrates how to use the clInitDevices object/function.

    Code :
    //  Jason Grimes - 8/30/2010 University of Alaska, GINA program.
    // Get information about installed OpenCL installed devices
    // ---------------------------------------------------------------------------
    // Use - openclinfo { -gpu } or { -cpu }
    // openclinfo defaults to -all and reports on all of the devices in the system
    // -gpu will list only gpu devices
    // -cpu will list only cpu devices
    // -ver #.# list only devices that are valid for the specified OpenCL version
    // ---------------------------------------------------------------------------
    // Compiled with the following g++ command:
    // g++ openclinfo.cpp -o openclinfo -I /usr/include/CL -lOpenCL -Wall
    //
     
    // Defines
    #define __CL_ENABLE_EXCEPTIONS
    //#define __NO_STD_STRING
     
    // Includes
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cl.hpp>
    #include <cstdio>
    #include <cstdlib>
    #include "opencl_devs.hpp"
     
    // Main
    int main( int argc, char **argv )
      {
      cl_device_type mode = CL_DEVICE_TYPE_ALL;  // Default type query mode/text
      std::string mode_name = "CL_DEVICE_TYPE_ALL";
      std::string clversion = "1.";              // Default OpenCL version check
     
      // Parse command line args
      if( argc > 1 )
        {
        for( int cnt=1; cnt<argc; cnt++ )
          {
          std::string args( argv[cnt] );
          if( args.compare( "-cpu" ) == 0 )
            {
            mode = CL_DEVICE_TYPE_CPU; // type CPU mode
            mode_name = "CL_DEVICE_TYPE_CPU";
            }
          if( args.compare( "-gpu" ) == 0 )
            {
            mode = CL_DEVICE_TYPE_GPU; // type GPU mode
            mode_name = "CL_DEVICE_TYPE_GPU";
            }
          if( args.compare( "-ver" ) == 0 )
            {
            cnt++;
            clversion = argv[cnt]; // set the version number to check
            }
          }
        }
     
      if( argc > 4 )
        {
        std::cout << std::endl;
        std::cout << "Usage - openclinfo {-gpu or -cpu} {-ver #.#}" << std::endl;
        std::cout << "openclinfo defaults to -all and reports on all of the" <<
            " devices in the system, version defaults to 1.#" << std::endl;
        std::cout << "-gpu will list only gpu devices" << std::endl;
        std::cout << "-cpu will list only cpu devices" << std::endl;
        std::cout << "-ver #.# will list only devices with that OpenCL version"
            << std::endl;
        std::cout << "Example: openclinfo -gpu -ver 1.0" << std::endl << std::endl;
        }
     
      // Initialize the OpenCL interface
      std::vector<clDeviceList*> myopencl =
          clInitDevices( (cl_device_type)mode, clversion );
     
      if( myopencl.size() == 0 )
        {
        std::cout << "This system does not have an OpenCL compatable device "
           << std::endl;
        std::cout << "that has the following profile:" << std::endl << std::endl;
        std::cout << "Type - " << mode_name << std::endl;
        std::cout << "OpenCL Version - " << clversion << std::endl;
        return 0;
        }
     
      // Report on the valid devices:
      std::cout << std::endl << "Found " <<  myopencl.size() << " Devices"
          << std::endl << std::endl;
     
      std::string name;            // Name of Device
      std::string extensions;      // The Extensions the Device Supports
      std::string openclver;       // The OpenCL Version the Device Supports
      for( unsigned int cnt=0; cnt<myopencl.size(); cnt++ )
        {
        std::cout << "Device - " << cnt << std::endl;
     
        myopencl[cnt]->getDevice()[0].getInfo( (cl_device_info)CL_DEVICE_NAME,
             &name );
        myopencl[cnt]->getDevice()[0].getInfo(
            (cl_device_info)CL_DEVICE_OPENCL_C_VERSION, &openclver );
        myopencl[cnt]->getDevice()[0].getInfo( (cl_device_info)CL_DEVICE_EXTENSIONS,
             &extensions );
     
        std::cout << "Name - " << name << std::endl;
        std::cout << "OpenCL Version - " << openclver << std::endl;
        std::cout << "Extensions - " << extensions << std::endl;
        std::cout << std::endl;
        }
      }

  2. #2
    Junior Member
    Join Date
    Feb 2010
    Posts
    23

    Re: C++ OpenCL helper object/function

    I changed the code slightly so that I no longer keep the device in a vector array. I think it's a lot cleaner now just change all of the "getDevice()[0]" to "getDevice()" in the example code and it should work.

    Code :
    // Jason Grimes - 8/30/2010 University of Alaska, GINA program.
    // This class holds all of objects needed for OpenCL to communicate with a
    // device.
    class clDeviceList
      {
      public:
      clDeviceList() { }
      clDeviceList( cl::Platform* newPlatform, cl::Device* newDevice,
          cl_device_type nDevType ) :
          clPlatform( *newPlatform ),
          clDevice( *newDevice )
        {
        cl_context_properties clProperties[] =
          {
          CL_CONTEXT_PLATFORM,
          (cl_context_properties)clPlatform(),
          0, 0, 0
          };
     
        clContext = cl::Context( (cl_device_type)nDevType, clProperties, NULL,
            NULL, NULL );
        clQueue = cl::CommandQueue( clContext, clDevice, 0, NULL );
        }
     
      const cl::Platform &getPlatform() const { return clPlatform; }
      const cl::Device &getDevice() const { return clDevice; }
      const cl::Context &getContext() const { return clContext; }
      const cl::CommandQueue &getQueue() const { return clQueue; }
     
      private:
      cl::Platform clPlatform;               // Holds this OpenCL Platform
      cl::Device clDevice;                   // Holds this OpenCL Device
      cl::Context clContext;                 // Holds this OpenCL Context
      cl::CommandQueue clQueue;              // Holds this OpenCL Command Queue
      };
     
    // A function to initialize OpenCL devices and to filter them by OpenCL 
    // version and device type. 
    std::vector<clDeviceList*> clInitDevices( cl_device_type nDevType,
          const std::string clVersionCompare )
      {
      std::vector<cl::Platform> clPlatforms;         // Platforms 
      std::vector<clDeviceList*> clDevices;          // OpenCL Devices
      cl::STRING_CLASS clVersion;                    // OpenCL version string
     
      // Get all platforms on the system
      cl::Platform::get( &clPlatforms );
     
      // Check each platform ...
      std::vector<cl::Device> clDeviceTemp;  // temp holding array
      for( unsigned int cnt=0; cnt < clPlatforms.size(); cnt++ )
        {
        // Process OpenCL platforms and devices, match to params 
        clPlatforms[cnt].getInfo( (cl_platform_info) CL_PLATFORM_VERSION,
           &clVersion );
     
        // Add compatable devices into devices vector
        try
          {
          clPlatforms[cnt].getDevices( (cl_device_type)nDevType, &clDeviceTemp );
          }
        catch( cl::Error error )
          {
          if( error.err() == -1 )
            continue;
          }
     
        for( unsigned int cnt2=0; cnt2 < clDeviceTemp.size(); cnt2++ )
          {
          clDeviceTemp[cnt2].getInfo( (cl_device_info)CL_DEVICE_OPENCL_C_VERSION,
              &clVersion );
     
          if( clVersion.find( clVersionCompare ) != std::string::npos )
            clDevices.push_back( new clDeviceList( &clPlatforms[cnt],
                &clDeviceTemp[cnt2], nDevType ));
          }
        }
      return clDevices;
      }

    Grimm

Similar Threads

  1. Image3D object in OpenCL
    By xargon in forum OpenCL
    Replies: 0
    Last Post: 05-15-2012, 09:06 AM
  2. OpenCL Object Queries and speed
    By moniker in forum OpenCL
    Replies: 1
    Last Post: 08-26-2010, 03:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •