1.opencv的基本流程
获取平台ID->获取设备ID->创建上下文->创建队列->读取源码->编译源码->创建核函数->设置变量->运行函数
2.cpp基本代码:
m_cl_errNum = clGetPlatformIDs(1, &m_cl_platform, NULL);
m_cl_errNum = clGetDeviceIDs(
m_cl_platform,
CL_DEVICE_TYPE_ALL,
1,
&m_cl_device,
NULL);
cl_context_properties cps[3] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)m_cl_platform, 0
};
m_cl_ctx = clCreateContext(
cps,
1,
&m_cl_device,
NULL,
NULL,
&m_cl_errNum);
m_cl_myqueue = clCreateCommandQueue(
m_cl_ctx,
m_cl_device,
0,
&m_cl_errNum);
QFile file(":cl.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug()<<"error";
return;
}else{
qDebug()<<"success";
}
QString filestr;
while (!file.atEnd()) {
filestr.append(file.readLine());
}
// qDebug()<<filestr;
std::string srcStr= filestr.toStdString();
m_cl_myprog = clCreateProgramWithSource(
m_cl_ctx,
1,
(const char**)&srcStr,
NULL,
&m_cl_errNum);
if(m_cl_errNum != CL_SUCCESS){
qDebug("编译失败");
}
m_cl_errNum = clBuildProgram(m_cl_myprog, 0, NULL, NULL, NULL, NULL);
if (m_cl_errNum != CL_SUCCESS) {
qDebug("clBuildProgram fail.\n");
exit(1);
}
mykernel = clCreateKernel(
m_cl_myprog,
"add",
&m_cl_errNum);
cl_mem memObjects[3] = { 0, 0, 0 };
float* a = new float[ARRAY_SIZE];
float* b = new float[ARRAY_SIZE];
float* result = new float[ARRAY_SIZE];
for (int i = 0; i < ARRAY_SIZE; i++) {
a[i] = (float)i;
b[i] = (float)i;
}
memObjects[0] = clCreateBuffer(m_cl_ctx, CL_MEM_READ_ONLY | // 2. 创建内存对象
CL_MEM_COPY_HOST_PTR,
sizeof(float) * ARRAY_SIZE,
a, NULL);
memObjects[1] = clCreateBuffer(m_cl_ctx, CL_MEM_READ_ONLY |
CL_MEM_COPY_HOST_PTR,
sizeof(float) * ARRAY_SIZE,
b, NULL);
memObjects[2] = clCreateBuffer(m_cl_ctx, CL_MEM_READ_WRITE |
CL_MEM_COPY_HOST_PTR,
sizeof(float) * ARRAY_SIZE,
result, NULL);
if (memObjects[0] == NULL || memObjects[1] == NULL ||
memObjects[2] == NULL) {
qDebug("Error in clCreateBuffer.\n");
exit(1);
}
size_t globalws[2] = { (size_t)1 , (size_t)ARRAY_SIZE};
// size_t localws[2] = { (size_t)width/200, (size_t)height/100 };
size_t localws[2] = { (size_t)1, (size_t)1 };
m_cl_errNum = clSetKernelArg(mykernel, 0, sizeof(cl_mem), &memObjects[0]); // 1. 设置内核参数
m_cl_errNum |= clSetKernelArg(mykernel, 1, sizeof(cl_mem), &memObjects[1]);
m_cl_errNum |= clSetKernelArg(mykernel, 2, sizeof(cl_mem), &memObjects[2]);
if (m_cl_errNum != CL_SUCCESS) {
qDebug("Error in clSetKernelArg.\n");
exit(1);
}
m_cl_errNum = clEnqueueNDRangeKernel(
m_cl_myqueue,
mykernel,
2,
NULL,
globalws,
localws,
0,
NULL,
NULL);
if (m_cl_errNum != CL_SUCCESS) {
qDebug("mykernel is fail is %d.\n",m_cl_errNum);
exit(1);
}
m_cl_errNum = clEnqueueReadBuffer(m_cl_myqueue, memObjects[2], // 3. 读取运算结果到主机
CL_TRUE, 0,
ARRAY_SIZE * sizeof(float), result,
0, NULL, NULL);
if (m_cl_errNum != CL_SUCCESS) {
qDebug("Error in clEnqueueReadBuffer.\n");
exit(1);
}
for (int i = 0; i < ARRAY_SIZE; i++)
qDebug("a[%d] * b[%d] = %f\n", i, i, result[i]);
这里需要注意的是,为了更好的读取源码,我将opencl代码的文件保存成了txt文件格式,将它当成txt文件读取。
2.核函数代码:
__kernel void add(__global const float* a,
__global const float* b,
__global float* result)
{
const int iy = get_global_id(1);
result[iy] = a[iy] * b[iy];
}
3.运行结果
源工程代码:https://download.csdn.net/download/qq_40621774/16767408