白嫖来的C端代码:

matrix.c:

#include <stdio.h>
#include <stdlib.h>
#include <alloca.h>
#include <CL/cl.h>
#pragma warning( disable : 4996 )
int main() {cl_int error;cl_platform_id platforms;cl_device_id devices;cl_context context;FILE *program_handle;size_t program_size;char *program_buffer;cl_program program;size_t log_size;char *program_log;char kernel_name[] = "createBuffer";cl_kernel kernel;cl_command_queue queue;//获取平台error = clGetPlatformIDs(1, &platforms, NULL);if (error != 0) {printf("Get platform failed!");return -1;}//获取设备error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_GPU, 1, &devices, NULL);if (error != 0) {printf("Get device failed!");return -1;}//创建上下文context = clCreateContext(NULL,1,&devices,NULL,NULL,&error);if (error != 0) {printf("Creat context failed!");return -1;}//创建程序;注意要用"rb"program_handle = fopen("kernel.cl","rb");if (program_handle == NULL) {printf("The kernle can not be opened!");return -1;}fseek(program_handle,0,SEEK_END);program_size = ftell(program_handle);rewind(program_handle);program_buffer = (char *)malloc(program_size+1);program_buffer[program_size] = '\0';error=fread(program_buffer,sizeof(char),program_size,program_handle);if (error == 0) {printf("Read kernel failed!");return -1;}fclose(program_handle);program = clCreateProgramWithSource(context,1,(const char **)&program_buffer, &program_size,&error);if (error < 0) {printf("Couldn't create the program!");return -1;}//编译程序error = clBuildProgram(program,1,&devices,NULL,NULL,NULL);if (error < 0) {//确定日志文件的大小clGetProgramBuildInfo(program,devices,CL_PROGRAM_BUILD_LOG,0,NULL,&log_size);program_log = (char *)malloc(log_size+1);program_log[log_size] = '\0';//读取日志clGetProgramBuildInfo(program, devices, CL_PROGRAM_BUILD_LOG, log_size+1, program_log, NULL);printf("%s\n",program_log);free(program_log);return -1;}free(program_buffer);//创建命令队列queue = clCreateCommandQueue(context, devices, CL_QUEUE_PROFILING_ENABLE, &error);if (error < 0) {printf("Coudn't create the command queue");return -1;}//创建内核kernel = clCreateKernel(program,kernel_name,&error);if (kernel==NULL) {printf("Couldn't create kernel!\n");return -1;}//初始化参数float result[100];float a_in[100];float b_in[100];for (int i = 0; i < 100; i++) {a_in[i] = i;b_in[i] = i*2.0;}//创建缓存对象cl_mem memObject1 = clCreateBuffer(context,CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,sizeof(float)*100,a_in,&error);if (error < 0) {printf("Creat memObject1 failed!\n");return -1;}cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float) * 100, b_in, &error);if (error < 0) {printf("Creat memObject2 failed!\n");return -1;}cl_mem memObject3 = clCreateBuffer(context, CL_MEM_WRITE_ONLY , sizeof(float) * 100, NULL, &error);if (error < 0) {printf("Creat memObject3 failed!\n");return -1;}//设置内核参数error = clSetKernelArg(kernel,0,sizeof(cl_mem),&memObject1);error|= clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2);error |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObject3);if (error != CL_SUCCESS) {printf("Error setting kernel arguments!\n");return -1;}//执行内核size_t globalWorkSize[1] = {100};size_t localWorkSize[1] = {1};error = clEnqueueNDRangeKernel(queue,kernel,1,NULL,globalWorkSize, localWorkSize,0,NULL,NULL);if (error != CL_SUCCESS) {printf("Error queuing kernel for execution!\n");return -1;}//读取执行结果error = clEnqueueReadBuffer(queue,memObject3,CL_TRUE,0,100*sizeof(float), result,0,NULL,NULL);if (error != CL_SUCCESS) {printf("Error reading result buffer!\n");return -1;}//显示结果for (int i = 0; i < 100; i++) {printf("%f ",result[i]);}printf("\n");//释放资源clReleaseDevice(devices);clReleaseContext(context);clReleaseCommandQueue(queue);clReleaseProgram(program);clReleaseKernel(kernel);clReleaseMemObject(memObject1);clReleaseMemObject(memObject2);clReleaseMemObject(memObject3);return 0;
}

OpenCL代码:

kernel.cl:

__kernel void createBuffer(__global const float *a_in,__global const float *b_in,__global float *result) {
int gid = get_global_id(0);
result[gid] = a_in[gid] + b_in[gid];
}

执行逻辑是,用opencl开发的kernel.cl程序,在HOST端的C程序中被动态加载,运行时编译,投递到GPU中运行,跑出结果后在从GPU MEM中读回来打印。


验证:

结合a_in,b_in初始化值和kernel.cl的逻辑,可以知道正确的结果应该是首项为0,公差为3的等差数列,我们编译运行,看一下结果是否符合我们预期:

编译命令,编译方式上和普通C语言用GCC编译无异,注意需要链接opencl的运行库libOpenCL即可。

gcc -I/usr/local/cuda-11.5/targets/x86_64-linux/include matrix.c -o main -L/usr/local/cuda-11.5/targets/x86_64-linux/lib/ -lOpenCL

符合预期,说明程序是对的。

和CUDA的关系:

架构上,它们在同一层面,cuda和OpenCL都属于一种并行计算开发语言,这从CUDA使用的编译器和OpenCL虽然使用GCC编译HOST侧代码,但是端册代码却需编译一个文本CL程序文件,交给OpenCL API执行在线编译看出来,他们虽然都有吸取C的语法特点,但是异构加速核心这一块和CPU端的编译器是不共用的,关于CUDA开发的例子,可以参考如下博客。

CUDA编程初探_tugouxp的专栏-CSDN博客_cuda并行程序设计CUDA的全称是Compute Unified Device Architecture,是显卡厂商NVIDIA推出的运算平台,开发者可以使用C语言来编写CUDA代码,使用NVCC编译器可以在支持CUDA的GPU处理器上以高速运行。虽然AMD也做显卡,但是CUDA是老黄自家提出的标准,没带AMD一起玩儿,所以,提到基于CUDA的高性能计算,使用的都是Nvidia的显卡。首先安装CUDA环境,具体方式参考博客:FairMOT Cuda环境搭建并进行推理_tugouxp的专栏-CSDN博客环境准备1.PChttps://blog.csdn.net/tugouxp/article/details/121293446

结束!

OpenCL编程之二相关推荐

  1. Python网络编程之二:网络编程基础

    Python网络编程之二:网络编程基础 一.基础概念 1.两个地址 1.1.mac地址 mac地址:直译为媒体存取控制位址,也称为局域网地址.MAC位址.以太网地址或物理地址,它是一个用来确认网络设备 ...

  2. socket编程之二:两种链接类型tcp和udp

    前面一篇文章说到了一些计算机网络的基础知识.引入了socket.从这节開始,就进入正题了. 一 概述 TCP:Transimission Control Protocol传输控制协议. UPD:Use ...

  3. IOS高级编程之二:IOS的数据存储与IO

    一.应用程序沙盒 IOS应用程序职能在系统为该应用所分配的文件区域下读写文件,这个文件区域就是应用程序沙盒.所有的非代码文件如:图片.声音.映象等等都存放在此. 在mac中command+shift+ ...

  4. 响应式编程之二:RxJava概述:在Android平台上开发详解

    RxJava 到底是什么 RxJava 好在哪 API 介绍和原理简析 1. 概念:扩展的观察者模式 观察者模式 RxJava 的观察者模式 2. 基本实现 1) 创建 Observer 2) 创建 ...

  5. ORACLE PL/SQL编程之二:PL/SQL块结构和组成元素

    2.1 PL/SQL块 PL/SQL程序由三个块组成,即声明部分.执行部分.异常处理部分. PL/SQL块的结构如下: DECLARE --声明部分: 在此声明PL/SQL用到的变量,类型及游标,以及 ...

  6. Linux C编程之二:Linux基础

    1.Linux的特点 (1)Linux就是一个操作系统(作为用户和计算机之间接口的软件程序) 注:操作系统的功能:命令解释,进程管理,内存管理,输入输出(I/O)操作和外围设备管理,文件管理 (2)特 ...

  7. 利用C#进行Socket通信编程之二:一个实例

    本文转载自: http://blog.csdn.net/huangxinfeng/article/details/4967629/ 转载于:https://www.cnblogs.com/tsyr/p ...

  8. ES6 异步编程之二:Promise

    异步回调的泥潭 异步回调是最直接的异步结果处理模式,将一个回调函数callback扔进异步处理函数中,当异步处理获得结果之后再调用这个回调函数就可以继续之后的处理,但是如果这个callback又是一个 ...

  9. (47)LINUX应用编程和网络编程之二Linux文件属性

    Linux下的文件系统为树形结构,入口为/ 树形结构下的文件目录: 无论哪个版本的Linux系统,都有这些目录,这些目录应该是标准的.各个Linux发行版本会存在一些小小的差异,但总体来说,还是大体差 ...

最新文章

  1. 施有朋:人工智能崛起,AI赋能医疗领域,创业者该如何选择
  2. 11 ORA系列:ORA-01791: 不是 SELECTed 表达式(distinct使用注意点)
  3. php 0行,php – 如果返回0行,MySQL返回结果
  4. 汇编语言(十三)之偶数转成哥德巴赫猜想
  5. Kafka启动报错:Timed out waiting for connection while in state: CONNECTING
  6. Python数据挖掘 环境搭建
  7. elixir官方入门教程 递归
  8. 第八届蓝桥杯第七题日期问题
  9. 超级素数幂--全国模拟(一)
  10. PHP 7.1 新特性一览
  11. PG数据库操作相关问题以及解决
  12. 细说促销(淘宝销售可看)
  13. 微服务的架构模式:一个服务一个数据库模式
  14. 首发:唯品会RPC服务框架与容器化演进
  15. 2013.08.08——— android 中文简繁体转换
  16. freebsd 更改镜像源
  17. 云应用程序服务器错误怎么办,“/”应用程序中的服务器错误解决方法
  18. js 时间格式字符串去掉中间的中横线
  19. 计算机考研专业课真题,计算机考研专业课 408 真题 20092013完美打印版.pdf
  20. 数据可视化Day1:Matplotlib初相识

热门文章

  1. 人体动作捕捉-坐标转换
  2. 基于STM32的恒流源设计
  3. IDEA配置远程debug调试
  4. RGB 色度空间转换
  5. 图像直方图均衡化和空间滤波
  6. uni-app跨域解决方案
  7. 数据结构 | 算法中的卡特兰数的应用
  8. SDWebImage使用详解
  9. 二十、HTTP 协议状态码-5XX
  10. [ML](HMM、MRF、CRF)