2016-10-20 52 views
1

我正在學習如何使用cmake編譯包含.cpp文件 和.cu文件的項目。目前我正在使用一個只有兩個文件一個main.cpp和kernel.cu的玩具示例。這些文件是如何使用cmake將cuda文件正確鏈接到cpp文件

main.cpp中:

#include <stdlib.h> 
#include <string.h> 
extern void kernel_wrapper(int *a, int *b); 

int main(int argc, char *argv[]){ 
    int a = 2; 
    int b = 3; 

    printf("Input: a = %d, b = %d\n",a,b); 
    kernel_wrapper(&a, &b); 
    printf("Ran: a = %d, b = %d\n",a,b); 
    return 0; 
} 

kernel.cu:

//#include "cuPrintf.cu" 
#include <stdio.h> 
__global__ void kernel(int *a, int *b){ 
    int tx = threadIdx.x; 
// cuPrintf("tx = %d\n", tx); 
    switch(tx){ 
    case 0: 
     *a = *a + 10; 
     break; 
    case 1: 
     *b = *b + 3; 
     break; 
    default: 
     break; 
    } 
} 

void kernel_wrapper(int *a, int *b){ 
// cudaPrintfInit(); 
    //cuPrintf("Anything...?"); 
    printf("Anything...?\n"); 
    int *d_1, *d_2; 
    dim3 threads(2, 1); 
    dim3 blocks(1, 1); 

    cudaMalloc((void **)&d_1, sizeof(int)); 
    cudaMalloc((void **)&d_2, sizeof(int)); 

    cudaMemcpy(d_1, a, sizeof(int), cudaMemcpyHostToDevice); 
    cudaMemcpy(d_2, b, sizeof(int), cudaMemcpyHostToDevice); 

    kernel<<< blocks, threads >>>(d_1, d_2); 
    cudaMemcpy(a, d_1, sizeof(int), cudaMemcpyDeviceToHost); 
    cudaMemcpy(b, d_2, sizeof(int), cudaMemcpyDeviceToHost); 
    printf("Output: a = %d\n", a[0]); 
    cudaFree(d_1); 
    cudaFree(d_2); 

// cudaPrintfDisplay(stdout, true); 
// cudaPrintfEnd(); 
} 

CMake的文件是從這個帖子的啓發:CMake script for CUDA 6.0 with C++11

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -lpthread") 
cmake_minimum_required(VERSION 3.2) 
project(CUDAAndCP) 
find_package(CUDA REQUIRED) 

# For compilation ... 
# Specify target & source files to compile it from 

# Pass options to NVCC 
set(
    CUDA_NVCC_FLAGS 
    ${CUDA_NVCC_FLAGS}; 
    -O3 -gencode arch=compute_30,code=sm_30; 
    --std=c++11 
    ) 

cuda_add_library(kernel_obj kernel.cu) 
cuda_add_executable(main main.cpp) 
target_link_libraries(main ${CUDA_LIBRARIES}) 
target_link_libraries(main kernel_obj) 

我得到的主二進制文件編譯但當我運行它,結果是

Input: a = 2, b = 3 
Anything...? 
Output: a = 2 
Ran: a = 2, b = 3 

而不是

Input: a = 2, b = 3 
Anything...? 
Output: a = 2 
Ran: a = 12, b = 6 

我通過運行

g++ -c main.cpp 
nvcc -c kernel.cu 
nvcc -o main main.o kernel.o 

得到了正確的主二進制文件,所以它似乎是CUDA文件沒有正確地鏈接到主二進制文件。我真的不明白爲什麼和任何幫助表示讚賞!

我在ubuntu 14.04,cuda 7.5和cmake 3.2.0上運行這個。

+0

感謝您的更新m.s. 。我試圖將int main(){}放入kernel.cu中,現在不應該有任何鏈接問題,因爲它只是一個文件。然而,cuda_add_executable(main kernel.cu)仍然可以編譯,但仍然會給出錯誤的結果。 gpu內核根本沒有運行。但是nvcc kernel.cu會產生一個正確的二進制文件。 –

+0

時髦的是,當我註釋掉cmakeList.txt中的set {nvcc ...}部分時,得到的main是正確的!任何人都知道是什麼原因導致問題? –

回答

0

我相信代碼生成有些棘手。我的平臺與您的平臺相同,我使用的是GTX 980.

真正的問題是arch=compute_30,code=sm_30;。如果將其更改爲52,則一切正常。

如果使用裸指令行構建,CUDA 7.5 nvcc默認爲生成compute_20sm_20的代碼。

+0

將數字更改爲52作品!很奇怪。 –

相關問題