2016-11-28 18 views
0

我的項目由五個CUDA文件組成:main.cu jacobian_kernel.cu hermite_kernel.cu cuSolver_LU.cpp Utilities.cu,最後一個從this GitHub repo改編而來,連同它的Utilities.h頭文件;三個標題是args.h linear_solver.h Utilities.h當鏈接可執行文件中的CUDA文件時cuSparse函數的多個定義錯誤

NVCC編譯他們成功地,但在構建trbdf2可執行它罵我多重定義錯誤,如:

nvcc -Xcompiler -fopenmp -o obj/trbdf2 obj/jacobian_kernel.o obj/hermite_kernel.o obj/utils.o obj/cusolver_lu.o obj/main.o -I/usr/local/cuda-8.0/targets/x86_64-linux/include -I../include -I/usr/local/cuda-8.0/samples/common/inc/ -L/usr/local/cuda-8.0/targets/x86_64-linux/lib -lgomp -lcublas -lcudart -lcusolver -lcusparse 
obj/hermite_kernel.o: In function `vec_norminf(int, double const*)': 
tmpxft_00006336_00000000-4_hermite_kernel.cudafe1.cpp:(.text+0xba1): multiple definition of `vec_norminf(int, double const*)' 
obj/jacobian_kernel.o:tmpxft_00006312_00000000-4_jacobian_kernel.cudafe1.cpp:(.text+0xba1): first defined here 
obj/hermite_kernel.o: In function `mat_norminf(int, int, double const*, int)': 
tmpxft_00006336_00000000-4_hermite_kernel.cudafe1.cpp:(.text+0xc20): multiple definition of `mat_norminf(int, int, double const*, int)' 
obj/jacobian_kernel.o:tmpxft_00006312_00000000-4_jacobian_kernel.cudafe1.cpp:(.text+0xc20): first defined here 
... 
obj/main.o: In function `second()': 
tmpxft_00006385_00000000-4_main.cudafe1.cpp:(.text+0xf32): multiple definition of `second()' 
obj/jacobian_kernel.o:tmpxft_00006312_00000000-4_jacobian_kernel.cudafe1.cpp:(.text+0xf32): first defined here 
collect2: error: ld returned 1 exit status 
Makefile:17: recipe for target 'obj/trbdf2' failed 
make: *** [obj/trbdf2] Error 1 

現在,我敢肯定,我是包括多次頭helper_cusolver.h這是隨CUDA工具包一起提供,並定義功能vec_norminfmat_norminf等。我猜不出如何重寫我的頭,它開始如下:

args.h:

#if !defined(ARGS_H_) 
#define ARGS_H_ 

#include <stdio.h> 
#include <stdlib.h> 
#include <iostream> 
#include <math.h> 
#include <assert.h> 

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

#include "Utilities.h" 
... 
#endif 

linear_solver.h:

#ifndef LINEAR_SOLVER_H_ 
#define LINEAR_SOLVER_H_ 

#include <cublas_v2.h> 
#include <cusparse_v2.h> 
#include <cusolverDn.h> 

#include <helper_cusolver.h> 
... 
#endif 

Utilities.h:

#ifndef UTILITIES_CUH 
#define UTILITIES_CUH 

#include "linear_solver.h" 
... 
#endif 

此外,依賴關係是:

jacobian_kernel.cu, hermite_kernel.cu -> args.h 
cuSolver_LU.cpp -> args.h, linear_solver.h, Utilities.h 
main.cu -> args.h, linear_solver.h, Utilities.h 
Utilities.cu -> linear_solver.cu 

此外,Utilities.cu初始指令與其他cuda文件的初始指令有些不同,但它是我項目的最新補充,在添加它之前我得到了相同的錯誤;反正,那就是:

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

#if defined(__CUDACC__) && (CUDA_VERSION >= 7000) 
#include <cusolverDn.h> 
#endif 

#include <cublas_v2.h> 

#include "Utilities.h" 

長話短說,這個問題似乎是在helper_cusolver.h頭被包含超過一次,但我甚至把linear_solver.h頭的第一行中的某些頭文件保護;我試過了#pragma once指令,這個指令由nvcc支持,我甚至在helper_cusolver上檢查了警衛。

我是C/C++的初學者,我真的不知道如何從這裏開始。我試圖取消大多數(顯然是多個)#include指令,一次一次,但我一直得到相同的錯誤。

讓我知道我是否應該包含其他信息。

EDIT另外,當我包裹CUDA和/或cuSolver功能與樣品的cudaCheckErrors或GitHub的cusolveSafeCall在Utilities.cu,它們似乎不被定義:

cuSolver_LU.cpp: In function ‘void linearSolverLU(cusolverDnHandle_t, int, const double*, int, const double*, double*)’: 
cuSolver_LU.cpp:28:51: error: cannot convert ‘cudaError_t {aka cudaError}’ to ‘cusolverStatus_t’ for argument ‘1’ to ‘void cusolveSafeCall(cusolverStatus_t)’ 
    cusolveSafeCall(cudaMalloc(&info, sizeof(int))); 

雖然正確包含頭文件Utilities.h。我認爲這可能是有用的信息,以找到不正確的指令。

+1

如果在2個不同的編譯單元中包含相同的內容,則包含警衛和'#pragma once'將無濟於事。你真的需要哪些模塊需要'helper_cusolver.h'中的東西? –

+0

'cuSolver_LU'是唯一需要它的人;順便說一句,它是從CUDA樣本cuSolver – Eugenio

+0

改編的代碼,因此重新排列您的頭文件,以便「helper_cusolver.h」只包含在該模塊中。這可以像從任何和所有頭文件中去除'helper_cusolver.h'一樣簡單,並且直接在'cuSolver_LU.cpp'文件中直接放入include語句:'#include '。 –

回答

2

看來我需要清理#include指令。正如Robert Crovella所指出的那樣,我從linear_solver.h中刪除了helper_cusolver.h,而我將它放在了cuSolver_LU.cpp中,因爲它是編譯期間唯一需要它的文件,並且可能將其包含在更多文件中導致多重定義錯誤;現在cuSolver_LU.cpp是這樣開始的:

#include "args.h" 
#include "linear_solver.h" 
#include "Utilities.h" 
#include <helper_cusolver.h> 

extern "C" void cusolveSafeCall(cusolverStatus_t err); 

... 

此外,通過聲明cusolveSafeCall()我管理,以及解決在包裝功能,這是我在編輯筆記指出定義的錯誤。謝謝!

相關問題