【发布时间】:2013-07-31 21:29:42
【问题描述】:
我在 C++ 中为 opencl 编写了一个点积内核,它适用于向量长度 4096(也尝试了 12k 个元素并且工作完美)但是当我将向量长度增加到 16k 个元素时,结果变为无穷大 虽然它不应该超过一个小的浮点数。显然有泄漏或类似的东西,但它适用于 n
这是从 C# 通过 DLL 调用传递给 C++ 的内核(Ln= 本地工作大小,n= 全局工作大小):
"__kernel void SkalarCarpim(__global float * v1, __global float * v2, __global float * v3)" +
"{" +
" int i = get_global_id(0);" +
" int j = get_local_id(0);" +
" __local float biriktirici [" + Ln.ToString() + "];" +
" barrier(CLK_LOCAL_MEM_FENCE);" +
" biriktirici[j]=v1[i]*v2[i];" +
" barrier(CLK_LOCAL_MEM_FENCE);" +
" barrier(CLK_GLOBAL_MEM_FENCE);" +
" float toplam=0.0f;" +
" if(j==0)" +
" {" +
" for(int k=0;k<"+Ln.ToString()+";k++)"+ // reduction
" {"+
" toplam+=biriktirici[k];"+
" }"+
" }" +
" barrier(CLK_GLOBAL_MEM_FENCE);" +
" v3[i]=toplam;" +
" barrier(CLK_GLOBAL_MEM_FENCE);" +
" toplam=0.0f;" +
" for(int k=0;k<"+(n/Ln).ToString()+";k++)" +
" {" +
" toplam+=v3[k*"+Ln.ToString()+"]; " + // sum of temporary sums
" }" +
" v3[i]=toplam;"+
"}";
这里是 C++ Opencl 缓冲区:
buf1=cl::Buffer(altYapi,CL_MEM_READ_WRITE,sizeof(cl_float) * N);
buf2=cl::Buffer(altYapi,CL_MEM_READ_WRITE,sizeof(cl_float) * N);
buf3=cl::Buffer(altYapi,CL_MEM_READ_WRITE,sizeof(cl_float) * N);
//CL_MEM_READ_ONLY makes same error, tried some other too, no solution :(
以下是缓冲区的发送方式:
komutSirasi.enqueueWriteBuffer(buf1,CL_TRUE,0,sizeof(cl_float)*N,v1);
komutSirasi.enqueueWriteBuffer(buf2,CL_TRUE,0,sizeof(cl_float)*N,v2);
//CL_TRUE makes a blocking action so waits until finished
执行:
komutSirasi.enqueueNDRangeKernel(kernel,0,Global,Local);
//I got this from an example and I dont know if it is blocking or not.
这是结果缓冲区的获取方式(所有元素都是结果,我知道它未完成):
komutSirasi.enqueueReadBuffer(buf3,CL_TRUE,0,sizeof(cl_float) * N,v3);
//CL_TRUE makes a blocking action so waits until finished
问题:在深入研究 C++ Opencl 之前,我必须做一些配置吗?这在 Java/Aparapi/Jocl 中不是问题。
使用来自 Khronos 网站的 Opencl 1.2 头文件和 AMD Opencl.lib + Opencl.dll 来解决这个问题(目标设备是 HD7870)。
【问题讨论】:
标签: c# c++ buffer opencl dot-product