我有一堆.cu文件使用动态并行(a.cu,b.cu,c.cu ..,e.cu,f.cu),以及一个使用MPI调用的main.c文件来自多个节点上的a.cu的函数。我正在尝试编写一个make文件来编译可执行文件,但我一直面临以下错误:
cudafiles.o: In function `__cudaRegisterLinkedBinary_66_tmpxft_00001a84_00000000_17_cuda_device_runtime_compute_61_cpp1_ii_8b1a5d37':
link.stub:(.text+0x1fb): undefined reference to `__fatbinwrap_66_tmpxft_00001a84_00000000_17_cuda_device_runtime_compute_61_cpp1_ii_8b1a5d37'
这是我的makefile:
INCFILES=-I/usr/local/cuda-8.0/include -I/opt/mpi/mvapich2-gnu/2.2/include -I./
LIBFILES=-L/usr/local/cuda-8.0/lib64 -L/opt/mpi/mvapich2-gnu/2.2/lib
LIBS=-lcudart -lcudadevrt -lcublas_device -lmpi
ARCH=-gencode arch=compute_60,code=sm_60
NVCC=nvcc -ccbin g++
default: all
all: clean final.o
io.o: io.cpp
g++ -c -std=c++11 io.cpp
final.o: io.o a.cu b.cu c.cu d.cu e.cu f.cu main.cpp
$(NVCC) -std=c++11 $(INCFILES) $(LIBFILES) $(LIBS) -g -G -Xptxas -v -dc $(ARCH) a.cu b.cu c.cu d.cu e.cu f.cu
$(NVCC) -std=c++11 $(ARCH) $(INCFILES) $(LIBFILES) $(LIBS) -rdc=true -dlink a.o b.o c.o d.o e.o f.o io.o -o cudafiles.o
mpicxx -O3 $(INCFILES) $(LIBFILES) -c main.cpp -o main.o
mpicxx $(INCFILES) $(LIBFILES) $(LIBS) cudafiles.o a.o b.o c.o d.o e.o f.o io.o main.o -o exec
clean:
rm -rf *.o exec
答案 0 :(得分:0)
报告的原始问题是对$cache->store('redis')->get('foo');
的未定义引用。这是由main
:
Makefile
构建时,这实际上指示$(NVCC) -std=c++11 $(ARCH) $(INCFILES) $(LIBFILES) $(LIBS) -rdc=true a.o b.o c.o d.o e.o f.o io.o -o cudafiles.o
执行完整/最终链接。但是,此行的目的是仅执行设备链接步骤,在使用nvcc
或-rdc=true
进行编译时以及未使用-dc
执行最终链接时需要。在这种情况下,最终链接由nvcc
/ mpicc
执行。要仅执行设备链接步骤,我们需要指定mpicxx
。如果没有该开关,-dlink
期望进行最终链接,但是失败,因为所提供的对象都不包含nvcc
函数。正确的解决方案,因为我们此时无意做最终链接,就是使用main
开关。
我还建议将所有内容转换为C ++样式链接,因为-dlink
以这种方式链接。也许可以用C ++风格的链接来整理C风格的链接,但这对我来说似乎很麻烦。因此,我建议将唯一的nvcc
文件(.c
)转换为main.c
文件,并将.cpp
转换为mpicc
出现的下一个问题是未定义的引用例如: mpicxx
和cudaSetDevice()
。这些是CUDA运行时API库的一部分(" libcudart")。与cudaFree()
执行最终链接时,会自动链接这些链接。但由于最后一个链接是由nvcc
执行的(基本上是mpicxx
上的包装器),因此必须使用g++
调用该库的链接。
最后,剩下的问题是链接顺序问题。简而言之,链接器依赖关系需要在链接器命令行中从左到右满足。不同的编译器或多或少对此有挑剔。最后的重新排序更改是指定要以正确顺序链接的库,还要在链接命令行的末尾指定这些库,以便在链接命令行的左侧对这些库的任何依赖性都是满意。