Сумма гармонической прогрессии c ++ MPI

Я пытаюсь сделать параллельную версиюСумма гармонической прогрессии«проблема с использованием MPI.
Но я новичок в MPI и не знаю, как запустить этот метод с MPI, потому что он не работает.

Параллельная программа:

//#include "stdafx.h"#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <mpi.h>

#define d 10    //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000  //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)

using namespace std;

int numProcess, rank, msg, source, dest, tag, qtd_elemento;

int escravo(long unsigned int *digits, int ValueEnd)
{
MPI_Status status;

MPI_Recv(digits, (d + 11), MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

for (int i = 1; i <= ValueEnd; ++i) {
long unsigned int remainder = 1;
for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}

MPI_Send(&digits, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
}

void HPSSeguencial(char* output) {
long unsigned int digits[d + 11];
int DivN = n / 4; //Limiting slave.

for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;

if (rank != 0){
escravo(digits, (DivN * 1 ) );
escravo(digits, (DivN * 2 ) );
escravo(digits, (DivN * 3 ) );
escravo(digits, (DivN * 4 ) );
}

for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}

int main() {
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcess);

char output[d + 10];
HPSSeguencial(output);
cout << output << endl;

MPI_Finalize();

system("PAUSE");
return 0;
}

Оригинальный код

#include "stdafx.h"#include <iostream>
#include <sstream>
#include <time.h>

#define d 10    //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000  //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)

using namespace std;

void HPS(char* output) {
long unsigned int digits[d + 11];

for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;

for (int i = 1; i <= n; ++i) {
long unsigned int remainder = 1;
for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}for (int i = d + 11 - 1; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
if (digits[d + 1] >= 5) {
++digits[d];
}for (int i = d; i > 0; --i) {
digits[i - 1] += digits[i] / 10;
digits[i] %= 10;
}
stringstream stringstreamA;
stringstreamA << digits[0] << ",";for (int i = 1; i <= d; ++i) {
stringstreamA << digits[i];
}
string stringA = stringstreamA.str();
stringA.copy(output, stringA.size());
}int main() {

char output[d + 10];
HPS(output);
cout << output<< endl;

system("PAUSE");
return 0;
}

Примеры:

Входные данные:

#define d 10
#define n 1000

Выход:

7,4854708606╠╠╠╠╠╠╠╠╠╠╠╠

Входные данные:

#define d 12
#define n 7

Выход:

2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÀÂ♂ü─¨@

С уважением

Оригинальный код

http://regulus.pcs.usp.br/marathon/current/warmup.pdf

3

Решение

Я предполагаю, что вы хотите распараллелить эту часть:

for (int i = 1; i <= ValueEnd; ++i)
{
long unsigned int remainder = 1;
for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit)
{
long unsigned int div = remainder / i;
long unsigned int mod = remainder % i;
digits[digit] += div;
remainder = mod * 10;
}
}

Вы можете разделить каждый для итерации на каждый процесс MPI:

int idP = getProcessId(), numP = numberProcess();
for (int i = idP; i <= ValueEnd; i+=numP)
{
...
}

getProcessId() дает вам идентификатор процесса и numberProcess() дает вам номер процесса:

int getProcessId(){
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
return rank;
}
// Get number of process
int numberProcess(){
int numProc;
MPI_Comm_size(MPI_COMM_WORLD, &numProc);
return numProc;
}

Каждый процесс будет иметь копию цифр массива; После параллельного выполнения главный процесс собирает результаты всех подчиненных процессов, используя MPI_Reduce. Или, если вы хотите объединить значения из всех процессов и распределить результат по всем процессам, которые вы можете использовать MPI_ALLREDUCE.

 long unsigned int digits[d + 11];
int DivN = n / 4; //Limiting slave.

for (int digit = 0; digit < d + 11; ++digit)
digits[digit] = 0;

if (rank != 0){
escravo(digits, (DivN * 1 ) );
escravo(digits, (DivN * 2 ) );
escravo(digits, (DivN * 3 ) );
escravo(digits, (DivN * 4 ) );
}

В соответствии с приведенным выше кодом процесс 0 не будет выполнять метод escravo, Кроме того, вы неправильно распределяете работу между процессами. Процесс 1 выполнит цикл out for внутри метода escravo от 1 до n / 4, но затем процесс 2 будет выполняться от 1 до 2n / 4 … Таким образом, у вас есть разные процессы, выполняющие одни и те же итерации, когда вы действительно хотите разделить эти итерации между процессами.

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector