Hi, Your understanding is incorrect : "Attributes are local to the process and specific to the communicator to which they are attached." (per https://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-1.1/node119.htm)
think an attribute is often a pointer, and really bad things can happen if rank 0 uses a pointer that is valid on rank 1, so if attributes were global, they would be virtually unusable. note the comment before the barrier is incorrect. this is a simple barrier and all MPI tasks will block until all of them invoke seqEnd() The main goal of using attributes in this example is to invoke MPI_Comm_dup() once per communicator (instead of once per sequence, since this is an expensive operation). Cheers, Gilles On Sun, Dec 16, 2018 at 1:04 AM 邹海峰 <haifengzou1...@gmail.com> wrote: > > Hi there, > > At first, I think attribute is just like global variable that attached to a > specific communicator. I can define and set the value on one process, then > get and modify the value on another process as long as those processes > belonging to the same communicator. But when I was reading chapter 6 of the > book using mpi: portable parallel programming with the message-passing > interface. I was confused by the usage of caching attribute. > > The purpose the code is to make the execution sequential. the main function is > > seqBegin( MPI_COMM_WORLD ); > printf( "My rank is %d\n", wrank ); > fflush( stdout ); > seqEnd( MPI_COMM_WORLD ); > > which is simple to understand. The program will print the rank in order. The > defination of the function "seqBegin()" is > > static int seqKeyval = MPI_KEYVAL_INVALID; > > void seqBegin( MPI_Comm comm ) > { > MPI_Comm lcomm; > int flag, mysize, myrank; > seqInfo *info; > if (seqKeyval == MPI_KEYVAL_INVALID) { > MPI_Comm_create_keyval( MPI_NULL_COPY_FN, seqDelFn, &seqKeyval, NULL ); > } > MPI_Comm_get_attr( comm, seqKeyval, &info, &flag ); > if (!flag) { > info = (seqInfo *)malloc( sizeof(seqInfo) ); > MPI_Comm_dup( comm, &info->lcomm ); > MPI_Comm_rank( info->lcomm, &myrank ); > MPI_Comm_size( info->lcomm, &mysize ); > info->prevRank = myrank - 1; > if (info->prevRank < 0) info->prevRank = MPI_PROC_NULL; > info->nextRank = myrank + 1; > if (info->nextRank >= mysize) info->nextRank = MPI_PROC_NULL; > if (verbose) { > printf( "seqbegin: prev = %d, next = %d\n", > info->prevRank, info->nextRank ); > } > MPI_Comm_set_attr( comm, seqKeyval, info ); > } > MPI_Recv( NULL, 0, MPI_INT, info->prevRank, 0, info->lcomm, > MPI_STATUS_IGNORE ); > } > > and the defination of function "seqEnd()" is > > void seqEnd( MPI_Comm comm ) > { > seqInfo *info; > int flag; > > /* Sanity check */ > if (seqKeyval == MPI_KEYVAL_INVALID) > MPI_Abort( MPI_COMM_WORLD, 1 ); > MPI_Comm_get_attr( comm, seqKeyval, &info, &flag ); > if (!info || !flag) > MPI_Abort( MPI_COMM_WORLD, 1 ); > if (verbose) { > printf( "seqend: prev = %d, next = %d\n", > info->prevRank, info->nextRank ); > } > MPI_Send( NULL, 0, MPI_INT, info->nextRank, 0, info->lcomm ); > > /* Make everyone wait until all have completed their send */ > MPI_Barrier( info->lcomm ); > } > > Other details are omitted. In fact, all the codes can be found in > https://www.mcs.anl.gov/research/projects/mpi/usingmpi/examples-usingmpi/libraries/index.html > which is provided by the author of the book. > > The program uses send and recv to block the execution. Only if the process > receive the message from last process, the process can continue to execute, > otherwise it is blocked, which resulting in the sequential execution. The > part I don't understand is in function "seqBegin()". If my undertstanding > about attribute is right, only one process will enter the if condition and > set the value of attribute, other processes just get the value . Here comes > the question: since other processes don't set the value, how can they get the > prevRank and nextRank of their own. > > The code can be executed as expected. But I still can't get the rational > behind this and there is little reference about attribute caching, so I come > here for help. Thank you very much ! > > Best Wishes ! > _______________________________________________ > users mailing list > users@lists.open-mpi.org > https://lists.open-mpi.org/mailman/listinfo/users _______________________________________________ users mailing list users@lists.open-mpi.org https://lists.open-mpi.org/mailman/listinfo/users