使用nvcc从CUDA创建DLL

9

我希望从CUDA代码(kernel.cu)创建一个.dll,以便从外部C程序中使用此库。经过一些尝试,我只在.cu文件中保留了一个简单的C函数。代码如下:

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

我首先尝试使用 nvcc 生成 kernel.o 对象,然后使用以下命令使用 g++ 创建 DLL:

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

它运行良好并生成kernel.dll。为了测试DLL文件,我编写了这个简单的程序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;
}

编译使用:

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

当执行开始时,结果会出现内存访问错误。

然而,如果我将 .cu 文件重命名为 .c(因为它只是 C 代码),使用相同的命令,它就可以正常工作。nvcc 的输出会发生变化,据我所知是因为它使用默认的 C 编译器而不是 CUDA 编译器。

你认为这是与 nvcc 相关的问题吗?还是我犯了什么错误?

编辑:我忘记了一些可能很重要的信息。警告出现在第一次调用 g++(创建 dll 时),并且根据 .cu、.c 或 .cpp 不同而不同。

.cu

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

它不起作用。

.cpp 和 .c

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

并且它可以正常工作。


如果将 .cu 文件重命名为 .cpp 而不是 .c,会发生什么?它还能正常工作吗? - Robert Crovella
@Robert 它也适用于 .cpp。 - BobCormorano
我意识到我忘记了警告。现在已经编辑了问题。 - BobCormorano
@BenC 是的,CUDA 5.0。g++是从MinGW网站下载的Windows x64个人构建版本: g++ (rubenvb-4.8.0) 4.8.0 版权所有 (C) 2013自由软件基金会。 - BobCormorano
2
在Windows平台上,唯一官方支持的C/C++编译器是cl.exe,也就是随MS Visual Studio一起提供的编译器。我相信许多人已经成功地使用MS VS设置构建了DLL。您可以使用任何MS VS Express产品获得免费版本。 - Robert Crovella
显示剩余2条评论
2个回答

7

问题已解决。虽然我仍不知道为什么会发生这种情况(也许是因为像Robert Crovella所说的没有使用官方编译器),但是用以下命令替换制作DLL的两个命令可以解决问题:

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

请注意双短线(nvcc 以此方式工作),以及直接制作而非先创建 .o 对象再从对象中制作 DLL。

1
在Visual Studio中,您也可以通过浏览选项将其编译为.dll文件而不是.obj文件:

调试 -> -项目名称- 属性 -> 配置属性 -> 配置类型

将选项从Application(.exe)更改为Dynamic Library(.dll)

编译后,您可以在DEBUG文件夹或RELEASE文件夹中找到dll。


1
选择 dll 后,该项目仍然只生成 exe。 - koonyook
这对我有用,但由于某种原因,dll被输出到与解决方案文件相同级别的文件夹中。 - Markus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接