Bryan Greenway
Bryan Greenway

Reputation: 733

CUDA, Win7, Qt Creator - LNK1104: cannot open file '<cuda file>.obj'

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

Answers (1)

talonmies
talonmies

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

Related Questions