⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relaxation.c

📁 《并行算法实践》附带的mpi源程序
💻 C
字号:
#include "stdio.h"#include "stdlib.h"#include "mpi.h"#include "math.h"#define E 0.0001#define a(x,y) a[x*size+y]#define b(x) b[x]#define v(x) v[x]#define A(x,y) A[x*size+y]#define B(x) B[x]#define V(x) V[x]#define intsize sizeof(int)#define floatsize sizeof(float)#define charsize sizeof(char)int size,N;                                       /*size 为系数矩阵的大小,N为size+1*/int m;float *B;float *A;float *V;                                         /* store the value x */double starttime;double time1;double time2;int my_rank;int p;MPI_Status status;FILE *fdA,*fdB,*fdB1;void Environment_Finalize(float *a,float *b,float *v){    free(a);    free(b);    free(v);}/* * 函数名: main * 输入:argc为命令行参数个数; *       argv为每个命令行参数组成的字符串数组。 * 输出:返回0代表程序正常结束 */int main(int argc, char **argv){    int i,j,my_rank,group_size;    int k;    float *sum;    float *b;    float *v;    float *a;    float *differ;    float temp,w;    int iteration,total,loop;    int r,q;    loop=0;    total=0;    w=0.9;    MPI_Init(&argc,&argv);                        /* 启动计算 */    MPI_Comm_size(MPI_COMM_WORLD,&group_size);    /* 找进程数 */    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);       /* 找自己的id */    p=group_size;    if(my_rank==0)    {        starttime=MPI_Wtime();                    /* 开始计时 */        fdA=fopen("dataIn.txt","r");              /* 读入输入的系数矩阵A,b */        fscanf(fdA,"%d %d", &size, &N);        /*size 要求 size=N+1*/        if (size != N-1)        {            printf("the input is wrong\n");            exit(1);        }        /*分配系数矩阵A,与b,解x的空间*/        A=(float *)malloc(floatsize*size*size);        B=(float *)malloc(floatsize*size);        V=(float *)malloc(floatsize*size);        /*存放A,b,x*/        for(i = 0; i < size; i++)        {            for(j = 0; j < size; j++)            {                fscanf(fdA,"%f", A+i*size+j);            }            fscanf(fdA,"%f", B+i);        }        for(i = 0; i < size; i ++)        {            fscanf(fdA,"%f", V+i);        }        fclose(fdA);        /*打印A,b,x*/        printf("Input of file \"dataIn.txt\"\n");        printf("%d\t%d\n", size, N);        for(i = 0; i < size; i ++)        {            for(j = 0; j < size; j ++) printf("%f\t",A(i,j));            printf("%f\n",B(i));        }        printf("\n");        for(i = 0; i < size; i ++)        {            printf("%f\t", V(i));        }        printf("\n\n");        printf("\nOutput of result\n");    }                                             /* end of if (my_rank==0) */    MPI_Bcast(&size,1,MPI_INT,0,MPI_COMM_WORLD);  /* 广播size到所有进程*/    m=size/p;if (size%p!=0) m++;                  /* m为每个进程保留的行数 */    /*每个进程分配系数等的空间*/    v=(float *)malloc(floatsize*size);    a=(float *)malloc(floatsize*m*size);    b=(float *)malloc(floatsize*m);    sum=(float *)malloc(floatsize*m);    if (a==NULL||b==NULL||v==NULL)        printf("allocate space  fail!");    if (my_rank==0)    {        for(i=0;i<size;i++)            v(i)=V(i);    }    MPI_Bcast(v,size,MPI_FLOAT,0,MPI_COMM_WORLD); /* 将初始x广播到所有进程 */    /* 给进程分配A,b,和x初值*/    if (my_rank==0)    {        for(i=0;i<m;i++)            for(j=0;j<size;j++)                a(i,j)=A(i,j);        for(i=0;i<m;i++)            b(i)=B(i);    }    /* 将A,b和x初值分配到所有进程,每个进程分配m行 */    if (my_rank==0)                               /* 进程0将数据广播出去 */    {        for(i=1;i<p;i++)        {            MPI_Send(&(A(m*i,0)),m*size,MPI_FLOAT,i,i,MPI_COMM_WORLD);            MPI_Send(&(B(m*i)),m,MPI_FLOAT,i,i,MPI_COMM_WORLD);        }        free(A); free(B); free(V);    }    else                                          /* 其他进程接收数据A,b和x的初值*/    {        MPI_Recv(a,m*size,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD,&status);        MPI_Recv(b,m,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD,&status);    }    time1=MPI_Wtime();                            /* 取开始计算时间 */    /* 求每行主对角线右边的元素和 */    for(i=0;i<m;i++)                              /* 开始计算 */    {        sum[i]=0.0;        for(j=0;j<size;j++)        {            if (j>(my_rank*m+i))                sum[i]=sum[i]+a(i,j)*v(j);        }    }    while (total<size)                            /* total为迭代差小于E的x分量个数,当所有解即所有x分量的迭代差均小于E时,停止计算 */    {        iteration=0;                              /* iteration为各个process中迭代差小于E的x分量个数 */        total=0;        for(j=0;j<size;j++)                       /* 依次以第0,1, ..., n-1行为主行 */        {            r=j%m; q=j/m;            if (my_rank==q)                       /* 主行所在的处理器 */            {                temp=v(my_rank*m+r);                /*sum[j]累加上本进程中已算出的新的x项,这些新项的行号小于当前处理的行号*/                for(i=0;i<r;i++)                    sum[r]=sum[r]+a(r,my_rank*m+i)*v(my_rank*m+i);                /*计算新的x值*/                v(my_rank*m+r)=(1-w)*temp+w*(b(r)-sum[r])/a(r,my_rank*m+r);                if (fabs(v(my_rank*m+r)-temp)<E)  /*新旧值差小于E,累加iteration*/                    iteration++;                /*广播新的x值*/                MPI_Bcast(&v(my_rank*m+r),1,MPI_FLOAT,my_rank,MPI_COMM_WORLD);                sum[r]=0.0;                       /*当前行处理完毕后,sum清零,为下一次计算做准备*/                for(i=0;i<r;i++)                  /*本process中前面行的sum累加新x值项,为下一次计算累加对角元素左边的项*/                    sum[i]=sum[i]+a(i,my_rank*m+r)*v(my_rank*m+r);            }            else                                  /*非主行所在的处理器*/            {                                                  /*接收广播来的新x值*/                MPI_Bcast(&v(q*m+r),1,MPI_FLOAT,q,MPI_COMM_WORLD);                for(i=0;i<m;i++)                  /*累加新x值对应的项*/                    sum[i]=sum[i]+a(i,q*m+r)*v(q*m+r);            }        }        /* 求所有处理器中iteration值的和total并广播到所有处理器中 */        MPI_Allreduce(&iteration,&total,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD);        loop++;        if (my_rank==0)                           /* 打印每次迭代的total值 */            printf("%-2d th total vaule = %d\n",loop,total);    }                                             /* while */    time2=MPI_Wtime();                            /* 取结束时间 */    if (my_rank==0)                               /* 打印解x值以及运行、分配和计算时间 */    {        for(i = 0; i < size; i ++) printf("x[%d] = %f\n",i,v(i));        printf("\n");        printf("Iteration num = %d\n",loop);        printf("Whole running time    = %f seconds\n",time2-starttime);        printf("Distribute data time  = %f seconds\n",time1-starttime);        printf("Parallel compute time = %f seconds\n",time2-time1);    }    MPI_Barrier(MPI_COMM_WORLD);                  /* 同步所有进程 */    MPI_Finalize();                               /* 结束计算 */    Environment_Finalize(a,b,v);    return (0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -