Які функції потрібні користувачам через інтерфейс MPI C ++?


28

Версія 3.0 стандарту MPI офіційно видалила інтерфейс C ++ (він раніше був застарілий). Хоча впровадження можливо все ще підтримує його, нові функції в MPI-3 не мають інтерфейсу C ++, визначеного в стандарті MPI. Докладнішу інформацію див. На веб-сайті http://blogs.cisco.com/performance/the-mpi-c-bindings-what-happened-and-why/ .

Мотивацією для видалення інтерфейсу C ++ з MPI було те, що він не мав значущого значення для інтерфейсу C. Окрім "s / _ / :: / g" було дуже мало відмінностей, і багато можливостей, до яких звикли користувачі C ++, не були використані (наприклад, автоматичне визначення типу за допомогою шаблонів).

Оскільки хтось, хто бере участь у Форумі MPI та працює з низкою проектів C ++, які реалізували власний C ++ інтерфейс до функцій MPI C, я хотів би знати, які бажані особливості інтерфейсу C ++ до MPI. Хоча я нічого не беру на себе, мені було б цікаво побачити реалізацію окремого інтерфейсу MPI C ++, який відповідає потребам багатьох користувачів.

І так, я знайомий з Boost :: MPI ( http://www.boost.org/doc/libs/1_54_0/doc/html/mpi.html ), але він підтримує лише функції MPI-1, і модель серіалізації буде надзвичайно складно підтримати RMA.

Один із інтерфейсів C ++ до MPI, який мені подобається, - це елемент Elemental ( https://github.com/poulson/Elemental/blob/master/src/core/imports/mpi.cpp ), тож, можливо, люди можуть надати певну підтримку підхід. Зокрема, я думаю, що MpiMap вирішує суттєву проблему.


Я не думаю, що це відповідне місце для такого питання.
Джек Поульсон

Чи можете ви навести деякі причини для цього? Багато питань MPI на цьому веб-сайті підказують, що люди тут готові відповісти на це питання. Також 0,2 оновлення в хвилину свідчать про те, що інші люди не згодні з вашою оцінкою. У будь-якому випадку, було б корисніше запропонувати альтернативне місце для розміщення цього повідомлення, якщо вам не подобається поточне місце.
Джефф

Питання є цінним, і я думаю, що він міг би отримати корисні відповіді у широких списках розсилки з обчислювальної науки, якщо він є в обсязі. (Можливо NA-дайджест, SIAM-CSE або навіть публічна публікація в G +?) Це питання може не підходити для сайту Stack Exchange, оскільки воно є суб'єктивним (див. Scicomp.stackexchange.com/help/dont-ask ) . Поки відповіді конкретні та зосереджені на конкретних випадках використання (без значних повторів чи перекриттів), я думаю, що варто триматись відкритими.
Джефф Оксберрі

@Jeff: Питання дуже схоже на опитування для мене. Я не заперечую, що це цінно, але я не бачу однієї прийнятої відповіді. Невже таке питання не є звичайним для форуму MPI?
Джек Поульсон

@JackPoulson Я не хочу знати, що реалізатори вважають правильною відповіддю; Я хочу знати, що потрібно вченим-обчислювачам. У цьому відношенні питання має об’єктивні відповіді. Немає однієї правильної відповіді, але це не означає, що це суб'єктивна ситуація.
Джефф

Відповіді:


17

Дозвольте спершу відповісти, чому я вважаю, що інтерфейси C ++ для MPI, як правило, не надто успішні, довго думаючи над проблемою, намагаючись вирішити, чи варто просто використовувати стандартні C прив’язки MPI або будувати щось на більш високому рівні :

Якщо ви подивитеся на коди MPI у реальному світі (скажімо, PETSc, або в моєму випадку .II), можна виявити, що, можливо, дивно, що кількість викликів MPI насправді не дуже велика. Наприклад, у 500k рядків deal.II є лише ~ 100 MPI-дзвінків. Наслідком цього є те, що біль при використанні інтерфейсів нижчого рівня, таких як прив'язки MPI C, не надто великий. І навпаки, не вдалося б отримати все так багато, використовуючи інтерфейси вищого рівня.

Моє друге спостереження полягає в тому, що в багатьох системах встановлено кілька бібліотек MPI (різні реалізації MPI або різні версії). Це створює значні труднощі, якщо ви хочете використовувати, скажімо, boost :: mpi, які не просто складаються із заголовкових файлів: або для цього пакета також повинно бути кілька установок, або потрібно створити його як частину проект, який використовує boost :: mpi (але це знову сама проблема, враховуючи, що boost використовує власну систему побудови, яка на відміну від усього іншого).

Тому я думаю, що все це склалося проти поточної культури інтерфейсів C ++ для MPI: Старі прив'язки MPI C ++ не надавали жодної переваги, а зовнішні пакети мали труднощі з реальним світом.

Це все сказано, ось що, на мою думку, було б вбивчою рисою, яку я хотів би мати із інтерфейсу вищого рівня:

  • Він повинен бути загальним. Необхідно вказати тип даних змінної, очевидно, не схожий на C ++. Звичайно, це також призводить до помилок. Клас MpiMap Elemental вже був би гарним першим кроком (хоча я не можу зрозуміти, чому хек MpiMap::typeзмінна не є статичним const, так що до неї можна отримати доступ, не створюючи об’єкт).

  • Він повинен мати засоби для потокової передачі довільних типів даних.

  • Операції, які потребують MPI_Opаргументу (наприклад, скорочення), повинні добре інтегруватися з std::functionінтерфейсом C ++ , так що легко просто передати функціональний покажчик (або лямбда!), А не незручно реєструвати щось.

boost :: mpi насправді задовольняє всім цим. Я думаю, якби це була лише бібліотека, яка займається заголовком, вона була б набагато популярнішою на практиці. Це також допоможе, якби він підтримував функції пост-MPI 1.0, але будьмо чесними: це охоплює більшу частину того, що нам потрібно найбільше часу.


Одне з питань серіалізації в Boost :: MPI полягає в тому, що він не працює з одностороннім (він же RMA). Як ви вважаєте, чи вдасться створити типи даних MPI для об'єктів C ++, які цікавлять користувачів? Звичайно, теоретично все слід підтримувати, але я вважаю за краще починати з більш прагматичної мети.
Джефф

Я думаю, що помилково думати, що серіалізований тип даних може колись працювати з однобічним зв’язком. Це передбачає думку, що серіалізація включає лише упаковку даних у рядок, а з іншого боку - повторне розпакування. Але функції серіалізації можуть зробити набагато більше (наприклад, відстежувати покажчики на інші об’єкти, рахувати байти, які були серіалізовані тощо), ніж можна очікувати, що вони працюватимуть, якщо ви не можете виконати нічого на хості призначення. На мою думку, серіалізація в стилі C ++ та однобічне спілкування - це просто нестандарт. Я думаю, що ніхто не повинен очікувати, що це спрацює, тому мало що буде пропущено.
Вольфганг Бангерт

Привіт Вольфганг, ви впевнені, що MpiMap був би більш елегантним, якби він використовував статичну змінну члена const. Я реорганізував реалізацію: github.com/poulson/Elemental/commit/…
Jack Poulson

Так, набагато приємніше :-)
Вольфганг Бангерт

+1 про не багато дзвінків у mpi @WolfgangBangerth. По суті, mpi повинен робити обчислення швидше, ви хочете звести до мінімуму дзвінки, оскільки вони коштують вам!
Чарльз

6

Ось дві мої потреби:

  • Інтерфейс повинен мати можливість усунути зайві або непотрібні аргументи, наприклад, MPI_IN_PLACE.
  • Інтерфейс повинен автоматично виявляти вбудовані типи даних ala Elemental's MpiMap.
  • Якщо / коли це можливо, для класів повинні бути побудовані визначені користувачем типи даних.

5

Мій список без особливого порядку. Інтерфейс повинен:

  • бути лише заголовком, без будь-яких залежностей, але <mpi.h>і стандартна бібліотека,
  • бути загальним і розширюваним,
  • бути неблокірующіх тільки (якщо ви хочете , щоб заблокувати, а потім блокувати явно, а не за замовчуванням),
  • дозволяти ланцюжок неблокуючих операцій на основі продовження,
  • підтримка розширюваної та ефективної серіалізації (наприклад, Boost.Fusion, що працює з RMA),
  • мати нульову штрафну абстракцію (тобто бути принаймні такою швидкою, як інтерфейс C),
  • будьте в безпеці (деструктор не готового майбутнього називається? -> std :: припинити!),
  • мати сильний DEBUGрежим з тоннами тверджень,
  • надзвичайно безпечний для типів (не більше ints / void * для всього, чортве, я хочу, щоб теги були типами!),
  • він повинен працювати з лямбдами (наприклад, всі зменшити + лямбда),
  • використовувати винятки послідовно як механізм звітування про помилки та механізм поводження з помилками (більше кодів помилок! більше аргументів виводу функції!)
  • MPI-IO повинен запропонувати неблокуючий інтерфейс вводу / виводу у стилі Boost.AFIO,
  • і просто дотримуйтесь належних сучасних практик дизайну інтерфейсів C ++ (визначте регулярні типи, функції, які не є членами інших країн, добре грайте з семантикою переміщення, операціями діапазону підтримки, ...)

Екстри:

  • дозвольте мені обрати виконавця середовища MPI, тобто який пул потоків він використовує. Зараз ви можете мати додатки із сумішшю OpenMP, MPI, CUDA та TBB ... все одночасно, коли кожен час роботи вважає, що йому належить середовище, і таким чином запитувати в операційній системі потоки кожного разу, коли вони відчують, що це. Серйозно?

  • використовуйте конвенцію іменування STL (і Boost). Чому? Кожен програміст на C ++ це знає.

Я хочу написати такий код:

auto buffer = some_t{no_ranks};
auto future = gather(comm, root(comm), my_offsets, buffer)
              .then([&](){
                /* when the gather is finished, this lambda will 
                   execute at the root node, and perform an expensive operation
                   there asynchronously (compute data required for load 
                   redistribution) whose result is broadcasted to the rest 
                   of the communicator */
                return broadcast(comm, root(comm), buffer);
              }).then([&]() {
                /* when broadcast is finished, this lambda executes 
                   on all processes in the communicator, performing an expensive
                   operation asynchronously (redistribute the load, 
                   maybe using non-blocking point-to-point communication) */
                 return do_something_with(buffer);
              }).then([&](auto result) {
                 /* finally perform a reduction on the result to check
                    everything went fine */
                 return all_reduce(comm, root(comm), result, 
                                  [](auto acc, auto v) { return acc && v; }); 
              }).then([&](auto result) {
                  /* check the result at every process */
                  if (result) { return; /* we are done */ }
                  else {
                    root_only([](){ write_some_error_log(); });
                    throw some_exception;
                  }
              });

/* Here nothing has happened yet! */

/* ... lots and lots of unrelated code that can execute concurrently 
   and overlaps with communication ... */

/* When we now call future.get() we will block 
   on the whole chain (which might have finished by then!).
*/

future.get();

Подумайте, як можна зв'язати всі ці операції за допомогою MPI_C request. Вам доведеться протестувати на декількох (або кожній окремій) проміжному кроці через безліч непов'язаних кодів, щоб побачити, чи зможете ви просунути ланцюг без блокування .


Це інтенсивний перелік вимог. Деякі з них неможливі для всіх практичних цілей (наприклад, підтримка лямбдів у скороченнях). Однак, в цілому, я думаю, що саме такий тип, яким має прагнути підтримка спільнота MPI.
Джефф

Що стосується потоків та середовища виконання, MPI використовує внутрішньо або жодні потоки або потоки ОС (POSIX, Windows або Solaris, залежно від ОС). Я не зовсім впевнений, що тут розумію вимогу.
Джефф

Проблема полягає в тому, що MPI може довільно запитувати потоки з операційної системи. У моїй програмі є пул потоків, і я хотів би, щоб MPI запитав ці теми з мого пулу потоків. Наразі це неможливо (і, як правило, не є проблемою), якщо у вас немає програми, що використовує OpenMP, TBB та MPI, кожен з яких має власні пули потоків, кожен з 4-х числом ядер.
gnzlbg

1
MPI може, але, як правило, не використовує внутрішні потоки ОС. У будь-якому випадку, з яким я знайомий (MPICH (2), MVAPICH2, OpenMPI, CrayMPI), це відбувається лише з можливістю виконання, передбаченою користувачем, тобто типовим є те, що це не так. Blue Gene / Q MPI є винятком, але в такій формі, що не має відношення до цієї дискусії.
Джефф

Дякую @Jeff! Не могли б ви детальніше розглянути, як MPI обробляє кілька неблокуючих дзвінків під час використання одного потоку? Він використовує корутини / зелені нитки / волокна?
gnzlbg

2

Особисто я не проти закликати до довгих функцій у стилі С саме з тієї причини, про яку згадував Вольфганг; насправді мало місць, щоб вам їх зателефонували, і навіть тоді вони майже завжди обволікаються кодом вищого рівня.

Єдині речі, які насправді турбують мене у форматі MPI у стилі C, - це власні типи даних і, меншою мірою, спеціальні операції (оскільки я їх використовую рідше). Щодо власних типів даних, я б сказав, що хороший інтерфейс C ++ повинен підтримувати загальний та ефективний спосіб вирішення цього питання, швидше за все, шляхом серіалізації. Це, звичайно, пройдений маршрут boost.mpi, який, якщо ви будете обережні , - це велика економія часу.

Щодо boost.mpiнаявності додаткових залежностей (особливо, boost.serializationщо саме по собі не є лише заголовком), я нещодавно натрапив на бібліотеку C ++ для серіалізації, що називається лише заголовком, називається зерновими, що здається перспективним; надано, потрібен компілятор, сумісний із C ++ 11. Можливо, варто вивчити і використовувати його як основу для чогось подібного boost.mpi.


Зауважте, що я не обов'язково шукав щось, що потрібно ввести у стандарт MPI. Я повністю погоджуюся з тим, що MPI майже завжди повинен "обернутись кодом вищого рівня", тому що мені цікаво, як виглядає цей код вищого рівня? У Elemental є приємний підхід, але чи найкращий він для всіх випадків? Якби хтось хотів мати інтерфейс C ++ до MPI, який намагався зробити дуже велику кількість людей щасливими, як це буде виглядати?
Джефф

@Jeff. Для мене: 1. Мені подобається, що я можу легко надсилати власні типи даних. 2. Мені подобається, що я можу легко виконувати скорочення за допомогою спеціальних операцій. Також я вважаю, що 1 я гойдаюся більш важливо / корисно, ніж 2
GradGuy

Я не бачу, як C ++ робить щось магічне wrt (2). Що ти тут уявляєш?
Джефф

@Jeff Я щось роздумував над тим, як thrustце зробити для скорочень: docs.thrust.googlecode.com/hg/group__reductions.html
GradGuy

-1

Проект github easyLambda забезпечує інтерфейс високого рівня для MPI з C ++ 14.

Я думаю, що проект має подібні цілі, і він дасть деяке уявлення про те, що може бути і робиться в цій галузі, використовуючи сучасний C ++. Керуючи іншими зусиллями, а також легкоLambda.

Початкові орієнтири щодо продуктивності та рядки коду показали перспективні результати.

введіть тут опис зображення

Далі йде короткий опис функцій та інтерфейсу, який він надає.

Інтерфейс заснований на програмуванні потоку даних та операціях з функціональним списком, які забезпечують властивий паралелізм. Паралелізм виражається як властивість задачі. Розподіл процесу та розподіл даних для завдання можна запитувати за допомогою властивості .prll (). Є велика кількість прикладів в веб - сторінки і код-сховища , які включають LAMMPS молекулярної динаміки постобработку, явне разностного рішення рівняння теплопровідності, логістичну регресію і т.д. В якості прикладу проблема дифузії тепла обговорюється в статті КВД вмирає ... можна виразити у ~ 20 рядках коду.

Я сподіваюсь, що це нормально, щоб надавати посилання, а не додавати тут більше деталей та прикладів кодів.

Відмова: Я є автором бібліотеки. Я вважаю, що не роблю ніякої шкоди, сподіваючись отримати конструктивний відгук про поточний інтерфейс easyLambda, який може бути вигідним для easyLambda та будь-якого іншого проекту, що переслідує подібні цілі.


Питання говорить: " Ми шукаємо довгі відповіді, які дають певні пояснення та контекст. Не просто дайте однорядну відповідь; поясніть, чому ваша відповідь правильна, в ідеалі цитатами. Відповіді, які не містять пояснень, можуть бути видалені. . ". Чому ви вважаєте, що ваша відповідь є достатньо повною, щоб відповідати цьому опису?
nicoguaro

Я вказую на проект, який забезпечує інтерфейс, аналогічний тому, що задається ОП. Я можу дати детальну інформацію про мотивацію та особливості проекту у самій відповіді та дозволити ОП та іншим прочитати та запропонувати, що вони думають про це. Однак я вирішив надати лише посилання. Я розумію вашу думку. Дозвольте додати трохи відповіді на текст відповіді.
Utkarsh Bhardwaj

@UtkarshBhardwaj: Деякі коментарі: (1) Дякую, що ви написали бібліотеку, яка взаємодіє на C ++ з MPI. Це важливе починання і, схоже, ви доклали багато роботи до цього. (2) Швидке ознайомлення з документами (знову ж таки, приємна робота), що виділяється - це довгі ланцюги використовуваних команд методів, що здається стилістично ... болючим налагодженням, навіть якщо ви їх добре відформатували. (3) Абстракції передбачають функціональну парадигму, яка виглядає корисною для завдань, схожих на зменшення карт, але, як хтось, хто програмує в MPI, я не хочу переробляти свої алгоритми і занадто віддалятися від інтерфейсів, які я знаю.
Джефф Оксберрі

(4) Я ніде в прикладі не бачу комунікаторів, що приводить мене до підозри, що ви використовуєте MPI_COMM_WORLD для всього, і обмежує потенціал вашої бібліотеки. (5) Абстракції, здається, будуються на абстракціях MPI і можуть мати різний підхід. (6) На основі (3) - (5) я не думаю, що ця бібліотека є інтерфейсом MPI, і я вважаю, що цей коментар є поза темою.
Джефф Оксберрі

@Geoff дякую за цінний відгук, дуже вдячний. Відповідь на конкретні моменти: 2) Ланцюжок іноді називають ExpressionBuilder . Це поширений спосіб вираження композиції у функціональному стилі. Не варто писати в цьому стилі в ezl. Можна спочатку записати окремі одиниці, а потім скласти їх, перевірити [приклад] ( goo.gl/YzaL0k ). 3) Я знаю, що важко перейти від контрольно-поточного та імперативного до потоку даних та функціоналу. У кожного є свої плюси і мінуси. Однак я вважаю, що останнє потрібно вивчити більше, щоб знати його справжню ефективність.
Utkarsh Bhardwaj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.