Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаб. 12 ТПП

.docx
Скачиваний:
1
Добавлен:
29.12.2024
Размер:
77.41 Кб
Скачать

Лабораторная работа №12

Виртуальные топологии

Цель: изучить основные принципы использования виртуальных топологий в технологии MPI на примере использования в рамках языка С++.

Задание:

#include <mpi.h>

#include <stdio.h>

#include <stdlib.h>

#include <cwchar>

#include <iostream>

#define GROUP1_SIZE 5 // Размер первой группы для кольцевого обмена

// chcp 65001

// mpiexec -n 9 .\TPP_LAB_7.exe

int main(int argc, char* argv[]) {

setlocale(LC_ALL, "ru_RU.UTF-8");

MPI_Init(&argc, &argv);

int rank, size, separator;

MPI_Comm group_comm;

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Comm_size(MPI_COMM_WORLD, &size);

if (size < GROUP1_SIZE + 2) {

if (rank == 0) {

wprintf(L"Требуется минимум %d процессов.\n", GROUP1_SIZE + 2);

}

MPI_Finalize();

return 0;

}

// Разделение процессов на две группы

if (rank < GROUP1_SIZE) {

separator = 0;

}

else {

separator = 1;

}

MPI_Comm_split(MPI_COMM_WORLD, separator, rank, &group_comm);

if (separator == 0) {

// Группа 1: Декартовая топология (кольцевой обмен)

MPI_Comm cart_comm;

int dims[1] = { GROUP1_SIZE };

int periods[1] = { 1 }; // Замкнутое кольцо

int reorder = 0;

MPI_Cart_create(group_comm, 1, dims, periods, reorder, &cart_comm);

int cart_rank, left, right;

MPI_Comm_rank(cart_comm, &cart_rank);

MPI_Cart_shift(cart_comm, 0, 1, &left, &right);

int send_data = cart_rank + 100;

int recv_data;

MPI_Sendrecv(&send_data, 1, MPI_INT, right, 0,

&recv_data, 1, MPI_INT, left, 0,

cart_comm, MPI_STATUS_IGNORE);

wprintf(L"Процесс ранга %d (Группа 1, ранг в группе: %d): послал %d процессу %d, получил %d от процесса %d\n",

rank, cart_rank, send_data, right, recv_data, left);

fflush(stdin);

MPI_Comm_free(&cart_comm);

}

else {

// Группа 2: Топология графа (звезда: master-slave)

int group2_rank, group2_size;

MPI_Comm_rank(group_comm, &group2_rank);

MPI_Comm_size(group_comm, &group2_size);

int* index = new int[group2_size];

int* edges = new int[2 * (group2_size - 1)];

// Настройка топологии звезды

for (int i = 0; i < group2_size - 1; i++) {

edges[i] = i + 1;

}

for (int i = group2_size - 1; i < 2 * (group2_size - 1); i++) {

edges[i] = 0;

}

for (int i = 0; i < group2_size; i++) {

if (i == 0) {

index[i] = group2_size - 1;

}

else {

index[i] = index[i - 1] + 1;

}

}

MPI_Comm graph_comm;

MPI_Graph_create(group_comm, group2_size, index, edges, 0, &graph_comm);

if (group2_rank == 0) {

for (int i = 1; i < group2_size; i++) {

int data_to_send = i + 100;

MPI_Send(&data_to_send, 1, MPI_INT, i, 0, graph_comm);

wprintf(L"Основной процесс (Группа 2): отправил %d процессу-исполнителю %d\n", data_to_send, i);

fflush(stdin);

}

for (int i = 1; i < group2_size; i++) {

int data_received;

MPI_Recv(&data_received, 1, MPI_INT, i, 0, graph_comm, MPI_STATUS_IGNORE);

wprintf(L"Основной процесс (Группа 2): получил %d от процесса-исполнителя %d\n", data_received, i);

fflush(stdin);

}

}

else {

int data_received;

MPI_Recv(&data_received, 1, MPI_INT, 0, 0, graph_comm, MPI_STATUS_IGNORE);

wprintf(L"Процесс-исполнитель (Группа 2, ранг в группе %d): получил %d от основного процесса\n", group2_rank, data_received);

fflush(stdin);

int data_to_send = data_received * 2;

MPI_Send(&data_to_send, 1, MPI_INT, 0, 0, graph_comm);

}

delete[] index;

delete[] edges;

MPI_Comm_free(&graph_comm);

}

MPI_Comm_free(&group_comm);

MPI_Finalize();

return 0;

}

Соседние файлы в предмете Технологии параллельного программирования