2013-05-08 75 views
1

我写下面的代码在CUDA发出带有映射的2D到1D阵列中的CUDA

__global__ void test(int *b_dev) 
{ 
    int index=blockDim.x*blockIdx.x+threadIdx.x; 
    b_dev[index]=1; 
} 

int main() 
{ 
    int **a; 
    int *b_dev; 
    a=(int**)malloc(sizeof(int*)*4); 
    for(i=0;i<4;i++) 
    a[i]=(int*)malloc(sizeof(int)*4); 

    //initialise array a here with 0 

    cudaMalloc((void**)&b_dev,sizeof(int)*16); 
    cudaMemcpy(b_dev,a,sizeof(int)*16,cudaMemcpyHostToDevice); 
    test<<<4,4>>>(dev_b); 
    cudaMemcpy(a,b_dev,sizeof(int)*16,cudaMemcpyDeviceToHost); 
    for(i=0;i<4;i++) 
    for(j=0;j<4;j++) 
     cout<<a[i][j]; 
    } 

我在宿主这2D阵列我弄平一维阵列和处理在GPU但是这个代码产生分割当我尝试在主机中打印数组a时出错,但是当我在内核中注释掉b_dev[valindex]=1行时,它会打印带有初始化零的数组a。 visual C++调试器指示

CXX0030:无法评估错误表达式。

好心请带我走

+1

您错误地将数据复制到和从GPU。以这种方式分配的2D阵列不能通过使用单个存储器副本直接复制。另外,不应该指定的语句是'b_dev [index] = 1;'? – sgarizvi 2013-05-08 18:08:25

+0

雅这是b_dev [指数] = 1.这是一个错字..你可以指点我如何可以实现这个 – Stormvirux 2013-05-08 18:18:37

+0

还是有任何其他的手段? – Stormvirux 2013-05-08 18:30:34

回答

2

当你在你做的方式分配数组的数组,你有没有机制保障,每个阵列会在内存中是连续的。更具体地说,在您的示例中,您有一个int**阵列a,它由4个int*阵列组成,a[0],a[1],a[2]a[3]。在每个数组a [i](其中i是您的二维数组中的数组索引)内存将是连续的。然而,没有保证阵列a[i]的存储器和阵列a[i+1]的存储器是。也就是说,在您拨打malloc的电话之间,分配的内存可以来自您的免费商店中的任何地方,并且它们是否连续是否达到malloc。 (顺便说一句,如果你在堆栈中分配内存,那么它将是连续的,或者作为一维数组在堆上)。

因此,您不能期待1个致电cudaMemcpy复制您的所有阵列。相反,您必须为每个1D阵列执行多个cudaMemcpy调用以复制所有这些数组,并在目标指针上进行指针运算,以确保将它们复制到正确的位置。

当连续的二维数据时,您可以使用cudaMemcpy2D,其中有签名:当使用

cudaError_t cudaMemcpy2D (void* dst, size_t dpitch, const void* src, size_t spitch, size_t width, size_t height, cudaMemcpyKind kind) 

,如果你知道的源和目标间距长度,你可以利用这一点,并采取沥青考虑数据。但是,这个函数假定数据维度是连续的,所以它不会帮助你。当然,最简单的解决方案是选择一个数组维度协议并坚持使用它(例如,要么所有的内存都是2D或全部为1D,但不要混合它们,除非有令人信服的理由)。我

而且会是失职,如果我没有离开的链接relevant CUDA documentation about cudaMemcpy