Многочисленные ошибки определения функций cuSparse при связывании файлов CUDA в исполняемом файле

Мой проект состоит из пяти файлов CUDA: main.cu jacobian_kernel.cu hermite_kernel.cu cuSolver_LU.cpp Utilities.cuпоследний из которых адаптирован из это GitHub репо, вместе с его 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

Теперь я уверен, что я включаю несколько раз заголовок helper_cusolver.h который предоставляется с CUDA Toolkit и который определяет функции vec_norminf, mat_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 директивы, по одному, но я продолжаю получать ту же ошибку.

Дайте мне знать, если я должен включить другую часть информации.

РЕДАКТИРОВАТЬ Кроме того, когда я обертываю функции CUDA и / или cuSolver с cudaCheckErrors образцов или citolveSafeCall GitHub в 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 правильно включен. Я думал, что это может быть полезной информацией, чтобы найти неправильную директиву.

0

Решение

Кажется, мне нужно навести порядок #include директивы. Как указал Роберт Кровелла, я удалил 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() Мне также удалось устранить ошибки определения функций-оболочек, на которые я указал в примечании к редактированию. Спасибо!

2

Другие решения

Других решений пока нет …