用一上午的时间,用MPI编写了高斯消去法解线性方程组。这次只是针对单线程负责一个线程方程的求解,对于超大规模的方程组,需要按行分块,后面会在这个基础上进行修改。总结一下这次遇到的问题:

(1)MPI_Allreduce()函数的使用;

(2)MPI_Allgather()函数的使用;

(3)线程之间不使用通信函数进行值传递(地址传递)是没有办法使用其他线程的数据,这是设计并行程序中最容易忽视的一点。

 #include "stdio.h"
#include "mpi.h"
#include "malloc.h" #define n 4
#define BLOCK_LOW(id,p,n) ((id) * (n)/(p))
#define BLOCK_HIGH(id,p,n) (BLOCK_LOW((id)+1,p,n)-1)
#define BLOCK_SIZE(id,p,n) (BLOCK_LOW((id)+1,p,n)-BLOCK_LOW((id),p,n))
#define BLOCK_OWNER(index,p,n) (((p) * ((index)+1)-1)/(n))
#define MIN(a,b) ((a)<(b)?(a):(b))
int NotIn(int id,int *picked);
struct {
double value;
int index;
}local,global; int main(int argc,char *argv[])
{
int id,p;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&p); //double a[n][n+1] = {{4,6,2,-2,8},{2,0,5,-2,4},{-4,-3,-5,4,1},{8,18,-2,3,40}};
double a[n][n+] = {{,,-,,},{,-,,-,},{,,-,,-},{,,-,,}}; int i,j;
int index; int *picked;
picked = (int *)malloc(sizeof(int) * n); //记录已被选中的行
for(i=;i<n;i++)
picked[i] = -; for(i=;i<n;i++)
{ if(NotIn(id,picked)) //判断该行是否已被选中,没有选择则进行下一步
{
local.value = a[id][i];
local.index = id;
}
else
{
local.value = -; //假设各个参数最小值不小于-100
local.index = id;
} MPI_Allreduce(&local,&global,,MPI_DOUBLE_INT,MPI_MAXLOC,MPI_COMM_WORLD); // 归约最大的值,并存入到global中
// printf(" i = %d,id =%d,value = %f,index = %d\n",i,id,global.value,global.index);
picked[i] = global.index; if(id == global.index)
{
MPI_Bcast(&global.index,,MPI_INT,id,MPI_COMM_WORLD);
} MPI_Allgather(&a[id][],n+,MPI_DOUBLE,a,n+,MPI_DOUBLE,MPI_COMM_WORLD);
//每个线程解决的是对应行的求解,例如:线程号为0的线程仅得到0行的解,但是第1行的改动,0线程没有办法得到,只有1线程自己才知道,所以需要使用MPI_Allg ather()函数进行去收集,并将结果存入到各个线程中,最后各个线程得到a为最新解 if(NotIn(id,picked))
{
double temp = - a[id][i] / a[picked[i]][i];
for(j=i;j<n+;j++)
{
a[id][j] += a[picked[i]][j] * temp;
}
} } MPI_Gather(&a[id][],n+,MPI_DOUBLE,a,n+,MPI_DOUBLE,,MPI_COMM_WORLD); //
//解上三角形,因为都需要使用到上一线程的数值,这样造成通信开销增大,不如直接让单一线程去求解上三角形矩阵
if(id == )
{
for(i=;i<n;i++)
{
for(j=;j<n+;j++)
{
printf("%f\t",a[i][j]);
}
printf("\n");
} /* for(i=0;i<n;i++)
{
printf("%d\t",picked[i]);
}
*/
double *x;
x = (double *)malloc(sizeof(double) * n);
for(i=(n-);i>=;i--) //这里还有一个小插曲,在这一行的后面加了”;“,导致i变成-1,使程序报错 Segmentation fault (11),在Linux下经常遇到这个问题,大体2点:1.占用的内存超出了系统内存 2.循环中,数组越界
      {
//printf("\n n =%d,i = %d",n,i);
x[i] = a[picked[i]][n] / a[picked[i]][i];
printf("x[%d] = %f\n",i,x[i]);
for(j=;j<n;j++)
{
a[picked[j]][n] = a[picked[j]][n] - x[i] * a[picked[j]][i] ;
a[picked[j]][i] = ;
} }
} MPI_Finalize();
return ;
} int NotIn(int id,int *picked)
{
int i;
for(i=;i<n;i++)
{
if(id == picked[i])
{
return ;
}
}
return ;
}

高斯消去法解线性方程组(MPI)的更多相关文章

  1. 【matlab】MTATLAB解线性方程组

    在求解线性方程组时,会遇到以下几种情形:定解方程组.不定方程组.超定方程组.奇异方程组. 首先以定解线性方程组为例: format rat  化成分数 format short >> A= ...

  2. Eigen解线性方程组

    一. 矩阵分解: 矩阵分解 (decomposition, factorization)是将矩阵拆解为数个矩阵的乘积,可分为三角分解.满秩分解.QR分解.Jordan分解和SVD(奇异值)分解等,常见 ...

  3. 《Fluid Engine Development》 学习笔记1-求解线性方程组

    我个人对基于物理的动画很感兴趣,最近在尝试阅读<Fluid Engine Development>,由于内容涉及太多的数学问题,而单纯学习数学又过于枯燥,难以坚持学习(我中途放弃好多次了) ...

  4. Widget Factory (高斯消元解线性方程组)

    The widget factory produces several different kinds of widgets. Each widget is carefully built by a ...

  5. 计算方法 -- 解线性方程组直接法(LU分解、列主元高斯消元、追赶法)

    #include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> ...

  6. 题解【AcWing883】高斯消元解线性方程组

    题面 高斯消元模板题. 这里直接讲述一下高斯消元的算法流程: 枚举每一列 \(c\): 找到第 \(c\) 列绝对值最大的一行: 将这一行换到最上面: 将该行的第一个数变成 \(1\): 将下面所有行 ...

  7. MATLAB矩阵的LU分解及在解线性方程组中的应用

    作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 三.实验程序 五.解答(按如下顺序提交电子版) 1.(程序) (1)LU分解源程序: function [ ...

  8. [CF917D]Stranger Trees[矩阵树定理+解线性方程组]

    题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...

  9. 「c++小学期」实验题目及代码

    面向对象编程的C++,和平时做题用的C++还是有差距的.实验的题目都是小题目,就都做一下吧.(没放代码的为要验收的 实验一 简单C++程序设计 1.  猜价格游戏 编写C++程序完成以下功能: (1) ...

随机推荐

  1. win10提示 磁盘包含不是“PARTITION_BASIC_DATA_GUID"类型的分区

    在win10创建新的磁盘分区的时候,有时候会提示 磁盘包含不是"PARTITION_BASIC_DATA_GUID"类型的分区 如果你试了其他方法都不凑效,那么看看你已经有几个盘( ...

  2. php-max_execution_time

    有时候我们需要跑一个脚本,比如执行几十万个请求.如果你使用浏览器,请求服务器.这时就会出现执行中断,因为超时了.我们可以通过下面的方式: 修改php.ini配置文件 max_execution_tim ...

  3. Laravel5使用ElasticSearch

    https://blog.csdn.net/qq_16829085/article/details/80725125 安装elasticsearch和ik插件 (elasticsearch的使用需要配 ...

  4. [转]什么是CNN、RNN、LSTM

    . 全连层 每个神经元输入: 每个神经元输出: (通过一个激活函数) 2. RNN(Recurrent Neural Network) 与传统的神经网络不通,RNN与时间有关. 3. LSTM(Lon ...

  5. 安装vue-cli和安装nuxt

    安装vue-cli:1.npm install vue-cli -g2.vue install webpack 项目名3.cd 项目名4.npm install5.npm i webpack-dev- ...

  6. H3C IGP与EGP

  7. java 综合示例代码

    package javaenhance.src.cn.itcast.day3; import java.lang.reflect.Constructor; import java.lang.refle ...

  8. slot的使用方法

    参考链接:https://www.cnblogs.com/loveyt/p/9946450.html 插槽的使用其实是很简单,你只需明白以下两点,就很容易理解. 1.插槽是使用在子组件中的, 2.插槽 ...

  9. SVG基础绘图实例

    SVG可缩放矢量图(Scalable Vector Graphics),是使用 XML 来描述二维图形和绘图程序的语言,图像在放大或改变尺寸的情况下其图形质量不会有所损失,是万维网联盟的标准. 下面整 ...

  10. Linux 内核bin+attribute 结构二进制属性

    sysfs 惯例调用所有属性来包含一个单个的人可读文本格式的值. 就是说, 只是偶然地很 少需要来创建能够处理大量二进制数据的属性. 这个需要真正地只出现在必须传递数据, 不可动地, 在用户空间和设备 ...