I am trying to learn/teach myself OpenCL and started with a program to do Matrix Multiply. No matter what I do, I end up with the answer of zero.
I know that a 1x3 and a 3x1 should yield a 1x1 answer, and it should be non zero with the way I have it setup to create random floats. Here is my main body, and the kernel. Other than the warnings; What am I missing, I have been over this for hours and can't see the problem.
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#include <iostream>
#include <fstream>
#include <sstream>
#include "./cl.hpp"
int main()
{
int nX = 1;
int nY = 3;
int nZ = 1;
// Get all platforms
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
if(platforms.empty()){
throw std::runtime_error("No Platforms found, check OpenCL installation.");
}
cl::Platform platform = platforms[0];
std::cout << "Using Platform: " << platform.getInfo<CL_PLATFORM_NAME>() << std::endl;
std::vector<cl::Device> devices;
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
if(devices.empty()){
throw std::runtime_error ("No Devices Found, check installation.");
}
cl::Device device = devices[0];
// Create an execusion context
cl::Context context(device);
// create a command queue
cl::CommandQueue queue(context, device);
// Load the kernel sources, use global memory
std::ifstream fs("mCrossProd.cl");
if(!fs.is_open()) {
throw std::runtime_error("Can not open kernel source file.");
}
std::stringstream ss;
ss << fs.rdbuf();
std::string code = ss.str();
cl::Program::Sources sources;
sources.push_back({code.c_str(), code.length()});
// Build the kernel
cl::Program program(context, sources);
try{
program.build({device});
} catch(std::exception &err){
throw std::runtime_error(program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device));
}
//Create Matrix arrays and fill with random float values
float *A = new float[nX*nY];
float *B = new float[nY*nZ];
float *C = new float[nX*nZ];
for(int i =0; i < nX; i++){
for(int j = 0; j < nY; j++)
{
A[j + i*nY] = rand()/(float)RAND_MAX * 10 + 1;
std::cout << " A[" << std::to_string(j + i * nY) << "] = ";
std::cout << A[j + i*nY] << ' ';
}
std::cout << std::endl;
}
std::cout << std::endl;
for(int i =0; i < nY; i++){
for(int j = 0; j < nZ; j++)
{
B[j + i*nY] = rand()/(float)RAND_MAX * 10 + 1 ;
std::cout << " B[" + std::to_string(j + i * nY) + "] = " ;
std::cout << B[j + i * nY] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
//fill Matrix C with random values
for(int i =0; i < nX; i++){
for(int j = 0; j < nZ; j++)
{
C[j + i*nX] = rand()/(float)RAND_MAX * 10 + 1 ;
std::cout << " C[" + std::to_string(j + i * nX) + "] = " ;
std::cout << B[j + i * nX] << " ";
}
std::cout << std::endl;
}
// Create data/memory buffers, and equeue them
cl::Buffer bufA(context, CL_MEM_READ_ONLY, sizeof(float) * nX * nY);
cl::Buffer bufB(context, CL_MEM_READ_ONLY, sizeof(float) * nY * nZ);
cl::Buffer bufC(context, CL_MEM_READ_WRITE, sizeof(float) * nX * nZ);
queue.enqueueWriteBuffer(bufA, CL_TRUE, 0, sizeof(float) * nX * nY, A);
queue.enqueueWriteBuffer(bufA, CL_TRUE, 0, sizeof(float) * nY * nZ, B);
// Select kernel, pass arguments
cl::Kernel kernel = cl::Kernel(program, "mCrossProd");
kernel.setArg(0, nX);
kernel.setArg(1, nY);
kernel.setArg(2, nZ);
kernel.setArg(3, bufA);
kernel.setArg(4, bufB);
kernel.setArg(5, bufC);
// Execute the kernel
queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(nX, nY), cl::NDRange(16,16));
// Retrieive results from global memory
queue.enqueueReadBuffer(bufC, CL_TRUE,0, sizeof(float) * nX * nZ, C);
queue.finish();
fs.close();
std::cout << "\nThe solution is" << std::endl;
for(int i = 0; i < nX; i++){
for(int j = 0; j < nZ; j++)
{
std::cout << "C[" + std::to_string(j*nZ+i) + "] = " ;
std::cout << C[j*nZ+i] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
This is my Kernel function:
__kernel void mCrossProd(const int nX, const int nY, const int nZ, __global float* A, __global float* B, __global float* C) {
int i = get_global_id(0);
int j = get_global_id(1);
for(int k = 0; k < nX; k++){
C[j*nY+i] += A[j*nX+k] * B[k*nY+i];
}
}
Aucun commentaire:
Enregistrer un commentaire