c++ - 使用 CUDA 代码编译 MINPACK 库的问题
问题描述
我需要求解一个非线性方程组,我找到了 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
我的主要文件是:
主文件
#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
thenmake
和make install
. 然后我去了源文件夹并做了make cuda
. 最后一个命令libcuminpack.a
在目录中生成文件cuda
,然后我将此.a
文件复制到/usr/local/lib64
cmake 安装其他库文件的位置。
如果有人可以帮助我,我将非常感激
编辑
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 */
...
解决方案
根据talonmies 的评论,我能够编译在文件中定义__device__
函数的代码。dpmpar
main.cu
然后我发现这篇文章https://forums.developer.nvidia.com/t/external-calls-to-device-functions/17737那个人回答说 CUDA 在设备端没有链接器,所以不是可以__device__
从不同的.cu
文件调用函数。
考虑到这一点,我只从库中复制了我需要的文件并进行了一些修改,比如更改__cminpack_attr__
为__device__
并重写了头文件。所以基本上我制作了自己的设备库(再次感谢talonmies 的)。
我做的最后一件事是将所有这些新文件移动到我main.cu
和我的makefile
生活所在的同一个文件夹中,我重写了makefile
.
现在代码编译好了!!
推荐阅读
- c# - WritingAnimation 冻结 UI
- amazon-ec2 - 如何在 EC2 AWS 中使用 Route53 设置子域?
- c# - C# 编译器如何检测它必须以什么顺序解析文件/类型?
- matlab - 巨大的广播变量,没有parfor的优化代码?
- java - simple RxAndroid code not working
- r - 如何将徽标保留在闪亮应用程序的窗口标题中
- sphinx - Sphinx 在索引完成之前过早执行 sql_query_post_index 查询
- sql - 获取所有行以及sql中的重复列数
- java - Jenkins windows slave不断失去连接并出现错误:ClosedChannelException
- java - Vaadin 设置背景不起作用