OpenCL:在全局内存地址 0x### 处写入大小 # 无效

如何解决OpenCL:在全局内存地址 0x### 处写入大小 # 无效

解决方案后编辑:问题仅在于代码。这里没有硬件问题。现在到原始帖子:

我正在尝试使用基本的 OpenCL 程序。

程序简单地创建一个缓冲区,将 42 写入缓冲区,读取并输出。

这是用 C 编写的代码:

#define MY_PLATFORM 2 // Adjustable
#define MY_DEVICE 0 // Adjustable

#include <stdio.h>

#define CL_TARGET_OPENCL_VERSION 200
#include <CL/cl.h>

// Simple kernel that outputs 42.
const char *myCode = " \
    __kernel void fourtyTwo(__global int *output) { \n \
        int i = get_global_id(0); \n \
        output[i] = 42; \n \
    } \n \
\0";

int main(void) {
    cl_platform_id *myPlatforms = (cl_platform_id*)malloc(sizeof(cl_platform_id));
    cl_uint *myPlatformCount = (cl_uint*)malloc(sizeof(cl_uint));

    cl_device_id *myDevices = (cl_device_id*)malloc(sizeof(cl_device_id));
    cl_uint *myDeviceCount = (cl_uint*)malloc(sizeof(cl_uint));

    int err;

    /* Reference:
        cl_int clGetPlatformIDs(
            cl_uint num_entries,// I want just enough to reach MY_PLATFORM.
            cl_platform_id *platforms,// myPlatforms
            cl_uint *num_platforms     // myPlatformCount
        )
    */
    err = clGetPlatformIDs(MY_PLATFORM + 1,myPlatforms,myPlatformCount);
    if(err != 0) fprintf(stderr,"\nCould not query platforms.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_int clGetDeviceIDs(
            cl_platform_id num_entries,// I want the MY_PLATFORM'th entry of myPlatforms.
            cl_device_type device_type,// Any device will do.
            cl_uint num_entries,// I want just enough to reach MY_DEVICE.
            cl_device_id *devices,// myDevices
            cl_uint *num_devices        // myDeviceCount
        )
    */
    err = clGetDeviceIDs(myPlatforms[MY_PLATFORM],CL_DEVICE_TYPE_ALL,MY_DEVICE + 1,myDevices,myDeviceCount);
    if(err != 0) fprintf(stderr,"\nCould not query devices.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_context clCreateContext(
            cl_context_properties *properties,// The default properties should suffice.
            cl_uint num_devices,// I want just enough to reach MY_DEVICE.
            const cl_device_id *devices,// myDevices
            void *pfn_notify,// No need for this.
            void *user_data,// No need for this.
            cl_int *errcode_ret                // err
        )
    */
    cl_context myContext = clCreateContext(NULL,NULL,&err);
    if(err != 0) fprintf(stderr,"\nCould not open context.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_command_queue clCreateCommandQueueWithProperties(
            cl_context context,// myContext
            cl_device_id device,// I want the MY_DEVICE'th device of myDevices.
            const cl_queue_properties properties,// The default properties should suffice.
            cl_int *errcode_ret                   // err
        )
    */
    cl_command_queue myCommandQueue = clCreateCommandQueueWithProperties(myContext,myDevices[MY_DEVICE],"\nCould not open command queue.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_program clCreateProgramWithSource(
            cl_context context,// myContext
            cl_uint count,// There's only 1 source code.
            const char **strings,// myCode,passed as a length-1 array.
            const size_t *lengths,// Passing NULL indicates that all the strings are null-terminated.
            cl_int *errcode_ret    // err
        )
    */
    cl_program myProgram = clCreateProgramWithSource(myContext,1,(const char**)&myCode,"\nCould not create program.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_int clBuildProgram(
            cl_program program,// myProgram
            const cl_device_id *device_list,// myDevices
            const char *options,// This can be NULL,right? The docs didn't specify.
            void *pfn_notify,// No need for this.
            void *user_data                  // No need for this.
        )
    */
    err = clBuildProgram(myProgram,NULL);
    if(err != 0) {
        fprintf(stderr,"\nCould not build program.\nOpenCL failed with exit code %d\n\n",err);
        char *errLog;
        size_t errLen;
        clGetProgramBuildInfo(myProgram,CL_PROGRAM_BUILD_LOG,&errLen);
        errLog = (char*)malloc((errLen + 1) * sizeof(char));
        clGetProgramBuildInfo(myProgram,errLen,errLog,NULL);
        errLog[errLen] = 0;
        fprintf(stderr,"\nFull Build Log:\n%s\n\n",errLog);
    }

    /* Reference:
        cl_kernel clCreateKernel(
            cl_program program,// myProgram
            const char *kernel_name,// "fourtyTwo" (See above,definition of myCode)
            cl_int *errcode_ret      // err
        )
    */
    cl_kernel myKernel = clCreateKernel(myProgram,"fourtyTwo","\nCould not create kernel.\nOpenCL failed with exit code %d\n\n",err);

    size_t *globalSize = (size_t*)malloc(sizeof(size_t));
    *globalSize = 1; // There is only 1 item.
    size_t *localSize = (size_t*)malloc(sizeof(size_t));
    *localSize = 1; // There can only be 1 out of 1 item.

    int *outputArr = (int*)malloc(1 * sizeof(int));

    /* Reference:
        cl_mem clCreateBuffer(
            cl_context context,// myContext
            cl_mem_flags flags,// I'm only writing to the output array.
            size_t size,// Its only 1 integer.
            void *host_ptr,// I haven't allocated this space yet.
            cl_int *errcode_ret // err
        )
    */
    cl_mem outputBuffer = clCreateBuffer(myContext,CL_MEM_WRITE_ONLY,1 * sizeof(int),"\nCould not create buffer.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_int clSetKernelArg(
            cl_kernel kernel,// myKernel
            cl_uint arg_index,// Setting the 1st argument.
            size_t arg_size,// Passing 1 cl_mem object.
            const void *arg_value // The argument shall be the output buffer for the kernel to write to.
        )
    */
    err = clSetKernelArg(myKernel,sizeof(cl_mem),(void*)outputBuffer);
    if(err != 0) fprintf(stderr,"\nCould not set kernel argument.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_int clEnqueueNDRangeKernel(
            cl_command_queue command_queue,// myCommandQueue
            cl_kernel kernel,// myKernel
            cl_uint work_dim,// 1 dimensional.
            const size_t *global_work_offset,// Don't offset anything.
            const size_t *global_work_size,// globalSize
            const size_t *local_work_size,// localSize
            cl_uint num_events_in_wait_list,// I don't have a wait list (whatever that is).
            const cl_event *event_wait_list,// I don't have a wait list (whatever that is).
            cl_event *event                   // Don't create an event (whatever this means).
        )
    */
    err = clEnqueueNDRangeKernel(myCommandQueue,myKernel,globalSize,localSize,NULL);
    if(err != 0) fprintf(stderr,"\nCould not run kernel.\nOpenCL failed with exit code %d\n\n",err);

    /* Reference:
        cl_int clEnqueueReadBuffer(
            cl_command_queue command_queue,// myCommandQueue
            cl_mem buffer,// outputBuffer
            cl_bool blocking_read,// I'm doing everything synchronously.
            size_t offset,// Don't offset anything.
            size_t cb,// Reading in 1 integer.
            void *ptr,// Putting the data into outputArr.
            cl_uint num_events_in_wait_list,// I don't have a wait list (whatever that is).
            cl_event *event                  // Don't create an event (whatever this means).
        )
    */
    clEnqueueReadBuffer(myCommandQueue,outputBuffer,CL_TRUE,1 * sizeof(cl_int),outputArr,"\nCould not read from buffer.\nOpenCL failed with exit code %d\n\n",err);

    // Print the result
    printf("%d\n",outputArr[0]);
    return 0;
}

该程序不起作用。它保持缓冲区不变,并通过 ocgrind 抛出错误。

输出如下:

gcc main.c -o main -lOpenCL
./main

Invalid write of size 4 at global memory address 0x560d0b2cefc0
        Kernel: fourtyTwo
        Entity: Global(0,0) Local(0,0) Group(0,0)
          store i32 42,i32 addrspace(1)* %arrayidx,align 4,!dbg !23,!tbaa !24
        At line 3 (column 15) of input.cl:
          output[i] = 42;

0

Press ENTER or type command to continue

如果这是系统问题,hereclinfo 的输出。

我使用的是配备 Radeon Graphics (16) @ 1.7000Ghz 的 AMD Ryzen 7 PRO 4750U。

我正在运行 Arch Linux。

有没有人知道问题可能是什么?谢谢!

P.S. 任何对我的代码或我的问题措辞的批评,无论是否文明,我都欢迎!

解决方法

我是个小丑。错误就在我去设置内核参数的行上:

    err = clSetKernelArg(myKernel,sizeof(cl_mem),(void*)outputBuffer);

我在应该写 (void*)outputBuffer 的时候输入了 (void*)&outputBuffer。由于这个错误,内核试图写入某个任意位置而不是缓冲区内存中的实际位置。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res