我有一个作业的书面代码,需要根据要求进行修复。你能帮帮我吗,我整个脑子都坏掉了。
作业: 根据变体使用阻塞和非阻塞操作编写程序:b = MIN(A+C) 提供多个进程中操作的执行。来源分布 数据应该使用非阻塞操作来执行,结果的收集应该使用阻塞操作。 结果 - 使用阻塞操作。
要求:
注释:
代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>
int main(int argc, char* argv[])
{
const int N = 30;
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int local_size = N / size;
srand(time(0) + rank);
int* A = new int[local_size];
int* C = new int[local_size];
for (int i = 0; i < local_size; i++)
{
A[i] = rand() % 100;
C[i] = rand() % 100;
}
printf("Process Rank: %d\n", rank);
printf("Vector A:");
for (int i = 0; i < local_size; i++)
{
printf(" %d", A[i]);
}
printf("\n");
printf("Vector C:");
for (int i = 0; i < local_size; i++)
{
printf(" %d", C[i]);
}
printf("\n");
int local_min_A = A[0];
int local_min_C = C[0];
for (int i = 0; i < local_size; i++)
{
if (A[i] < local_min_A)
{
local_min_A = A[i];
}
if (C[i] < local_min_C)
{
local_min_C = C[i];
}
}
int local_min_sum = local_min_A + local_min_C;
printf("Local b min(A + C) = %d + %d = %d\n", local_min_A, local_min_C, local_min_sum);
if (rank == 0)
{
int global_min_A = local_min_A;
int global_min_C = local_min_C;
int global_min_sum = local_min_sum;
for (int i = 1; i < size; i++)
{
int recv_min_A, recv_min_C, recv_min_sum, recv_local_size;
MPI_Recv(&recv_min_A, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&recv_min_C, 1, MPI_INT, i, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&recv_min_sum, 1, MPI_INT, i, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
if (recv_min_A < global_min_A)
{
global_min_A = recv_min_A;
}
if (recv_min_C < global_min_C)
{
global_min_C = recv_min_C;
}
if (recv_min_sum < global_min_sum)
{
global_min_sum = recv_min_sum;
}
}
printf("Global b min(A + C) = %d\n", global_min_sum);
}
else
{
MPI_Send(&local_min_A, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(&local_min_C, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
MPI_Send(&local_min_sum, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
}
delete[] A;
delete[] C;
MPI_Finalize();
return 0;
}
总和计算示例
#include <iostream>
#include <time.h>
#include <mpi.h>
using namespace std;
#define n 40000000L
int main(int argc, char** argv){
int rank,size;
MPI_Status st;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if (!rank){
double *x, sum=0, d;
x=new double[n];
srand((unsigned)time(0));
for (int i=0; i<n; i++)
x[i]=(rand()%20)/2.;
unsigned pSize = n/(size-1);
printf("Master started!\n");
for (int i=1; i<size; i++) {
MPI_Send(&pSize,1,MPI_UNSIGNED,i,0,MPI_COMM_WORLD);
MPI_Send(x+(i-1)*pSize,pSize,MPI_DOUBLE,i,0,MPI_COMM_WORLD);
cout << "Master sent " <<
pSize << endl;
}
for (int i=pSize*(size-1); i<n; i++)
sum+=x[i];
for (int i=1; i<size; i++) {
MPI_Recv(&d, 1, MPI_DOUBLE, i,MPI_ANY_TAG, MPI_COMM_WORLD, &st);
cout << "Got sum from " << i<< ": sum="<< d << endl;
sum+=d;
}
cout << "Sum=" << sum << endl;
MPI_Finalize();
delete[] x;
return 0;
} else {
double *data, s = 0;
unsigned count;
data=new double[count];
MPI_Recv(&count, 1, MPI_UNSIGNED, 0,MPI_ANY_TAG, MPI_COMM_WORLD, &st);
MPI_Recv(data, count, MPI_DOUBLE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &st);
cout << "Rank " << rank << " got " << count << endl;
for (unsigned i=0; i<count; i++)
s+=data[i];
MPI_Send(&s,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD);
MPI_Finalize();
delete[] data;
return 0;
}
}
…b = MIN(A+C)…
int local_min_A = A[0]; int local_min_C = C[0]; for (int i = 0; i < local_size; i++) { if (A[i] < local_min_A) { local_min_A = A[i]; } if (C[i] < local_min_C) { local_min_C = C[i]; } } int local_min_sum = local_min_A + local_min_C;
您计算的是 MIN(A)+MIN(C),而不是 MIN(A+C)。
我重新编写了代码,但是导师说我错误地使用了阻塞和非阻塞操作。
源数据的分发应使用非阻塞操作来执行,结果的收集应使用阻塞操作来执行。结果 - 使用阻塞操作。
#define N 20
void PrintVector(double V[N])
{
for (int i = 0; i < N; i++)
{
printf("%.2f ", V[i]);
}
printf("\n");
}
int main(int argc, char* argv[])
{
MPI_Init(&argc, &argv);
MPI_Status st;
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
double* A, * C;
A = new double[N];
C = new double[N];
double localMin = DBL_MAX;
MPI_Request request;
if (!rank)
{
srand((unsigned)time(0));
for (int i = 0; i < N; i++) {
A[i] = (rand() % 20) / 2.;
C[i] = (rand() % 20) / 2.;
}
unsigned pSize = N / (size - 1);
printf("Master started!\n");
for (int i = 1; i < size; i++)
{
MPI_Isend(&pSize, 1, MPI_UNSIGNED, i, 0, MPI_COMM_WORLD, &request);
MPI_Isend(A + (i - 1) * pSize, pSize, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &request);
MPI_Isend(C + (i - 1) * pSize, pSize, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &request);
cout << "Master sent " << pSize << endl;
}
printf("Vector A:");
PrintVector(A);
printf("Vector C:");
PrintVector(C);
for (int i = (size - 1) * pSize; i < N; i++) {
double temp = A[i] + C[i];
localMin = min(localMin, temp);
}
for (int i = 1; i < size; i++)
{
double receivedMin;
MPI_Recv(&receivedMin, 1, MPI_DOUBLE, i, MPI_ANY_TAG, MPI_COMM_WORLD, &st);
localMin = min(localMin, receivedMin);
}
printf("\nMinumum b = min(A+C) = %f", localMin);
}
else {
double* dataA, * dataC;
unsigned count;
MPI_Recv(&count, 1, MPI_UNSIGNED, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &st);
dataA = new double[count];
dataC = new double[count];
MPI_Recv(dataA, count, MPI_DOUBLE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &st);
MPI_Recv(dataC, count, MPI_DOUBLE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &st);
cout << "Rank " << rank << " got " << count << endl;
for (unsigned i = 0; i < count; i++)
{
double temp = dataA[i] + dataC[i];
localMin = min(localMin, temp);
}
MPI_Send(&localMin, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
delete[] dataA;
delete[] dataC;
}
delete[] A;
delete[] C;
MPI_Finalize();
}