2

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();
}
Community
  • 1
  • 1
Bryan Greenway
  • 703
  • 11
  • 30
  • Is there a way you can post a copy of the compilation commands issued by the makefile? – talonmies Aug 29 '15 at 10:29
  • I assume you are referring to any "nvcc" command lines in the makefile? If so, I just searched my makefile and found no reference to nvcc. I could post the entire makefile on a share site if that would help, but I'm guessing now that nvcc is not being called for some reason??? If I'm off base here, let me know. Thanks. – Bryan Greenway Aug 29 '15 at 14:48
  • If you can't see any nvcc invocations then the problem is clearly that the objects are never being complied (as opposed to being compiled but having a different name or being in a different place). So the solution is fix that first, but how you do that is really a qmake question rather than anything to do with CUDA per se – talonmies Aug 29 '15 at 15:01
  • You're exactly right. Looks like issues with my qmake project file. I now have nvcc being invoked, but now it's looking for "C:\Program.obj". Strange. In case you're interested, here's the nvcc command from my make file: "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\bin\nvcc.exe" -D_DEBUG -I"C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.0/include" -lcuda -lcudart --machine 64 -arch=sm_50 -c -o obj\cuda_code.obj cuda_code.cu – Bryan Greenway Aug 29 '15 at 16:05
  • Added an edit above that appears to have fixed the problem. – Bryan Greenway Aug 31 '15 at 16:12

1 Answers1

4

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]

Community
  • 1
  • 1
talonmies
  • 70,661
  • 34
  • 192
  • 269
  • @BryanGreenway: If you want to upvote or accept the answer, the question will be removed from the unanswered question list (note its a community wiki answer so there is no reputation changes to anyone involved in voting or accepting) – talonmies Feb 04 '16 at 21:01
  • About the quotation problem, I think there's no fix and should be reported as bug. Quotation marks must be there when there are spaces in the path. The problem is that Qt creator use the whole string, including the quotes, to generate the Makefile – José Aug 18 '16 at 12:24