Hod*_*lcs 5 c# dll cuda unmanaged access-violation
我是CUDA的新手,也不熟悉C.我写了一个Dll来实现CUDA方法(FFT)到我的C#程序中.我首先调试dll作为控制台应用程序,以确保它正常工作,然后将其构建为dll.所以我的问题是,在我的dll的第一次调用(cufftPlan1d())导致AccessViolationException.到目前为止,我已经查了这个博客和其他谷歌搜索结果,但没有.我使用不安全的代码来处理指针并使用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);
}
Run Code Online (Sandbox Code Playgroud)
和包装类:
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);
}
Run Code Online (Sandbox Code Playgroud)
谢谢,Szabolcs