基於MPI的大規模矩陣乘法問題


轉載請注明出處。

/*
	Function:C++實現並行矩陣乘法;
	Time: 19/03/25;
	Writer:ZhiHong Cc;
*/

 

運行方法:切到工程文件x64\Debug文件下,打開命令行,輸入以下指令:

mpiexec -n N Project.exe NUM

// N代表開啟進程數量,NUM代表矩陣規模大小(size)

 

具體代碼:

1.頭文件:

#include<stdio.h>
#include <iostream>
#include<math.h>
#include<mpi.h>
#include<time.h>

 

2.矩陣規模(size)接收,通過C++自帶參數argv和argc[ ]:

if (argv == 2)
    {
	//判斷有無矩陣大小size接收,無則初始化為5
	size = atoi(argc[1]);
    }
else { size = 5; }

 

3.為各指針變量分配空間

int *a, *b, *c, *pce, *ans;
a = (int*)malloc(sizeof(int)*size*size);//矩陣a
b = (int*)malloc(sizeof(int)*size*size);//矩陣b
c = (int*)malloc(sizeof(int)*size*size);//結果矩陣
pce = (int*)malloc(sizeof(int)*size*line);//接收a矩陣下的塊矩陣
ans = (int*)malloc(sizeof(int)*size*line);//暫存次進程的答案

 

4.定義進程號,進程個數以及塊矩陣的行數

int rank, numprocess, line;
line = size / numprocess;//將數據分為(進程數)個塊,主進程也要處理數據

 

5.主進程中進行一系列操作:生成矩陣、分配矩陣、接收次進程答案、拼接答案、計算耗時、最終輸出三個矩陣

for (int i = 0; i<size; i++)
{
	for (int j = 0; j<size; j++)
	{
		//隨機兩個相乘的矩陣a,b
		a[i*size + j] = random(10);
		b[i*size + j] = random(10);
	}
}
for (int i = 1; i<numprocess; i++)
{
	//將b矩陣傳遞給各進程
	MPI_Send(b, size*size, MPI_INT, i, 0, MPI_COMM_WORLD);
}
for (int i = 1; i<numprocess; i++)
{
	//將a矩陣分成塊矩陣,傳遞給各進程
	MPI_Send(a + (i - 1)*line*size, size*line, MPI_INT, i, 1, MPI_COMM_WORLD);
}
for (int k = 1; k<numprocess; k++)
{
	MPI_Recv(ans, line*size, MPI_INT, k, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
	//接收傳遞結果到數組c
	for (int i = 0; i<line; i++)
	{
		for (int j = 0; j<size; j++)
		{
			c[((k - 1)*line + i)*size + j] = ans[i*size + j];
		}
	}
}
for (int i = (numprocess - 1)*line; i<size; i++)
{
	//計算分配給主進程的塊矩陣
	for (int j = 0; j<size; j++)
	{
		int temp = 0;
		for (int k = 0; k<size; k++)
      {
			temp += a[i*size + k] * b[k*size + j];
      }
		c[i*size + j] = temp;
	}
}
for (int i = 0; i < size; i++)
{
	//打印顯示
	for (int j = 0; j<size; j++) { printf("%d ", a[size*i + j]); }printf("  ");
	for (int j = 0; j<size; j++) { printf("%d ", b[size*i + j]); }printf("  ");
	for (int j = 0; j<size; j++) { printf("%d ", c[size*i + j]); }printf("\n");
}
endtime = MPI_Wtime();
printf("Took %f secodes.\n", endtime - starttime);
}

  

6.次進程中進行此類操作:接收相乘矩陣,計算答案傳送給主進程

MPI_Recv(b, size*size, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
//接收b矩陣
MPI_Recv(pce, size*line, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
//接收塊矩陣
for (int i = 0; i<line; i++)
{
	//計算塊矩陣與b矩陣相乘的結果
	for (int j = 0; j<size; j++)
	{
		int temp = 0;
		for (int k = 0; k<size; k++)
			temp += pce[i*size + k] * b[k*size + j];
		ans[i*size + j] = temp;
	}
}
MPI_Send(ans, line*size, MPI_INT, 0, 2, MPI_COMM_WORLD);
//將結果傳遞到主進程

 

運行:開啟10個進程處理兩個12×12的矩陣相乘問題

運行:直接運行,不錄入參數

 

  歡迎大家在評論區提問或者指出問題!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM