Programming Taskbook


E-mail:

Пароль:

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

 

ЮФУ SMBU

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

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

 

PT for MPI-2 | Разработка новых заданий | Особенности работы задачника в параллельном режиме

PrevNext


Особенности работы задачника в параллельном режиме

Варианты запуска откомпилированной программы

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

Прежде всего, следует учитывать, что откомпилированная учебная программа (exe-файл), предназначенная для выполнения задания по параллельному программированию, может выступать в различных качествах.

Программа, запускаемая непосредственно из среды программирования, всегда выполняется как обычная непараллельная программа. В частности, в непараллельном режиме всегда выполняется демонстрационный запуск программы (напомним, что для этого в конце имени задания, указываемого в качестве параметра функции Task, надо добавить символ «?» или «#»). При демонстрационном запуске не требуется подключения системы MPICH2, поэтому ознакомиться с содержанием задач по параллельному программированию можно и на тех компьютерах, на которых система MPICH2 не установлена.

Если запуск не является демонстрационным, то программа, запущенная из среды программирования, выступает в роли «загрузчика» своего параллельного варианта. Это позволяет максимально упростить действия учащегося при тестировании параллельной программы, поскольку требует от него только запуска разработанной программы непосредственно из среды программирования. Все прочие действия, связанные с нахождением файла mpiexec.exe системы MPICH2 и его запуском с требуемыми параметрами командной строки, выполняются задачником автоматически. Для ускорения процесса тестирования разработанного алгоритма программа-загрузчик последовательно выполняет несколько запусков параллельного варианта. Кроме того, при каждом запуске параллельного варианта программы программа-загрузчик обеспечивает случайный выбор количества выполняемых процессов.

Действия программы в режиме загрузчика

При своем запуске программа-загрузчик проверяет наличие программы mpiexec.exe системы MPICH2, создает в рабочем каталоге учащегося пакетный файл $pt_run$.bat, содержащий команду для запуска программы mpiexec.exe, и запускает созданный пакетный файл. Если программа mpiexec не найдена или пакетный файл нельзя создать или запустить, то выводится сообщение об ошибке, и выполнение программы-загрузчика немедленно завершается. Если же пакетный файл успешно запущен, то программа-загрузчик ожидает его завершения, после чего выполняет необходимые завершающие действия и заканчивает работу.

Разумеется, программу mpiexec.exe с требуемыми параметрами можно было бы запускать и непосредственно из программы-загрузчика, однако вариант с использованием пакетного файла обладает рядом преимуществ. Прежде всего, запуск пакетного файла приводит к отображению на экране стандартного консольного окна, в котором можно вывести информацию о том, что выполнен запуск программы в параллельном режиме, а также отобразить ту командную строку, которая обеспечивает запуск программы mpiexec.exe. Это позволяет сделать для учащегося более наглядным способ запуска параллельной программы; кроме того, из параметров командной строки учащийся может легко определить, сколько процессов параллельной программы запущено. Еще более важной является возможность стандартным образом (нажатием Ctrl+C или Ctrl+Break) прервать выполнение пакетного файла в случае зависания параллельной программы, что при выполнении заданий может происходить достаточно часто. Заметим, что описание действий, требующихся для прерывания выполнения пакетного файла (а также действий, связанных с настройкой некоторых параметров выполнения учебных программ в параллельным режиме), также приводится в его консольном окне (рис. 26).

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

Осталось обсудить следующий вопрос: как запущенная программа определяет, что она является загрузчиком? Казалось бы, для этого достаточно с помощью средств MPI определить количество процессов, связанное с запущенным экземпляром программы: если число процессов равно 1, значит, программа запущена не в параллельном режиме и, следовательно, является загрузчиком, тогда как в противном случае программа выступает в роли одного из процессов параллельной программы и не должна выполнять действия загрузчика. Однако при таком способе проверки появляется возможность запустить программу в параллельном режиме без предварительного запуска программы-загрузчика. Действительно, ничто не мешает учащемуся создать явным образом пакетный файл с командой запуска программы mpiexec.exe и, запустив этот пакетный файл, выполнить программу, решающую задачу, в параллельном режиме. Такой способ запуска является нежелательным прежде всего потому, что в этой ситуации количество процессов параллельной программы задает сам учащийся и, таким образом, задачник лишается возможности протестировать предложенное решение при различном числе процессов. Кроме того, в задании обычно предполагается, что число параллельных процессов лежит в определенном диапазоне, выход за границы которого может привести к ошибке при инициализации этого задания.

Следовало реализовать такой способ проверки, который делал бы невозможным выполнение параллельного варианта программы без предварительного запуска программы-загрузчика. Для этого проще всего было сделать так, чтобы экземпляр программы, выступающий в роли загрузчика, при своем запуске оставлял какую-либо метку в каталоге учащегося, а любой экземпляр запущенной программы проверял наличие этой метки: если метка обнаружена, то этот экземпляр считается одним из процессов параллельной программы, в противном случае он считается загрузчиком. При завершении работы параллельного варианта программы метка удаляется. Ясно, что метка должна быть защищена от «подделки», поэтому в качестве такой метки нельзя использовать, например, факт наличия в каталоге пакетного файла $pt_run$.bat.

В задачнике реализован достаточно надежный способ установки метки программой-загрузчиком. Благодаря ему учащийся не сможет запустить параллельный вариант своей программы с помощью «стороннего» пакетного файла: при таком запуске первый из запущенных параллельных процессов не обнаружит в каталоге метки загрузчика, поэтому он «решит», что сам является загрузчиком, поместит свою метку в каталог, создаст свой пакетный файл и запустит его на выполнение. При этом остальные параллельные процессы из «стороннего» пакетного файла даже не будут запущены, так как для их запуска программой mpiexec.exe необходимо, чтобы первый запущенный ею процесс в течение определенного времени после запуска (по умолчанию 10 с) перешел в параллельный режим, а в случае программы, выполняющей роль загрузчика, этого не произойдет.

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

Действия программы в параллельном режиме и обработка ошибок

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

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

Следует отметить, что главный процесс не только принимает от подчиненных процессов сигналы об ошибках, но и самостоятельно выявляет те ошибки, которые сами подчиненные процессы выявить не могут. В частности, он распознает ошибки, связанные с полным отсутствием операций ввода-вывода в некотором подчиненном процессе (в ситуации, когда в других процессах ввод или вывод выполнялся). Сам подчиненный процесс, в котором не выполнялись действия по вводу-выводу, «предполагает», что производится ознакомительный запуск программы, и поэтому в подобной ситуации не посылает главному процессу сигнал об ошибке.

При выполнении подчиненных процессов могут возникнуть ошибки, приводящие к их зависанию или аварийному завершению. В этом случае главный процесс не сможет получить от этих процессов информацию о результатах их работы. Если в течение определенного времени (зависящего от общего числа подчиненных процессов) главный процесс не получит информацию от некоторых подчиненных процессов, то он выведет в окне задачника сообщение «MPI error. Процессы … не отвечают» (где на месте многоточия указываются ранги зависших процессов). В этой ситуации после закрытия окна задачника потребуется явным образом прервать выполнение зависших процессов параллельного приложения, нажав несколько раз комбинацию клавиш Ctrl+C или Ctrl+Break. Время ожидания отклика от подчиненных процессов можно настраивать с помощью команд контекстного меню окна задачника; эта возможность добавлена для того, чтобы при выполнении сложных заданий на компьютерах с низким быстродействием время ожидания было достаточным для завершения в подчиненных процессах всех необходимых операций.

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

Все «обычные» ошибки времени выполнения (не связанные с библиотекой MPI) подчиненные процессы также перехватывают, после чего пересылают информацию о них главному процессу, который в этом случае выводит сообщение «Run-time error». Кроме того, подчиненные процессы могут распознавать различные ошибки, связанные с неверным вводом-выводом (ввод недостаточного числа исходных данных, попытка ввода лишних исходных данных или исходных данных неверного типа; вывод недостаточного числа результирующих данных, попытка вывода лишних результирующих данных или результирующих данных неверного типа).

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

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

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

Если ошибки в подчиненных процессах не обнаружены, то выполняется завершающая проверка правильности решения в главном процессе. При наличии ошибок ввода-вывода, ошибок времени выполнения или в случае несоответствия результирующих данных контрольным данным выводится соответствующее сообщение; если же ошибки отсутствуют, а результаты совпадают с требуемыми контрольными значениями, то данное испытание программы считается успешным. Как и для обычных, «непараллельных» заданий, входящих в базовый вариант задачника Programming Taskbook, задание считается выполненным после определенного числа успешных испытаний, проведенных подряд (для всех заданий, входящих в задачник PT for MPI-2, количество тестовых испытаний равно пяти). Как уже отмечалось ранее, все тестовые испытания выполняются при однократном запуске учебной программы (это еще одна часть действий, которые берет на себя экземпляр программы, выступающий в роли загрузчика).

Возможна ситуация, когда из-за ошибок в реализации параллельного алгоритма произойдет зависание главного процесса. Главный процесс можно считать зависшим, если в течение 20–30 с после отображения консольного окна с информацией о запуске программы в параллельном режиме на экране не появится окно задачника. В этом случае необходимо явным образом прервать выполнение параллельной программы, нажав несколько раз Ctrl+C или Ctrl+Break. В файл результатов в такой ситуации заносится информация о том, что выполнение задания было прервано.

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

  • этап 1 – запуск программы из интегрированной среды
  • этап 2 (выполняется несколько раз) – определение числа процессов K для очередного тестового испытания, создание и запуск пакетного файла;
  • этап 3 – запуск программы в параллельном режиме на локальном компьютере;
  • этап 4 – взаимодействие параллельных процессов при выполнении задания;
  • этап 5 – отображение результатов (в случае успешного прохождения всех испытаний или при обнаружении ошибки);
  • этап 6 (выполняется для каждого тестового испытания) –  завершающие действия, в частности, выгрузка зависших процессов.

PrevNext

 

Рейтинг@Mail.ru

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

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