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

轉載請註明出處。ios

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

 

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

mpiexec -n N Project.exe NUMdom

// N表明開啓進程數量,NUM表明矩陣規模大小(size)spa

 

具體代碼:命令行

1.頭文件:指針

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

 

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

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

 

3.爲各指針變量分配空間blog

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.主進程中進行一系列操做:生成矩陣、分配矩陣、接收次進程答案、拼接答案、計算耗時、最終輸出三個矩陣it

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的矩陣相乘問題

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

 

  歡迎你們在評論區提問或者指出問題!

相關文章
相關標籤/搜索