我正在第一次尝试构建一个充满 CUDA 例程的
.so
。我有 matrix_vector_mult.cu
文件,目前什么也不做:
#include <stdio.h>
extern "C"
double *
matrix_vector_mult(const double ** const M,
const double * const v,
const size_t num_rows,
const size_t num_cols)
{
printf("Hello!\n");
double * p = (double *) malloc(num_rows*sizeof(double));
return p;
}
我还有一个makefile,其内容如下:
CC := clang
UNAME := $(shell uname -s)
ifeq ($(UNAME), Darwin)
CUDA_PATH := /Developer/NVIDIA/CUDA-6.5
CUDA_LIB := ${CUDA_PATH}/lib
endif
ifeq ($(UNAME), Linux)
CUDA_PATH := /usr/local/cuda-6.5
CUDA_LIB := ${CUDA_PATH}/lib64
endif
LIBS := -L ${CUDA_LIB} -lcudart -lcudadevrt
NVCC := ${CUDA_PATH}/bin/nvcc -ccbin ${CC}
CFLAGS := -g -std=c11 -Wextra -Wall -I include -rpath ${CUDA_LIB}
NVCCFLAGS := -g -m64 -D__STRICT_ANSI__
vpath %.cu src
vpath %.h include
all: matrix_vector_mult.o
${CC} ${CFLAGS} -o matrix_vector_mult.so -shared -fPIC $^ ${LIBS}
matrix_vector_mult.o: matrix_vector_mult.cu
${NVCC} ${NVCCFLAGS} -o $@ -c $^
clean:
rm -f *.o *.so *.pyc
在 Mac 上,编译得很好。然而,在我的 Ubuntu 机器上,我收到错误消息:
/usr/bin/ld: matrix_vector_mult.o: relocation R_X86_64_32S against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
matrix_vector_mult.o: error adding symbols: Bad value
可能是什么问题? (将
-fPIC
添加到编译行不起作用。)nvcc --version
在两个框中产生相同的信息,clang --version
给出
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
在 Mac 上,以及
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
在 Ubuntu 盒子上。我有点怀疑 LLVM 版本的轻微差异是问题所在,因为我已经将 makefile 视为一团糟了。任何帮助表示赞赏。
构建宿主对象的共享库通常需要编译这些对象,以便它们仅包含位置无关的代码。正如错误消息所示,您可以在使用 gcc 的 gnu-linux 系统上使用
-fPIC
主机编译器选项来执行此操作。
nvcc 包含一个选项
-XCompiler
,可用于将选项传递给主机编译器。因此,在用于生成用于构建共享库的主机代码的编译语句中添加 -XCompiler="-fPIC"
可用于解决此特定问题。
上图:“nvcc 包含一个选项 -XCompiler”。一个小错字,该选项目前至少是 -Xcompiler 并带有小写 c。我有一段时间相信这不再起作用,因为复制粘贴产生了错误......但只需使用小写 c 即可。
(我无法将其添加为上面的简单评论,因为我没有足够的声誉来限制 50。)