QT+opencl(二)向量相乘

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值