我的项目包含五个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
。
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
现在,我非常确定我会多次提供CUDA工具包提供的标题helper_cusolver.h
,并定义函数vec_norminf
,{{1}等等。我无法猜测如何重写我的标题,开头如下:
args.h:
mat_norminf
linear_solver.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
Utilities.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
此外,依赖关系是:
#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
初始指令与其他cuda文件开头的指令略有不同,但它是我项目的最新成员,在添加之前我得到了同样的错误;无论如何,这是:
Utilities.cu
长话短说,问题似乎是#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
上的警卫。
我是C / C ++的初学者,我真的不知道如何从这里开始。我试图一次取消注释大多数(显然是多个)helper_cusolver
指令,但我一直得到同样的错误。
如果我应该包含其他信息,请告诉我。
编辑此外,当我使用样本的cudaCheckErrors或者Utilities.cu中的GitHub的cusolveSafeCall包装CUDA和/或cuSolver函数时,它们似乎没有被定义:
#include
虽然正确包含了头部Utilities.h。我认为这可能是有用的信息,以便找到不正确的指令。
答案 0 :(得分:2)
似乎我需要清理#include
指令。正如Robert Crovella所指出的,我从helper_cusolver.h
中删除了linear_solver.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()
我也设法解决了包装函数的定义错误,我在编辑说明中指出了这一点。谢谢!
答案 1 :(得分:0)
如果有多个文件需要“ helper_cusolver.h”,则此解决方案将不起作用。.我通过在此文件中的每个函数之前添加“静态”来解决该问题。请注意,“ helper_cuda.h”中的函数具有此“静态”,这就是为什么可以多次包含它而不会出现问题的原因。
或者更好,请参见https://codeyarns.com/2010/08/26/c-static-function-in-header-file/