2015-01-12 2 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; 
} 

불행하게도,이 프로그램은 두 개의 프로세스에서 실행하는 경우, 세그먼트 폴트로 추락 다음과 같은 메시지 제공 : 내가 OpenMPI 실행을 사용

*** 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 *** 

을 내가 알고있는 것처럼, 다음 코드는 일을한다고 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

segfault는 MPI가 호스트 포인터를 기다리고있을 때 장치 포인터를 MPI로 전달하기 때문에 거의 확실합니다. 올바르게 구축 된 CUDA 인식 MPI만이 장치 포인터를 받아 들일 수 있습니다. OpenMPI 1.8.2 만 있으면 충분하지 않습니다. CUDA 인식 설정으로 명시 적으로 빌드 된 OpenMPI 버전이 있어야합니다. OpenMPI 실행을 위해

,

시작 here

발췌 :

  1. 가 어떻게 CUDA 인식 지원 열기 MPI를 구축합니까?

CUDA 인식 지원은 MPI 라이브러리가 GPU 버퍼를 직접 보내고받을 수 있음을 의미합니다. 이 기능은 Open MPI 1.7 시리즈 이상에 있습니다. 지원이 지속적으로 업데이트되어 서로 다른 버전의 지원이 서로 다릅니다.

구성 열기 MPI 1.7

, MPI 1.7.1 및 다음

--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 

1.7.2 CUDA 지원을 활성화 구성 명령의 몇 가지 예입니다.

  1. 기본 위치에서 검색합니다./usr/local/cuda/include에 cuda.h가 있고/usr/lib64에 libcuda.so가 있습니다. 는/usr/lib64에의 기본 위치에 /usr/local/cuda-v4.0/cuda/include에서 cuda.h 및 libcuda.so에 대한

    ./configure --with-cuda 
    
  2. 검색합니다.

    ./configure --with-cuda=/usr/local/cuda-v4.0/cuda 
    
  3. /usr/local/cuda-v4.0/cuda/include에서 cuda.h 검색하고있는 libcuda.so는/usr/lib64에.

    ./configure --with-cuda=/usr/local/cuda-v4.0/cuda --with-cuda-libdir=/usr/lib64 
    

cuda.h 경우, 또는 파일 libcuda.so를 찾을 수 없습니다 (이전과 동일), 다음 구성은 중단됩니다.

참고 : Open MPI 1.7.2에 버그가있어서 --enable-static으로 라이브러리를 구성하면 오류가 발생합니다.이 오류를 해결하려면 구성 라인에 다음을 추가하고 재구성하십시오. 이것은 거의 사용되지 않는 PML BFO의 빌드를 비활성화합니다. 이 버그는 Open MPI 1.7.3에서 수정되었습니다.

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

구성 열기 MPI 1.7.3 열기 MPI 1.7.3로 나중에

나중에 libcuda.so 라이브러리는 동적으로 경로를 지정할 필요가 없기 때문에로드 구성시. 따라서 필요한 것은 cuda.h 헤더 파일의 경로입니다.

  1. 기본 위치에서 검색합니다./usr/local/cuda/include에있는 cuda.h를 찾습니다. /usr/local/cuda-v5.0/cuda/include에서 cuda.h에 대한

    ./configure --with-cuda 
    
  2. 검색합니다. 즉 동적 libcuda.so로드 열기 MPI 라이브러리의 능력을 깰 것이다 당신이 --disable-dlopen로 구성 할 수 없습니다

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

참고.

는 CUDA 지원을 사용하는 방법에 대한 자세한 내용은

this FAQ entry

를 참조하십시오.

이 지침은 OpenMPI를 작성하는 데 어느 정도 익숙하다고 가정합니다. 간단히 실행하는 것만으로는 충분하지 않습니다. ./configure ... 그 이후에 make와 make 설치 단계가 있습니다. 그러나 위의 구성 명령은 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

기본적으로 동일한 소프트웨어 환경에서 다른 (훨씬 새로운) 장치 (테슬라 K40)에서 프로그램을 실행하려고했습니다. 거기 그것은 작동한다! 내 첫 번째, 실패한 시도는 Tesla T10 카드에있었습니다. 그것에 대한 설명이 있습니까? 컴퓨팅 기능과 관련이 있습니까? – piripiri

+1

예, 페르미 이상이 필요합니다. "GPUDirect 피어 - 투 - 피어 전송 및 메모리 액세스는 기본적으로 CUDA 드라이버에서 지원됩니다. CUDA 툴킷 v4.0 및 R270 드라이버 (또는 그 이상) 및 두 개 이상의 페르미 또는 케플러 아키텍처 GPU가 설치된 시스템이 필요합니다. 동일한 PCIe 버스. " https://developer.nvidia.com/gpudirect –