Creating a CUDA DLL

I have been trying to use CUDA to remove lens distortion and do stereo rectification on a calibrated stereo camera pair. A majority of what I am doing used OpenCV. What I would like to do is create a .dll from my cuda project that just takes two pixel arrays as input and outputs two new pixel arrays. How would I go about doing this? I am using VS2005.

Thanks
PS: The reason I need the .dll is because I was unable to link to the opencv libraries in c but can in c++. If anybody has any other suggestions it will be appreciated.

Specifically, what help do you need? Do you have the program written and compiled in C and just need to turn it into .dll? Do you know how to write DLLs but not CUDA programs?

It is definitely possible to write a DLL, as I am currently running CUDA through Labview via a DLL.

Thanks,

Austin

I have no problem generating and compiling CUDA code. I don’t have this specific code written yet though, it’s about ~80%. I need to know how to write DLLs and compile to a DLL.

Ok, DLLs aren’t to terrible to create. The basic DLL structure is as follows:

#include <allmyheadershere.h>

void FunctionDeclarationHere(void){

 return;

}

__declspec(dllexport) void GPU_Code(float *ptrVarOne, float *ptrVarTwo)

{

FunctionDeclarationHere();

return;

}

To configure VS2005 do the following:

1.) Goto Project Properties -> Configuration Properties -> Project Details -> Configuration Type -> Change to DLL

2.) Goto Project Properties -> Configuration Properties -> Linker -> General -> Change the Output File to something that ends in .DLL

I think that is all. It has been a while since I actually configured the project, so let me know and I can hunt through the project properties again.

Thanks,

Austin

Just to make sure I understand the FunctionDeclarationHere() is my cuda c function that has the call to the CUDA kernel and CPU_Code() would be the function used when accesing the dll from another project. Is my understanding correct?

Thanks for your time.

Yes, I think that is correct. The example, when applied to CUDA, should look like:

#include <allmyheadershere.h>

global FunctionDeclarationHere(void){ //GPU function

return;

}

__declspec(dllexport) void GPU_Code(float *ptrVarOne, float *ptrVarTwo)

{

<<<x,y,z>>>FunctionDeclarationHere();

return;

}

Thanks alot I’ll give that a try and let you know how things go.

Did this ever work out for you?

I was distracted by some other work and have never gotten around to trying it.

Hi all, I am working on JNI and CUDA also. I am using Visual Studio 2005 with the CUDA build rule. The jni.h is included to my .cu file, and the directories for jni.h is set by adding (JAVA_HOME)\include and (JAVA_HOME)\include\win32 to myProject->Properties->Configuration Properties->C/C+±>General->Additional Include Directories; and by adding $(JAVA_HOME)\lib to Linker->Additional Library Directories. But I still get the error says that jni.h not found. I am wondering if it is because I am using cuda’s compiler that VS cannot recognize the path I set. Any suggestion of how to set the JNI environment will be appreciated.

Doesn’t work for me.
Unresolved external symbol.
Has anyone else tried it?

OK, I guess there are some naming conventions.
I suggest that you should use a tool like DLL Export to see the real names of the functions that are inside the DLL.

Once the names are correct everything works fine (hopefully)…

Austin,

Jus my 2 cents:

First cent:

function declaration is different from function definition. I think you have mixed both of them in your replies.

void gpuKernel(float *, int ); --- function declaration
void gpuKernel(float *b, int n) -- function definition

{

 Â  for(int i=blockIdx.x*blockDim.x+threadIdx.x; Â i<n; i+= gridDim.x*blockDim.x)

 Â  {

 Â  Â  Â  b[i] = 0;

 Â  }

}

Second cent:

While linking DLLs to applications, you should link against the “LIB” and not the DLL file. If you do it against the DLL - you will get LNK1107 “invalid or corrupt file! Cannot read offset 0x1F0” or some mesage like that from the linker!

Linking against the LIB is the best thing to do - It is called implicit linking and the DLL function call in your application looks the same as any other function call!

Best Regards,

Sarnath

Hello,

If you want that your dll contains the functions with the good names you must declare your functions like that

extern "C" __declspec(dllexport) int myfunction(int a);

Hello

Can anyone tell me an example of creating CUDA DLL and how to call it in FORTRAN.

Best Regards
Praveen

You can call CUDA code in a DLL from Fortran the same way you call any C API in a DLL from Fortran.

Here is a very simplistic example. I used the Microsoft C/C++ compiler and Intel Fortran on Windows here. For a real project, you would probably want to read up on how to use ISO C bindings in Fortran.

We have three source files: cuda_dll.cu and cuda_dll.h for building the DLL, and the main program written in Fortan in main.f90 that calls into the DLL.

cuda_dll.cu:

#include <stdio.h>
#include <stdlib.h>
#include "cuda_dll.h"

__global__ void kernel (int n)
{
    printf ("kernel: n = %d\n", n);
}

void wrapper (int *n)
{
    printf ("wrapper: calling kernel()\n");
    kernel<<<1,1>>>(*n);
    cudaDeviceSynchronize();
}

cuda_dll.h:

#ifdef CUDADLL_EXPORTS
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

extern "C" DLLEXPORT void wrapper (int *n);

main.f90:

program call_cuda
write (*,*) "Calling wrapper from Fortran"
call wrapper (5)
stop
end program call_cuda

Build the DLL (which on Windows results in two files, the actual dynamically linked library with a .dll extension and a stub library with the .lib extension):

nvcc --shared -DCUDADLL_EXPORTS -o cuda_dll.dll cuda_dll.cu

Now use the Intel Fortran compiler, ifort, to build the main program and link to the library. Note that we need to adjust the symbol generation of the Fortran compiler to generate lowercase symbol names to match the symbols exported from the library:

ifort -names:lowercase -Fefortran_main.exe main.f90 cuda_dll.lib

Now run the resulting executable fortran_main.exe, which produces the following output:

Calling wrapper from Fortran
wrapper: calling kernel()
kernel: n = 5