2

我想做一个二维数组的一维 FFT(比如只沿着列)。我将 vs2010/C# 与 managedcuda 一起使用。

我遇到了一些问题:

  1. 如何制作二维 CudaDeviceVariable?我试过了:

            int n1 = 10;
            int n2 = 2;
            int batch = 1;
            //SizeT test;
    
            CudaDeviceVariable<double>[,] datad;
            datad = new CudaDeviceVariable<double>[n1, n2]; 
    

datad不是一个CudaDeviceVariable。它现在是一个普通的二维数组。所以我无法在设备中分配内存。喜欢:

    double[,] data11 = new double[,] {{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }};

    datad.CopyToDevice(data11);//Error??

这是一个错误,因为CopyToDevice它不是System.Array. 如果我做datad一个n1*n2 CudaDeviceVariable,错误仍然存​​在,因为CopyToDevice作为double[]输入参数,而不是[,].上述方法适用于一维数组。

2.是否可以对大型一维阵列进行一维 FFT。例如,我从data11. 然后在 10 个元素中执行 FFT?CudaFFTPlanMany有一些选项,但我不是 100% 清楚如何使用它们或它们对我有什么用处。

如果我不清楚,请询问更多细节。非常感谢。

编辑:我得到了更多细节,问题仍然存在,但我制作了 1-D 数组data11,然后分批执行了 2 批大小为 10 的 fft。它给了我想要的结果。语法是:

            CudaFFTPlanMany planm;
            planm = new CudaFFTPlanMany(1, n, 1,cufftType.D2Z);

干杯

4

1 回答 1

3

在设计 managedCuda 时,我决定反对多维数组支持,因为我找不到任何保证 CLR 不允许引入一些线距。在与 p/invoke 互操作时,多维数组的处理方式也不同。

所以唯一支持的数组是简单的一维数组,类似于 C/C++ 中的数组。因此,二维数组只是一个大小为 的大型一维数组width * height,并且索引的计算方式类似于y * width + x

在设备端,您可以使用CudaPitchedDeviceVariable<double>它为每行引入一些额外的字节,以便在正确对齐的内存地址上开始每个阵列行 -> 另请参见 CUDA 编程指南,例如第 73 页。在主机端,这些阵列仍然表示为简单的一维阵列,没有任何额外的间距。

关于 cufft 的第二个问题:是的,CudaFFTPlanMany使用批处理是可行的方法,managedCuda 实现的接口与原始 cufft API 完全相同,有关更多详细信息,请参阅 CUFFT 用户指南中的第 2 章。对于给定的示例,您的计划如下所示:

int[] n = new int[] { 10 };
plan = new CudaFFTPlanMany(1, n, 2, cufftType.D2Z);

2D 数组的特殊提示:包含维度信息的数组,例如inembedorn是一种“逆”:[height, width]而不是[width, height]...

于 2013-05-24T15:18:12.057 回答