Ich arbeite gerade an einem Programm, das eine 2D-FFT implementieren muss, (für Kreuzkorrelation). Ich habe eine 1D FFT mit CUDA gemacht, die mir die richtigen Ergebnisse lieferte, ich versuche jetzt eine 2D Version zu implementieren. Mit wenigen Beispielen und Dokumentation online finde ich es schwierig herauszufinden, was der Fehler ist.CUDA cammt 2D Beispiel
Bisher habe ich nur das cuFFT-Handbuch verwendet.
Wie auch immer, ich habe zwei 5x5 Arrays erstellt und sie mit 1 gefüllt. Ich habe sie auf den GPU-Speicher kopiert und die Vorwärts-FFT gemacht, sie multipliziert und dann auf dem Ergebnis ift gemacht. Dies ergibt ein 5x5-Array mit Werten von 650. Ich würde erwarten, ein Gleichstromsignal mit dem Wert 25 in nur einem Schlitz in dem 5x5-Array zu erhalten. Stattdessen bekomme ich 650 im gesamten Array.
Außerdem darf ich den Wert des Signals nicht ausdrucken, nachdem es auf den GPU-Speicher kopiert wurde. Schreiben
cout << d_signal[1].x << endl;
Gibt mir eine Zugriffsverletzung. Ich habe das gleiche in anderen Cuda-Programmen gemacht, wo dies kein Problem war. Hat es etwas damit zu tun, wie die komplexe Variable funktioniert, oder handelt es sich um menschliches Versagen?
Wenn jemand irgendwelche Hinweise hat, was falsch läuft, würde ich es sehr schätzen. Hier ist der Code
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <helper_functions.h>
#include <helper_cuda.h>
#include <ctime>
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <cufft.h>
#include <fstream>
using namespace std;
typedef float2 Complex;
__global__ void ComplexMUL(Complex *a, Complex *b)
{
int i = threadIdx.x;
a[i].x = a[i].x * b[i].x - a[i].y*b[i].y;
a[i].y = a[i].x * b[i].y + a[i].y*b[i].x;
}
int main()
{
int N = 5;
int SIZE = N*N;
Complex *fg = new Complex[SIZE];
for (int i = 0; i < SIZE; i++){
fg[i].x = 1;
fg[i].y = 0;
}
Complex *fig = new Complex[SIZE];
for (int i = 0; i < SIZE; i++){
fig[i].x = 1; //
fig[i].y = 0;
}
for (int i = 0; i < 24; i=i+5)
{
cout << fg[i].x << " " << fg[i + 1].x << " " << fg[i + 2].x << " " << fg[i + 3].x << " " << fg[i + 4].x << endl;
}
cout << "----------------" << endl;
for (int i = 0; i < 24; i = i + 5)
{
cout << fig[i].x << " " << fig[i + 1].x << " " << fig[i + 2].x << " " << fig[i + 3].x << " " << fig[i + 4].x << endl;
}
cout << "----------------" << endl;
int mem_size = sizeof(Complex)* SIZE;
cufftComplex *d_signal;
checkCudaErrors(cudaMalloc((void **) &d_signal, mem_size));
checkCudaErrors(cudaMemcpy(d_signal, fg, mem_size, cudaMemcpyHostToDevice));
cufftComplex *d_filter_kernel;
checkCudaErrors(cudaMalloc((void **)&d_filter_kernel, mem_size));
checkCudaErrors(cudaMemcpy(d_filter_kernel, fig, mem_size, cudaMemcpyHostToDevice));
// cout << d_signal[1].x << endl;
// CUFFT plan
cufftHandle plan;
cufftPlan2d(&plan, N, N, CUFFT_C2C);
// Transform signal and filter
printf("Transforming signal cufftExecR2C\n");
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_FORWARD);
cufftExecC2C(plan, (cufftComplex *)d_filter_kernel, (cufftComplex *)d_filter_kernel, CUFFT_FORWARD);
printf("Launching Complex multiplication<<< >>>\n");
ComplexMUL <<< 32, 256 >> >(d_signal, d_filter_kernel);
// Transform signal back
printf("Transforming signal back cufftExecC2C\n");
cufftExecC2C(plan, (cufftComplex *)d_signal, (cufftComplex *)d_signal, CUFFT_INVERSE);
Complex *result = new Complex[SIZE];
cudaMemcpy(result, d_signal, sizeof(Complex)*SIZE, cudaMemcpyDeviceToHost);
for (int i = 0; i < SIZE; i=i+5)
{
cout << result[i].x << " " << result[i + 1].x << " " << result[i + 2].x << " " << result[i + 3].x << " " << result[i + 4].x << endl;
}
delete result, fg, fig;
cufftDestroy(plan);
//cufftDestroy(plan2);
cudaFree(d_signal);
cudaFree(d_filter_kernel);
}
Der obige Code den folgenden Terminal-Ausgabe gibt:
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
----------------
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
----------------
Transforming signal cufftExecR2C
Launching Complex multiplication<<< >>>
Transforming signal back cufftExecC2C
625 625 625 625 625
625 625 625 625 625
625 625 625 625 625
625 625 625 625 625
625 625 625 625 625
Der Code, den Sie gepostet haben, ist unvollständig und kann nicht kompiliert werden. Könnten Sie das bitte korrigieren? Es ist sehr schwer, Ihnen zu sagen, was falsch sein könnte, ohne den Code zu kompilieren und auszuführen, und ich kann das jetzt nicht tun. – talonmies
Sicher, ich hatte einen unkommentierten Abschnitt, den ich nicht hinzufügen wollte. Ich habe es entfernt und alles jetzt in meinem Beitrag bearbeitet. – LukaK