如何在C中使用MPI_Scatterv和置换

时间:2017-01-07 15:18:50

标签: c mpi openmpi

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>

int size;

typedef struct process_struct
{
    int start;
    int end;
} process_tag;

int main(int argc, char **argv)
{   //array size
    size=11;

    int rc, myrank, world_size;
    rc = MPI_Init(&argc, &argv);
    if (rc != MPI_SUCCESS) {
        printf ("Error starting MPI program\n");
        MPI_Abort(MPI_COMM_WORLD, rc);
    }
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int i, j;

    int process_num=4;
    int processs_i;
    int start, end;

    double **a = malloc(size*sizeof(double*));
    if (a == NULL) { printf("malloc failed\n"); return 1; }

    for (i = 0;  i < size;  i++) {
        a[i] = malloc(size*sizeof(double));
        if (a[i] == NULL) { printf("malloc failed\n"); return 1; }
    }
    //initialize array "a"
    a=ini(a);

    if(myrank == 0 ) {
        printarray(a,size);
    }

    // store starting row and ending row for each process
    process_tag process[process_num];

    int chunk_size = (size - 2 )  / process_num ;
    int remain = (size - 2) - chunk_size * process_num ;

    start = 1;
    end = 1;
    int process_i =0;

    while(start < size) {

        start = end;
        end = start + chunk_size;

        if (remain > 0) {
            end++;
            remain--;
        }

        process[process_i].start = start;
        process[process_i].end = end;
        process_i++;

    }

    int send_count[process_num];
    for (process_i = 0; process_i < process_num; process_i++) {
        send_count[process_i] = process[process_i].end - process[process_i].start;
    }

    int receive_count = send_count[myrank];

    int *displs = malloc(sizeof(int)*size);
    int sum =1;
    for (i = 0; i < process_num; i++) {

        displs[i] = sum;
        sum += send_count[i];

    }

    double **blocal;

    blocal = malloc(receive_count*sizeof(double*));
    if (blocal == NULL)
        { printf("malloc failed\n"); return 1; }

    for (i = 0;  i < size;  i++) {
        blocal[i] = malloc(size*sizeof(double));
        if (blocal[i] == NULL)
            { printf("malloc failed\n"); return 1; }
    }

    MPI_Scatterv(a, send_count, displs, MPI_DOUBLE, blocal,
        receive_count, MPI_DOUBLE, 0, MPI_COMM_WORLD);


    printarray(blocal,receive_count);
    printf("from rank %d  \n", myrank);
}

输出是:

array a is 
1.000000 3.700000 2.000000 6.000000 5.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 8.200000 3.000000 7.000000 3.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 6.000000 9.000000 1.000000 6.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 5.000000 1.000000 3.000000 4.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 4.500000 6.000000 4.000000 7.600000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000

blocal from rank 0
1.000000 8.200000 3.000000 7.000000 3.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 6.000000 9.000000 1.000000 6.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 5.000000 1.000000 3.000000 4.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000

blocal from rank 1
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

blocal from rank 2
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

blocal from rank 3
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

我想将11 * 11 sendbuf数组“a”的元素分散到数组“blocal”(receivebuf)。
我想要实现的是进程0的blocal获得第1行到第3行,进程1获得第4行到第5行,进程2获得第6行到第7行,进程3获得第8行到第9行。忽略第0行和第10行。
但是在我的输出中,只有进程0从数组“a”获得了子数组 有人能在我的代码中发现任何错误吗?我认为问题可能是流离失所。

0 个答案:

没有答案