用一上午的时间,用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. <%@ include file=""%>与<jsp:include page=""/>两种方式的作用以及传值

      一:使用    1.include指令: 1 <%@include file="文件的绝对路径或者相对路径"%> file属性是必填的(绝对或相对路径),但它不支持 ...

  2. hdu 3264 Open-air shopping malls(圆相交面积+二分)

    Open-air shopping malls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  3. Springboot2 Logback mybatis 打印sql执行语句

    把这个加入到logback.xml 中就可以打印mysql的日志了 <logger name="jdbc.sqltiming" level="debug" ...

  4. mysql基础(库、表相关)

    一. mysql支持的数据类型 1.1 mysql支持的数字类型: TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 768,32 767 ...

  5. 2018-8-10-win10-uwp-调试软件启动

    title author date CreateTime categories win10 uwp 调试软件启动 lindexi 2018-08-10 19:16:51 +0800 2018-03-0 ...

  6. H3C 环路避免机制四:定义最大值

  7. laravel5数据库配置及其注意事项

    今天分享一个Laravel5数据库配置上的坑. Laravel5作为一套简洁.优雅的PHP Web开发框架(笑),唯一不足的一点就是中文手册或者说是资料比较少,虽然现在很多大神也开始普及这些东西,但是 ...

  8. windows常用命令行命令

    https://blog.csdn.net/qq_32451373/article/details/77743869 打开"运行"对话框(Win+R),输入cmd,打开控制台命令窗 ...

  9. Linux 内核使用 USB 数据函数

    USB 核心中的几个帮忙函数可用来从所有的 USB 设备中存取标准信息. 这些函数不能从 中断上下文或者持有自旋锁时调用. 函数 usb_get_descriptor 获取指定的 USB 描述符从特定 ...

  10. es6笔记 day2---字符串模板及字符串新增

    字符串连接案例 注意:引号变了,为键盘数字1旁边的飘花键 以前的老写法是在字符串中加入“+”号,给几个字符串给串起来,那种写法是要死人的. 现在只需加上一对``即可将字符串连接起来 --------- ...