Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCL内核不会将字符数据返回到主机程序_C_Pointers_Kernel_Opencl - Fatal编程技术网

OpenCL内核不会将字符数据返回到主机程序

OpenCL内核不会将字符数据返回到主机程序,c,pointers,kernel,opencl,C,Pointers,Kernel,Opencl,我是OpenCL的新手,从中学习。我研究了一个向量矩阵乘法的例子(第11-13页)。由于某种原因,该示例在我的计算机上不起作用。内核没有返回这些值。我开始寻找从内核输出数据的简单示例 我在Wesley Shillingford的youtube频道中发现了一个从内核输出字符串“Hello world!”的方法。在我的家用电脑上,这个例子奏效了。然而,OpenCL“厨房”一直保持关闭,因为示例是用C++编写的。代码的简洁掩盖了正在发生的事情的概念。所以我开始进一步寻找C代码中的示例 在Stackov

我是OpenCL的新手,从中学习。我研究了一个向量矩阵乘法的例子(第11-13页)。由于某种原因,该示例在我的计算机上不起作用。内核没有返回这些值。我开始寻找从内核输出数据的简单示例

我在Wesley Shillingford的youtube频道中发现了一个从内核输出字符串“Hello world!”的方法。在我的家用电脑上,这个例子奏效了。然而,OpenCL“厨房”一直保持关闭,因为示例是用C++编写的。代码的简洁掩盖了正在发生的事情的概念。所以我开始进一步寻找C代码中的示例

在Stackoverflow的答案中,我发现了一个在内核中增加值的方法。我把这段代码作为编写程序的基础,因为它对初学者来说既简单又方便。正如我后来发现的,该示例包含一个错误

另一个例子说服我使用指针从内核返回数据。使用数组存储内核的输出值会导致目标数组的值不会更改,并且在输出过程中来自内核的数据会消失。 我意识到我们需要使用指针从内核输出数据。然而,这对我没有帮助。将数据从内核传输到主机程序的问题仍然存在。如果我有什么地方弄错了,请纠正我。本主题的实质是:内核不会将字符数据返回到宿主程序。可能是什么问题?

#include <CL/cl.h>
#include <stdio.h>  
#include <stdlib.h>

int main(){

    cl_platform_id *platforms =NULL;
    cl_device_id *devices=NULL;
    cl_context context;
    cl_command_queue cmdQueue;
    cl_program program;
    cl_kernel kernel = NULL;
    char *cpOutputData;
    int output_size = 8;
    cl_mem output_buff;
    cl_int status;      // to check the output of each API call

    const char *source =
        "__kernel void Hello( __global char* ch) {\n"
        "   ch[0]='P';"
        "   ch[1]='r';"
        "   ch[2]='i';"
        "   ch[3]='v';"
        "   ch[4]='e';"
        "   ch[5]='t';"
        "   ch[6]='!';"
        "   ch[7]='\0';"
        "}\0";

    printf("GetPlatformIDs... ");
    cl_uint numPlatforms = 0;
    //STEP 1: Discover and initialize platforms
    // Use clGetPlatformIDs to retreive the number of platforms
    status = clGetPlatformIDs(0, 
                              NULL, 
                              &numPlatforms);
    // Allocate enough space for each platform
    platforms = (cl_platform_id*)malloc(numPlatforms*sizeof(cl_platform_id));
    // Fill in platforms with clGetPlatformIDs()
    status=clGetPlatformIDs(numPlatforms, 
                            platforms, 
                            NULL);
    printf("\nNumber of discovered platforms is %d. ", numPlatforms);

    // STEP 2: Discover and initialize devices
    printf("OK.\nGetDeviceIDs... ");
    cl_uint numDevices = 0;
    // Use clGetDeviceIDs() to retrieve the number of devices present
    status = clGetDeviceIDs(platforms[0], 
                            CL_DEVICE_TYPE_CPU, 
                            0, 
                            NULL, 
                            &numDevices);
    // Allocate enough space for each device
    devices = (cl_device_id*)malloc(numDevices*sizeof(cl_device_id));
    // Fill in devices with clGetDeviceIDs()
    clGetDeviceIDs(platforms[0], 
                   CL_DEVICE_TYPE_CPU, 
                   numDevices, 
                   devices, 
                   NULL);
    printf("\nNumber of discovered devices is %d. ", numDevices);

    // STEP 3: Create a context
    printf("OK.\nCreating context... ");
    // Create context using clCreateContext() and associate it with the devices
    context = clCreateContext(NULL, 
                              numDevices, 
                              devices, 
                              NULL, 
                              NULL, 
                              &status);

    // STEP 4: Create a command queue
    printf("OK.\nQueue creating... ");
    cmdQueue = clCreateCommandQueue(context, 
                                    devices[0], 
                                    CL_QUEUE_PROFILING_ENABLE, 
                                    &status);

    // STEP 5: Create device buffers
    printf("OK.\nOutput buffer creating... ");
    output_buff = clCreateBuffer(context, 
                                 CL_MEM_WRITE_ONLY, 
                                 sizeof(char)*output_size, 
                                 NULL, 
                                 &status);

    // STEP 6: Create and compile program
    printf("OK.\nBuilding program... ");
    // Create a program using clCreateProgramWithSource()
    program = clCreateProgramWithSource(context, 
                                        1, 
                                        (const char**)&source, 
                                        NULL, 
                                        &status);
    // Build (compile) the program for the devices with clBuildProgram()
    status=clBuildProgram(program, 
                          numDevices, 
                          devices, 
                          NULL, 
                          NULL, 
                          NULL);

    // STEP 7: Create a kernel
    printf("OK.\nCreating kernel... ");
    kernel = clCreateKernel(program, 
                            "Hello", 
                            &status);

    // STEP 8: Set kernel arguments
    // Associate ouput buffer with the kernel
    printf("OK.\nSetting kernel arguments... ");
    status = clSetKernelArg(kernel, 
                            0, 
                            sizeof(cl_mem), 
                            &output_buff);

    // STEP 9: Configure the work-item structure
    // Define an index space (global work size) of work itmes for execution. 
    // A workgroup size (local work size) is not required, but can be used.
    size_t globalWorkSize[1];
    // There are 'elements' work-items
    globalWorkSize[0] = output_size;

    // STEP 10: Enqueue the kernel for execution
    printf("OK.\nExecuting kernel... ");
    //Execute the kernel by using clEnqueueNDRangeKernel().
    // 'globalWorkSize' is the 1D dimension of the work-items
    clEnqueueNDRangeKernel(cmdQueue, 
                           kernel, 
                           1, 
                           NULL, 
                           globalWorkSize, 
                           NULL, 
                           0, 
                           NULL, 
                           NULL);

    clFinish(cmdQueue);

    // STEP 11: Read the ouput buffer back to the host
    printf("OK.\nReading buffer... ");
    // Allocate space for the data to be read
    cpOutputData = (char*)malloc(output_size*sizeof(char));
    // Use clEnqueueReadBuffer() to read the OpenCL ouput buffer to the host ouput array
    clEnqueueReadBuffer(cmdQueue, 
                        output_buff, 
                        CL_TRUE, 
                        0, 
                        output_size, 
                        cpOutputData, 
                        0, 
                        NULL, 
                        NULL);

    printf("\nPrinting output data: \n");
    printf(cpOutputData);

    // STEP 12: Releasing resources
    printf("\n...Releasing OpenCL resources... ");
    clReleaseKernel(kernel);
    clReleaseProgram(program);
    clReleaseCommandQueue(cmdQueue);
    clReleaseMemObject(output_buff);
    clReleaseContext(context);

    printf("OK.\n...Releasing host resources... ");
    free(cpOutputData);
    free(platforms);
    free(devices);

    printf("OK.\nEnd of program. Bey!\n");
    system("PAUSE");
    return 0;
}

#包括
#包括
#包括
int main(){
cl_platform_id*platforms=NULL;
cl_设备_id*设备=NULL;
语境;
cl_命令_队列cmdQueue;
CLU计划;
cl_内核=NULL;
char*cpOutputData;
int输出_size=8;
cl_mem输出_buff;
cl_int status;//检查每个API调用的输出
常量字符*源=
“uuu内核void Hello(uuu全局字符*ch){\n”
“ch[0]='P';”
“ch[1]='r';”
“ch[2]='i'
“ch[3]='v';”
“ch[4]='e'
“ch[5]='t'
“ch[6]='!';”
“ch[7]='\0'
"}\0";
printf(“GetPlatformIDs…”);
cl_uint numPlatforms=0;
//步骤1:发现和初始化平台
//使用clGetPlatformIDs检索平台的数量
状态=clGetPlatformIDs(0,
无效的
&模板);
//为每个平台分配足够的空间
平台=(cl_平台id*)malloc(numPlatforms*sizeof(cl_平台id));
//使用clGetPlatformIDs()填充平台
状态=clGetPlatformIDs(numPlatforms,
平台,
无效);
printf(“\n发现的平台数量为%d.”,numPlatforms);
//步骤2:发现和初始化设备
printf(“确定。\n设备…”);
cl_uint numDevices=0;
//使用CLGetDeviceID()检索存在的设备数
状态=CLGetDeviceID(平台[0],
CL\U设备类型\U CPU,
0, 
无效的
&数字设备);
//为每个设备分配足够的空间
设备=(cl_设备id*)malloc(numDevices*sizeof(cl_设备id));
//用CLGetDeviceID()填充设备
CLGetDeviceID(平台[0],
CL\U设备类型\U CPU,
numDevices,
装置,
无效);
printf(“\n发现的设备数为%d.”,numDevices);
//步骤3:创建上下文
printf(“确定。\n正在创建上下文…”);
//使用clCreateContext()创建上下文并将其与设备关联
context=clCreateContext(NULL,
numDevices,
装置,
无效的
无效的
&地位);
//步骤4:创建命令队列
printf(“确定。\n取消创建…”);
cmdQueue=clCreateCommandQueue(上下文,
设备[0],
CL_队列_分析_启用,
&地位);
//步骤5:创建设备缓冲区
printf(“确定。\n输出缓冲区创建…”);
输出\u buff=clCreateBuffer(上下文,
CL_MEM_WRITE_仅限,
sizeof(char)*输出大小,
无效的
&地位);
//步骤6:创建并编译程序
printf(“确定。\n生成程序…”);
//使用clCreateProgramWithSource()创建程序
program=clCreateProgramWithSource(上下文,
1.
(常量字符**)和来源,
无效的
&地位);
//使用clBuildProgram()为设备生成(编译)程序
状态=clBuildProgram(程序,
numDevices,
装置,
无效的
无效的
无效);
//步骤7:创建内核
printf(“确定。\n正在创建内核…”);
kernel=clCreateKernel(程序,
“你好”,
&地位);
//步骤8:设置内核参数
//将输出缓冲区与内核关联
printf(“确定。\n设置内核参数…”);
status=clSetKernelArg(内核,
0, 
sizeof(cl_mem),
&输出增益);
//步骤9:配置工作项结构
//定义要执行的工作ITME的索引空间(全局工作大小)。
//工作组大小(loca)
__kernel void Hello( __global char* ch) {
   ch[0]='P';
   ch[1]='r';
   ch[2]='i';
   ch[3]='v';
   ch[4]='e';
   ch[5]='t';
   ch[6]='!';
   ch[7]='
    "   ch[7]='\\0';"
//              ^--- note second backslash