将MPI和CUDA的编译与动态并行混合

时间:2014-01-12 22:39:50

标签: compiler-construction cuda mpi nvcc

当我想用动态并行支持编译MPI + CUDA混合程序时遇到了一个编译问题。

dyn_pal.cu的源代码

#include <stdio.h>
#include <cuda.h>
#define N 100
#define M 32
#define K 2
__device__ volatile int vint = 0;
__global__ void entry( volatile int* foo ) {
    for (int i = 0; i < N; ++i) {
        atomicAdd((int*)foo, 1);
    }
}

//extern "C" __global__ void diverge_cta( volatile int *foo )
extern "C" __global__ void diverge_cta( volatile int *foo )
{
  __shared__ int x;
  if ((threadIdx.x%32) != 0) {return;}
////    entry(foo);   //original design: each thread call entry()
    if (threadIdx.x == 0) {
        entry<<<1,M>>>( foo );
        cudaDeviceSynchronize();
        x = 5;
        return;
    }
    __syncthreads();
    atomicAdd((int*)foo, x);
}

extern "C" void mycal(int myrank){
    int *foo; int h_foo;
    cudaMalloc((void**)&foo, sizeof(int)); cudaMemset(foo, 0, sizeof(int));
    printf("foo addr: 0x%x\n", (unsigned)(size_t)foo);
    diverge_cta<<<K,M*32>>>( foo );
    cudaDeviceSynchronize();
    cudaMemcpy(&h_foo, foo, sizeof(int), cudaMemcpyDeviceToHost);
    if (h_foo == K*(M*N+5*(M-1))) {
        printf("simple_scan_test test PASSED\n");
    } else {
        printf("Result: %d\n", h_foo); printf("simple_scan_test test FAILED\n");
    }
}

MPI代码的源代码:indexed_gpu.c。

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
void diverge_cta( volatile int *foo);
void mycal(int myrank);

int main(int argc, char *argv[]){
  int myid, numprocs, i, j, k;
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  mycal(myid);
  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
  return EXIT_SUCCESS;
}

我使用的编译命令:

  • nvcc -arch = sm_35 -dc dyn_pal.cu -o dynpal.o -lcudadevrt
  • mpicc -c indexed_gpu.c -o mpi_bench.o
  • mpicc mpi_bench.o dynpal.o -o gpu_idx -L / opt / cuda / 5.5 / lib64 -lcudart

我得到的错误:

dynpal.o:在函数__sti____cudaRegisterAll_42_tmpxft_000044ae_00000000_6_dyn_pal_cpp1_ii_vint()': tmpxft_000044ae_00000000-3_dyn_pal.cudafe1.cpp:(.text+0x314): undefined reference to __ cudaRegisterLinkedBinary_42_tmpxft_000044ae_00000000_6_dyn_pal_cpp1_ii_vint' collect2:ld返回1退出状态

BTW,如果我在编译cuda目标文件(第1行)时没有包含'-dc',我收到了这个错误:

dyn_pal.cu(25):错误:从设备全局函数启动内核需要单独的编译模式 在编译“/tmp/tmpxft_00004303_00000000-6_dyn_pal.cpp1.ii”时检测到1错误。

如果我不使用MPI程序,支持并行性的纯CUDA程序可以在我的Kepler GPU上成功编译和运行。

我想知道,混合程序是否支持CUDA动态并行?

非常感谢。

1 个答案:

答案 0 :(得分:2)

  1. 我怀疑你发布的indexed_gpu.c源代码并不是真的 你在用什么你不需要包括cuda.h和 cuda_runtime.h在那个文件中,但根据我的理解 mpi,你需要在该文件中包含mpi.h。
  2. 使用此编译命令:nvcc -arch=sm_35 -dc dyn_pal.cu -o dynpal.o -lcudadevrt没有必要提供-lcudadevrt开关。这是一个链接器开关,您没有使用此命令链接任何内容。
  3. 参考nvcc documentation,我们看到当我们想分别使用主机链接器进行可执行文件的最终链接时,当我们使用单独的编译和链接时,需要执行额外的设备链接步骤(这是动态并行性所必需的。)
  4. 通过以下命令序列和上述更改,我能够编译和链接您的代码:

    nvcc -arch=sm_35 -dc dyn_pal.cu -o dynpal.o
    mpicc -c indexed_gpu.c -o mpi_bench.o
    nvcc -arch=sm_35 -dlink dynpal.o -o dynpal_link.o -lcudadevrt
    mpicc mpi_bench.o dynpal.o dynpal_link.o -o gpu_idx -L/opt/cuda/5.5/lib64 -lcudart