Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
4ca844c5ab7a66e6528263d170189f38238c6587
[simgrid.git] / src / smpi / colls / allgather-bruck.c
1 #include "colls_private.h"
2
3 /*****************************************************************************
4
5 Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
11   * Redistributions of source code must retain the above copyright notice,
12     this list of conditions and the following disclaimer.
13
14   * Redistributions in binary form must reproduce the above copyright notice,
15     this list of conditions and the following disclaimer in the documentation
16     and/or other materials provided with the distribution.
17
18   * Neither the name of the Florida State University nor the names of its
19     contributors may be used to endorse or promote products derived from this
20     software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33   *************************************************************************
34   *     Any results obtained from executing this software require the     *
35   *     acknowledgment and citation of the software and its owners.       *
36   *     The full citation is given below:                                 *
37   *                                                                       *
38   *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
39   *     Collective Communication Routines." The 19th ACM International    *
40   *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
41   *     June 20-22, 2005.                                                 *
42   *************************************************************************
43
44 *****************************************************************************/
45
46
47 /*****************************************************************************
48  * Function: allgather_bruck
49  * return: int
50  * inputs:
51  *   send_buff: send input buffer
52  *   send_count: number of elements to send
53  *   send_type: data type of elements being sent
54  *   recv_buff: receive output buffer
55  *   recv_count: number of elements to received
56  *   recv_type: data type of elements being received
57  *   comm: communication
58  * Descrp: Function realizes the allgather operation using the bruck
59  *         algorithm.
60  * Auther: MPICH
61  * Comment: Original bruck algorithm from MPICH is slightly modified by
62  *          Ahmad Faraj.  
63  ****************************************************************************/
64 int smpi_coll_tuned_allgather_bruck(void *send_buff, int send_count,
65                                     MPI_Datatype send_type, void *recv_buff,
66                                     int recv_count, MPI_Datatype recv_type,
67                                     MPI_Comm comm)
68 {
69   // MPI variables
70   MPI_Status status;
71   MPI_Aint recv_extent;
72
73   // local int variables
74   int i, src, dst, rank, num_procs, count, remainder;
75   int tag = 1;
76   int pof2 = 1;
77   int success = 0;
78
79   // local string variables
80   char *tmp_buff;
81   char *send_ptr = (char *) send_buff;
82   char *recv_ptr = (char *) recv_buff;
83
84   // get size of the communicator, followed by rank 
85   num_procs = smpi_comm_size(comm);
86   rank = smpi_comm_rank(comm);
87
88   // get size of single element's type for recv buffer
89   recv_extent = smpi_datatype_get_extent(recv_type);
90
91   count = recv_count;
92
93   tmp_buff = (char *) xbt_malloc(num_procs * recv_count * recv_extent);
94   if (!tmp_buff) {
95     printf("allgather-bruck:54: cannot allocate memory\n");
96     MPI_Finalize();
97     exit(0);
98   }
99   // perform a local copy
100   MPIR_Localcopy(send_ptr, send_count, send_type, tmp_buff, recv_count,
101                  recv_type);
102
103   while (pof2 <= (num_procs / 2)) {
104     src = (rank + pof2) % num_procs;
105     dst = (rank - pof2 + num_procs) % num_procs;
106
107     MPIC_Sendrecv(tmp_buff, count, recv_type, dst, tag,
108                   tmp_buff + count * recv_extent, count, recv_type,
109                   src, tag, comm, &status);
110     count *= 2;
111     pof2 *= 2;
112   }
113
114   remainder = num_procs - pof2;
115   if (remainder) {
116     src = (rank + pof2) % num_procs;
117     dst = (rank - pof2 + num_procs) % num_procs;
118
119     MPIC_Sendrecv(tmp_buff, remainder * recv_count, recv_type, dst, tag,
120                   tmp_buff + count * recv_extent, remainder * recv_count,
121                   recv_type, src, tag, comm, &status);
122   }
123
124   MPIC_Sendrecv(tmp_buff, (num_procs - rank) * recv_count, recv_type, rank,
125                 tag, recv_ptr + rank * recv_count * recv_extent,
126                 (num_procs - rank) * recv_count, recv_type, rank, tag, comm,
127                 &status);
128
129   if (rank)
130     MPIC_Sendrecv(tmp_buff + (num_procs - rank) * recv_count * recv_extent,
131                   rank * recv_count, recv_type, rank, tag, recv_ptr,
132                   rank * recv_count, recv_type, rank, tag, comm, &status);
133   free(tmp_buff);
134   return success;
135 }
136
137 /*#include "ompi_bindings.h"
138
139 int ompi_coll_tuned_alltoall_intra_pairwise(void *sbuf, int scount, 
140                                             MPI_Datatype sdtype,
141                                             void* rbuf, int rcount,
142                                             MPI_Datatype rdtype,
143                                             MPI_Comm comm)
144 {
145     int line = -1, err = 0;
146     int rank, size, step;
147     int sendto, recvfrom;
148     void * tmpsend, *tmprecv;
149     ptrdiff_t lb, sext, rext;
150
151     size = ompi_comm_size(comm);
152     rank = ompi_comm_rank(comm);
153
154     OPAL_OUTPUT((ompi_coll_tuned_stream,
155                  "coll:tuned:alltoall_intra_pairwise rank %d", rank));
156
157     err = ompi_datatype_get_extent (sdtype, &lb, &sext);
158     if (err != MPI_SUCCESS) { line = __LINE__; goto err_hndl; }
159     err = ompi_datatype_get_extent (rdtype, &lb, &rext);
160     if (err != MPI_SUCCESS) { line = __LINE__; goto err_hndl; }
161
162     
163     // Perform pairwise exchange - starting from 1 so the local copy is last 
164     for (step = 1; step < size + 1; step++) {
165
166         // Determine sender and receiver for this step. 
167         sendto  = (rank + step) % size;
168         recvfrom = (rank + size - step) % size;
169
170         // Determine sending and receiving locations 
171         tmpsend = (char*)sbuf + sendto * sext * scount;
172         tmprecv = (char*)rbuf + recvfrom * rext * rcount;
173
174         // send and receive 
175         err = ompi_coll_tuned_sendrecv( tmpsend, scount, sdtype, sendto, 
176                                         MCA_COLL_BASE_TAG_ALLTOALL,
177                                         tmprecv, rcount, rdtype, recvfrom, 
178                                         MCA_COLL_BASE_TAG_ALLTOALL,
179                                         comm, MPI_STATUS_IGNORE, rank);
180         if (err != MPI_SUCCESS) { line = __LINE__; goto err_hndl;  }
181     }
182
183     return MPI_SUCCESS;
184  
185  err_hndl:
186     OPAL_OUTPUT((ompi_coll_tuned_stream,
187                  "%s:%4d\tError occurred %d, rank %2d", __FILE__, line, 
188                  err, rank));
189     return err;
190 }
191 */