Повышаю. MPI предоставляет альтернативный интерфейс MPI из языка программирования Python через модуль boost.mpi. Начало. MPI Привязки Python, построенные поверх C++ Boost. MPI, использующий библиотеку Boost.Python, обеспечивает практически всю функциональность Boost. MPI в динамическом объектно-ориентированном языке.
Начало. MPI Модуль Python может быть построен и установлен из каталога libs/mpi/build. Просто следуйте инструкциям конфигурация и установка для C++ Boost.MPI. После установки модуля Python убедитесь, что место установки находится в вашем PYTHONPATH.
Quickstart
Начало работы с Boost. Модуль MPI Python так же прост, как импорт boost.mpi. Наша первая программа «Здравствуй, мир!» состоит из двух строк:
importboost.mpiasmpiprint"I am process %d of %d."%(mpi.rank,mpi.size)
Продолжайте и запустите эту программу с несколькими процессами. Обязательно вызовите интерпретатор python из mpirun, например,
mpirun -np 5 python hello_world.py
Это возвращает такие результаты, как:
I am process 1 of 5.
I am process 3 of 5.
I am process 2 of 5.
I am process 4 of 5.
I am process 0 of 5.
Операции «точка-точка» в Boost. MPI имеет почти такой же синтаксис в Python, как и в C++. Мы можем написать простую двухпроцессную программу Python, которая печатает «Привет, мир!», передавая строки Python:
Существует лишь несколько заметных различий между этим кодом Python и примером в учебнике C++ . Прежде всего, нам не нужно писать какой-либо код инициализации на Python: просто загрузка модуля boost.mpiMPI_Init и MPI_Finalize. Во-вторых, мы передаем объекты Python из одного процесса в другой через MPI. Любой объект Python, который может быть замаринован, может быть передан; в следующем разделе будет описано более подробно, как увеличить. Слой MPI Python передает объекты. Наконец, когда мы получаем объекты с recv, нам не нужно указывать тип, потому что передача объектов Python является полиморфной.
Эксперименты с Boost. MPI в Python, не забывайте, что помощь всегда доступна через pydoc: Просто передайте имя модуля или объекта модуля в командной строке (например, pydocboost.mpi.коммуникатор) для получения полной справочной документации. Если сомневаетесь, попробуйте!
Transmitting User-Defined Data
Повышаю. MPI может передавать пользовательские данные несколькими различными способами. Самое главное, что он может передавать произвольные объекты Python, собирая их у отправителя и отбирая их у приемника, позволяя произвольно сложным структурам данных Python взаимодействовать с MPI.
Повышаю. MPI также поддерживает эффективную сериализацию и передачу объектов C++ (которые были подвержены воздействию Python) через интерфейс C++. Любой тип C++, который обеспечивает (де)сериализацию, которая соответствует требованиям Boost. Библиотека сериализации имеет право на эту оптимизацию, но тип должен быть зарегистрирован заранее. Для регистрации типа C++ введите функцию C++ register_serialized. Если ваши типы C++ происходят из других модулей Python (они, вероятно, будут!), эти модули должны будут ссылаться на библиотеки boost_mpi и boost_mpi_python, как описано в разделе установки . Обратите внимание, что вам нужно , а не , чтобы связать с Boost. Модуль расширения MPI Python.
Наконец-то, Буст. MPI поддерживает отделение структуры объекта от данных, которые он хранит, позволяя передавать две части отдельно. Этот механизм «скелет/контент», более подробно описанный в более позднем разделе, является оптимизацией связи, подходящей для проблем с фиксированными структурами данных, внутренние данные которых часто меняются.
Collectives
Повышаю. MPI поддерживает все коллективы MPI (scatter, reduce, scan, broadcast и т.д.) для любого типа данных, которые могут передаваться с помощью операций связи точка-точка. Для MPI-коллективов, требующих операции, заданной пользователем (например, сократить и scan), операция может быть произвольной функцией Python. Например, можно соединить строки с all_reduce:
mpi.all_reduce(my_string,lambdax,y:x+y)
Следующие функции уровня модулей реализуют MPI-коллективы: all_gather Соберите ценности из всех процессов. All_Reduce Объедините результаты всех процессов. All_to_all Каждый процесс отправляет данные в любой другой процесс. Трансляция данных из одного процесса во все другие процессы. Соберите значения от всех процессов до корня. уменьшать Объедините результаты всех процессов в корень. Сканирование префикса уменьшения значений от всех процессов. рассеивать Разброс значений, хранящихся в корне, по всем процессам.
Повышаю. MPI обеспечивает механизм скелета/контента, который позволяет разделить передачу больших структур данных на две отдельные стадии, причем скелет (или «форма») структуры данных отправляется первым, а содержимое (или «данные») структуры данных отправляется позже, потенциально несколько раз, если структура не изменилась с момента передачи скелета. Механизм скелета/содержимого может улучшить производительность, когда структура данных велика и его форма фиксирована, потому что, хотя скелет требует сериализации (он имеет неизвестный размер), передача контента имеет фиксированный размер и может быть выполнена без дополнительных копий.
Чтобы использовать механизм скелета/контента из Python, необходимо сначала зарегистрировать тип структуры данных с помощью механизма скелета/контента из C++. Функция регистрации register_skeleton_and_content и находится в заголовке .
После того, как вы зарегистрировали свои структуры данных C++, вы можете извлечь скелет для примера этой структуры данных с помощью skeleton(). Полученный skeleton_proxy может передаваться через обычную процедуру отправки, например,
mpi.world.send(1,0,skeleton(my_data_structure))
skeleton_proxy объекты могут быть приняты на другом конце через recv(), который хранит вновь созданный экземпляр вашей структуры данных с той же «формой», что и отправитель в его атрибуте "объект":
После того, как скелет был передан, контент (доступ через get_content) может быть передан во многом таким же образом. Обратите внимание, однако, что приемник также указывает get_content(my_data_structure) в своем призыве к приему:
Конечно, такая передача контента может происходить неоднократно, если изменяются значения в структуре данных, но не его форма.
Механизм скелета/содержимого представляет собой структурированный способ использования взаимодействия между построенными на заказ типами данных MPI и MPI_BOTTOM для устранения дополнительных буферных копий.
C++/Python MPI Compatibility
Повышаю. MPI - это библиотека C++, средства которой были открыты для Python через Boost. Библиотека Python. С самого начала. Привязки MPI Python построены непосредственно поверх библиотеки C++, и почти каждая функция библиотеки C++ доступна в программах Python, гибридных C++ / Python с использованием Boost. MPI может взаимодействовать, например, посылая значение из Python, но получая это значение в C++ (или наоборот). Однако это требует некоторой осторожности. Поскольку объекты Python динамически типизированы, Boost. MPI передает информацию о типе вместе с последовательной формой объекта, так что объект может быть принят даже тогда, когда его тип не известен. Этот механизм отличается от своего аналога на C++, где всегда известны статические типы передаваемых значений.
Единственный способ общения между C++ и Python на Boost. MPI — это трафик, полностью связанный с объектами Python. Для Python это нормальное состояние дел, поэтому ничего не изменится. Для C++ это означает отправку и получение значений типа boost::python::object, из библиотеки Boost.Python. Например, скажем, что мы хотим передать целое значение из Python:
comm.send(1,0,17)
В C++ мы получим это значение в объект Python, а затем извлечь целое значение:
В будущем, рост. MPI будет расширен для улучшения взаимодействия с C++ Boost. MPI и C MPI связывания.
Reference
Модуль Boost.MPI Python, boost.mpi, имеет собственную справочную документацию, которая также доступна с использованием pydoc (из командной строки) или help(boost.mpi) (из интерпретатора Python).
Design Philosophy
Философия дизайна библиотеки Parallel MPI очень проста: быть удобным и эффективным. MPI - это библиотека, созданная для высокопроизводительных приложений, но ориентированная на производительность FORTRAN, дизайн делает ее довольно гибкой с точки зрения C++: передача строки из одного процесса в другой неудобна, требует нескольких сообщений и явной буферизации; передача контейнера строк из одного процесса в другой требует дополнительного уровня ручной бухгалтерии; и передача карты из строк в контейнеры строк положительно раздражает. Библиотека Parallel MPI позволяет передавать все эти типы данных с помощью одних и тех же простых примитивов send() и recv(). Аналогично, коллективные операции, такие как уменьшение(), позволяют произвольные типы данных и объекты функций, подобно C++. Стандартная библиотека.
Абстракции более высокого уровня, предоставляемые для удобства, не должны влиять на производительность приложения. Например, отправка целого числа через send должна быть такой же эффективной, как вызов MPI_Send, что означает, что оно должно быть реализовано простым вызовом MPI_Send; аналогично, целое число reduce() с использованием std::> должно быть реализовано с вызовом MPI_SUM на целых числах с использованием операции MPI_SUM: все меньшее повлияет на производительность. По сути, это принцип «не платите за то, что вы не используете»: если пользователь не передает строки, он не должен платить накладные расходы, связанные со строками.
Иногда достижение максимальной производительности означает отказ от удобных абстракций и реализацию определенной функциональности с использованием примитивов более низкого уровня. По этой причине в Boost всегда можно извлечь достаточно информации из абстракций. MPI минимизирует количество усилий, необходимых для взаимодействия между Boost. MPI и библиотека C MPI.
Threads
Растет число гибридных параллельных приложений, которые смешивают распределенный и общий параллелизм памяти. Чтобы знать, как поддерживать эту модель, нужно знать, какой уровень поддержки потоков гарантируется реализацией MPI. Существует 4 упорядоченных уровня возможной поддержки потоков, описанных mpi::threading::level. На самом низком уровне вообще не следует использовать потоки, на самом высоком уровне любой поток может выполнять вызов MPI.
Если вы хотите использовать многопоточность в своем приложении MPI, вы должны указать в конструкторе среды предпочитаемую поддержку потоков. Затем проверьте ту, которую предоставила библиотека, и решите, что вы можете с ней сделать (это может быть ничем, тогда аборт является действительным вариантом):
#include<boost/mpi/environment.hpp>#include<boost/mpi/communicator.hpp>#include<iostream>namespacempi=boost::mpi;namespacemt=mpi::threading;intmain(){mpi::environmentenv(mt::funneled);if(env.thread_level()<mt::funneled){env.abort(-1);}mpi::communicatorworld;std::cout<<"I am process "<<world.rank()<<" of "<<world.size()<<"."<<std::endl;return0;}
Performance Evaluation
Производительность передачи сообщений имеет решающее значение в высокопроизводительных распределенных вычислениях. Чтобы оценить производительность Boost. MPI, мы изменили стандартный бенчмарк NetPIPE (версия 3.6.2) для использования Boost. MPI и сравнил его производительность с сырым MPI. Мы запустили пять различных вариантов бенчмарка NetPIPE:
MPI: Немодифицированный бенчмарк NetPIPE.
Повышаю. MPI: NetPIPE модифицирован для использования Boost. MPI требует коммуникации.
MPI (типы данных): NetPIPE модифицирован для использования производного типа данных (который сам по себе содержит один MPI_BYTE), а не фундаментальный тип данных.
Boost.MPI (типы данных): NetPIPE модифицируется с использованием определяемого пользователем типа Char вместо основного типа char. Тип Char содержит один char, метод serialize(), чтобы сделать его сериализуемым, и специализируется на is_mpi_datatype для форсирования Boost. MPI для построения производного типа данных MPI.
Boost.MPI (Serialized): NetPIPE модифицирован для использования определяемого пользователем типа Char вместо основного типа char. Этот тип Char содержит один char и может быть сериализован. В отличие от случая Datatypes, is_mpi_datatype является не специализированным, вынуждающим Boost. MPI для выполнения многих, многих серийных вызовов.
Фактические тесты были проведены на кластере Одина в Кафедра компьютерных наук в Индианский университет, который содержит 128 узлов, подключенных через Infiniband. Каждый узел содержит 4 ГБ памяти и два процессора AMD Opteron. Тесты NetPIPE были составлены с помощью компилятора Intel C++, версии 9.0, Boost 1.35.0 (предварительный выпуск) и Open MPI версии 1.1. Результаты NetPIPE следуют:
Есть некоторые наблюдения, которые мы можем сделать об этих результатах NetPIPE. Прежде всего, два лучших сюжета показывают, что Boost. MPI работает наравне с MPI для фундаментальных типов. Следующие два сюжета показывают, что рост. MPI работает наравне с MPI для производных типов данных, даже если Boost. MPI обеспечивает гораздо более абстрактный, полностью прозрачный подход к построению производных типов данных, чем необработанный MPI. Общая производительность для производных типов данных значительно хуже, чем для основных типов данных, но узким местом является сама реализация MPI. Наконец, при форсированном росте. MPI для сериализации персонажей индивидуально, производительность сильно страдает. Этот конкретный случай является наихудшим возможным случаем для Boost. MPI, потому что мы сериализуем миллионы отдельных персонажей. В целом, дополнительная абстракция, предоставляемая Boost. MPI не ухудшает его производительность.
Revision History
Повышение 1.36.0:
Поддержка неблокирующих операций в Python от Andreas Klöckner
Boost 1.35.0: Начальный выпуск, содержащий следующие изменения после обзора
Повышаю. MPI был разработан при поддержке Zurcher Kantonalbank. Дэниел Эглофф и Майкл Гауклер внесли много идей в Boost. Конструкция MPI, особенно в разработке абстракций для типов данных MPI и нового механизма скелета / контекста для больших структур данных. Прабханджан (Анджу) Камбадур разработал предшественника Бооста. MPI, который доказал полезность библиотеки сериализации в настройках MPI и преимущества специализации на уровне абстракции C++ для MPI. Джереми Сик руководил официальным обзором Boost. MPI.
Статья Python Bindings раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 24. Boost.MPI может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.