2

The following code creates a window in process 0 (master) and the other processes put some values in it and I'm trying to get the window of the master from other processes each time to print it but I'm getting totally confusing results. Here's the code:

int main ( int argc, char *argv[] )
{
    int id;
    MPI_Init ( &argc, &argv );

    MPI_Comm_rank ( MPI_COMM_WORLD, &id );
    MPI_Win win;

    if (id == 0)
    {
        int *arr;
        int in = 0;
        MPI_Alloc_mem(10 * sizeof(int), MPI_INFO_NULL, &arr);
        for(in = 1; in < 10; in++)
        {
            arr[in] = -1;
        }
        arr[0] = 0;
        MPI_Win_create(arr, 10 * sizeof(int), sizeof(int), MPI_INFO_NULL,MPI_COMM_WORLD, &win);
        int ready = 0;
        while (!ready)
        {
            MPI_Win_lock(MPI_LOCK_SHARED, 0, 0, win);
            ready = fini(arr);
            MPI_Win_unlock(0, win);
        }
        printf("All workers checked in using RMA\n");

        MPI_Win_free(&win);
        MPI_Free_mem(arr);

        printf("Master done\n");
    }
    else
    {
        int one = id;
        int *local;
        int i = 0;
        MPI_Alloc_mem(sizeof(int)*10, MPI_INFO_NULL, &local);
        MPI_Win_create(NULL, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);

        MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 0, 0, win);

        for(i = 0; i < 10; i++)
        {
            MPI_Get(&local[i], 1, MPI_INT, 0, i,1, MPI_INT, win);
        }

        printf("Worker before %d: ", id);
        pt(local); //Printing array "local"
        MPI_Put(&one, 1, MPI_INT, 0, id, 1, MPI_INT, win);
        for(i = 0; i < 10; i++)
        {
            MPI_Get(&local[i], 1, MPI_INT, 0, i,1, MPI_INT, win);
        }

        printf("Worker %d done: ", id);
        pt(local);

        MPI_Win_unlock(0, win);

        MPI_Win_free(&win);
    }

    MPI_Finalize ( );

    return 0;
}

int fini ( int table[] )
{
    int i = 0;

    while(i < 10)
    {
        if(table[i] == -1) return 0;
        i++;
    }

    return 1;
}

void pt(int t[])
{
    int i = 0;
    while(i < 10)
    {
        printf("%d ",t[i]);
        i++;
    }
    printf("\n");
}

This actually gives me the following result:

Worker before 4: 1152288776 32731 1152288776 32731 4 0 0 0 48 0 
Worker 4 done: 1152288776 32731 1152288776 32731 4 0 0 0 48 0 
Worker before 1: 1525372936 32743 1525372936 32743 4 0 0 0 48 0 
Worker 1 done: 1525372936 32743 1525372936 32743 4 0 0 0 48 0 
Worker before 3: 1422645256 32661 1422645256 32661 4 0 0 0 48 0 
Worker 3 done: 1422645256 32661 1422645256 32661 4 0 0 0 48 0 
Worker before 6: 1553508328 32675 34348016 0 0 0 33 0 1553508280 32675 
Worker 6 done: 1553508328 32675 34348016 0 0 0 33 0 1553508280 32675 
Worker before 5: -1745405976 32676 33995760 0 0 0 33 0 -1745406024 32676 
Worker 5 done: -1745405976 32676 33995760 0 0 0 33 0 -1745406024 32676 
Worker before 9: -990742552 32568 20737008 0 0 0 33 0 -990742600 32568 
Worker 9 done: -990742552 32568 20737008 0 0 0 33 0 -990742600 32568 
Worker before 2: 1455122440 32635 1455122440 32635 4 0 0 0 48 0 
Worker 2 done: 1455122440 32635 1455122440 32635 4 0 0 0 48 0 
Worker before 7: -1086933016 32650 18463728 0 0 0 33 0 -1086933064 32650 
Worker 7 done: -1086933016 32650 18463728 0 0 0 33 0 -1086933064 32650 
Worker before 8: 1328670696 32548 24464368 0 0 0 33 0 1328670648 32548 
Worker 8 done: 1328670696 32548 24464368 0 0 0 33 0 1328670648 32548

Can you please help me figure out what's wrong with my code ? Thanks.

edit : Apparently the problem is that MPI_Get doesn't fill the "local" buffer...

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
Reda94
  • 331
  • 4
  • 12
  • 1
    The problem is that `MPI_Get` is non-blocking and there is no guarantee that the transfer will complete before your start reading the values at the originator in the call to `pt()`. The MPI RMA semantics could be really confusing when one just starts using them. Let some of the RMA gurus here like @Jeff explain you how it should be done properly. – Hristo Iliev May 14 '16 at 07:54
  • @HristoIliev hi and thanks for your response, I hope the guru will help me figure out! :) I'm about to go crazy... – Reda94 May 14 '16 at 07:59
  • 1
    Add `MPI_Win_flush(0, win);` before the first call to `pt()` and move the second call to `pt()` after the `MPI_Win_unlock()` call and you'll get the desired behaviour. I'm not sure if `MPI_Put()` followed by an overlapping `MPI_Get()` is allowed without an intermediate synchronisation within a single access epoch (though it works with Open MPI on my desktop) and will therefore not write an answer. Also, use `MPI_Get(local, 10, MPI_INT, 0, 0, 10, MPI_INT, win);` instead of 10 separate calls to `MPI_Get()`. – Hristo Iliev May 14 '16 at 08:09
  • @HristoIliev Hey! I tried this and indeed it worked for me!! SO I have to do this everytime I execute an MPI_Get ? Thank you very much. – Reda94 May 14 '16 at 08:34
  • My understanding of MPI RMA is poor. As noted earlier, there are other people on SO that could provide more educated answers. – Hristo Iliev May 14 '16 at 08:40

0 Answers0