Ben CUDA ile yeni ve C ya da çok aşina değilim. C# programm CUDA yöntemleri (FFT) uygulamak için bir Dll yazdı. İlk olarak dll'i bir konsol uygulaması olarak hatalı şekilde çalıştığından emin olmak için hata ayıkladı ve bunu bir dll olarak oluşturdum. Yani benim sorunum, ilk çağrımda (cufftPlan1d()) bir AccessViolationException neden olur. Şimdiye kadar bu blogu ve diğer google sonuçlarını inceledim, ama hiçbir şey. İşaretçileri işlemek ve Marshal.AllocHGlobal() yöntemiyle bellek ayırmak için güvenli olmayan kod kullanıyorum, bu yüzden sorunun nerede olduğunu anlamıyorum. İşte benim dll benim kodudur ve çağıran C# sınıfı:CUDA Dll'yi çağıran erişim ihlali istisnasından nasıl kaçınılırım?
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);
}
ve sarıcı sınıfı: önceden
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);
}
sayesinde Szabolcs
'extern' C '' ve 'CallingConvention.StdCall'? 'CallingConvention.Cdecl' programını denediniz mi? –
Sadece denedim ama sorun hala devam ediyor. Teşekkürler, Szabolcs –
Ben çözdüm, sadece plan için, bu yüzden "plan = (int *) Marshal.AllocHGlobal (sizeof (int)) ekleyerek, planlamak için memeli unutmayı;" Sorunumu çözer. –