next up previous contents
Next: Gather Up: Collectives Previous: Barrier

Bcast

int MPI_Bcast(void *buf, int count, MPI_Datatype dtype, 
              int root, MPI_Comm comm)
{
  int myrank;

  MPI_Comm_rank(comm, &myrank);

  /* global phase */
  if (is_master(myrank, comm)) {
    master_bcast(buf, count, dtype, root, comm);
  }

  /* local phase */
  if (are_local(myrank, root, comm)) {
    broadcast the data from the root to the local processes;
  } else {
    broadcast the data from the local master to the local processes;
  }

  return(MPI_SUCCESS);
}

int master_bcast(void *buf, int count, MPI_Datatype dtype, 
                 int root, MPI_Comm comm)
{
  MPI_Status status;
  int myrank, nmasters, mynum, rootnum, vnum, dim, hibit;
  int i, peer, mask;

  MPI_Comm_rank(comm, &myrank);
  nmasters = num_masters(comm);

  if (nmasters <= MAXLINEARBCAST) {
    /* linear broadcast between masters */
    if (myrank == root) {
      for (i = 0; i < nmasters; i++) {
        if (i == local_master_num(root, comm)) continue;

        MPI_Send(buf, count, dtype, master_rank(i, comm), 
                 IMPI_BCAST_TAG, comm);
      }
    } else {
      MPI_Recv(buf, count, dtype, root, IMPI_BCAST_TAG, comm, &status);
    }
  } else {
    /* tree broadcast between masters */
    mynum = master_num(myrank, comm);
    rootnum = master_num(root, comm);
    vnum = (mynum + nmasters - rootnum) % nmasters;
    dim = cubedim(nmasters);
    hibit = hibit(vnum, dim);
    --dim;

    /* receive data from parent in the tree */
    if (vnum > 0) {
      peer = ((vnum & ~(1 << hibit)) + rootnum) % nmasters;
      MPI_Recv(buf, count, dtype, master_rank(peer, comm),
               IMPI_BCAST_TAG, comm, &status);
    }

    /* send data to the children */
    for (i = hibit + 1, mask = 1 << i; i <= dim; ++i, mask <<= 1) {
      peer = vnum | mask;
      if (peer < nmasters) {
        peer = (peer + rootnum) % nmasters;
        MPI_Send(buf, count, dtype, master_rank(peer, comm),
                 IMPI_BCAST_TAG, comm,);
      }
    }
  }

  return(MPI_SUCCESS);
}



IMPI Protocol ver 0.0
DRAFT March 22, 1999