Hi all,

I observed non-consistent behaviors for the lock functions when applied to 
windows either created using MPI_Win_create or using 
MPI_Win_allocate/MPI_Win_allocate_shared.

I am using openmpi 1.8.4. A sample of the code is joined to this mail.

1- Locking a window created using allocate functions.

As explained by Nathan Hjelm, the MPI_MODE_NOCHECK assert had a bug in its 
path, so I use 0 instead.

In my tests, each process use the lock functions as follows, first a 
lock/unlock for read then a lock/unlock for write, nothing is done between 
lock/unlock but it does not change the behavior:

-----
// Lock for read (local rank)
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win_shared);
MPI_Win_unlock(rank, win_shared);

// Lock for write (local rank)
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win_shared);
MPI_Win_unlock(rank, win_shared);
-----

This works fine.

2- Locking a window created using MPI_Win_create.

In this case, the same code ...

-----
// Lock for read (local rank)
MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
MPI_Win_unlock(rank, win);

// Lock for write (local rank)
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win);
MPI_Win_unlock(rank, win);
-----

... freezes when entering the lock for write (it happens for all processes)

Further tests show that it works fine when:

- the MPI_MODE_NOCHECK assert is used
- the locks are applied to non-local rank
- the exclusive lock is done before the shared lock

In this last case, if I call a third lock with MPI_LOCK_EXCLUSIVE option, it 
works also.

Maybe, I misunderstand something :-/ ! 

Thanks for your help :-) !

Cheers,

Thibaud.

-------------------------------------------------
Ingénieur d'Expérimentation et de Développement
Inria CRISAM
2004, route des lucioles
06902 Sophia Antipolis
FRANCE
+33 4 92 38 50 03
// Version: $Id$
// 
// 

// Commentary: 
// 
// 

// Change Log:
// 
// 

// Code:

#include "mpi.h"
#include <iostream>

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

    int cap = 11;
    int objectSize = sizeof(int);
    int buffer_size = cap * objectSize;

    // Shared window
    int *array = NULL;
    MPI_Win win_shared;
    MPI_Win_allocate_shared(buffer_size, objectSize, MPI_INFO_NULL, MPI_COMM_WORLD, &array, &win_shared);
    
    // Classic window
    int *buffer = NULL;
    MPI_Alloc_mem(buffer_size, MPI_INFO_NULL, &buffer);
    MPI_Win win;
    MPI_Win_create(buffer, buffer_size, objectSize, MPI_INFO_NULL, MPI_COMM_WORLD, &win);

    int size;
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    MPI_Barrier(MPI_COMM_WORLD);

    if (rank == 0) {

        char version[MPI_MAX_LIBRARY_VERSION_STRING];
        int len;
        MPI_Get_library_version(version, &len);
        std::cout << version << std::endl;

    }

    MPI_Barrier(MPI_COMM_WORLD);

    {
        // Locking shared window
            
        std::cout << "Shared Window: Read locking for rank = " << rank << std::endl;

        MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win_shared);
        MPI_Win_unlock(rank, win_shared);

        std::cout << "Shared Window: Write locking for rank = " << rank << std::endl;
            
        MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win_shared);
        MPI_Win_unlock(rank, win_shared);
    }

    std::cout << "Rank " << rank << " has done for shared window"<< std::endl;

    {
        // Locking classic window
        
        std::cout << "Classic Window: Read locking for rank = " << rank << std::endl;
        
        MPI_Win_lock(MPI_LOCK_SHARED, rank, 0, win);
        MPI_Win_unlock(rank, win);

        std::cout << "Classic Window: Write locking for rank = " << rank << std::endl;
        
        MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, 0, win);
        MPI_Win_unlock(rank, win);
    }

    std::cout << "Rank " << rank << " has done for classic window."<< std::endl;

    
    MPI_Win_free(&win);
    MPI_Free_mem(buffer);
    
    MPI_Win_free(&win_shared);

    MPI_Finalize();

    return 0;
}

// 
// main.cpp ends here

Reply via email to