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