Библиотека MPI [Электронный ресурс] (90
..pdfамогутинеобладатьсвойствомодновременновозвращатьуправлениевсем |
|
|
|
|
процессам;нодлянихэтосвойствоявляетсяпобочныминеобязательным. |
|
|
||
Есливпрограмменеобходимасинхронность,используйтетолько |
|
|
|
|
MPI_Barrier. |
|
|
|
|
Когдаможетпотребоватьсясинхрониза |
|
ция?Впримере3.1 |
|
|
синхронизиспользуетсяпередавазавершениемцйным:тампроцесс0 |
|
|
|
|
рапобшибкертует,чтниобыдинизоставшихпроцессоввызовомя |
|
|
|
|
MPI_Abortнезавершиланулевойдосрочно |
|
-принудительно,перед |
MPI_Abort |
|
поставленбар |
ьер. |
|
|
|
Алгоритмическойнеобходимовбарьерах,какпред,нетст. иавляется |
|
|
||
Паралгоритмдлялельныйсвоегоописаниятребуетпосравнению |
|
|
|
|
алгоритмомкласвслишьическимегодвухдополнительныхопераций |
|
– |
||
приередачиданныхмамеждупроцессами.Точкисинхронизациинес |
|
ут |
||
чистотехнологичнагврузку,чтодописанайевскуюпредыдущем |
|
|
|
|
абзаце. |
|
|
|
|
Функцииколлективногообменаданн |
|
ыми. |
|
|
Основныеособенностиотличияобычныхмежпроцессных |
|
|
||
коммуникацийтипаточка" |
-точка": |
всезадачи -абоненты |
||
напри/илипеемредачуаботаютодновременно |
|
|||
указываемогокоммуникатпроцедура,соответствующаябытьлжна |
|
|
||
вызванакаждымпроце,бытьможет,ссвоимомнабопаром |
|
|
аметров; |
|
коллективнаяфункциявыполняетодновремпри, ;меннодачу |
|
|
||
онаимеетбольшоеколичествопараметров |
|
,частькоторыхнужнадля |
|
|
приема,частьдляперед;вразныхтдчиилиинчахстья |
|
|
|
|
игнорируется; |
|
|
|
|
какправило,значения всехпараметровзаисключением( адресов буферов)должныбытьидентичнымивовсехзадачах;
MPIназначаетидентификатордлясообщ |
|
енийавтоматич |
ески; |
кртого,сообщмепернепоуказываемомудаютсяниякоммуникатору, |
|
|
|
аповременномукоммуникатору |
|
-дуплика;темсамымпотокиданныху |
|
коллектфункцийнадежновныхзолируютсядруготдругаот |
|
|
|
пот,создаковфунных |
кциямиточка" |
-точка"; |
|
возвратизпроцедурыколлективнвзаиможпрдоевгойствияизойти тотмомент,когдаучастиепроцвданнойоперссаужезаконченоции, какидляблокирующихпроцедур,возврознто,чтоачаетазрешен
свободныйдоступкбуферуприемаилипосылки,ноне |
значаетнитого, |
чтооперациязавед процессамиугимише,ндажетого,чтоонаими |
|
начатаесли(этов зможнопосмыслуопер |
ации). |
int MPI_Bcast( void *buf, int count, MPI_Datatype datatype, int source, MPI_Comm comm);
Параметры: |
|
|
buf -адресначалабу |
ферапосообщенияылкивыходной( пар |
аметр); |
|
31 |
|
count -числопередаваемыхэлементовсообщ |
|
ении |
|
||
datatype -типпередаваемыхэлементов |
|
|
|
||
source -номеррассылающегопроцесса |
|
|
|
||
comm -идентификаторгруппы |
|
|
|
||
Выполняетсяра сылкаообщенияотпроцесса |
|
sourceвсем процессам, |
|||
включаярассылающийпроцесс.Привозвиз оцатесодержимоедуры |
|
|
|
||
буфера bufпроцесса sourceбудетскопировапроцессалокальбуфер.ный |
|
||||
Значенияпараметров |
count, datatypeи sourceдолжныбытьодинаковымиу |
||||
всехпр оцессов. |
|
|
|
|
|
int MPI_Gather(void *sbuf, int scount, MPI_Datatype stype, |
|||||
|
|
void *rbuf, int rcount, MPI_Datatype rtype, |
|||
Параметры: |
int dest, MPI_Comm comm); |
|
|||
|
|
|
|
||
sbuf -адресначалабуферапосылки |
|
|
|
||
scount -числоэлементвпосылаемомсообщв |
|
ении |
|
||
stype -типэлементотсылаемогосо вбщ |
|
ения |
|
||
rbuf -адресначалабуфеданныхсборкивыходной( пар |
|
|
аметр) |
||
rcount -числоэлементовпринимаемомсообщ |
|
ении |
|
||
rtype -типэлементовпринимаемогосоо |
|
бщения |
|
||
dest -номерпроцесса,накоторомпроисходитсборкаданных |
|
|
|
||
comm -идентификаторгруппы |
|
|
|
||
ierror -код ошибкивыходной( параметр) |
|
|
|
||
Даннаяфункциясо("")выполняетоксборкуданныхсовсехпроцессов |
|
|
|
||
буфере |
rbufпроцесса dest.Каждыйпроцесс,включая |
|
dest,посылает |
||
содержимоесвоегобуфера |
|
sbufпроцессу |
dest.Собирающийпроцесс |
||
сохраняетданныевбуф ре |
|
rbuf,располагаяихвпорядкевозрастания |
|
||
номеровпроце |
ссов.Параметр |
rbufимеетзначениетолькособирающем |
count, datatypeи |
||
процессеина |
стальигн,ыхорируетсязначенияпараметров |
|
|||
destдолжныбытьодинаковымиувсехпр |
оцессов. |
|
|||
Векторныйвариантфункци |
|
исбораданных |
– MPI_Gatherv –позволяет |
||
задавать |
разное |
количествоотпра |
вляемыхданныхвразныхзадачах |
- |
|
отправителях.Соответственно,наприемнойсторонезадаетсямассив |
|
|
|
||
позицийвприемномбуфере,покотоследуетразымпоступающиеещать |
|
|
|
||
данные,имаксима |
льныедлиныпорцийданныхотвсехзадач.Обамассива |
|
rcount. |
||
содержатпозиции/длиныневбайтах,вкол |
|
|
ичесячеектипаве |
||
Функция MPI_Scatter разбр(" ")вызгиватполняобратнсовку"" етлью |
|
|
|||
операцию –частипередающегобуфераиззадачиrootраспределяются |
|
по |
|||
приемнымбуферамвсехз |
адач. |
|
|
|
|
Векторныйвариант |
– MPI_Scatterv,рассылаетчастинеодинаковой |
|
|||
длинывприемныебуф |
еранеодинаковойлины. |
|
|
||
|
|
|
32 |
|
|
Функция MPI_Allgatherаналогична |
MPI_Gather,ноприем |
||||
осущнводнойествлязадаче,во тся |
всех:каждаяимеетсп |
ецифическое |
|||
содержимоевпередающембуфере,всполучаютодинаковоесодержимое |
MPI_Gather,приемныйбуферпоследовательно |
|
|||
буферепр |
иемном.Какив |
|
|||
заполданизовснымияетсяпередающх.Вариантснеод хнаковым |
MPI_Allgatherv. |
|
|
||
количествомда |
нныхназывается |
|
|
||
MPI_Alltoall каждый: процесснар редающзаетбуфернакуский |
|
|
|||
рассылкускиостальнымпроцессамет;каждыйполуотскичает |
|
|
|
||
всехостальныхипоочередноразмещаетихприемнбуфере.Эс"о"ивокм |
|
|
|
||
"разбрызгива"одномфлаконе.Векторль |
|
ныйвариантназывается |
|||
MPI_Alltoallv. |
|
|
|
|
|
Вучебнике,изданномMITстьхорошаясхемаPress,длявсех |
|
|
|
||
перечислевэтомразделефу.нкцийных |
|
|
|
||
Помните,чток ллфункцииктивныенесовмстимы |
|
|
|
||
коммунифункциямитипаационнымиточка" |
|
-точка":недопустимым, |
|||
например,являетсявызоводнойизпринимающихшироковещательное |
|
|
|||
сообщениезадач |
MPI_Recvвместо MPI_Bcast. |
|
|
||
Распределенныеоперации. |
|
|
|
||
Идеяпроста:вкажзаимедойачемас.Надтнулевымисивяячейками |
|
|
|
||
всехмассивовпроизнекоперацияторадитсясложение( /прои |
|
|
зведение/ |
||
поискминимума/максимумат.д.),надпервымиячейкамипроизводится |
|
|
|
||
такаяжеоперацият.д.Четыфункцииредляназначенывызлваэтих |
|
|
|
||
операцийотличаютсяспособомразмещениярезультатавзад |
|
|
ачах. |
||
int MPI_AllReduce( void *sbuf, void *rbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
Параметры: |
|
|
|
sbuf -адресначабуферадларгументовя |
|
|
|
rbuf -адресначабуфдлреаяразультатавыходной( пар |
аметр) |
|
|
count -числоаргукаждогоментовпроце |
сса |
|
|
datatype -типаргументов |
|
|
|
op - идентификатоперацииглобальной |
|
|
|
comm -идентификаторгруппы |
|
|
|
Выполнение countглобальныхопераций |
opсвозвратом |
count |
|
результатоввовсехпроцессахбуфере |
|
rbuf.Операциявыполняется |
|
независимонадсоответствующимиаргументамивсехпроцессов.Значени |
|
я |
|
параметров countи datatypeувсехпроцессовдолжныбытьодинаковыми.Из |
op |
||
соображенийэ |
ффективностиреализациипредп,чтоперациялагается |
|
|
обладаетсвойсассоциативностивамикоммут |
ативности. |
|
|
33
int MPI_Reduce( void *sbuf, void *rbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
Параметры: |
|
|
sbuf -адресначабуферадларгя |
|
ументов |
rbuf -адресначабуфдлреаяразультатавыходной( пар |
аметр) |
|
count -числоаргукаждогоментовпроце |
сса |
|
datatype -типаргументов |
|
|
op -иденти фикаторглобальнойоперации |
|
|
root -процесс -получательрезультата |
|
|
comm -идентификаторгруппы |
|
|
Фуаналогичнакцияпредыд,норезбудетзаписанльтатщейвбуфер |
|
|
rbufтолькоупроцесса |
root. |
|
int vector[16];
int resultVector[16];
MPI_Comm_rank( MPI_COMM_WORLD, &myRank ); for( i=0; i<16; i++ )
vector[i] = myRank*100 + i; MPI_Reduce(
каждаяvector,задачавкоммуникаторепредоставляет/*
вектор*/ resultVecзадачаномер'root'собираетданныеor, /*
с юда */
количество16,ячеекисходномрезультирующем/*
массивах*/
иMPIтипячеек*/INT, /*
описательMPIоперацииSUM,:поэлементноесложение/*
векторов*/ номер0,задачи,собрезурающей/* льтатыв
'resultVector' */ MPIописательобластиCOMMсвяз*/WORLD /*
);
if( myRank==0 )
печатаем/* resultVector,равныйсуммевекторов*/
ПредописателейределенныхоперацийвMPIнасчит |
|
|
|
ывается12: |
MPI_MAXи MPI_MINищутпо |
элемаксимументные |
инимум; |
||
MPI_SUMвычисляетсуммувекторов; |
|
|
|
|
MPI_PRODвычиспоэлпроизведениеементноеяет |
|
кторов; |
||
MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR, MPI_BXOR - |
||||
логическиедв ичныеперацииИ,ИЛИ, |
|
|
|
сключающееИЛИ; |
MPI_MAXLOC, |
MPI_MINLOC |
-поискиндексированного |
||
минимума/максимума |
-здесьнерассматр |
иваются. |
||
|
|
|
34 |
|
Каждфункцияработаетсмассивамиопределенныхтиповтаблица( 2). Этиоперандпамогутсоооветпи,приведенныествоватьатели таблице3.
Таблица2Соотв. оператствие |
циоперандовй |
|
|
|
||||
|
|
|
|
|
|
|
|
|
Операция |
|
|
|
Допустимыйтип |
ерандов |
|||
MPI_MAX, MPI_MIN |
|
|
целыеивещественные |
|
|
|||
MPI_SUM, MPI_PROD |
|
|
целые,вещественные,комплек |
|
сные |
|||
MPI_LAND, MPI_LOR, MPI_LXOR |
|
цеилогые |
ические |
|
|
|||
MPI_LAND, MPI_LOR, MPI_LXOR |
|
целыев(т.ч.байтовые) |
|
|
||||
Таблица3Соотв. опеиописателейрандовтствие |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
Тип |
|
|
ОписательвС |
|
|
Описательв |
||
|
|
|
|
FORTRAN |
||||
|
|
|
|
|
|
|
|
|
|
|
MPI_INT, MPI_UNSIGNED_INT, |
|
|
|
|||
Целый |
|
MPI_LONG, MPI_UNSIGNED_LONG, |
|
MPI_INTEGER |
||||
|
|
MPI_SHORT, MPI_UNSIGNED_SHORT |
|
|
||||
Целый |
|
MPI_BYTE |
|
|
|
(нет) |
||
Байтовый |
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
MPI_FLOAT, MPI_DOUBLE, |
|
|
MPI_REAL, |
|||
Вещественный |
|
|
|
MPI_DOUBLE_ |
||||
|
MPI_LONG_DOUBLE |
|
|
|
||||
|
|
|
|
|
PRECISION |
|||
|
|
|
|
|
|
|
|
|
Логический |
|
(нет,пользуйтесьтипомint) |
|
|
|
MPI_LOGICAL |
||
Комплексный |
|
(нет) |
|
|
|
|
|
MPI_COMPLEX |
Количествоподдержоперациямитиповдляячвекторовваых |
|
|
|
|
||||
строгоограниченовышеперечисленными. |
|
|
Никакиедругвстроенныели |
|||||
пользовательскиеописателитиповиспольз |
|
|
|
оватьсянемогут. |
|
|
||
MPI_Reduce_scatter каж: заполучданеячавесьмассивет |
|
|
|
-результат, |
||||
егочасть.Длиныэтихчастейнаходятсявмассиве |
|
|
|
|
|
-третьемпара етре |
||
функции.Размерисходныхмас |
|
сивосехзадачаховодиравеннаковсумме |
|
|
|
|||
длинрезультирующихмасс |
ивов. |
|
|
|
|
|||
MPI_Scan аналогична: функции |
|
|
MPI_Allreduceвтотношениим,что |
|||||
кажзаполучаетдарезультрующямассив.Главноеотличие:здесьй |
|
|
|
|
|
|
||
содержимоемассива |
-результатавзадачеявляетi |
|
сярезультатомвыполнение |
|||||
опернадм цииссиззадачсномерамиваотдо0вклi |
|
|
|
|
|
ючительно. |
||
Помимовстр,п енныхльзоваможетвводитьсв ельбственные |
|
|
|
|
||||
операции,номеханизмихсозднеаниярассматриваетсяесь.Дляэтого |
|
|
|
|
|
|
||
служатфункции |
MPI_Op_create |
и MPI_Op_free,атакжетип |
||||||
MPI_User_function. |
|
|
|
|
|
|
||
|
|
|
|
|
35 |
|
|
|
Коммуникаторы,группыобластисвязи
|
Группа -этонекоемножествопроцесс.Одинпроцессбытьжетв |
|
|
|||
членомнесколькихгрупп.Враспоряжрогпреаммистатипдоставлене |
|
|
||||
MPI_Groupинаборфункций,работающих |
спеременнымиконстантами |
|
||||
этоготипа.К ,собственнонстант,две: |
|
|
MPI_GROUP_EMPTYможетбыть |
|||
возвращена,еслигруппазапрхарактеристмымишивпринципеками |
|
|
||||
можетбытьсоздана,нопокнесодержитниоднойветви; |
|
|
|
|
||
MPI_GROUP_NULLвозвращ,когдается |
апрашиваемыехарактеристики |
|
||||
противоречивы.Согла |
|
сноконцепцииMPI,послесозданиягруппунельзя |
|
|||
дополнитьилиусечь |
|
|
–можносоздатьтольконовгрподутребуемыйюппу |
|
||
наборветвейбазесущес |
|
|
твующей. |
|
|
|
|
Областьсвязи |
(communication |
domain) –этонечтоабстр |
актное.В |
||
распрограмморяжениинеттипаданных,описывающегоста |
|
|
||||
непосредственнообластисвязи,какнетфункцуправлению.мий |
|
|
||||
Областисвязиавтом |
|
|
атическисоздаютуничтожаютсявместе |
всезадачи |
||
коммуникаторами.Аб нентамиднойобластсвязиявляются |
|
|
||||
либоодной,либодвухгрупп. |
|
|
|
|
|
|
|
Коммуникатор,илиописательобластисвязи |
–этоверхушка |
||||
трехслойногопирогагруппы( ,областисвязи,опобластейсателисвяз), |
|
|
||||
которымработзад.Именноасчиюткоммунпрогрикмеетаторамиммист |
|
|
||||
дело,в |
ызываяфункци |
|
ипересылкиданных,такжеподавляющуючасть |
|
||
вспомогательныхфункций.Однообластисвязимогутсоо ветствовать |
|
|
||||
несколькокоммуникаторявляются.Комму "есикаторыобщающимися |
|
|
||||
сосудами":еслиданныеотправленычерезодинкоммуникатор,ветвь |
|
- |
||||
получательс |
можетприхтольконятьчерезэтотжесамыйкоммуникатор,но |
|
|
|||
ничерезкакой |
-либодр |
|
угой. |
|
|
|
Зачемнужныразныегруппы,разныеобластисвязиразныеих описатели?
Посуществу,онислужаттойжецели,чидентификаторысообщений -помогаютветви -приемникуиветви -получателюнадежнееопред лять
друга,такжесодсооржимое |
бщения; |
|
|
Ветвивнутрипараллельногоприлм гутбъединятьсяженияв |
|
|
|
подколлектдлярешенияпромежуточныхзадачвы |
|
-посредством |
|
созданиягрупп,областейсвязинадгруппами.Пользу |
|
ясьописателем |
|
этойобла |
стисвязи,ветвигараничеготинепризвнеимутованно |
|
|
подколл,иничегонеотправятнаружукти.Параллельноприэтомони |
|
|
|
могутпродопользоватьсялюбымжатьдругимимеющимсяих |
|
|
|
распкоряженииммуник |
аторомдляпересылоквнеподк |
оллектива, |
|
например, |
MPI_COMM_WORLDдляобмеданвнвсегоаутрыми |
|
|
приложения;
Коллективныефункциисоздаютдубликатотполученногоаргументом коммуник,передданныечерездубликатторают,неопасаясь,чтоих
36
сообщениябудперепутаныслучайносо б |
щениямифункцийто" |
чка- |
точка",распространяемымичеоригинальезкомму икый |
|
атор; |
Программистэтойжецельювразныхкускахкодаможетпередавать данныемеждуветвямичерезразныекоммуникаторы,одинизкоторых созданкопидр.угогоованием
Коммуникаторыраспределяютсяавтоматичфункциями( сем скийства "Создатьновыйкомму"),идлянихсуществуетикаторджокеров
("принимайчерезкакоугоднокоммуникатор") |
–вотещедваих |
существиденыхдостоипереднстсообщенийваификаторами. |
|
Идентификаторыцел( |
ыечисла)распределяюпользовавручную, телемся |
иэтослужитистодвухчастыхникомошибоквследствпутнаницые |
|
приемнойстороне: |
|
сообщениям,имеющимразнсм,вручыпослйошибкенуюазначается |
|
одинтотжеидентифик |
атор; |
функцияприемасджокеромсгр ебавсеподряд,втомтчитесле сообщения,котд лжнырпртьиобработанынятывдругомместе ветви.
Важнопомнить,чтовсефункции,создающиекоммуникатор,являются |
|
|
|||
коллективными.Именноэтокачествопозволяеттакимфункциямвозвращать |
|
||||
вразныев |
етви |
одинтотже |
описатель.Коллезаключаетсятивность |
|
|
следующем: |
|
|
|
|
|
однимизаргументовфункцииявляетсякоммуникатор; |
всеветви -абонентыуказываемого |
|
|||
функциюдолжнывызывать |
|
|
|||
коммуникатора. |
|
|
|||
Созданиекоммуникаторовгрупп |
|
|
|||
Копирование. |
Самыйпростойсп |
особзданиякоммуникатора |
- |
||
скопироватьодин" |
|
-в-од"ужеинмеющи |
йся: |
|
|
int MPI_Comm_dup( MPI_Comm comm, MPI_Comm *newcomm); |
|
||||
Параметры: |
|
|
|
|
|
comm -идентификаторгруппы |
|
|
|||
newcomm -иденовойтификгрупвыходной( партор |
аметр) |
|
|||
Новаягруппаприэтомнесозда |
|
ется -наборзадачостапрежним. тся |
|
||
Новыйкоммунинаслвсвойсекопирудуетаторва |
|
емого. |
|
||
Разбиение. |
Соответствующаякоммуникгруппаразбиваетсятору |
|
|||
непересеподгруппы,длякаждойизющиесякоторыхзаводитсясвой коммуникатор.
int MPI_Comm_Split( MPI_Comm comm, int color, int key, MPI_Comm *newcomm);
Параметры:
37
comm -идентификаторгруппы |
|
|
|
||
color -призразделениягруппык |
|
|
|
||
key -парам,опрнумерациютрделяющийвновыхгруппах |
|
|
|
||
newcomm -иденовойтификаторгруппывыходно( |
|
йпар аметр) |
|||
Даннаяпроцедураразбиввсемножествопроцессовет,входящих |
|
|
|
||
группу comm,нанепересекающиесяподгруппы |
-однуподгруппунакаждое |
||||
значениепараметра |
color неотр( чи)Кажд.слоцательноеновподгруппаая |
colorуказзначениено |
|||
содевсепржитодногоцессыцвета.Е |
|
|
сливкачестве |
||
MPI_UNDEFINED,тов |
newcommбудетвозврзначениещено |
||||
MPI_COMM_NULL. |
|
|
|
||
Созданиечегр.езуппы |
|
Впредвухслучаяхыдущихкоммуникатор |
|
||
создаетсяотсуществующегокоммуникаторанапрямую,безявнсозданияго |
|
|
|
||
группы:группа |
|
либотажесамая,либосоздаетсяавтоматически.Самыйже |
|
|
|
общийсп |
особтаков: |
|
|
|
|
1.функцией MPI_Comm_groupопределяетсягруппа,накоторуюуказывает соответствующийкоммуникатор;
2. набазесуществующихгруппфункциямисемейства |
MPI_Group_xxx |
|
создаютсяновыегруп |
пыснужнымнаборомве |
твей; |
3. дляитоговойгруппыфункцией |
|
MPI_Comm_createсоздается |
коммуник;незабу,чтоондолжнаьбытьвеор |
|
ызванавоВСЕХ |
ветвях-абонентахкоммуникатора,передаваепервыпара огое |
тром; |
|
4. всеописателисозданнгруппоч вщаютсяыхз |
|
овамифункции |
MPI_Group_free. |
|
|
Такоймеханизмпозволяет,час,неностиолькорасщегруплятьпы |
|
|
подобно MPI_Comm_split,нои бъединятьих.ВсеговMPIопределено7 |
|
|
разныхфункцийконстгрупп. ирования |
|
|
Можетлизадачаобркоблтитьсясвязи,астибонен |
|
томкоторойне |
явля?Нет.ОписатобластисясвязиельредаетсязадачуфункциямиMPI, |
|
|
которыеодновременноделэтузадачуютабонентомописываемойобласти. |
|
|
Таковединствсуществующийспоснныйполучитьописательб.Попытки |
|
|
"пиратскими"средствамиобойти |
этопрепятствиена( , римолучитьр |
|
описатель,посредством |
MPI_Send/MPI_Recvпереслеговдругуюза,дачуть |
|
неявляющуюсяегоабонентом,итамивоспользоваться)не привет,исходих, ткореевсего,уютсябудетопределятьсядеталями реализации.
Пример 3
/*
*
*Созданиекоммуникатора -дуплик,надежноеразделениета
*потсообщенийков:
*MPI_Comm_dup, MPI_Comm_free
Измененныйподход* кобработкеошибокчерез
38
* MPI_Abort, MPI_Barrier */
#include <mpi.h> #include <stdio.h>
#define tag1 1 #define tag2 2 #defineсознательнаяошtag3"":ибкадентификатор1 /*
равен'tag1' */
#define ELEMS(x) (sizeof( x )/sizeof( x[0] ))
int main( int argc, char **argv )
{
MPI_Comm myComm; int rank, size;
MPI_Init( &argc, &argv );
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
/*Обработкаошибневерное" иол |
-возапущенныхзадач" */ |
if( size != |
2 && rank==0 ) { |
printf( |
"ERROR: 2 processes required ", |
|
"instead of %d, abort.\n", size ); |
MPI_Abort( MPI_COMM_WORLD, MPI_ERR_OTHER );
}
/*Барьернужен,чтобывслучаеошиб,поветвькаи0 рапортует* нейивызываетMPIосAbort,ветвиальные
не*смоглиприступитьквыполнениюсо держчательнойсти программы* .
*/
MPI_Barrier( MPI_COMM_WORLD );
/**Общаячастьзакончена, начинаетсодержательная** ча...ть
**/
/*Создаемещеодинко муникатор |
- копиюMPI_COMM_WORLD */ |
MPI_Comm_dup( MPI_COMM_WORLD, &myComm ); |
|
if( rankВетвьпередает0== */0 ) |
/* |
{ |
|
static char buf1[] = "Contents of first message"; static char buf2[] = "Contents of second message"; static char buf3[] = "Contents of third message";
/*Обратитевнимание:хотядлс |
ообщенвыбранодитотий |
же*идентифик,описателиобластисвязразныетор |
|
|
39 |
*/
MPI_Send( buf1, ELEMS(buf1), MPI_CHAR, 1, tag1, myComm );
MPI_Send( buf2, ELEMS(buf2), MPI_CHAR, 1, tag2, MPI_COMM_WORLD );
MPI_Send( buf3, ELEMS(buf3), MPI_CHAR, 1, tag3, MPI_COMM_WORLD );
}
elseВетвьпринимает1 */ /*
{
char buf1[100], buf2[100], buf3[100]; MPI_Status st;
/*ВызовНЕперехватитпервсообщен |
иеиз -затого, |
чтоtag1=tag3 */ |
|
MPI_Recv( buf3, ELEMS(buf3), MPI_CHAR, 0, tag3, MPI_COMM_WORLD, &st );
/*ВызовНЕперехватитпервсообщениеджокером*/
MPI_Recv( buf2, ELEMS(buf2), MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &st );
/*Первсообщениебудетусприештам,нгденадоято*/
MPI_Recv( buf1, ELEMS(buf1), MPI_CHAR, 0, tag1, myComm, &st );
Печатаемрезультатыприема/**/
printf("Received in buf1 = \'%s\'\n", buf1 ); printf("Received in buf2 = \'%s\'\n", buf2 ); printf("Received in buf3 = \'%s\'\n", buf3 );
} /* rank 1 */ |
|
|
/*УведомляемMPI,чтоб коммуникаторомльшенепользуемся. |
I_COMM_NULL |
|
Послеэтого* myCommбудетсброшенв MP |
||
то*естьв(а0),соответствующиеемуданныебудутпомечены |
|
|
на*удал |
ение. |
|
*/ |
|
|
MPI_Comm_free( &myComm );
MPI_Finalize();
}
Пример4
/*
40
