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