OpenCL如何更改cl_mem的内存地址?

OpenCL如何更改cl_mem的内存地址?,opencl,matrix-multiplication,Opencl,Matrix Multiplication,我想做一个子矩阵乘法。假设我有一个函数: void MatMul(cl_mem A, cl_mem B, cl_mem C, int M, int K, int N) void ocl_push_array(cl_mem d_x, float *h_x, int n){ size_t data_size = sizeof(float)*n; err = clEnqueueWriteBuffer(queue, d_x, CL_TRUE, 0, data_size, h_x, 0,

我想做一个子矩阵乘法。假设我有一个函数:

void MatMul(cl_mem A, cl_mem B, cl_mem C, int M, int K, int N)
void ocl_push_array(cl_mem d_x, float *h_x, int n){
    size_t data_size = sizeof(float)*n;
    err = clEnqueueWriteBuffer(queue, d_x, CL_TRUE, 0, data_size, h_x, 0, NULL, NULL);
}
其中A是M*K,B是K*N,C是M*N,A、B、C都是通过主机内存
float*h_A、*h_B、*hC通过以下函数传递的行主一维数组:

void MatMul(cl_mem A, cl_mem B, cl_mem C, int M, int K, int N)
void ocl_push_array(cl_mem d_x, float *h_x, int n){
    size_t data_size = sizeof(float)*n;
    err = clEnqueueWriteBuffer(queue, d_x, CL_TRUE, 0, data_size, h_x, 0, NULL, NULL);
}

我想问一下:

如果我想做子矩阵乘法,比如说逐行切片:

    // cl_mem A, B, C;
    for(int x=0; x<M; x+=16)
    {
        cl_mem A_sub = (cl_mem)((float *)A+x*K);
        cl_mem C_sub = (cl_mem)((float *)C+x*N);
        if((M-x+1)>=16)
            MatMul(A_sub, B, C_sub, 16, K, N);
        else
            MatMul(A_sub, B, C_sub, M-x+1, K, N);
    }
尺寸为:

#define BLOCK_SIZE 16

size_t localWorkSize[] = {BLOCK_SIZE, BLOCK_SIZE};
size_t globalWorkSize[] = {shrRoundUp(BLOCK_SIZE, N), shrRoundUp(BLOCK_SIZE, M)};

size_t shrRoundUp(int group_size, int global_size) 
{
    int r = global_size % group_size;
    if(r == 0) 
    {
        return global_size;
    } else 
    {
        return global_size + group_size - r;
    }
}
该代码采用Nvidia OpenCL矩阵乘法示例。我的GPU是:英特尔(R)高清图形4600


谢谢

我认为你做不到:

cl_mem A_sub = (cl_mem)((float *)A+x*K);
因为cl_mem是OpenCL中的一个对象,它实际上是一个复杂的数据结构,而不仅仅是一个数据指针。它维护诸如指向实际内存的数据指针、对象引用、内存属性等信息。不同的运行时甚至可能有不同的cl_mem对象实现。这就是为什么会出现CL_INVALID_MEM_对象错误消息

要获得子矩阵的所需数据,可以执行以下操作之一:

  • 定义两个新的cl_mem对象,并使用一个单独的内核 复印工作

  • 使用clEnqueueCopyBuffer函数在主机上复制数据 代码域

  • 使用CL_MEM_ALLOC_HOST_PTR到内存缓冲区,然后使用 ClenqueueEmapBuffer将GPU内存映射到主机内存指针,并 然后使用映射的主机内存修改内存内容 指针,完成后,取消映射指针以返回GPU内存 到设备内存域