OpenCL的映射内存不起作用 [英] opencl mapped memory doesn't work

查看:300
本文介绍了OpenCL的映射内存不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现我的OpenCL程序存储器映射的工艺,但它不工作!在这里,这是我的内核code:

I try to implement memory mapped technics in my OpenCL program, but it's doesn't work! Here it's my kernel code:

__kernel void update(__global char *in, __global char *out)
{
    size_t i;
    for (i = 0; i < 10; i++);
        out[i] += 'A' - 'a';
}

这的主机code:

Here it's host code:

cl_platform_id platformId = NULL;
cl_device_id deviceId = NULL;

cl_context context = NULL;
cl_command_queue commandQueue = NULL;

cl_mem cmPinnedBufIn = NULL;
cl_mem cmPinnedBufOut = NULL;
cl_mem cmDevBufIn = NULL;
cl_mem cmDevBufOut = NULL;
unsigned char *cDataIn = NULL;
unsigned char *cDataOut = NULL;

cl_program program = NULL;
cl_kernel kernel = NULL;
cl_uint retNumDevices;
cl_uint retNumPlatforms;
cl_int ret;

cl_event event;
cl_ulong start;
cl_ulong end;

size_t group_size = GLOBAL_ITEM_SIZE / LOCAL_ITEM_SIZE;

FILE *fp;
const char fileName[] = "./update.cl";
size_t sourceSize;
char *sourceStr;

unsigned char tt[10];

/* Load kernel source file */
if ( !(fp = fopen(fileName, "r")) )
    quitErr("Failed to load kernel.", EXIT_FAILURE);

sourceStr = (char *)malloc(MAX_SOURCE_SIZE);
sourceSize = fread(sourceStr, 1, MAX_SOURCE_SIZE, fp);
fclose(fp);

/* Get Platform/Device Information */
ret = clGetPlatformIDs(1, &platformId, &retNumPlatforms);
assert(ret == CL_SUCCESS);
ret = clGetDeviceIDs(platformId, CL_DEVICE_TYPE_GPU, 1, &deviceId, &retNumDevices);
assert(ret == CL_SUCCESS);

/* Create OpenCL Context */
context = clCreateContext( NULL, retNumDevices, &deviceId, NULL, NULL, &ret);

/* Create command queue with measurment of preformance */
commandQueue = clCreateCommandQueue(context, deviceId, CL_QUEUE_PROFILING_ENABLE, &ret);

/* Create buffer objects */
size_t memSize = 10 * sizeof(unsigned char);
cmPinnedBufIn = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, memSize, NULL, &ret);
assert(ret == CL_SUCCESS);
cmPinnedBufOut = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, memSize, NULL, &ret);
assert(ret == CL_SUCCESS);

/* Mapp pinned memmory */
cDataIn = (unsigned char *)clEnqueueMapBuffer(commandQueue, cmPinnedBufIn, CL_TRUE, CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, &ret);
assert(ret == CL_SUCCESS);

/* Initialize data */
for (size_t w = 0; w < memSize; w++)
    cDataIn[w] = 'a' + w;

/* Create kernel program from source file */
program = clCreateProgramWithSource(context, 1, (const char **)&sourceStr, (const size_t *)&sourceSize, &ret);
assert(ret == CL_SUCCESS);
ret = clBuildProgram(program, 1, &deviceId, NULL, NULL, NULL);
if (ret != CL_SUCCESS) {  
    error("\nFail to build the program\n");
    char buffer[10240];
    clGetProgramBuildInfo(program, deviceId, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, NULL);
    quitErr(buffer, EXIT_FAILURE);
}

/* Create data parallel OpenCL kernel */
kernel = clCreateKernel(program, "update", &ret);
assert(ret == CL_SUCCESS);

/* Set OpenCL kernel arguments */
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&cmPinnedBufIn);
assert(ret == CL_SUCCESS);

ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&cmPinnedBufOut);
assert(ret == CL_SUCCESS);

size_t global_item_size = GLOBAL_ITEM_SIZE;
size_t local_item_size = LOCAL_ITEM_SIZE;

/* Execute OpenCL kernel as data parallel */
ret = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, &event);
if (ret == CL_INVALID_WORK_GROUP_SIZE)
    quitErr("Invalid work group size: error when compute group size.", EXIT_FAILURE);
assert(ret == CL_SUCCESS);

/* Execute measurment issue */
if (preformanceMeas) {
    clWaitForEvents(1, &event);
    clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &start, NULL);
    clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &end, NULL);
    printf("Kernels execution time: %10.6f [ms]\n", (end - start) * 1.0e-6f);
}

cDataOut = (unsigned char *)clEnqueueMapBuffer(commandQueue, cmPinnedBufOut, CL_TRUE, CL_MAP_READ, 0, memSize, 0, NULL, NULL, &ret);
assert(ret == CL_SUCCESS);

/* Transfer result to host */
memcpy(tt, cDataOut, memSize);

/* Transfer measurment issue */
if (preformanceMeas) {
    //clWaitForEvents(1, &event);
    clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &start, NULL);
    clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &end, NULL);
    printf("Memory x buffer read: %10.6f [ms]\n", (end - start) * 1.0e-6f);
}

/* Display Results */
int i;
for (i = 0; i < group_size; i++)
    for (size_t x = 0; x < memSize; x++)
        printf("%c", tt[x]);
printf("\n"); 

/* Finalization */
clFlush(commandQueue);
clFinish(commandQueue);
clReleaseKernel(kernel);
clReleaseProgram(program);
clReleaseMemObject(cmPinnedBufIn);
clReleaseMemObject(cmPinnedBufOut);
clReleaseMemObject(cmDevBufIn);
clReleaseMemObject(cmDevBufOut);
clReleaseCommandQueue(commandQueue);
clReleaseContext(context);

free(sourceStr);

return EXIT_SUCCESS;

内核改变小写字母为大写,但我的输出是空的。当我静态分配的人物在这样的内核:

The kernel change the lower case characters to uppercase, but my output is empty. When I statically assign the characters in the kernel like this:

__kernel void update(__global char *in, __global char *out)
{
    size_t i;
    for (i = 0; i < 10; i++)
        out[i] = 'A' + i;
}

比结果是OK。因此,与我从输入数据得出不正确调入内存,但是为什么呢?谁能帮我吗?

than the result is OK. So with that I conclude from the input data are not transferred correctly to the memory, but why? Can anyone help me please?

推荐答案

您必须在您的映射的缓冲区写入输入之后调用 clEnqueueUnmapMemObject 。见的OpenCL 1.1规范,5.4.2.1。

You must call clEnqueueUnmapMemObject after you write input in the mapped buffer. See The OpenCL 1.1 spec, 5.4.2.1.

您的内核不能访问,并且不依赖于螺纹指数 get_global_id(0)。你可能想是这样的:

Your kernels do not access in, and do not depend on the thread index get_global_id(0). You are probably wanting something like:

size_t i = get_global_id(0)
char c = in[i];
out[i] = (c>='a' && c<='z')?(c + 'A' - 'a'):c;

要在针对OpenCL 1.0写字符数组,你需要启用 byte_addressable_store extension.r

To write char arrays in OpenCL 1.0, you need to enable the byte_addressable_store extension.r

这篇关于OpenCL的映射内存不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆