Ich bin neu mit CUDA und nicht wirklich vertraut mit C entweder. Ich schrieb eine DLL, um CUDA-Methoden (FFT) in mein C# -Programm zu implementieren. Ich debuggte zuerst die DLL als eine Konsolenanwendung, um sicherzustellen, dass es richtig funktioniert, und baute es dann als DLL auf. Also mein Problem ist, dass beim ersten Aufruf (cammttPlan1d()) meiner DLL eine AccessViolationException verursacht. Ich habe schon mal diesen Blog und andere Google-Ergebnisse nachgelesen, aber nichts. Ich verwende unsafe Code, um Zeiger zu behandeln und Speicher mit Marshal.AllocHGlobal() -Methode zuzuweisen, so sehe ich nicht wirklich, wo das Problem ist. Hier ist mein Code meiner dll und die anrufende C# Klasse:Wie vermeide ich Zugriffsverletzung Ausnahme Aufruf einer CUDA Dll?
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);
}
und die Wrapper-Klasse:
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);
}
Vielen Dank im Voraus, Szabolcs
'extern' C 'und' CallingConvention.StdCall '? Haben Sie CallingConvention.Cdecl versucht? –
Ich habe es gerade versucht, aber das Problem tritt immer noch auf. Danke, Szabolcs –
Ich löste es, ich vergesse nur, mamory für den Plan zuzuweisen, also fügte "plan = (int *) Marshal.AllocHGlobal (sizeof (int));" löst mein Problem. –