因此,花了几个小时的阅读和理解之后,我终于做出了我的第一个OpenCL程序,它实际上做了一些事情,这是它向文件添加了两个向量和输出。
#include
#include
#include
#include
#include
#define __CL_ENABLE_EXCEPTIONS
#include
int main(int argc, char *argv[])
{
try
{
// get platforms, devices and display their info.
std::vector<:platform> platforms;
cl::Platform::get(&platforms);
std::vector<:platform>::iterator i=platforms.begin();
std::cout<getInfo()<<:endl>
std::cout<getInfo()<<:endl>
std::cout<getInfo()<<:endl>
std::cout<getInfo()<<:endl>
// get devices
std::vector<:device> devices;
i->getDevices(CL_DEVICE_TYPE_ALL,&devices);
int o=99;
std::cout<
// iterate over available devices
for(std::vector<:device>::iterator j=devices.begin(); j!=devices.end(); j++)
{
std::cout<getInfo()<<:endl>
std::cout<getInfo()<<:endl>
std::cout<getInfo()<<:endl>
std::cout<getInfo()<<:endl>
std::cout<getInfo()/(1024*1024)<
std::cout<getInfo()/1024<
std::cout<getInfo()<<:endl>
std::cout<getInfo()<
}
std::cout<
//MAIN CODE BEGINS HERE
//get Kernel
std::ifstream ifs("vector_add_kernel.cl");
std::string kernelSource((std::istreambuf_iterator(ifs)), std::istreambuf_iterator());
std::cout<
//Create context, select device and command queue.
cl::Context context(devices);
cl::Device &device=devices.front();
cl::CommandQueue cmdqueue(context,device);
// Generate Source vector and push the kernel source in it.
cl::Program::Sources sourceCode;
sourceCode.push_back(std::make_pair(kernelSource.c_str(), kernelSource.size()));
//Generate program using sourceCode
cl::Program program=cl::Program(context, sourceCode);
//Build program..
try
{
program.build(devices);
}
catch(cl::Error &err)
{
std::cerr<
<
<
<(devices.front());
}
//Declare and initialize vectors
std::vectorB(993448,1.3);
std::vectorC(993448,1.3);
std::vectorA(993448,1.3);
cl_int N=A.size();
//Declare and intialize proper work group size and global size. Global size raised to the nearest multiple of workGroupSize.
int workGroupSize=128;
int GlobalSize;
if(N%workGroupSize) GlobalSize=N - N%workGroupSize + workGroupSize;
else GlobalSize=N;
//Declare buffers.
cl::Buffer vecA(context, CL_MEM_READ_WRITE, sizeof(cl_float)*N);
cl::Buffer vecB(context, CL_MEM_READ_ONLY , (B.size())*sizeof(cl_float));
cl::Buffer vecC(context, CL_MEM_READ_ONLY , (C.size())*sizeof(cl_float));
//Write vectors into buffers
cmdqueue.enqueueWriteBuffer(vecB, 0, 0, (B.size())*sizeof(cl_float), &B[0] );
cmdqueue.enqueueWriteBuffer(vecB, 0, 0, (C.size())*sizeof(cl_float), &C[0] );
//Executing kernel
cl::Kernel kernel(program, "vector_add");
cl::KernelFunctor kernel_func=kernel.bind(cmdqueue, cl::NDRange(GlobalSize), cl::NDRange(workGroupSize));
kernel_func(vecA, vecB, vecC, N);
//Reading back values into vector A
cmdqueue.enqueueReadBuffer(vecA,true,0,N*sizeof(cl_float), &A[0]);
cmdqueue.finish();
//Saving into file.
std::ofstream output("vectorAdd.txt");
for(int i=0;i
}
catch(cl::Error& err)
{
std::cerr << "OpenCL error: " << err.what() << "(" << err.err() <<
")" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}问题是,对于较小的N值,我得到的正确结果是2.6
但对于较大的值,如上面代码(993448)中的那样,我得到的垃圾输出在1到2.4之间变化。
这是内核代码:
__kernel void vector_add(__global float *A, __global float *B, __global float *C, int N) {
// Get the index of the current element
int i = get_global_id(0);
//Do the operation
if(i
}更新:好吧,看来代码现在正在工作。我在上面的代码中修复了一些小错误
1)GlobalSize初始化的部分已被修复。
2)enqueueWriteBuffer中的错误(给出了错误的参数)
现在它正在输出正确的结果,N值很大。