【问题标题】:Force NVCC straight to linking phase强制 NVCC 直接进入链接阶段
【发布时间】:2020-04-12 21:32:41
【问题描述】:

我正在使用 MSVC 将 GPU 应用程序移植到 Windows,这似乎与 NVCC 不太兼容。我已经分离了编译和链接阶段。 nvcc 将只预处理 cuda 文件:

nvcc -dc -ccbin cl somefile.cu

cl 将编译其他所有内容:

cl anotherfile.c

这种分离是必要的,因为许多 MSVC 标志(此处不包括)与 nvcccl.exe 的包装不兼容(相关症状 here)。

编译完成后,我可以通过两种方式进行链接。

  1. 使用nvcc 链接 CUDA 设备代码,然后使用link.exe 链接所有内容,按照this guide

尽我所能,我无法让link 找到 CUDA 标头,也找不到任何有关如何将link 指向cudart 库的文档。要是像他们的 g++ 例子一样简单就好了!

  1. nvcc 完成所有链接。

然而,根据doc,“没有选项”可以跳转到链接阶段。因此,当我尝试链接所有内容时,使用...

nvcc somefile.o anotherfile.o -o app.exe

我收到了来自cl 的一些警告!

cl : Command line warning D9024 : unrecognized source file type 'somefile.o', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'anotherfile.o', object file assumed

当然,nvcc 假定这些目标文件是源代码并将它们发送到 cl,因为文档包括:

请注意,nvcc 不区分对象、库或资源文件。

当然cl 抱怨 - 这些目标文件应该直接传递给链接器。我知道link 最终会被调用,因为我用-Xlinker 传递了一些不相关的参数。在这些警告之后,app.exe 确实被编译了。

尽管文档表明没有链接器阶段参数,但我如何强制nvcc链接 对象,而不是错误地将它们传递给cl?没有办法抑制这些警告(至少在 stackoverflow 社区没有 condemned 时是这样)。

【问题讨论】:

  • 即使-link 标志指定“编译并链接”,糟糕!

标签: visual-c++ linker nvcc cl


【解决方案1】:

http://github.com/fangq/mcx查看我的 cuda 代码

你可以在Windows上的Cygwin64/MSYS2终端编译它,进入mcx/src文件夹,输入“make”,我看到的就是这个

nvcc -c -g -lineinfo -Xcompiler -Wall -Xcompiler "/openmp /W0" -DSAVE_DETECTORS -use_fast_math -arch=sm_30 -DMCX_TARGET_NAME='"Fermi MCX"' -DUSE_ATOMIC -use_fast_math -o mcx_core.obj  mcx_core.cu
mcx_core.cu
e:\gitroot\project\github\mcx\src\mcx_core.cu(2042) : warning C4701: potentially uninitialized local variable 'gsrcpattern' used
e:\gitroot\project\github\mcx\src\mcx_core.cu(2042) : warning C4703: potentially uninitialized local pointer variable 'gsrcpattern' used
nvcc -I/usr/local/cuda/include -I"/lib/include" -c -D_CRT_SECURE_NO_DEPRECATE -DWIN32 -Xcompiler /openmp -c -o mcx_utils.obj  mcx_utils.c
mcx_utils.c
nvcc -I/usr/local/cuda/include -I"/lib/include" -c -D_CRT_SECURE_NO_DEPRECATE -DWIN32 -Xcompiler /openmp -c -o mcx_shapes.obj  mcx_shapes.c
mcx_shapes.c
nvcc -I/usr/local/cuda/include -I"/lib/include" -c -D_CRT_SECURE_NO_DEPRECATE -DWIN32 -Xcompiler /openmp -c -o tictoc.obj  tictoc.c
tictoc.c
nvcc -I/usr/local/cuda/include -I"/lib/include" -c -D_CRT_SECURE_NO_DEPRECATE -DWIN32 -Xcompiler /openmp -c -o mcextreme.obj  mcextreme.c
mcextreme.c
nvcc -I/usr/local/cuda/include -I"/lib/include" -c -D_CRT_SECURE_NO_DEPRECATE -DWIN32 -Xcompiler /openmp -c -o cjson/cJSON.obj  cjson/cJSON.c
cJSON.c
nvcc mcx_core.obj mcx_utils.obj mcx_shapes.obj tictoc.obj mcextreme.obj cjson/cJSON.obj -o ../bin/mcx -L"/lib/x64" -lcudart -Xcompiler /openmp
mcx_core.obj
mcx_utils.obj
mcx_shapes.obj
tictoc.obj
mcextreme.obj
cJSON.obj
   Creating library ../bin/mcx.lib and object ../bin/mcx.exp

它编译每个 c 单元,并按预期链接 .obj 文件,我没有发现任何错误。

【讨论】:

  • 感谢您的回答,尽管我正在使用 MSVC 专门进行编译,并询问编译和链接的分离(您的构建没有这样做)
  • 不,我的命令确实将编译与链接(最后一个命令)分开,并且 nvcc 被配置为调用 msvc 进行编译和链接。
  • 我很抱歉 - 但你没有说明如何;与我的示例有什么不同?几乎不是 MWE,但一种可能的解释是我编译为 .o 文件,而您使用 Windows 传统的 .obj。在我的情况下使用.o 是必要的
  • 我不认为后缀有问题。我只是将我的 makefile (github.com/fangq/mcx/blob/master/src/Makefile#L75) 中的一行从 .obj 更改为 .o,我能够在我的 Windows 机器(win10、vc12、cuda 8)上正确编译/链接,唯一的区别是链接器发出一个警告cl : Command line warning D9024 : unrecognized source file type 'mcx_core.o', object file assumed,和你看到的一样。但是二进制文件是正确创建的。
  • 好吧,重新阅读您的原始帖子 - 您的问题是为什么将链接命令发送到 cl?您可以通过在最后一个 nvcc 链接命令中添加 -v 来查找。根据我的测试,它调用nvlink-link 进行链接,但在最后有这行:cl.exe @"C:\...\tmp/tmpxft_00...-8.res" -Fe"../bin/mcx" 发出警告。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
  • 1970-01-01
  • 2011-05-10
相关资源
最近更新 更多