1 /*****************************************************************************
3 * Function: alltoall_bruck
8 send_buff: send input buffer
9 send_count: number of elements to send
10 send_type: data type of elements being sent
11 recv_buff: receive output buffer
12 recv_count: number of elements to received
13 recv_type: data type of elements being received
16 * Descrp: Function realizes the alltoall operation using the bruck algorithm.
18 * Auther: MPICH / modified by Ahmad Faraj
20 ****************************************************************************/
22 smpi_coll_tuned_alltoall_bruck(void *send_buff, int send_count,
23 MPI_Datatype send_type, void *recv_buff,
24 int recv_count, MPI_Datatype recv_type,
29 MPI_Datatype new_type;
31 int *blocks_length, *disps;
32 int i, src, dst, rank, num_procs, count, remainder, block, position;
33 int pack_size, tag = 1, pof2 = 1, success = 1, failure = 0;
37 char *send_ptr = (char *) send_buff;
38 char *recv_ptr = (char *) recv_buff;
40 MPI_Comm_size(comm, &num_procs);
41 MPI_Comm_rank(comm, &rank);
43 MPI_Type_extent(recv_type, &extent);
45 tmp_buff = (char *) malloc(num_procs * recv_count * extent);
47 printf("alltoall-bruck:53: cannot allocate memory\n");
52 disps = (int *) malloc(sizeof(int) * num_procs);
54 printf("alltoall-bruck:61: cannot allocate memory\n");
59 blocks_length = (int *) malloc(sizeof(int) * num_procs);
61 printf("alltoall-bruck:69: cannot allocate memory\n");
67 MPI_Sendrecv(send_ptr + rank * send_count * extent,
68 (num_procs - rank) * send_count, send_type, rank, tag,
69 recv_ptr, (num_procs - rank) * recv_count, recv_type, rank,
72 MPI_Sendrecv(send_ptr, rank * send_count, send_type, rank, tag,
73 recv_ptr + (num_procs - rank) * recv_count * extent,
74 rank * recv_count, recv_type, rank, tag, comm, &status);
78 MPI_Pack_size(send_count * num_procs, send_type, comm, &pack_size);
80 while (pof2 < num_procs) {
81 dst = (rank + pof2) % num_procs;
82 src = (rank - pof2 + num_procs) % num_procs;
86 for (block = 1; block < num_procs; block++)
88 blocks_length[count] = send_count;
89 disps[count] = block * send_count;
93 MPI_Type_indexed(count, blocks_length, disps, recv_type, &new_type);
94 MPI_Type_commit(&new_type);
97 MPI_Pack(recv_buff, 1, new_type, tmp_buff, pack_size, &position, comm);
99 MPI_Sendrecv(tmp_buff, position, MPI_PACKED, dst, tag, recv_buff, 1,
100 new_type, src, tag, comm, &status);
101 MPI_Type_free(&new_type);
109 MPI_Sendrecv(recv_ptr + (rank + 1) * recv_count * extent,
110 (num_procs - rank - 1) * recv_count, send_type,
111 rank, tag, tmp_buff, (num_procs - rank - 1) * recv_count,
112 recv_type, rank, tag, comm, &status);
114 MPI_Sendrecv(recv_ptr, (rank + 1) * recv_count, send_type, rank, tag,
115 tmp_buff + (num_procs - rank - 1) * recv_count * extent,
116 (rank + 1) * recv_count, recv_type, rank, tag, comm, &status);
119 for (i = 0; i < num_procs; i++)
120 MPI_Sendrecv(tmp_buff + i * recv_count * extent, recv_count, send_type,
122 recv_ptr + (num_procs - i - 1) * recv_count * extent,
123 recv_count, recv_type, rank, tag, comm, &status);