Я изо всех сил пытался целый день, пытаясь сделать правильный пример CUFFT правильно. Однако я столкнулся с небольшой проблемой, которую я не могу определить. В основном у меня есть линейный 2D-массив vx с координатами x и y. Тогда я просто вычислил вперед, а затем назад CUFFT (на месте), что просто. Затем я скопирую массив vx, нормализовать его по NX * NY, а затем отобразить.CUFFT | не может понять простой пример
#define NX 32
#define NY 32
#define LX (2*M_PI)
#define LY (2*M_PI)
float *x = new float[NX*NY];
float *y = new float[NX*NY];
float *vx = new float[NX*NY];
for(int j = 0; j < NY; j++){
for(int i = 0; i < NX; i++){
x[j*NX + i] = i * LX/NX;
y[j*NX + i] = j * LY/NY;
vx[j*NX + i] = cos(x[j*NX + i]);
}
}
float *d_vx;
CUDA_CHECK(cudaMalloc(&d_vx, NX*NY*sizeof(float)));
CUDA_CHECK(cudaMemcpy(d_vx, vx, NX*NY*sizeof(float), cudaMemcpyHostToDevice));
cufftHandle planr2c;
cufftHandle planc2r;
CUFFT_CHECK(cufftPlan2d(&planr2c, NY, NX, CUFFT_R2C));
CUFFT_CHECK(cufftPlan2d(&planc2r, NY, NX, CUFFT_C2R));
CUFFT_CHECK(cufftSetCompatibilityMode(planr2c, CUFFT_COMPATIBILITY_NATIVE));
CUFFT_CHECK(cufftSetCompatibilityMode(planc2r, CUFFT_COMPATIBILITY_NATIVE));
CUFFT_CHECK(cufftExecR2C(planr2c, (cufftReal *)d_vx, (cufftComplex *)d_vx));
CUFFT_CHECK(cufftExecC2R(planc2r, (cufftComplex *)d_vx, (cufftReal *)d_vx));
CUDA_CHECK(cudaMemcpy(vx, d_vx, NX*NY*sizeof(cufftReal), cudaMemcpyDeviceToHost));
for (int j = 0; j < NY; j++){
for (int i = 0; i < NX; i++){
printf("%.3f ", vx[j*NX + i]/(NX*NY));
}
printf("\n");
}
Когда ъх определяется как соз (х) или грех (х), она работает нормально, но при использовании греха (у) или соз (у), это дает мне обратно правильную функцию (грех или соз), но с половинной амплитудой (т. е. осциллируя между 0,5 и -0,5 вместо 1 и -1)! Заметим, что использование sin (2 * y) или cos (2 * y) (или sin (4 * y), cos (4 * y), ...) отлично работает. Есть идеи?
Почему ваша первая операция cudaMemcpy указывает cudaMemcpyDeviceToHost? Это не имеет смысла и не соответствует порядку указателей. Если ваш макрос CUDA_CHECK не вызывает ошибку, тогда что-то не так с вашим макросом. –
Извините, я не копировал/вставлял правильную строку, в моем коде смысл копии правильный. Я обновляю –
. Эта строка кода, которую вы ранее не могли быть в любом месте. Если эта строка кода отображается в другом месте вашего кода, это неверно. Кстати, SO ожидает, что вы предоставите код SSCCE.org для таких вопросов. –