C++ 在Windows上的Qt Creator中编译Cuda代码

C++ 在Windows上的Qt Creator中编译Cuda代码,c++,windows-7,qt4,cuda,C++,Windows 7,Qt4,Cuda,几天来,我一直试图在32位Windows7系统上运行一个Qt项目文件,其中我希望/需要包含Cuda代码。这些事情的结合要么是如此简单以至于没有人愿意在网上举例,要么是如此困难以至于似乎没有人成功。不管怎样,我发现的唯一有用的论坛线程是Linux或Mac上的相同问题,或者Windows上的Visual Studio。 然而,所有这些都会产生各种不同的错误,无论是由于链接或冲突库,还是由于Cuda SDK Windows版本中文件名或不存在文件夹中的空格。 有没有人可以提供一个清晰的.pro文件来实

几天来,我一直试图在32位Windows7系统上运行一个Qt项目文件,其中我希望/需要包含Cuda代码。这些事情的结合要么是如此简单以至于没有人愿意在网上举例,要么是如此困难以至于似乎没有人成功。不管怎样,我发现的唯一有用的论坛线程是Linux或Mac上的相同问题,或者Windows上的Visual Studio。 然而,所有这些都会产生各种不同的错误,无论是由于链接或冲突库,还是由于Cuda SDK Windows版本中文件名或不存在文件夹中的空格。 有没有人可以提供一个清晰的
.pro
文件来实现这个目的

我的目标是用Qt风格的普通C++代码编译一个简单的程序,用Qt 4.8库,引用Cu文件中的几个CUDA模块。某种形式:

TestCUDA \
    TestCUDA.pro
    main.cpp
    test.cu

因此,我最终成功地组装了一个
.pro
文件,它可以在我的系统上工作,也可能在所有Windows系统上工作。下面是一个简单的测试程序,可能会达到这个目的。下面是一个小项目文件加测试程序,它至少在我的系统上工作

文件系统如下所示:

TestCUDA \
    TestCUDA.pro
    main.cpp
    vectorAddition.cu
项目文件的内容如下:

TARGET = TestCUDA

# Define output directories
DESTDIR = release
OBJECTS_DIR = release/obj
CUDA_OBJECTS_DIR = release/cuda

# Source files
SOURCES += src/main.cpp

# This makes the .cu files appear in your project
OTHER_FILES +=  vectorAddition.cu

# CUDA settings <-- may change depending on your system
CUDA_SOURCES += src/cuda/vectorAddition.cu
CUDA_SDK = "C:/ProgramData/NVIDIA Corporation/NVIDIA GPU Computing SDK 4.2/C"   # Path to cuda SDK install
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v4.2"            # Path to cuda toolkit install
SYSTEM_NAME = Win32         # Depending on your system either 'Win32', 'x64', or 'Win64'
SYSTEM_TYPE = 32            # '32' or '64', depending on your system
CUDA_ARCH = sm_11           # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
NVCC_OPTIONS = --use_fast_math

# include paths
INCLUDEPATH += $$CUDA_DIR/include \
               $$CUDA_SDK/common/inc/ \
               $$CUDA_SDK/../shared/inc/

# library directories
QMAKE_LIBDIR += $$CUDA_DIR/lib/$$SYSTEM_NAME \
                $$CUDA_SDK/common/lib/$$SYSTEM_NAME \
                $$CUDA_SDK/../shared/lib/$$SYSTEM_NAME
# Add the necessary libraries
LIBS += -lcuda -lcudart

# The following library conflicts with something in Cuda
QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
QMAKE_LFLAGS_DEBUG   = /NODEFAULTLIB:msvcrtd.lib

# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')

# Configuration of the Cuda compiler
CONFIG(debug, debug|release) {
    # Debug mode
    cuda_d.input = CUDA_SOURCES
    cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
    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}
    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}_cuda.o
    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}
    cuda.dependency_type = TYPE_C
    QMAKE_EXTRA_COMPILERS += cuda
}
Cuda文件
vectorAddition.cu
,描述了一个简单的向量加法,如下所示:

#include <cuda.h>
#include <builtin_types.h>
#include <drvapi_error_string.h>

#include <QtCore/QCoreApplication>
#include <QDebug>

// Forward declare the function in the .cu file
void vectorAddition(const float* a, const float* b, float* c, int n);

void printArray(const float* a, const unsigned int n) {
    QString s = "(";
    unsigned int ii;
    for (ii = 0; ii < n - 1; ++ii)
        s.append(QString::number(a[ii])).append(", ");
    s.append(QString::number(a[ii])).append(")");

    qDebug() << s;
}

int main(int argc, char* argv [])
{
    QCoreApplication(argc, argv);

    int deviceCount = 0;
    int cudaDevice = 0;
    char cudaDeviceName [100];

    unsigned int N = 50;
    float *a, *b, *c;

    cuInit(0);
    cuDeviceGetCount(&deviceCount);
    cuDeviceGet(&cudaDevice, 0);
    cuDeviceGetName(cudaDeviceName, 100, cudaDevice);
    qDebug() << "Number of devices: " << deviceCount;
    qDebug() << "Device name:" << cudaDeviceName;

    a = new float [N];    b = new float [N];    c = new float [N];
    for (unsigned int ii = 0; ii < N; ++ii) {
        a[ii] = qrand();
        b[ii] = qrand();
    }

    // This is the function call in which the kernel is called
    vectorAddition(a, b, c, N);

    qDebug() << "input a:"; printArray(a, N);
    qDebug() << "input b:"; printArray(b, N);
    qDebug() << "output c:"; printArray(c, N);

    if (a) delete a;
    if (b) delete b;
    if (c) delete c;
}
#include <cuda.h>
#include <builtin_types.h>

extern "C"
__global__ void vectorAdditionCUDA(const float* a, const float* b, float* c, int n)
{
    int ii = blockDim.x * blockIdx.x + threadIdx.x;
    if (ii < n)
        c[ii] = a[ii] + b[ii];
}

void vectorAddition(const float* a, const float* b, float* c, int n) {
    float *a_cuda, *b_cuda, *c_cuda;
    unsigned int nBytes = sizeof(float) * n;
    int threadsPerBlock = 256;
    int blocksPerGrid   = (n + threadsPerBlock - 1) / threadsPerBlock;

    // allocate and copy memory into the device
    cudaMalloc((void **)& a_cuda, nBytes);
    cudaMalloc((void **)& b_cuda, nBytes);
    cudaMalloc((void **)& c_cuda, nBytes);
    cudaMemcpy(a_cuda, a, nBytes, cudaMemcpyHostToDevice);
    cudaMemcpy(b_cuda, b, nBytes, cudaMemcpyHostToDevice);

    vectorAdditionCUDA<<<blocksPerGrid, threadsPerBlock>>>(a_cuda, b_cuda, c_cuda, n);

    // load the answer back into the host
    cudaMemcpy(c, c_cuda, nBytes, cudaMemcpyDeviceToHost);

    cudaFree(a_cuda);
    cudaFree(b_cuda);
    cudaFree(c_cuda);
}
#包括
#包括
外部“C”
__全局无效向量添加CUDA(常量浮点*a、常量浮点*b、浮点*c、整数n)
{
int ii=blockDim.x*blockIdx.x+threadIdx.x;
if(ii
如果你能做到这一点,那么我认为更复杂的例子是不言而喻的


编辑(24-1-2013):我添加了
QMAKE\u LFLAGS\u DEBUG=/NODEFAULTLIB:msvctd.lib
和带有额外
D\u DEBUG
标志的
CONFIG(DEBUG)
,这样它也可以在调试模式下编译。

使用msvc 2010我发现链接器不接受-l参数,但nvcc需要它。因此,我在.pro文件中做了一个简单的更改:

# Add the necessary libraries
CUDA_LIBS = cuda cudart
# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
# LIBRARIES IN FORMAT NEEDED BY NVCC
NVCC_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
# LIBRARIES IN FORMAT NEEDED BY VISUAL C++ LINKER
LIBS += $$join(CUDA_LIBS,'.lib ', '', '.lib')
和nvcc命令(发布版本):

插入了$$NVCC_LIBS而不是$$LIBS。 适用于我的整个.pro文件:

QT       += core

QT       -= gui

TARGET = TestCUDA
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app

# Define output directories
DESTDIR = release
OBJECTS_DIR = release/obj
CUDA_OBJECTS_DIR = release/cuda

# Source files
SOURCES += main.cpp

# This makes the .cu files appear in your project
OTHER_FILES +=  vectorAddition.cu

# CUDA settings <-- may change depending on your system
CUDA_SOURCES += vectorAddition.cu
#CUDA_SDK = "C:/ProgramData/NVIDIA Corporation/NVIDIA GPU Computing SDK 4.2/C"   # Path to cuda SDK install
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v5.0"           # Path to cuda toolkit install
SYSTEM_NAME = win32         # Depending on your system either 'Win32', 'x64', or 'Win64'
SYSTEM_TYPE = 32            # '32' or '64', depending on your system
CUDA_ARCH = sm_11           # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
NVCC_OPTIONS = --use_fast_math

# include paths
INCLUDEPATH += $$CUDA_DIR/include
               #$$CUDA_SDK/common/inc/ \
               #$$CUDA_SDK/../shared/inc/

# library directories
QMAKE_LIBDIR += $$CUDA_DIR/lib/$$SYSTEM_NAME
                #$$CUDA_SDK/common/lib/$$SYSTEM_NAME \
                #$$CUDA_SDK/../shared/lib/$$SYSTEM_NAME


# The following library conflicts with something in Cuda
QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
QMAKE_LFLAGS_DEBUG   = /NODEFAULTLIB:msvcrtd.lib

# Add the necessary libraries
CUDA_LIBS = cuda cudart
# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
NVCC_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
LIBS += $$join(CUDA_LIBS,'.lib ', '', '.lib')

# Configuration of the Cuda compiler
CONFIG(debug, debug|release) {
    # Debug mode
    cuda_d.input = CUDA_SOURCES
    cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
    cuda_d.commands = $$CUDA_DIR/bin/nvcc.exe -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
    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}_cuda.o
    cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
    cuda.dependency_type = TYPE_C
    QMAKE_EXTRA_COMPILERS += cuda
}
QT+=core
QT-=gui
目标=TestCUDA
配置+=控制台
配置-=应用程序包
模板=应用程序
#定义输出目录
DESTDIR=释放
对象\u DIR=释放/obj
CUDA_OBJECTS_DIR=发布/CUDA
#源文件
SOURCES+=main.cpp
#这会使.cu文件出现在项目中
其他_文件+=vectorAddition.cu

#CUDA设置我尝试了这种组合。由于中存在许多依赖项,无法使其工作 我的项目。 我的最终解决方案是在Windows上将应用程序分成两个独立的应用程序 (一)

  • 在VC中开发的CUDA应用程序,在Windows中作为服务/DLL运行
  • 在QT中开发的GUI界面,并使用DLL执行CUDA相关任务

  • 希望它能为其他人节省一些时间

    嗨,我几乎可以正常工作了——除了它没有创建
    vectorAddition.obj
    ,我得到
    链接:致命错误LNK1181:无法打开输入文件'release\obj\vectorAddition.obj'
    。我注意到
    vectorAddition\u cuda.o
    是创建的,所以它已经通过了那个阶段,
    main.obj
    也被创建了。你知道如何让它(第10节,来自VS2010)生成
    vectorAddition.obj
    ?好的,我解决了这个问题。您在这里为我节省了大量的时间,非常感谢。您好,您是否有机会发布此文件的64位版本,即经过适当修改的.pro文件?我一直在试图找出如何调整路径等,但就是不能很好地把它放在一起。我没有64位系统,所以我没有办法测试它。但我认为,您所需要做的就是将系统文件夹和类型更改为64,其他内容保持不变。像这样:
    SYSTEM\u NAME=Win32
    SYSTEM\u TYPE=32
    这样行吗?嗯,恐怕我没什么道理,但无可否认,我对编译器64位程序没有太多经验。我有点惊讶警告说,它正在
    /lib
    中查找东西。您确定已将
    系统名称
    更改为
    x64
    ?如果不是这样,我建议你就这个错误开始一个新的主题。那么你的意思是我不能有一个包含.cpp和.cu文件的项目?iwant.cpp文件使用gcc编译,cu使用NVCC,我需要在.cpp中使用cu文件中的所有函数
    QT       += core
    
    QT       -= gui
    
    TARGET = TestCUDA
    CONFIG   += console
    CONFIG   -= app_bundle
    
    TEMPLATE = app
    
    # Define output directories
    DESTDIR = release
    OBJECTS_DIR = release/obj
    CUDA_OBJECTS_DIR = release/cuda
    
    # Source files
    SOURCES += main.cpp
    
    # This makes the .cu files appear in your project
    OTHER_FILES +=  vectorAddition.cu
    
    # CUDA settings <-- may change depending on your system
    CUDA_SOURCES += vectorAddition.cu
    #CUDA_SDK = "C:/ProgramData/NVIDIA Corporation/NVIDIA GPU Computing SDK 4.2/C"   # Path to cuda SDK install
    CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v5.0"           # Path to cuda toolkit install
    SYSTEM_NAME = win32         # Depending on your system either 'Win32', 'x64', or 'Win64'
    SYSTEM_TYPE = 32            # '32' or '64', depending on your system
    CUDA_ARCH = sm_11           # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
    NVCC_OPTIONS = --use_fast_math
    
    # include paths
    INCLUDEPATH += $$CUDA_DIR/include
                   #$$CUDA_SDK/common/inc/ \
                   #$$CUDA_SDK/../shared/inc/
    
    # library directories
    QMAKE_LIBDIR += $$CUDA_DIR/lib/$$SYSTEM_NAME
                    #$$CUDA_SDK/common/lib/$$SYSTEM_NAME \
                    #$$CUDA_SDK/../shared/lib/$$SYSTEM_NAME
    
    
    # The following library conflicts with something in Cuda
    QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
    QMAKE_LFLAGS_DEBUG   = /NODEFAULTLIB:msvcrtd.lib
    
    # Add the necessary libraries
    CUDA_LIBS = cuda cudart
    # The following makes sure all path names (which often include spaces) are put between quotation marks
    CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
    NVCC_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
    LIBS += $$join(CUDA_LIBS,'.lib ', '', '.lib')
    
    # Configuration of the Cuda compiler
    CONFIG(debug, debug|release) {
        # Debug mode
        cuda_d.input = CUDA_SOURCES
        cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
        cuda_d.commands = $$CUDA_DIR/bin/nvcc.exe -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
        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}_cuda.o
        cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
        cuda.dependency_type = TYPE_C
        QMAKE_EXTRA_COMPILERS += cuda
    }