首页 > 解决方案 > 如何在根进程中将子二维数组 MPI_Gather 成一个连续的二维数组?

问题描述

    #include <stdlib.h>
    #include <stdio.h>
    #include "mpi.h"
    #include <time.h>
    #include <sys/time.h>

    #define N 8

    void print(int n, int m, double (*matrix)[m]){
        for(int i = 0; i<n; i++){
            for(int j = 0; j < m; j++)
                printf("%.0f\t", matrix[i][j]);
                printf("\n");       
        }
        printf("\n");
    }

    int main(int argc, char *argv[]){

        int nproc, rank, source, dest, rows, offset;  
        double (*matrix_A)[N] = NULL;
        double (*matrix_C)[N] = NULL; 
        
        MPI_Init(&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &nproc);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
            
        rows = N / nproc;
        double subA[rows][N];
        double subC[rows][N];
        double matrix_B[N][N];    
            
        //initializing matrix  B
        for(int i = 0; i < N; i++){
           for(int j = 0; j < N; j++){
               matrix_B[i][j] = 15+j+i;
           }
        }                 
        if(rank == 0){          
            
            //Allocating memory space for both matrix A and C that need to be only in the root process
            matrix_A = malloc(N * sizeof(*matrix_A));
            matrix_C = malloc(N * sizeof(*matrix_C));
            
            //initializing matrix A only in the root process
            for(int i = 0; i < N; i++){
            for(int j = 0; j < N; j++)
                matrix_A[i][j] = 10+j+i;        
        }                
        printf("\nProcess %d\n", rank);
        printf("----------\n");
        printf("Matrix A\n\n");    
        print(N, N, matrix_A);  
        printf("Matrix B\n\n");    
        print(N, N, matrix_B);      
        }               
        //Scattering matrix A into sub matrices in other processes
        MPI_Scatter(matrix_A, N*N/nproc, MPI_DOUBLE, subA, N*N/nproc, MPI_DOUBLE, 0, MPI_COMM_WORLD);    
        
        //multyplying each sub matrix with matrix B and saving the results in sub matrices C
        for(int k = 0; k < rows; k++){
            for(int i = 0; i < N; i++){
                for(int j = 0; j < N; j++)      
                    subC[k][i] += subA[k][j] * matrix_B[j][i];
            }
        }   

        printf("\nProcess %d\n", rank);
        printf("----------\n");
        printf("Matrix subA\n\n");
        print(rows, N, subA);
        printf("Matrix subC\n\n");
        print(rows, N, subC);
                
        //Gathering all sub matrices C of all processes into one big matrix C in the root process - DOESN'T WORK
        MPI_Gather(subC, N*N/nproc, MPI_INT, matrix_C, N*N/nproc, MPI_INT, 0, MPI_COMM_WORLD);       

        if(rank == 0){
                printf("\nProcess %d\n", rank);
            printf("----------\n");     
                printf("Matrix C\n\n"); 
            print(N, N, matrix_C);      
        }     
        MPI_Finalize();       
    }

上面的代码旨在使用 Scatter 和 Gather 函数将两个 NxN 矩阵相乘。一切都很好,直到收集部分。

我需要将矩阵 A 和矩阵 B 相乘。矩阵 A 和结果矩阵 C 只需要在根进程中,而 B 是全局矩阵。我已经设法将矩阵 A 分散到所有进程中的子矩阵中,与全局矩阵 B 相乘并将结果保存在子矩阵 C 中。但随后我尝试将 MPI_Gather 子矩阵与最终结果合并为一个矩阵 C 在根进程中,但由于某种原因,它不起作用。最后的矩阵 C 打印出错误的答案。

标签: cparallel-processingmpi

解决方案


推荐阅读