Opencl入门Demo
最近負責的幾個項目需要使用opencl進行編程,進行了學習,并將學習后編寫的主要Demo代碼記錄下來,供大家初步入門使用。
opencl的介紹,原理等這里就不說了,百度一下有很多,直接切入主題。
這個demo實現(xiàn)兩個數(shù)組的相加操作。
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執(zhí)行的平臺*/
? ? 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);
? ? /*獲取平臺執(zhí)行設備*/
? ? 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);
? ? /*創(chuàng)建context*/
? ? tplatformObj->context = clCreateContext(NULL,1,&tplatformObj->device,NULL,NULL,&err);
? ? if(err != CL_SUCCESS){
? ? ? ? printErr("initPlatform_clCreateContext:%d",err);
? ? ? ? return err;
? ? }
? ? /*創(chuàng)建命令隊列*/
? ? tplatformObj->queue = clCreateCommandQueue(tplatformObj->context,tplatformObj->device, 0, &err);
? ? if(err != CL_SUCCESS){
? ? ? ? printErr("initPlatform_clCreateCommandQueue:%d",err);
? ? ? ? return err;
? ? }
? ? return 0;
}
2.加載kernel函數(shù),執(zhí)行,直接整個文件拷貝過來了
#include "Rotate.h"
/*初始化工程*/
int initProgram(TPlatformObject* tplatformObj)
{
? ? FILE* fp=NULL; ? ? ? ? ? ? ? ?/*文件指針指向*.cl內(nèi)核代碼文件*/
? ? char* program_buffer=NULL; ? ?/*用于拷貝*.cl中的內(nèi)容*/
? ? 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指針位置之間的數(shù)據(jù)大小*/
? ? rewind(fp); ? ? ? ? ? ? ? ? ? /*讓fp指針重新回到文件頭位置*/
? ? program_buffer=(char*)malloc(program_size+1); ? /*分配內(nèi)存*/
? ? program_buffer[program_size]='\0'; ? ? ? ? ? ? ?/*添加結尾標志*/
? ? fread(program_buffer,sizeof(char),program_size,fp);
? ? fclose(fp);
? ? /*創(chuàng)建程序?qū)ο?/
? ? 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;
? ? /*構建程序執(zhí)行體*/
? ? 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;
}
/*獲取創(chuàng)建的kernel函數(shù)句柄*/
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;
}
/*創(chuàng)建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函數(shù)設置參數(shù)*/
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");
? ? /*創(chuàng)建kernel可執(zhí)行函數(shù)*/
? ? if(CreateKernel(tplatformObj,tRotObj) != CL_SUCCESS){
? ? ? ? printErr("RotateOpen CreateKernel failed!!");
? ? ? ? return -1;
? ? }
? ? /*測試用數(shù)組*/
? ? 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;
? ? /*創(chuàng)建buffer*/
? ? if(CreateBuffer(tplatformObj,tRotObj) != 0){
? ? ? ? printErr("RotateOpen CreateBuffer failed!!");
? ? ? ? return -1;
? ? }
? ? /*設置kernel的參數(shù)*/
? ? if(SetKernelArgs(tRotObj)){
? ? ? ? printErr("RotateOpen SetKernelArgs failed!!");
? ? ? ? return -1;
? ? }
? ? /*執(zhí)行kernel函數(shù)*/
? ? cl_uint work_dim=1; /*工作項維數(shù)*/
? ? 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);/*執(zhí)行結束*/
? ? /*讀取計算出的結果*/
? ? 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");
? ? ? ? }
? ? }
? ? /*釋放內(nèi)存*/
? ? 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;
}
?
總結
以上是生活随笔為你收集整理的Opencl入门Demo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 01: 实现注册登录功能
- 下一篇: Wincc7.3安装说明