SlideShare a Scribd company logo
Лекция 4. Производные типы
данных в MPI
Пазников Алексей Александрович
Параллельные вычислительные технологии
СибГУТИ (Новосибирск)
Осенний семестр 2015
www: cpct.sibsutis.ru/~apaznikov/teaching
q/a: piazza.com/sibsutis.ru/fall2015/pct2015fall
Производные типы
данных
3
Производные типы данных (derived datatypes)
Сообщения содержат некоторое число элементов некоторого типа данных.
В MPI типы бывают
▪ Базовые (basic)
▪ Производные (derived), которые могут быт получены из базовых
и производных типов.
Примеры сообщений в MPI
Соответствия между базовыми типами MPI и типами С:
4
Производные типы данных (derived datatypes)
struct buff_s {
int ival[3];
double dval[5];
} buffer;
Компилятор
int double
MPI_Send(&buffer, 1, buff_datatype, ...)
&buffer = начальный
адрес данных
Указатель,
описывающий
смещение
array_of_types[0]=MPI_INT;
array_of_blocklengths[0]=3;
array_of_displacements[0]=0;
array_of_types[1]=MPI_DOUBLE;
array_of_blocklengths[1]=5;
array_of_displacements[1]=...;
MPI_Type_struct(2, array_of_blocklengths,
array_of_displacements, array_of_types,
&buff_datatype );
MPI_Type_commit(&buff_datatype);
5
Производные типы данных (derived datatypes)
базовый тип 0
Производные типы данных представляют собой список указателей на базовые
типы данных.
базовый тип 1
...
базовый тип n – 1
смещение для типа 0
смещение для типа 1
...
смещение для типа n – 1
c 11 22 2.343546e35Пример:
0 4 8 12 16 20 24
MPI_CHAR
MPI_INT
MPI_INT
MPI_DOUBLE
0
4
8
16
Производные типы
данных описывают
расположение объектов в
памяти, например, для
структур, блоков,
массивов и т.д.
6
Непрерывные данные
▪ Самый простой вид производных типов.
▪ Состоит из числа непрерывных элементов одного типа
старый тип
новый тип
int MPI_Type_contiguous(int count, MPI_Datatype oldtype,
MPI_Datatype *newtype);
7
Векторный тип данных
blocklength = 3
элемента в блоке
int MPI_Type_vector(int count, int blocklength, int stride,
MPI_Datatype oldtype, MPI_Datatype *newtype);
старый тип
новый тип
stride = 5
(элементов между блоками)
Пустые области памяти также
необходимо передавать
count = 2
(число блоков)
8
Структурный тип данных
блок 1
int MPI_Type_vector(int count, int *array_of_blocklengths,
MPI_Aint *array_of_displacements,
MPI_Datatype *array_of_types,
MPI_Datatype *newtype);
старый тип
новый тип
Пустая область памяти, если double
хранится с 8-байтным смещением
MPI_INT MPI_DOUBLE
блок 2
count = 2
array_of_blocklengths = (3, 5 )
array_of_displacements = (0, addr1 - addr0 )
array_of_types = (MPI_INT, MPI_DOUBLE )
9
Структурный тип данн
блок 1
struct buff {
int ival[3];
double dval[5];
}
buf_datatype
Пустая область памяти, если double
хранится с 8-байтным смещением
блок 2
▪ Каждый массив хранится независимо.
▪ Каждый буфер – это пара массива из 3 переменных int и массива из 5 переменных
double
▪ Длина пустой области памяти между массивами может быть любая.
10
Как расчитать смещение
int MPI_Get_address(void* location, MPI_Aint* address);
▪ array_of_disp[i] = address(block_i) – address(block_0)
Как получить адрес в формате MPI:
11
Фиксация типа данных
int MPI_Type_commit(MPI_Datatype * datatype);
▪ Перед тем, как использовать новый тип данных, его необходимо активировать с
помощью функции MPI_Type_commit
▪ Это необходимо сделать только один раз
12
Размер и протяжённость типа данных
▪ Размер – количество байт, которые необходимо передать.
▪ Протяжённость – промежуток от первого до последнего типа
▪ Для базовыйх типов размер равен протяжённости и равен числу байт,
используемых компилятором.
▪ Для производных типов данных это не так:
старый тип
новый тип
▪ size = 6 * sizeof(oldtype)
▪ extent = 8 * sizeof(oldtype)
int MPI_Type_size(MPI_Datatype datatype, int * size )
int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent )
int MPI_Type_get_extent(MPI_Datatype datatype,
MPI_Aint * lb , MPI_Aint * extent )
13
Пример
rank
0
sendbuf
2
recvbuf
2
sum
2
rank
1
sendbuf
0
recvbuf
0
sum
0
rank
2
sendbuf
recvbuf
1
sum
1
Процесс 0
Процесс 1
Процесс 2
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
1 1.0
2 2.0
0 0.0
0 0.00 0.0
1 1.0
2 2.0 2 2.0
1 1.01 1.0
2 2.0
0 0.0
Управление
коммуникаторами
15
Создание новых коммуникаторов
MPI_Comm_split(MPI_Comm comm, int color, int key,
MPI_Comm* newcomm)
▪ Функция создаёт новый коммуникатор путём разделения старого коммуникатора на
под-коммуникаторы на основе color и key.
▪ Старый коммуникатор остаётся.
▪ Каждый процесс передаёт своё значение color, который определяет, к какому
коммуникаторы он принадлежит.
▪ Если значение color равно MPI_UNDEFINED, то процесс не включается ни в один
новый коммуникатор.
▪ key определяет ранг процесса в новом коммуникаторе
16
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
MPI_COMM_WORLD
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Создание новых коммуникаторов
COMM1, COMM2, COMM3, COMM4
17
Создание новых коммуникаторов
int world_rank, world_size;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Определить цвет (номер строки)
int color = world_rank / 4;
// Разбить коммуникатор
MPI_Comm row_comm;
MPI_Comm_split(MPI_COMM_WORLD, color, world_rank, &row_comm);
int row_rank, row_size;
MPI_Comm_rank(row_comm, &row_rank);
MPI_Comm_size(row_comm, &row_size);
printf("WORLD RANK/SIZE: %d/%d t ROW RANK/SIZE: %d/%dn",
world_rank, world_size, row_rank, row_size);
MPI_Comm_free(&row_comm);
18
Группы процессов
▪ Коммуникатор – это композиция контекста и группы процессов.
▪ Группа процессов – это множество процессов.
▪ Группы, подобно множествам, поддерживают операции объединения и
пересечения.
0 2 2 4
1 3 3 5
0 2 2 4
1 3 3 5
Объединение
Пересечени
е
2
3
0 2 4
1 3 5
19
Группы процессов
MPI_Comm_group(MPI_Comm comm, MPI_Group* group)
MPI_Group_union(MPI_Group group1, MPI_Group group2,
MPI_Group* newgroup)
MPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int tag,
MPI_Comm* newcomm)
MPI_Group_intersection(MPI_Group group1, MPI_Group group2,
MPI_Group* newgroup)
Создание группы
Объединение групп:
Пересечение групп:
Создание нового коммуникаторы из группы:
20
Создание новых коммуникаторов
int world_rank, world_size;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Group world_group;
MPI_Comm_group(MPI_COMM_WORLD, &world_group);
int n = 7;
const int ranks[7] = {1, 2, 3, 5, 7, 11, 13};
// Создать группу из из world_group и включить в неё 7 процессов
MPI_Group prime_group;
MPI_Group_incl(world_group, 7, ranks, &prime_group);
// Создать новый коммуникатор
MPI_Comm prime_comm;
MPI_Comm_create_group(MPI_COMM_WORLD, prime_group, 0, &prime_comm);
int prime_rank = -1, prime_size = -1;
if (MPI_COMM_NULL != prime_comm) {
MPI_Comm_rank(prime_comm, &prime_rank);
MPI_Comm_size(prime_comm, &prime_size);
}
printf("WORLD RANK/SIZE: %d/%d t PRIME RANK/SIZE: %d/%dn",
world_rank, world_size, prime_rank, prime_size);
MPI_Group_free(&world_group);
MPI_Group_free(&prime_group);
MPI_Comm_free(&prime_comm);

More Related Content

PDF
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
PDF
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
PDF
Лекция 1. Основные понятия стандарта MPI. Дифференцированные обмены
PDF
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
PDF
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
PDF
Семинар 9. Параллельное программирование на MPI (часть 2)
PDF
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
PDF
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
Лекция 1. Основные понятия стандарта MPI. Дифференцированные обмены
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
Семинар 9. Параллельное программирование на MPI (часть 2)
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...

What's hot (20)

PDF
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
PDF
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
PPTX
Введение в MPI
PPTX
Функции передачи сообщений MPI
PDF
Стандарт MPI (Message Passing Interface)
PDF
Лекция 6. Стандарт OpenMP
PDF
Семинар 4. Многопоточное программирование на OpenMP (часть 4)
PDF
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
PDF
Семинар 2. Многопоточное программирование на OpenMP (часть 2)
PDF
Лекция 6. Стандарт OpenMP
PDF
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
PDF
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
PDF
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
PDF
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
PDF
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
PDF
Семинар 8. Параллельное программирование на MPI (часть 1)
PDF
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
PDF
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
PDF
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
PDF
20140420 parallel programming_kalishenko_lecture10
Семинар 6. Многопоточное программирование на OpenMP (часть 6)
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Введение в MPI
Функции передачи сообщений MPI
Стандарт MPI (Message Passing Interface)
Лекция 6. Стандарт OpenMP
Семинар 4. Многопоточное программирование на OpenMP (часть 4)
Семинар 1. Многопоточное программирование на OpenMP (часть 1)
Семинар 2. Многопоточное программирование на OpenMP (часть 2)
Лекция 6. Стандарт OpenMP
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Семинар 8. Параллельное программирование на MPI (часть 1)
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Семинар 7. Многопоточное программирование на OpenMP (часть 7)
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
20140420 parallel programming_kalishenko_lecture10
Ad

Similar to Лекция 4. Производные типы данных в стандарте MPI (20)

PPT
20090721 hpc exercise2
PDF
Семинар 11. Параллельное программирование на MPI (часть 4)
PPS
Prezent
PPT
Prezent
PDF
Семинар 10. Параллельное программирование на MPI (часть 3)
PDF
О.В.Сухорослов "Параллельное программирование. Часть 2"
PDF
Step cpp0201
PPT
2009 10-31 есть ли жизнь после mpi
PPTX
Cpp/cli types
PDF
C++ Базовый. Занятие 09.
PDF
Основы С++ (операторы, типы данных, функции)
PPT
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
PPT
PPT
PDF
Основы программирования на C++
PDF
C++ Базовый. Занятие 02.
PDF
книга с++
PDF
C++ for real_programmers
PDF
C++ STL & Qt. Занятие 06.
PDF
C++ STL & Qt. Занятие 05.
20090721 hpc exercise2
Семинар 11. Параллельное программирование на MPI (часть 4)
Prezent
Prezent
Семинар 10. Параллельное программирование на MPI (часть 3)
О.В.Сухорослов "Параллельное программирование. Часть 2"
Step cpp0201
2009 10-31 есть ли жизнь после mpi
Cpp/cli types
C++ Базовый. Занятие 09.
Основы С++ (операторы, типы данных, функции)
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Основы программирования на C++
C++ Базовый. Занятие 02.
книга с++
C++ for real_programmers
C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 05.
Ad

More from Alexey Paznikov (19)

PDF
Лекция 5. Метод конечных разностей (параллельные алгоритмы в стандарте MPI)
PDF
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
PDF
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
PDF
ПВТ - весна 2015 - Лекция 0. Описание курса
PDF
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
PDF
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
PDF
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
PDF
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
PDF
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
PDF
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
PDF
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
PDF
ПВТ - осень 2014 - лекция 1а - Описание курса
PDF
Анализ эффективности выполнения алгоритма параллельной редукции в языке Cray ...
PPTX
ТФРВС - весна 2014 - лекция 11
PPTX
ТФРВС - весна 2014 - лекция 10
PPTX
ТФРВС - весна 2014 - лекция 9
PPTX
ТФРВС - весна 2014 - лекция 8
PPTX
ТФРВС - весна 2014 - лекция 7
PPTX
ТФРВС - весна 2014 - лекция 6
Лекция 5. Метод конечных разностей (параллельные алгоритмы в стандарте MPI)
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 0. Описание курса
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 2 - Архитектура вычислительных систем с общей памятью
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1а - Описание курса
Анализ эффективности выполнения алгоритма параллельной редукции в языке Cray ...
ТФРВС - весна 2014 - лекция 11
ТФРВС - весна 2014 - лекция 10
ТФРВС - весна 2014 - лекция 9
ТФРВС - весна 2014 - лекция 8
ТФРВС - весна 2014 - лекция 7
ТФРВС - весна 2014 - лекция 6

Лекция 4. Производные типы данных в стандарте MPI

  • 1. Лекция 4. Производные типы данных в MPI Пазников Алексей Александрович Параллельные вычислительные технологии СибГУТИ (Новосибирск) Осенний семестр 2015 www: cpct.sibsutis.ru/~apaznikov/teaching q/a: piazza.com/sibsutis.ru/fall2015/pct2015fall
  • 3. 3 Производные типы данных (derived datatypes) Сообщения содержат некоторое число элементов некоторого типа данных. В MPI типы бывают ▪ Базовые (basic) ▪ Производные (derived), которые могут быт получены из базовых и производных типов. Примеры сообщений в MPI Соответствия между базовыми типами MPI и типами С:
  • 4. 4 Производные типы данных (derived datatypes) struct buff_s { int ival[3]; double dval[5]; } buffer; Компилятор int double MPI_Send(&buffer, 1, buff_datatype, ...) &buffer = начальный адрес данных Указатель, описывающий смещение array_of_types[0]=MPI_INT; array_of_blocklengths[0]=3; array_of_displacements[0]=0; array_of_types[1]=MPI_DOUBLE; array_of_blocklengths[1]=5; array_of_displacements[1]=...; MPI_Type_struct(2, array_of_blocklengths, array_of_displacements, array_of_types, &buff_datatype ); MPI_Type_commit(&buff_datatype);
  • 5. 5 Производные типы данных (derived datatypes) базовый тип 0 Производные типы данных представляют собой список указателей на базовые типы данных. базовый тип 1 ... базовый тип n – 1 смещение для типа 0 смещение для типа 1 ... смещение для типа n – 1 c 11 22 2.343546e35Пример: 0 4 8 12 16 20 24 MPI_CHAR MPI_INT MPI_INT MPI_DOUBLE 0 4 8 16 Производные типы данных описывают расположение объектов в памяти, например, для структур, блоков, массивов и т.д.
  • 6. 6 Непрерывные данные ▪ Самый простой вид производных типов. ▪ Состоит из числа непрерывных элементов одного типа старый тип новый тип int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype);
  • 7. 7 Векторный тип данных blocklength = 3 элемента в блоке int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype); старый тип новый тип stride = 5 (элементов между блоками) Пустые области памяти также необходимо передавать count = 2 (число блоков)
  • 8. 8 Структурный тип данных блок 1 int MPI_Type_vector(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements, MPI_Datatype *array_of_types, MPI_Datatype *newtype); старый тип новый тип Пустая область памяти, если double хранится с 8-байтным смещением MPI_INT MPI_DOUBLE блок 2 count = 2 array_of_blocklengths = (3, 5 ) array_of_displacements = (0, addr1 - addr0 ) array_of_types = (MPI_INT, MPI_DOUBLE )
  • 9. 9 Структурный тип данн блок 1 struct buff { int ival[3]; double dval[5]; } buf_datatype Пустая область памяти, если double хранится с 8-байтным смещением блок 2 ▪ Каждый массив хранится независимо. ▪ Каждый буфер – это пара массива из 3 переменных int и массива из 5 переменных double ▪ Длина пустой области памяти между массивами может быть любая.
  • 10. 10 Как расчитать смещение int MPI_Get_address(void* location, MPI_Aint* address); ▪ array_of_disp[i] = address(block_i) – address(block_0) Как получить адрес в формате MPI:
  • 11. 11 Фиксация типа данных int MPI_Type_commit(MPI_Datatype * datatype); ▪ Перед тем, как использовать новый тип данных, его необходимо активировать с помощью функции MPI_Type_commit ▪ Это необходимо сделать только один раз
  • 12. 12 Размер и протяжённость типа данных ▪ Размер – количество байт, которые необходимо передать. ▪ Протяжённость – промежуток от первого до последнего типа ▪ Для базовыйх типов размер равен протяжённости и равен числу байт, используемых компилятором. ▪ Для производных типов данных это не так: старый тип новый тип ▪ size = 6 * sizeof(oldtype) ▪ extent = 8 * sizeof(oldtype) int MPI_Type_size(MPI_Datatype datatype, int * size ) int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent ) int MPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb , MPI_Aint * extent )
  • 15. 15 Создание новых коммуникаторов MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* newcomm) ▪ Функция создаёт новый коммуникатор путём разделения старого коммуникатора на под-коммуникаторы на основе color и key. ▪ Старый коммуникатор остаётся. ▪ Каждый процесс передаёт своё значение color, который определяет, к какому коммуникаторы он принадлежит. ▪ Если значение color равно MPI_UNDEFINED, то процесс не включается ни в один новый коммуникатор. ▪ key определяет ранг процесса в новом коммуникаторе
  • 16. 16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 MPI_COMM_WORLD 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Создание новых коммуникаторов COMM1, COMM2, COMM3, COMM4
  • 17. 17 Создание новых коммуникаторов int world_rank, world_size; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); // Определить цвет (номер строки) int color = world_rank / 4; // Разбить коммуникатор MPI_Comm row_comm; MPI_Comm_split(MPI_COMM_WORLD, color, world_rank, &row_comm); int row_rank, row_size; MPI_Comm_rank(row_comm, &row_rank); MPI_Comm_size(row_comm, &row_size); printf("WORLD RANK/SIZE: %d/%d t ROW RANK/SIZE: %d/%dn", world_rank, world_size, row_rank, row_size); MPI_Comm_free(&row_comm);
  • 18. 18 Группы процессов ▪ Коммуникатор – это композиция контекста и группы процессов. ▪ Группа процессов – это множество процессов. ▪ Группы, подобно множествам, поддерживают операции объединения и пересечения. 0 2 2 4 1 3 3 5 0 2 2 4 1 3 3 5 Объединение Пересечени е 2 3 0 2 4 1 3 5
  • 19. 19 Группы процессов MPI_Comm_group(MPI_Comm comm, MPI_Group* group) MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) MPI_Comm_create_group(MPI_Comm comm, MPI_Group group, int tag, MPI_Comm* newcomm) MPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group* newgroup) Создание группы Объединение групп: Пересечение групп: Создание нового коммуникаторы из группы:
  • 20. 20 Создание новых коммуникаторов int world_rank, world_size; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); MPI_Group world_group; MPI_Comm_group(MPI_COMM_WORLD, &world_group); int n = 7; const int ranks[7] = {1, 2, 3, 5, 7, 11, 13}; // Создать группу из из world_group и включить в неё 7 процессов MPI_Group prime_group; MPI_Group_incl(world_group, 7, ranks, &prime_group); // Создать новый коммуникатор MPI_Comm prime_comm; MPI_Comm_create_group(MPI_COMM_WORLD, prime_group, 0, &prime_comm); int prime_rank = -1, prime_size = -1; if (MPI_COMM_NULL != prime_comm) { MPI_Comm_rank(prime_comm, &prime_rank); MPI_Comm_size(prime_comm, &prime_size); } printf("WORLD RANK/SIZE: %d/%d t PRIME RANK/SIZE: %d/%dn", world_rank, world_size, prime_rank, prime_size); MPI_Group_free(&world_group); MPI_Group_free(&prime_group); MPI_Comm_free(&prime_comm);