【问题标题】:MPI Vector multiplicationMPI 向量乘法
【发布时间】:2016-07-18 21:02:28
【问题描述】:
#include<stdio.h>
#include<mpi.h>

int main()
{
        int a_r = 0, a_c = 0, v_s = 0, i = 0, rank = 0, size = 0;
        int local_row = 0, partial_sum = 0, sum = 0, j = 0;
        int my_first_ele = 0, my_last_ele = 0;
        int a[10][10], v[10], partial_mul[10] = {0}, mul[10] = {0};

        MPI_Init(NULL, NULL);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);

        if(rank == 0)
        {
                printf("Enter the row of array A: ");
                scanf("%d", &a_r);
                printf("Enter the column of array A: ");
                scanf("%d", &a_c);
                printf("Enter the array A: ");

                for(i = 0; i < a_r; i++)
                {
                        for(j = 0; j < a_c; j++)
                                scanf("%d", &a[i][j]);
                }

                printf("Enter the size of vector array: ");
                scanf("%d", &v_s);
                printf("Enter the vector array: ");
                for(i = 0; i < v_s; i++)
                {
                        scanf("%d", &v[i]);
                }

                MPI_Bcast(&a_r, 1, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(&a_c, 1, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(&v_s, 1, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(a, a_r*a_c, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(v, v_s, MPI_INT, 0, MPI_COMM_WORLD);

                local_row = a_r / size;
                my_first_ele = rank * local_row;
                my_last_ele = (rank+1) * local_row;

                if(a_c == v_s)
                {      
                        for(i = my_first_ele; i < my_last_ele; i++)
                        {
                                for(j = 0; j < a_c; j++)
                                {
                                        partial_mul[i] = partial_mul[i] + (a[i][j]*v[j]);
                                }
                        }
                        printf("\nPartial multiplication in Rank 0: \n");
                        for(i = my_first_ele; i < my_last_ele; i++)
                                printf("%d \n", partial_mul[i]);

                        MPI_Gather(partial_mul, local_row, MPI_INT, mul, local_row, MPI_INT, 0, MPI_COMM_WORLD);

                        printf("\n \nGlobal Multiplication: \n");
                        for(i = 0; i < a_r; i++)
                        {
                                printf("%d \n", mul[i]);
                        }
                }
                else
                        printf("\nCan't multiply. \n");
        }

        else
        {
                MPI_Bcast(&a_r, 1, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(&a_c, 1, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(&v_s, 1, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(a, a_r*a_c, MPI_INT, 0, MPI_COMM_WORLD);
                MPI_Bcast(v, v_s, MPI_INT, 0, MPI_COMM_WORLD);

                local_row = a_r / size;
                my_first_ele = rank * local_row;
                my_last_ele = (rank+1) * local_row;
                if(a_c == v_s)
                {     
                        for(i = my_first_ele; i < my_last_ele; i++)
                        {
                                for(j = 0; j < a_c; j++)
                                {
                                        partial_mul[i] = partial_mul[i] + (a[i][j]*v[j]);
                                }
                        }
                        printf("\nPartial multiplication in Rank %d: \n", rank);
                        for(i = my_first_ele; i < my_last_ele; i++)
                                printf("%d \n", partial_mul[i]);

                        MPI_Gather(partial_mul, local_row, MPI_INT, mul, local_row, MPI_INT, 0, MPI_COMM_WORLD);

                }
                else
                        printf("\nCan't multiply. \n");
        }
        MPI_FINALIZE();
}

上面的代码有问题。我的部分乘法值是正确的。但是在我的整体乘法中,我只能收集 ​​0 级元素,其余的值被打印为 0。任何人都可以解释什么问题。

【问题讨论】:

    标签: c mpi


    【解决方案1】:

    查看您的数据布局,我认为您误解了 MPI 中的数据结构:所有数据在每个等级中都是分开的,没有隐式共享或分发。您的向量 partial_sum 在每个等级上都是独立的,每个等级都有完整的 10 个元素。所以假设size=2,a_r=10和零初始化,计算后的内容会是这样的:

    • 排名 0:{x0,x1,x2,x3,x4,0,0,0,0,0}
    • 排名1:{0,0,0,0,0,x5,x6,x7,x8,x9}

    其中 x 是正确的计算值。 Gather 将从每个等级中收集第一个 local_row=5 元素,从而产生 {x0,x1,x2,x3,x4,0,0,0,0,0}。

    您可以通过添加正确的偏移量来解决这个问题:

    MPI_Gather(&partial_mul[my_first_ele], local_row, MPI_INT, mul, local_row, MPI_INT, 0, MPI_COMM_WORLD);
    

    但请不要那样做。相反,您应该重新考虑您的数据结构以真正分配数据,为向量/数组的每个部分保留正确的大小。要将部分数据发送到每个等级,请使用MPI_Scatter(与MPI_Gather 相反)。最困难的是得到正确的矩阵。 this excellent answer详细解释了这个。

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 1970-01-01
      • 2012-11-24
      • 2020-08-01
      • 2020-03-16
      • 2018-09-08
      • 2017-10-30
      • 2021-01-20
      • 2012-11-04
      相关资源
      最近更新 更多