Средства отладки MPI-программ. Анализатор корректности
|
Nproc |
abend |
abort |
normal |
unknown |
Nerr |
Nwarn |
NPsend |
NPrecv |
2 |
1 |
0 |
1 |
0 |
2 |
1 |
0 |
0 |
Рис.1 Головная таблица протокола анализатора
2.
Сurrent Function. Таблица c именами различных MPI-функций, к которым были последние обращения
(приведена на Рис.2) содержит для каждой
функции:
·
число процессов,
обратившихся к ней (Nproc);
·
число различных
точек в исходных текстах программы, последнее обращение в которых было к этой
функции (Nsrc).
Current functions:
N |
function |
Nproc |
Nsrc |
1 |
Call MPI_Recv |
1 |
1 |
2 |
ret MPI_Finalize |
1 |
1 |
Рис.2 Таблица протокола с последними выполнявшимися MPI-функциями
3.
Current source code points (src). Таблица со
ссылками на исходный текст программы для последних выполнявшихся MPI-функций (приведена на Рис.3) содержит для каждой точки:
·
номер строки и
имя файла (line, file);
·
число процессов с
данной текущей точкой выполнения (Nproc);
·
имя MPI-функции,
к которой произошло обращение в данной точке (function).
Current source code points (src):
N |
line |
file |
Nproc |
function |
1 |
34 |
demo.f |
1 |
call MPI_Recv |
2 |
38 |
demo.f |
1 |
ret MPI_Finalize |
Рис.3 Таблица протокола анализатора со ссылками на исходный
текст программы для последних выполнявшихся MPI-функций
4.
All errors/warnings. Таблица
обнаруженных ошибок (приведена на Рис.4) содержит для каждого типа ошибки:
·
краткое название
ошибки (error name);
·
код ошибки и важность
ошибки (error code): собственно ошибка (err) или предупреждение (warn);
·
число найденных
ошибок данного типа (Nerr);
·
число процессов,
в которых произошла ошибка данного типа (Nproc);
·
число различных
точек в исходных текстах программы, в которых произошла ошибка данного типа (Nsrc).
All errors/warnings:
N |
error code |
error name |
Nerr |
Nproc |
Nsrc |
1 2 3 |
1 err 57 warn 60 err |
abend/abort possible hang-up wrong data type |
1 1 1 |
1 2 1 |
1 2 1 |
Рис.4 Таблица обнаруженных ошибок
5.
Source code points of all errors/warnings. Таблица
различных точек в исходных текстах программы, в которых произошли ошибки
(любые) (приведена на Рис.5). Для каждой такой точки таблица содержит:
·
номер строки и
имя файла (line, file);
·
число процессов,
при выполнении которых в данной точке произошли ошибки (Nproc);
·
имя MPI-функции,
к которой произошло обращение в данной точке (function).
Source code points of all errors/warnings:
N |
line |
file |
Nproc |
function |
1 2 |
32 34 |
demo.f demo.f |
1 1 |
MPI_Send MPI_Recv |
Рис.5 Таблица различных точек в исходных текстах программы,
в которых произошли ошибки
Кроме того, для каждого
типа обнаруженной ошибки выводится отдельная таблица, аналогичная таблице 5.
Таблицы для ошибок, обнаруженных в тесте
demo.f, приведены на Рис.6.
Source code points of abends/aborts:
N |
line |
file |
Nproc |
function |
1 |
34 |
demo.f |
1 |
call MPI_Recv |
Source code points of potential deadlocks and hang-ups:
N |
line |
file |
Nproc |
function |
1 2 |
32 34 |
demo.f demo.f |
1 1 |
MPI_Send MPI_Recv |
Source code points of data type errors:
N |
line |
file |
Nproc |
function |
1 |
34 |
demo.f |
1 |
MPI_Recv |
Рис.6 Таблицы различных точек в исходных текстах программы,
в которых произошли ошибки, для каждого типа ошибки
Состояние
каждого процесса представлено в протоколе отдельной таблицей (приведена на
Рис.7), которая для каждого процесса содержит:
1.
номер процесса (Proc);
2.
тип завершения
процесса (нормальное, авостное или принудительное завершение) (Term);
3.
число ошибок (Nerr) и число предупреждений (Nwarn);
4.
число операций send (Nsend), число
операций receive (Nrecv) и число коллективных операций (Ngop);
5.
число незавершённых
операций send (Npsend) и число незавершённых операций receive (Nprecv);
6.
имя текущей
функции MPI;
7.
номер строки и
имя файла точки завершения процесса;
8.
число прохождений
через точку завершения процесса (кратность точки завершения);
9.
фрагмент исходного
текста программы, соответствующий точке завершения;
10.
стек обращений к
функциям для точки завершения (если длина стека в этой точке больше 1).
State of processes
Proc |
Term |
Nerr |
Nwarn |
NPrecv |
NPsend |
Nrecv |
Nsend |
Ngop |
0 |
norm |
|
1 |
|
|
|
1 |
|
ret MPI_Finalize ( 1) src=demo.f ( 38 ) call MPI_Finalize(ierr) |
Proc |
Term |
Nerr |
Nwarn |
NPrecv |
NPsend |
Nrecv |
Nsend |
Ngop |
1 |
abend |
2 |
1 |
|
|
1 |
|
|
call
MPI_Recv ( 1) src=demo.f ( 34
) call
MPI_Recv(A,3,MPI_INTEGER,0,999,comm,MPI_Status,ierr) |
Рис.7 Таблицы
состояния процессов программы
Все обнаруженные анализатором ошибки, кроме дедлоков и
зависаний, выводятся в протокол отдельно для каждого процесса в порядке
их возникновения.
Для каждой найденной ошибки выводится (см. Рис.8):
·
краткое название
ошибки (Error);
·
номер процесса,
при выполнении которого произошла ошибка (Proc);
·
имя MPI-функции,
при обращении к которой произошла ошибка;
·
номер строки и
имя файла точки, в которой произошла ошибка;
·
число прохождений
через точку, в которой произошла ошибка (кратность точки);
·
фрагмент
исходного текста программы, соответствующий точке, в которой произошла ошибка;
·
информация о
коммуникаторе (если ошибка связана с передачей сообщений);
·
стек обращений к
функциям для точки, в которой произошла ошибка (если длина стека в этой точке
больше 1);
·
совокупность
фрагментов трассировки, каждый из которых непосредственно или косвенно связан с
ошибкой; порядковый номер в трассировке каждого события при этом заканчивается
символом “!”, если событие является “аномальным” (событием, с которым
связывается ошибка), или символом “i”, если
событие является информационным (т. е. выводимым для лучшего понимания
ситуации).
Errors and warnings
===================
________________________________________________________________________________
| PROC | N | Error
| src | tag/ind | size
| rcnt=3 |
|______|______|_________________|______|___________|___________|_______________|
| 1 | 1 | wrong data type | 0 | 999
| 12 | INTEGER |
| | | | | | 24 | scnt=3 |
| | | | | | | COMPLEX |
|
|-----------------------------------------------------------------------|
| |
send type = COMPLEX
receive type = INTEGER
|
| | send dtcode = 138 receive dtcode = 0 |
|
|-----------------------------------------------------------------------|
| | MPI_Recv ( 1) src=demo.f (34 ) |
| | call
MPI_Recv(A,3,MPI_INTEGER,0,999,comm,MPI_Status,ierr ) |
| | C call
MPI_Probe(1,secarr,comm,MPI_Status,ierr) |
| |-----------------------------------------------------------------------|
| | MPI_Send ( 1) src=demo.f (32 ) |
| | call
MPI_Send(A,3,MPI_COMPLEX,1,999,comm,ierr) |
| | else |
|
|-----------------------------------------------------------------------|
| | communicator = 1 proc number = 2 tripl number = 1 |
| | init=0 last=1
step=1 |
|______|_______________________________________________________________________|
6!
call MPI_Recv. src = demo.f(34)
time=00.00.00.006858
call
MPI_Recv(A,3,MPI_INTEGER,0,999,comm,MPI_Status,ierr )
buf=0xbffffb80 count=3 dtype=INTEGER
size=12
source=0 wsource=0 tag=999 comm=1
InitEvent=6 StartEvent=6
FinishEvent=undef MatchedStartEvent=6
Trace fragment of process 0
------------------------------
6!
call MPI_Send. src = demo.f(32)
time=00.00.00.006942
call MPI_Send(A,3,MPI_COMPLEX,1,999,comm,ierr)
buf=0xbffff740 count=3 dtype=COMPLEX
size=24
dest=1 wdest=1 tag=999 comm=1 sum=0x0 dtcode=138
InitEvent=6 StartEvent=6
FinishEvent=7 MatchedStartEvent=6
________________________________________________________________________________
| PROC | N | Error
| trace event num = 6 |
|______|______|_________________|______________________________________________|
| 1 | 2 |
abend | |
| |-----------------------------------------------------------------------|
| | call MPI_Recv ( 1) src=demo.f (34 ) |
| | call
MPI_Recv(A,3,MPI_INTEGER,0,999,comm,MPI_Status,ierr ) |
| | C call MPI_Probe(1,secarr,comm,MPI_Status,ierr) |
|
|-----------------------------------------------------------------------|
| | MPI error: Message
truncated |
|______|_______________________________________________________________________|
6! call MPI_Recv. src = demo.f(34) time=00.00.00.006858
call
MPI_Recv(A,3,MPI_INTEGER,0,999,comm,MPI_Status,ierr )
buf=0xbffffb80
count=3 dtype=INTEGER size=12
source=0
wsource=0 tag=999 comm=1
InitEvent=6 StartEvent=6 FinishEvent=undef MatchedStartEvent=6
Рис.8 Таблицы
состояния процессов программы и фрагменты трассировки
Кроме того, для каждого типа ошибки может выводиться
специфическая для него информация: длина сообщения в байтах, тег, имя типа
данных и т. д.
Завершает вывод ошибок информация о дедлоках и
зависаниях (Рис. 9): сначала - информация о
реальных дедлоках и зависаниях, затем - о
потенциальных.
Potential deadlocks and hang-ups
================================
Warning 1
===========
0:MPI_Send 1:call MPI_Recv abend !
Proc=0 event=6 call MPI_Send. src = demo.f(32) time=00.00.00.006942
call
MPI_Send(A,3,MPI_COMPLEX,1,999,comm,ierr)
else
buf=0xbffff740 count=3 dtype=COMPLEX
size=24
dest=1 wdest=1 tag=999 comm=1
sum=0x0 dtcode=138
InitEvent=6 StartEvent=6
FinishEvent=7 MatchedStartEvent=6
comm = 1 proc number = 2 tripl number = 1
init=0 last=1
step=1
Proc=1 event=6 call MPI_Recv. src = demo.f(34) time=00.00.00.006858
call
MPI_Recv(A,3,MPI_INTEGER,0,999,comm,MPI_Status,ierr )
C call
MPI_Probe(1,secarr,comm,MPI_Status,ierr)
buf=0xbffffb80 count=3 dtype=INTEGER
size=12
source=0 wsource=0 tag=999 comm=1
InitEvent=6 StartEvent=6
FinishEvent=undef MatchedStartEvent=6
Рис.9 Информация о реальных и потенциальных дедлоках
В качестве иллюстрации работы блока динамического контроля приведем
примеры реакции на ошибки, возникающие на этапе выполнения программы.
1. В программе test1.c возникла ошибка – деление на 0.
Если
анализатор корректности не используется, то возникает стандартная диагностика:
[1] Aborting program !
[1] Aborting program!
p1_29283: p4_error:
: 14
Блок динамического контроля позволяет пользователю получить не только
сообщение о возникновении ошибки, но и дает информацию о месте в исходном
тексте программы, соответствующем обнаруженной ошибке. Диагностика блока
динамического контроля, в которой указан номер строки – 87 – и приведен текст этой
строки, выглядит следующим образом:
[1] *** Dynamic analyzer err: SIGFPE [8]:
Integer divide by zero addr=0x804a8fc
[1]
error src = test1.c(87)
j=j/i;
2.
В программе test4.c обнаружено несоответствие операторов MPI_Send и
MPI_Receive, возникшее из-за неверного задания получателя сообщения.
Получатель (процесс 1) ждет
сообщения от отправителя (процесс 0). Процесс 0 “ошибочно” посылает сообщение
другому процессу (NDEST=2). Так как указан
несуществующий получатель сообщения, программа завершается.
При запуске программы без
анализатора корректности, пользователь увидит следующую стандартную диагностику
0 -
MPI_SEND : Invalid rank 2
[0] Aborting program !
p0_4795: p4_error:
: 8262
Информация, предоставляемая в той
же ситуации блоком динамического контроля, упрощает поиск ошибки, так как указывается
номер строки – 83, приведен текст строки, где обнаружена ошибка, и приведены
пояснения об отсутствии получателя:
[0] *** Dynamic
analyzer err: wrong call MPI_Send (incorrect dest 2)
[0]
error src = test4.c(83)
MPI_Send(buf, COUNT, MPI_INT, NDEST,
s_tag, comm);
Dynamic
analyzer: <test4> task abnormal termination !
Incorrect
receiver in Send function:
(0) Send
10 MPI_INT (100, 101, ...) to 2; (1) Recv 10 MPI_INT from 0
Более того, если после завершения
выполнения программы запустить анализатор корректности трасс, можно получить
ещё более подробную информацию об ошибке. Приведем для примера некоторые из
таблиц протокола, полученного анализатором корректности трасс для рассматриваемой
ситуации.
Errors and warnings
===================
_______________________________________________________________________________
| PROC |
N | Error
| trace event num = 12
|
|______|______|_________________|______________________________________________|
| 0 | 1
| abend | |
|
|-----------------------------------------------------------------------|
| |
call MPI_Send ( 1) src=test4.c (83 ) |
|
| MPI_Send(buf, COUNT, MPI_INT, NDEST,
s_tag, comm); |
|
| printf("Send is
canceled\n");fflush(stdout); |
|
|-----------------------------------------------------------------------|
| |
incorrect dest 2
|
|______|_______________________________________________________________________|
Trace fragment of process 0
------------------------------
12! call
MPI_Send. src = test4.c(83)
time=00.00.02.006
MPI_Send(buf, COUNT, MPI_INT, NDEST,
s_tag, comm);
buf=0x81793e8
count=10 dtype=INT size=0
dest=2
wdest=-6789 tag=123 comm=1 sum=0x0 dtcode=0
InitEvent=12
StartEvent=12 FinishEvent=undef MatchedStartEvent=undef
________________________________________________________________________________
| PROC | N
| Error | src
| tag | size | count=10 |
|______|______|_________________|______|___________|___________|_______________|
| 1 |
1 | unfinished recv | 0 | 123
| 40 | INT |
|
|-----------------------------------------------------------------------|
| |
MPI_Recv ( 1) src=test4.c (87 ) |
|
| MPI_Recv(buf, COUNT, MPI_INT,
0, r_tag, comm, &r_status);
|
|
| printf("%d: Recv from 0
(%d, %d, ...)\n", rank, buf[0],buf[1]); |
|
|-----------------------------------------------------------------------|
| |
communicator = 1 proc number =
2 tripl number = 1 |
| |
init=0 last=1 step=1 |
|______|_______________________________________________________________________|
Trace fragment of process 1
------------------------------
12! call
MPI_Recv. src = test4.c(87)
time=00.00.02.006
MPI_Recv(buf, COUNT, MPI_INT, 0, r_tag, comm,
&r_status);
buf=0x8178df8
count=10 dtype=INT size=40
source=0
wsource=0 tag=123 comm=1
InitEvent=12
StartEvent=12 FinishEvent=undef MatchedStartEvent=undef
Приведем также примеры
использования анализатора корректности трасс в ситуациях, когда обнаружение
ошибок обычными средствами может потребовать значительных усилий.
1. В программе test5.c – скрытый реальный дедлок, так как
выданы встречные операции MPI_Send.
Два процесса выдают друг другу сначала
встречные MPI_Send, а затем MPI_Recv. Посылаются сообщения типа MPI_INT длиной COUNT*STEP_SIZE. После завершения передачи длина
передаваемого массива увеличивается на STEP_SIZE, и операции повторяются.
Программа
выполняется до “зависа”, который возникает при переполнении временного
системного MPI-буфера (обычно при попытке
обменяться сообщениями длиной больше, чем 32K).
Ниже приведены некоторые таблицы
из протокола анализатора, из которых видно, в какой программе, в какой строке,
при выполнении какой MPI-функции обнаружены ошибочные
ситуации.
Общее состояние задачи – задача
снята принудительно (abort), анализатор обнаружил 7 ошибок и сделал 22 предупреждения:
Task state
==========
test5
________________________________________________________________________________
| Nproc
| abend | abort | normal | unknown | Nerr
| Nwarn | NPsend | NPrecv
|
|_______|_______|_______|________|_________|________|________|________|________|
| 2 | 0
| 2 | 0 |
0 | 7 | 22
| 4 | 0 |
|_______|_______|_______|________|_________|________|________|________|________|
Общий список ошибок и предупреждений:
All errors/warnings:
_______________________________________________________________
| N | error
code | error name | Nerr
| Nproc | Nsrc |
|______|____________|_________________|________|_______|______|
| 1 | 56 warn |possible deadlock| 22 | 2
| 2 |
| 2 | 1 err
| abend/abort | 2
| 2 | 2 |
| 3 | 44 err
| unfinished send | 2 |
2 | 2 |
| 4 | 46 err
| nonpaired send | 2 | 2
| 2 |
| 5 | 58 err
| real deadlock | 1 | 2
| 2 |
|______|____________|_________________|________|_______|______|
Описание ошибок в процессе
0:
Errors and warnings
===================
________________________________________________________________________________
|
PROC | N | Error
| dest | tag | size | count=32768 |
|______|______|_________________|______|___________|___________|_______________|
| 0 | 1
| unfinished send | 1 |
123 | 131072 | INT |
| |-----------------------------------------------------------------------|
| | MPI_Send ( 23) src=test5.c (84 ) |
| |
MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 1, s_tag, comm); |
| |
MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 1, r_tag, comm,
&r_status); |
|
|-----------------------------------------------------------------------|
| | communicator = 1 proc number = 2 tripl number = 1 |
| | init=0 last=1
step=1 |
|______|_______________________________________________________________________|
________________________________________________________________________________
| PROC |
N | Error
| dest | tag | size | count=32768 |
|______|______|_________________|______|___________|___________|_______________|
| 0 | 2
| nonpaired send | 1 | 123
| 131072 | INT |
|
|-----------------------------------------------------------------------|
| | MPI_Send ( 23) src=test5.c (84 ) |
| |
MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 1, s_tag, comm); |
| |
MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 1, r_tag, comm,
&r_status); |
| |-----------------------------------------------------------------------|
| | communicator = 1 proc number = 2 tripl number = 1 |
| | init=0 last=1
step=1 |
|______|_______________________________________________________________________|
_______________________________________________________________________________
| PROC |
N | Error
| trace event num = 98 |
|______|______|_________________|______________________________________________|
| 0 | 3
| abort | |
|
|-----------------------------------------------------------------------|
| | call MPI_Send ( 23) src=test5.c (84 )
|
| |
MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 1, s_tag, comm); |
| |
MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 1, r_tag, comm,
&r_status); |
|
|-----------------------------------------------------------------------|
| | SIGINT [2]: Interrupt
|
|______|_______________________________________________________________________|
Описание ошибок в процессе 1:
_______________________________________________________________________________
| PROC | N
| Error | dest | tag | size | count=32768 |
|______|______|_________________|______|___________|___________|_______________|
| 1 | 1 | unfinished send | 0 | 123
| 131072 | INT |
|
|-----------------------------------------------------------------------|
| |
MPI_Send ( 23) src=test5.c (87 ) |
| | MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 0,
s_tag, comm); |
| | MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 0,
r_tag, comm, &r_status); |
|
|-----------------------------------------------------------------------|
| |
communicator = 1 proc number =
2 tripl number = 1 |
| |
init=0 last=1 step=1 |
|______|_______________________________________________________________________|
________________________________________________________________________________
| PROC | N
| Error | dest | tag | size | count=32768 |
|______|______|_________________|______|___________|___________|_______________|
| 1 | 2 | nonpaired send | 0
| 123 | 131072 | INT |
|
|-----------------------------------------------------------------------|
| |
MPI_Send ( 23) src=test5.c (87 ) |
| | MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 0,
s_tag, comm); |
| | MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 0,
r_tag, comm, &r_status); |
|
|-----------------------------------------------------------------------|
| |
communicator = 1 proc number =
2 tripl number = 1 |
| |
init=0 last=1 step=1 |
|______|_______________________________________________________________________|
________________________________________________________________________________
| PROC | N
| Error | trace event num = 98 |
|______|______|_________________|______________________________________________|
| 1 | 3 |
abort | |
|
|-----------------------------------------------------------------------|
| | call
MPI_Send ( 23) src=test5.c (87 ) |
| | MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 0,
s_tag, comm); |
| | MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 0,
r_tag, comm, &r_status); |
|
|-----------------------------------------------------------------------|
| | SIGINT
[2]: Interrupt
|
|______|_______________________________________________________________________|
Диагностика о дедлоке – встречные операции MPI_SEND в процессе 0 и процессе 1:
Real deadlocks and hang-ups
===========================
Error 1
=========
0:MPI_Send
1:MPI_Send deadlock !
Proc=0 event=98
call MPI_Send. src = test5.c(84)
time=00.00.02.474
MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 1,
s_tag, comm);
MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 1,
r_tag, comm, &r_status);
buf=0x81934b8
count=32768 dtype=INT size=131072
dest=1 wdest=1
tag=123 comm=1 sum=0x5fb200 dtcode=196608
InitEvent=98
StartEvent=98 FinishEvent=undef MatchedStartEvent=undef
comm = 1 proc number = 2 tripl number = 1
init=0 last=1
step=1
Proc=1 event=98
call MPI_Send. src = test5.c(87)
time=00.00.02.477
MPI_Send(buf, STEP_SIZE*cnt, MPI_INT, 0,
s_tag, comm);
MPI_Recv(buf, STEP_SIZE*cnt, MPI_INT, 0,
r_tag, comm, &r_status);
buf=0x8192e88
count=32768 dtype=INT size=131072
dest=0 wdest=0
tag=123 comm=1 sum=0x5fe400 dtcode=196608
InitEvent=98
StartEvent=98 FinishEvent=undef MatchedStartEvent=undef
comm = 1 proc number = 2 tripl number = 1
init=0
last=1 step=1
2. В программе test12.c скрытая ошибка: запись в буфер посылки до завершения операции MPI_Isend
В тексте программы встречается следующая
последовательность операторов:
if (rank==0) {
………..
MPI_Isend(buf, COUNT, MPI_INT, 1, s_tag, comm,
&s_req);
buf[0]=COUNT;buf[COUNT-1]=COUNT+1;
MPI_Wait(&s_req,&s_status);
} else if(rank==1) {
MPI_Recv(buf, COUNT, MPI_INT, 0, r_tag,
comm, &r_status);
Таким образом, процесс 0
посылает целочисленный массив из COUNT элементов процессу 1. До завершения
операции MPI_Isend, то есть до выполнения MPI_Wait, в буфер посылки
осуществляется запись. Программа заканчивается без диагностики ошибок, однако
работает неверно, так как буфер посылки “затирается”.
Анализатор корректности
трасс, работающий с собранными трассами, выполняет сравнение контрольных сумм
сообщения до и после выполнения операции MPI_Isend и сообщает о скрытой ошибке
в таблицах своего протокола.
Общее состояние задачи – задача
завершена нормально, но анализатор обнаружил 1 ошибку:
Task state
==========
test12
________________________________________________________________________________
| Nproc
| abend | abort | normal | unknown | Nerr
| Nwarn | NPsend | NPrecv
|
|_______|_______|_______|________|_________|________|________|________|________|
| 2 | 0 | 0
| 2 | 0
| 1 | 0 | 0
| 0 |
|_______|_______|_______|________|_________|________|________|________|________|
Общий список ошибок и предупреждений – неверная
контрольная сумма, вычисленная для буфера операции отправки:
All errors/warnings:
_______________________________________________________________
| N | error code | error name | Nerr | Nproc | Nsrc |
|______|____________|_________________|________|_______|______|
| 1 | 49 err | send checksum | 1
| 1 | 1 |
|______|____________|_________________|________|_______|______|
Описание ошибок в процессе 0:
Errors and warnings
===================
________________________________________________________________________________
| PROC |
N | Error
| dest | tag | size |
count=10 |
|______|______|_________________|______|___________|___________|_______________|
| 0 | 1
| send checksum | 1
| 123 | 40 | INT |
|
|-----------------------------------------------------------------------|
| |
addr = 81793e8 start chksum =
2d finish chksum = 39 |
|
|-----------------------------------------------------------------------|
| | MPI_Wait ( 1) src=test12.c (81 ) |
| |
MPI_Wait(&s_req,&s_status); |
| |
} else if(rank==1) { |
|
|-----------------------------------------------------------------------|
| | MPI_Isend ( 1) src=test12.c (79 ) |
| |
MPI_Isend(buf, COUNT, MPI_INT, 1, s_tag, comm, &s_req); |
| |
buf[0]=COUNT;buf[COUNT-1]=COUNT+1; |
| |-----------------------------------------------------------------------|
| | communicator = 1 proc number = 2 tripl number = 1 |
| | init=0 last=1
step=1 |
|______|_______________________________________________________________________|
Фрагмент трассы процесса 0 – признак i – “информационный”:
Trace
fragment of process 0
------------------------------
12i call MPI_Isend. src = test12.c(79) time=00.00.01.003
MPI_Isend(buf, COUNT, MPI_INT, 1, s_tag, comm,
&s_req);
buf=0x81793e8 count=10 dtype=INT size=40
dest=1 wdest=1 tag=123 comm= 1 sum=0x2d req=1
InitEvent=12 StartEvent=12 FinishEvent=15
MatchedStartEvent=12
Фрагмент трассы процесса 0 – признак ! – “ошибочный”:
Trace
fragment of process 0
------------------------------
14! call MPI_Wait. src = test12.c(81) time=00.00.01.003
MPI_Wait(&s_req,&s_status);
req=1 sum=0x39
InitEvent=12 StartEvent=12 FinishEvent=15
MatchedStartEvent=12
3. В
программе test7.c – различный порядок выдачи коллективных и редукционных
операций.
В тексте программы встречается
следующая последовательность операторов:
if
(rank==0) {
MPI_Bcast(s_buf, COUNT, MPI_INT, ROOT,
comm);
MPI_Allreduce(s_buf,r_buf,COUNT,MPI_INT,MPI_SUM,comm);
} else if (rank==1) {
MPI_Allreduce(s_buf,r_buf,COUNT,MPI_INT,MPI_SUM,comm);
MPI_Bcast(s_buf, COUNT, MPI_INT, ROOT, comm);
}
В операции MPI_Bcast в качестве рассылаемого массива
задается динамический массив типа integer
длиной COUNT.
Выполнение программы приводит к
следующей ситуации: процесс 0 выполняет последовательность операций MPI_Bcast(); MPI_Allreduce(); процесс 1 “ошибочно”
выполняет операции в другом порядке: MPI_Allreduce(); MPI_Bcast().
Если длина рассылаемого массива (COUNT) меньше 32К и в качестве корня (ROOT) указан процесс 0, то программа успешно завершается. В остальных
случаях (если в качестве корня указан процесс 1 или длина рассылаемого
массива больше 32К) процесс 0 зависает на MPI_Bcast, а процесс 1 - на MPI_Allreduce.
Даже в случае успешного
завершения программы, протокол анализатора корректности трасс позволяет увидеть
возможный потенциальный дедлок. Фрагменты протокола приведены ниже.
Общее состояние задачи – задача завершена нормально, но
анализатор выдает 1 предупреждение:
Task state
==========
test7
________________________________________________________________________________
| Nproc
| abend | abort | normal | unknown | Nerr
| Nwarn | NPsend | NPrecv
|
|_______|_______|_______|________|_________|________|________|________|________|
| 2 | 0 | 0
| 2 | 0
| 0 | 1 | 0
| 0 |
|_______|_______|_______|________|_________|________|________|________|________|
Общий список ошибок и предупреждений – обнаружен
потенциальный дедлок:
All errors/warnings:
_______________________________________________________________
| N | error code | error name
| Nerr | Nproc | Nsrc |
|______|____________|_________________|________|_______|______|
| 1 | 56
warn |possible deadlock| 1 |
2 | 2 |
|______|____________|_________________|________|_______|______|
Диагностика о потенциальном дедлоке – возможен неверный
порядок выполнения операций MPI_Bcast и MPI_ Allreduce:
Potential
deadlocks and hang-ups
================================
Warning 1
===========
0:MPI_Bcast 1:MPI_Allreduce deadlock !
Proc=0
event=10 call MPI_Bcast. src = test7.c(84) time=00.00.01.002
MPI_Bcast(s_buf, COUNT, MPI_INT, ROOT, comm);
printf("%d: End of Bcast\n", rank);
buf=0x81793e8 count=10 dtype=INT size=40
root=0 wroot=0 sum=0x415
comm=1 OpNum=2 StartEvent=10 FinishEvent=11
GlobalColl=81ec384
comm = 1 proc number = 2 tripl number = 1
init=0
last=1 step=1
Proc=1
event=10 call MPI_Allreduce. src = test7.c(89) time=00.00.01.003
MPI_Allreduce(s_buf,r_buf,COUNT,MPI_INT,MPI_SUM,comm);
MPI_Bcast(s_buf, COUNT, MPI_INT, ROOT, comm);
op=SUM sbuf=0x8178df8 rbuf=0x8178e28
count=10 dtype=INT arg size=40
comm=1 OpNum=2 StartEvent=10 FinishEvent=11
GlobalColl=81ec398
comm = 1
proc number = 2 tripl number = 1
init=0 last=1
step=1
В данной
работе описаны основные возможности анализатора корректности, предназначенного
для отладки параллельных программ, написанных на Фортране-77, Фортране-90 или Си/Си++
с использованием библиотеки передачи сообщений MPI.
Анализатор корректности входит в
состав разработанного в ИПМ им. М.В.Келдыша пакета инструментальных средств
отладки MPI-программ, который включает также
средства сравнительной отладки и анализатор эффективности выполнения
параллельной программы.
Анализатор
корректности реализован для различных аппаратно-программных сред и может применяться с операционными системами Windows и Linux.
Более подробная информация может
быть получена на сайтах http://www.keldysh.ru/dvm/, http://www.kiam.ru/dvm/, http://sp.cmc.msu.ru/dvm/.
Дальнейшее развитие созданных
средств отладки MPI-программ связано с разработкой
диалоговой системы, обеспечивающей графическое представление результатов
анализа и синхронный просмотр диагностической информации об ошибках, трасс и
исходных текстов программ, а также с разработкой и реализацией параллельных
алгоритмов анализа.
В приложении приводятся результаты ответов на некоторые вопросы, заданные
при анкетировании пользователей, занимающихся разработкой параллельных
MPI-программ. Эти ответы дают представление о типах специфических ошибок в
MPI-программах и важности их обнаружения с точки зрения пользователей.
Какие
типы ошибок должны обнаруживать средства отладки? Оцените сложность от 0
(менее важно) до 10 (наиболее важно) |
Сумма в
баллах |
|
1. |
Неверное
число и/или тип параметров MPI-функций |
195 |
2. |
Несогласование
send/receive из-за неверного задания отправителя или
получателя сообщения |
244 |
3. |
Несогласование
send/receive из-за ошибки в управлении выполнением программы
(например, сообщение не послано из-за того, что один из процессов вышел из
выполнения цикла раньше времени) |
248 |
4. |
Несогласование send/receive из-за ошибочной трактовки порядка выполнения функций (например, не принимается во внимание, что функция MPI_Send может приводить к ожиданию, пока получатель не вызовет соответствующую функцию MPI_Recv) |
233 |
5. |
Неверные
типы данных в send/receive |
179 |
6. |
Ошибочное
задание длины сообщения в send/receive |
216 |
7. |
Неверный
адрес буфера или пересылаемых/принимаемых данных |
206 |
8. |
Неповторяющиеся/недетерминированные
ошибки, зависящие от времени или порядка принимаемых сообщений |
241 |
9. |
Неповторяющиеся/недетерминированные
ошибки из-за записи в буфер отправки или приема, когда неблокирующие send/receive не
завершились |
226 |
10. |
Неповторяющиеся/недетерминированные
ошибки из-за чтения из буфера приема до того, как MPI_Irecv завершилась |
221 |
11. |
Различная
последовательность вызова коллективных операций и редукционных операций в
разных процессах (MPI_Bcast, MPI_Gather, MPI_Allreduce, …) |
202 |
12. |
Несовпадение параметров для коллективных операций и редукционных операций в
разных процессах |
170 |
13. |
Неповторяющиеся/недетерминированные
ошибки из-за неинициализированных переменных |
209 |
14. |
Неповторяющиеся/недетерминированные
ошибки из-за выхода индекса за границу массива |
238 |
15. |
Ошибки
точности вычисления в редукционных функциях (суммирование) из-за другого
порядка вычислений (по сравнению с последовательным) |
207 |
16. |
Ошибки
при создании и использовании коммуникаторов, производных типов и топологий |
181 |
17. |
Исчерпание
памяти из-за порождения коммуникаторов, производных типов и т.п., без их
освобождения |
184 |
18. |
Исчерпание
памяти при использовании неблокирующих операций посылки без задания операции wait |
208 |
19. |
Ошибки,
возникающие при изменении числа процессоров для выполнения и связанные с
неверной параметризацией по числу процессоров, размерам массивов и т.п. |
159 |
20. |
Ошибки,
возникающие при изменении среды компиляции или выполнения (например, другая
параллельная платформа, компилятор или библиотека MPI |
222 |
21. |
Ошибки,
возникающие при изменении объема рабочей загрузки |
158 |
Какие
типы ошибок в MPI-программах наиболее сложны для обнаружения?
Оцените сложность от 0 (просто) до 10 (наиболее сложно) |
Сумма в
баллах |
|
1. |
Ошибки,
приводящие к зависанию программы и завершению по истечению времени |
289 |
2. |
Ошибки,
приводящие к авосту в программе (деление на нуль, переполнение, обращение к
чужой памяти) |
182 |
3. |
Зацикливание программы |
160 |
4. |
Ошибки,
приводящие к неверным результатам (неверные значения расчетных переменных) |
271 |
5. |
Ошибки,
приводящие к авостам в MPI-функциях (плохая диагностика) |
211 |
6. |
Ошибки,
приводящие к недостатку ресурсов (например, если не освобождаются порождаемые
ресурсы) |
194 |
7. |
Ошибки,
приводящие к нестабильному/недетерминированному поведению программы
(например, два запуска программы дают различные результаты вычислений либо
различное завершение) |
334 |
1.
http://www.etnus.com
2.
В.А.Крюков,
Р.В.Удовиченко, “Отладка DVM-программ”, Препринт ИПМ им. М.В.Келдыша РАН №56, 1999.
3.
В.Ф. Алексахин, К.Н. Ефимкин, В.Н. Ильяков, В.А. Крюков,
М.И. Кулешова, Ю.Л. Сазанов. Средства отладки MPI-программ в DVM-системе. В сб. Труды Всероссийской научной конференции “Научный сервис в сети
Интернет”, Новороссийск, 19-24 сентября, 2005 г.
4.
http://www.csse.monash/edu/au/%7Edavida/papers/pdsc00.pdf
5.
http://www.llnl.gov/CASC/people/vetter/pubs/sc00-umpire-vetter.pdf
6.
http://www.hlrs.de/people/mueller/projects/marmot/
7.
http://andrew.ait.iastate.edu/HPC/MPI-CHECK.htm
8.
Самофалов В.В., Желтов С.Н., Гаврина Е.В., Братанов С.В., Kuhn B.H.,
DeSouza J., Невидин К.В., Стариков В.С. Анализ корректности MPI-программ. В сб. Труды
Всероссийской научной конференции “Научный сервис в сети Интернет”, Новороссийск,
19-24 сентября, 2005 г.