我正在尝试学习一些cuda,我无法弄清楚如何解决以下情况:
考虑两组G1和G2:
任务是对每个组中的向量a和b求和并返回一个已排序的c向量,所以:
G1 will give c1 = {10,9,14) => (sort algorithm) => c1 = {9,10,14}
G2 will give c2 = {11,5,10) => (sort algorithm) => c1 = {5,10,11}
如果我有一个拥有92个cuda核心的gforce,我想创建92个G组并将所有总和并行,所以
core 1-> G1 -> c1 = a1 + b1 -> sort c1 -> return c1
core 2-> G2 -> c2 = a2 + b2 -> sort c2 -> return c2
....
core 92-> G92 -> c92 = a92 + b92 -> sort c92 -> return c92
下面的内核并行地将两个向量相加并返回另一个向量:
__global__ void add( int*a, int*b, int*c )
{
c[blockIdx.x] = a[blockIdx.x] + b[blockIdx.x];
}
我无法理解的是如何让内核处理整个向量而不仅仅是一个 向量的元素,它们返回一个完整的向量。
这样的事情:
__global__ void add( int*a, int*b, int*c, int size )
{
for (int i = 0; i < size ; i++)
c[i] = a[i] + b[i];
//sort c
}
有人可以解释我是否有可能以及怎么做?
答案 0 :(得分:1)
92个3-D向量可以看作1 276-D向量,然后你可以使用单向量添加内核来添加它们。推动将是一种更简单的方法。
如果您的矢量只是3-D,您可以使用顺序方法在计算后立即对元素进行排序。
如果您的向量具有更高的维度,则可以考虑使用cub::BlockRadixSort
。我们的想法是首先为每个线程/块添加一个向量,然后使用cub::BlockRadixSort
对块内的向量进行排序。
http://nvlabs.github.io/cub/classcub_1_1_block_radix_sort.html
答案 1 :(得分:1)
这是一个小例子。它使用cudaMallocPitch
和cudaMemcpy2D
。我希望它能为您提供解决特定问题的指导原则:
#include<stdio.h>
#include<cuda.h>
#include<cuda_runtime.h>
#include<device_launch_parameters.h>
#include<conio.h>
#define N 92
#define M 3
__global__ void test_access(float** d_a,float** d_b,float** d_c,size_t pitch1,size_t pitch2,size_t pitch3)
{
int idx = threadIdx.x;
float* row_a = (float*)((char*)d_a + idx*pitch1);
float* row_b = (float*)((char*)d_b + idx*pitch2);
float* row_c = (float*)((char*)d_c + idx*pitch3);
for (int i=0; i<M; i++) row_c[i] = row_a[i] + row_b[i];
printf("row %i column 0 value %f \n",idx,row_c[0]);
printf("row %i column 1 value %f \n",idx,row_c[1]);
printf("row %i column 2 value %f \n",idx,row_c[2]);
}
/********/
/* MAIN */
/********/
int main()
{
float a[N][M], b[N][M], c[N][M];
float **d_a, **d_b, **d_c;
size_t pitch1,pitch2,pitch3;
cudaMallocPitch(&d_a,&pitch1,M*sizeof(float),N);
cudaMallocPitch(&d_b,&pitch2,M*sizeof(float),N);
cudaMallocPitch(&d_c,&pitch3,M*sizeof(float),N);
for (int i=0; i<N; i++)
for (int j=0; j<M; j++) {
a[i][j] = i*j;
b[i][j] = -i*j+1;
}
cudaMemcpy2D(d_a,pitch1,a,M*sizeof(float),M*sizeof(float),N,cudaMemcpyHostToDevice);
cudaMemcpy2D(d_b,pitch2,b,M*sizeof(float),M*sizeof(float),N,cudaMemcpyHostToDevice);
test_access<<<1,N>>>(d_a,d_b,d_c,pitch1,pitch2,pitch3);
cudaMemcpy2D(c,M*sizeof(float),d_c,pitch3,M*sizeof(float),N,cudaMemcpyDeviceToHost);
for (int i=0; i<N; i++)
for (int j=0; j<M; j++) printf("row %i column %i value %f\n",i,j,c[i][j]);
getch();
return 0;
}