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

Лаб. 10 ТПП

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

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

Производные типы данных в MPI

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

Задание:

#include <stdio.h>

#include <wchar.h>

#include <stdlib.h>

#include <iostream>

#include <vector>

#include <mpi.h>

using namespace std;

#define DIGITS 1 // Количество цифр в числе (>=1)

#define A 2 // Количество чисел (>=2)

// mpiexec -n 5 .\TPP_LAB_7.exe

vector<wchar_t> multiply_long_ints(vector<vector<wchar_t>>& numbers) {

const wchar_t* num1 = numbers[0].data();

const wchar_t* num2 = numbers[1].data();

int len1 = wcslen(num1);

int len2 = wcslen(num2);

//wprintf(L"len1: %d\n", len1);

//wprintf(L"len2: %d\n\n", len2);

int temp_res_len = len1 + len2;

int array_rows = len2;

int array_cols = len1 + len2 + 1;

//wprintf(L"array_cols: %d\n\n", array_cols);

int result_size = len1 + len2 + 1;

vector<wchar_t> temp_result(result_size, L'0');

temp_result[result_size - 1] = L'\0';

// Массив для хранения результатов умножения столбиком,

// для дальнейшего суммирования каждого столбца и получения

// итогового результата

vector<vector<wchar_t>> array(array_rows, vector<wchar_t>(array_cols, L'0'));

for (auto& row : array) {

row[array_cols - 1] = L'\0';

}

int a = 0;

int count = 1;

int temp;

int col;

for (int i = len2 - 1; i >= 0; i--) {

temp = 0;

//col = static_cast<int>(wcslen(result)) - count;

col = temp_res_len - count;

for (int j = len1 - 1; j >= 0; j--) {

a = (num1[j] - L'0') * (num2[i] - L'0') + temp;

temp = a / 10;

if (j != 0) {

a = a % 10;

array[i][col] = L'0' + a;

col--;

}

else {

a = a % 10;

array[i][col] = L'0' + a;

array[i][col - 1] = L'0' + temp;

}

}

count++;

}

int sum;

temp = 0;

//col = static_cast<int>(wcslen(result));

col = temp_res_len;

for (int i = col - 1; i >= 0; i--) {

sum = 0;

for (int j = array_rows - 1; j >= 0; j--) {

sum += (array[j][i] - L'0');

}

sum += temp;

temp = sum / 10;

sum = sum % 10;

//result[i] = L'0' + sum;

temp_result[i] = L'0' + sum;

}

//wprintf(L"wcslen_result: %d\n", wcslen(result));

//wprintf(L"wcslen_temp_result: %d\n\n", wcslen(temp_result.data()));

//wprintf(L"result_result: %s\n", result);

//wprintf(L"temp_result: %s\n\n", temp_result.data());

numbers.erase(numbers.begin());

numbers.erase(numbers.begin());

if (!numbers.empty()) {

numbers.push_back(temp_result);

return multiply_long_ints(numbers);

}

/*for (int i = 0; i < 6; i++) {

wprintf(L"NNN: %s\n", numbers[i].data());

}*/

return temp_result;

}

// Функция для генерации длинного целого числа

void generate_long_ints(vector<vector<wchar_t>>& numbers, int max_digits) {

for (auto& num : numbers) {

for (int j = 0; j < max_digits - 1; j++) {

num[j] = L'0' + rand() % 10;

}

num[max_digits - 1] = L'\0';

wprintf(L"Generated num: %ls\n", num.data());

fflush(stdin);

}

}

void create_long_int_type(MPI_Datatype* long_int_type, int size) {

//int result_size = max_digits * 2 + 1;

MPI_Type_contiguous(size, MPI_WCHAR, long_int_type);

MPI_Type_commit(long_int_type);

}

//void create_long_int_result_type(MPI_Datatype* long_int_result_type, int size) {

// //int result_size = max_digits * 2 + 1;

// MPI_Type_contiguous(size, MPI_WCHAR, long_int_result_type);

// MPI_Type_commit(long_int_result_type);

//}

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

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

MPI_Init(&argc, &argv);

int rank, size;

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Comm_size(MPI_COMM_WORLD, &size);

int max_digits = DIGITS; // Максимальное количество цифр

int max_numbers = A; // Количество чисел в массиве

int num_size = max_digits + 1; // Размер числа с учётом завершающего символа

int result_size = max_digits * max_numbers + 1; // Размер результата с учётом завершающего символа

/*if (rank == 0) {

wprintf(L"result_size: %d\n", result_size);

fflush(stdin);

}

if (rank == 0) {

wprintf(L"num_size_1: %d\n", num_size);

fflush(stdin);

}*/

MPI_Datatype long_int_type;

create_long_int_type(&long_int_type, num_size);

// Массив перемножающихся чисел

vector<vector<wchar_t>> array_of_multiplying_numbers(max_numbers,

vector<wchar_t>(result_size, L'0'));

// Массив временного хранения двух перемножающихся чисел

/*vector<vector<wchar_t>> array_for_storing_two_numbers(2,

vector<wchar_t>(result_size, L'0'));*/

// Временный результат перемножения двух чисел

//vector<wchar_t> temporary_result(result_size, L'0');

//temporary_result[result_size - 1] = L'\0';

//Итоговый результат

/*vector<wchar_t> final_result(result_size + 1, L'0');

final_result[result_size - 1 + 1] = L'\0';*/

srand(static_cast<unsigned>(time(nullptr)) + rank);

if (rank == 0) {

generate_long_ints(array_of_multiplying_numbers, num_size);

}

// Количество используемых процессов

int count_of_processes_used = size - 1;

// Количество используемых процессов в прошлом цикле

//int las_count_of_processes_used = size - 1;

// Текущее количество используемых чисел

//int current_size_array_of_multiplying_numbers =

// static_cast<int>(array_of_multiplying_numbers.size());

// Количество используемых чисел

//int size_array_of_multiplying_numbers =

// static_cast<int>(array_of_multiplying_numbers.size());

if (count_of_processes_used > (A / 2)) {

count_of_processes_used = A / 2;

}

/*if (rank == 0) {

wprintf(L"count_of_processes_used: %d\n", count_of_processes_used);

fflush(stdin);

}*/

/*int length =

static_cast<int>(array_of_multiplying_numbers.size());*/

int count_of_transmitted_numbers = A / count_of_processes_used;

/*if (rank == 0) {

wprintf(L"count_of_transmitted_numbers: %d\n", count_of_transmitted_numbers);

fflush(stdin);

}*/

int remains = A % count_of_processes_used;

/*if (rank == 0) {

wprintf(L"remains: %d\n", remains);

fflush(stdin);

}*/

MPI_Datatype long_int_result_type;

num_size = max_digits * count_of_transmitted_numbers + 1;

/*if (rank == 0) {

wprintf(L"num_size_2: %d\n", num_size);

fflush(stdin);

}*/

create_long_int_type(&long_int_result_type, num_size);

if (rank == 0) {

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

for (int j = 0; j < count_of_transmitted_numbers; j++) {

MPI_Send(array_of_multiplying_numbers[0].data(), 1, long_int_type,

i, 0, MPI_COMM_WORLD);

array_of_multiplying_numbers.erase(array_of_multiplying_numbers.begin());

}

}

if (count_of_transmitted_numbers < A) {

vector<vector<wchar_t>> results(count_of_processes_used,

vector<wchar_t>(result_size, L'0'));

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

MPI_Recv(results[i].data(), 1, long_int_result_type,

i + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

}

if (!array_of_multiplying_numbers.empty()) {

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

results.push_back(array_of_multiplying_numbers[i]);

}

//wprintf(L"Q: %s\n", array_of_multiplying_numbers[0].data());

//fflush(stdin);

}

vector<wchar_t> final_result = multiply_long_ints(results);

wprintf(L"\n\nfinal_result: %ls\n", final_result.data());

fflush(stdin);

}

else {

vector<wchar_t> final_result(result_size + 1, L'0');

final_result[result_size - 1 + 1] = L'\0';

MPI_Recv(final_result.data(), 1, long_int_result_type,

1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

wprintf(L"\n\nfinal_result: %ls\n", final_result.data());

fflush(stdin);

}

}

else if (rank > 0 and rank <= count_of_processes_used) {

vector<vector<wchar_t>> array_for_one_process(count_of_transmitted_numbers,

vector<wchar_t>(result_size, L'0'));

for (int j = 0; j < count_of_transmitted_numbers; j++) {

MPI_Recv(array_for_one_process[j].data(), 1, long_int_type,

0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);

}

vector<wchar_t> temp_result = multiply_long_ints(array_for_one_process);

/* wprintf(L"temp_result: %ls\n", temp_result.data());

fflush(stdin);*/

int length =

static_cast<int>(temp_result.size());

/*if (rank == 1) {

wprintf(L"length: %d\n", length);

fflush(stdin);

}*/

MPI_Send(temp_result.data(), 1, long_int_result_type, 0, 0, MPI_COMM_WORLD);

//MPI_Send(temporary_result.data(), 1, long_int_type, 0, 5, MPI_COMM_WORLD);

}

/*else {

}*/

/*if (rank == 0) {

wprintf(L"Result 1: %ls\n", final_result.data());

fflush(stdin);

}*/

MPI_Type_free(&long_int_type);

MPI_Type_free(&long_int_result_type);

MPI_Finalize();

return 0;

}

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