2012-12-13 27 views
5

Tôi mới với CUDA và không thực sự quen thuộc với C. Tôi đã viết một dll để thực hiện các phương pháp CUDA (FFT) vào C# programm của tôi. Tôi đã sửa lỗi trước dll như một ứng dụng giao diện điều khiển để đảm bảo nó hoạt động đúng, và sau đó đã xây dựng nó như một dll. Vì vậy, vấn đề của tôi là tại cuộc gọi đầu tiên (cufftPlan1d()) của dll của tôi gây ra một AccessViolationException. Tôi đã tra cứu blog này và các kết quả khác của google cho đến nay, nhưng không có gì. Tôi sử dụng mã không an toàn để xử lý con trỏ và phân bổ bộ nhớ với phương thức Marshal.AllocHGlobal(), vì vậy tôi không thực sự thấy vấn đề ở đâu. Đây là mã của tôi về dll của tôi và gọi C# lớp:Làm cách nào để tránh ngoại lệ vi phạm truy cập khi gọi một Dll CUDA?

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); 
} 

và lớp wrapper:

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); 
    } 

Cảm ơn trước, Szabolcs

+0

'extern "C"' và 'CallingConvention.StdCall'? Bạn đã thử 'CallingConvention.Cdecl' chưa? –

+0

Tôi vừa thử nó, nhưng vấn đề vẫn xảy ra. Cảm ơn, Szabolcs –

+0

Tôi đã giải quyết nó, tôi chỉ quên phân bổ mamory cho kế hoạch, vì vậy thêm "plan = (int *) Marshal.AllocHGlobal (sizeof (int));" giải quyết vấn đề của tôi. –

Trả lời

1

plan xuất hiện không bao giờ được phân bổ.

Các vấn đề liên quan