目录
问题描述
A07. 从键盘输入一个正整数n,由进程0产生一个n行5列的矩阵A,该矩阵的第一行元素依次为-1,0,1,2,3;第k行元素依次为(-1)k,0,1,2-k,3-k。用send和recv实现将矩阵A的各行按“周期分布(亦称为卷帘分布)”分布到各进程。各进程输出收到的各行数据。
一、问题分析
二、程序结构
按周期间隔的将矩阵不同行分配给对应的进程。
三、程序样例
// HelloMPI.c
#include "pch.h"
#include <stdio.h>
#include <string.h> // For strlen() function
#include <mpi.h> // For MPI programming functions
#include <iostream>
#include <algorithm>
#include <string>
#include <math.h>
using namespace std;
//进程间通信共享缓冲
double A[1000];
int main(int argc, char *argv[])
{
//部分初始化工作
int rank, np, n = atoi(argv[1]);//输入获取矩阵大小
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);//获取进程编号
MPI_Comm_size(MPI_COMM_WORLD, &np);//np 存储 从 MPI_COMM_WORLD 获得的进程数量
if (rank == 0) {
int k = 0, r = 1, step = np - 1;//周期偏移量k,进程r,分段步长step
for (; k*step + r <= n; k++) {//周期偏移量k*步长小于等于总行数n
for (r = 1; r < np&&k*step + r <= n; r++) {//周期偏移量k*步长小于等于总行数n
int index = k * step + r;//行标
A[index * 5 + 0] = pow(-1, index);
A[index * 5 + 1] = 0;
A[index * 5 + 2] = 1;
A[index * 5 + 3] = pow(2, -index);
A[index * 5 + 4] = pow(3, -index);
MPI_Send(&A[index * 5], 5, MPI_DOUBLE, r, index, MPI_COMM_WORLD);//tag用行标记录来自哪行
}
r = 1;
}
}
else {
double a[5];
int k = 0, step = np - 1;//周期偏移量k,进程rank,分段步长step
for (; k*step + rank <= n; k++) {//周期偏移量k*步长小于等于总行数n
int index = k * step + rank;//行标
MPI_Recv(a, 5, MPI_DOUBLE, 0, index, MPI_COMM_WORLD, &status);
cout << "进程" << rank << "输出:" << "第" << index << "行元素(" << a[0] << "," << a[1] << "," << a[2] << "," << a[3] << "," << a[4] << ")" << endl;
}
}
MPI_Finalize();
return 0;
}
四、样例运行
1.项目生成,生成MPIProject1.exe执行文件
2.VS2017的开发人员命令提示符,命令传参执行
到生成的MPIProject1.exe文件目录下,执行命令:
mpiexec -n x ProjectName.exe parm1 parm2
x是指定的进程数,ProjectName是对于项目名,parm1 and parm2是程序需要传的参数(若程序需要的话);
含义:指定4个进程,传入矩阵行数n=14值;