2015-11-23 3 views
1

Мне сложно интегрировать CUDA в создателя Qt.CUDA, создатель Qt и Mac

Я уверен, что проблема связана с неправильной информацией в моем файле .pro. Я разместил свой текущий файл .pro, мой .cu-файл (DT_GPU.cu), а затем ошибки ниже этого.

Я пробовал много комбинаций файлов .pro, взятых из linux и windows, но ничего не работает. Кроме того, я никогда не видел файл Mac/CUDA .pro, так что это может быть полезным источником для будущих людей, надеющихся заставить всех трех работать вместе.

Заранее благодарим за любую помощь.

.pro файл:

CUDA_SOURCES += ../../Source/DT_GPU/DT_GPU.cu 

CUDA_DIR = "/Developer/NVIDIA/CUDA-7.5" 


SYSTEM_TYPE = 64   # '32' or '64', depending on your system 
CUDA_ARCH = sm_21   # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10' 
NVCC_OPTIONS = --use_fast_math 


# include paths 
INCLUDEPATH += $$CUDA_DIR/include 

# library directories 
QMAKE_LIBDIR += $$CUDA_DIR/lib/ 

CUDA_OBJECTS_DIR = ./ 


# Add the necessary libraries 
CUDA_LIBS = -lcublas_device \ 
    -lcublas_static \ 
    -lcudadevrt \ 
    -lcudart_static \ 
    -lcufft_static \ 
    -lcufftw_static \ 
    -lculibos \ 
    -lcurand_static \ 
    -lcusolver_static \ 
    -lcusparse_static \ 
    -lnppc_static \ 
    -lnppi_static \ 
    -lnpps_static 

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

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

DT_GPU.cu

#include <cuda.h> 
#include <cuda_runtime.h> 
#include <device_launch_parameters.h> 

__global__ void zero_GPU(double *l_p_array_gpu) 
{ 
    int i = threadIdx.x; 
    printf(" %i: Hello World!\n", i); 
    l_p_array_gpu[i] = 0.; 
} 

void zero(double *l_p_array, int a_numElements) 
{ 
    double *l_p_array_gpu; 

    int size = a_numElements * int(sizeof(double)); 

    cudaMalloc((void**) &l_p_array_gpu, size); 

    cudaMemcpy(l_p_array_gpu, l_p_array, size, cudaMemcpyHostToDevice); 

    zero_GPU<<<size,1>>>(l_p_array_gpu); 

    cudaMemcpy(l_p_array, l_p_array_gpu, size, cudaMemcpyDeviceToHost); 

    cudaFree(l_p_array_gpu); 
} 

Предупреждения:

Makefile:848: warning: overriding commands for target `DT_GPU_cuda.o' 
Makefile:792: warning: ignoring old commands for target `DT_GPU_cuda.o' 
Makefile:848: warning: overriding commands for target `DT_GPU_cuda.o' 
Makefile:792: warning: ignoring old commands for target `DT_GPU_cuda.o' 

Ошибки:

In file included from ../SimplexSphereSource.cpp:8: 
../../../Source/DT_GPU/DT_GPU.cu:75:19: error: expected expression 
     zero_GPU<<<size,1>>>(l_p_array_gpu); 
       ^
../../../Source/DT_GPU/DT_GPU.cu:75:28: error: expected expression 
     zero_GPU<<<size,1>>>(l_p_array_gpu); 
         ^
2 errors generated. 
make: *** [SimplexSphereSource.o] Error 1 
16:47:18: The process "/usr/bin/make" exited with code 2. 
Error while building/deploying project SimplexSphereSource (kit: Desktop Qt 5.4.0 clang 64bit) 
When executing step "Make" 

ответ

1

Мне удалось запустить ваш пример с небольшими корректировками в файл .pro. Если вы или кто-либо еще по-прежнему интересуетесь более крупным примером C++/CUDA/Qt для Mac и Linux, проверьте this answer несколько месяцев назад. Ваша конкретная ситуация (или, по крайней мере, то, что вы предоставили) не требует всех дополнительных фреймворков Qt и настройки графического интерфейса, поэтому файл .pro остается довольно простым.

Если вы еще этого не сделали, убедитесь, что у вас есть последние драйверы CUDA Mac и проверьте, что некоторые из основных образцов CUDA скомпилированы и запущены. настоящее время я использую:

  • OSX версии 10.10.5
  • Qt 5.5.0
  • NVCC v7.5.17

Я добавил главный метод в файл DP_GPU.cu вы предоставили и успешно выполнили программу, используя ваш файл .pro с несколькими изменениями:

#CUDA_SOURCES += ../../Source/DT_GPU/DT_GPU.cu 
CUDA_SOURCES += DT_GPU.cu # <-- same dir for this small example 

CUDA_DIR = "/Developer/NVIDIA/CUDA-7.5" 


SYSTEM_TYPE = 64   # '32' or '64', depending on your system 
CUDA_ARCH = sm_21   # (tested with sm_30 on my comp) Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10' 
NVCC_OPTIONS = --use_fast_math 


# include paths 
INCLUDEPATH += $$CUDA_DIR/include 

# library directories 
QMAKE_LIBDIR += $$CUDA_DIR/lib/ 

CUDA_OBJECTS_DIR = ./ 


# Add the necessary libraries 
CUDA_LIBS = -lcudart # <-- changed this 

# The following makes sure all path names (which often include spaces) are put between quotation marks 
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"') 
#LIBS += $$join(CUDA_LIBS,'.so ', '', '.so') <-- didn't need this 
LIBS += $$CUDA_LIBS # <-- needed this 


# SPECIFY THE R PATH FOR NVCC (this caused me a lot of trouble before) 
QMAKE_LFLAGS += -Wl,-rpath,$$CUDA_DIR/lib # <-- added this 
NVCCFLAGS = -Xlinker -rpath,$$CUDA_DIR/lib # <-- and this 

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

И DP_GPU.cu файл с основной функцией и некоторыми незначительными изменениями:

#include <cuda.h> 
#include <cuda_runtime.h> 
#include <device_launch_parameters.h> 
#include <stdio.h> // <-- added for 'printf' 


__global__ void zero_GPU(double *l_p_array_gpu) 
{ 
    int i = blockIdx.x * blockDim.x + threadIdx.x; // <-- in case you use more blocks 
    printf(" %i: Hello World!\n", i); 
    l_p_array_gpu[i] = 0.; 
} 


void zero(double *l_p_array, int a_numElements) 
{ 
    double *l_p_array_gpu; 

    int size = a_numElements * int(sizeof(double)); 

    cudaMalloc((void**) &l_p_array_gpu, size); 

    cudaMemcpy(l_p_array_gpu, l_p_array, size, cudaMemcpyHostToDevice); 

    // use one block with a_numElements threads 
    zero_GPU<<<1, a_numElements>>>(l_p_array_gpu); 

    cudaMemcpy(l_p_array, l_p_array_gpu, size, cudaMemcpyDeviceToHost); 

    cudaFree(l_p_array_gpu); 
} 

// added a main function to run the program 
int main(void) 
{ 
    // host variables 
    const int a_numElements = 5; 
    double l_p_array[a_numElements]; 

    // run cuda function 
    zero(l_p_array, a_numElements); 

    // Print l_p_array 
    printf("l_p_array: { "); 
    for (int i = 0; i < a_numElements; ++i) 
    { 
     printf("%.2f ", l_p_array[i]); 
    } 
    printf("}\n"); 

    return 0; 
} 

Выход:

0: Hello World! 
    1: Hello World! 
    2: Hello World! 
    3: Hello World! 
    4: Hello World! 
l_p_array: { 0.00 0.00 0.00 0.00 0.00 } 

После того, как вы получите эту работу убедитесь, что потребуется некоторое время, проверяя базовый синтаксис CUDA и примеры, прежде чем зайти слишком далеко. В противном случае отладка будет настоящей проблемой. Поскольку я здесь, хотя я решил, что я также дам вам знать, что синтаксис ядра CUDA равен
kernel_function<<<block_size, thread_size>>>(args).
Ваш вызов ядра zero_GPU<<<size,1>>>(l_p_array_gpu) фактически создал бы кучу блоков с одним потоком, когда вы действительно хотите обратное.

Следующие функции приходят из образцов CUDA и поможет определить, сколько потоков и блоков нужно для заданного числа элементов:

typedef unsigned int uint; 

inline uint iDivUp(uint a, uint b) 
{ 
    return (a % b != 0) ? (a/b + 1) : (a/b); 
} 

// compute grid and thread block size for a given number of elements 
inline void computeGridSize(uint n, uint blockSize, uint &numBlocks, uint &numThreads) 
{ 
    numThreads = min(blockSize, n); 
    numBlocks = iDivUp(n, numThreads); 
} 

Вы можете добавить их в верхней части файла .cu или к helper header file и использовать их для правильного вызова функций ядра. Если вы хотите использовать их в файле DP_GPU.cu вы бы просто добавить:

// desired thread count (may change if there aren't enough elements) 
dim3 threads(64); 
// default block count (will also change based on number of elements) 
dim3 blocks(1); 
computeGridSize(a_numElements, threads.x, blocks.x, threads.x); 

// run kernel 
zero_GPU<<<blocks, threads>>>(l_p_array_gpu); 

Во всяком случае, есть немного отвлекаться, но я надеюсь, что это помогает! Ура!

+1

Большое спасибо за помощь, ваш пример работает в кратчайшие сроки! Теперь работаем над тем, как расширить этот пример для многих элементов (~ 10E8) вместо 5 ... – mbcx9rb9

Смежные вопросы