OpenCL 设备队列
▶ 按书上写的设备队列的代码,需要 OpenCL2.0 的平台和设备,先把代码堆上来
● 程序主要功能:用主机上的数组 Ahost 和 Bhost 创建设备缓冲区 Adevice 和 Bdevice,调用核函数 foo 及其子核函数 fooChild 计算 factor * Adevice .* Bdevice,结果写入 Cdevice,最后拷贝回主机数组 Chost 检查结果。
● 代码
//deviceQueue.cl
__kernel void fooChild(const int nElement, const float factor,
__global const float *A, __global const float *B, __global float *C)
{
uint gid = get_global_id();
if (gid < nElement)
C[gid] = factor * A[gid] * B[gid];
} __kernel void foo(const int nElement, const float factor,
__global const float *A, __global const float *B, __global float *C)
{
uint gid = get_global_id(), gsize = get_global_size();
uint childGsize = nElement / gsize, childOffset = gid * childGsize; __global const float *Achild = &A[childOffset];
__global const float *Bchild = &B[childOffset];
__global const float *Cchild = &C[childOffset]; queue_t defQ = get_default_queue();
ndrange_t ndrange = ndrange_1D(childGsize);
void(^fooChildWrapper)(void) = ^{ fooChild(childGsize, factor, Achild, Bchild, Cchild); };
enqueue_kernel(defQ, CLK_ENQUEUE_FLAGS_NO_WAIT, ndrange, saxpyDpChildWrapper);
}
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <cl.h> const char *sourceCode = "D:/Code/deviceQueue.cl"; char* readSource(const char* kernelPath)// 读取文本文件,存储为 char *
{
FILE *fp;
char *source;
long int size;
//printf("readSource, Program file: %s\n", kernelPath);
fopen_s(&fp, kernelPath, "rb");
if (!fp)
{
printf("Open kernel file failed\n");
exit(-);
}
if (fseek(fp, , SEEK_END) != )
{
printf("Seek end of file faildd\n");
exit(-);
}
if ((size = ftell(fp)) < )
{
printf("Get file position failed\n");
exit(-);
}
rewind(fp);
if ((source = (char *)malloc(size + )) == NULL)
{
printf("Allocate space failed\n");
exit(-);
}
fread(source, , size, fp);
fclose(fp);
source[size] = '\0';
return source;
} int main()
{
const int nElement = , nChildElement = , dataSize = nElement * sizeof(float);
float factor = 2.3f;
char info[] = { };
int i; // 初始化平台
cl_int status;
cl_platform_id platform;
status = clGetPlatformIDs(, &platform, NULL);
cl_device_id device;
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, , &device, NULL);
cl_context_properties contextProp[] = { CL_CONTEXT_PLATFORM,(cl_context_properties)(platform), };
cl_context context = clCreateContext(contextProp, , &device, NULL, contextProp, &status);
cl_queue_properties queueProp[] = { CL_QUEUE_PROPERTIES,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT, };
cl_command_queue queue = clCreateCommandQueueWithProperties(context, device, queueProp, &status);
cl_event eventProducer, eventConsumer; const char* source = readSource(sourceCode);
cl_program program = clCreateProgramWithSource(context, , &source, NULL, &status);
status = clBuildProgram(program, , &device, NULL, NULL, NULL);
if (status)
{
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, , info, NULL);
printf("Build log:\n%s\n", info);
} cl_kernel foo = clCreateKernel(program, "foo", &status);
size_t globalSize = nElement / nChildElement, localSize = ;// 每个父工作项调度 nChildElement 个子工作项 float *Ahost = (float *)malloc(dataSize);
float *Bhost = (float *)malloc(dataSize);
float *Chost = (float *)malloc(dataSize);
for (i = ; i < nElement; Ahost[i] = i, Bhost[i] = i + , Chost[i] = .f, i++); cl_mem Adevice, Bdevice, Cdevice;
Adevice = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, dataSize, Ahost, &status);
Bdevice = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, dataSize, Bhost, &status);
Cdevice = clCreateBuffer(context, CL_MEM_WRITE_ONLY, dataSize, NULL, &status); clSetKernelArg(foo, , sizeof(int), (void*)&nElement);
clSetKernelArg(foo, , sizeof(float), (void*)&factor);
clSetKernelArg(foo, , sizeof(cl_mem), Adevice);
clSetKernelArg(foo, , sizeof(cl_mem), Bdevice);
clSetKernelArg(foo, , sizeof(cl_mem), Cdevice); clEnqueueNDRangeKernel(queue, foo, , NULL, &globalSize, &localSize, , NULL, &eventProducer);
clFinish(queue); clEnqueueReadBuffer(queue, Cdevice, CL_TRUE, dataSize, dataSize, Chost, , &eventConsumer, NULL);
clFinish(queue); for (i = ; i < nElement; i++)
{
if (Chost[i] != factor*i*(i + ))
break;
}
printf("Output is %s.\n", (i == nElement) ? "correct" : "incorrect"); free(Ahost);
free(Bhost);
free(Chost);
clReleaseContext(context);
clReleaseCommandQueue(queue);
clReleaseProgram(program);
clReleaseKernel(foo);
clReleaseMemObject(Adevice);
clReleaseMemObject(Bdevice);
clReleaseMemObject(Cdevice);
getchar();
return ;
}
● 输出结果
■ 一直卡在函数 clCreateCommandQueueWithProperties 的调用上,返回值 -6(CL_OUT_OF_HOST_MEMORY),原因不明,stackExchange 上有人说换了显卡驱动就好了(https://stackoverflow.com/questions/39864947/opencl-cl-out-of-host-memory-on-clcreatecommandqueuewithproperties-with-minima),还有人说是设备位数的问题(https://stackoverflow.com/questions/45231329/opencl-clcreatecommandqueue-cl-out-of-host-memory-error),但是我更新了显卡驱动,工程改成 32 位(才发现显卡是 32 位的)还是不行。
■ 强行忽略上面的问题(clCreateCommandQueueWithProperties 第四参数用 NULL)仍然程序编译失败,返回 -11(CL_BUILD_PROGRAM_FAILURE),原因是不能支持和函数中的 queue_t 和 ndrange_t 数据类型,后面的块语法就更别想了,应该是平台和设备不能完全支持 OpenCL2.0 所致。
■ 更新心啊卡驱动和 AMD OpenCL2.0 驱动,编译失败,报错 -11,报错信息变成了【Error: Inserting openCl Source to binary】和【Error: Compiling CL to IR】
OpenCL 设备队列的更多相关文章
- 《OpenCL异构并行编程实战》补充笔记散点,第一至四章
▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...
- GPGPU OpenCL编程步骤与简单实例
http://www.cnblogs.com/xudong-bupt/p/3582780.html 1.OpenCL概念 OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU.GPU或其 ...
- OpenCL与CUDA,CPU与GPU
OpenCL OpenCL(全称Open Computing Language,开放运算语言)是第一个面向异构系统通用目的并行编程的开放式.免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计 ...
- OPENCL 错误码
#define CL_SUCCESS 0 #define CL_DEVICE_NOT_FOUND -1 #define CL_DEVICE_NOT_AVAILABLE -2 #define CL_CO ...
- CUDA与OpenCL架构
CUDA与OpenCL架构 目录 CUDA与OpenCL架构 目录 1 GPU的体系结构 1.1 GPU简介 1.2 GPU与CPU的差异 2 CUDA架构 2.1 硬件架构 2.1.1 GPU困境 ...
- OpenCV、OpenCL、OpenGL、OpenPCL
对于几个开源库的总结,作为标记,以前看过,现在开始重视起来!更详细资料请移步 开源中国社区! 涉及:OpenCV,OpenCL,OpenGL,OpenPCL 截止到目前: OpenGL的最新版本为4. ...
- 【OpenCV开发】使用OpenCV的OpenCL(ocl)模块
参加OpenCV的OpenCL模块(以下称OCL)移植工作已经有2个月了.这里我说移植而不是开发,是因为大部分OCL模块的函数都是从已经很成熟的GPU模块移植过来的.于是目前阶段OCL模块所支持的函数 ...
- OpenCL介绍
OpenCL(全称Open Computing Language,开放运算语言)是第一个面向异构系统通用目的并行编程的开放式.免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计算服务器.桌面 ...
- 一文说清OpenCL框架
背景 Read the fucking official documents! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: 对不 ...
随机推荐
- hdu1097
hdu1097 求a^b的末位数 打表O(1) import java.util.*; public class Main { static int [][]a = new int[15][15]; ...
- LG2044 [NOI2012]随机数生成器
题意 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础.栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随机数列,这种方法需要设置四个非负整数参数m,a,c ...
- Ubuntu配置操作总结
一.fstab和mtab的区别 /etc/fstab:是开机自动挂载的配置文件,在开机时起作用.相当于启动linux的时候,自动使用检查分区的fsck命令和挂载分区的mount命令,检查分区和挂载分区 ...
- sqlserver linux 容器运行
sqlserver linux 版本的容器大小目前已经相对比较小了,对于开发来说已经比较方便了 docker-compose 文件 version: "3" services: d ...
- pycharm -- 导入主题(theme) and 修改背景颜色(护眼色)
前情提要 众所周知,随着python语言的不断流行,越来越多的程序员开始用python来开发自己的项目以及产品. pycharm作为一款流行的IDE,被越来越多的程序员所接受和使用. 尽管pychar ...
- Oracle 存储过程发送邮件
CREATE OR REPLACE PROCEDURE PROCSENDEMAIL(P_TXT VARCHAR2, ...
- java 的关键字 native
native native 关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中.Java语言本身不能对操作系统底层进行访问和操作,但是可 ...
- linux I2C_client产生方法一
\arch\arm\mach-omap2/board-am335xevm.c static struct i2c_board_info am335x_i2c2_boardinfo[] = { { I ...
- 【shell】正则表达式语法
一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式.该模式描述在查找文字主体时待匹配的一个或多个字符串.正则表达式作为一个模板,将某个字符模式与所搜索的字符串 ...
- keepalived的配置详解(非常详细)
keepalived的配置详解(非常详细) 2017-01-22 15:24 2997人阅读 评论(0) 收藏 举报 分类: 运维学习(25) 转载自:http://blog.csdn.net ...