代码之家  ›  专栏  ›  技术社区  ›  user2330963

编译多个cuda文件(具有动态并行性)和MPI代码

  •  0
  • user2330963  · 技术社区  · 6 年前

    我有一大堆。cu使用动态并行(a.cu、b.cu、c.cu..、e.cu、f.cu)和main的文件。使用MPI在多个节点上从a.cu调用函数的c文件。我试图编写一个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
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Robert Crovella    6 年前
    1. 报告的原始问题是未定义的引用 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公司 期望执行最终链接,但由于提供的对象中没有包含 主要的 作用正确的解决方案是使用 -数据链接 转换

    2. 我还建议将所有内容转换为C++风格的链接,因为 nvcc公司 以这种方式链接。也许可以将C风格的链接与C++风格的链接进行分类,但这对我来说似乎很麻烦。因此,我建议将 .c 文件( main.c )到a .cpp 文件,并从转换 mpicc mpicxx

    3. 出现的下一个问题是未定义的引用,例如。 cudaSetDevice() cudaFree() 。这些是CUDA运行时API库(“libcudart”)的一部分。执行最终链接时 nvcc公司 ,这些将自动链接。但由于最终链接是由 mpicxx (基本上是包装 g++ ),有必要调用针对该库的链接,特别是 -lcudart

    4. 最后,剩下的问题是链接顺序问题。简而言之,在链接器命令行中,需要从左到右满足链接依赖关系。不同的编译器对此或多或少都很挑剔。最后的重新排序更改是按照正确的顺序指定要链接的库,并在link命令行的末尾指定这些库,以便满足对这些库在link命令行左侧的任何依赖关系。