[Mpi3-ft] Using MPI_Comm_shrink and MPI_Comm_agreement in the same application
Darius Buntinas
buntinas at mcs.anl.gov
Fri Apr 6 11:32:44 CDT 2012
Ignore the last email there were bugs, and the bcast should be in a while loop.
-d
do {
if (root) read_some_data_from_a_file(buffer);
do {
int val;
err = MPI_Bcast(buffer, .... ,root, comm);
if (err) {
val = FALSE;
MPI_Comm_agreement(comm, &val);
MPI_Comm_invalidate(comm);
MPI_Comm_shrink(comm, &newcomm);
MPI_Comm_free(&comm);
comm = newcomm;
} else {
val = TRUE;
MPI_Comm_agreement(comm, &val);
if (!val) {
MPI_Comm_shrink(comm, &newcomm);
MPI_Comm_free(&comm);
comm = newcomm;
}
} while (!val);
MPI_Comm_size(comm, size);
done = do_computation(buffer, size);
/* Let's agree for sure if we are done with the computation */
MPI_Comm_agreement(comm, &done);
while (!done);
MPI_Finalize();
On Apr 6, 2012, at 11:28 AM, Darius Buntinas wrote:
>
> Wouldn't you need to do something like this?
>
> -d
>
> do {
>
> if (root) read_some_data_from_a_file(buffer);
>
> err = MPI_Bcast(buffer, .... ,root, comm);
> if (err) {
> int val = FALSE;
> MPI_Comm_invalidate(comm);
> MPI_Comm_shrink(comm, &newcomm);
> MPI_Comm_free(&comm);
> comm = newcomm;
> MPI_Comm_agreement(comm, &val);
> } else {
> int val = TRUE;
> MPI_Comm_agreement(comm, &val);
> if (!val) {
> MPI_Comm_shrink(comm, &newcomm);
> MPI_Comm_free(&comm);
> comm = newcomm;
> }
> MPI_Comm_size(comm, size);
>
> done = do_computation(buffer, size);
>
> /* Let's agree for sure if we are done with the computation */
>
> MPI_Comm_agreement(comm, &done);
>
> while (!done);
>
> MPI_Finalize();
>
> On Apr 5, 2012, at 4:50 PM, David Solt wrote:
>
>> I have another question about MPI_Comm_agreement:
>>
>> If I want to do this:
>>
>> ....
>> do {
>>
>> if (root) read_some_data_from_a_file(buffer);
>>
>> err = MPI_Bcast(buffer, .... ,root, comm);
>> if (err) {
>> MPI_Comm_invalidate(comm);
>> MPI_Comm_shrink(comm, &newcomm);
>> MPI_Comm_free(&comm);
>> comm = newcomm;
>> }
>>
>> MPI_Comm_size(comm, size);
>>
>> done = do_computation(buffer, size);
>>
>> /* Let's agree for sure if we are done with the computation */
>>
>> MPI_Comm_agreement(comm, &done);
>>
>> while (!done);
>>
>> MPI_Finalize();
>>
>> This code can deadlock because some ranks may enter MPI_Comm_agreement while others detect an error in MPI_Bcast and call MPI_Comm_invalidate followed by MPI_Comm_shrink (assume that do_computation is really, really fast). The call to MPI_Comm_invalidate will not allow the processes that have already entered MPI_Comm_agreement to leave that call (P543L45: "Advice to users. MPI_COMM_AGREEMENT maintains its collective behavior even
>> if the comm is invalidated. (End of advice to users.)" ) and MPI_Comm_agreement cannot return an error due to the call to MPI_Comm_invalidate (P545L38: "This function must not return an error due to process failure (error classes MPI_ERR_PROC_FAILED and MPI_ERR_INVALIDATED)...") .
>>
>> This would not work:
>> ....
>> do {
>>
>> if (root) read_some_data_from_a_file(buffer);
>>
>> err = MPI_Bcast(buffer, .... ,root, comm);
>> if (err) {
>> MPI_Comm_invalidate(comm);
>> MPI_Comm_shrink(comm, &newcomm);
>> MPI_Comm_free(&comm);
>> comm = newcomm;
>> }
>>
>> MPI_Comm_size(comm, size);
>>
>> done = do_computation(buffer, size);
>>
>> /* Let's agree for sure if we are done with the computation */
>>
>> MPI_Barrier(comm); // don't check the error code, this is just to "catch" invalidate messages
>> MPI_Comm_agreement(comm, &done);
>>
>> while (!done);
>>
>> MPI_Finalize();
>>
>> because a rank may enter the barrier, get knocked out by the call to invalidate and then go on to call MPI_Comm_agreement anyway. So we can try the following:
>>
>> do {
>>
>> if (root) read_some_data_from_a_file(buffer);
>>
>> err = MPI_Bcast(buffer, .... ,root, comm);
>> if (err) {
>> MPI_Comm_invalidate(comm);
>> MPI_Comm_shrink(comm, &newcomm);
>> MPI_Comm_free(&comm);
>> comm = newcomm;
>> }
>>
>> MPI_Comm_size(comm, size);
>>
>> done = do_computation(buffer, size);
>>
>> /* Let's agree for sure if we are done with the computation */
>>
>> err = MPI_Barrier(comm);
>> if (err) {
>> MPI_Comm_invalidate(comm);
>> MPI_Comm_shrink(comm, &newcomm);
>> MPI_Comm_free(&comm);
>> comm = newcomm;
>> }
>> MPI_Comm_agreement(comm, &done);
>>
>> while (!done);
>>
>> MPI_Finalize();
>>
>> But now we have done nothing more than move the problem down a few lines. Some ranks may succeed the MPI_Barrier and go on to MPI_Comm_agreement while others attempt to invalidate/shrink. Is there a solution to this problem? How can one safely use MPI_Comm_agreement and MPI_Comm_shrink in the same application?
>>
>> Thanks,
>> Dave _______________________________________________
>> mpi3-ft mailing list
>> mpi3-ft at lists.mpi-forum.org
>> http://lists.mpi-forum.org/mailman/listinfo.cgi/mpi3-ft
>
More information about the mpiwg-ft
mailing list