Главная страница
Навигация по странице:

  • 1. Широкомовна розсилка

  • 2. Обмін з синхронізацією

  • 3. Розподіл і збір даних

  • 4. Векторні підпрограми розподілу даних

  • 5. Операції передачі даних від всіх процесів всім процесам

  • MPI_Allgather Збирає дані від всіх процесів і пересилає їх усім процесам MPI Allgatherv

  • MPI Allreduce Збирає дані від всіх процесів, виконує операцію приведення, і результат розподіляє всім процесам MPI_Alltoall

  • MPI Alltoallv Пересилає дані від всіх процесів всім процесам ("векторний" варіант підпрограми MPI Alltoall) MPI_Gather Збирає дані від групи процесів MPI Gatherv

  • 6. Операції приведення і сканування

  • Операція Опис МРI_МАХ Визначення максимальних значень елементів одновимірних масивів цілого або дійсного типу MPI_MIN

  • MPI_SUM Обчислення суми елементів одновимірних масивів цілого, дійсного або комплексного типу MPI_PROD

  • MPI LAND Логічне " І"MPI BAND Бітове " І"MPI_LOR Логічне " АБО"MPI_BOR Бітове " АБО"MPI_LXOR

  • трспо. Лекція Колективні операції обміну повідомленнями в mpi


    Скачать 3.37 Mb.
    НазваниеЛекція Колективні операції обміну повідомленнями в mpi
    Анкортрспо
    Дата23.11.2022
    Размер3.37 Mb.
    Формат файлаpdf
    Имя файлаilovepdf_merged.pdf
    ТипЛекція
    #806999
    страница1 из 12
      1   2   3   4   5   6   7   8   9   ...   12

    Лекція 8. Колективні операції обміну повідомленнями в MPI.
    План лекції:
    1. Широкомовна розсилка
    2. Обмін з синхронізацією
    3. Розподіл і збір даних
    4. Векторні підпрограми розподілу даних
    5. Операції передачі даних від всіх процесів всім процесам
    6. Операції приведення і сканування
    У будь-якому колективному обміні бере участь кожен процес з деякої області взаємодії (рис. 8.1). Можна організувати обмін і в підмножині процесів, для цього є засоби створення нових областей взаємодії і відповідних їм комунікаторів.
    У MPI є підпрограми, що виконують операції розподілу і збору даних, глобальні математичні операції, такі як додавання елементів масиву або його обчислення максимального елемента і т.п.
    Рисунок 8.1. Колективний обмін даними
    Колективні обміни характеризуються наступними властивостями:
    • колективні обміни не можуть взаємодіяти з двоточковими.
    Колективна передача, наприклад, не може бути перехоплена двоточковою підпрограмою прийому;
    • колективні обміни можуть виконуватися як із синхронізацією, так і без неї;
    • всі колективні обміни є блокуючими для обміну, який ініціював їх;
    • теги повідомлень призначаються системою.
    1. Широкомовна розсилка
    Широкомовна розсилка виконується одним виділеним процесом, який називається головним (root), а всі інші процеси, які беруть участь в обміні, отримують по одній копії повідомлення від головного процесу

    Рисунок 8.2. Широкомовна розсилка
    Виконується широкомовна розсилка з допомогою підпрограми
    MPI_Bcast: int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root,
    MPI_Comm comm)
    Її параметри одночасно є вхідними та вихідними:
    • buffer — адреса буфера;
    • count — кількість елементів даних у повідомленні;
    • datatype — тип данихMPI;
    • root — ранг головного процесу, що виконує широкомовну розсилку;
    • comm — комунікатор.
    Особливості:
    1. Функція MPI_Bcast визначає колективну операцію і, тим самим, при виконанні необхідних розсилок даних виклик функції MPI_Bcast має бути здійснений всіма процесами комунікатора що вказано.
    2. Вказаний у функції Mpi_Bcast буфер пам'яті має різне призначення в різних процесах. Для процесу з рангом root, з якого здійснюється розсилка даних, в цьому буфері повинне знаходитися повідомлення, що розсилається.
    Для всіх останніх процесів вказаний буфер призначений для прийому даних.
    2. Обмін з синхронізацією
    Синхронізація за допомогою "бар'єру"є найпростішою формою синхронізації колективних обмінів. Вона не вимагає пересилання даних.
    Підпрограма MPІ_Barrierблокує виконання кожного процесу з комунікатора comm до тих пір, поки всі процеси не викличуть цю підпрограму.
    Параметром підпрограми є поточний комунікатор: int MPI_Barrier(MPI_Comm comm.)

    Рисунок 8.3. Загальна схема операції сихронізації
    Лістинг 8.1. Приклад використання колективного обміну:
    #include "mpi.h"
    #include int main(int argc,char *argv[])
    { char data[24]; int myrank, count = 25;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if (myrank == 0) { strcpy(data, "Hi, Parallel Programmer!");
    MPI_Bcast (&data, count, MPI_BYTE, 0, MPI_ COMM _WORLD) ; printf("send: %s\n", data); } else{
    MPI_Bcast(&data, count, MPI_BYTE, 0, MPI_COMM_WORLD); printf("received: %s\n", data);
    }
    MPI_Finalize(); return 0;
    }
    Результат виконання цієї програми:
    send:Hi, Parallel Programmer! received: Hi, Parallel Programmer! received: Hi, Parallel Programmer!

    Лістинг 8.2. Приклад використання широкомовної розсилки
    #include "mpi.h"
    #include int main (int argc, char *argv[])
    { int my rank; int root = 0; int count = 1; float a, b; int n;
    MPI_Init (&argc, &argv) ;
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank) ; if (myrank == 0) { printf ("Enter a, b, n\n"); scanf("%f %f %i", &a, &b, &n) ;
    MPI_Bcast (&a, count, MPI_FLOAT, root, MPI_COMM_WORLD)
    MPI_Bcast (&b, count, MPI_FLOAT, root, MPI_COMM_WORLD)
    MPI_Bcast(&n, count, MPI_INT, root, MPI_COMM_WORLD) ;
    } else
    {
    MPI_Bcast(&a, count, MPI_FLOAT, root, MPI_COMM_WORLD) ;
    MPI Bсast (&b, count, MPI FLOAT, root, MPI COMM_WORLD) ;
    MPI_Bcast (&n, count, MPI_INT, root, MPI_COMM_WORLD) ; printf("%i Process got %f %f %i\n", myrank, a, b, n) }
    MPI_Finalize() ; return 0;
    }
    3. Розподіл і збір даних
    Розподіл і збір даних виконуються з допомогою підпрограм
    MPI_Scatter і MPI_Gather відповідно. Список аргументів у обох підпрограм однаковий, але діють вони по-різному.

    Рисунок 8.4. Схема передачі даних для операції розподілу даних
    Рисунок 8.5. Схема передачі даних для операції збору даних
    При широкомовній розсилці всім процесам передається один і той же набір даних, а при розподілі передаються його частини.
    Виконується розподіл даних підпрограмою MPI_Scatter, яка пересилає дані від одного процесу всім іншим процесам в групі. int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *rcvbuf, int rcvcount, MPI_Datatype rcvtype, int root, MPI_Comm сomm)
    Її вхідні параметри:
    • sendbuf — адреса буфера передачі;;
    • sendcount — кількість елементів, що пересилаються кожному процесу (але не сумарна кількість елементів що пересилаються);
    • sendtype — тип переданих даних;
    • rcvcount — кількість елементів у буфері прийому;
    • rcvtype — тип прийнятих даних;

    • root — ранг передавального процесу;
    • comm — комунікатор.
    Вихідний параметр rcvbuf - адреса буфера прийому.
    Працює ця підпрограма наступним чином. Процес з рангом root
    ("головний процес") розподіляє вміст буфера передачі sendbuf серед всіх процесів. Вміст буфера передачі розбивається на кілька фрагментів, кожен з яких містить sendcount елементів. Перший фрагмент передається процесу 0, другий процесу 1 і т.п. Аргументи send мають значення тільки на стороні процесу root.
    Особливості:
    1.Оскільки функція MPI_Scatter визначає колективну операцію, виклик цієї функції при виконанні розсилки даних має бути забезпечений в кожному процесі комунікатора.
    2.Функція MPI_Scatter передає всім процесам повідомлення однакового розміру. Виконання загальнішого варіанту операції розподілу даних, коли розміри повідомлень для процесів можуть бути різного розміру, забезпечується за допомогою функції MPI_Scatterv.
    Підпрограма MPI_Gatherвиконує збір повідомлень від інших процесів у буфер головного процеса. int MPI_Gather (void * sendbuf, int sendcount, MPI_Datatype sendtype, void * rcvbuf, int rcvcount, MPI_Datatype rcvtype, int root, MPI_Comm comm)
    Кожен процес в комунікаторі comm пересилає вміст буфера передачі sendbuf процессу з рангом root. Процес root "склеює" отримані дані в буфері прийому. Порядок склеювання визначається рангами процесів, тобто в результуючому наборі після даних від процессу 0 йдуть дані від процессу 1, потім дані від процессу 2 і т.п.
    Аргументи rcvbuf, rcvcount і rcvtype відіграють роль тільки на стороні головного процесу. Аргумент rcvcount вказує кількість елементів даних, отриманих від кожного процесу (але не сумарну їх кількість).
    При виклику підпрограм MPI_Scatter і MPI_Gather з різних процесів варто використовувати спільний головний процес
    Особливості:
    1. Функція MPI_Gather також визначає колективну операцію, і її виклик при виконанні збору даних має бути забезпечений в кожному процесі комунікатора.
    2. При використанні функції MPI_Gather збірка даних здійснюється лише в одному процесі. Для здобуття всіх збираних даних на кожному з процесів комунікатора необхідно використовувати функцію збору і розсилки
    MPI_Allgather
    4. Векторні підпрограми розподілу даних
    Підпрограми
    MPI_Scatterv
    і
    MPI_Gatnerv
    є розширеними
    ("векторними") версіями підпрограм MPI_Scatter і MPI_Gather. Вони дозволяють пересилати різним процесам (або збирати від них) різну кількість
    елементів даних. Завдяки аргументу displs, який задає відстань між елементами, елементи які пересилаються можуть не розташовуватися безперервно в пам'яті головного процесу. Це може виявитися корисним, наприклад, при пересиланні частин масивів.
    Векторна підпрограма розподілу має наступні параметри: int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *rcvbuf, int rcvcount,MPI_Datatype rcvtype, int root, MPI_Comm comm)
    Вхідні параметри:
    • sendbuf – адреса буфера передачі;
    • send counts – цілочисельний одновимірний масив, що містить кількість елементів, переданих кожному процесу (індекс дорівнює рангу адресата). Його довжина дорівнює кількості процесів в комунікаторі;
    • displs — цілочисельний масив, довжина якого дорівнює кількості процесів в комунікаторі. Елемент з індексом i задає зсув відносно початку буфера передачі. Ранг адресата дорівнює значенню індексу i;
    • sendtype — тип даних в буфері передачі;
    • rcvcount — кількість елементів у буфері прийому;
    • rcvtype — тип даних в буфері прийому;
    • root — ранг передавального процесу;
    • comm — комунікатор.
    Вихідним є адреса буфера прийому rcvbuf.
    Підпрограма MРІ_Gatherv використовується для збору даних від всіх процесів в заданому комунікаторі та запису їх в буфер прийому із зазначеним зміщенням:
    іnt MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void
    *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, int root,
    MPI_Comm comm)
    Список параметрів у цієї підпрограми схожий на список параметрів підпрограми MPI_Scatterv.
    Виконання загального варіанту операції збору даних, коли розміри повідомлень, що передаються процесами, можуть бути різні, забезпечується за допомогою функції MPI_Allgathev.
    5. Операції передачі даних від всіх процесів всім процесам

    Рисунок 8.6. Загальна схема операції передачі даних від всіх процесів всім процесам (повідомлення показуються позначеннями вигляду i=>j, де i і j
    є ранги передавальних і приймаючих процесів відповідно)
    Кожен процес в комунікаторі передає дані з scount елементів кожному процесу (загальний розмір повідомлень, що відправляються, в процесах має бути рівний scount * p елементів, де p є кількість процесів в комунікаторі comm) і приймає повідомлення від кожного процесу.
    У обмінах, що виконуються підпрограмами MPI_Allgather і
    MPI_Alltoall, немає головного процесу. Деталі відправки і прийому важливі для усіх процесів, що беруть участь в обміні. Підпрограма MPI_Allgather збирає дані від усіх процесів і розподіляє їх усім процесам (рис. 8.7). Дія цієї підпрограми рівносильна дії послідовності викликів підпрограми
    MPI_Gather, в кожному з яких як головний використовуються різні процеси.
    Прийом виконується в усіх завданнях. Буфер прийому послідовно заповнюється повідомленнями від усіх процесів-посилачів.
    Рисунок 8.7.
    Схема передачі даних для підпрограми MPI_Allgather
    int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *rcvbuf, int rcvcount, MPI_Datatype rcvtype, MPI_Comm comm)
    Вхідні параметри цієї підпрограми:
    • sendbuf — початкова адреса буфера передачі;
    • sendcount — кількість елементів у буфері передачі;
    • sendtype — тип переданих даних;
    • rcvcount — кількість елементів, отриманих від кожного процесу;
    • rcvtype — тип даних у буфері прийому;
    • comm — комунікатор.
    Вихідним параметром є адреса буфера прийому (rcvbuf). Блок даних, переданий від i-го процесу, приймається кожним процесом і розміщується в i-м блоці буфера прийому recvbuf.
    Підпрограма MPІ_Alltoall пересилає дані за схемою "кожен - всім" і аналогічна підпрограмі int MPI_Allgather: int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *rcvbuf, int rcvcount, MPI_Datatype rcvtype, MPI_Comm comm)
    Вхідні параметри:
    • sendbuf — початкова адреса буфера передачі;
    • sendcount — кількість елементів даних, що пересилаються кожному процесу;
    • sendtype — тип даних у буфері передачі;
    • rcvcount — кількість елементів даних, що приймаються від кожного процесу;
    • rcvtype — тип даних, що приймаються;
    • comm — комунікатор.
    Вихідний параметр - адреса буфера прийому rcvbuf.
    Особливості:
    1. Виклик функції MPI_Alltoall при виконанні операції загального обміну даними має бути виконаний в кожному процесі коммунікатора.
    2. Варіант операції загального обміну даних, коли розміри передаваних процесами повідомлень можуть бути різні, забезпечується за допомогою функції MPI_Alltoallv.
    Векторними версіями MPI _ Allgather і MPI _ Alltoall є підпрограми
    MPI _ Allgatherv і MPI _ Alltoallv.
    Підпрограма MPI_Allgatherv збирає дані від усіх процесів і пересилає
    їх усім процесам: int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *rcvbuf, int *rcvcounts, int *displs, MPI_Datatype rcvtype,
    MPI_Comm comm)
    Її параметри співпадають з параметрами підпрограми MPI _ Allgatner, за винятком додаткового вхідного параметра displs. Це цілочисельний одновимірний масив, кількість елементів в якому дорівнює кількості процесів в комунікаторові. Елемент масиву з індексом i задає зміщення відносно початку буфера прийому recvbuf, в якому розташовуються дані, що
    приймаються від процесу i. Блок даних, переданий від j- го процесу, приймається кожним процесом і розміщується в j -му блоці буфера прийому.
    Підпрограма MPI_Alltoallv пересилає дані від усіх процесів усім процесам зі зміщенням: int MPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
    MPI_Datatype sendtype, void *rcvbuf, int *rcvcounts, int *rdispls, MPI_Datatype rcvtype, MPI_Comm comm)
    Її параметри аналогічні параметрам підпрограми MPІ _ Alltoall, окрім двох додаткових параметрів:
    • sdispls – цілочисельний масив, кількість елементів в якому дорівнює кількості процесів в комунікаторі. Елемент j задає зміщення відносно початку буфера, з якого дані передаються у'-му процесу.
    • rdispls – цілочисельний масив, кількість елементів в якому дорівнює кількості процесів в комунікаторі. Елемент i задає зміщення відносно початку буфера, в який приймається повідомлення від i- го процесу.
    Табл. 8.1. Підпрограми розподілу і збору даних
    Підпрограма
    Короткий опис
    MPI_Allgather
    Збирає дані від всіх процесів і пересилає їх усім процесам
    MPI Allgatherv
    Збирає дані від всіх процесів і пересилає їх усім процесам
    ("векторний" варіант підпрограми MPI_Allgather)
    MPI Allreduce
    Збирає дані від всіх процесів, виконує операцію приведення,
    і результат розподіляє всім процесам
    MPI_Alltoall
    Пересилає дані від всіх процесів всім процесам
    MPI Alltoallv
    Пересилає дані від всіх процесів всім процесам ("векторний" варіант підпрограми MPI Alltoall)
    MPI_Gather
    Збирає дані від групи процесів
    MPI Gatherv
    Збирає дані від групи процесів ("векторний" варіант підпрограми MPI Gather)
    6. Операції приведення і сканування
    Операції приведення і сканування належать до категорії глобальних обчислень. У глобальній операції приведення до даних від усіх процесів із заданого комунікатора застосовується операція MPI _ Reduce.
    Аргументом операції приведення є масив даних – по одному елементу від кожного процесу. Результат такої операції – єдине значення.
    У підпрограмах глобальних обчислень можливі наступні функції, що передається в підпрограму:

    • функція MPI, наприклад MPI_SUM;
    • функція користувача;
    • обробник функції користувача, який створюється підпрограмою
    MPI_op_create.
    Рисунок 8.8. Операція приведення
    Три версії операції приведення повертають результат:
    • одному процесу;
    • усім процесам;
    • розподіляють вектор результатів між усіма процесами.
    Операція приведення, результат якої передається одному процесу, виконується при виклику підпрограми MPІ_Reduce: int MPI_Reduce(void *buf, void *result, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
    Вхідні параметри підпрограми MPI _ Reduce:
    • buf – адреса буфера передачі;
    • count – кількість елементів у буфері передачі;
    • datatype – тип даних у буфері передачі;
    • ор – операція приведення;
    • root – ранг головного процесу;
    • comm – комунікатор.

    Рисунок 8.9. Глобальна операція приведення
    Підпрограма MPI_Reduce застосовує операцію приведення до операндів з buf, а результат кожної операції поміщається у буфер результату result. MPI_Reduce повинна викликатися усіма процесами в комунікаторові comm, a аргументи count, datatype і op в цих викликах повинні співпадати.
    Функція приведення (ор) не повертає код помилки, тому при виникненні аварійної ситуації або завершується робота усієї програми, або помилка мовчазно ігнорується.
    У MPI є 12 зумовлених операцій приведення:
    Табл. 8.2. Список зумовлених операцій приведення MPI
    Операція
    Опис
    МРI_МАХ
    Визначення максимальних значень елементів одновимірних масивів цілого або дійсного типу
    MPI_MIN
    Визначення мінімальних значень елементів одновимірних масивів цілого або дійсного типу
    MPI_SUM
    Обчислення суми елементів одновимірних масивів цілого, дійсного або комплексного типу
    MPI_PROD
    Обчислення поелементного добутку одновимірних масивів цілого, дійсного або комплексного типу
    MPI LAND
    Логічне " І"
    MPI BAND
    Бітове " І"
    MPI_LOR
    Логічне " АБО"
    MPI_BOR
    Бітове " АБО"
    MPI_LXOR
    Логічне виключаюче "АБО"
    MPI_BXOR
    Бітове виключаюче "АБО"

    Операція
    Опис
    MPI MAXLOC
    Максимальні значення елементів одновимірних масивів та їх
    індекси
    MPI MINLOC
    Мінімальні значення елементів одновимірних масивів та їх
    індекси
    Програміст може визначити і власні глобальні операції приведення.
    Це робиться за допомогою підпрограми MPI_Op_Сreate: int MPI_Op_Сreate(MPI_User_function *function, int commute, MPI_Op
    *op)
    Вхідними параметрами цієї підпрограми є:
    • function — функція користувача;
    • commute — прапор, яким присвоюється значення "істина", якщо операція коммутативна (тобто її результат не залежить від порядку операндів).
    Опис типу функції користувача виглядає наступним чином:
    typedef void (MPI_User_function)
    (void*a, void *b, int *len, MPI_Datatype *dtype)
    Тут операція визначається так:
    b[I] = a [I] op b[I] для І = 0, ..., len - 1.
    Після того, як функція користувача зіграла свою роль, її слід анулювати за допомогою підпрограми MPI_op_free: int MPI_Op_free(MPI_Op *ор)
    По завершенні виклику змінній ор присвоюється значення
    MPI_OP_NULL.
    У підпрограми MPI_Reduce є варіанти.
    Підпрограма MPI_Reduce
      1   2   3   4   5   6   7   8   9   ...   12


    написать администратору сайта