Programming Taskbook


E-mail:

Пароль:

Регистрация пользователя   Восстановление пароля

English

ЮФУ

Электронный задачник по программированию

©  М. Э. Абрамян (Южный федеральный университет), 1998–2019

 

PT for MPI-2 | Выполнение заданий в параллельном режиме   | Выполнение задания

PrevNext


Выполнение задания MPI1Proc2

Перейдем к выполнению задания. Теперь, когда мы подробно познакомились с механизмом работы программы в параллельном режиме, решение этой простой задачи не будет представлять для нас особых проблем.

Начнем с ввода исходных данных. По условию в каждом процессе дано по одному целому числу. Перейдем на пустую строку, расположенную ниже вызова функции MPI_Comm_rank. Если при выполнении программы будет достигнут данный участок кода, то это означает, что программа была запущена как один из процессов параллельного приложения (в противном случае был бы выполнен оператор выхода, указанный в условном операторе). Таким образом, в этом месте программы можно ввести элемент исходных данных, предварительно описав его (здесь и далее будем приводить только содержимое функции Solve):

Task("MPI1Proc2");
int flag;
MPI_Initialized(&flag);
if (flag == 0)
  return;
int rank, size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int n;
pt >> n;

Для ввода исходных данных мы использовали специальный поток ввода pt, определенный в задачнике. Это поток позволяет вводить данные любых скалярных типов, в частности, int и double, которые обычно и требуются при выполнении заданий из задачника PT for MPI-2.

Запустив полученную программу, мы увидим на экране окно задачника:

Задачник обнаружил, что ввод данных выполнен, и, таким образом, программа приступила к решению задачи. Однако ни один результирующий элемент данных не был выведен. Строго говоря, это свидетельствует об ошибочном решении, однако первый шаг к правильному решению нами сделан: правильно введены все исходные данные. В подобной ситуации задачник выводит сообщение на светло-синем фоне «Запуск с правильным вводом данных: все требуемые данные введены, результаты не выведены»

Обратите внимание на то, что добавленные нами действия по вводу данных выполняются во всех процессах параллельного приложения. Отметим также, что при данном запуске программы количество процессов стало другим. При выполнении задания число процессов может изменяться, поэтому решение будет считаться правильным только в случае, если оно дает верный результат при любом допустимом количестве процессов.

Закроем окно задачника и вернемся к нашей программе. В каждом процессе нам надо вывести удвоенное значение введенного числа, поэтому добавим в конец функции Solve еще один оператор:

pt << 2 * n;

Для вывода данных при решении задач используется тот же поток pt; таким образом, этот поток является потоком ввода-вывода.

Запуск исправленного варианта приведет к появлению окна с сообщением об ошибке:

Теперь во всех подчиненных процессах выведены требуемые результаты. Кроме того, удвоенное число выведено и в главном процессе. Эти данные являются правильными, в чем можно убедиться, сравнив значения, выведенные в разделе результатов и показанные в разделе с примером верного решения.

Однако в главном процессе требовалось также вывести количество процессов, входящих в коммуникатор, а это сделано не было. Поэтому информационная панель содержит сообщение «Выведены не все результирующие данные. Ошибка произошла в процессе 0», причем сообщение выводится на оранжевом фоне. Оранжевый цвет используется для выделения ошибок, связанных с вводом или выводом недостаточного количества данных. При попытке ввести или вывести лишние данные информационная панель выделяется малиновым цветом, если возникают ошибки, связанные с использованием данных неверного типа, то цвет панели становится фиолетовым. Для всех прочих ошибок используется красный цвет.

Количество процессов хранится в переменной size. Попытаемся вывести значение этой переменной в конце функции Solve:

pt << size;

Окно задачника примет вид, приведенный на следующем рисунке:

Можно убедиться в том, что все результирующие данные выведены. Однако решение по-прежнему считается ошибочным, поскольку теперь мы попытались вывести лишние данные (а именно значение size) в подчиненных процессах. Как уже отмечалось выше, для выделения ошибок, связанных с попыткой ввода или вывода лишних данных, используется малиновый цвет.

Если ошибки обнаружены в подчиненных процессах, то в окне задачника отображается дополнительный раздел отладки, в котором для каждого подчиненного процесса выводится более подробная информация об ошибке.

Определить, с каким процессом связано то или иное сообщение, выведенное в разделе отладки, можно по номеру, указываемому в левой части строки (перед символом «|»). Все строки, связанные с определенным процессом, нумеруются независимо от остальных строк; их номера указываются после номера процесса и отделяются от текста сообщения символом «>». Для того чтобы отобразить в разделе отладки только сообщения, связанные с каким-либо одним процессом, достаточно щелкнуть мышью на маркере с номером (рангом) этого процесса (все маркеры расположены на нижней границе окна) или нажать соответствующую цифровую клавишу. Для отображения сводной информации по всем процессам надо выбрать маркер с символом «*» или ввести этот символ с клавиатуры (перебирать маркеры можно также с помощью клавиш со стрелками Left и Right). Если строка сообщения в разделе отладки начинается с символа «!», то это означает, что данное сообщение является сообщением об ошибке и добавлено в раздел отладки самим задачником. Программа учащегося может выводить в раздел отладки свои собственные сообщения; об этой возможности будет подробно рассказано далее (см. раздел «Использование раздела отладки»).

Если задачник обнаружил ошибку хотя бы в одном подчиненном процессе, то он не анализирует результат, полученный в главном процессе (об этом также сообщается в разделе отладки).

Для того чтобы значение size было выведено только в главном процессе, необходимо перед выполнением этого действия убедиться, что ранг текущего процесса равен 0. Добавив соответствующую проверку, мы получим решение, который задачник сочтет правильным:

Task("MPI1Proc2");
int flag;
MPI_Initialized(&flag);
if (flag == 0)
  return;
int rank, size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int n;
pt >> n;
pt << 2 * n;
if (rank == 0)
  pt << size;

При запуске этого варианта решения на экране будут последовательно выводиться пять консольных окон, каждое из которых связано с выполняемой параллельной программой. Таким образом, однократный запуск программы из среды разработки приводит к целой серии запусков этой программы в параллельном режиме, что позволяет сразу протестировать полученное решение на нескольких наборах исходных данных. Серия тестовых испытаний завершается либо при обнаружении какой-либо ошибки, либо при успешном прохождении требуемого количества тестов (для всех заданий, входящих в задачник PT for MPI-2 количество тестовых испытаний равно пяти). Данная возможность еще более упрощает процесс проверки правильности полученного решения задачи.

После пяти успешных тестовых испытаний на экране появится окно задачника с сообщением об успешном выполнении задания:

В данном случае все индикаторы, расположенные на панели индикаторов (под информационной панелью), имеют зеленый цвет.

При каждом запуске учебной программы задачник сохраняет результаты ее работы в специальном файле результатов results.dat. Этот файл можно просмотреть с помощью модуля PT4Results, входящего в состав задачника (для запуска этого модуля в рабочем каталоге предусмотрен ярлык Results.lnk). Кроме того, результаты можно просмотреть и непосредственно из окна задачника, нажав в нем метку «Результаты (F2)» или клавишу F2. На экране появится окно с протоколом выполнения всех заданий. В нашем случае оно будет содержать примерно такой текст:

MPI1Proc2   c04/09 15:44 Ознакомительный запуск.
MPI1Proc2   c04/09 15:49 Запуск с правильным вводом данных.
MPI1Proc2   c04/09 15:54 Выведены не все результирующие данные.
MPI1Proc2   c04/09 15:59 Попытка вывести лишние результирующие данные.
MPI1Proc2   c04/09 16:03 Задание выполнено!

После имени задания указывается символ, соответствующей использованному языку программирования (в данном случае — символ «c», означающий, что использовался язык C++), дата и время запуска программы и описание результата ее выполнения.


PrevNext

 

Рейтинг@Mail.ru

Разработка сайта:
М. Э. Абрамян, В. Н. Брагилевский

Последнее обновление:
01.01.2019