Programming Taskbook


E-mail:

Пароль:

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

 

ЮФУ SMBU

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

©  М. Э. Абрамян (Южный федеральный университет, Университет МГУ-ППИ в Шэньчжэне), 1998–2024

 

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

PrevNext


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

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

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

[C++]

void Solve()
{
  Task("MPIBegin1");
  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;
}

[Pascal]

program MPIBegin1;
uses PT4, MPI;
var
  flag, size, rank: integer;
  n: integer;
begin
  Task('MPIBegin1');
  MPI_Initialized(flag);
  if flag = 0 then exit;
  MPI_Comm_size(MPI_COMM_WORLD, size);
  MPI_Comm_rank(MPI_COMM_WORLD, rank);
  GetN(n);
end.

Для ввода исходных данных мы используем стандартные для задачника Programming Taskbook операции: процедуру GetN для Pascal и поток ввода pt для C++ (вместо процедуры GetN можно было бы использовать «универсальную» процедуру Get). Запустив полученную программу, мы увидим на экране окно задачника:

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

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

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

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

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

Добавим после оператора ввода соответствующий оператор вывода, в котором выведем удвоенное значение исходного значения n:

[C++]

  pt << 2 * n;

[Pascal]

  PutN(2 * n);

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

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

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

[C++]

  pt << size;

[Pascal]

  PutN(size);

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

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

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

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

[C++]

void Solve()
{
  Task("MPIBegin1");
  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;
}

[Pascal]

program MPIBegin1;
uses PT4, MPI;
var
  flag, size, rank: integer;
  n: integer;
begin
  Task('MPIBegin1');
  MPI_Initialized(flag);
  if flag = 0 then exit;
  MPI_Comm_size(MPI_COMM_WORLD, size);
  MPI_Comm_rank(MPI_COMM_WORLD, rank);
  GetN(n);
  PutN(2 * n);
  if rank = 0 then
    PutN(size);
end.

Начиная с версии 4.13, задачник автоматически выполняет многократный запуск учебной программы, пока не будет выявлена какая-либо ошибка или пока не будет успешно пройдено требуемое число тестов. Для заданий группы MPIBegin требуется успешно пройти пять тестовых запусков, после чего на экране появится окно задачника с сообщением «Задание выполнено!»:

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


PrevNext

 

Рейтинг@Mail.ru

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

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