【发布时间】:2021-05-31 04:33:20
【问题描述】:
我需要求解一个非线性方程组,我找到了 MINPACK 库来完成这项工作。 但我需要代码才能与 CUDA 一起使用,但我无法编译代码。
我正面临这个问题:
nvcc -arch sm_61 -Iinc -I/usr/local/include obj/main.o -o oi -L/usr/local/lib64 -lcuminpack
nvlink error : Undefined reference to 'dpmpar' in 'obj/main.o'
make: *** [makefile:55: oi] Erro 255
我的主要文件是:
main.cu
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define __cminpack_double__
#include <cminpack-1/cminpack.h>
#define real __cminpack_real__
typedef struct{
real fnorm1, fnorm2;
int info;
real solution[2];
} ResultType;
__cminpack_attr__ int fcn(void *p, int n, const real *x, real *fvec, int iflag){
--fvec;
--x;
fvec[0] = x[0] + x[0]*x[1] - 4.0;
fvec[1] = x[0] + x[1] -3.0;
return 0;
}
__global__ void SolvingSystem(ResultType *pResults){
int info;
real fnorm1, fnorm2, tol;
int n = 2;
real fvec[2];
real x[2];
const int lwa = (n*(3*n + 13))/2;
real wa[50];
tol = sqrt(dpmpar(1));
x[0] = 1.98;
x[1] = 1.02;
printf("Initial Guess: %g, %g\n", x[0], x[1]);
}
int main(int argc, char const *argv[]){
cudaSetDevice(0);
ResultType *reuslt_GPU, *reuslt_CPU;
cudaMalloc((void**)&reuslt_GPU, sizeof(ResultType));
cudaMallocHost((void**)&reuslt_CPU, sizeof(ResultType));
printf("Solving System...\n");
dim3 grid(1, 1, 1);
dim3 block(1, 1, 1);
SolvingSystem<<< grid, block>>>(reuslt_GPU);
cudaDeviceSynchronize();
printf("Done!\n");
return 0;
}
我的makefile是:
制作文件
# MakeFile
# Program Name
EXE = oi
# Compilers
NVCC := nvcc
ALL_LIBRARIES := cuminpack
LIBDIR := /usr/local/lib64
# Directories
SRCDIR := src
OBJDIR := obj
INCDIR := inc /usr/local/include
#Flags
NVCCARCHFLAG := -arch sm_61
NVCCFLAGS := -std=c++11
LDFLAGS := $(addprefix -L, $(LIBDIR))
INCLUDES := $(addprefix -I, $(INCDIR))
LIBRARIES := $(addprefix -l, $(ALL_LIBRARIES))
LIBRARIES +=
ALL_CPFLAGS := -MMD
ALL_CPFLAGS += $(NVCCARCHFLAG)
ALL_CPFLAGS += $(NVCCFLAGS)
ALL_LDFLAGS := $(LDFLAGS)
# Files
C_FILES := $(wildcard $(SRCDIR)/*.c)
CU_FILES := $(wildcard $(SRCDIR)/*.cu)
C_OBJ := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(C_FILES))
CU_OBJ := $(patsubst $(SRCDIR)/%.cu, $(OBJDIR)/%.o, $(CU_FILES))
C_DEP := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.d, $(C_FILES))
CU_DEP := $(patsubst $(SRCDIR)/%.cu, $(OBJDIR)/%.d, $(CU_FILES))
SRC := $(C_FILES) $(CU_FILES)
OBJ := $(C_OBJ) $(CU_OBJ)
DEP := $(C_DEP) $(CU_DEP)
COMPILE.c := $(NVCC) -MMD -g $(INCLUDES) -c
COMPILE.cu := $(NVCC) $(ALL_CPFLAGS) $(INCLUDES) -dc
.PHONY: all clean
all:$(EXE)
$(EXE): $(OBJ)
$(NVCC) $(NVCCARCHFLAG) $(INCLUDES) $^ -o $@ $(ALL_LDFLAGS) $(LIBRARIES)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(COMPILE.c) $< -o $@
$(OBJDIR)/%.o: $(SRCDIR)/%.cu | $(OBJDIR)
$(COMPILE.cu) $< -o $@
$(OBJDIR):
@mkdir -p $@
# Cleaning up
clean:
@echo Cleaning up...
@rm -f -r $(OBJDIR)
@rm $(EXE)
# Including dependency
-include $(DEP)
主文件需要完成,这就是一些未使用变量的原因。
我只是不知道是什么导致了这个错误,我认为问题出在 cuminpack 库中,但我现在不知道如何解决它。
我正在使用来自该网站的 cminpack-1.3.8:http://devernay.free.fr/hacks/cminpack/
我使用cmake 然后make 和make install 安装了库。然后我去了源文件夹并做了make cuda。最后一条命令在cuda 目录中生成了libcuminpack.a 文件,然后我将此.a 文件复制到了cmake 安装其他库文件的/usr/local/lib64。
如果有人能帮助我,我将非常感激
编辑
来自 cminpack 库的文件
cminpack.h
...
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
...
#if defined(__CUDA_ARCH__) || defined(__CUDACC__)
#define __cminpack_attr__ __device__
#ifndef __cminpack_real__
#define __cminpack_float__
#define __cminpack_real__ float
#endif
#define __cminpack_type_fcn_nn__ __cminpack_attr__ int fcn_nn
#define __cminpack_type_fcnder_nn__ __cminpack_attr__ int fcnder_nn
#define __cminpack_type_fcn_mn__ __cminpack_attr__ int fcn_mn
#define __cminpack_type_fcnder_mn__ __cminpack_attr__ int fcnder_mn
#define __cminpack_type_fcnderstr_mn__ __cminpack_attr__ int fcnderstr_mn
#define __cminpack_decl_fcn_nn__
#define __cminpack_decl_fcnder_nn__
#define __cminpack_decl_fcn_mn__
#define __cminpack_decl_fcnder_mn__
#define __cminpack_decl_fcnderstr_mn__
#define __cminpack_param_fcn_nn__
#define __cminpack_param_fcnder_nn__
#define __cminpack_param_fcn_mn__
#define __cminpack_param_fcnder_mn__
#define __cminpack_param_fcnderstr_mn__
...
__cminpack_attr__
__cminpack_real__ CMINPACK_EXPORT __cminpack_func__(dpmpar)( int i );
dpmpar.c
#include "cminpack.h"
#include <float.h>
#include "cminpackP.h"
#define DPMPAR(type,X) _DPMPAR(type,X)
#define _DPMPAR(type,X) type ## _ ## X
__cminpack_attr__
real __cminpack_func__(dpmpar)(int i)
{
/* ********** */
/* Function dpmpar */
...
【问题讨论】:
-
您在 CUDA 内核中调用
dpmpar。这意味着要让它在那里工作 必须 有一个名为dpmpar的专用 CUDA__device__函数,它可以通过您导入的标头或在库中内联定义。如果它在库中,那么您必须使用 CUDA 单独编译和设备链接来构建代码。如果不是这两件事中的任何一个,那么您就处于神奇的思维领域,而您正在尝试做的是在 CUDA 内核中使用随机主机函数,而这永远不会起作用。我不能告诉你其中哪一项适用于这里 -
我将部分头文件和
dpmpar.c的开头从 cminpack 库添加到帖子中。如果我没记错的话,库作者通过__cminpack_attr__定义了__device__函数。所以,这意味着我需要使用 CUDA 单独编译和设备链接,对吗?但这不是用-dc标志完成的吗? -
刚刚查看了库,我看到这个“cuda 需要与内核内联编译的 __device__ 源代码”。因此,您的整个构建过程将无法使用提供的此库。您也许可以从代码中创建自己的设备库,但据我所知,您需要自己为库创建一个新的 Makefile
-
我想到了你说的解决了这个问题!!非常感谢!!
-
@MatheusIurk 是一种并行算法吗?我会很高兴错了,因为我认为这是连续剧。