• 基于MPI的大规模矩阵乘法问题


    转载请注明出处。

    /*
    	Function:C++实现并行矩阵乘法;
    	Time: 19/03/25;
    	Writer:ZhiHong Cc;
    */

    运行方法:切到工程文件x64Debug文件下,打开命令行,输入以下指令:

    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("
    ");
    }
    endtime = MPI_Wtime();
    printf("Took %f secodes.
    ", 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的矩阵相乘问题

    运行:直接运行,不录入参数

      欢迎大家在评论区提问或者指出问题!

  • 相关阅读:
    Java 核心编程——文件随机读写类(RandomAccessFile)
    java 核心编程——文件过滤类(FileFilter和FilenameFilter)
    java 核心编程 ——文件操作类File
    java 编程思想笔记(七)——异常
    java 编程思想笔记(六)——内部类
    enote笔记法使用范例(2)——指针(1)智能指针
    enote笔记法使用范例(1)——自己总结的一些编写代码的常识 (a)
    enote笔记语言(2)
    enote笔记语言(1)
    monkey命令——压力测试——转载参考07
  • 原文地址:https://www.cnblogs.com/chenzhihong294/p/10633342.html
Copyright © 2020-2023  润新知