精华内容
下载资源
问答
  • 本程序时利用mpi实现矩阵向量并行相乘。你需要安装mpich并配置好环境。编译:mpicc Mat_vect_mult.c -o Mat_vect_mult 运行:mpirun -np 5 ./Mat_vect_mult ;5为进程数,可以更换
  • 利用MPI写的矩阵向量相乘并行算法

    热门讨论 2009-12-14 20:30:44
    利用C++和MPI写的矩阵向量相乘并行算法,在WINDOWS、LINUX下测试没问题。
  • 矩阵向量乘法

    2012-03-10 14:47:14
    用两个ROM实现一个矩阵向量的乘法,利用了乘累加。
  • MPI矩阵向量乘法

    千次阅读 2017-12-29 14:46:00
    然后输入矩阵向量的维度n 然后输入一个n维向量 然后输入K个n阶方阵 程序会给出该向量连续与此K个方阵做乘法后的结果 主要用了MPI_Gather, MPI_Allgather, MPI_Bcast, MPI_Scatter 等 注意printf在终端中打印...

    输入作乘法的次数K

    然后输入矩阵和向量的维度n

    然后输入一个n维向量

    然后输入K个n阶方阵

    程序会给出该向量连续与此K个方阵做乘法后的结果

    主要用了MPI_Gather, MPI_Allgather, MPI_Bcast, MPI_Scatter 等

    注意printf在终端中打印的时机会很玄学 往往会在程序完全执行完毕之后才会打印

    注意 本程序将矩阵的所有行划分成一些段,分别分配给各个进程 仍然没有处理进程数无法整除维度n的情况

    typedef long long __int64;
    #include "mpi.h"
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int main(int argc, char* argv[]){
        int my_rank=0, comm_sz=0, local_int=0, total_int=0;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
        int n,zongci;
        int* x;
        if(my_rank==0){
            scanf("%d%d",&zongci,&n);
        }
        MPI_Bcast(&zongci,1,MPI_INT,0,MPI_COMM_WORLD);
        MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
        x=new int[n];
        if(my_rank==0){
            for(int i=0;i<n;++i){
                scanf("%d",&x[i]);
            }
        }
        MPI_Bcast(x,n,MPI_INT,0,MPI_COMM_WORLD);
        if(my_rank==0){
            printf("第0次与%d*%d矩阵相乘后的x向量:\n",n,n);
            for(int i=0;i<n;++i){
                printf("%d\n",x[i]);
            }
            puts("");
        }
        for(int ci=1;ci<=zongci;++ci){
            int* local_A=new int[n*n/comm_sz];
            int* A=new int[n*n];
            if(my_rank==0){
                for(int i=0;i<n;++i){
                    for(int j=0;j<n;++j){
                        scanf("%d",&A[i*n+j]);
                    }
                }
                MPI_Scatter(A,n*n/comm_sz,MPI_INT,local_A,n*n/comm_sz,MPI_INT,0,MPI_COMM_WORLD);
                delete[] A;
            }
            else{
                MPI_Scatter(A,n*n/comm_sz,MPI_INT,local_A,n*n/comm_sz,MPI_INT,0,MPI_COMM_WORLD);
            }
            int* local_x=new int[n/comm_sz];
            for(int i=0;i<n/comm_sz;++i){
                local_x[i]=0;
                for(int j=0;j<n;++j){
                    local_x[i]+=local_A[i*n+j]*x[j];
                }
            }
            if(ci<zongci){
                MPI_Allgather(local_x,n/comm_sz,MPI_INT,x,n/comm_sz,MPI_INT,MPI_COMM_WORLD);
            }
            else{
                MPI_Gather(local_x,n/comm_sz,MPI_INT,x,n/comm_sz,MPI_INT,0,MPI_COMM_WORLD);
            }
            if(my_rank==0){
                printf("第%d次与%d*%d矩阵相乘后的x向量:\n",ci,n,n);
                for(int i=0;i<n;++i){
                    printf("%d\n",x[i]);
                }
                puts("");
            }
            delete[] local_x;
        }
        delete[] x;
        MPI_Finalize();
        return 0;
    }

    转载于:https://www.cnblogs.com/autsky-jadek/p/8144458.html

    展开全文
  • 矩阵按照行划分,之后,再每个线程都用整个向量跟这个块做内积。之后,传回来一个数值。 这里的方法二, 将矩阵按照列进行划分。然后将列向量传递给所有的线程,之后,再传对应的向量的对应的元素,给这个线程。...

    简述

    有留心过的朋友可能会发现,其实我没写过解法一。

    因为解法一就是大家最直观的感受的一种解法。

    • 将矩阵按照行划分,之后,再每个线程都用整个向量跟这个块做内积。之后,传回来一个数值。

    这里的方法二,

    • 将矩阵按照列进行划分。然后将列向量传递给所有的线程,之后,再传对应的向量的对应的元素,给这个线程。之后,这个元素(数值),乘上传给它的向量的每一个元素。最后,再做一个Reduce的操作,将所有的向量加起来。就得到了一个新的向量。这个向量就是解。

    数学表达式

    解法一的数学表达

    T h r e a d ( i ) : ∑ j = 0 n − 1 A i j ∗ X j Thread(i):\sum_{j=0}^{n-1}{A_{ij}*X_j} Thread(i):j=0n1AijXj
    r e s u l t = { j ∈ { 0 , 1 , . . , n − 1 } ∣ T h r e a d ( j ) } result = {\{j\in\{0,1,..,n-1\}| Thread(j)\}} result={j{0,1,..,n1}Thread(j)}

    • 第一步得到的是一个数值
    • result的过程是将数值组合成向量的过程。

    解法二的数学表达式

    T h r e a d ( i ) : { j ∈ { 0 , 1 , . . , n − 1 } ∣ A i j ∗ X i } Thread(i):{\{j\in\{0,1,..,n-1\}| A_{ij}*X_i\}} Thread(i):{j{0,1,..,n1}AijXi}

    r e s u l t = ∑ i = 0 n − 1 T h r e a d ( i ) result = \sum_{i=0}^{n-1}{Thread(i)} result=i=0n1Thread(i)

    • 第一步得到的是一个向量
    • result求和的过程是向量的求和过程。

    从数学表达式上,可以很清楚地知道这个结果是一致的。(这里假设了这个矩阵是n*n)

    在VS上可以编译的程序

    #include<stdio.h>
    #include<string.h>
    #include<mpi.h>
    #pragma warning(disable : 4996)
    #define MAX_STRING 100
    using namespace std;
    #include <fstream>
    #include <iostream>
    
    int main(void) {
    	int comm_sz;
    	int my_rank;
    	MPI_Init(NULL, NULL);
    	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    
    
    	// 只有一个线程的时候不操作
    	if (comm_sz <= 1) {
    		MPI_Finalize();
    		return 0;
    	}
    	ifstream cin("D:\\C++\\VS\\repo\\MPI-DEMO\\MPI-DEMO\\input.txt");
    	int N = 0;
    	double *b = NULL, *local, **a, *ks, k, *local_arr;
    	cin >> N;
    	int rank_len = 0;
    
    	// initialize
    	if (my_rank == 0) {
    		a = new double*[N];
    		for (int i = 0; i < N; ++i) {
    			a[i] = new double[N];
    		}
    		// read a
    		for (int i = 0; i < N; ++i)
    			for (int j = 0; j < N; ++j)
    				cin >> a[j][i]; // transpose 
    		ks = new double[N];
    		// read ks
    		for (int i = 0; i < N; ++i) cin >> ks[i];
    		// send data to other.
    		rank_len = N / comm_sz;
    		for (int i = 1; i < comm_sz; ++i) {
    			// send N
    			MPI_Send(&N, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
    			for (int j = 0; j < rank_len; ++j) {
    				MPI_Send(a[i * rank_len + j], N, MPI_DOUBLE, i, 2 * j + 1, MPI_COMM_WORLD);
    				MPI_Send(&ks[i * rank_len + j], 1, MPI_DOUBLE, i, 2 * j + 2, MPI_COMM_WORLD);
    			}
    		}
    		local_arr = new double[N];
    		local = new double[N];
    		for (int i = 0; i < N; ++i) 
    			local_arr[i] = 0;
    		for (int i = 0; i < rank_len; ++i) {
    			for (int j = 0; j < N; ++j) {
    				local_arr[j] += (a[i][j] * ks[i]);
    			}
    		}
    		MPI_Reduce(local_arr, local, N, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    		for (int i = 0; i < N; ++i) cout << local[i] << " ";
    		cout << endl;
    
    		// release 
    		for (int i = 0; i < N; ++i) delete[]a[i];
    		delete[]a;
    		delete[]ks;
    	}
    	else {
    		MPI_Recv(&N, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    		local = new double[N];
    		local_arr = new double[N];
    		for (int i = 0; i < N; ++i) local_arr[i] = 0;
    		rank_len = N / comm_sz;
    		for (int j = 0; j < rank_len; ++j) {
    			MPI_Recv(local, N, MPI_DOUBLE, 0, 2 * j + 1, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    			MPI_Recv(&k, 1, MPI_DOUBLE, 0, 2 * j + 2, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    			for (int i = 0; i < N; ++i) local_arr[i] += (k * local[i]);
    		}
    		MPI_Reduce(local_arr, NULL, N, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    	}
    
    	delete[]local_arr;
    	delete[] local;
    
    	// finalize
    	MPI_Finalize();
    
    	return 0;
    }
    

    实例输入数据

    • 最后一行是向量,上面的是方阵。
    10
    3 10 6 0 8 5 6 4 1 6 
    0 1 10 7 2 10 8 10 3 2 
    6 1 10 10 2 5 5 5 5 2 
    3 7 1 2 7 2 3 8 2 7 
    3 7 8 4 8 7 4 4 4 1 
    5 4 8 3 4 10 7 5 5 0 
    2 4 7 10 5 7 9 6 5 10 
    9 9 1 4 10 0 1 8 1 5 
    8 0 3 2 10 9 10 8 10 7 
    6 9 0 4 4 9 1 0 0 6 
    2 1 0 2 5 8 7 4 6 4 
    

    计算过程

    在这里插入图片描述

    HINTS

    注意,这里调用的线程数量,必须可以整除n

    • 关于MPI_Reduce : 我会之后补一份介绍。
    展开全文
  • MPI实现矩阵相乘

    千次阅读 2019-05-17 17:31:27
    之前一直想写一个关于MPI的例子,之后便想起了矩阵相乘,之后便在网上找资料,结果发现有些地方实现不了,于是便自己参考网上例子,踩了各种各样的雷之后于是才有了这次分享 1.MPI并行运算的思想 MPI并行运算通过...

    之前一直想写一个关于MPI的例子,之后便想起了矩阵相乘,之后便在网上找资料,结果发现有些地方实现不了,于是便自己参考网上例子,踩了各种各样的雷之后于是才有了这次分享
    1.MPI并行运算的思想
    MPI并行运算通过由用户指定分配进程,来实现多进程的一种思想。MPI(Message-Passing-Interface 消息传递接口)实现并行是进程级别的,通过通信在进程之间进行消息传递。MPI并不是一种新的开发语言,它是一个定义可以被C、C++和Fortran程序调用的函数库。这些函数库里面主要涉及的是两个进程之间通信的函数。MPI可以在Windows和linux环境中都有相应的库,本篇以Windows10作为演示开发环境。
    2.配置MPI环境
    Windows为了兼容MPI,自己做了一套基于一般个人电脑的MPI实现。如果要安装正真意义上的MPI的话,请直接去www.mpich.org下载,里面根据对应的系统下载相应的版本。
    安装 mpi
    我的电脑是64位的,所以安装的是 mpi_x64.msi ,默认安在C:\Program Files\Microsoft HPC Pack 2008 R2,在此,为了之后调试代码方便,最好设置一下环境变量:在用户变量PATH中,加入:C:\Program Files\Microsoft HPC Pack 2008 R2\Bin\。

    配置mpi
    配置目录,即加载Include和Lib库
    ​​​​在这里插入图片描述
    加载依赖项
    在这里插入图片描述

    3.编译
    根据编程员的习俗先从一个helloworld开始

    #include "mpi.h"  
    #include <stdio.h>  
    
    int main(int argc, char* argv[])
    {
        int rank, numproces;
        int namelen;
        char processor_name[MPI_MAX_PROCESSOR_NAME];
    
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);//获得进程号
        MPI_Comm_size(MPI_COMM_WORLD, &numproces);//返回通信子的进程数
    
        MPI_Get_processor_name(processor_name, &namelen);
        fprintf(stderr, "hello world! process %d of %d on %s\n", rank, numproces, processor_name);
        MPI_Finalize();
    
        return 0;
    }
    

    4.mpi 矩阵相乘
    接下来便开始我们的主题
    实际的思想是使用0进程将矩阵切分成n份分别发送个其他的进程,再有其他的进程计算完成之后再发回0进程。

    0进程进行分发,切分,以及整合矩阵。

    if (myid == 0) {
      int  **N = NULL;
      int *buffer3 = nullptr;
      cout << "输入你的值" << endl;
      cin >> am;
      start2 = MPI_Wtime();
    //将am的值广播给每一个进程(除了0进程)
      for (int i = 0; i < size; i++) {
       MPI_Send(&am, 1, MPI_INT, i + 1, 33, MPI_COMM_WORLD);
      }
      /*
      新建矩阵并初始化
      */
      srand((unsigned)time(NULL));
      buffer3 = (int*)malloc(sizeof(int)*am);
      int* M = new int[am*am];
      cout << "-------A类矩形------" << endl;
      for (int i = 0; i < am; i++) {
       for (int j = 0; j < am; j++) {
       M[i*am + j] = (rand() % 9) + 1;
        cout << M[i*am + j] << " ";
       }
       cout << endl;
      }
      N = (int**)malloc(sizeof(int)*am);
      for (int i = 0; i < am; i++) {
       N[i] = (int*)malloc(sizeof(int)*am);
       }
       cout << "-------B类矩形------" << endl;
      for (int i = 0; i < am; i++) {
       for (int j = 0; j < am; j++) {
       N[i][j] = (rand() % 9) + 1;
        cout << N[i][j] << " ";
       }
       cout << endl;
      }
     /*
       判断是否采用单线程
       */  
       if (numprocs <am) {
       int temp;
       int **P = NULL;
       P = (int**)malloc(sizeof(int)*am);
       for (int i = 0; i < am; i++) {
        P[i] = (int*)malloc(sizeof(int)*am);
        }
     
        for (int z = 0; z < am; z++) {
        for (int i = 0; i < am; i++) {
         P[z][i] = 0;
         temp = 0;
         for (int j = 0; j < am; j++) {
          temp = +M[j*am + i] * N[z][j];
          }
         P[z][i] = temp;
        }
        }
        cout << endl;
       cout << "得到的矩阵为" << endl;
       for (int i = 0; i < am; i++) {
       for (int j = 0; j < am; j++) {
         printf("%-8d", P[i][j]);
        }
        cout << endl;
       }
       end = MPI_Wtime();
       double time = end - start2;
       cout << "单进程需要的时间为" << end - start2 << endl;
       }
      else
      {
      /*
       向各个进程发送信息
       */
       
       for (int i = 0; i < am; i++) {
        for (int j = 0; j < am; j++) {
         buffer3[j] = N[j][i];
         }
        MPI_Send(buffer3, am, MPI_INT, i + 1, 11,MPI_COMM_WORLD);
        }
        for (int i = 0; i < am; i++) {
        MPI_Send(&M[0 + 0], am*am, MPI_INT, i + 1, 22, MPI_COMM_WORLD);
       }
       free(N);
       free(buffer3);
          /*
       回收各个进程的值
       */
    
       int **P = NULL;
       P = (int**)malloc(sizeof(int)*am);
       for (int i = 0; i < am; i++) {
       P[i] = (int*)malloc(sizeof(int)*am);
       }
       for (int i = 0; i < am; i++) {
       MPI_Recv(&(P[i][0]), am, MPI_INT, i + 1, i + 1, MPI_COMM_WORLD, &status);
    }
    cout << endl;
       cout << "得到的矩阵为" << endl;
       for (int i = 0; i < am; i++) {
       for (int j = 0; j < am; j++) {
         //cout << P[i][j] << " ";
         printf("%-8d", P[i][j]);
         }
        cout << endl;
       }
         end = MPI_Wtime();
       double time = end - start2;
       cout << "多进程需要的时间为" << end - start2 << endl;
       }
     }
    ``
    
    其他进程则负责接收以及计算在发送给0进程
    
    

    //接受来自0进程的值
    if (myid != 0) {
    MPI_Recv(&am, 1, MPI_INT, 0, 33, MPI_COMM_WORLD, &status);
    }
    if (myid != 0 && myid <= am && numprocs>am) {
    int temp;
    int buffer2, m;
    int buffer = new int[amam];
    buffer2 = (int
    )malloc(sizeof(int)am);
    m = (int
    )malloc(sizeof(int)am);
    /

    接受来自0进程的数据
    /
    MPI_Recv(buffer2, am, MPI_INT, 0, 11, MPI_COMM_WORLD, &status);
    MPI_Recv(buffer, am
    am, MPI_INT, 0, 22, MPI_COMM_WORLD, &status);
    for (int i = 0; i < am; i++) {
    m[i] = 0;
    temp = 0;
    for (int j = 0; j < am; j++) {
    temp = +buffer[j
    am + i] * buffer2[j];
    }
    m[i] = temp;
    }
    /*
    将得到的数据进行计算并且将其传回0进程
    */
    MPI_Send(m, am, MPI_INT, 0, myid, MPI_COMM_WORLD);
    free(buffer);
    free(buffer2);
    free(m);
    }
    在这里我也将头部添上

    #include<stdio.h>
    #include<iostream>
    #include<string>
    #include"mpi.h"
    #include <stdlib.h>
    #include <time.h>
    #pragma comment(lib,"msmpi.lib")
    using namespace std;
    int am;
    int main(int argc, char **argv) {
     int numprocs;
     int myid, size;
     MPI_Status status;
     double start1, start2, end;
     MPI_Init(&argc, &argv);//MPI Initialize
     MPI_Comm_rank(MPI_COMM_WORLD, &myid);//获得当前进程号
     MPI_Comm_size(MPI_COMM_WORLD, &numprocs);//获得进程个数
     size = numprocs - 1;
    

    尾部添上

    MPI_Finalize();
     return 0;
    }
    
    展开全文
  • 课程计算流体力学作业:矩阵相乘MPI并行程序。FORtran和C++代码,
  • MPI实现矩阵乘法

    2015-12-24 20:29:52
    通过分块利用MPI通讯实现矩阵乘法的并行计算。
  • 简述 子矩阵分解,就是说,将原来的矩阵给分解为更小的矩阵块。 让所有的线程都共享有向量(但不共享矩阵) 为了试验简单,这里做了几个简单的假设 ...【MPI编程】矩阵向量乘法–解法二(高性能计算) 数据也是用...

    简述

    子矩阵分解,就是说,将原来的矩阵给分解为更小的矩阵块。

    • 让所有的线程都共享有向量(但不共享矩阵)

    为了试验简单,这里做了几个简单的假设

    • 矩阵为方阵(n*n)
    • comm_sz(线程数量)和n满足下面的关系
      • n被 c o m m _ s z \sqrt{comm\_sz} comm_sz 整除
      • comm_sz为平方数

    我们基于之前的版本改进

    算法分析

    • 用一个一维数据来记录数据
    • 线程0来读取数据,并分发给其他线程。最后大家一起来算,最后再汇总给线程0。
    • 每个线程算自己对应的矩阵,和部分的向量的内积。

    汇总的过程:

    • 汇总的过程中,处于同一行的其他线程将数据发给同行的第一个
    • 最后第0列的所有元素按顺序发给线程0。之后,按顺序输出数据。

    难点:

    • 定位上,通过一维数组来表示,便于传递数据,但是在设计程序上稍显麻烦。可以用宏定义的方式来减轻负担。不过这次的代码只有160行。不太需要这些操作。(可以用来锻炼思维)

    代码

    在VS上可以编译代码

    #include<stdio.h>
    #include<string.h>
    #include<mpi.h>
    #pragma warning(disable : 4996)
    #define MAX_STRING 100
    using namespace std;
    #include <fstream>
    #include <iostream>
    #include <cmath>
    
    int main(void) {
    	int comm_sz;
    	int my_rank;
    	MPI_Init(NULL, NULL);
    	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    
    
    	// 只有一个线程的时候不操作
    	if (comm_sz <= 1) {
    		MPI_Finalize();
    		return 0;
    	}
    
    	int N = 0, local_N, sqrtCommSZ = sqrt(comm_sz);
    	double *b = NULL, *local, *a, *ks, *local_a, *local_ans;
    	int rank_len = 0, local_len;
    	// initialize
    	if (my_rank == 0) {
    		ifstream cin("D:\\C++\\VS\\repo\\MPI-DEMO\\MPI-DEMO\\input.txt");
    		cin >> N;
    		// Send N to all 
    		MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
    		// create a
    		a = new double[N*N];
    		// read a
    		for (int i = 0; i < N; ++i)
    			for (int j = 0; j < N; ++j)
    				cin >> a[i * N + j];
    		// create ks
    		ks = new double[N];
    		// read ks
    		for (int i = 0; i < N; ++i) cin >> ks[i];
    		// send data to other.
    		MPI_Bcast(ks, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    		local_N = N * N / comm_sz;
    		local = new double[local_N];
    		local_a = new double[local_N];
    		local_len = N / sqrtCommSZ;
    		for (int i = 0; i < sqrtCommSZ; ++i) {
    			for (int j = 0; j < sqrtCommSZ; ++j) {
    				if (i == 0 && j == 0) { // record from Mat a
    					for (int k = 0; k < local_len; ++k) {
    						for (int t = 0; t < local_len; ++t) {
    							local_a[k * local_len + t] =
    								a[k * N + t];
    						}
    					}
    				}
    				else { // copy and send!
    					// (i * sqrtCommSZ + j) is the target rank.
    					for (int k = 0; k < local_len; ++k) {
    						for (int t = 0; t < local_len; ++t) {
    							local[k * local_len + t] = // keep 
    								a[i * local_len * N + j * local_len // 定位到左上角
    								+ k * N + t];
    							// 左上角坐标:[i * local_len, j * local_len]
    						}
    					}
    					MPI_Send(local, local_len * local_len, MPI_DOUBLE,
    						i * sqrtCommSZ + j, 0, MPI_COMM_WORLD);
    				}
    			}
    		}
    		local_ans = new double[local_len];
    		for (int i = 0; i < local_len; ++i) {
    			local_ans[i] = 0;
    			for (int j = 0; j < local_len; ++j) {
    				local_ans[i] += local_a[i * local_len + j] * ks[j];
    			}
    		}
    
    		// recv from the same row
    		double * temp_local = new double[local_len];
    		for (int i = 1; i < sqrtCommSZ; ++i) {
    			MPI_Recv(temp_local, local_len, MPI_DOUBLE,
    				my_rank + i, 1, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    			for (int j = 0; j < local_len; ++j) {
    				local_ans[j] += temp_local[j];
    			}
    		}
    		// recv from different rows
    
    		for (int i = 0; i < local_len; ++i) {
    			cout << local_ans[i] << " ";
    		}
    
    		for (int i = 1; i < sqrtCommSZ; ++i) {
    			MPI_Recv(temp_local, local_len, MPI_DOUBLE,
    				my_rank + i * sqrtCommSZ, 2, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    			for (int j = 0; j < local_len; ++j) {
    				cout << temp_local[j] << " ";
    			}
    		}
    		cout << endl;
    
    		delete[] temp_local;
    		delete[]a;
    		delete[]local;
    	}
    	else { // other rank
    		// recv data
    		MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
    		ks = new double[N];
    		MPI_Bcast(ks, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    		local_len = N / sqrtCommSZ;
    		local_a = new double[local_len * local_len];
    		MPI_Recv(local_a, local_len * local_len, MPI_DOUBLE, 
    			0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    		// 本地做乘法
    		local_ans = new double[local_len];
    		for (int i = 0; i < local_len; ++i) {
    			local_ans[i] = 0;
    			for (int j = 0; j < local_len; ++j) {
    				local_ans[i] += local_a[i * local_len + j] * 
    					ks[j + local_len * (my_rank % sqrtCommSZ)];
    			}
    		}
    
    		
    
    		if (my_rank % sqrtCommSZ == 0) { // recv and send to 0,0
    			double * temp_local = new double[local_len];
    			for (int i = 1; i < sqrtCommSZ; ++i) {
    				MPI_Recv(temp_local, local_len, MPI_DOUBLE,
    					my_rank + i, 1, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
    				for (int j = 0; j < local_len; ++j) {
    					local_ans[j] += temp_local[j];
    				}
    			}
    			delete[] temp_local;
    			// send to 0, 0
    			MPI_Send(local_ans, local_len, MPI_DOUBLE,
    				0, 2, MPI_COMM_WORLD);
    		}
    		else { // send
    			MPI_Send(local_ans, local_len, MPI_DOUBLE,
    				my_rank - my_rank % sqrtCommSZ, 1, MPI_COMM_WORLD);
    		}
    		
    	}
    	delete[] local_ans;
    	delete[]ks;
    	delete[] local_a;
    
    	// finalize
    	MPI_Finalize();
    
    	return 0;
    }
    

    测试数据

    10
    3 10 6 0 8 5 6 4 1 6 
    0 1 10 7 2 10 8 10 3 2 
    6 1 10 10 2 5 5 5 5 2 
    3 7 1 2 7 2 3 8 2 7 
    3 7 8 4 8 7 4 4 4 1 
    5 4 8 3 4 10 7 5 5 0 
    2 4 7 10 5 7 9 6 5 10 
    9 9 1 4 10 0 1 8 1 5 
    8 0 3 2 10 9 10 8 10 7 
    6 9 0 4 4 9 1 0 0 6 
    2 1 0 2 5 8 7 4 6 4 
    

    测试结果

    在这里插入图片描述

    很明显跟之前的结果是一样的。

    Hints

    展开全文
  • OpenMP并行计算矩阵向量相乘

    千次阅读 2019-05-21 16:06:19
    程序计算随机生成的矩阵向量相乘 函数f():单线程计算 函数fp():多线程并行计算 #include <stdio.h> #include <omp.h> #include <stdlib.h> #include <time.h> const int NUM_THREADS ...
  • 随着多核处理器及并行计算机的发展,并行程序设计在高性能计算及进程通信等领域得到更广泛的应用.而MPI(Message Passing Interface消息传递接口)作为目前最重要的并… 文件:n459.com/file/25127180-476147410 ...
  • MPI编程----矩阵乘法

    千次阅读 2018-06-04 17:57:48
    如图所示,将一个矩阵每一列分配给各个子进程,然后在进程内部将一列与另一个矩阵相乘,最后将根进程收集结果并进行输出。 代码如下: #include &lt;stdio.h&gt; #include "mpi.h" #include &...
  • 大致看了看MPI的一些函数...要求一个行向量和一个方阵的乘积,乘积结果也是一个行向量,用MPI编写并行程序。假设子任务数目总是能被进程数均匀划分。 ①方阵按列分配任务 在输入时转置输入,则按列分配就变成了按行分
  • 矩阵相乘MPI并行算法

    热门讨论 2010-11-01 17:16:31
    使用MPI+C并行语言实现矩阵相乘,该程序已经经过调试,完全可运行。
  • //获得当前矩阵块横坐标方向相聚x的左右邻居 MPI_Cart_shift(Cart_Comm_World, 1, x, &leftRank, &rightRank); if (leftRank != myid) MPI_Sendrecv_replace(&A(0, 0), num*num, MPI_DOUBLE, leftRank, 0, ...
  • MPI并行程序】矩阵乘法

    千次阅读 2018-05-24 21:46:53
    具体思路为创建矩阵,给每个进程分配矩阵的不同部分,每个进程根据进程号的不同处理矩阵的不同部分,计算完成后将每个进程的数组发送给一个特定的进程,由该进程合成一个完整的矩阵输出出来。问题是不一定每个进程都...
  • 使用OpenMP及MPI完成的几个并行程序设计小实验:矩阵相乘矩阵LU分解、文档分类中的文档向量过程 我所使用的运行环境 Ubuntu 16.04(64位版本) gcc version 5.4.0 20160609 (低版本gcc可能无法使用OpenMP) ...
  • MPI矩阵乘法的两种实现方法

    万次阅读 2015-05-21 15:39:17
    MPI矩阵乘法去年学习了并行计算,接触了MPI、Pthreads和OpenMP等常用的并行方法实现了并行的矩阵乘法,本章在此总结一下MPI的矩阵乘法使用。 使用简单的MPI_Send和MPI_Recv实现 使用较高级的MPI_Scatter和MPI_Gather...
  • 在科学与工程计算的许多问题中, 矩阵乘积是最基本的算法之一。在分布存储并行机上的经典矩阵乘积算法主要有1969年Cannon提出的二维mesh 上的矩阵乘积算法和1987年Fox等提出的“广播-乘积-滚动”算法。 1994年Choi ...
  • 矩阵相乘并行设计

    2017-11-06 09:22:43
    矩阵相乘并行程序设计与实现,可以实现多个线程,基于MPI平台
  • 并行计算——OpenMP加速矩阵相乘

    千次阅读 2018-10-22 21:47:22
     并行计算的一个比较麻烦的问题就是数据同步,我们使用经典的矩阵相乘来绕开这些不是本文关心的问题。 环境和结果  我的测试环境是: CPU:Intel Core i7 4790。主频3.6G, 4核8线程 ,8MB三级缓存,集成...
  • 为了完成高性能计算课程作业,学习了一下以前从来没有接触过的MPI、Pthread和OpenMP,现将MPI实现矩阵乘法的过程记录如下: 运行环境:win10系统 cpu:AMD E2-3800 APU with Radeon(TM) HD Grapics 1.30GHZ 四核 四...
  • MPI多进程并行计算矩阵乘法实现

    万次阅读 2014-11-15 22:02:05
    MPI多进程并行计算矩阵乘法实现
  • Pthreads矩阵乘法实现

    千次阅读 2015-05-21 15:55:00
    其实与MPI矩阵乘法的实现比起来,Pthreads要简单很多,主要是由于MPI是基于进程的通信,而Pthreads和之后要提到的OpenMP则是基于线程的通信,从代码量和实现方式相比较来看,线程的通信似乎是要更简单一些,将矩阵...
  • mpi.h&gt; #include&lt;stdlib.h&gt; #include&lt;omp.h&gt; #define N 100 //time_t start,end;//开始和结束时间 double start,end; int main(int argc,char* argv[]) { ...
  • 矩阵相乘的OpenMP实现

    千次阅读 2018-10-03 00:22:48
    矩阵相乘的OpenMP实现 OpenMP简介 OpenMP是基于共享内存的编程,不同于MPI,因为是共享内存,所以它不需要将计算结果丢来丢去共享。事实上,我们可以用很少的编译指导语句实现并行,而不需要关心底层的操作。 举个...
  • mpi函数C++形式的原型

    2011-09-01 15:17:43
    网上多mip的c函数,这是我收集的c++函数原型
  • 对于中国象棋的博弈树怎样用MPI+OpenMP混合编程模型分解,MPI是进程级的,OpenMP是线程级的,两者混合可以实现博弈树的并行搜索吗
  • 因为MapReduce是第一个在大规模集群上运行的不同于MPI的并行计算框架,对于基于RDD模型的Spark实现具有很强的参考价值,因此我们决定先参考HAMA的实现方式在Spark上试验性的尝试矩阵乘法算法的实现,然后观测一下...
  • 矩阵乘法并行优化

    千次阅读 2016-01-13 15:26:16
    http://blog.csdn.net/realxie/article/details/7260072

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 473
精华内容 189
关键字:

mpi矩阵向量相乘