2015-05-27 2 views
2

Я пытаюсь следующей простого OpenCL программы сложения векторов (я не включил свою функцию printSystemInfo() для краткости):OpenCL демо-программа работает на одной системе, но не на другой очень подобную системе VirtualBox

// Vector addition demo similar to one from Oak Ridge lab: 
// https://www.olcf.ornl.gov/tutorials/opencl-vector-addition/#vecAdd.c 


#include <stdio.h> 
#include <stdlib.h> 

//To suppress warnings when using the deprecated clCreateCommandQueue of OpenCL v1.0: 
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS 

#include <math.h> 
#include <CL/opencl.h> 

// Declaration of a printing function, that is not seen at this StackOverflow question 
int printSystemInfo (cl_platform_id platform_id, cl_device_id device_id); 

// OpenCL kernel. Each work item takes care of one element of vector c 
const char *kernelSource =          "\n" \ 
"__kernel void vecAdd( __global int *a,      \n" \ 
"      __global int *b,      \n" \ 
"      __global int *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" ; 

int main(int argc, char* argv[]) 
{ 
    // Length of vectors 
    unsigned int n = 10; 

    // Host input vectors 
    int *h_a; 
    int *h_b; 
    // Host output vector 
    int *h_c; 

    // Device input buffers 
    cl_mem d_a; 
    cl_mem d_b; 
    // Device output buffer 
    cl_mem d_c; 

    cl_platform_id platform_id;  // 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, in bytes, of each vector 
    size_t bytes = n*sizeof(int); 

    // Allocate memory for each vector on host 
    h_a = (int*)malloc(bytes); 
    h_b = (int*)malloc(bytes); 
    h_c = (int*)malloc(bytes); 

    // Initialize vectors on host 
    int i; 
    for(i = 0; i < n; i++) 
    { 
     h_a[i] = i; 
     h_b[i] = i+1; 
    } 

    size_t globalSize, localSize; 
    cl_int err; 

    // Number of work items in each local work group 
    localSize = 64; 

    // Number of total work items - localSize must be a divisor 
    globalSize = ceil(n/(float)localSize)*localSize; 

    // Bind to platform 
    err = clGetPlatformIDs(1, &platform_id, NULL); 

    // Get ID for the device 
    //err = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); 
    err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); 

    // Call a local function that fetches and prints system info 
    err = printSystemInfo (platform_id, device_id); 

    // Create a context 
    context = clCreateContext(0, 1, &device_id, NULL, NULL, &err); 

    // Create a command queue 
    queue = clCreateCommandQueue(context, device_id, 0, &err); 

    // Create the compute program from the source buffer 
    program = clCreateProgramWithSource(context, 1, 
          (const char **) & kernelSource, NULL, &err); 

    // Build the program executable 
    clBuildProgram(program, 0, NULL, NULL, NULL, NULL); 

    // Create the compute kernel in the program we wish to run 
    kernel = clCreateKernel(program, "vecAdd", &err); 

    // Create the input and output arrays in device memory for our calculation 
    d_a = clCreateBuffer(context, CL_MEM_READ_ONLY, bytes, NULL, NULL); 
    d_b = clCreateBuffer(context, CL_MEM_READ_ONLY, bytes, NULL, NULL); 
    d_c = clCreateBuffer(context, CL_MEM_WRITE_ONLY, bytes, NULL, NULL); 

    // Write our data set into the input array in device memory 
    err = clEnqueueWriteBuffer(queue, d_a, CL_TRUE, 0, 
            bytes, h_a, 0, NULL, NULL); 
    err |= clEnqueueWriteBuffer(queue, d_b, CL_TRUE, 0, 
            bytes, h_b, 0, NULL, NULL); 

    // Set the arguments to our compute kernel 
    err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_a); 
    err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &d_b); 
    err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &d_c); 
    err |= clSetKernelArg(kernel, 3, sizeof(unsigned int), &n); 

    // Execute the kernel over the entire range of the data set 
    err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &globalSize, &localSize, 
                   0, NULL, NULL); 

    // Wait for the command queue to get serviced before reading back results 
    clFinish(queue); 

    // Read the results from the device 
    clEnqueueReadBuffer(queue, d_c, CL_TRUE, 0, 
           bytes, h_c, 0, NULL, NULL); 

    //Print vectors a, b and c=a+b 
    for(i=0; i<n; i++) 
     printf("a: %d b: %d c=a+b: %d \n", h_a[i], h_b[i], h_c[i]); 

    // release OpenCL resources 
    clReleaseMemObject(d_a); 
    clReleaseMemObject(d_b); 
    clReleaseMemObject(d_c); 
    clReleaseProgram(program); 
    clReleaseKernel(kernel); 
    clReleaseCommandQueue(queue); 
    clReleaseContext(context); 

    //release host memory 
    free(h_a); 
    free(h_b); 
    free(h_c); 

    return 0; 
} 

Он работает на системе EC2 Amazon под управлением Ubuntu 14.04 ...

[email protected]:~/programs/OpenCL$ gcc ./cldemo.c ./printSystemInfo.c -o ./cldemo -I/opt/intel/intel-opencl-1.2-5.0.0.43/opencl-1.2-sdk-5.0.0.43/include -L/opt/intel/intel-opencl-1.2-5.0.0.43/opencl-1.2-5.0.0.43/lib64 -lOpenCL -Wall -lm 

[email protected]:~/programs/OpenCL$ ./cldemo 

OS name: Linux 
Release:3.13.0-52-generic 
Version:#86-Ubuntu SMP Mon May 4 04:32:59 UTC 2015 
Machine:x86_64 

Platform name = Intel(R) OpenCL 
Platform version = OpenCL 1.2 LINUX 
Platform extensions = cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_depth_images cl_khr_3d_image_writes cl_intel_exec_by_local_thread cl_khr_spir cl_khr_fp64 

Device name =  Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz 
Device version = OpenCL 1.2 (Build 43) 
Device global memory size= 1040740352 
Device extensions= cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_depth_images cl_khr_3d_image_writes cl_intel_exec_by_local_thread cl_khr_spir cl_khr_fp64 

a: 0 b: 1 c=a+b: 1 
a: 1 b: 2 c=a+b: 3 
a: 2 b: 3 c=a+b: 5 
a: 3 b: 4 c=a+b: 7 
a: 4 b: 5 c=a+b: 9 
a: 5 b: 6 c=a+b: 11 
a: 6 b: 7 c=a+b: 13 
a: 7 b: 8 c=a+b: 15 
a: 8 b: 9 c=a+b: 17 
a: 9 b: 10 c=a+b: 19 

но не на подобной системы у себя дома (но с Ubuntu 14.04 работает как машина Vagrant VirtualBox внутри хоста Windows 7):

OS name: Linux 
Release:3.13.0-53-generic 
Version:#89-Ubuntu SMP Wed May 20 10:34:39 UTC 2015 
Machine:x86_64 

Platform name = Intel(R) OpenCL 
Platform version = OpenCL 1.2 LINUX 
Platform extensions = cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_depth_images cl_khr_3d_image_writes cl_intel_exec_by_local_thread cl_khr_spir 

Device name =  Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz 
Device version = OpenCL 1.2 (Build 43) 
Device global memory size= 3156189184 
Device extensions= cl_khr_icd cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_depth_images cl_khr_3d_image_writes cl_intel_exec_by_local_thread cl_khr_spir 

a: 0 b: 1 c=a+b: 0 
a: 1 b: 2 c=a+b: 0 
a: 2 b: 3 c=a+b: 0 
a: 3 b: 4 c=a+b: 0 
a: 4 b: 5 c=a+b: 0 
a: 5 b: 6 c=a+b: 0 
a: 6 b: 7 c=a+b: 0 
a: 7 b: 8 c=a+b: 0 
a: 8 b: 9 c=a+b: 0 
a: 9 b: 10 c=a+b: 0 

Я новичок в OpenCL. Любые полезные указатели будут очень благодарны!

+1

Попробуйте вызвать 'clGetDeviceInfo' с запросом' CL_DEVICE_AVAILABLE'. Кажется, я помню, что у меня были проблемы с реализацией Intel OpenCL на виртуальной машине. – jprice

+0

Спасибо! Это указывало мне в правильном направлении. Я отправлю свое решение ниже, если это поможет. – crackjack

+0

[VitualBox 5.0 beta3 теперь поддерживает SSE4.1, SSE4.2 и AVX] (https://stackoverflow.com/questions/24543874/does-ubuntu-14-04-support-avx-extension/30299294#30299294). Поэтому, если вы используете VB 5.0 beta3, то Intel OpenCL должен работать. –

ответ

2

Как уже здесь говорилось, от Intel OpenCL SDK не работает из коробки на VirtualBox. По-видимому, SDK требует, чтобы ЦП поддерживали SIMD-расширения SSE4_1 и SSE4_2, но для них отключены настройки по умолчанию для VirtualBox (можно проверить: cat /proc/cpuinfo)

Итак, откройте консоль хоста (Windows, в моем случае), идите в директорию установки VirtualBox и введите:

VBoxManage setextradata "your-VM-name" VBoxInternal/CPUM/SSE4.1 1 
VBoxManage setextradata "your-VM-name" VBoxInternal/CPUM/SSE4.2 1 

Теперь перезапустите виртуальную машину, и OpenCL должны работать (по крайней мере, это было для меня).

+0

Я не знал, что такие варианты существуют, я включил SSE4.1/2 для моей виртуальной машины, и я вижу, что они есть. Я не собираюсь проверять, работает ли Intel OpenCL, не хочу связываться с ним, поскольку у меня уже установлен один AMD :) Спасибо! – doqtor

+0

Добро пожаловать. Теперь я уже сталкиваюсь с другой проблемой - я вижу расширение cl_khr_fp64 (необходимое для двойной точности) на Ubuntu + Intel Amazon и вижу его онлайн для других с тем же процессором Intel, что и у меня, но я не вижу его в своей домашней системе выше. Вздох! В конце концов, я могу пойти с AMD. – crackjack

+1

Это интересно! Я удивлен этим. Почему они будут отключены по умолчанию? В любом случае [VB 5.0 beta3 теперь поддерживает их, а также AVX и AVX2 по умолчанию] (https://stackoverflow.com/questions/24543874/does-ubuntu-14-04-support-avx-extension/30299294#30299294). –

1

Я не смог выполнить работу с Intel OpenCL с использованием Intel SDK/драйверов на Ubuntu 14.04 под VirtualBox. Вы можете установить AMD APP SDK, если это не имеет никакого значения для вас (это не должно быть), он отлично работает на процессоре Intel.

Ссылка: AMD APP SDK

+0

Вы были правы - у Intel OpenCL SDK есть некоторые проблемы с VirtualBox. Я вложу свое решение, если оно поможет кому угодно. – crackjack

Смежные вопросы