Hello all,
I am a novice to programming in general and am attempting to add two 2D c++ vectors a specified amount of times on the GPU using OpenCL. I think I am running into issues when I attempt to write my data to the created device buffer. I am uncertain as to how I need to create my vectors in order to pass them to GPU. When running this code, I get a pointer error when I attempt to access the data that is contained within the vector that receives the data from the GPU indicating to me that the data are never actually brought back from the device.
Here I post a portion of my code. I have some functions that I wrote called packVector and unPackVector. These are simply used to make the vectors one dimensional so I can pass them to the GPU and when receiving 1D data from the GPU, make it 2D.
I have successfully implemented this code with 2D arrays but I am getting memory leaks and therefore would like to use vectors.
The GPU I am using is a NVIDIA GeForce 9400M and I am using the OpenCL framework via Mac OS X 10.7.5
Thank you in advance.
int n1 = 2;
int n2 = 2;
int dims = n1*n2;
int iters = 2;
std::vector<std::vector<float> > h_xx(n1, std::vector<float>(n2));
std::vector<std::vector<float> > h_yy(n1, std::vector<float>(n2));
std::vector<std::vector<float> > h_zz(n1, std::vector<float>(n2));
std::vector<float> h_x(dims);
std::vector<float> h_y(dims);
std::vector<float> h_z(dims);
for (int i = 0; i < n1; ++i){
for (int j = 0; j < n2; ++j){
h_xx[i][j] = 1;
h_yy[i][j] = 1;
}
}
cl_mem d_xx, d_yy, d_zz;
d_xx = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float)*dims, NULL, &err);
if(err != CL_SUCCESS){
std::cout << "Error: Could not create the buffer." << std::endl;
exit(1);
}
d_yy = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float)*dims, NULL, &err);
if(err != CL_SUCCESS){
std::cout << "Error: Could not create the buffer." << std::endl;
exit(1);
}
d_zz = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float)*dims, NULL, &err);
if(err != CL_SUCCESS){
std::cout << "Error: Could not create the buffer." << std::endl;
exit(1);
}
arr.packVector(h_xx, h_x);
arr.packVector(h_yy, h_y);
clEnqueueWriteBuffer(queue, d_xx, CL_FALSE, 0, sizeof(float)*h_x.size(), &h_x, 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not write vector to buffer." << std::endl;
std::cout << "OpenCL error code: " << std::endl;
exit(1);
}
clEnqueueWriteBuffer(queue, d_yy, CL_FALSE, 0, sizeof(float)*h_y.size(), &h_y, 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not write vector to buffer." << std::endl;
std::cout << "OpenCL error code: " << std::endl;
exit(1);
}
err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_xx);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set the kernel argument." << std::endl;
std::cout << "OpenCL error code: " << err << std::endl;
exit(1);
}
err = clSetKernelArg(kernel, 1, sizeof(cl_mem), &d_yy);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set the kernel argument." << std::endl;
std::cout << "OpenCL error code: " << err << std::endl;
exit(1);
}
err = clSetKernelArg(kernel, 2, sizeof(cl_mem), &d_zz);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set the kernel argument." << std::endl;
std::cout << "OpenCL error code: " << err << std::endl;
exit(1);
}
err = clSetKernelArg(kernel, 3, sizeof(iters), &iters);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set the integer kernel argument." << std::endl;
std::cout << "OpenCL error code: " << err << std::endl;
exit(1);
}
size_t work_units_per_kernel = dims;
err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &work_units_per_kernel, NULL, 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not execute the kernel." << std::endl;
exit(1);
}
err = clEnqueueReadBuffer(queue, d_zz, CL_TRUE, 0, sizeof(float)*h_z.size(), &h_z, 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not read vector from the kernel." << std::endl;
std::cout << "OpenCL error code: " << std::endl;
exit(1);
}
arr.unPackVector(h_z, h_zz);
arr.printVec2D(h_zz);