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

Reply via email to