CUDA数组/表面内存

3
调用函数test后,我打印dtr1数组。我期望所有元素都是100,但实际上不是。为什么会这样?
#include "ImageUtil2D.h"
#define W 10
#define H 10
#define MAX 100000
#define No_THREADS 10
surface<void,2> surfD;

__global__ void test()
{
for(int i=0;i<W;i++)
    for(int j=0;j<H;j++)
    {
        float a=100;
        surf2Dwrite(a, surfD, i,j, cudaBoundaryModeTrap);
    }
}

int main()
{
int *image = new int[W*H];
float *dtr = new float[W*H];
ImageUtil2D::InitImg(image, dtr, W, H);
const size_t sizef = size_t(W*H)*sizeof(float);

cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 0, 0, 0, cudaChannelFormatKindFloat);
cudaArray* cuArrD;
cudaMallocArray(&cuArrD, &channelDesc, W*H, 0, cudaArraySurfaceLoadStore);
//cudaMemcpyToArray(cuArrD, 0, 0, dtr, sizef, cudaMemcpyHostToDevice);
cudaBindSurfaceToArray(surfD, cuArrD);

test<<<1, 1>>>();

float *dtr1=new float[W*H];
cudaMemcpyFromArray(&dtr1, cuArrD, 0, 0, sizef, cudaMemcpyDeviceToHost );
ImageUtil2D::Print(dtr1);
return 0;
}

在cuda api调用周围添加错误处理代码,并记录它在哪里以及如何失败。 - fabrizioM
2个回答

5

CUDA C编程指南3.2节:3.2.4.2.2 表面绑定

与纹理内存不同,表面内存使用字节寻址。这意味着,通过纹理函数访问纹理元素所使用的x坐标需要乘以元素的字节大小,才能通过表面函数访问相同的元素。

试一下:

surf2Dwrite(a, surfD, i * 4, j, cudaBoundaryModeTrap);

希望这可以帮到你。
建议:阅读有关表面内存的整个章节,否则您将在意料之外遇到读/写一致性问题。;)

哦,对不起,我几乎确定了。我进行了一个快速测试,发现cudaMemcpyFromArray(&dtr1, cuArrD, 0, 0, sizef, cudaMemcpyDeviceToHost )存在一些奇怪的问题。 - pQB

1

pQB在他自己的回答中指出的另一个问题是

cudaMemcpyFromArray(&dtr1, cuArrD, 0, 0, sizef, cudaMemcpyDeviceToHost );

可以通过将上面的行更改为来修复。
cudaMemcpyFromArray(dtr1, cuArrD, 0, 0, sizef, cudaMemcpyDeviceToHost );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接