Opencl入门Demo

2023-11-14

最近负责的几个项目需要使用opencl进行编程,进行了学习,并将学习后编写的主要Demo代码记录下来,供大家初步入门使用。

opencl的介绍,原理等这里就不说了,百度一下有很多,直接切入主题。

这个demo实现两个数组的相加操作。

1.进行平台的初始化相关操作

int initPlatform(TPlatformObject* tplatformObj)
{
    cl_int err= CL_SUCCESS;
    cl_uint num_platforms;
    char platformInfo[100];
    char deviceInfo[100];
    size_t nameLen;


    printInfo("InitPlatform\n");
    /*获取opencl执行的平台*/
    err=clGetPlatformIDs(0,NULL,&num_platforms);
    if(err != CL_SUCCESS){
        printErr("initPlatform_clGetPlatformIDS0 failed!err:%d",err);
        return err;
    }
    err=clGetPlatformIDs(1,&tplatformObj->platform,NULL);
    if(err != CL_SUCCESS){
        printErr("initPlatform_clGetPlatformIDS1 failed!err:%d",err);
        return err;
    }

    err=clGetPlatformInfo(tplatformObj->platform,CL_PLATFORM_VENDOR,100,platformInfo,&nameLen);
    if(err != CL_SUCCESS){
        printErr("initPlatform_clGetPlatforminfo failed!err:%d",err);
        return err;
    }
    printInfo("CL_PLATFORM_VENDOR:%s\n",platformInfo);


    /*获取平台执行设备*/
    err=clGetDeviceIDs(tplatformObj->platform,CL_DEVICE_TYPE_GPU,1,&tplatformObj->device,NULL);
    if(err != CL_SUCCESS){
        printErr("initPlatform_clGetPlatforminfo failed!err:%d",err);
        return err;
    }
    err=clGetDeviceInfo(tplatformObj->device,CL_DEVICE_VERSION,100,deviceInfo,&nameLen);
    printInfo("initPlatform_CL_DRIVER_VERSION:%s\n",deviceInfo);


    /*创建context*/
    tplatformObj->context = clCreateContext(NULL,1,&tplatformObj->device,NULL,NULL,&err);
    if(err != CL_SUCCESS){
        printErr("initPlatform_clCreateContext:%d",err);
        return err;
    }

    /*创建命令队列*/
    tplatformObj->queue = clCreateCommandQueue(tplatformObj->context,tplatformObj->device, 0, &err);
    if(err != CL_SUCCESS){
        printErr("initPlatform_clCreateCommandQueue:%d",err);
        return err;
    }

    return 0;
}

2.加载kernel函数,执行,直接整个文件拷贝过来了

#include "Rotate.h"

/*初始化工程*/
int initProgram(TPlatformObject* tplatformObj)
{
    FILE* fp=NULL;                /*文件指针指向*.cl内核代码文件*/
    char* program_buffer=NULL;    /*用于拷贝*.cl中的内容*/
    size_t program_size;          /**.cl文件大小*/
    cl_int errCode=0;


    fp=fopen("Operation.cl","r");
    if(fp == NULL){
        printErr("initProgram:fp is NULL\n");
        return -1;
    }
    fseek(fp,0,SEEK_END);         /*文件指针指向文件结尾*/
    program_size=ftell(fp);       /*计算出文件开头与fp指针位置之间的数据大小*/
    rewind(fp);                   /*让fp指针重新回到文件头位置*/
    program_buffer=(char*)malloc(program_size+1);   /*分配内存*/
    program_buffer[program_size]='\0';              /*添加结尾标志*/
    fread(program_buffer,sizeof(char),program_size,fp);
    fclose(fp);

    /*创建程序对象*/
    tplatformObj->program=clCreateProgramWithSource(tplatformObj->context,
        1,(const char**) &program_buffer,&program_size,&errCode);
    if(errCode != CL_SUCCESS){
        printErr("initProgram-Couldn't create the program,errcode=%d\n",errCode);
        free(program_buffer);
        program_buffer=NULL;
        return -1;
    }
    free(program_buffer);
    program_buffer=NULL;

    /*构建程序执行体*/
    errCode=clBuildProgram(tplatformObj->program,0,NULL,NULL,NULL,NULL);
    if(errCode != CL_SUCCESS){
        printErr("initProgram_clBuildProgram failed!errcode is :%d\n",errCode);
        return -1;
    }

    return 0;
}

/*获取创建的kernel函数句柄*/
int CreateKernel(TPlatformObject* tplatformObj,TRotObj* tRotObj)
{
    cl_int errCode=0;
    tRotObj->VecAdd=clCreateKernel(tplatformObj->program,"vecadd",&errCode);
    if(errCode != CL_SUCCESS){
        printErr("CreateKernel failed! errCode:%d\n",errCode);
        return -1;
    }
    return 0;
}

/*创建buffer*/
int CreateBuffer(TPlatformObject* tplatformObj,TRotObj* tRotObj)
{
    cl_int errCode=0;
    tRotObj->cl_A=clCreateBuffer(tplatformObj->context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
        1024*sizeof(float),(void*)tRotObj->A,&errCode);
    if(errCode != CL_SUCCESS){
        printErr("clCreateBuffer cl_A failed!!");
    }

    tRotObj->cl_B=clCreateBuffer(tplatformObj->context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
        1024*sizeof(float),(void*)tRotObj->B,&errCode);
    if(errCode != CL_SUCCESS){
        printErr("clCreateBuffer cl_B failed!!");
    }

    tRotObj->cl_C=clCreateBuffer(tplatformObj->context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
        1024*sizeof(float),(void*)tRotObj->C,&errCode);
    if(errCode != CL_SUCCESS){
        printErr("clCreateBuffer cl_B failed!!");
    }

    return 0;
}


/*为kernel函数设置参数*/
int SetKernelArgs(TRotObj* tRotObj)
{
    cl_int errCode=CL_SUCCESS;
    errCode=clSetKernelArg(tRotObj->VecAdd,0,sizeof(cl_mem),&tRotObj->cl_A);
    errCode=clSetKernelArg(tRotObj->VecAdd,1,sizeof(cl_mem),&tRotObj->cl_B);
    errCode=clSetKernelArg(tRotObj->VecAdd,2,sizeof(cl_mem),&tRotObj->cl_C);
    return errCode;
}


int RotateOpen(TPlatformObject* tplatformObj,TRotObj* tRotObj)
{
    int ret=0;
    int i=0;
    ret=initProgram(tplatformObj);
    if(ret != CL_SUCCESS){
        printErr("RotateOpen initProgram failed!!");
    }
    printInfo("initProgram done!!\n");

    /*创建kernel可执行函数*/
    if(CreateKernel(tplatformObj,tRotObj) != CL_SUCCESS){
        printErr("RotateOpen CreateKernel failed!!");
        return -1;
    }

    /*测试用数组*/
    float* A=(float*)malloc(1024*sizeof(float));
    float* B=(float*)malloc(1024*sizeof(float));
    float* C=(float*)malloc(1024*sizeof(float));
    memset(A,1,sizeof(float)*1024);
    memset(B,2,sizeof(float)*1024);
    for(i=0;i<1024;i++){
        A[i]=i;
        B[i]=i;
    }
    memset(C,0,sizeof(float)*1024);
    tRotObj->A=A;
    tRotObj->B=B;
    tRotObj->C=C;
    /*创建buffer*/
    if(CreateBuffer(tplatformObj,tRotObj) != 0){
        printErr("RotateOpen CreateBuffer failed!!");
        return -1;
    }

    /*设置kernel的参数*/
    if(SetKernelArgs(tRotObj)){
        printErr("RotateOpen SetKernelArgs failed!!");
        return -1;
    }

    /*执行kernel函数*/
    cl_uint work_dim=1; /*工作项维数*/
    size_t global_work_size=1024;
    ret=clEnqueueNDRangeKernel(tplatformObj->queue,tRotObj->VecAdd,work_dim,
        NULL,&global_work_size,NULL,0,NULL,NULL);
    if(ret != CL_SUCCESS){
        printErr("RotateOpen clEnqueueNDRangeKernel failed!!");
        return -1;
    }
    clFinish(tplatformObj->queue);/*执行结束*/

    /*读取计算出的结果*/
    ret=clEnqueueReadBuffer(tplatformObj->queue,tRotObj->cl_C,CL_TRUE,0,1024*4,tRotObj->C,0,NULL,NULL);

    /*打印程序结果*/
    for(i=0;i<global_work_size;i++){
        printf("%f ",tRotObj->C[i]);
        if((i+1)%16==0){
            printf("\n");
        }
    }

    /*释放内存*/
    clReleaseCommandQueue(tplatformObj->queue);
    clReleaseContext(tplatformObj->context);
    clReleaseDevice(tplatformObj->device);
    clReleaseKernel(tRotObj->VecAdd);
    clReleaseMemObject(tRotObj->cl_A);
    clReleaseMemObject(tRotObj->cl_B);
    free(tRotObj->A);
    free(tRotObj->B);
    free(tRotObj->C);
    return ret;
}
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Opencl入门Demo 的相关文章

  • Java 中 GPGPU/CUDA/OpenCL 的最佳方法?

    图形处理单元上的通用计算 GPGPU http en wikipedia org wiki GPGPU 是一个非常有吸引力的概念 可以利用 GPU 的强大功能进行任何类型的计算 我喜欢使用 GPGPU 进行图像处理 粒子和快速几何运算 目前
  • 什么样的工作受益于 OpenCL

    首先 我很清楚 OpenCL 并没有神奇地让一切变得更快 我很清楚 OpenCL 有局限性 现在回答我的问题 我习惯使用编程进行不同的科学计算 我处理的一些事情在计算的复杂性和数量方面非常激烈 所以我想知道 也许我可以使用 OpenCL 来
  • OpenCL 中的矩阵求逆

    我正在尝试使用 OpenCL 加速一些计算 算法的一部分包括反转矩阵 是否有任何开源库或免费可用的代码来计算用 OpenCL 或 CUDA 编写的矩阵的 lu 分解 lapack dgetrf 和 dgetri 或一般求逆 该矩阵是实数且为
  • 限制 AMD OpenCL 的 GPU 数量

    是否有解决方案限制 AMD OpenCL 平台使用的 GPU 数量 对于 NVIDIA 平台 只需设置环境变量即可CUDA VISIBLE DEVICES限制 OpenCL 可用的 GPU 集 编辑 我知道 我可以使用更少的设备创建一个上下
  • 使用 GPU PyOpenCL 优化 python 代码的不同方法:内核 GPU/PyOpenCL 内的 extern 函数

    我使用以下命令来分析我的 Python 代码 python2 7 m cProfile o X2 non flat multiprocessing dummy prof X2 non flat py 然后 我可以全局可视化不同贪婪函数的重新
  • OpenGL-OpenCL 互操作传输时间 + 位图纹理

    两部分问题 我正在开展一个学校项目 使用生命游戏作为实验 gpgpu 的工具 我使用 OpenCL 和 OpenGL 进行实时可视化 目标是让这个东西尽可能大 更快 经过分析 我发现帧时间主要由 CL 获取和释放 GL 缓冲区决定 并且时间
  • 并行化 std::nth_element 和 std::partition

    我正在移植使用的 C 代码std nth element and std partition到 OpenCL nth element http www cplusplus com reference algorithm nth elemen
  • OpenCL:头文件的附加目录

    OpenCL 规范中写道5 6 3 构建选项 5 6 3 1 预处理器选项 I dir Add the directory dir to the list of directories to be searched for header f
  • OpenCL 编译器预处理定义?

    我正在 Snow Leopard 上开发 OpenCL 代码 并且了解 OpenCL 即时编译是由 Clang LLVM 完成的 是否使用了 C 预处理器 有没有办法使用编译器设置预处理定义 存在哪些定义 我希望代码知道它是为 CPU 还是
  • OpenCL C/C++ 动态绑定库(win32 及更多)

    我正在尝试 OpenCL 为了将其投入生产 我希望能够动态绑定到 OpenCL DLL 在 Windows 下 以便 优雅地 处理没有 OpenCL 的情况安装在主机上 是否有任何可用的库 或代码片段 可以在 C 或 C 中处理这种动态绑定
  • boost::计算流压缩

    如何使用 boost compute 进行流压缩 例如 如果您只想对数组中的某些元素执行繁重的操作 首先 生成掩码数组 其中包含与要执行操作的元素相对应的元素 mask 0 0 0 1 1 0 1 0 1 然后对掩码数组进行排它扫描 前缀和
  • 为什么程序(全局)作用域变量必须是 __constant?

    我是 OpenCL 新手 对这个限制感到非常困惑 例如 如果我想写一个LCG 我必须使状态字可以修改为rand and srand 在 ANSI C 中 我将使用以下方法来做到这一点 ANSI C static unsigned long
  • 空的 openCL 程序抛出弃用警告

    我下载了 AMD APP 3 0 SDK 一旦包含 include
  • 使用 Fortran (CLFORTRAN) 在 OpenCL 中将两个选项作为参数传递

    当我的主机程序采用 C 语言时 我可以传递两个选项作为 OpenCL 函数的参数 例如 我可以通过两个 标志到clCreateBuffer像这样的函数 clCreateBuffer context CL MEM READ ONLY CL M
  • 使用 OpenCL 支持构建 OpenCV

    在 CMake 中 我使用 OpenCL Enable ON 构建了 OpenCV 它自动检测到OPENCL INCLUDE DIR路径但是OPENCL LIBRARY即使单击配置后也是空的 为了OPENCL LIBRARY我也没有看到浏览
  • 在 Mac OS X 10.7.4 上使用 OpenCL 禁用 Nvidia 看门狗

    我有一个 OpenCL 程序 对于小问题运行良好 但是当运行较大的问题超过 Nvidia 硬件上运行内核的 8 10 秒时间限制时 虽然我没有将显示器连接到我正在计算的 GPU Nvidia GTX580 上 但一旦内核运行大约 8 10
  • 如何在 C 中将向量参数传递给 OpenCL 内核?

    我在将向量类型 uint8 参数从 C 中的主机代码传递到 OpenCL 内核函数时遇到问题 在主机中 我将数据存储在数组中 cl uint dataArr 8 1 2 3 4 5 6 7 8 我的真实数据不仅仅是 1 8 这只是为了便于解
  • 在内核 OpenCL 中实现 FIFO 的最佳方法

    目标 在 OpenCL 中实现下图所示 OpenCl 内核所需的主要内容是将系数数组和临时数组相乘 然后最后将所有这些值累加为 1 这可能是最耗时的操作 并行性在这里非常有帮助 我正在为内核使用一个辅助函数来执行乘法和加法 我希望这个函数也
  • 如何在 pyopencl 中创建可变大小的 __local 内存?

    在我的 C OpenCL 代码中我使用clSetKernelArg创建 可变尺寸 local我的内核中使用的内存 OpenCL 本身不提供该内存 看我的例子 clSetKernelArg clKernel ArgCounter sizeof
  • OpenCL 内核在 Nvidia GPU 上每个线程使用多少寄存器?

    我的第一个问题是如何获取 Nvidia GPU 上 OpenCL 内核代码的寄存器使用信息 因为 nvcc 编译器给出了相同的使用信息nvcc ptxas options vCUDA 内核代码的标志 我还从 AMD GPU for Open

随机推荐

  • linux启动和停止springboot项目的命令

    1 启动命令 nohup java jar dingding function 0 0 1 SNAPSHOT jar gt catalina out 2 gt 1 2 命令详解 nohup 不挂断地运行命令 退出帐户之后继续运行相应的进程
  • Accessors are only available when targeting ECMAScript 5 and higher 错误提示

    来到这里 说明聪明又勤快的你 一定是在学习JavaScript的超大集群Typescript 幸幸苦苦写完代码 运行结果如下 error TS1056 Accessors are only available when targeting
  • 码云实战(一)——idea实现将本地的项目推送到码云上

    文章目录 前言 一 创建本地仓库并关联 二 将项目提交本地仓库 三 关联远程仓库 3 1 创建空白的远程库 四 推送到远程仓库 五 验证是否推送成功 总结 前言 本系列文章主要记录日常使用中碰到的码云的相关问题 一 创建本地仓库并关联 用I
  • Pandas知识点-详解聚合函数agg

    Pandas知识点 详解聚合函数agg Pandas提供了多个聚合函数 聚合函数可以快速 简洁地将多个函数的执行结果聚合到一起 本文介绍的聚合函数为DataFrame aggregate 别名DataFrame agg aggregate
  • 计算机共享打印怎么设置密码,共享打印机需要密码的解决方法

    Q 共享打印机 客户机访问主机计算机提示输入账户和密码如何解决 A 造成是此问题的原因是主机电脑安全级别较高造成的 在主机电脑按照以下方法调整即可解决 1 Windows XP 点击 开始 控制面板 WINDOWS防火墙 列外 将 文件和打
  • Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect

    Session 0x0 for server null unexpected error closing socket connection and attempting reconnect 错误原因 zookeeper没有正常启动 为了避
  • Linux系统下PORT端口引脚导出GPIO对应的序号关系

    文章首发于同名微信公众号 DigCore 欢迎关注同名微信公众号 DigCore 及时获取最新技术博文 PORT端口中的引脚序号与GPIOx的对应关系 GPIOx P 32 N P PORTA 0 PORTB 1 PORTC 2 N PA0
  • 聊一聊fastjson

    文章目录 一 新手引导 1 什么是fastjson 2 fastjson的优点 2 1 速度快 2 2 使用广泛 2 3 测试完备 2 4 使用简单 2 5 功能完备 三 源码分析 3 1JSON toJSONString 3 1 1调用J
  • 使用OpenCASCADE绘制线束的基本操作

    使用OpenCASCADE绘制线束的基本操作 在OpenCASCADE中 绘制线束是一个常见的操作 下面我们将介绍OpenCASCADE中绘制线束的基本命令 以及相应的源代码 创建导向线 要在OpenCASCADE中创建导向线 可以使用以下
  • vscode卡顿优化设置

    点击左上角 文件 首选项 设置 1 向Microsoft发送使用情况 搜索关键词 telemetry 2 搜索索引 搜索关键词 search exclude 搜索是VSCode最耗费内存的活动之一 它必须保留所有文件及其内容的索引 您可能不
  • 渗透信息收集步骤(简约版)

    第一步 域名的信息收集 1 whois信息查询 备案信息查询 相关查询地址 天眼查 https www tianyancha com ICP备案查询网 http www beianbeian com 国家企业信用信息公示系统 http ww
  • 互联网情报屋

    社交领域 微信 手机 QQ 新浪微博 陌陌等 在线游戏 腾讯 奇虎 360 昆仑 在线视频 优酷 土豆 爱奇艺 PPS 乐视 迅雷看看 在线娱乐 YY 9158 招聘 51job 智联招聘 下载工具 迅雷 QQ旋风 网盘 金山快盘 360云
  • THE MNIST DATABASE of handwritten digits

    The MNIST database of handwritten digits available from this page has a training set of 60 000 examples and a test set o
  • FL Studio 20汉化补丁及详细激活使用说明/fl studio21怎么设置中文?

    音乐在人们心中的地位日益增高 近几年音乐选秀的节目更是层出不穷 喜爱音乐 创作音乐的朋友们也是越来越多 音乐的类型有很多 好比古典 流行 摇滚等等 对新手友好程度基本上在首位 电音类制作支持仅次于Ableton Push 调用音色和素材很方
  • 第五站:入门级小白易上手JavaScript

    第五站 入门级小白易上手JavaScript 文章目录 第五站 入门级小白易上手JavaScript 复习Web标准 三位好基友 什么是JavaScript 让我们开启JavaScript的奇妙冒险 引入JavaScript 让魔法生效 内
  • 如何下载安装jdk

    1 下载jdk 在oracle官网中下载jdk https www oracle com https www oracle com 按照如下流程依次点击 下载自己喜欢的版本即可 2 安装jdk 3 配置环境变量 新建 gt 变量名 JAVA
  • Web存储

    目录 什么是 HTML5 Web 存储 方法 cookie webStorage 会话存储 sessionStorage 本地存储localStorage 什么是 HTML5 Web 存储 使用HTML5可以在本地存储用户的浏览数据 早些时
  • Node.js连接MySQL连接池解决自动断开问题

    1 为什么要使用连接池 自己将node 写的api接口 部署服务器时 发现运行一段时间后 会查询不到数据库里的内容 通过自己百度发现到了自己没有关闭数据库 默认数据库可以保持连接一段时间 之后 就会断开连接 2 连接池如何使用 const
  • UA分享

    之前自架短地址服务搜集到的UA 感觉很乱没法分析 看看大佬们有没有兴趣 Mozilla 5 0 Linux U Android 4 4 2 zh cn GT I9500 Build KOT49H AppleWebKit 537 36 KHT
  • Opencl入门Demo

    最近负责的几个项目需要使用opencl进行编程 进行了学习 并将学习后编写的主要Demo代码记录下来 供大家初步入门使用 opencl的介绍 原理等这里就不说了 百度一下有很多 直接切入主题 这个demo实现两个数组的相加操作 1 进行平台