~ubuntu-branches/ubuntu/vivid/mpich/vivid-proposed

« back to all changes in this revision

Viewing changes to src/mpid/pamid/src/coll/alltoallv/mpido_alltoallv.c

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2014-04-01 20:24:20 UTC
  • mfrom: (5.2.4 sid)
  • Revision ID: package-import@ubuntu.com-20140401202420-t5ey1ia2klt5dkq3
Tags: 3.1-4
* [c3e3398] Disable test_primitives, which is unreliable on some platforms.
            (Closes: #743047)
* [265a699] Add minimal autotest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
/*                                                                  */
16
16
/* end_generated_IBM_copyright_prolog                               */
17
17
/*  (C)Copyright IBM Corp.  2007, 2011  */
18
 
/**
 
18
/**  
19
19
 * \file src/coll/alltoallv/mpido_alltoallv.c
20
20
 * \brief ???
21
21
 */
22
 
/*#define TRACE_ON*/
 
22
/* #define TRACE_ON */
23
23
 
24
24
#include <mpidimpl.h>
25
25
 
43
43
                   MPID_Comm *comm_ptr,
44
44
                   int *mpierrno)
45
45
{
46
 
   if(comm_ptr->rank == 0)
47
 
      TRACE_ERR("Entering MPIDO_Alltoallv\n");
 
46
#ifndef HAVE_PAMI_IN_PLACE
 
47
  if (sendbuf == MPI_IN_PLACE)
 
48
  {
 
49
    MPID_Abort (NULL, 0, 1, "'MPI_IN_PLACE' requries support for `PAMI_IN_PLACE`");
 
50
    return -1;
 
51
  }
 
52
#endif
 
53
   TRACE_ERR("Entering MPIDO_Alltoallv\n");
48
54
   volatile unsigned active = 1;
49
 
   int sndtypelen, rcvtypelen, snd_contig, rcv_contig;
 
55
   void *snd_noncontig_buff = NULL, *rcv_noncontig_buff = NULL;
 
56
   void *sbuf = NULL, *rbuf = NULL;
 
57
   int recvok=PAMI_SUCCESS, sendok=PAMI_SUCCESS;
 
58
   int sndtypelen, rcvtypelen, snd_contig=0, rcv_contig=0;
50
59
   MPID_Datatype *sdt, *rdt;
51
60
   pami_type_t stype, rtype;
52
61
   MPI_Aint sdt_true_lb, rdt_true_lb;
53
62
   MPIDI_Post_coll_t alltoallv_post;
54
63
   int pamidt = 1;
55
64
   int tmp;
56
 
 
57
 
   if(sendbuf == MPI_IN_PLACE) 
58
 
     pamidt = 0; /* Disable until ticket #632 is fixed */
59
 
   if(MPIDI_Datatype_to_pami(sendtype, &stype, -1, NULL, &tmp) != MPI_SUCCESS)
60
 
      pamidt = 0;
61
 
   if(MPIDI_Datatype_to_pami(recvtype, &rtype, -1, NULL, &tmp) != MPI_SUCCESS)
62
 
      pamidt = 0;
63
 
 
64
 
   if(
65
 
      (comm_ptr->mpid.user_selected_type[PAMI_XFER_ALLTOALLV_INT] == 
66
 
            MPID_COLL_USE_MPICH) ||
67
 
       pamidt == 0)
 
65
   const int rank = comm_ptr->rank;
 
66
#if ASSERT_LEVEL==0
 
67
   /* We can't afford the tracing in ndebug/performance libraries */
 
68
    const unsigned verbose = 0;
 
69
#else
 
70
    const unsigned verbose = (MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL) && (rank == 0);
 
71
#endif
 
72
   const struct MPIDI_Comm* const mpid = &(comm_ptr->mpid);
 
73
   const int selected_type = mpid->user_selected_type[PAMI_XFER_ALLTOALLV_INT];
 
74
   const int size = comm_ptr->local_size;
 
75
   int sendcontinuous , recvcontinuous=0;
 
76
   size_t recv_size=0, send_size=0;
 
77
   size_t totalrecvcount=0;
 
78
   int *lrecvdispls = NULL; /* possible local displs calculated for noncontinous */
 
79
   int *lsenddispls = NULL;/* possible local displs calculated for noncontinous */
 
80
   int *lrecvcounts  = NULL;/* possible local counts calculated for noncontinous */
 
81
   int *lsendcounts  = NULL;/* possible local counts calculated for noncontinous */
 
82
   const int *precvdispls = recvdispls; /* pointer to displs to use as pami parmi */
 
83
   const int *psenddispls = senddispls; /* pointer to displs to use as pami parmi */
 
84
   const int *precvcounts = recvcounts; /* pointer to counts to use as pami parmi */
 
85
   const int *psendcounts = sendcounts; /* pointer to counts to use as pami parmi */
 
86
   int inplace = sendbuf == MPI_IN_PLACE? 1 : 0;
 
87
   if(selected_type == MPID_COLL_USE_MPICH)
68
88
   {
69
 
      if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL && comm_ptr->rank == 0))
 
89
      if(unlikely(verbose))
70
90
         fprintf(stderr,"Using MPICH alltoallv algorithm\n");
71
 
      if(!comm_ptr->rank)
72
 
         TRACE_ERR("Using MPICH alltoallv\n");
73
91
      return MPIR_Alltoallv(sendbuf, sendcounts, senddispls, sendtype,
74
92
                            recvbuf, recvcounts, recvdispls, recvtype,
75
93
                            comm_ptr, mpierrno);
76
94
   }
77
 
   if(!comm_ptr->rank)
78
 
      TRACE_ERR("Using %s for alltoallv protocol\n", pname);
79
95
 
 
96
   if(!inplace)
 
97
   {
 
98
     sendok = MPIDI_Datatype_to_pami(sendtype, &stype, -1, NULL, &tmp);
 
99
     MPIDI_Datatype_get_info(1, sendtype, snd_contig, sndtypelen, sdt, sdt_true_lb);
 
100
     sbuf = (char *)sendbuf + sdt_true_lb;
 
101
     if(!snd_contig || (sendok != PAMI_SUCCESS))
 
102
     {
 
103
        stype = PAMI_TYPE_UNSIGNED_CHAR;
 
104
        size_t totalsendcount = sendcounts[0];
 
105
        sendcontinuous = senddispls[0] == 0? 1 : 0 ;
 
106
        int i;
 
107
        psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
 
108
        psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
 
109
        lsenddispls[0]= 0;
 
110
        lsendcounts[0]= sndtypelen * sendcounts[0];
 
111
        for(i=1; i<size; ++i)
 
112
        {
 
113
           lsenddispls[i]= sndtypelen * totalsendcount;
 
114
           totalsendcount += sendcounts[i];
 
115
           if(senddispls[i] != (senddispls[i-1] + (sendcounts[i-1]*sndtypelen)))
 
116
              sendcontinuous = 0;
 
117
           lsendcounts[i]= sndtypelen * sendcounts[i];
 
118
        }
 
119
        send_size = sndtypelen * totalsendcount;
 
120
        TRACE_ERR("Pack receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, sndtypelen %zu,  send_size %zu\n",
 
121
                (size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) sndtypelen, (size_t)send_size);
 
122
        snd_noncontig_buff = MPIU_Malloc(send_size);
 
123
        sbuf = snd_noncontig_buff;
 
124
        if(snd_noncontig_buff == NULL)
 
125
        {
 
126
           MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
 
127
              "Fatal:  Cannot allocate pack buffer");
 
128
        }
 
129
        if(sendcontinuous)
 
130
        {
 
131
           MPIR_Localcopy(sendbuf, totalsendcount, sendtype, 
 
132
                          snd_noncontig_buff, send_size,MPI_CHAR);
 
133
        }
 
134
        else
 
135
        {
 
136
           size_t extent; 
 
137
           MPID_Datatype_get_extent_macro(sendtype,extent);
 
138
           for(i=0; i<size; ++i)
 
139
           {
 
140
              char* scbuf = (char*)sendbuf + senddispls[i]*extent;
 
141
              char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
 
142
              MPIR_Localcopy(scbuf, sendcounts[i], sendtype, 
 
143
                             rcbuf, psendcounts[i], MPI_CHAR);
 
144
              TRACE_ERR("Pack send src  extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
145
                        (size_t)extent, (size_t)i,(size_t)senddispls[i],(size_t)i,(size_t)sendcounts[i],(size_t)senddispls[i], *(int*)scbuf);
 
146
              TRACE_ERR("Pack send dest             displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
147
                        (size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
 
148
           }
 
149
        }
 
150
     } 
 
151
   }
80
152
   MPIDI_Datatype_get_info(1, recvtype, rcv_contig, rcvtypelen, rdt, rdt_true_lb);
 
153
   recvok = MPIDI_Datatype_to_pami(recvtype, &rtype, -1, NULL, &tmp);
 
154
   rbuf = (char *)recvbuf + rdt_true_lb;
 
155
   if(!rcv_contig || (recvok != PAMI_SUCCESS))
 
156
   {
 
157
      rtype = PAMI_TYPE_UNSIGNED_CHAR;
 
158
      totalrecvcount = recvcounts[0];
 
159
      recvcontinuous = recvdispls[0] == 0? 1 : 0 ;
 
160
      int i;
 
161
      precvdispls = lrecvdispls = MPIU_Malloc(size*sizeof(int));
 
162
      precvcounts = lrecvcounts = MPIU_Malloc(size*sizeof(int));
 
163
      lrecvdispls[0]= 0;
 
164
      lrecvcounts[0]= rcvtypelen * recvcounts[0];
 
165
      for(i=1; i<size; ++i)
 
166
      {
 
167
         lrecvdispls[i]= rcvtypelen * totalrecvcount;
 
168
         totalrecvcount += recvcounts[i];
 
169
         if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1]*rcvtypelen)))
 
170
            recvcontinuous = 0;
 
171
         lrecvcounts[i]= rcvtypelen * recvcounts[i];
 
172
      }
 
173
      recv_size = rcvtypelen * totalrecvcount;
 
174
      TRACE_ERR("Pack receive rcv_contig %zu, recvok %zd, totalrecvcount %zu, recvcontinuous %zu, rcvtypelen %zu, recv_size %zu\n",
 
175
                (size_t)rcv_contig, (size_t)recvok, (size_t)totalrecvcount, (size_t)recvcontinuous,(size_t)rcvtypelen, (size_t)recv_size);
 
176
      rcv_noncontig_buff = MPIU_Malloc(recv_size);
 
177
      rbuf = rcv_noncontig_buff;
 
178
      if(rcv_noncontig_buff == NULL)
 
179
      {
 
180
         MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
 
181
            "Fatal:  Cannot allocate pack buffer");
 
182
      }
 
183
      /* need to copy it now if it's used for the send buffer and then do not do in place */
 
184
      if(inplace)
 
185
      {
 
186
        inplace = 0;
 
187
        stype = PAMI_TYPE_UNSIGNED_CHAR;
 
188
        size_t totalsendcount = recvcounts[0];
 
189
        sendcontinuous = recvdispls[0] == 0? 1 : 0 ;
 
190
        int i;
 
191
        psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
 
192
        psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
 
193
        lsenddispls[0]= 0;
 
194
        lsendcounts[0]= rcvtypelen * recvcounts[0];
 
195
        for(i=1; i<size; ++i)
 
196
        {
 
197
           lsenddispls[i]= rcvtypelen * totalsendcount;
 
198
           totalsendcount += recvcounts[i];
 
199
           if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1]*rcvtypelen)))
 
200
              sendcontinuous = 0;
 
201
           lsendcounts[i]= rcvtypelen * recvcounts[i];
 
202
        }
 
203
        send_size = rcvtypelen * totalsendcount;
 
204
        TRACE_ERR("Pack MPI_IN_PLACE receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, rcvtypelen %zu,  send_size %zu\n",
 
205
                (size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) rcvtypelen, (size_t)send_size);
 
206
        snd_noncontig_buff = MPIU_Malloc(send_size);
 
207
        sbuf = snd_noncontig_buff;
 
208
        if(snd_noncontig_buff == NULL)
 
209
        {
 
210
           MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
 
211
              "Fatal:  Cannot allocate pack buffer");
 
212
        }
 
213
        if(sendcontinuous)
 
214
        {
 
215
           MPIR_Localcopy(recvbuf, totalsendcount, recvtype, 
 
216
                          snd_noncontig_buff, send_size,MPI_CHAR);
 
217
        }
 
218
        else
 
219
        {
 
220
           size_t extent; 
 
221
           MPID_Datatype_get_extent_macro(recvtype,extent);
 
222
           for(i=0; i<size; ++i)
 
223
           {
 
224
              char* scbuf = (char*)recvbuf + recvdispls[i]*extent;
 
225
              char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
 
226
              MPIR_Localcopy(scbuf, recvcounts[i], recvtype, 
 
227
                             rcbuf, psendcounts[i], MPI_CHAR);
 
228
              TRACE_ERR("Pack send src  extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
229
                        (size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)scbuf);
 
230
              TRACE_ERR("Pack send dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
231
                        (size_t)extent, (size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
 
232
           }
 
233
        }
 
234
      }
 
235
   }
 
236
 
81
237
 
82
238
   pami_xfer_t alltoallv;
83
239
   pami_algorithm_t my_alltoallv;
84
 
   pami_metadata_t *my_alltoallv_md;
 
240
   const pami_metadata_t *my_md = (pami_metadata_t *)NULL;
85
241
   int queryreq = 0;
86
242
 
87
 
   if(comm_ptr->mpid.user_selected_type[PAMI_XFER_ALLTOALLV_INT] == MPID_COLL_OPTIMIZED)
 
243
   if(selected_type == MPID_COLL_OPTIMIZED)
88
244
   {
89
245
      TRACE_ERR("Optimized alltoallv was selected\n");
90
 
      my_alltoallv = comm_ptr->mpid.opt_protocol[PAMI_XFER_ALLTOALLV_INT][0];
91
 
      my_alltoallv_md = &comm_ptr->mpid.opt_protocol_md[PAMI_XFER_ALLTOALLV_INT][0];
92
 
      queryreq = comm_ptr->mpid.must_query[PAMI_XFER_ALLTOALLV_INT][0];
 
246
      my_alltoallv = mpid->opt_protocol[PAMI_XFER_ALLTOALLV_INT][0];
 
247
      my_md = &mpid->opt_protocol_md[PAMI_XFER_ALLTOALLV_INT][0];
 
248
      queryreq = mpid->must_query[PAMI_XFER_ALLTOALLV_INT][0];
93
249
   }
94
250
   else
95
251
   { /* is this purely an else? or do i need to check for some other selectedvar... */
96
252
      TRACE_ERR("Alltoallv specified by user\n");
97
 
      my_alltoallv = comm_ptr->mpid.user_selected[PAMI_XFER_ALLTOALLV_INT];
98
 
      my_alltoallv_md = &comm_ptr->mpid.user_metadata[PAMI_XFER_ALLTOALLV_INT];
99
 
      queryreq = comm_ptr->mpid.user_selected_type[PAMI_XFER_ALLTOALLV_INT];
 
253
      my_alltoallv = mpid->user_selected[PAMI_XFER_ALLTOALLV_INT];
 
254
      my_md = &mpid->user_metadata[PAMI_XFER_ALLTOALLV_INT];
 
255
      queryreq = selected_type;
100
256
   }
101
257
   alltoallv.algorithm = my_alltoallv;
102
 
   char *pname = my_alltoallv_md->name;
 
258
   char *pname = my_md->name;
103
259
 
104
260
 
105
261
   alltoallv.cb_done = cb_alltoallv;
106
262
   alltoallv.cookie = (void *)&active;
107
263
   /* We won't bother with alltoallv since MPI is always going to be ints. */
108
 
   if(sendbuf == MPI_IN_PLACE)
 
264
   if(inplace)
109
265
   {
110
 
      if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL))
 
266
     if(unlikely(verbose))
111
267
         fprintf(stderr,"alltoallv MPI_IN_PLACE buffering\n");
112
268
      alltoallv.cmd.xfer_alltoallv_int.stype = rtype;
113
 
      alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) recvdispls;
114
 
      alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) recvcounts;
115
 
      alltoallv.cmd.xfer_alltoallv_int.sndbuf = (char *)recvbuf+rdt_true_lb;
 
269
      alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) precvdispls;
 
270
      alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) precvcounts;
 
271
      alltoallv.cmd.xfer_alltoallv_int.sndbuf = PAMI_IN_PLACE;
116
272
   }
117
273
   else
118
274
   {
119
 
      MPIDI_Datatype_get_info(1, sendtype, snd_contig, sndtypelen, sdt, sdt_true_lb);
120
275
      alltoallv.cmd.xfer_alltoallv_int.stype = stype;
121
 
      alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) senddispls;
122
 
      alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) sendcounts;
123
 
      alltoallv.cmd.xfer_alltoallv_int.sndbuf = (char *)sendbuf+sdt_true_lb;
 
276
      alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) psenddispls;
 
277
      alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) psendcounts;
 
278
      alltoallv.cmd.xfer_alltoallv_int.sndbuf = sbuf;
124
279
   }
125
 
   alltoallv.cmd.xfer_alltoallv_int.rcvbuf = (char *)recvbuf+rdt_true_lb;
 
280
   alltoallv.cmd.xfer_alltoallv_int.rcvbuf = rbuf;
126
281
      
127
 
   alltoallv.cmd.xfer_alltoallv_int.rdispls = (int *) recvdispls;
128
 
   alltoallv.cmd.xfer_alltoallv_int.rtypecounts = (int *) recvcounts;
 
282
   alltoallv.cmd.xfer_alltoallv_int.rdispls = (int *) precvdispls;
 
283
   alltoallv.cmd.xfer_alltoallv_int.rtypecounts = (int *) precvcounts;
129
284
   alltoallv.cmd.xfer_alltoallv_int.rtype = rtype;
130
285
 
131
 
   if(unlikely(queryreq == MPID_COLL_ALWAYS_QUERY || queryreq == MPID_COLL_CHECK_FN_REQUIRED))
 
286
   if(unlikely(queryreq == MPID_COLL_ALWAYS_QUERY || 
 
287
               queryreq == MPID_COLL_CHECK_FN_REQUIRED))
132
288
   {
133
289
      metadata_result_t result = {0};
134
290
      TRACE_ERR("querying alltoallv protocol %s, type was %d\n", pname, queryreq);
135
 
      result = my_alltoallv_md->check_fn(&alltoallv);
 
291
      if(my_md->check_fn == NULL)
 
292
      {
 
293
        /* process metadata bits */
 
294
         if((!my_md->check_correct.values.inplace) && (sendbuf == MPI_IN_PLACE))
 
295
            result.check.unspecified = 1;
 
296
/* Can't check ranges like this.  Non-local.  Comment out for now.
 
297
         if(my_md->check_correct.values.rangeminmax)
 
298
         {
 
299
            MPI_Aint data_true_lb;
 
300
            MPID_Datatype *data_ptr;
 
301
            int data_size, data_contig;
 
302
            MPIDI_Datatype_get_info(??, sendtype, data_contig, data_size, data_ptr, data_true_lb); 
 
303
            if((my_md->range_lo <= data_size) &&
 
304
               (my_md->range_hi >= data_size))
 
305
               ; 
 
306
            else
 
307
            {
 
308
               result.check.range = 1;
 
309
               if(unlikely(verbose))
 
310
               {   
 
311
                  fprintf(stderr,"message size (%u) outside range (%zu<->%zu) for %s.\n",
 
312
                          data_size,
 
313
                          my_md->range_lo,
 
314
                          my_md->range_hi,
 
315
                          my_md->name);
 
316
               }
 
317
            }
 
318
         }
 
319
*/
 
320
      }
 
321
      else /* calling the check fn is sufficient */
 
322
         result = my_md->check_fn(&alltoallv);
136
323
      TRACE_ERR("bitmask: %#X\n", result.bitmask);
137
 
      if(!result.bitmask)
 
324
      result.check.nonlocal = 0; /* #warning REMOVE THIS WHEN IMPLEMENTED */
 
325
      if(result.bitmask)
138
326
      {
139
 
         fprintf(stderr,"Query failed for %s\n", pname);
 
327
        if(unlikely(verbose))
 
328
          fprintf(stderr,"Query failed for %s. Using MPICH alltoallv\n", pname);
 
329
        MPIDI_Update_last_algorithm(comm_ptr, "ALLTOALLV_MPICH");
 
330
        return MPIR_Alltoallv(sendbuf, sendcounts, senddispls, sendtype,
 
331
                              recvbuf, recvcounts, recvdispls, recvtype,
 
332
                              comm_ptr, mpierrno);
 
333
      }
 
334
      if(my_md->check_correct.values.asyncflowctl && !(--(comm_ptr->mpid.num_requests))) 
 
335
      { 
 
336
         comm_ptr->mpid.num_requests = MPIDI_Process.optimized.num_requests;
 
337
         int tmpmpierrno;   
 
338
         if(unlikely(verbose))
 
339
            fprintf(stderr,"Query barrier required for %s\n", pname);
 
340
         MPIDO_Barrier(comm_ptr, &tmpmpierrno);
140
341
      }
141
342
   }
142
343
 
143
 
   if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL && comm_ptr->rank == 0))
 
344
   if(unlikely(verbose))
144
345
   {
145
346
      unsigned long long int threadID;
146
347
      MPIU_Thread_id_t tid;
148
349
      threadID = (unsigned long long int)tid;
149
350
      fprintf(stderr,"<%llx> Using protocol %s for alltoallv on %u\n", 
150
351
              threadID,
151
 
              my_alltoallv_md->name,
 
352
              my_md->name,
152
353
              (unsigned) comm_ptr->context_id);
153
354
   }
154
355
 
155
356
   MPIDI_Context_post(MPIDI_Context[0], &alltoallv_post.state,
156
357
                      MPIDI_Pami_post_wrapper, (void *)&alltoallv);
157
358
 
158
 
   TRACE_ERR("%d waiting on active %d\n", comm_ptr->rank, active);
 
359
   TRACE_ERR("%d waiting on active %d\n", rank, active);
159
360
   MPID_PROGRESS_WAIT_WHILE(active);
160
361
 
 
362
   if(!rcv_contig || (recvok != PAMI_SUCCESS))
 
363
   {
 
364
      if(recvcontinuous)
 
365
      {
 
366
         MPIR_Localcopy(rcv_noncontig_buff, recv_size,MPI_CHAR,
 
367
                        recvbuf, totalrecvcount, recvtype);
 
368
      }
 
369
      else
 
370
      {
 
371
         size_t extent; 
 
372
         int i;
 
373
         MPID_Datatype_get_extent_macro(recvtype,extent);
 
374
         for(i=0; i<size; ++i)
 
375
         {
 
376
            char* scbuf = (char*)rcv_noncontig_buff+ precvdispls[i];
 
377
            char* rcbuf = (char*)recvbuf + recvdispls[i]*extent;
 
378
            MPIR_Localcopy(scbuf, precvcounts[i], MPI_CHAR, 
 
379
                           rcbuf, recvcounts[i], recvtype);
 
380
            TRACE_ERR("Pack recv src  extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
381
                      (size_t)extent, (size_t)i,(size_t)precvdispls[i],(size_t)i,(size_t)precvcounts[i],(size_t)precvdispls[i], *(int*)scbuf);
 
382
            TRACE_ERR("Pack recv dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
383
                      (size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)rcbuf);
 
384
         }
 
385
      }
 
386
      MPIU_Free(rcv_noncontig_buff);
 
387
   }
 
388
   if(!snd_contig || (sendok != PAMI_SUCCESS))  MPIU_Free(snd_noncontig_buff);
 
389
   if(lrecvdispls) MPIU_Free(lrecvdispls);
 
390
   if(lsenddispls) MPIU_Free(lsenddispls);
 
391
   if(lrecvcounts) MPIU_Free(lrecvcounts);
 
392
   if(lsendcounts) MPIU_Free(lsendcounts);
161
393
 
162
394
   TRACE_ERR("Leaving alltoallv\n");
163
395
 
164
396
 
165
397
   return 0;
166
398
}
 
399
 
 
400
 
 
401
int MPIDO_Alltoallv_simple(const void *sendbuf,
 
402
                   const int *sendcounts,
 
403
                   const int *senddispls,
 
404
                   MPI_Datatype sendtype,
 
405
                   void *recvbuf,
 
406
                   const int *recvcounts,
 
407
                   const int *recvdispls,
 
408
                   MPI_Datatype recvtype,
 
409
                   MPID_Comm *comm_ptr,
 
410
                   int *mpierrno)
 
411
{
 
412
#ifndef HAVE_PAMI_IN_PLACE
 
413
  if (sendbuf == MPI_IN_PLACE)
 
414
  {
 
415
    MPID_Abort (NULL, 0, 1, "'MPI_IN_PLACE' requries support for `PAMI_IN_PLACE`");
 
416
    return -1;
 
417
  }
 
418
#endif
 
419
   TRACE_ERR("Entering MPIDO_Alltoallv_optimized\n");
 
420
   volatile unsigned active = 1;
 
421
  int sndtypelen, rcvtypelen, snd_contig = 1, rcv_contig = 1;
 
422
   MPID_Datatype *sdt, *rdt;
 
423
   pami_type_t stype = NULL, rtype;
 
424
   MPI_Aint sdt_true_lb = 0, rdt_true_lb;
 
425
   MPIDI_Post_coll_t alltoallv_post;
 
426
  void *snd_noncontig_buff = NULL, *rcv_noncontig_buff = NULL;
 
427
  void *sbuf = NULL, *rbuf = NULL;
 
428
  int recvok=PAMI_SUCCESS, sendok=PAMI_SUCCESS;
 
429
   int tmp;
 
430
   const int rank = comm_ptr->rank;
 
431
  const int size = comm_ptr->local_size;
 
432
 
 
433
  int sendcontinuous , recvcontinuous=0;
 
434
  size_t recv_size=0, send_size=0;
 
435
  size_t totalrecvcount=0;
 
436
  int *lrecvdispls = NULL; /* possible local displs calculated for noncontinous */
 
437
  int *lsenddispls = NULL;/* possible local displs calculated for noncontinous */
 
438
  int *lrecvcounts  = NULL;/* possible local counts calculated for noncontinous */
 
439
  int *lsendcounts  = NULL;/* possible local counts calculated for noncontinous */
 
440
  const int *precvdispls = recvdispls; /* pointer to displs to use as pami parmi */
 
441
  const int *psenddispls = senddispls; /* pointer to displs to use as pami parmi */
 
442
  const int *precvcounts = recvcounts; /* pointer to counts to use as pami parmi */
 
443
  const int *psendcounts = sendcounts; /* pointer to counts to use as pami parmi */
 
444
  int inplace = sendbuf == MPI_IN_PLACE? 1 : 0;
 
445
 
 
446
 
 
447
 
 
448
 
 
449
   const struct MPIDI_Comm* const mpid = &(comm_ptr->mpid);
 
450
   /* We don't pack and unpack in alltoallv as we do in alltoall because alltoallv has
 
451
      more overhead of book keeping for sendcounts/displs and recvcounts/displs. Since,
 
452
      alltoallv is non-rooted and all tasks has type info, decision to punt to mpich
 
453
      will be the same on all tasks */
 
454
 
 
455
 
 
456
  /* Check if collsel has MPICH algorithm as the best performing one, if so, call MPICH now w/o doing any conversions */
 
457
  MPIDI_Datatype_get_info(1, recvtype, rcv_contig, rcvtypelen, rdt, rdt_true_lb);
 
458
  if(MPIDI_Pamix_collsel_advise != NULL && mpid->collsel_fast_query != NULL)
 
459
  {
 
460
    advisor_algorithm_t advisor_algorithms[1];
 
461
    int num_algorithms = MPIDI_Pamix_collsel_advise(mpid->collsel_fast_query, PAMI_XFER_ALLTOALLV_INT, rcvtypelen * recvcounts[0], advisor_algorithms, 1);
 
462
    if(num_algorithms)
 
463
    {
 
464
      if(advisor_algorithms[0].algorithm_type == COLLSEL_EXTERNAL_ALGO)
 
465
      {
 
466
        return MPIR_Alltoallv(sendbuf, sendcounts, senddispls, sendtype,
 
467
                              recvbuf, recvcounts, recvdispls, recvtype,
 
468
                              comm_ptr, mpierrno);
 
469
       }
 
470
     }
 
471
   }
 
472
 
 
473
  /* Now do checks on send data and datatypes (contig and contin) and do necessary conversions */
 
474
  if(!inplace)
 
475
   {
 
476
    sendok = MPIDI_Datatype_to_pami(sendtype, &stype, -1, NULL, &tmp);
 
477
     MPIDI_Datatype_get_info(1, sendtype, snd_contig, sndtypelen, sdt, sdt_true_lb);
 
478
    sbuf = (char *)sendbuf + sdt_true_lb;
 
479
    if(!snd_contig || (sendok != PAMI_SUCCESS))
 
480
    {
 
481
      stype = PAMI_TYPE_UNSIGNED_CHAR;
 
482
      size_t totalsendcount = sendcounts[0];
 
483
      sendcontinuous = senddispls[0] == 0? 1 : 0 ;
 
484
      int i;
 
485
      psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
 
486
      psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
 
487
      lsenddispls[0]= 0;
 
488
      lsendcounts[0]= sndtypelen * sendcounts[0];
 
489
      for(i=1; i<size; ++i)
 
490
      {
 
491
        lsenddispls[i]= sndtypelen * totalsendcount;
 
492
        totalsendcount += sendcounts[i];
 
493
        if(senddispls[i] != (senddispls[i-1] + (sendcounts[i-1])))
 
494
          sendcontinuous = 0;
 
495
        lsendcounts[i]= sndtypelen * sendcounts[i];
 
496
   }
 
497
      send_size = sndtypelen * totalsendcount;
 
498
      TRACE_ERR("Pack receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, sndtypelen %zu,  send_size %zu\n",
 
499
                (size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) sndtypelen, (size_t)send_size);
 
500
      snd_noncontig_buff = MPIU_Malloc(send_size);
 
501
      sbuf = snd_noncontig_buff;
 
502
      if(snd_noncontig_buff == NULL)
 
503
   {
 
504
        MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
 
505
                   "Fatal:  Cannot allocate pack buffer");
 
506
      }
 
507
      if(sendcontinuous)
 
508
      {
 
509
        MPIR_Localcopy(sendbuf, totalsendcount, sendtype, 
 
510
                       snd_noncontig_buff, send_size,MPI_CHAR);
 
511
      }
 
512
      else
 
513
      {
 
514
        size_t extent; 
 
515
        MPID_Datatype_get_extent_macro(sendtype,extent);
 
516
        for(i=0; i<size; ++i)
 
517
        {
 
518
          char* scbuf = (char*)sendbuf + senddispls[i]*extent;
 
519
          char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
 
520
          MPIR_Localcopy(scbuf, sendcounts[i], sendtype, 
 
521
                         rcbuf, psendcounts[i], MPI_CHAR);
 
522
          TRACE_ERR("Pack send src  extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
523
                    (size_t)extent, (size_t)i,(size_t)senddispls[i],(size_t)i,(size_t)sendcounts[i],(size_t)senddispls[i], *(int*)scbuf);
 
524
          TRACE_ERR("Pack send dest             displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
525
                    (size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
 
526
        }
 
527
      }
 
528
    }
 
529
  }
 
530
 
 
531
  recvok = MPIDI_Datatype_to_pami(recvtype, &rtype, -1, NULL, &tmp);
 
532
  rbuf = (char *)recvbuf + rdt_true_lb;
 
533
  if(!rcv_contig || (recvok != PAMI_SUCCESS))
 
534
  {
 
535
    rtype = PAMI_TYPE_UNSIGNED_CHAR;
 
536
    totalrecvcount = recvcounts[0];
 
537
    recvcontinuous = recvdispls[0] == 0? 1 : 0 ;
 
538
    int i;
 
539
    precvdispls = lrecvdispls = MPIU_Malloc(size*sizeof(int));
 
540
    precvcounts = lrecvcounts = MPIU_Malloc(size*sizeof(int));
 
541
    lrecvdispls[0]= 0;
 
542
    lrecvcounts[0]= rcvtypelen * recvcounts[0];
 
543
    for(i=1; i<size; ++i)
 
544
    {
 
545
      lrecvdispls[i]= rcvtypelen * totalrecvcount;
 
546
      totalrecvcount += recvcounts[i];
 
547
      if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1])))
 
548
        recvcontinuous = 0;
 
549
      lrecvcounts[i]= rcvtypelen * recvcounts[i];
 
550
   }   
 
551
    recv_size = rcvtypelen * totalrecvcount;
 
552
    TRACE_ERR("Pack receive rcv_contig %zu, recvok %zd, totalrecvcount %zu, recvcontinuous %zu, rcvtypelen %zu, recv_size %zu\n",
 
553
              (size_t)rcv_contig, (size_t)recvok, (size_t)totalrecvcount, (size_t)recvcontinuous,(size_t)rcvtypelen, (size_t)recv_size);
 
554
    rcv_noncontig_buff = MPIU_Malloc(recv_size);
 
555
    rbuf = rcv_noncontig_buff;
 
556
    if(rcv_noncontig_buff == NULL)
 
557
    {
 
558
      MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
 
559
                 "Fatal:  Cannot allocate pack buffer");
 
560
    }
 
561
    /* need to copy it now if it's used for the send buffer and then do not do in place */
 
562
    if(inplace)
 
563
    {
 
564
      inplace = 0;
 
565
      stype = PAMI_TYPE_UNSIGNED_CHAR;
 
566
      size_t totalsendcount = recvcounts[0];
 
567
      sendcontinuous = recvdispls[0] == 0? 1 : 0 ;
 
568
      int i;
 
569
      psenddispls = lsenddispls = MPIU_Malloc(size*sizeof(int));
 
570
      psendcounts = lsendcounts = MPIU_Malloc(size*sizeof(int));
 
571
      lsenddispls[0]= 0;
 
572
      lsendcounts[0]= rcvtypelen * recvcounts[0];
 
573
      for(i=1; i<size; ++i)
 
574
      {
 
575
        lsenddispls[i]= rcvtypelen * totalsendcount;
 
576
        totalsendcount += recvcounts[i];
 
577
        if(recvdispls[i] != (recvdispls[i-1] + (recvcounts[i-1])))
 
578
          sendcontinuous = 0;
 
579
        lsendcounts[i]= rcvtypelen * recvcounts[i];
 
580
      }
 
581
      send_size = rcvtypelen * totalsendcount;
 
582
      TRACE_ERR("Pack MPI_IN_PLACE receive sndv_contig %zu, sendok %zd, totalsendcount %zu, sendcontinuous %zu, rcvtypelen %zu,  send_size %zu\n",
 
583
                (size_t)snd_contig, (size_t)sendok, (size_t)totalsendcount, (size_t)sendcontinuous, (size_t) rcvtypelen, (size_t)send_size);
 
584
      snd_noncontig_buff = MPIU_Malloc(send_size);
 
585
      sbuf = snd_noncontig_buff;
 
586
      if(snd_noncontig_buff == NULL)
 
587
      {
 
588
        MPID_Abort(NULL, MPI_ERR_NO_SPACE, 1,
 
589
                   "Fatal:  Cannot allocate pack buffer");
 
590
      }
 
591
      if(sendcontinuous)
 
592
      {
 
593
        MPIR_Localcopy(recvbuf, totalsendcount, recvtype, 
 
594
                       snd_noncontig_buff, send_size,MPI_CHAR);
 
595
      }
 
596
      else
 
597
      {
 
598
        size_t extent; 
 
599
        MPID_Datatype_get_extent_macro(recvtype,extent);
 
600
        for(i=0; i<size; ++i)
 
601
        {
 
602
          char* scbuf = (char*)recvbuf + recvdispls[i]*extent;
 
603
          char* rcbuf = (char*)snd_noncontig_buff + psenddispls[i];
 
604
          MPIR_Localcopy(scbuf, recvcounts[i], recvtype, 
 
605
                         rcbuf, psendcounts[i], MPI_CHAR);
 
606
          TRACE_ERR("Pack send src  extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
607
                    (size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)scbuf);
 
608
          TRACE_ERR("Pack send dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
609
                    (size_t)extent, (size_t)i,(size_t)psenddispls[i],(size_t)i,(size_t)psendcounts[i],(size_t)psenddispls[i], *(int*)rcbuf);
 
610
        }
 
611
      }
 
612
    }
 
613
  }
 
614
 
 
615
 
 
616
 
 
617
   pami_xfer_t alltoallv;
 
618
   const pami_metadata_t *my_alltoallv_md;
 
619
   my_alltoallv_md = &mpid->coll_metadata[PAMI_XFER_ALLTOALLV_INT][0][0];
 
620
 
 
621
   alltoallv.algorithm = mpid->coll_algorithm[PAMI_XFER_ALLTOALLV_INT][0][0];
 
622
   char *pname = my_alltoallv_md->name;
 
623
 
 
624
   alltoallv.cb_done = cb_alltoallv;
 
625
   alltoallv.cookie = (void *)&active;
 
626
  if(inplace)
 
627
   {
 
628
    alltoallv.cmd.xfer_alltoallv_int.stype = rtype;
 
629
    alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) precvdispls;
 
630
    alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) precvcounts;
 
631
      alltoallv.cmd.xfer_alltoallv_int.sndbuf = PAMI_IN_PLACE;
 
632
   }
 
633
  else
 
634
  {
 
635
    alltoallv.cmd.xfer_alltoallv_int.stype = stype;
 
636
    alltoallv.cmd.xfer_alltoallv_int.sdispls = (int *) psenddispls;
 
637
    alltoallv.cmd.xfer_alltoallv_int.stypecounts = (int *) psendcounts;
 
638
    alltoallv.cmd.xfer_alltoallv_int.sndbuf = sbuf;
 
639
  }
 
640
  alltoallv.cmd.xfer_alltoallv_int.rcvbuf = rbuf;
 
641
 
 
642
  alltoallv.cmd.xfer_alltoallv_int.rdispls = (int *) precvdispls;
 
643
  alltoallv.cmd.xfer_alltoallv_int.rtypecounts = (int *) precvcounts;
 
644
   alltoallv.cmd.xfer_alltoallv_int.rtype = rtype;
 
645
 
 
646
 
 
647
   MPIDI_Context_post(MPIDI_Context[0], &alltoallv_post.state,
 
648
                      MPIDI_Pami_post_wrapper, (void *)&alltoallv);
 
649
 
 
650
   TRACE_ERR("%d waiting on active %d\n", rank, active);
 
651
   MPID_PROGRESS_WAIT_WHILE(active);
 
652
 
 
653
  if(!rcv_contig || (recvok != PAMI_SUCCESS))
 
654
  {
 
655
    if(recvcontinuous)
 
656
    {
 
657
      MPIR_Localcopy(rcv_noncontig_buff, recv_size,MPI_CHAR,
 
658
                     recvbuf, totalrecvcount, recvtype);
 
659
    }
 
660
    else
 
661
    {
 
662
      size_t extent; 
 
663
      int i;
 
664
      MPID_Datatype_get_extent_macro(recvtype,extent);
 
665
      for(i=0; i<size; ++i)
 
666
      {
 
667
        char* scbuf = (char*)rcv_noncontig_buff+ precvdispls[i];
 
668
        char* rcbuf = (char*)recvbuf + recvdispls[i]*extent;
 
669
        MPIR_Localcopy(scbuf, precvcounts[i], MPI_CHAR, 
 
670
                       rcbuf, recvcounts[i], recvtype);
 
671
        TRACE_ERR("Pack recv src  extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
672
                  (size_t)extent, (size_t)i,(size_t)precvdispls[i],(size_t)i,(size_t)precvcounts[i],(size_t)precvdispls[i], *(int*)scbuf);
 
673
        TRACE_ERR("Pack recv dest extent %zu, displ[%zu]=%zu, count[%zu]=%zu buf[%zu]=%u\n",
 
674
                  (size_t)extent, (size_t)i,(size_t)recvdispls[i],(size_t)i,(size_t)recvcounts[i],(size_t)recvdispls[i], *(int*)rcbuf);
 
675
      }
 
676
    }
 
677
    MPIU_Free(rcv_noncontig_buff);
 
678
  }
 
679
  if(!snd_contig || (sendok != PAMI_SUCCESS))  MPIU_Free(snd_noncontig_buff);
 
680
  if(lrecvdispls) MPIU_Free(lrecvdispls);
 
681
  if(lsenddispls) MPIU_Free(lsenddispls);
 
682
  if(lrecvcounts) MPIU_Free(lrecvcounts);
 
683
  if(lsendcounts) MPIU_Free(lsendcounts);
 
684
 
 
685
 
 
686
   TRACE_ERR("Leaving alltoallv\n");
 
687
 
 
688
 
 
689
   return MPI_SUCCESS;
 
690
}
 
691
 
 
692
int
 
693
MPIDO_CSWrapper_alltoallv(pami_xfer_t *alltoallv,
 
694
                          void        *comm)
 
695
{
 
696
   int mpierrno = 0;
 
697
   MPID_Comm   *comm_ptr = (MPID_Comm*)comm;
 
698
   MPI_Datatype sendtype, recvtype;
 
699
   void *sbuf;
 
700
   MPIDI_coll_check_in_place(alltoallv->cmd.xfer_alltoallv_int.sndbuf, &sbuf);
 
701
   int rc = MPIDI_Dtpami_to_dtmpi(  alltoallv->cmd.xfer_alltoallv_int.stype,
 
702
                                   &sendtype,
 
703
                                    NULL,
 
704
                                    NULL);
 
705
   if(rc == -1) return rc;
 
706
 
 
707
   rc = MPIDI_Dtpami_to_dtmpi(  alltoallv->cmd.xfer_alltoallv_int.rtype,
 
708
                               &recvtype,
 
709
                                NULL,
 
710
                                NULL);
 
711
   if(rc == -1) return rc;
 
712
 
 
713
   rc  =  MPIR_Alltoallv(sbuf,
 
714
                         alltoallv->cmd.xfer_alltoallv_int.stypecounts, 
 
715
                         alltoallv->cmd.xfer_alltoallv_int.sdispls, sendtype,
 
716
                         alltoallv->cmd.xfer_alltoallv_int.rcvbuf,
 
717
                         alltoallv->cmd.xfer_alltoallv_int.rtypecounts,
 
718
                         alltoallv->cmd.xfer_alltoallv_int.rdispls, recvtype,
 
719
                          comm_ptr, &mpierrno);
 
720
   if(alltoallv->cb_done && rc == 0)
 
721
     alltoallv->cb_done(NULL, alltoallv->cookie, PAMI_SUCCESS);
 
722
   return rc;
 
723
 
 
724
}
 
725