一、准备好工程文件
(一)Qt中创建一个工程:(二)cuda程序内容(三)cuda程序的头文件内容(四)主程序入口内容 二、混合编程的三种方法
(一)使用NVCC编译器预编译生成*.obj后在Qt工程文档中调用(二)在pro文件中添加额外编译器nvcc和主程序同时编译(三)将cu文件封装为库文件,而后在工程文件中引用
三、总结
尝试在Qt中实现CUDA的混合编程,因为CUDA不支持MinGW编译器,因此只能使用VS编译器,于是选用MSVC2017编译器。
为了实现混合编程,其实实际上是同一种方法,核心在于对CUDA部分的代码使用NVCC编译器,而对别的代码内容使用VS2017编译器。区别在于,对CUDA代码的编译结果在VS2017中调用的方式。
bilinear.cu
#include "bilinear.h"
extern "C"
__global__ void hellofromGPU(void)
{
printf("GPU:hello sunyin");
}
void showhello(void)
{
hellofromGPU <<<1,10>>>();
cudaDeviceSynchronize();
}
(三)cuda程序的头文件内容
bilinear.h
#ifndef BILINEAR_H #define BILINEAR_H #include "cuda_runtime.h" #include "device_launch_parameters.h" #include(四)主程序入口内容#include "malloc.h" #define WIDTH 11 #define HEIGHT 10 #define X_INTER 3 #define Y_INTER 3 #define BLOCK_SIZE 8 void showhello(void); #endif // BINLINEARINTERPOLATIONCUDA_H
main.cpp
#include二、混合编程的三种方法 (一)使用NVCC编译器预编译生成*.obj后在Qt工程文档中调用#include "bilinear.h" int main(void) { showhello(); while(1); } //nvcc -arch sm_45
将VS2017的include,lib,bin写入环境变量。如果是默认的安装目录,应该是在C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6的目录下。
使用VS2017自带的命令行工具,适用于VS 2017的x64本机工具命令提示(也有可能是英文名,搞不清是哪个,可以将命令工具挨个试一下)。转到bilinear.cu目录下。
输入nvcc -Xcompiler "/MDd" -D_DEBUG -c bilinear.cu,则会生成bilinear.obj。
而后在testCUDA.pro中添加OBJECTS += bilinear.obj,就可以正常编译了。
将bilinear.obj放到编译目录下,debug下。
这个不需要事先生成bilinear.obj文件,但在pro文件中添加额外编译器nvcc的目的也是生成bilinear.obj,原理是一样的,只是将生成的命令写入pro文件中,在编译前先生成pro文件。
testCUDA.pro
QT -= gui
ConFIG += c++11 console
ConFIG -= app_bundle
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES +=
main.cpp
OBJECTS +=
# CUDA 设置
CUDA_SOURCES += bilinear.cu
CUDA_DIR = "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6"
SYSTEM_NAME = x64
SYSTEM_TYPE = 64
CUDA_ARCH = sm_61
NVCC_OPTIONS = --use_fast_math
# 头文件路径
INCLUDEPATH += "$$CUDA_DIR/include"
# 导入库文件路径
QMAKE_LIBDIR += "$$CUDA_DIR/lib/x64"
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
# 依赖库
CUDA_LIB_NAMES +=
cuda
cudadevrt
cudart
CONFIG(debug, debug|release) {
CUDA_LIB_NAMES += ucrtd
}
else{
CUDA_LIB_NAMES += ucrt
}
for(lib, CUDA_LIB_NAMES) {
CUDA_LIBS += $$lib.lib
}
for(lib, CUDA_LIB_NAMES) {
NVCC_LIBS += -l$$lib
}
LIBS += $$NVCC_LIBS
MSVCRT_link_FLAG_DEBUG = "/MDd"
MSVCRT_link_FLAG_RELEASE = "/MD"
# 这部分内容,实质上就是在Qt中调用环境中的命令行工具来先编译生成bilinear.obj
CONFIG(debug, debug|release) {
# Debug 模式
OBJECTS_DIR = debug/obj
CUDA_OBJECTS_DIR = debug
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_base}.obj
cuda_d.commands = $$CUDA_DIR/bin/nvcc.exe -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$LIBS
--machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH
--compile -cudart static -g -DWIN32 -D_MBCS
-Xcompiler "/wd4819,/EHsc,/W3,/nologo,/Od,/Zi,/RTC1"
-Xcompiler $$MSVCRT_link_FLAG_DEBUG
-c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
}
else {
# Release 模式
OBJECTS_DIR = release/obj
CUDA_OBJECTS_DIR = release
cuda.input = CUDA_SOURCES
cuda.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_base}.obj
cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$LIBS
--machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH
--compile -cudart static -D_MBCS
-Xcompiler "/wd4819,/EHsc,/W3,/nologo,/O3,/Zi"
-Xcompiler $$MSVCRT_link_FLAG_RELEASE
-c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda
}
HEADERS +=
bilinear.h
DISTFILES +=
bilinear.cu
注意! 这个方法,我在windows sever2019服务器上使用,不知道为什么,一直没有编译生成bilinear.obj文件,试了很久都没成功,但是换了一台windows10,几乎一样的工具,一遍就编译通过了。所以如果你也遇到了类似的问题,换个电脑,换个系统试试。
正常编译输出内容如下,仅供参考:
12:00:27: 为项目testCUDA执行步骤 ... 12:00:27: 配置没有改变, 跳过 qmake 步骤。 12:00:28: 正在启动 "C:QtQt5.12.12ToolsQtCreatorbinjomjom.exe" C:QtQt5.12.12ToolsQtCreatorbinjomjom.exe -f Makefile.Debug C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6/bin/nvcc.exe -D_DEBUG --use_fast_math -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6/include" -lcuda -lcudadevrt -lcudart -lucrtd --machine 64 -arch=sm_61 --compile -cudart static -g -DWIN32 -D_MBCS -Xcompiler /wd4819,/EHsc,/W3,/nologo,/Od,/Zi,/RTC1 -Xcompiler /MDd -c -o debugbilinear.obj ..testCUDAbilinear.cu cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc /FddebugobjtestCUDA.vc.pdb -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_QML_DEBUG -DQT_CORE_LIB -I..testCUDA -I. -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6include" -IC:QtQt5.12.125.12.12msvc2017_64include -IC:QtQt5.12.125.12.12msvc2017_64includeQtCore -Idebug -IC:QtQt5.12.125.12.12msvc2017_64mkspecswin32-msvc -Fodebugobj @C:UsersADMINI~1AppDataLocalTempmain.obj.31692.343.jom main.cpp bilinear.cu link /NOLOGO /DYNAMICbase /NXCOMPAT /DEBUG /SUBSYSTEM:ConSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST:embed /OUT:debugtestCUDA.exe @C:UsersADMINI~1AppDataLocalTemptestCUDA.exe.31692.12781.jom 12:00:42: 进程"C:QtQt5.12.12ToolsQtCreatorbinjomjom.exe"正常退出。 12:00:42: Elapsed time: 00:15.
把Makefile.Debug中的部分内容也贴一下,仅供参考:
compiler_cuda_d_make_all: debugbilinear.obj compiler_cuda_d_clean: -$(DEL_FILE) debugbilinear.obj debugbilinear.obj: ..testCUDAbilinear.cu ..testCUDAbilinear.h "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecuda_runtime.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrthost_config.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includebuiltin_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includedevice_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrthost_defines.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includedriver_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includevector_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesurface_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includetexture_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includelibrary_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includechannel_descriptor.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecuda_runtime_api.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecuda_device_runtime_api.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includedriver_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includevector_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includevector_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtdevice_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtdevice_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includedevice_atomic_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includedevice_atomic_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtdevice_double_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtdevice_double_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_20_atomic_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_20_atomic_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_32_atomic_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_32_atomic_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_35_atomic_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_60_atomic_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_60_atomic_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_20_intrinsics.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_20_intrinsics.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_30_intrinsics.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_30_intrinsics.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_32_intrinsics.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_32_intrinsics.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_35_intrinsics.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_61_intrinsics.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesm_61_intrinsics.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtsm_70_rt.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtsm_70_rt.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtsm_80_rt.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtsm_80_rt.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesurface_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecuda_surface_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includetexture_fetch_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecuda_texture_types.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includetexture_indirect_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includesurface_indirect_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtcommon_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtmath_functions.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtfunc_macro.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includecrtmath_functions.hpp" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includemath_constants.h" "C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6includedevice_launch_parameters.h" C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6/bin/nvcc.exe -D_DEBUG --use_fast_math -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv11.6/include" -lcuda -lcudadevrt -lcudart -lucrtd --machine 64 -arch=sm_61 --compile -cudart static -g -DWIN32 -D_MBCS -Xcompiler /wd4819,/EHsc,/W3,/nologo,/Od,/Zi,/RTC1 -Xcompiler /MDd -c -o debugbilinear.obj ..testCUDAbilinear.cu(三)将cu文件封装为库文件,而后在工程文件中引用
这个方法我具体没有测试,但是理论上跟方法一应该是同个道理,只是方法一是将bilinear.cu文件编译成了bilinear.obj文件,在这个方法中,是将bilinear.cu封装成bilinear.lib或者bilinear.dll文件,而后调用。是一个道理。
在这个方法中,在编译完成后,应该至少生成两个文件。
bilinear.h和bilinear.lib。或者还有一个bilinear.dll。
具体的我就不试了,但是想想应该是简单的。
包括在openCV中调用到CUDA的内容,应该实质上也是类似于此的方法,因此调用openCV的库文件,并不需要自己解决CUDA的配置问题。
- 千万记住CUDA的编译暂不支持MinGW,所以别在这方面浪费时间了。如果生成obj文件失败,可以换个系统试试。根据我的观察,我在之前那个系统中一直生成失败,是因为在之前那个系统中,压根就没启用cmd命令行来调用额外编译器nvcc,具体原因暂时不知道。关于不同显卡的sm值是多少的填写,在英伟达官网可以查到,比如我的GTX1060 3G写的是6.1,则sm=61。查询GPU算力的官网



