[solved] CUDA DLL import in C#

UPD 09.10.2013
Hi everyone!
After compiling CUDA project in VS 2012 (Cuda 5.5, x86, w/o ATL, w/o CLR) I have a problem importing dll-file in a C# project.

cudalib1.cuh

#pragma once

#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <thrust\device_vector.h>
#include <thrust\host_vector.h>
#include <thrust\fill.h>
#include <thrust\copy.h>
#include <Windows.h>

__global__ void AddKernel(int, float*);
extern "C" int __declspec(dllexport) __cdecl _AddKernel(int);

cudalib1.cu

#include "culib1.cuh"

extern "C" int __declspec(dllexport) __cdecl _AddKernel(int Vector_size)
{
	thrust::host_vector<float> H(Vector_size);
	thrust::fill(H.begin(), H.end(), 1.0);

	thrust::device_vector<float> D = H;
	float* _dev_ptr_D = thrust::raw_pointer_cast(&D[0]);
	AddKernel<<<12, 12>>>(D.size(), _dev_ptr_D);
	thrust::copy(D.begin(), D.end(), H.begin());
	delete _dev_ptr_D;
	cudaDeviceReset();
	//for (int i = 0; i < Vector_size; i++)
	//{
	//	Vector[i] = H[i];
	//}
	return 10;
}

__global__ void AddKernel(int N, float* D)
{
	unsigned int idx = threadIdx.x + blockIdx.x * blockDim.x;
	if (idx < N)
	{
		D[idx] = idx - 0.3f;
	}
}

C# code

[DllImport("culib1.dll", EntryPoint="_AddKernel", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public unsafe static extern int _AddKernel(int Vector_size);

After the C# application started, I recieved an error:
“Attempt to read or write protected memory. This often indicates that the other memory is corrupt.”

What I’m doing wromg?
Thank you!

Maybe this will be helpful… .

  • In VS create the new solution and then add three projects: C#, Win32 *.dll and CUDA respectively
  • In the CUDA project's properties, change the "*.exe" value in "Configuration Properties\General\Configuration Type" for ".lib" - the static library
  • Compile the CUDA project
  • In the Win32 *.dll project's properties, find the "Linker\Input\Additional Dependencies" section and simply add the name of your output *.lib file (don't forget to copy it to the appropriate folder)
  • In the Win32 *.dll project create the auxillary function with the name and the parameters exactly the same as one in the CUDA project. Declare it as
    extern "C" __declspec(dllimport)
    
  • Create your export function as you've just done and put your auxillary function call into the code
  • Compile project
  • Copy the output *.dll to the appropriate folder of the C# project
  • Thank you. I will try!

    It didn’t help me. Sorry.
    I can’t run CUDA methods from a Win32 project, because there is an error: “C2059: Syntax error <”. Win32 doesn’t recognize the “<<< >>>” term. Also it doesn’t recognize CUDA Thrust headers after including .lib-file in project.

    Do you have any suggestions?

    It seems the build process is trying to compile CUDA code using the host C/C++ compiler. CUDA code, in source files with a .cu extension, needs to be compiled with nvcc. I would suggest to check your build settings.

    Sorry for my little misunderstood :) … . Writing “auxillary function” I meant external HOST function, which calls the kernel (and does some other things like texture binding, CUDA memory allocation, etc.), NOT the very kernel. Of course VS C++ compiler doesn’t support additional C CUDA syntax… .

    One more thing, you’ve to compile above mentioned three projects separately, because as I noticed, Win32 *.dll project depends on the CUDA one in the sense that it requires the output *.lib file as the additional dependency… .

    Btw., try also to put

    #define __CUDACC__
    

    at the beginning of Your *.cu file. I came across strange VS behavior like underlining the texture references:

    texture<..., ..., ...> ...
    

    as errors until I put it into the *.cu file.

    Thank you! Let’s try again ))

    Thank you for your patience!
    Now I have these things:

    • CUDA project

    cu_runtime.cu

    #include "cu_runtime.cuh"
    
    __host__ int _RunKernel(int N)
    {
    	RunKernel<<<128, 128>>>(N);
    	return -1;
    }
    
    __global__ void RunKernel(int N)
    {
    
    }
    
    __device__ void DoNothing()
    {
    }
    

    cu_runtime.cuh

    #pragma once
    
    #include <cuda.h>
    #include <cuda_runtime.h>
    #include <device_launch_parameters.h>
    
    __host__ int _RunKernel(int);
    __global__ void RunKernel(int);
    __device__ void DoNothing();
    
    • Win32 .dll project:

    cu_lib.cpp

    #include "cu_lib.h"
    
    extern "C" int __declspec(dllexport) __cdecl RunKernel(int N)
    {
    	_RunKernel(N);
    	return -1;
    }
    

    cu_lib.h

    #pragma once
    
    #include <Windows.h>
    
    extern "C" int __declspec(dllimport) __cdecl _RunKernel(int);
    extern "C" int __declspec(dllexport) __cdecl RunKernel(int);
    

    While compiling the Win32 project I had an error: “LNK 2019: Link to the unresolved external symbol __imp___Runkernel in function _RunKernel.”

    Sorry. It works! Many thanks to all =))