(1)问题
MPI实现矩阵向量:Ab的乘积。其中A:100行100列,b为列向量。
(2)思路
将所有进程分为两部分,rank=0的进程为master节点,其余进程为worker节点。
master节点:
(1)对A,b赋值,同时将b广播出去(这里涉及一个对广播这个函数不太熟悉的点)
(2)对A进行划分,使其被划分为worker数量的份数,并将相应数据发送给相应的工人节点
(3)接收工人节点的计算结果,并对收到的结果及进行一定的处理从而得到最终结果
worker节点:
(1)接受来自master的参数
(2)对接收到的数据进行计算
(3)将结果返回给master
(3)代码
main.cpp:
- #include
- #include "mpi.h"
- #include "conf.h"
- #include "masterMain.h"
- #include "workerMain.h"
- #include
-
- using namespace std;
-
- MPI_Status status;
-
- int main(int argc, char *argv[]) {
- int size, rank;
- MPI_Init(&argc, &argv);
- char message[20];
- MPI_Comm_rank(MPI_COMM_WORLD, &rank);
- MPI_Comm_size(MPI_COMM_WORLD, &size);
-
- int a[ROW][COL];
- int b[COL], res[COL]; //A为参加运算的矩阵,B为参加运算的向量,result为结果
- masterMain mastermain;
- workerMain workerMain1;
- if (rank == MASTER) {
- cout<<"进程0"<
- // cout << "主进程开始对矩阵和向量初始化~" << endl;
- for (int i = 0; i < ROW; ++i) {
- for (int j = 0; j < COL; ++j) {
- a[i][j] = 1;
- }
- b[i] = 2;
- }
- }
- //广播必须在主进程之外吗?(这里不太理解!!!)
- MPI_Bcast(&b, COL, MPI_INT, 0, MPI_COMM_WORLD);
- if(rank==MASTER){
- mastermain.matrixMuliplication(a,b,ROW,COL,size,res,status);
- }else{
- workerMain1.workerRun(a,b,ROW,COL,status);
- }
-
- MPI_Finalize();
-
- }
masterMain.cpp
- //
- // Created by unbuntu-xcr on 22-10-15.
- //
-
- #include "masterMain.h"
- #include "conf.h"
- #include
-
- using namespace std;
-
- void masterMain::masterRun() {
-
- }
-
- /**
- *
- * @param a 矩阵A
- * @param b 向量b
- * @param row A的行数
- * @param col A的列数
- * @param size 参与运算的所有进程数
- * @param rank 当前进程号
- */
- void masterMain::matrixMuliplication(int a[][100], int *b, int row, int col, int size,int *res,MPI_Status status) {
- //master节点任务:首先是初始化矩阵,再分发矩阵,收集各个从节点返回的结果,并放到指定位置
- //(1)设置当前进程所需的行
- size = size - 1;
- int rowPerWorker;
- rowPerWorker = row / size;
- //master给每个进程传递数据的偏移量
- int offset = 0;
- cout << "主进程开始对数据进行分发~" << endl;
- for (int i = 1; i <= size; ++i) {
- rowPerWorker = (i <= row % size ? rowPerWorker + 1 : rowPerWorker);
- int count = row * rowPerWorker;
- //给从进程传递计算数据
- MPI_Send(&offset,1,MPI_INT,i,FROMMASTER,MPI_COMM_WORLD);
- MPI_Send(&rowPerWorker,1,MPI_INT,i,FROMMASTER,MPI_COMM_WORLD);
- MPI_Send(a[offset], count, MPI_INT, i, FROMMASTER, MPI_COMM_WORLD);
- offset+=rowPerWorker;
- }
-
- int result[rowPerWorker];
- //MASTER接收从进程发来的消息
- for (int i = 1; i <= size ; ++i) {
- int k=0;
- MPI_Recv(&offset,1,MPI_INT,i,FROMWORKER,MPI_COMM_WORLD,&status);
- MPI_Recv(&rowPerWorker,1,MPI_INT,i,FROMWORKER,MPI_COMM_WORLD,&status);
- MPI_Recv(result,rowPerWorker,MPI_INT,i,FROMWORKER,MPI_COMM_WORLD,&status);
- for (int j = offset; j <= offset+rowPerWorker ; ++j) {
- res[j]=result[k++];
- }
- }
-
- cout<<"矩阵向量乘结果为:"<
- for (int i = 0; i < col; ++i) {
- cout<
" "; - }
-
- }
workerMain.cpp
- //
- // Created by unbuntu-xcr on 22-10-15.
- //
-
- #include "workerMain.h"
- #include "conf.h"
-
- void workerMain::workerRun(int a[][100], int *b, int row, int col,MPI_Status status) {
- //接收主进程传递的向量,相应矩阵,相应数据,并返回相应计算结果
- int offset;
- int rowPerWorker;
- //接收偏移量
- MPI_Recv(&offset,1,MPI_INT,MASTER,FROMMASTER,MPI_COMM_WORLD,&status);
- //接收行数
- MPI_Recv(&rowPerWorker,1,MPI_INT,MASTER,FROMMASTER,MPI_COMM_WORLD,&status);
- //接收矩阵A
- MPI_Recv(a,rowPerWorker*col,MPI_INT,MASTER,FROMMASTER,MPI_COMM_WORLD,&status);
-
- int result[rowPerWorker];
- // 计算
- for (int i = 0; i < rowPerWorker; ++i) {
- result[i]=0;
- for (int j = 0; j < col; ++j) {
- result[i]+=a[i][j]*b[j];
- }
- }
-
- MPI_Send(&offset,1,MPI_INT,MASTER,FROMWORKER,MPI_COMM_WORLD);
- MPI_Send(&rowPerWorker,1,MPI_INT,MASTER,FROMWORKER,MPI_COMM_WORLD);
- MPI_Send(result,rowPerWorker,MPI_INT,MASTER,FROMWORKER,MPI_COMM_WORLD);
- }
(4)总结
1)为什么要分这么多CPP文件来写?因为想熟悉c++在工程结构上的写法,所以要慢慢开始以这种写法来写
2)问题:mpi_bcast()函数放在master判断条件内为什么就不能将值广播出去?
3)注意:写的时候,先写master发送的,然后写worker接收相应的值,在其进行一定处理并发送给master后,再在master中写接受到相应值之后的操作,这样不至于逻辑混乱
4)还要注意:send和recv必须保持顺序一致,send谁在前,那么接收谁就在前,不然就会出错
-
相关阅读:
JAVA社区疫情防控系统毕业设计,社区疫情防控管理系统设计与实现,毕设作品参考
根据PPG估算血压利用频谱谱-时间深度神经网络【翻】
Golang中init()函数初始化顺序
文件上传下载
小米 vivo oppo 等mtk芯片机型线刷授权的分析描述 免授权操作
栈和队列oj题
黑寡妇(BWO)优化算法(Matlab代码实现)
【从Python基础到深度学习】 8. VIM两种状态
机器学习面试准备(一)KNN
【C++】map & set 底层刨析
-
原文地址:https://blog.csdn.net/jaaccck/article/details/127412709