9

I want to create a .dll from a CUDA code (kernel.cu) in order to use this library from an external C program. After some attempts I just left a simple C function in .cu file. Code follows:

kernel.cu

#include <stdio.h>
#include "kernel.h"

void hello(const char *s) {
        printf("Hello %s\n", s);
}/*

kernel.h

#ifndef KERNEL_H
#define KERNEL_H

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#ifdef __cplusplus
extern "C" {
#endif

void __declspec(dllexport) hello(const char *s);

#ifdef __cplusplus
}
#endif

#endif  // KERNEL_H

I tried to first generate a kernel.o object with nvcc and after i used g++ for creating DLL as following:

nvcc -c kernel.cu -o kernel.o
g++ -shared -o kernel.dll kernel.o -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\lib\x64" -lcudart

It works fine and generates kernel.dll. To test DLL file I wrote this simple program main.c:

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

void __declspec ( dllimport ) hello(const char *s);

#ifdef __cplusplus
}
#endif

int main(void) {
        hello("World");
        return 0;
}

compiled with:

g++ -o app.exe main.c -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\include" -L. -lkernel

Result is a memory access error when execution starts.

Nevertheless, if I rename .cu file in .c (as it is just C code), using the same commands, it does work. nvcc's output changes, as far as I know because it uses default C compiler instead of CUDA one.

What do you think, is it a problem related with nvcc? Or am I making any mistake?

EDIT: I forgot some info which may be important. Warnings appear in the first call to g++ (when dll is created) and they are different depending on whether .cu .c or .cpp.

.cu

Warning: .drectve `/FAILIFMISMATCH:"_MSC_VER=1600" /FAILIFMISMATCH:"_ITERATOR_DEBUG_LEVEL=0" 
/DEFAULTLIB:"libcpmt" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" /EXPORT:hello ' unrecognized

and it doesn't work.

.cpp and .c

Warning: .drectve `/DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" /EXPORT:hello ' unrecognized

and it works.

BobCormorano
  • 650
  • 1
  • 7
  • 14
  • What happens if you rename the .cu file to .cpp instead of .c does it still work? – Robert Crovella May 07 '13 at 16:44
  • Works fine for me on Linux (well, without `dllimport` and with `-fPIC`). When I use the verbose mode (`nvcc -v`), I can see that `nvcc` calls `gcc` in C++ mode by default (`gcc -x c++ ...`). – BenC May 08 '13 at 02:17
  • @Robert It works with .cpp also. – BobCormorano May 08 '13 at 07:31
  • I realized I had forgotten about Warnings. Question is edited now. – BobCormorano May 08 '13 at 08:11
  • So, you're apparently using CUDA 5.0. What is your `g++` version? – BenC May 08 '13 at 08:17
  • @BenC Yes, CUDA 5.0. g++ is a Windows x64 personal-build downloaded from MinGW site: `g++ (rubenvb-4.8.0) 4.8.0 Copyright (C) 2013 Free Software Foundation, Inc.` – BobCormorano May 08 '13 at 08:24
  • 2
    The only officially supported C/C++ compiler on windows platforms is cl.exe, the compiler that ships with MS Visual Studio. I believe many folks have been successful building DLLs with the MS VS setup. You can get a free version using any of the MS VS express products. – Robert Crovella May 08 '13 at 11:56

2 Answers2

7

Solved. I still don't know why happened (maybe it is because of not using official compiler like Robert Crovella said), but replacing the two commands for making a DLL by this one works:

nvcc -o kernel.dll --shared kernel.cu

Note the double dash (nvcc works this way), and the fact of making it directly instead of creating first .o and then making DLL from the object.

BobCormorano
  • 650
  • 1
  • 7
  • 14
1

In visual studio you can also make it compile into a .dll instead of a .obj file by navigating through the options:

DEBUG -> -Project name- Properties -> Configuration properties -> Configuration Type

Change the option from Application(.exe) to Dynamic Library(.dll)

You can find the dll after compiling in the DEBUG folder or RELEASE folder

Jack
  • 102
  • 1
  • 14