MPI 프로그램을 어떻게 디버깅합니까?


129

컴파일하고 실행하는 MPI 프로그램이 있지만 기괴한 일이 일어나지 않도록 단계별로 진행하고 싶습니다. 이상적으로는 특정 프로세스에 GDB를 연결하는 간단한 방법을 원하지만 그것이 가능한지 또는 어떻게하는지 확실하지 않습니다. 대안은 각 프로세스가 디버그 출력을 별도의 로그 파일에 쓰도록하는 것이지만 이것은 실제로 디버거와 같은 자유를주지는 않습니다.

더 나은 접근법이 있습니까? MPI 프로그램을 어떻게 디버깅합니까?

답변:


62

다른 사람이 말했듯이 TotalView 가 이에 대한 표준입니다. 그러나 팔과 다리가 필요합니다.

OpenMPI 사이트에는 MPI 디버깅에 대한 훌륭한 FAQ가 있습니다. FAQ의 6 번 항목은 GDB를 MPI 프로세스에 연결하는 방법을 설명합니다. 모든 것을 읽으십시오. 좋은 팁이 있습니다.

추적 할 프로세스가 너무 많으면 스택 추적 분석 도구 (STAT)를 확인하십시오 . Livermore에서는이를 사용하여 잠재적으로 수십만 개의 실행중인 프로세스에서 스택 추적을 수집하고이를 사용자에게 지능적으로 표현합니다. 완전한 기능을 갖춘 디버거는 아니지만 (모든 기능을 갖춘 디버거는 208k 코어로 확장되지 않음) 어떤 프로세스 그룹이 동일한 작업을 수행하는지 알려줍니다. 그런 다음 표준 디버거에서 각 그룹의 담당자를 단계별로 안내 할 수 있습니다.


14
2010 년 현재 Allinea DDT 는 208k 코어 이상으로 확장되는 모든 기능을 갖춘 디버거입니다
Mark

1
계속해서 @Mark의 답변을 여기에 올리겠습니다. DDT가 좋습니다. 시도해보십시오. TotalView는 이제 STAT 와도 통합되므로 사이트에 TotalView 설치가 있으면 시도해 볼 수도 있습니다. LLNL은 TotalView와 DDT를 유지하고 있으며 TotalView가 마침내 치열한 경쟁을 벌이는 것이 좋습니다.
토드 감 블린

MPI 디버깅에 대한 FAQ 링크 ( open-mpi.org/faq/?category=debugging#serial-debuggers ) 를 두 번째로보고 싶습니다 . 특히, 글 머리 기호 6은 적어도 개별 프로세스를 디버그하는 방법을 이해하기에 좋고, 빠르며, 쉽습니다.
Jeff

FAQ 페이지 # 6의 단계가 훌륭하게 작동하여 문제를 파악하는 데 도움이되었습니다. 정말 감사합니다.
Jon Deaton

86

gdb가 매우 유용하다는 것을 알았습니다. 나는 그것을

mpirun -np <NP> xterm -e gdb ./program 

이것은 내가 할 수있는 xterm 창을 시작합니다.

run <arg1> <arg2> ... <argN>

보통 잘 작동합니다

다음을 사용하여 이러한 명령을 함께 패키지 할 수도 있습니다.

mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]

모든 NP gdb xterm에 동일한 입력을 보내려면 어떻게해야합니까? 예를 들어, 모든 프로세스에 두 개의 중단 점을 추가하고 싶은데 16 개의 프로세스가 있습니다. 이것을하기위한 xterm에 대한 대안이 있습니까? 세션을 화면, tmux 또는 Chris Jones의 터미네이터 단일 인스턴스에 연결할 수 있습니까?
osgx

@osgx 명령 ( "break xxx", "break yyy", "run")을 저장 <file>하고 -x <file>gdb에 전달 하면됩니다.
eush77

하지만 오류가 발생하면 오류 메시지는 "xterm 파일의 execvp 오류 (파일 또는 디렉토리가 없음)"
hitwlh

jdb & OpenMPI로 이것을 시도하면 작동하지 않습니다. 즉, 각 jdb 인스턴스는 -np 인수에 주어진 것 대신 1의 num_ranks를 봅니다. 왜 그런지 알아?
Michel Müller

26

여기의 많은 게시물은 GDB에 관한 것이지만 시작에서 프로세스에 연결하는 방법은 언급하지 않았습니다. 분명히 모든 프로세스에 연결할 수 있습니다.

mpiexec -n X gdb ./a.out

그러나 모든 프로세스를 시작하려면 바운스해야하기 때문에 이는 비효율적입니다. 하나 (또는 ​​소수의) MPI 프로세스 만 디버그하려는 경우 :연산자를 사용하여 명령 행에서 별도의 실행 파일로 추가 할 수 있습니다 .

mpiexec -n 1 gdb ./a.out : -n X-1 ./a.out

이제 프로세스 중 하나만 GDB를 얻습니다.


"mpiexec -n X gdb ./a.out"을 사용할 수 있지만 gdb -tui 모드를 사용하는 방법이 있습니까?
hitwlh

16

다른 사람들이 언급했듯이, 소수 의 MPI 프로세스 로만 작업 하는 경우 여러 gdb 세션 , 중복 가능 valgrind 또는 자체 printf / logging 솔루션 을 사용하려고 시도 할 수 있습니다 .

그보다 많은 프로세스를 사용하고 있다면 실제로 적절한 디버거가 필요합니다. 는 OpenMPI 자주 묻는 질문은 모두 권장 Allinea DDTTotalView을 .

나는 Allinea DDT에서 일한다 . 완전한 기능을 갖춘 그래픽 소스 코드 디버거이므로 다음과 같이 할 수 있습니다.

  • MPI 프로세스 (200k 이상) 디버그 또는 첨부
  • 그룹으로 또는 개별적으로 단계 및 일시 중지
  • 중단 점, 시계 및 추적 점 추가
  • 캐치 메모리 오류 및 누수

...등등. Eclipse 또는 Visual Studio를 사용했다면 집에있을 것입니다.

병렬 코드 디버깅을 위해 특별히 흥미로운 기능을 추가 했습니다 (MPI, 멀티 스레드 또는 CUDA 등).

  • 스칼라 변수는 모든 프로세스에서 자동으로 비교됩니다 : (source : allinea.com )프로세스 전체의 값을 보여주는 스파크 라인

  • 프로세스 및 시간에 따른 변수 및 표현식의 값을 추적하고 필터링 할 수도 있습니다. 시간 경과에 따른 추적 점 로그 값

ORNL , NCSA , LLNL , Jülich 등과 같은 상위 500 HPC 사이트 에서 널리 사용됩니다 . 알.

인터페이스는 매우 빠릅니다. 우리는 Oak Ridge의 Jaguar 클러스터에 대한 승인 테스트의 일환으로 0.1 초에 220,000 개의 프로세스 스택과 변수를 스테핑하고 병합하는 시간을 정했습니다.

@tgamblin 은 몇 가지 다른 인기있는 오픈 소스 프로젝트 와 마찬가지로 Allinea DDT 와 통합 된 우수한 STAT를 언급 했습니다.



7

당신이 tmux사용자라면 Benedikt Morbach 의 스크립트를 사용하는 것이 매우 편할 것입니다 .tmpi

원본 출처 : https://github.com/moben/scripts/blob/master/tmpi

포크 : https://github.com/Azrael3000/tmpi

그것으로 여러 개의 패널 (프로세스 수)이 모두 동기화됩니다 (모든 명령은 모든 패널 또는 프로세스에서 동시에 복사되므로 xterm -e접근 방식 과 비교하여 많은 시간을 절약 할 수 있습니다 ). 또한 원하는 프로세스에서 변수 값을 알 수 있습니다.print 다른 패널로 이동하지 않고 그러면 각 프로세스의 변수 값이 각 패널에 인쇄됩니다.

당신이 tmux사용자 가 아닌 경우 나는 그것을 시도하고 참조하는 것이 좋습니다.


2
tmpi가 정말 환상적이고 정확하게 내가 찾던 것이기 때문에, 나는 원래의 저자가 그것을 제거한 이후 github 계정 ( github.com/Azrael3000/tmpi) 에서 포크 했습니다
Azrael3000

6

http://github.com/jimktrains/pgdb/tree/master 는이 작업을 수행하기 위해 작성한 유틸리티입니다. 몇 가지 문서가 있으며 궁금한 점이 있으시면 언제든지 저를 찾으십시오.

기본적으로 GDB를 감싸고 IO를 중앙 서버로 퍼널 링하는 perl 프로그램을 호출합니다. 이를 통해 각 호스트에서 GDB를 실행할 수 있으며 터미널의 각 호스트에서 GDB에 액세스 할 수 있습니다.


감사! 다음에 MPI에서 일할 때 확실히 확인하겠습니다.
Jay Conrod

5

MPI 응용 프로그램을 디버깅 screen하는 gdb데 함께 사용하면 특히 xterm사용할 수 없거나 몇 개 이상의 프로세서를 처리하는 경우에 효과적입니다. 스택 오버 플로우 검색과 함께 많은 함정이 있었으므로 솔루션을 완전히 재현 할 것입니다.

먼저 MPI_Init 뒤에 코드를 추가하여 PID를 인쇄하고 연결을 기다리는 프로그램을 중지하십시오. 표준 솔루션은 무한 루프 인 것 같습니다. 결국에 정착했습니다 .gdb 내에서 탈출하기 위해 raise(SIGSTOP);추가 호출이 필요합니다 continue.

}
    int i, id, nid;
    MPI_Comm_rank(MPI_COMM_WORLD,&id);
    MPI_Comm_size(MPI_COMM_WORLD,&nid);
    for (i=0; i<nid; i++) {
        MPI_Barrier(MPI_COMM_WORLD);
        if (i==id) {
            fprintf(stderr,"PID %d rank %d\n",getpid(),id);
        }
        MPI_Barrier(MPI_COMM_WORLD);
    }
    raise(SIGSTOP);
}

컴파일 후 백그라운드에서 실행 파일을 실행하고 stderr을 잡으십시오. 그런 다음 grep키워드 (여기서는 리터럴 PID)에 대한 stderr 파일을 사용하여 각 프로세스의 PID 및 순위를 얻을 수 있습니다.

MDRUN_EXE=../../Your/Path/To/bin/executable
MDRUN_ARG="-a arg1 -f file1 -e etc"

mpiexec -n 1 $MDRUN_EXE $MDRUN_ARG >> output 2>> error &

sleep 2

PIDFILE=pid.dat
grep PID error > $PIDFILE
PIDs=(`awk '{print $2}' $PIDFILE`)
RANKs=(`awk '{print $4}' $PIDFILE`)

를 사용하여 각 프로세스에 gdb 세션을 첨부 할 수 있습니다 gdb $MDRUN_EXE $PID. 스크린 세션 내에서 그렇게하면 모든 gdb 세션에 쉽게 액세스 할 수 있습니다. -d -m화면을 분리 모드로 시작하고 -S "P$RANK"나중에 쉽게 액세스 할 수 있도록 화면 이름을 지정할 수 있으며, -lbash 옵션은 대화식 모드에서 화면을 시작하고 gdb가 즉시 종료되지 않도록합니다.

for i in `awk 'BEGIN {for (i=0;i<'${#PIDs[@]}';i++) {print i}}'`
do
    PID=${PIDs[$i]}
    RANK=${RANKs[$i]}
    screen -d -m -S "P$RANK" bash -l -c "gdb $MDRUN_EXE $PID"
done

화면에서 gdb가 시작되면 화면 -X stuff명령을 사용하여 화면에 입력을 스크립팅 할 수 있습니다 (따라서 모든 화면을 입력하고 동일한 내용을 입력하지 않아도 됨) . 명령 끝에 줄 바꿈이 필요합니다. 여기에서 -S "P$i"이전에 제공된 이름 을 사용하여 화면에 액세스합니다 . 이 -p 0옵션은 중요합니다. 그렇지 않으면 명령이 간헐적으로 실패합니다 (이전에 화면에 연결했는지 여부에 따라).

for i in `awk 'BEGIN {for (i=0;i<'${#PIDs[@]}';i++) {print i}}'`
do
    screen -S "P$i" -p 0 -X stuff "set logging file debug.$i.log
"
    screen -S "P$i" -p 0 -X stuff "set logging overwrite on
"
    screen -S "P$i" -p 0 -X stuff "set logging on
"
    screen -S "P$i" -p 0 -X stuff "source debug.init
"
done

이 시점 screen -rS "P$i"에서을 사용 하여 모든 화면에 연결 하고 분리 할 수 있습니다 Ctrl+A+D. 명령은 이전 코드 섹션과 유사하게 모든 gdb 세션으로 전송 될 수 있습니다.


3

병렬 프로그래밍에 도움이되는 오픈 소스 도구 인 padb도 있습니다. 디버거뿐만 아니라 프로그램과 같은 병렬 상단 기능도 수행 할 수있을뿐 아니라 "작업 검사 도구"라고합니다. "전체 보고서"모드에서 실행하면 응용 프로그램 내 모든 프로세스의 추적을 모든 순위에 대한 모든 함수에 대한 로컬 변수와 함께 표시합니다 (-g로 컴파일 한 것으로 가정). 또한 "MPI 메시지 대기열", 즉 작업 내 각 순위에 대한 미해결 전송 및 수신 목록이 표시됩니다.

전체 보고서를 표시 할뿐만 아니라 작업 내에서 개별 비트 정보를 확대하도록 padb에 지시 할 수 있으며, 표시되는 정보를 제어하기위한 다양한 옵션 및 구성 항목이 있습니다. 자세한 내용은 웹 페이지를 참조하십시오.

패드


3

MPI 프로그램을 디버깅하는 "표준"방법은 해당 실행 모델을 지원하는 디버거를 사용하는 것입니다.

UNIX에서 TotalView 는 MPI에 대한 훌륭한 지원을 제공한다고합니다.


2

이 작은 자체 양조 방법을 사용하여 디버거를 MPI 프로세스에 연결합니다. 코드에서 MPI_Init () 바로 다음에 DebugWait () 함수를 호출하십시오. 프로세스가 키보드 입력을 기다리는 동안 항상 디버거를 연결하고 중단 점을 추가해야합니다. 완료되면 단일 문자 입력을 제공하면 바로 사용할 수 있습니다.

static void DebugWait(int rank) {
    char    a;

    if(rank == 0) {
        scanf("%c", &a);
        printf("%d: Starting now\n", rank);
    } 

    MPI_Bcast(&a, 1, MPI_BYTE, 0, MPI_COMM_WORLD);
    printf("%d: Starting now\n", rank);
}

물론 디버그 빌드를 위해서만이 함수를 컴파일하고 싶을 것입니다.


MPI는 심지어 간단한 코드를 위해 작성한 것 중 가장 많은 디버그 문을 요구했습니다. (lol) 이것은 매우 도움이 될 수 있습니다.
Troggy

3
이 솔루션은 여기의 글 머리표 6과 유사합니다 ( open-mpi.org/faq/?category=debugging#serial-debuggers ). 을 추가하여 코드를 약간 향상시킬 수 있습니다 gethostname(hostname, sizeof(hostname)); printf("PID %d on host %s ready for attach\n", getpid(), hostname);. 그런 다음을 입력 rsh <hostname_from_print_statement>하고 마지막 으로을 입력하여 프로세스에 연결합니다 gdb --pid=<PID_from_print_statement>.
Jeff

2

gdb를 mpi 프로세스에 첨부하는 명령이 불완전합니다.

mpirun -np <NP> xterm -e gdb ./program 

mpi 및 gdb에 대한 간단한 설명은 여기 에서 찾을 수 있습니다.


2

MPI 프로그램을 디버깅하는 아주 간단한 방법입니다.

메인 () 함수에서 수면 추가 (some_seconds)

평소대로 프로그램을 실행

$ mpirun -np <num_of_proc> <prog> <prog_args>

프로그램이 시작되고 잠자기 상태가됩니다.

따라서 ps로 프로세스를 찾고 gdb를 실행하고 연결하는 데 몇 초가 걸립니다.

QtCreator와 같은 편집기를 사용하면

디버그-> 디버깅 시작-> 실행중인 애플리케이션에 첨부

거기에서 프로세스를 찾으십시오.


1

로그 추적으로 일부 MPI 관련 디버깅을 수행하지만 mpich2를 사용하는 경우 gdb를 실행할 수도 있습니다 : MPICH2 및 gdb . 이 기술은 일반적으로 디버거에서 시작하기 까다로운 프로세스를 처리 할 때 좋은 방법입니다.


끊어지지 않은 다른 링크로 변경되어 주석이 추가되었습니다.
Jim Hunziker


0

또 다른 솔루션은 SMPI 내에서 시뮬레이션 된 MPI 내에서 코드를 실행하는 것입니다. 그것은 내가 참여하는 오픈 소스 프로젝트입니다. 모든 MPI 순위는 동일한 UNIX 프로세스의 스레드로 변환됩니다. 그런 다음 gdb를 쉽게 사용하여 MPI 순위를 단계적으로 수행 할 수 있습니다.

SMPI는 MPI 응용 프로그램 연구에 대한 다른 이점을 제안합니다. 호스트에서) 등

자세한 내용은 이 프레젠테이션 또는 관련 답변을 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.