2015-01-12 32 views
2

我想通過this article中所述的CUDA感知MPI在不同CUDA設備之間交換數據。據我瞭解,下面的代碼應該做的工作:使用CUDA感知MPI的要求

#include <mpi.h> 

int main(int argc, char *argv[]) 
{ 
    int rank; 
    float *ptr = NULL; 
    const size_t elements = 32; 
    MPI_Status status; 

    MPI_Init(NULL, NULL); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    cudaMalloc((void**)&ptr, elements * sizeof(float)); 

    if(rank == 0) 
    MPI_Send(ptr, elements, MPI_FLOAT, 1, 0, MPI_COMM_WORLD); 
    if(rank == 1) 
    MPI_Recv(ptr, elements, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, &status); 

    cudaFree(ptr); 
    MPI_Finalize(); 

    return 0; 
} 

不幸的是,這個程序有段錯誤崩潰時,在兩個進程執行,給予以下消息:

*** Process received signal *** 
Signal: Segmentation fault (11) 
Signal code: Address not mapped (1) 
Failing at address: 0x210000 
[ 0] /lib64/libc.so.6[0x39d94326a0] 
[ 1] /lib64/libc.so.6(memcpy+0xd2)[0x39d9489742] 
[ 2] /usr/lib64/openmpi/lib/libopen-pal.so.6(opal_convertor_pack+0x18e)[0x2b750326cb1e] 
[ 3] /usr/lib64/openmpi/lib/openmpi/mca_btl_smcuda.so(mca_btl_smcuda_sendi+0x3dc)[0x2b7507c2252c] 
[ 4] /usr/lib64/openmpi/lib/openmpi/mca_pml_ob1.so(+0x890f)[0x2b75086ec90f] 
[ 5] /usr/lib64/openmpi/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_send+0x499)[0x2b75086ed939] 
[ 6] /usr/lib64/openmpi/lib/libmpi.so.1(PMPI_Send+0x1dd)[0x2b7502d3ef8d] 
[ 7] prog(main+0x98)[0x400d51] 
[ 8] /lib64/libc.so.6(__libc_start_main+0xfd)[0x39d941ed5d] 
[ 9] prog[0x400be9] 
*** End of error message *** 

我用的openmpi 1.8.2和nvcc 6.5;據我所知,這些版本應該支持這個功能。

所以,我的問題是:我做錯了什麼?我錯過了一些觀點嗎?我非常感謝任何關於如何獲得最小工作示例的提示!

+0

我對此並不瞭解,但按照簡單的邏輯,爲什麼不檢查'cudaMalloc()'中分配的成功或者它不是必需的? –

+0

我檢查了一下,發現這不是問題。一般來說,我同意支票是一個好主意,但在這裏我只是試圖保持代碼簡短。 – piripiri

回答

1

我只是簡要的回答總結討論。該代碼是正確的,但下面的問題可能arrise:

  1. MPI一直沒有使用CUDA支持(見@Robert Crovella答案)建成。這可以通過調用檢查:

    ompi_info --parsable -l 9 --all | grep mpi_built_with_cuda_support:value

    其中,在情況下,一切都很好,應該給:

    mca:mpi:base:param:mpi_built_with_cuda_support:value:true

  2. 的GPU的架構不支持特徵。需要費米或更高版本(請參閱@Christian Sarofeen的評論)

原來,第二個問題適用於我的情況。

3

當MPI期待主機指針時,segfault幾乎肯定是由於將設備指針傳遞給MPI。只有正確構建的支持CUDA的MPI才能接受設備指針。僅僅擁有OpenMPI 1.8.2是不夠的。您必須擁有一個OpenMPI版本,該版本明確使用CUDA感知設置進行構建。

有關的openmpi,

開始here

摘編:

  • 如何構建開放式MPI與CUDA感知的支持?
  • 支持CUDA的支持意味着MPI庫可以直接發送和接收GPU緩衝區。該功能存在於Open MPI 1.7系列及更高版本中。支持正在不斷更新,因此不同版本中存在不同級別的支持。

    配置Open MPI 1.7,MPI 1.7.1和1.7.2

    --with-cuda(=DIR)  Build cuda support, optionally adding DIR/include, 
             DIR/lib, and DIR/lib64 
    
    
    --with-cuda-libdir=DIR Search for cuda libraries in DIR 
    

    這裏是配置命令,使CUDA支持的一些例子。

    1. 在默認位置搜索。在/ usr/lib64中的/ usr/local/cuda/include和libcuda.so中查找cuda.h。

      ./configure --with-cuda 
      
    2. 搜索用於/usr/local/cuda-v4.0/cuda/include cuda.h和libcuda.so在/ usr/lib64下的默認位置。

      ./configure --with-cuda=/usr/local/cuda-v4.0/cuda 
      
    3. 搜索用於/usr/local/cuda-v4.0/cuda/include cuda.h和libcuda.so在/ usr/lib64下。 (同前一個)

      ​​

    如果cuda.h或libcuda.so文件無法找到,那麼配置將中止。

    注意:Open MPI 1.7.2中存在一個錯誤,如果您使用--enable-static配置庫,將會出現錯誤。要解決此錯誤,請將以下內容添加到配置行並重新配置。這將禁用基本上未使用的PML BFO的構建。這個bug在Open MPI 1.7.3中修復。

    --enable-mca-no-build=pml-bfo 
    

    配置Open MPI 1.7.3後來

    通過Open MPI 1.7.3及以後libcuda.so庫是動態的,所以沒有必要指定它的路徑裝載在配置時間。因此,所有你需要的是cuda.h頭文件的路徑。

    1. 在默認位置搜索。在/ usr/local/cuda/include中查找cuda.h。

      ./configure --with-cuda 
      
    2. 搜索在/usr/local/cuda-v5.0/cuda/include cuda.h。

      ./configure --with-cuda=/usr/local/cuda-v5.0/cuda 
      

    請注意,你不能用--disable-dlopen配置爲將打破開放MPI庫的動態加載libcuda.so的能力。

    有關如何使用CUDA支持的詳細信息,請參閱

    this FAQ entry

    請注意,這些說明假設您熟悉OpenMPI的構建。僅僅運行./configure ...是不夠的。之後有make和make install步驟。但是,上述配置命令是將CUDA感知型OpenMPI版本與普通版本區分開來的區別。

    +0

    謝謝!不幸的是,我使用的MPI實現是使用CUDA支持構建的('ompi_info --parsable -l 9 --all | grep mpi_built_with_cuda_support:value'給出了'mca:mpi:base:param:mpi_built_with_cuda_support:value:true'),所以這個不是問題。 – piripiri

    +0

    我試圖在另一個(更新的)設備(Tesla K40)上運行該程序,其軟件環境基本相同。它有效!我的第一次,不成功的嘗試是在Tesla T10卡上。對此有何解釋?它是否與計算能力有關? – piripiri

    +1

    是的,它需要費米或更高版本。 「CUDA驅動程序本機支持GPUDirect對等傳輸和內存訪問,您需要的僅僅是CUDA Toolkit v4.0和R270驅動程序(或更高版本)以及搭載兩個或更多Fermi-或Kepler體系結構GPU的系統相同的PCIe總線。「 https://developer.nvidia.com/gpudirect –