调用clCreateContext时出错CL_DEVICE_NOT_AVAILABLE(Intel Core2Duo,Intel OCL SDK 3.0 beta)

时间:2013-03-19 12:28:31

标签: linux opencl intel

我正在尝试使用OpenCL(英特尔opencl-1.2-3.0.56860)。我设法在Ubuntu 12.05下安装了英特尔的OpenCL SDK(使用“alien”将rpm包转换为* .deb包)。现在我尝试让我的第一个简单的OpenCL程序运行...要运行程序,我需要使用设置LD_LIBRARY_PATH:

export LD_LIBRARY_PATH=/opt/intel/opencl/lib64/

我的问题是,在调用clCreateContext(...)时,我总是收到错误“CL_DEVICE_NOT_AVAILABLE”。

这是我的源代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#include <string.h>

// Enable double precision values
#pragma OPENCL EXTENSION cl_khr_fp64 : enable

// OpenCL kernel. Each work item takes care of one element of c
const char *kernelSource =                                      "\n" \
"__kernel void vecAdd(  __global double *a,                       \n" \
"                       __global double *b,                       \n" \
"                       __global double *c,                       \n" \
"                       const unsigned int n)                    \n" \
"{                                                               \n" \
"    //Get our global thread ID                                  \n" \
"    int id = get_global_id(0);                                  \n" \
"                                                                \n" \
"    //Make sure we do not go out of bounds                      \n" \
"    if (id < n)                                                 \n" \
"        c[id] = a[id] + b[id];                                  \n" \
"}                                                               \n" \
                                                                "\n" ;

const char* err2str(cl_int err) {
  switch(err) {
  case CL_SUCCESS: return "CL_SUCCESS";
  case CL_INVALID_PROGRAM: return "CL_INVALID_PROGRAM";
  case CL_INVALID_VALUE: return "CL_INVALID_VALUE";
  case CL_INVALID_DEVICE: return "CL_INVALID_DEVICE";
  case CL_INVALID_BINARY: return "CL_INVALID_BINARY";
  case CL_INVALID_BUILD_OPTIONS: return "CL_INVALID_BUILD_OPTIONS";
  case CL_INVALID_OPERATION: return "CL_INVALID_OPERATION";
  case CL_DEVICE_NOT_AVAILABLE: return "CL_DEVICE_NOT_AVAILABLE";
  default: return "unknown";
  }
}

void pfn_notify(const char *errinfo, const void *private_info, size_t cb, void *user_data)
{
  fprintf(stderr, "OpenCL Error (via pfn_notify): %s\n", errinfo);
}

cl_platform_id GetIntelOCLPlatform()
{
    cl_platform_id pPlatforms[10] = { 0 };
    char pPlatformName[128] = { 0 };

    cl_uint uiPlatformsCount = 0;
    cl_int err = clGetPlatformIDs(10, pPlatforms, &uiPlatformsCount);
    for (cl_uint ui = 0; ui < uiPlatformsCount; ++ui)
    {
        err = clGetPlatformInfo(pPlatforms[ui], CL_PLATFORM_NAME, 128 * sizeof(char), pPlatformName, NULL);
        if ( err != CL_SUCCESS )
        {
            printf("ERROR: Failed to retreive platform vendor name.\n", ui);
            return NULL;
        }

        if (!strcmp(pPlatformName, "Intel(R) OpenCL"))
            return pPlatforms[ui];
    }

    return NULL;
}

int main( int argc, char* argv[] )
{
    cl_platform_id cpPlatform;        // OpenCL platform
    cl_device_id device_id;           // device ID
    cl_context context;               // context
    cl_command_queue queue;           // command queue
    cl_program program;               // program
    cl_kernel kernel;                 // kernel
    size_t cb;
    cl_device_id devices[100];
    cl_uint devices_n = 0;
    cl_int err;


    cl_platform_id intel_platform_id = GetIntelOCLPlatform();
    if( intel_platform_id == NULL ) {
      printf("ERROR: Failed to find Intel OpenCL platform.\n");
      return -1;
    }

    // Get Device Info...
    err = clGetDeviceIDs(intel_platform_id, CL_DEVICE_TYPE_ALL, 100, devices, &devices_n);
    printf("ERR(clGetDeviceIDs) = %d\n", err);
    printf("#DEVICES: %d\n", devices_n);


    for (int i=0; i<devices_n; i++) {
       char buffer[10240];
       cl_uint buf_uint;
       cl_ulong buf_ulong;
       printf("  -- %d --\n", i);
       err = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
       printf("  DEVICE_NAME = %s\n", buffer);
       err = clGetDeviceInfo(devices[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL);
       printf("  DEVICE_VENDOR = %s\n", buffer);
       err = clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, sizeof(buffer), buffer, NULL);
       printf("  DEVICE_VERSION = %s\n", buffer);
       err = clGetDeviceInfo(devices[i], CL_DRIVER_VERSION, sizeof(buffer), buffer, NULL);
       printf("  DRIVER_VERSION = %s\n", buffer);
       err = clGetDeviceInfo(devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(buf_uint), &buf_uint, NULL);
       printf("  DEVICE_MAX_COMPUTE_UNITS = %u\n", (unsigned int)buf_uint);
       err = clGetDeviceInfo(devices[i], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(buf_uint), &buf_uint, NULL);
       printf("  DEVICE_MAX_CLOCK_FREQUENCY = %u\n", (unsigned int)buf_uint);
       err = clGetDeviceInfo(devices[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(buf_ulong), &buf_ulong, NULL);
       printf("  DEVICE_GLOBAL_MEM_SIZE = %llu\n", (unsigned long long)buf_ulong);
    }

    context = clCreateContext(NULL, 1, devices, &pfn_notify, NULL, &err);
    printf("ERR(clCreateContext) = %d [%s]\n", err, err2str(err));


    // Create a context
    cl_context_properties context_properties[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)intel_platform_id, (cl_context_properties)NULL };

//    context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
    context = clCreateContextFromType(context_properties, CL_DEVICE_TYPE_CPU, NULL, NULL, &err);
    printf("ERR(clCreateContextFromType) = %d [%s]\n", err, err2str(err));
    if (err != CL_SUCCESS) exit(0);

    if (context == (cl_context)0) {
      printf("Illegal context?");
      exit(0);
    }

    return 0;
}

输出是:

ERR(clGetDeviceIDs) = 0
#DEVICES: 1
  -- 0 --
  DEVICE_NAME = Intel(R) Core(TM)2 Duo CPU     P7450  @ 2.13GHz
  DEVICE_VENDOR = Intel(R) Corporation
  DEVICE_VERSION = OpenCL 1.2 (Build 56860)
  DRIVER_VERSION = 1.2
  DEVICE_MAX_COMPUTE_UNITS = 2
  DEVICE_MAX_CLOCK_FREQUENCY = 2130
  DEVICE_GLOBAL_MEM_SIZE = 3152510976
ERR(clCreateContext) = -2 [CL_DEVICE_NOT_AVAILABLE]
ERR(clCreateContextFromType) = -2 [CL_DEVICE_NOT_AVAILABLE]

任何想法如何解决?

此致 斯蒂芬

----编辑-----

CPU有sse4_1标志(也是:sse,sse2,sss3)。

cat / proc / cpuinfo

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 23
model name      : Intel(R) Core(TM)2 Duo CPU     P7450  @ 2.13GHz
stepping        : 6
microcode       : 0x60c
cpu MHz         : 800.000
cache size      : 3072 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 10
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm sse4_1 lahf_lm dtherm
bogomips        : 4255.56
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

[ same for the other core]

1 个答案:

答案 0 :(得分:7)

英特尔OpenCL CPU至少需要SSE 4.1。 Core 2 Duo只能升级到SSSE3。

http://software.intel.com/en-us/articles/opencl-sdk-frequently-asked-questions#14

编辑:某些版本的Core 2 Duo支持SSE 4.1 以下是Intel OpenCL驱动程序支持的处理器列表 http://software.intel.com/en-us/articles/opencl-release-notes#2

不支持某些版本的Core 2。 “不支持所有其他版本的英特尔®酷睿™2处理器”

例如,您可以使用CPU-Z来查找CPU支持的SSE版本。

安装AMD OpenCL CPU驱动程序。它只需要SSE2。在Windows上我安装了Radeon GPU驱动程序,即使我没有AMD GPU。它仍然安装了AMD OpenCL CPU驱动程序,它与Nvidia驱动程序没有冲突。我不知道在Linux上。但现在我可以使用Intel CPU,AMD CPU和Nvidia GPU OpenCL驱动程序。