2013-05-24 9 views
1

Я хочу сделать 1-D FFT двухмерного массива (скажем только по столбцам). Я использую vs2010/C# с managedcuda.1D преобразование БПФ 2D-массива в CUDA

У меня возникли некоторые проблемы:

  1. Как я сделать 2-D CudaDeviceVariable? Я пробовал:

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

datad Но не CudaDeviceVariable. Теперь это обычный 2-мерный массив. Поэтому я не могу выделить память в устройстве. Как:

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 a n1*n2CudaDeviceVariable, ошибка все еще существует, потому что CopyToDevice принимает double[] как входной аргумент, а не [,]. Выше метод работает для 1-D массивов.

2.может ли это сделать 1-D БПФ большого массива. Например, я делаю одномерный массив от data11. А затем выполнить БПФ в частях из 10 элементов? CudaFFTPlanMany имеет некоторые варианты, но я не на 100% понятен, как их использовать или как они могут быть полезны для меня.

Пожалуйста, задайте более подробную информацию, если я не понимаю. Большое спасибо.

EDIT: у меня есть еще какие-то детали, вопрос остается, но я сделал 1-мерный массив data11, а затем выполнил пакетный fft в 2 партиях по размеру 10. Он дал мне результаты, что я хотел. Синтаксис:

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

Приветствие

ответ

2

при проектировании managedCuda я решил против многомерного массива поддержки, поскольку я не мог найти какую-либо гарантии, что CLR не позволило ввести некоторую высоту строки. Также многомерные массивы обрабатываются по-разному, когда речь идет о взаимодействии с p/invoke.

Таким образом, единственными поддерживаемыми массивами являются простые массивы 1D, аналогичные массивам в C/C++. Поэтому 2D-массив представляет собой только большой массив 1D с размером width * height, а индекс вычисляется как y * width + x.

На стороне устройства вы можете использовать CudaPitchedDeviceVariable<double>, который вводит некоторые дополнительные байты в каждую строку, чтобы начать каждую строку массива по правильно выровненному адресу памяти -> см. Также руководство по программированию CUDA, например. Страница 73. На стороне хоста эти массивы все еще представлены как простой массив 1D без какого-либо дополнительного тона.

Что касается вашего второго вопроса о cufft: да, CudaFFTPlanMany с партией - это путь, управляемый. Cuda реализует интерфейс точно так же, как оригинальный API cufft, более подробно см. Главу 2 в руководстве пользователя CUFFT. Для данного примера ваш план будет выглядеть следующим образом:

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

Специальная подсказка для 2D массивов: массивы, содержащие размерный данные как inembed или n являются своего рода «обратного»: [height, width] вместо [width, height] ...

+0

спасибо много. Я просто смутился о двухмерном массиве.И, кстати, это очень поможет, если есть несколько документированных примеров. Мне потребовалось некоторое время, чтобы разобраться, учитывая, что я не программист CUDA/C. Есть примеры, но мне пришлось копать в коде, чтобы увидеть реализации. Еще раз спасибо. Отличная работа. – Naresh

+0

Я знаю, управляемыйКуда пропускает некоторые простые сквозные примеры. Но для их создания мне понадобилось бы гораздо больше времени, чем в настоящее время ... Возможно, в будущем ;-) – kunzmi

Смежные вопросы