zoukankan      html  css  js  c++  java
  • 【MPI】矩阵向量乘法

    输入作乘法的次数K

    然后输入矩阵和向量的维度n

    然后输入一个n维向量

    然后输入K个n阶方阵

    程序会给出该向量连续与此K个方阵做乘法后的结果

    主要用了MPI_Gather, MPI_Allgather, MPI_Bcast, MPI_Scatter 等

    注意printf在终端中打印的时机会很玄学 往往会在程序完全执行完毕之后才会打印

    注意 本程序将矩阵的所有行划分成一些段,分别分配给各个进程 仍然没有处理进程数无法整除维度n的情况

    typedef long long __int64;
    #include "mpi.h"
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int main(int argc, char* argv[]){
        int my_rank=0, comm_sz=0, local_int=0, total_int=0;
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
        int n,zongci;
        int* x;
        if(my_rank==0){
            scanf("%d%d",&zongci,&n);
        }
        MPI_Bcast(&zongci,1,MPI_INT,0,MPI_COMM_WORLD);
        MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
        x=new int[n];
        if(my_rank==0){
            for(int i=0;i<n;++i){
                scanf("%d",&x[i]);
            }
        }
        MPI_Bcast(x,n,MPI_INT,0,MPI_COMM_WORLD);
        if(my_rank==0){
            printf("第0次与%d*%d矩阵相乘后的x向量:
    ",n,n);
            for(int i=0;i<n;++i){
                printf("%d
    ",x[i]);
            }
            puts("");
        }
        for(int ci=1;ci<=zongci;++ci){
            int* local_A=new int[n*n/comm_sz];
            int* A=new int[n*n];
            if(my_rank==0){
                for(int i=0;i<n;++i){
                    for(int j=0;j<n;++j){
                        scanf("%d",&A[i*n+j]);
                    }
                }
                MPI_Scatter(A,n*n/comm_sz,MPI_INT,local_A,n*n/comm_sz,MPI_INT,0,MPI_COMM_WORLD);
                delete[] A;
            }
            else{
                MPI_Scatter(A,n*n/comm_sz,MPI_INT,local_A,n*n/comm_sz,MPI_INT,0,MPI_COMM_WORLD);
            }
            int* local_x=new int[n/comm_sz];
            for(int i=0;i<n/comm_sz;++i){
                local_x[i]=0;
                for(int j=0;j<n;++j){
                    local_x[i]+=local_A[i*n+j]*x[j];
                }
            }
            if(ci<zongci){
                MPI_Allgather(local_x,n/comm_sz,MPI_INT,x,n/comm_sz,MPI_INT,MPI_COMM_WORLD);
            }
            else{
                MPI_Gather(local_x,n/comm_sz,MPI_INT,x,n/comm_sz,MPI_INT,0,MPI_COMM_WORLD);
            }
            if(my_rank==0){
                printf("第%d次与%d*%d矩阵相乘后的x向量:
    ",ci,n,n);
                for(int i=0;i<n;++i){
                    printf("%d
    ",x[i]);
                }
                puts("");
            }
            delete[] local_x;
        }
        delete[] x;
        MPI_Finalize();
        return 0;
    }
  • 相关阅读:
    列表标签
    超链接标签
    HTML:如何把一个无序列表转换成横向菜单
    window界面控制
    C++文件读写
    宽度,对齐方式的设置
    取出一个整数的每一位
    求两个数的最大公约数
    判断素数
    天才ACM ---待复习标志
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/8144458.html
Copyright © 2011-2022 走看看