用一上午的时间,用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. hdu 4347 The Closest M Points(KD树)

    Problem - 4347 一道KNN的题.直接用kd树加上一个暴力更新就撸过去了.写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天. ...

  2. Android Studio(一):介绍、安装、配置

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  3. larave5.6 将Excel文件数据导入数据库代码实例

    <?php namespace App\Admin\Controllers; use App\AdminUser; use Illuminate\Http\Request; use Excel; ...

  4. PyCharm indexing goes into infinite loop pycharm 不同的indexing

    https://stackoverflow.com/questions/24955896/pycharm-indexing-goes-into-infinite-loop 5 1 I opened u ...

  5. laravel validate 设置为中文(验证提示为中文)

    把 resources\lang 下en 的文件夹 复制在同一目录并改名为 zn 把zn 中的 validation.php文件修改为 https://laravel-china.org/articl ...

  6. Python--day47--mysql执行计划

    1,什么是mysql执行计划? 让mysql预估执行操作:在要执行的语句前面加explain,就不会真的执行sql语句,只是给出了要执行的数据的情况,如大约有多少条,查询类型.

  7. [转]Spring 注解大全与详解

    Spring使用的注解大全和解释 注解 解释 @Controller 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类 ...

  8. C# json 转 xml 字符串

    本文告诉大家如何将 json 转 xml 或将 xml 转 json 字符串 首先需要安装 Newtonsoft.Json 库,打开 VisualStudio 2019 新建一个 dotnet cor ...

  9. 记录vue创建项目过程

    已经学过无数次,但是每次都忘记,毕竟脑容量太小了,每次都需要翻看原来项目和视频再次学习,所以以此文字形式记录下来,方便于下次使用观看 1.打开git,找到创建vue的文件夹(已经安装好git的,然后在 ...

  10. CF1214

    CF1214 C题WA3发的菜鸡还能涨分 A 发现货币面值都是倍数关系,直接暴力枚举第第一种换了多少个更新答案就好了 B 按照题意模拟 C 首先,左括号的数量不等于有括号的数量一定无解 想等的话在括号 ...