Reputation: 733
I'm trying to use CUDA with Qt Creator, Win7, and VS2012 compiler. I have experience with Qt on Windows, but have been unsuccessful setting up to integrate CUDA code into a Qt project. I've tried several posted solutions (such as Compiling Cuda code in Qt Creator on Windows), but have had no success. I finally decided to simplify and base my code on this blog post: https://cudaspace.wordpress.com/2012/07/05/qt-creator-cuda-linux-review/ but am still having issues.
Currently, I get the error "LNK1104: cannot open file 'obj\cuda_code.obj'"
My .pro file is:
QT += core
QT -= gui
TARGET = QtCuda
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
cuda_code.cu
# project build directories
DESTDIR = $$PWD
OBJECTS_DIR = $$DESTDIR/obj
# C++ flags
QMAKE_CXXFLAGS_RELEASE =-O3
# Cuda sources
CUDA_SOURCES += cuda_code.cu
# Path to cuda toolkit install
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.0"
# Path to header and libs files
INCLUDEPATH += $$CUDA_DIR/include
QMAKE_LIBDIR += $$CUDA_DIR/lib/x64
# libs used in your code
LIBS += -lcudart -lcuda
# GPU architecture
CUDA_ARCH = sm_50
# Here are some NVCC flags I've always used by default.
NVCCFLAGS = --compiler-options -use_fast_math
# Prepare the extra compiler configuration (taken from the nvidia forum - i'm not an expert in this part)
CUDA_INC = $$join(INCLUDEPATH,' -I','-I',' ')
cuda.commands = $$CUDA_DIR/bin/nvcc -m64 -O3 -arch=$$CUDA_ARCH -c $$NVCCFLAGS \
$$CUDA_INC $$LIBS ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT} \
2>&1 | sed -r \"s/\\(([0-9]+)\\)/:\\1/g\" 1>&2
cuda.dependency_type = TYPE_C
cuda.depend_command = $$CUDA_DIR/bin/nvcc -O3 -M $$CUDA_INC $$NVCCFLAGS ${QMAKE_FILE_NAME}
cuda.input = $$CUDA_SOURCES
cuda.output = $$OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.obj
# Tell Qt that we want add more stuff to the Makefile
QMAKE_EXTRA_COMPILERS += cuda
My main.cpp
#include <QtCore/QCoreApplication>
#include <iostream>
using namespace std;
#include <cuda_runtime.h>
extern "C"
cudaError_t cuda_main();
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cudaError_t cuerr = cuda_main();
if (cuerr != cudaSuccess) cout << "CUDA Error: " << cudaGetErrorString( cuerr ) << endl;
return a.exec();
}
My cuda file (cuda_code.cu):
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
extern "C"
cudaError_t cuda_main()
{
// generate 16M random numbers on the host
thrust::host_vector<int> h_vec(1 << 24);
thrust::generate(h_vec.begin(), h_vec.end(), rand);
// transfer data to the device
thrust::device_vector<int> d_vec = h_vec;
// sort data on the device (805 Mkeys/sec on GeForce GTX 480)
thrust::sort(d_vec.begin(), d_vec.end());
// transfer data back to host
thrust::copy(d_vec.begin(), d_vec.end(), h_vec.begin());
return cudaGetLastError();
}
Upvotes: 2
Views: 1880
Reputation: 72348
The OP was able to get a successful compile link by making the following changes:
1) In the .pro file, added
MSVCRT_LINK_FLAG_DEBUG = "/MDd"
MSVCRT_LINK_FLAG_RELEASE = "/MD"
along with (to the cuda.command statement) -Xcompiler $$MSVCRT_LINK_FLAG_DEBUG -or- -Xcompiler $$MSVCRT_LINK_FLAG_RELEASE
as described in: Compile cuda file error: "runtime library" mismatch value 'MDd_DynamicDebug' doesn't match value 'MTd_StaticDebug' in vectorAddition_cuda.o
2) Also had a very strange detail in the makefile that I had to fix manually. I hope that there is a real fix for this, but I haven't been able to figure it out.
At the top of the makefile, there are several definitions, including one for LIBS. After close inspection of this definition, I found that there was an extra set of quotation marks in the specification of library locations. Like this:
LIBS = /LIBPATH:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64" ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64"\cuda.lib" ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64"\cudart.lib" /LIBPATH:C:\Qt\5.2.1\msvc2012_64_opengl\lib C:\Qt\5.2.1\msvc2012_64_opengl\lib\Qt5Cored.lib
If you look closely, you can see the extra set of quotation marks in the locations for cuda.lib and cudart.lib. I couldn't figure out what might be causing this (probably something in my .pro file), but if I manually removed the extra quotations, the compile/link worked. Here's the corrected line in the makefile:
LIBS = /LIBPATH:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64" "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64\cuda.lib" "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64\cudart.lib" /LIBPATH:C:\Qt\5.2.1\msvc2012_64_opengl\lib C:\Qt\5.2.1\msvc2012_64_opengl\lib\Qt5Cored.lib
I would sure like to be able to fix this in my .pro file so that these extra quotations didn't appear. Suggestions would be appreciated.
For reference, here's my latest .pro file.
QT += core
QT -= gui
TARGET = QtCuda
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
cuda_code.cu
# project build directories
DESTDIR = $$PWD
OBJECTS_DIR = $$DESTDIR/obj
# C++ flags
QMAKE_CXXFLAGS_RELEASE =-O3
# Cuda sources
CUDA_SOURCES += cuda_code.cu
# Path to cuda toolkit install
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.0"
# Path to header and libs files
INCLUDEPATH += $$CUDA_DIR/include
QMAKE_LIBDIR += $$CUDA_DIR/lib/x64
SYSTEM_TYPE = 64 # '32' or '64', depending on your system
# libs used in your code
LIBS += -lcuda -lcudart
# GPU architecture
CUDA_ARCH = sm_50
# Here are some NVCC flags I've always used by default.
NVCCFLAGS = --use_fast_math
# Prepare the extra compiler configuration (taken from the nvidia forum - i'm not an expert in this part)
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
# MSVCRT link option (static or dynamic, it must be the same with your Qt SDK link option)
MSVCRT_LINK_FLAG_DEBUG = "/MDd"
MSVCRT_LINK_FLAG_RELEASE = "/MD"
# Tell Qt that we want add more stuff to the Makefile
QMAKE_EXTRA_COMPILERS += cuda
# Configuration of the Cuda compiler
CONFIG(debug, debug|release) {
# Debug mode
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$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 -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} -Xcompiler $$MSVCRT_LINK_FLAG_DEBUG
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
}
else {
# Release mode
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 -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} -Xcompiler $$MSVCRT_LINK_FLAG_RELEASE
cuda.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda
}
[Note: this answer has been created from an edit to the question which included the solution. It has been added as a community wiki entry to get the question off the unanswered list for the CUDA tag]
Upvotes: 4