简述

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

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

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

这里的方法二,

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

数学表达式

解法一的数学表达

Thread(i):∑j=0n−1Aij∗XjThread(i):\sum_{j=0}^{n-1}{A_{ij}*X_j}Thread(i):j=0∑n−1​Aij​∗Xj​
result={j∈{0,1,..,n−1}∣Thread(j)}result = {\{j\in\{0,1,..,n-1\}| Thread(j)\}}result={j∈{0,1,..,n−1}∣Thread(j)}

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

解法二的数学表达式

Thread(i):{j∈{0,1,..,n−1}∣Aij∗Xi}Thread(i):{\{j\in\{0,1,..,n-1\}| A_{ij}*X_i\}}Thread(i):{j∈{0,1,..,n−1}∣Aij​∗Xi​}

result=∑i=0n−1Thread(i)result = \sum_{i=0}^{n-1}{Thread(i)}result=i=0∑n−1​Thread(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;// initializeif (my_rank == 0) {a = new double*[N];for (int i = 0; i < N; ++i) {a[i] = new double[N];}// read afor (int i = 0; i < N; ++i)for (int j = 0; j < N; ++j)cin >> a[j][i]; // transpose ks = new double[N];// read ksfor (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 NMPI_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;// finalizeMPI_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编程】矩阵向量乘法--解法二(高性能计算)相关推荐

  1. 【MPI编程】矩阵向量乘法--解法三(子矩阵块分解)【高性能计算】

    简述 子矩阵分解,就是说,将原来的矩阵给分解为更小的矩阵块. 让所有的线程都共享有向量(但不共享矩阵) 为了试验简单,这里做了几个简单的假设 矩阵为方阵(n*n) comm_sz(线程数量)和n满足下 ...

  2. MPI实现矩阵向量乘法

    (1)问题 MPI实现矩阵向量:Ab的乘积.其中A:100行100列,b为列向量. (2)思路 将所有进程分为两部分,rank=0的进程为master节点,其余进程为worker节点. master节 ...

  3. 【MPI】矩阵向量乘法

    输入作乘法的次数K 然后输入矩阵和向量的维度n 然后输入一个n维向量 然后输入K个n阶方阵 程序会给出该向量连续与此K个方阵做乘法后的结果 主要用了MPI_Gather, MPI_Allgather, ...

  4. 编写一个完整的矩阵向量乘法的MPI编程代码

    答:以下是一个完整的矩阵向量乘法的MPI编程代码:#include <stdio.h> #include <stdlib.h> #include <mpi.h>in ...

  5. 【MPI编程】任意数节点的树形求和(高性能计算)

    简述 之前写过一个只能在2幂次数的节点环境下使用的树形结构求和 [MPI编程]2幂节点的树形求和(高性能计算) 稍微修改了一下对应代码,就可以使用了.其实就是在逻辑上扩充一下为2的幂数.也就是说接受节 ...

  6. MPI矩阵向量乘法代码《并行程序设计导论》

    本文所写内容是根据<并行程序设计导论>第三章中的矩阵向量乘法代码总结而来的完整代码. 完整代码如下Mat_vect_mult.c #include<stdio.h> #incl ...

  7. CUDA编程--并行矩阵向量乘法【80+行代码】

    简述 矩阵向量乘法. 读取文件data.txt 并输入到output.txt文件中 用typedef方便的修改数据类型(要是写成模板也是可以的) 代码 #include "cuda_runt ...

  8. MPI编程及性能优化

    第1节 MPI简介 1.1 MPI及其历史 与OpenMP相似,消息传递接口(Message Passing Interface,简称MPI)是一种编程接口标准,而不是一种具体的编程语言.该标准是由消 ...

  9. 【HNU分布式与云计算系统】MPI实现矩阵乘矩阵运算

    MPI实现矩阵乘矩阵运算 实验环境 操作系统:Ubuntu 20.04 编程语言:C++ 实验原理 什么是MPI MPI是一个跨语言的通讯协议,用于编写并行计算机.支持点对点和广播.MPI是一个信息传 ...

最新文章

  1. vim文本编辑器使用技巧
  2. 如何打开python的交互窗口-使用Python显示图形交互窗口
  3. 计算机视觉与深度学习 | 像素坐标转相机坐标转世界坐标,求R,t(附C++和Python源代码)
  4. 腾讯急招多名.NET Core,5年30k!
  5. Python学习笔记:函数(Function)
  6. oracle归档日志太多(ORA-00257: archiver error. Connect internal only, until freed)错误的处理方法
  7. mac文件丢失,苹果电脑有没有好用的恢复软件?
  8. 简明Python3教程 1.翻译
  9. Ad-Hoc(点对点)模式
  10. matlab绘制雷达图
  11. 设计模式-单一职责原著
  12. rack puma rails
  13. 隔行插入行——《超级处理器》应用
  14. 鹰迪电商|抖音发布作品定位可以随便设置吗?
  15. 内存系列三:内存初始化浅析
  16. 关于iPhone改变的一切,这也许是史上最详细的盘点
  17. c语言报错(二)expected initializer before “int“
  18. 【SF08】:经典KD指标另类使用有奇效,股指商品双版本策略;
  19. 干货 | 万字长文详解携程酒店订单缓存 存储系统升级实践
  20. android计算器功能实现,在android中利用 studio实现一个简单的计算器功能

热门文章

  1. Ubuntu下安装星际译王
  2. 幻方加密代码——自动生成幻方密钥方法,罗伯法单偶数阶的解法代码基于python
  3. js:使用amaze select插件
  4. 大数据技术怎么自学?大数据开发如何自学?
  5. python爬取选股宝(https://xuangubao.cn)之二度尝试
  6. windows用ffmpeg将flv视频转换为mp4
  7. 百度网盘mac损害计算机,Mac 电脑百度网盘一直闪退怎么办?解决办法
  8. 【微信早安定时推送3.0最牛版】微信消息推送后 可提醒可顶置,聊天框名称,头像都可修改~
  9. Go GUI---lxn/walk 自带demo学习---16.notifyicon通知图标
  10. mpvue微信小程序动画_mpvue 与微信小程序的火花