代码之家  ›  专栏  ›  技术社区  ›  mrei

参数超过256字节的CUDA内核调用的想法

  •  4
  • mrei  · 技术社区  · 11 年前

    我有几个结构的总和超过了允许作为内核调用中的参数传递的256字节大小。

    这两个结构都已分配并复制到设备全局内存中。

    1) 如何在这些结构的同一内核中使用而不作为参数传递?

    更多详情。另外,这些结构可以作为参数传递。例如,在不同的内核中。但是:

    2) 如何在同一内核中使用这两种结构?

    2 回复  |  直到 11 年前
        1
  •  3
  •   Community CDub    5 年前

    如果您的数据结构已经在全局内存中,那么您可以只传入一个指针作为内核参数。

    另一方面,对于计算能力为2.x或更高的设备,内核参数的限制为4KB:

    全球的 将函数参数传递给设备:

    • 并且在计算能力1.x,
    • 并且在计算能力为2.x或更高的设备上限制为4KB。

    装置 全球的 函数不能有可变数量的参数。

    (参考。 http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#function-parameters )

        2
  •  2
  •   Maja Piechotka    11 年前

    正如罗伯特·克罗维拉(Robert Crovella)在评论中所建议的那样,你应该能够传递一个指向这些领域的指针。 我在opencl也遇到过类似的问题。。 这是我实现结构的方式:

    (我的内核和主机函数是opencl的,语法可能是你的问题……但上下文是一样的。!)

    以下两个在我的“Mapper.c”中定义-->主机功能

    typedef struct data
    {
      double dattr[10];
      int d_id;
      int bestCent;
    }Data;
    
    
    typedef struct cent
    {
      double cattr[5];
      int c_id;
    }Cent;
    
    Data *dataNode;
    Cent *centNode;
    

    在设备的全局内存上分配内存后,我传输了数据。 我不得不在我的另一个内核函数中重新定义结构定义,如下所示:

    映射.cl:

    #pragma OPENCL EXTENSION cl_khr_fp64 : enable
    typedef struct data
    {
      double dattr[10];
      int d_id;
      int bestCent;
    }Data;
    
    
    typedef struct cent
    {
      double cattr[5];
      int c_id;
    }Cent;
    
    __kernel void mapper(__global int *keyMobj, __global int *valueMobj,__global Data *dataMobj,__global Cent *centMobj)
    {
        int i= get_global_id(0);
        int j,k,color=0;
        double dmin=1000000.0, dx;
        for(j=0; j<2; j++)      //here 2 is number of centroids considered
         {
            dx = 0.0;
            for(k=0; k<2; k++)
            {
               dx+= ((centMobj[j].cattr[k])-(dataMobj[i].dattr[k])) * ((centMobj[j].cattr[k])-(dataMobj[i].dattr[k]));
            }  
            if(dx<dmin)            
            {  color = j;   
               dmin = dx;
            }
         }  
         keyMobj[i] = color;
         valueMobj[i] = dataMobj[i].d_id;
    
    }
    

    你可以看到我只传递了指向这些区域的指针。。即keyMobj和valueMobj。

    kernel = clCreateKernel(program, "mapper", &ret);
    ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&keyMobj);
    ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&valueMobj);
    ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&dataMobj);
    ret = clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)&centMobj);
    

    上面的代码行属于主机端函数(mapper.c),它创建内核函数(maper.cl)..,接下来的4行(clSetKernelArg..)将参数传递给内核函数。