+ /* if some processes in this process's subtree in this step
+ did not have any destination process to communicate with
+ because of non-power-of-two, we need to send them the
+ data that they would normally have received from those
+ processes. That is, the haves in this subtree must send to
+ the havenots. We use a logarithmic recursive-halfing algorithm
+ for this. */
+
+ /* This part of the code will not currently be
+ executed because we are not using recursive
+ doubling for non power of two. Mark it as experimental
+ so that it doesn't show up as red in the coverage tests. */
+
+ /* --BEGIN EXPERIMENTAL-- */
+ if (dst_tree_root + mask > comm_size)
+ {
+ nprocs_completed = comm_size - my_tree_root - mask;
+ /* nprocs_completed is the number of processes in this
+ subtree that have all the data. Send data to others
+ in a tree fashion. First find root of current tree
+ that is being divided into two. k is the number of
+ least-significant bits in this process's rank that
+ must be zeroed out to find the rank of the root */
+ j = mask;
+ k = 0;
+ while (j)
+ {
+ j >>= 1;
+ k++;
+ }
+ k--;
+
+ offset = scatter_size * (my_tree_root + mask);
+ tmp_mask = mask >> 1;
+
+ while (tmp_mask)
+ {
+ relative_dst = relative_rank ^ tmp_mask;
+ dst = (relative_dst + root) % comm_size;
+
+ tree_root = relative_rank >> k;
+ tree_root <<= k;
+
+ /* send only if this proc has data and destination
+ doesn't have data. */
+
+ /* if (rank == 3) {
+ printf("rank %d, dst %d, root %d, nprocs_completed %d\n", relative_rank, relative_dst, tree_root, nprocs_completed);
+ fflush(stdout);
+ }*/
+
+ if ((relative_dst > relative_rank) &&
+ (relative_rank < tree_root + nprocs_completed)
+ && (relative_dst >= tree_root + nprocs_completed))
+ {
+
+ /* printf("Rank %d, send to %d, offset %d, size %d\n", rank, dst, offset, recv_size);
+ fflush(stdout); */
+ smpi_mpi_send(((char *)tmp_buf + offset),
+ recv_size, MPI_BYTE, dst,
+ COLL_TAG_BCAST, comm);
+ /* recv_size was set in the previous
+ receive. that's the amount of data to be
+ sent now. */
+ }
+ /* recv only if this proc. doesn't have data and sender
+ has data */
+ else if ((relative_dst < relative_rank) &&
+ (relative_dst < tree_root + nprocs_completed) &&
+ (relative_rank >= tree_root + nprocs_completed))
+ {
+ /* printf("Rank %d waiting to recv from rank %d\n",
+ relative_rank, dst); */
+ smpi_mpi_recv(((char *)tmp_buf + offset),
+ nbytes - offset,
+ MPI_BYTE, dst, COLL_TAG_BCAST,
+ comm, &status);
+ /* nprocs_completed is also equal to the no. of processes
+ whose data we don't have */
+ recv_size=smpi_mpi_get_count(&status, MPI_BYTE);
+ curr_size += recv_size;
+ /* printf("Rank %d, recv from %d, offset %d, size %d\n", rank, dst, offset, recv_size);
+ fflush(stdout);*/
+ }
+ tmp_mask >>= 1;
+ k--;
+ }
+ }
+ /* --END EXPERIMENTAL-- */