Може би най-елегантното решение би било да направите кода на Python част от вашето MPI приложение. След това ще може директно да изпраща данни (чрез MPI съобщения) до останалата част от MPI приложението, тъй като ще бъде част от него. Тук има два различни подхода:
1) Вмъкнете двоичния файл на Python като ранг 0 във вашата MPI работа. За да го изключите от участие в колективни операции в mpibinary
, ще трябва да направите субкомуникатор, който изключва ранг 0 и да го използвате за цялата по-нататъшна колективна комуникация в mpibinary
. Първата стъпка е лесната част. В Open MPI бихте направили:
mpirun --hostfile hosts -np 1 pythonbinary args : -np 32 mpibinary args
Това се нарича стартиране на MPMD (множество програми с множество данни) и ще стартира едно копие на pythonbinary
, което ще стане ранг 0, а също и 32 копия на mpibinary
, които ще станат ранг 1, ранг 2, ... до ранг 32 (33 процеса в обща сума). Други реализации на MPI също предоставят много подобни механизми за стартиране на MPMD. Тогава ще използвате MPI_Comm_split()
, за да създадете нов комуникатор, който не включва програмата Python. Разделянето на комуникатор е колективна операция. Ето защо трябва да го извикате както във вашия Python код, така и във вашето C++ приложение. MPI_Comm_split()
взема "цвят" и ключ и разделя комуникатора на множество подкомуникатори според различните цветове. След това процесите със същия цвят се сортират въз основа на стойността на ключа. Най-вероятно ще искате да го наречете така:
в Python:
python_comm = mpi.mpi_comm_split(mpi.MPI_COMM_WORLD, 0, 0)
in C++:
int rank;
MPI_Comm c_comm;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_split(MPI_COMM_WORLD, 1, rank, &c_comm);
Чрез използването на rank
като ключ се гарантира, че редът на процесите в c_comm
ще бъде същият, както беше преди разделянето, т.е. ранг 1 от MPI_COMM_WORLD
ще стане ранг 0 в c_comm
, ранг 2 ще стане ранг 1 и т.н.
Отсега нататък C++ приложението може да използва c_comm
за извършване на колективни операции както обикновено. За да комуникирате между кода на Python и C++, все още трябва да използвате MPI_COMM_WORLD
и кодът на Python все още ще бъде ранг 0 в него.
2) Използвайте средствата за управление на процеси MPI-2. Първо бихте изпълнили MPI задача, която се състои само от двоичния файл на Python:
mpirun --hostfile hosts -np 1 pythonbinary args
Тогава двоичният файл на Python ще създаде другия двоичен файл на MPI директно, използвайки MPI_Comm_spawn()
с желания брой нови процеси. Новосъздадените процеси ще имат свои собствени MPI_COMM_WORLD
и няма да е необходимо да използвате MPI_Comm_split()
. Освен това операцията за създаване на хайвер ще създаде интеркомуникатор, който ще позволи на кода на Python да изпраща съобщения до другата част на приложението MPI.
И в двата случая файлът hosts
ще съдържа дефиниция на всички хостове за изпълнение, които могат да изпълняват двоичните файлове на MPI. Ще трябва също да използвате едно от наличните MPI свързвания на Python.
Обърнете внимание, че трябва само да добавите някои MPI извиквания към вашия скрипт на Python като MPI_Init
, MPI_Finalize
, MPI_Comm_split
и съответните MPI_Send
/MPI_Recv
. Не е необходимо да го правите успоредно. MPI е доста гъвкав, което ви позволява не само да го използвате за паралелно споделяне на работа, но и като обща рамка за съобщения. Но имайте предвид, че обвързванията на Python трябва да използват същата MPI библиотека като останалата част от програмата.
Друго решение би било да се използва някаква библиотека за опашка за съобщения или групиране на файлове (което наистина е грубо изпълнение на MQ).
person
Hristo Iliev
schedule
15.05.2012