(1)問題
MPI實(shí)現(xiàn)矩陣向量:Ab的乘積。其中A:100行100列,b為列向量。
(2)思路
將所有進(jìn)程分為兩部分,rank=0的進(jìn)程為master節(jié)點(diǎn),其余進(jìn)程為worker節(jié)點(diǎn)。
master節(jié)點(diǎn):
(1)對A,b賦值,同時(shí)將b廣播出去(這里涉及一個(gè)對廣播這個(gè)函數(shù)不太熟悉的點(diǎn))
(2)對A進(jìn)行劃分,使其被劃分為worker數(shù)量的份數(shù),并將相應(yīng)數(shù)據(jù)發(fā)送給相應(yīng)的工人節(jié)點(diǎn)
(3)接收工人節(jié)點(diǎn)的計(jì)算結(jié)果,并對收到的結(jié)果及進(jìn)行一定的處理從而得到最終結(jié)果
worker節(jié)點(diǎn):
(1)接受來自master的參數(shù)
(2)對接收到的數(shù)據(jù)進(jìn)行計(jì)算
(3)將結(jié)果返回給master
(3)代碼
main.cpp:?
#include <iostream>
#include "mpi.h"
#include "conf.h"
#include "masterMain.h"
#include "workerMain.h"
#include<string.h>
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為參加運(yùn)算的矩陣,B為參加運(yùn)算的向量,result為結(jié)果
masterMain mastermain;
workerMain workerMain1;
if (rank == MASTER) {
cout<<"進(jìn)程0"<<endl;
// cout << "主進(jìn)程開始對矩陣和向量初始化~" << endl;
for (int i = 0; i < ROW; ++i) {
for (int j = 0; j < COL; ++j) {
a[i][j] = 1;
}
b[i] = 2;
}
}
//廣播必須在主進(jìn)程之外嗎?(這里不太理解!?。。? 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 <iostream>
using namespace std;
void masterMain::masterRun() {
}
/**
*
* @param a 矩陣A
* @param b 向量b
* @param row A的行數(shù)
* @param col A的列數(shù)
* @param size 參與運(yùn)算的所有進(jìn)程數(shù)
* @param rank 當(dāng)前進(jìn)程號
*/
void masterMain::matrixMuliplication(int a[][100], int *b, int row, int col, int size,int *res,MPI_Status status) {
//master節(jié)點(diǎn)任務(wù):首先是初始化矩陣,再分發(fā)矩陣,收集各個(gè)從節(jié)點(diǎn)返回的結(jié)果,并放到指定位置
//(1)設(shè)置當(dāng)前進(jìn)程所需的行
size = size - 1;
int rowPerWorker;
rowPerWorker = row / size;
//master給每個(gè)進(jìn)程傳遞數(shù)據(jù)的偏移量
int offset = 0;
cout << "主進(jìn)程開始對數(shù)據(jù)進(jìn)行分發(fā)~" << endl;
for (int i = 1; i <= size; ++i) {
rowPerWorker = (i <= row % size ? rowPerWorker + 1 : rowPerWorker);
int count = row * rowPerWorker;
//給從進(jìn)程傳遞計(jì)算數(shù)據(jù)
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接收從進(jìn)程發(fā)來的消息
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<<"矩陣向量乘結(jié)果為:"<<endl;
for (int i = 0; i < col; ++i) {
cout<<res[i]<<" ";
}
}
?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) {
//接收主進(jìn)程傳遞的向量,相應(yīng)矩陣,相應(yīng)數(shù)據(jù),并返回相應(yīng)計(jì)算結(jié)果
int offset;
int rowPerWorker;
//接收偏移量
MPI_Recv(&offset,1,MPI_INT,MASTER,FROMMASTER,MPI_COMM_WORLD,&status);
//接收行數(shù)
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];
// 計(jì)算
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)總結(jié)
1)為什么要分這么多CPP文件來寫?因?yàn)橄胧煜++在工程結(jié)構(gòu)上的寫法,所以要慢慢開始以這種寫法來寫
2)問題:mpi_bcast()函數(shù)放在master判斷條件內(nèi)為什么就不能將值廣播出去?
3)注意:寫的時(shí)候,先寫master發(fā)送的,然后寫worker接收相應(yīng)的值,在其進(jìn)行一定處理并發(fā)送給master后,再在master中寫接受到相應(yīng)值之后的操作,這樣不至于邏輯混亂文章來源:http://www.zghlxwxcb.cn/news/detail-503394.html
4)還要注意:send和recv必須保持順序一致,send誰在前,那么接收誰就在前,不然就會出錯(cuò)文章來源地址http://www.zghlxwxcb.cn/news/detail-503394.html
到了這里,關(guān)于MPI實(shí)現(xiàn)矩陣向量乘法的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!