OpenCL零基础笔记3
先来讲一下目录源代码目录存放了.cpp.h.cl等文件debug/release目录按下编译后VS会把源代码翻译成机器码生成了.exe文件放在该目录下工作目录程序当前的视野。当.exe文件运行起来后默认从源代码目录找。如果代码找不到.cl文件如果是在VS里面运行它会去源代码目录里找。如果是在文件夹里双击.exe文件运行它会在debug目录里找。那么怎么设置属性让VS自动实现搬运不用每次都把.cl文件复制到debug目录下首先先来讲一下VS怎么配置OpenCL环境。先下载好CUDA然后在具体的编程文件里面点开属性更改C/C常规里面的附加包含目录C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.2\include。更改链接器/输入里面的附加依赖项C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.2\lib\x64\OpenCL.lib双击附加依赖项将地址复制进去。再来讲一下上面的那个问题先找到.cl文件。然后右击选择属性在常规选项卡里找到项类型将其修改为复制文件或者文本即可。多文件开发将.cl和.cpp文件分开将内核函数存在.cl文件里然后在.cpp文件里写一个读取的函数。示例创建一个vector_add.cl文件。//vector_add.cl __kernel void vector_add(__global const int *A,__global const int *B,__global const int *C) { int iget_global_id(0); C[i]A[i]B[i]; }在C中读取代码。#includefstream #includesstream #includestring std::string loadKernelSource(const std::String filename) { std::ifstream file(filename); //尝试打开名为filename的文件 if(!file.isopen()) { std::coutcannot open this file; return ; } std::stringstream buffer; //stringstream是内存里的一块缓冲区可以往里面存字符串 bufferfile.rdbuf(); //rdbuf()获取文件的全部原始数据流符号将数据搬进buffer return buffer.str(); //把buffer里面的内容转换成string对象并返回 }那么在原本代码里是const char *kernelSourceR();现在就改成std::String sourceStrloadKernelSource(vector_add.cl); //转换为opencl需要的C风格字符串指针 const char*kernelSourcesourceStr.c_str();完整的示例代码//vector_add.cl __kernel void vector_add(__global const int *A,__global const int *B,__global int *C) { int iget_global_id(0); C[i]A[i]B[i]; }//simple_addition.cpp #includeiostream #includevector #includeCL/cl.h #includefstream #includesstream #includestring using namespace std; string loadKernelSource(const stringfilename) { ifstream file(filename); if(!file.is_open()) { coutcannot open .cl; return ; } stringstream buffer; bufferfile.rdbuf(); return buffer.str(); } string sourceStrloadKernelSource(vector_add.cl); const char* kernelSourcesourceStr.c_str(); int main() { const int N1024; size_t sizesizeof(int)*N; vectorinth_A(N,1); vectorinth_B(N,2); vectorinth_C(N,0); cl_platform_id platform; clGetPlatformIDs(1,platform,NULL); cl_device_id device; clGetDeviceIDs(platform,CL_DEVICE_TYPE_GPU,1,device,NULL); cl_context contextclCreateContext(NULL,1,device,NULL,NULL,NULL); cl_command_queue queueclCreateCommandQueueWithProperties(context,device,0,NULL); cl_mem bufAclCreateBuffer(context,CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,size,h_A.data(),NULL); cl_mem bufBclCreateBuffer(context,CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,size,h_B.data(),NULL); cl_mem bufCclCreateBuffer(context,CL_MEM_WRITE_ONLY,size,NULL,NULL); cl_program programclCreateProgramWithSource(context,1,kernelSource,NULL); clBuildProgram(program,1,device,NULL,NULL,NULL); cl_kernel kernelclCreateKernel(program,vector_add,NULL); clSetKernelArg(kernel,0,sizeof(cl_mem),bufA); clSetKernelArg(kernel,1,sizeof(cl_mem),bufB); clSetKernelArg(kernel,2,sizeof(cl_mem),bufC); size_t global_sizeN; clEnqueueNDRangeKernel(queue,kernel,1,NULL,global_size,NULL,0,NULL,NULL); clEnqueueReadBuffer(queue,bufC,CL_TRUE,0,size,h_C.data(),0,NULL,NULL); coutResult[0]:h_C[0]endl; coutResult[1023]:h_C[1023]endl; clReleaseMemObject(bufA); clReleaseMemObject(bufB); clReleaseMemObject(bufC); clReleaseKernel(kernel); clReleaseProgram(program); clReleaseCommandQueue(queue); clReleaseContext(context); return 0; }