用一上午的时间,用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. 洛谷 1372 又是毕业季I

    题目背景 “叮铃铃铃”,随着高考最后一科结考铃声的敲响,三年青春时光顿时凝固于此刻.毕业的欣喜怎敌那离别的不舍,憧憬着未来仍毋忘逝去的歌.1000多个日夜的欢笑和泪水,全凝聚在毕业晚会上,相信,这一定 ...

  2. 2019-11-17-dotnet-C#-获取本机外网-IP-地址

    title author date CreateTime categories dotnet C# 获取本机外网 IP 地址 lindexi 2019-11-17 16:38:10 +0800 201 ...

  3. rowStyle设置Bootstrap Table行样式

    日常开发中我们通常会用到隔行变色来美化表格,也会根据每行的数据显示特定的背景颜色,如果库存低于100的行显示红色背景 CSS样式 <style> .bg-blue { background ...

  4. poj 1279 Art Gallery (Half Plane Intersection)

    1279 -- Art Gallery 还是半平面交的问题,要求求出多边形中可以观察到多边形所有边的位置区域的面积.其实就是把每一条边看作有向直线然后套用半平面交.这题在输入的时候应该用多边形的有向面 ...

  5. Unity5.6.4f1 配置WebGL教程

    Unity 5.6.4f1 发布WebGL的配置教程 步骤一:先查看自带的Unity是否yi配置好WebGL的项,若无,则可遵循以下教程来设置 步骤二:下图是我已经设置好的,未设置好的状态是,有个Op ...

  6. Python--day70--ORM多对多的三种方式

  7. 2019-1-16-git-subtree-pull-错误-Working-tree-has-modifications

    title author date CreateTime categories git subtree pull 错误 Working tree has modifications lindexi 2 ...

  8. 【知识小结】Git 个人学习笔记及心得

    https://mp.weixin.qq.com/s/D96dXYfu3XAA4ac456qo0g git架构 工作区:就是你在电脑里能看到的目录. 版本库:工作区有一个隐藏目录.git,,而是Git ...

  9. HTML5中Js多线程编程

    Web Worker Web Worker是HTML5提出的新标准,为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行.在主线程运行的同时,Work ...

  10. Hex编码

    编码原理 Hex编码就是把一个8位的字节数据用两个十六进制数展示出来,编码时,将8位二进制码重新分组成两个4位的字节,其中一个字节的低4位是原字节的高四位,另一个字节的低4位是原数据的低4位,高4位都 ...