在openCL中创建子缓冲区

在openCL中创建子缓冲区,opencl,Opencl,我正在尝试运行OpenCL中的第一个代码。为了创建子缓冲区,我从“OpenCL in Action”一书中获得了以下代码。代码告诉我创建子缓冲区失败时出错。我的电脑有Intel CPU和NVIDIA GPU。然而,当我在另一台装有AMD CPU和GPU的计算机上运行代码时,它工作正常。你知道为什么这段代码在非AMD平台上不起作用吗? 以下是错误: 这是代码: #include <stdio.h> #include <stdlib.h> #include <sys/

我正在尝试运行OpenCL中的第一个代码。为了创建子缓冲区,我从“OpenCL in Action”一书中获得了以下代码。代码告诉我创建子缓冲区失败时出错。我的电脑有Intel CPU和NVIDIA GPU。然而,当我在另一台装有AMD CPU和GPU的计算机上运行代码时,它工作正常。你知道为什么这段代码在非AMD平台上不起作用吗? 以下是错误:

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#ifdef MAC
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif

/* Find a GPU or CPU associated with the first available platform */
cl_device_id create_device() {

    cl_platform_id platform;
    cl_device_id dev;
    int err;


    /* Identify a platform */
    err = clGetPlatformIDs(1, &platform, NULL);
    if (err < 0) {
        perror("Couldn't identify a platform");
        exit(1);
    }

    /* Access a device */
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &dev, NULL);
    if (err == CL_DEVICE_NOT_FOUND) {
        err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &dev, NULL);
    }
    if (err < 0) {
        perror("Couldn't access any devices");
        exit(1);
    }

    return dev;
}

int main() {

    /* Host/device data structures */
    cl_device_id device;
    cl_context context;
    cl_int err;

    /* Data and buffers */
    float main_data[100] = {};
    cl_mem main_buffer, sub_buffer;
    void *main_buffer_mem = NULL, *sub_buffer_mem = NULL;
    size_t main_buffer_size, sub_buffer_size;
    cl_buffer_region region;

    /* Create device and context */
    device = create_device();
    context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
    if (err < 0) {
        perror("Couldn't create a context");
        exit(1);
    }

    /* Create a buffer to hold 100 floating-point values */
    main_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY |
        CL_MEM_COPY_HOST_PTR, sizeof(main_data), main_data, &err);
    if (err < 0) {
        perror("Couldn't create a buffer");
        exit(1);
    }

    /* Create a sub-buffer */
    /* Modified on 2/12/2014 to account for unaligned memory error */
    region.origin = 0 * sizeof(float);
    region.size = 20 * sizeof(float);
    sub_buffer = clCreateSubBuffer(main_buffer, CL_MEM_READ_ONLY |
        CL_MEM_COPY_HOST_PTR, CL_BUFFER_CREATE_TYPE_REGION, &region, &err);
    if (err < 0) {
        perror("Couldn't create a sub-buffer.");
        exit(1);
    }

    /* Obtain size information about the buffers */
    clGetMemObjectInfo(main_buffer, CL_MEM_SIZE,
        sizeof(main_buffer_size), &main_buffer_size, NULL);
    clGetMemObjectInfo(sub_buffer, CL_MEM_SIZE,
        sizeof(sub_buffer_size), &sub_buffer_size, NULL);
    printf("Main buffer size: %lu\n", main_buffer_size);
    printf("Sub-buffer size:  %lu\n", sub_buffer_size);

    /* Obtain the host pointers */
    clGetMemObjectInfo(main_buffer, CL_MEM_HOST_PTR, sizeof(main_buffer_mem),
        &main_buffer_mem, NULL);
    clGetMemObjectInfo(sub_buffer, CL_MEM_HOST_PTR, sizeof(sub_buffer_mem),
        &sub_buffer_mem, NULL);
    printf("Main buffer memory address: %p\n", main_buffer_mem);
    printf("Sub-buffer memory address:  %p\n", sub_buffer_mem);

    /* Print the address of the main data */
    printf("Main array address: %p\n", main_data);

    /* Deallocate resources */
    clReleaseMemObject(main_buffer);
    clReleaseMemObject(sub_buffer);
    clReleaseContext(context);

    return 0;
}
#包括
#包括
#包括
#ifdef MAC
#包括
#否则
#包括
#恩迪夫
/*查找与第一个可用平台关联的GPU或CPU*/
cl_设备\u id创建\u设备(){
cl_平台\u id平台;
cl_设备id开发;
INTERR;
/*识别平台*/
err=clGetPlatformIDs(1,&platform,NULL);
如果(误差<0){
perror(“无法识别平台”);
出口(1);
}
/*访问设备*/
err=CLGetDeviceID(平台,CL\U设备类型\U GPU,1,&dev,NULL);
如果(err==CL\u未找到设备){
err=clgetDeviceID(平台,CL\u设备类型\u CPU,1,&dev,NULL);
}
如果(误差<0){
perror(“无法访问任何设备”);
出口(1);
}
返回dev;
}
int main(){
/*主机/设备数据结构*/
cl_设备\u id设备;
语境;
cl_int err;
/*数据和缓冲区*/
浮点主_数据[100]={};
cl_mem主缓冲区、子缓冲区;
void*main\u buffer\u mem=NULL,*sub\u buffer\u mem=NULL;
大小\u t主缓冲区大小、子缓冲区大小;
cl_缓冲区区域;
/*创建设备和上下文*/
设备=创建设备();
context=clCreateContext(NULL,1,&device,NULL,NULL,&err);
如果(误差<0){
perror(“无法创建上下文”);
出口(1);
}
/*创建一个缓冲区来保存100个浮点值*/
main\u buffer=clCreateBuffer(上下文,CL\u MEM\u只读|
CL_MEM_COPY_HOST_PTR、sizeof(主数据)、主数据和错误);
如果(误差<0){
perror(“无法创建缓冲区”);
出口(1);
}
/*创建一个子缓冲区*/
/*2014年2月12日修改,以说明未对齐的内存错误*/
region.origin=0*sizeof(浮动);
region.size=20*sizeof(浮动);
sub_buffer=clCreateSubBuffer(主_buffer,CL_MEM_READ_ONLY|
CL_MEM_COPY_HOST_PTR,CL_BUFFER_CREATE_TYPE_REGION,®ION,&err);
如果(误差<0){
perror(“无法创建子缓冲区”);
出口(1);
}
/*获取有关缓冲区的大小信息*/
CLGetMemoObjectInfo(主缓冲区、CL内存大小、,
sizeof(主缓冲区大小)和主缓冲区大小,NULL;
CLGetMemoObjectInfo(子缓冲区、CL内存大小、,
sizeof(sub_buffer_size)和sub_buffer_size,NULL);
printf(“主缓冲区大小:%lu\n”,主缓冲区大小);
printf(“子缓冲区大小:%lu\n”,子缓冲区大小);
/*获取主机指针*/
CLGetMemoObjectInfo(主缓冲区、主内存、主机内存、大小),
&主缓冲区内存,空);
CLGetMemoObjectInfo(子缓冲区、子内存、主机PTR、子缓冲区内存大小),
&子缓冲区内存,空);
printf(“主缓冲区内存地址:%p\n”,主缓冲区内存);
printf(“子缓冲区内存地址:%p\n”,子缓冲区内存);
/*打印主数据的地址*/
printf(“主数组地址:%p\n”,主数据);
/*释放资源*/
CLRELEASEMOBJECT(主缓冲区);
CLRELEASEMOBJECT(子缓冲区);
clReleaseContext(上下文);
返回0;
}

由于在创建
main\u buffer
时已为缓冲区分配了内存,因此在获取子缓冲区时无需再次分配内存。您应该只使用
CL\u MEM\u READ\u
作为
CL\u MEM\u标志

sub_buffer = clCreateSubBuffer(main_buffer, CL_MEM_READ_ONLY,
                               CL_BUFFER_CREATE_TYPE_REGION, &region, &err);