在Windows上编译Qt Creator中的Cuda代码 [英] Compiling Cuda code in Qt Creator on Windows

查看:3596
本文介绍了在Windows上编译Qt Creator中的Cuda代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图获得一个Qt项目文件运行在32位的Windows 7系统,其中我想/需要包括Cuda代码。这种组合的东西要么是这么简单,没有人曾经打算在网上举一个例子,或者如此困难,没有人成功,似乎。无论如何,唯一有用的论坛线程我发现是在Linux或Mac上的相同的问题,或在Windows上的Visual Studio。
所有这些都给出各种不同的错误,然而,无论是链接或冲突的库,或文件名中的空格或Cuda SDK的Windows版本中不存在的文件夹。
是否有谁拥有清楚的 .pro 文件提供,这是骗局?

I have been trying for days to get a Qt project file running on a 32-bit Windows 7 system, in which I want/need to include Cuda code. This combination of things is either so simple that no one ever bothered to put an example online, or so difficult that nobody ever succeeded, it seems. Whatever way, the only helpful forum threads I found were the same issue on Linux or Mac, or with Visual Studio on a Windows. All of these give all sorts of different errors, however, whether due to linking or clashing libraries, or spaces in file names or non-existing folders in the Windows version of the Cuda SDK. Is there someone who has a clear .pro file to offer that does the trick?

我的目标是使用Qt风格的普通C ++代码编译一个简单的程序,使用Qt 4.8库,它引用.cu文件中的几个Cuda模块。形式如下:

I am aiming to compile a simple programme with ordinary C++ code in Qt style, with Qt 4.8 libraries, which reference several Cuda modules in .cu files. Something of the form:

TestCUDA \
    TestCUDA.pro
    main.cpp
    test.cu


推荐答案

code> .pro 文件,可以在我的,可能在所有Windows系统上。以下是一个简单的测试程序,应该可以做的伎俩。以下是一个小项目文件加测试程序,至少在我的系统上工作。

So I finally managed to assemble a .pro file that works on my and probably on all Windows systems. The following is an easy test programme that should probably do the trick. The following is a small project file plus test programme that works at least on my system.

文件系统如下所示:

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

}

注意 QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib :需要我很长时间out,但是这个库似乎与Cuda中的其他东西发生冲突,这会产生奇怪的连接警告和错误。

Note the QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib: it took me a long time to figure out, but this library seems to clash with other things in Cuda, which produces strange linking warnings and errors. If someone has an explanation for this, and potentially a prettier way to get around this, I'd like to hear it.

此外,由于Windows文件路径通常包含空格,因此,如果有人对此有解释,并且可能是更好的解决方法(默认情况下,NVIDIA的SDK也是如此),有必要在包含路径周围人为添加引号。再次,如果有人知道一个更优雅的方式来解决这个问题,我很想知道。

Also, since Windows file paths often include spaces (and NVIDIA's SDK by default does so too), it is necessary to artificially add quotation marks around the include paths. Again, if someone knows a more elegant way of solving this problem, I'd be interested to know.

main.cpp 文件如下所示:

#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;
}

Cuda文件 vectorAddition.cu ,它描述了一个简单的向量加法,看起来像这样:

The Cuda file vectorAddition.cu, which describes a simple vector addition, look like this:

#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);
}



如果你得到这个工作,那么更复杂的例子是不言而喻的,我认为。

If you get this to work, then more complicated examples are self-evident, I think.

编辑(24-1-2013):我添加了 QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:msvcrtd.lib CONFIG(debug)和额外的 D_DEBUG 标志,模式。

Edit (24-1-2013): I added the QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:msvcrtd.lib and the CONFIG(debug) with the extra D_DEBUG flag, such that it also compiles in debug mode.

这篇关于在Windows上编译Qt Creator中的Cuda代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆