5

私はCUDAが初めてで、Cにもあまり慣れていません。C# プログラムに CUDA メソッド (FFT) を実装するための Dll を作成しました。最初に dll をコンソール アプリケーションとしてデバッグして正しく動作することを確認し、それから dll としてビルドしました。したがって、私の問題は、dll の最初の呼び出し (cufftPlan1d()) で AccessViolationException が発生することです。これまでにこのブログや他の Google の結果を調べましたが、何もありません。安全でないコードを使用してポインターを処理し、Marshal.AllocHGlobal() メソッドでメモリを割り当てているため、どこに問題があるのか​​ わかりません。私のdllと呼び出し元のC#クラスのコードは次のとおりです。

DLL:

extern "C" __declspec(dllexport)
unsigned int fftPlan(unsigned int* plan, int signal_size, int batch)
{
    if(cufftPlan1d(plan, signal_size, CUFFT_D2Z, batch) != CUFFT_SUCCESS) return 0;
    return 1;
}

extern "C" __declspec(dllexport)
int allocateMemory(double** signalGPU, cufftDoubleComplex** signalFft, int size)
{
    if(cudaMalloc(signalGPU, size) != cudaSuccess) return 0;
    if(cudaMalloc(signalFft, size+16) != cudaSuccess) return 0;
    return 1;
}

extern "C" __declspec(dllexport)
int fftCaller(unsigned int* plan, const double* real, double* realGPU,             cufftDoubleComplex* signalFft, cufftDoubleComplex* signalFftGPU, int size)
{
    cufftDoubleReal *idata=(cufftDoubleReal*)realGPU;
    if(cudaMemcpy(idata, real, size, cudaMemcpyHostToDevice) != cudaSuccess) return 0;
    if(cufftExecD2Z(*plan, idata, signalFftGPU) != CUFFT_SUCCESS) return 0;
    if(cudaMemcpy(signalFft, signalFftGPU, size+16, cudaMemcpyDeviceToHost) !=    cudaSuccess) return 0;
    return 1;
}

extern "C" __declspec(dllexport)
void cudaClean(void* GPUPtr)
{
    cudaFree(GPUPtr);
}

そしてラッパークラス:

unsafe public class CudaFft
    public struct cufftDoubleComplex
    {
            public double x;
            public double y;
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int fftPlan(int* plan, int signal_size, int batch);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int allocateMemory(double** signalGPU, cufftDoubleComplex** signalFftGPU, int size);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int fftcaller(int* plan, double* signal, double* signalGPU, cufftDoubleComplex* signalFft, cufftDoubleComplex* signalFftGPU, int size);

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    unsafe public delegate int cudaclean(void* GPUPtr);

    public static int pDll, a;
    //static IntPtr signal, signalFft;
    unsafe static int* plan;
    unsafe static double* signal;
    unsafe static double** signalGPU;
    unsafe static int signal_size;
    unsafe static cufftDoubleComplex* signalFft;
    unsafe static cufftDoubleComplex** signalFftGPU;

    unsafe public static int Plan(int* plan, int signal_size, int batch)
    {
        IntPtr pAddressOfFunctionToCall = DllImport.GetProcAddress(pDll, "fftPlan");


        fftPlan fftplan = (fftPlan)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(fftPlan));
        return fftplan(plan, signal_size, batch); //THIS LINE CAUSES THE EXCEPTION 
    }  
    (...) //some irrelevant code here
    unsafe public CudaFft(int signal_length) //constructor
    {
        pDll = DllImport.LoadLibrary("d:\\CudaFft.dll");
        a = DllImport.GetLastError();
        signal_size = signal_length;
        signal = (double*)Marshal.AllocHGlobal(signal_size * 8).ToPointer();
        signalFft = (cufftDoubleComplex*)Marshal.AllocHGlobal((signal_size / 2 + 1) * 16).ToPointer();
        CudaFft.Plan(plan, signal_length, 1);
        CudaFft.allocMemory(signalGPU, signalFftGPU, signal_size);
    }

前もって感謝します、Szabolcs

4

1 に答える 1

1

plan割り当てられていないようです。

于 2012-12-31T17:01:50.147 に答える