OpenCL中整数的组合

时间:2014-01-02 19:31:49

标签: algorithm opencl

我有一堆载体(~500)。我需要找到OpenCL中所有向量组合的三重产品。在C ++中有很多combination algorithms(n个n),但我还没有找到任何针对GPU的实现。我在Cuda看到了不少parallel permutation algorithms,但我只是想知道是否存在任何可行的组合算法?

1 个答案:

答案 0 :(得分:0)

我需要在这里和那里猜测一下你的问题。

我想你有一个n(~500)向量的数组V.这些向量都具有相同的维数m(可能m = 3)。

你想要的是每3个向量v i ,v j ,v k 的组件明智乘积,其中i,j,k在{0,..,n-1}。

简单的三维示例:

result[idx].x = V[i].x * V[j].x * V[k].x;
result[idx].y = V[i].y * V[j].y * V[k].y;
result[idx].z = V[i].z * V[j].z * V[k].z;

现在也许你的矢量不是三维的,也许你不想要组件明智的产品,而是它的总和(如点积),但我相信你能够相应地调整代码。

这里真正的问题是如何计算所有可能的i,j,k和idx。正确的吗?

现在有了CUDA,你处于一个非常幸运的位置。您可以在网格中启动n * n * n个线程,因此可以免费获得i,j,k,而无需考虑计算组合或排列的方法。只需执行以下操作:

dim3 grid, block;
block.x = n;
block.y = 1;
block z = 1;
grid.x = n;
grid.y = n;
grid.z = 1;

compute_product_kernel<<<grid, block>>>( V, result );

这样你就可以启动n个n个n个线程的块。计算i,j,k变得微不足道,计算idx很容易:

__device__ void compute_product_kernel( myVector* V, myVector* result)
{
    int i = blockIdx.x;
    int j = blockIdx.y;
    int k = threadIdx.x;
    int idx = i * gridDim.y * blockDim.x + j * blockDim.x + k;
    ...
}

当然所有这一切都有效,因为你的n在CUDA的块和网格范围内。

但还有两件事:

  1. 也许你想要排列而不是组合。你可以通过跳过i,j,k中任意两个相同的每个组合来做到这一点。但我仍然建议保留它们,因为计算何时跳过可能比实际工作更昂贵。另外,我建议不要使用排列来为result节省内存,因为它可以节省1%的内存并使计算更加复杂。
  2. 你确定你有足够的记忆来实际做到这一点吗?存储结果需要n * n * n * m * sizeof(float)字节。 n = 500且m = 3,已经是1.5 GB。这真的是你在找什么?也许你的处理的下一步可以合并到计算中,这样就不需要存储中间结果。