I am working on a project that requires creating a dll file which contains some cuda functions.
The problem is, .cu file does not get exported into the dll i.e. my application linked to the dll, cannot find functions declared in .cu files. I am getting LNK2019 unresolved external symbol error with VS2005.
In my project, I can define other functions in seperate cpp files and they are exported correctly - however .cu functions not.
Can anyone tell how can I export cuda files to the dll.
I created a .lib file that works by wrappping a C++ class around the methods in the .CU file. I believe it should be the same for dll.
Simply create a regular class - in the .cpp file forward declare the method of the .cu file that you wish to call and create a method that calls that function. In the .cu file the method header should look like that:
extern "C" void myMethod()
The class methods can be called when compiled into the lib.
Could you give more details about how you did implement your library? I saw an implementation of a library pug by Mark Harris, but it is for cg code. I will appreciate your explanation. Thanks,
Let’s say you have created your kernel called testKernel(). And you created a function testLauncher() that executes the kernel (with <<< >>> and cudaMemcpy and all those cool things). Both are C/CUDA functions. To execute your kernel you have to call testLauncher().
What you do now is declare your testLauncher() as extern “C”:
/* the old function declaration.. */
void testLauncher(int param1, int param2 ...)
{
/*prepare and launch kernel here*/
}
/* is rewritten to look like that: */
extern "C" void testLauncher(int param1, int param2 ...)
{
/*prepare and launch kernel here*/
}
Now create a class that has a method callTestLauncher(). In the file where callTestLauncher() is implemented the testLauncher() function has to be forward declared so in on of the first lines of the class cpp file put
extern "C" void testLauncher(int param1, int param2 ...);
Now in the callTestLauncher() method you can call the testLauncher function:
testLauncher(256, 25, ...);
which when executed will launch the kernel. So you’re call graph would be something like: callTestLauncher()->testLauncher()->testKernel() whereas the first method can be a regular c++ class method.
When this is compiled as a .lib file the kernel can be launched by calling callTestLauncher().
This method works indeed; however, it seems that wrapping all CUDA calls in C functions would make the use of C++ classes pretty cumbersome. If most of the methods in a C++ class implement CUDA functionality then the class would basically be reduced to a data container, and if that’s the case I’d rather use regular C struct’s. I wonder if NVIDIA has any plans to support full blown C++ accessible CUDA.
I have an application using GPU and OpenGL. I compiled the project to obtain a dll file and I wanna use that dll to call the application as a thread of C# GUI project. I declared the export of the dll project as:
If i don’t include the cuda kernel (.cu files), it works fine with openGL in C# (no nvcc objects). However, when .cu files are added to the dll, the dll does not work in the C#. Such that the C# code throws “System.DLLnotFoundException” error.
I wanna ask how to obtain a working dll from the cuda projects.
As far as I understand, if the dll contains the obj files that created by nvcc, C# side does not recognize this dll. So I splitted my dll project into two projects:
i) Cuda_Kernel
ii) Cuda_API
First one is including the kernel files and does the real job and the other is to call the first dll.
Cuda_Kernel project has one entry function and defined as:
Cuda_API project also has one entry function and defined as:
“extern “C” __declspec( dllexport ) int CUDA_main(Parameters *params”.
Here is the code of CUDA_main function:
extern "C" __declspec( dllexport ) int CUDA_main(Parameters *params)
{
// get handle to dll
HINSTANCE hGetProcIDDLL = LoadLibrary("cuda_Kernel.dll");
// get pointer to the function in the dll
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hGetProcIDDLL), "runTest");
//Define the Function in the DLL for reuse. This is just prototyping
//the dll's function. A mock of it. Use "stdcall" for maximum
//compatibility.
typedef void (* pICFUNC)(Parameters*);
pICFUNC runTest;
runTest = pICFUNC(lpfnGetProcessID);
// The actual call to the function contained in the dll
runTest(params);
// Release the Dll
FreeLibrary(hGetProcIDDLL);
return 0;
}
This project outputs “cuda_API.dll”.
And from C# side “CUDA_main” is called like this:
class CUDAMAIN_class
{
[DllImport("cuda_API.dll")]
public static extern int CUDA_main(ref Parameters p);
public void CUDA_main_call(ref Parameters p)
{
CUDA_main(ref p);
}
}
...
CUDAMAIN_class my_cuda = new CUDAMAIN_class();
my_cuda.CUDA_main_call(ref params_struct);
[Solution] I too struggled with this problem. The simplest solution that I have found for generating a dll with cuda functionality and importing into C# is as follows:
(Tested on Cuda v1.0. I hear there are problems in 0.8)
Declare exports in cu file (or header file). Example:
Compile with the -shared flag. Use the -o flag to name the dll. Without this flag your dll will be named a.exe. I didnt realize that this was actually a dll until i tried to execute it. Example:
3)Declare an external function in C#. (I chose to place the dll in the project \debug folder with the managed executable). Note: The return:MarshalAs() attribute is specific to my example and instructs the CLR to convert the char* to a managed string.
I’m trying to build a static library with nvcc. It will have some functions which I would like to call from a C++ class. Library seems to build ok, but when I link it with my C++ project I keep getting “undefined reference to”. Could you explain me what I’m doing wrong?
I’m using Netbeans on Ubuntu. I compiled and run other CUDA application so I’m pretty sure it’s not CUDA configuration issue.