▶ 按书上写的设备队列的代码,需要 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 设备队列的更多相关文章

  1. 《OpenCL异构并行编程实战》补充笔记散点,第一至四章

    ▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...

  2. GPGPU OpenCL编程步骤与简单实例

    http://www.cnblogs.com/xudong-bupt/p/3582780.html  1.OpenCL概念 OpenCL是一个为异构平台编写程序的框架,此异构平台可由CPU.GPU或其 ...

  3. OpenCL与CUDA,CPU与GPU

    OpenCL OpenCL(全称Open Computing Language,开放运算语言)是第一个面向异构系统通用目的并行编程的开放式.免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计 ...

  4. OPENCL 错误码

    #define CL_SUCCESS 0 #define CL_DEVICE_NOT_FOUND -1 #define CL_DEVICE_NOT_AVAILABLE -2 #define CL_CO ...

  5. CUDA与OpenCL架构

    CUDA与OpenCL架构 目录 CUDA与OpenCL架构 目录 1 GPU的体系结构 1.1 GPU简介 1.2 GPU与CPU的差异 2 CUDA架构 2.1 硬件架构 2.1.1 GPU困境 ...

  6. OpenCV、OpenCL、OpenGL、OpenPCL

    对于几个开源库的总结,作为标记,以前看过,现在开始重视起来!更详细资料请移步 开源中国社区! 涉及:OpenCV,OpenCL,OpenGL,OpenPCL 截止到目前: OpenGL的最新版本为4. ...

  7. 【OpenCV开发】使用OpenCV的OpenCL(ocl)模块

    参加OpenCV的OpenCL模块(以下称OCL)移植工作已经有2个月了.这里我说移植而不是开发,是因为大部分OCL模块的函数都是从已经很成熟的GPU模块移植过来的.于是目前阶段OCL模块所支持的函数 ...

  8. OpenCL介绍

    OpenCL(全称Open Computing Language,开放运算语言)是第一个面向异构系统通用目的并行编程的开放式.免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计算服务器.桌面 ...

  9. 一文说清OpenCL框架

    背景 Read the fucking official documents! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: 对不 ...

随机推荐

  1. python--selenium实用的自动生成测试HTML报告方法--HTMLTestRunner

    python--selenium实用的自动生成测试HTML报告方法--HTMLTestRunner 下面给大家介绍下用HTMLTestRunner模块自动生成测试报告的方法. 一.首先我们导入unit ...

  2. (11)shutil模块(文件处理模块)

    shutil模块的格式 shutil.copyfileobj(文件1,文件2)   #将文件1的数据覆盖copy给文件2 import shutil f1 = open("1.txt&quo ...

  3. vector容器的用法以及动态数组

    vector容器不必去管大小 string申明的数组已经是动态的了 若是int类型的话,需要 cin>>N: int a[N]会出错 ,必须是int *p = new int[N] 然后再 ...

  4. day27 python学习 logging

    logging模块 函数式简单配置 import logging logging.debug('debug message') logging.info('info message') logging ...

  5. treeql 基于rest 标准的接口开发协议

    treeql 可以让我们按照数据库的关系模型,生成一个tree 模型的json 数据,基于rest 标准, 从设计上,来说还是很不错的,但是从长远发展来说graphql 应该会更好,也有相关的比较 参 ...

  6. Nginx 安装成Windows 服务方法

    1. 下载nginx windows版本 http://www.nginx.org 2. 下载微软的2个工具: instsrv.exe.srvany.exe 去微软网站下载安装Windows Serv ...

  7. commonJS规范基本结构

    commonJS规范:使用 module.exports 和 require ,基本结构如下: // foo.js 输出模块 module.exports = function(x) { consol ...

  8. webpack的3个路径配置项: assetsRoot、assetsSubDirectory、assetsPublicPath

    在 vue-cli 构建模版的配置文件config.js中有assetsRoot,assetsSubDirectory和assetsPublicPath这三个路径配置项 assetsRoot:构建输出 ...

  9. openVPN之Luci及tap模式

    一. 1.复制luci-sc-openvpn源码到/home/tingpan/openwrt/barrier_breaker/feeds/luci/applications文件夹下. 二. /home ...

  10. SQL Server存储过程 对数组参数的循环处理

    方法一 分割 例:通过SQL Server存储过程传送数组参数删除多条记录 eg. ID 值为'1,2,3' 以下存储过程就是删除表中id号为1,2,3的记录: CREATE PROCEDURE De ...