Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
72d40cd595c8b311be1fed93bdda9ebe743bd24f
[simgrid.git] / src / smpi / colls / smpi_mvapich2_selector.c
1 /* selector for collective algorithms based on mvapich decision logic */
2
3 /* Copyright (c) 2009-2010, 2013-2014. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include "colls_private.h"
10
11 #include "smpi_mvapich2_selector_stampede.h"
12
13
14 static void init_mv2_alltoall_tables_stampede(){
15 int i;
16   int agg_table_sum = 0;
17 mv2_alltoall_tuning_table **table_ptrs = NULL;
18    mv2_alltoall_num_ppn_conf = 3;
19         mv2_alltoall_thresholds_table
20           = malloc(sizeof(mv2_alltoall_tuning_table *)
21                         * mv2_alltoall_num_ppn_conf);
22         table_ptrs = malloc(sizeof(mv2_alltoall_tuning_table *)
23                                  * mv2_alltoall_num_ppn_conf);
24         mv2_size_alltoall_tuning_table = malloc(sizeof(int) *
25                                                      mv2_alltoall_num_ppn_conf);
26         mv2_alltoall_table_ppn_conf =malloc(mv2_alltoall_num_ppn_conf * sizeof(int));
27         mv2_alltoall_table_ppn_conf[0] = 1;
28         mv2_size_alltoall_tuning_table[0] = 6;
29         mv2_alltoall_tuning_table mv2_tmp_alltoall_thresholds_table_1ppn[] = {
30           {2,
31            1, 
32            {{0, -1, &MPIR_Alltoall_pairwise_MV2},
33            },
34   
35            {{0, -1, &MPIR_Alltoall_inplace_MV2},
36            },
37           },
38   
39           {4,
40            2,
41            {{0, 262144, &MPIR_Alltoall_Scatter_dest_MV2},
42             {262144, -1, &MPIR_Alltoall_pairwise_MV2},
43            },
44                 
45            {{0, -1, &MPIR_Alltoall_inplace_MV2},
46            },
47           },
48   
49           {8,
50            2,
51            {{0, 8, &MPIR_Alltoall_RD_MV2},
52             {8, -1, &MPIR_Alltoall_Scatter_dest_MV2},
53            },
54   
55            {{0, -1, &MPIR_Alltoall_inplace_MV2},
56            },
57           },
58   
59           {16,
60            3,
61            {{0, 64, &MPIR_Alltoall_RD_MV2},
62             {64, 512, &MPIR_Alltoall_bruck_MV2},
63             {512, -1, &MPIR_Alltoall_Scatter_dest_MV2},
64            },
65   
66            {{0,-1, &MPIR_Alltoall_inplace_MV2},
67            },
68           },
69   
70           {32,
71            3,
72            {{0, 32, &MPIR_Alltoall_RD_MV2},
73             {32, 2048, &MPIR_Alltoall_bruck_MV2},
74             {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
75            },
76   
77            {{0, -1, &MPIR_Alltoall_inplace_MV2},
78            },
79           },
80   
81           {64,
82            3,
83            {{0, 8, &MPIR_Alltoall_RD_MV2},
84             {8, 1024, &MPIR_Alltoall_bruck_MV2},
85             {1024, -1, &MPIR_Alltoall_Scatter_dest_MV2},
86            },
87   
88            {{0, -1, &MPIR_Alltoall_inplace_MV2},
89            },
90           },
91         };
92         table_ptrs[0] = mv2_tmp_alltoall_thresholds_table_1ppn;
93         mv2_alltoall_table_ppn_conf[1] = 2;
94         mv2_size_alltoall_tuning_table[1] = 6;
95         mv2_alltoall_tuning_table mv2_tmp_alltoall_thresholds_table_2ppn[] = {
96           {4,
97            2,
98            {{0, 32, &MPIR_Alltoall_RD_MV2},
99             {32, -1, &MPIR_Alltoall_Scatter_dest_MV2},
100            },
101                 
102            {{0, -1, &MPIR_Alltoall_inplace_MV2},
103            },
104           },
105   
106           {8,
107            2,
108            {{0, 64, &MPIR_Alltoall_RD_MV2},
109             {64, -1, &MPIR_Alltoall_Scatter_dest_MV2},
110            },
111                 
112            {{0, -1, &MPIR_Alltoall_inplace_MV2},
113            },
114           },
115   
116           {16,
117            3,
118            {{0, 64, &MPIR_Alltoall_RD_MV2},
119             {64, 2048, &MPIR_Alltoall_bruck_MV2},
120             {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
121            },
122   
123            {{0,-1, &MPIR_Alltoall_inplace_MV2},
124            },
125           },
126   
127           {32,
128            3,
129            {{0, 16, &MPIR_Alltoall_RD_MV2},
130             {16, 2048, &MPIR_Alltoall_bruck_MV2},
131             {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
132            },
133   
134            {{0, -1, &MPIR_Alltoall_inplace_MV2},
135            },
136           },
137   
138           {64,
139            3,
140            {{0, 8, &MPIR_Alltoall_RD_MV2},
141             {8, 1024, &MPIR_Alltoall_bruck_MV2},
142             {1024, -1, &MPIR_Alltoall_Scatter_dest_MV2},
143            },
144   
145            {{0, -1, &MPIR_Alltoall_inplace_MV2},
146            },
147           },
148
149           {128,
150            3,
151            {{0, 4, &MPIR_Alltoall_RD_MV2},
152             {4, 2048, &MPIR_Alltoall_bruck_MV2},
153             {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
154            },
155   
156            {{0, -1, &MPIR_Alltoall_inplace_MV2},
157            },
158           },
159         };
160         table_ptrs[1] = mv2_tmp_alltoall_thresholds_table_2ppn;
161         mv2_alltoall_table_ppn_conf[2] = 16;
162         mv2_size_alltoall_tuning_table[2] = 7;
163         mv2_alltoall_tuning_table mv2_tmp_alltoall_thresholds_table_16ppn[] = {
164           {16,
165            2, 
166            {{0, 2048, &MPIR_Alltoall_bruck_MV2},
167             {2048, -1,  &MPIR_Alltoall_Scatter_dest_MV2},
168            },
169   
170            {{32768, -1, &MPIR_Alltoall_inplace_MV2},
171            },
172           },
173   
174           {32,
175            2,
176            {{0, 2048, &MPIR_Alltoall_bruck_MV2},
177             {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
178            },
179                 
180            {{16384, -1, &MPIR_Alltoall_inplace_MV2},
181            },
182           },
183   
184           {64,
185            3,
186            {{0, 2048, &MPIR_Alltoall_bruck_MV2},
187             {2048, 16384, &MPIR_Alltoall_Scatter_dest_MV2},
188             {16384, -1, &MPIR_Alltoall_pairwise_MV2},
189            },
190   
191            {{32768, 131072, &MPIR_Alltoall_inplace_MV2},
192            },
193           },
194   
195           {128,
196            2,
197            {{0, 2048, &MPIR_Alltoall_bruck_MV2},
198             {2048, -1, &MPIR_Alltoall_pairwise_MV2},
199            },
200   
201            {{16384,65536, &MPIR_Alltoall_inplace_MV2},
202            },
203           },
204   
205           {256,
206            2,
207            {{0, 1024, &MPIR_Alltoall_bruck_MV2},
208             {1024, -1, &MPIR_Alltoall_pairwise_MV2},
209            },
210   
211            {{16384, 65536, &MPIR_Alltoall_inplace_MV2},
212            },
213           },
214   
215           {512,
216            2,
217            {{0, 1024, &MPIR_Alltoall_bruck_MV2},
218             {1024, -1, &MPIR_Alltoall_pairwise_MV2},
219            },
220   
221            {{16384, 65536, &MPIR_Alltoall_inplace_MV2},
222            },
223           },
224           {1024,
225            2,
226            {{0, 1024, &MPIR_Alltoall_bruck_MV2},
227             {1024, -1, &MPIR_Alltoall_pairwise_MV2},
228            },
229   
230            {{16384, 65536, &MPIR_Alltoall_inplace_MV2},
231            },
232           },
233   
234         };
235         table_ptrs[2] = mv2_tmp_alltoall_thresholds_table_16ppn;
236         agg_table_sum = 0;
237         for (i = 0; i < mv2_alltoall_num_ppn_conf; i++) {
238           agg_table_sum += mv2_size_alltoall_tuning_table[i];
239         }
240         mv2_alltoall_thresholds_table[0] =
241           malloc(agg_table_sum * sizeof (mv2_alltoall_tuning_table));
242         memcpy(mv2_alltoall_thresholds_table[0], table_ptrs[0],
243                     (sizeof(mv2_alltoall_tuning_table)
244                      * mv2_size_alltoall_tuning_table[0]));
245         for (i = 1; i < mv2_alltoall_num_ppn_conf; i++) {
246           mv2_alltoall_thresholds_table[i] =
247             mv2_alltoall_thresholds_table[i - 1]
248             + mv2_size_alltoall_tuning_table[i - 1];
249           memcpy(mv2_alltoall_thresholds_table[i], table_ptrs[i],
250                       (sizeof(mv2_alltoall_tuning_table)
251                        * mv2_size_alltoall_tuning_table[i]));
252         }
253         free(table_ptrs);
254         
255         
256 }
257                             
258 int smpi_coll_tuned_alltoall_mvapich2( void *sendbuf, int sendcount, 
259                                              MPI_Datatype sendtype,
260                                              void* recvbuf, int recvcount, 
261                                              MPI_Datatype recvtype, 
262                                              MPI_Comm comm)
263 {
264
265     if(mv2_alltoall_table_ppn_conf==NULL)
266         init_mv2_alltoall_tables_stampede();
267         
268     int sendtype_size, recvtype_size, nbytes, comm_size;
269     char * tmp_buf = NULL;
270     int mpi_errno=MPI_SUCCESS;
271     int range = 0;
272     int range_threshold = 0;
273     int conf_index = 0;
274     comm_size =  smpi_comm_size(comm);
275
276     sendtype_size=smpi_datatype_size(sendtype);
277     recvtype_size=smpi_datatype_size(recvtype);
278     nbytes = sendtype_size * sendcount;
279
280     /* check if safe to use partial subscription mode */
281
282     /* Search for the corresponding system size inside the tuning table */
283     while ((range < (mv2_size_alltoall_tuning_table[conf_index] - 1)) &&
284            (comm_size > mv2_alltoall_thresholds_table[conf_index][range].numproc)) {
285         range++;
286     }    
287     /* Search for corresponding inter-leader function */
288     while ((range_threshold < (mv2_alltoall_thresholds_table[conf_index][range].size_table - 1))
289            && (nbytes >
290                mv2_alltoall_thresholds_table[conf_index][range].algo_table[range_threshold].max)
291            && (mv2_alltoall_thresholds_table[conf_index][range].algo_table[range_threshold].max != -1)) {
292         range_threshold++;
293     }     
294     MV2_Alltoall_function = mv2_alltoall_thresholds_table[conf_index][range].algo_table[range_threshold]
295                                 .MV2_pt_Alltoall_function;
296
297     if(sendbuf != MPI_IN_PLACE) {  
298         mpi_errno = MV2_Alltoall_function(sendbuf, sendcount, sendtype,
299                                               recvbuf, recvcount, recvtype,
300                                                comm);
301     } else {
302         range_threshold = 0; 
303         if(nbytes < 
304           mv2_alltoall_thresholds_table[conf_index][range].in_place_algo_table[range_threshold].min
305           ||nbytes > mv2_alltoall_thresholds_table[conf_index][range].in_place_algo_table[range_threshold].max
306           ) {
307             tmp_buf = (char *)malloc( comm_size * recvcount * recvtype_size );
308             mpi_errno = smpi_datatype_copy((char *)recvbuf,
309                                        comm_size*recvcount, recvtype,
310                                        (char *)tmp_buf,
311                                        comm_size*recvcount, recvtype);
312
313             mpi_errno = MV2_Alltoall_function(tmp_buf, recvcount, recvtype,
314                                                recvbuf, recvcount, recvtype,
315                                                 comm );        
316             free(tmp_buf);
317         } else { 
318             mpi_errno = MPIR_Alltoall_inplace_MV2(sendbuf, sendcount, sendtype,
319                                               recvbuf, recvcount, recvtype,
320                                                comm );
321         } 
322     }
323
324     
325     return (mpi_errno);
326 }
327
328
329 static void init_mv2_allgather_tables_stampede(){
330 int i;
331   int agg_table_sum = 0;
332 mv2_allgather_tuning_table **table_ptrs = NULL;
333  mv2_allgather_num_ppn_conf = 3;
334         mv2_allgather_thresholds_table
335             = malloc(sizeof(mv2_allgather_tuning_table *)
336                   * mv2_allgather_num_ppn_conf);
337         table_ptrs = malloc(sizeof(mv2_allgather_tuning_table *)
338                                  * mv2_allgather_num_ppn_conf);
339         mv2_size_allgather_tuning_table = malloc(sizeof(int) *
340                                                       mv2_allgather_num_ppn_conf);
341         mv2_allgather_table_ppn_conf 
342             = malloc(mv2_allgather_num_ppn_conf * sizeof(int));
343         mv2_allgather_table_ppn_conf[0] = 1;
344         mv2_size_allgather_tuning_table[0] = 6;
345         mv2_allgather_tuning_table mv2_tmp_allgather_thresholds_table_1ppn[] = {
346             {
347                 2,
348                 {0},
349                 1,
350                 {
351                     {0, -1, &MPIR_Allgather_Ring_MV2},
352                 },
353             },
354             {
355                 4,
356                 {0,0},
357                 2,
358                 {
359                     {0, 262144, &MPIR_Allgather_RD_MV2},
360                     {262144, -1, &MPIR_Allgather_Ring_MV2},
361                 },
362             },
363             {
364                 8,
365                 {0,0},
366                 2,
367                 {
368                     {0, 131072, &MPIR_Allgather_RD_MV2},
369                     {131072, -1, &MPIR_Allgather_Ring_MV2},
370                 },
371             },
372             {
373                 16,
374                 {0,0},
375                 2,
376                 {
377                     {0, 131072, &MPIR_Allgather_RD_MV2},
378                     {131072, -1, &MPIR_Allgather_Ring_MV2},
379                 },
380             },
381             {
382                 32,
383                 {0,0},
384                 2,
385                 {
386                     {0, 65536, &MPIR_Allgather_RD_MV2},
387                     {65536, -1, &MPIR_Allgather_Ring_MV2},
388                 },
389             },
390             {
391                 64,
392                 {0,0},
393                 2,
394                 {
395                     {0, 32768, &MPIR_Allgather_RD_MV2},
396                     {32768, -1, &MPIR_Allgather_Ring_MV2},
397                 },
398             },
399         };
400         table_ptrs[0] = mv2_tmp_allgather_thresholds_table_1ppn;
401         mv2_allgather_table_ppn_conf[1] = 2;
402         mv2_size_allgather_tuning_table[1] = 6;
403         mv2_allgather_tuning_table mv2_tmp_allgather_thresholds_table_2ppn[] = {
404             {
405                 4,
406                 {0,0},
407                 2,
408                 {
409                     {0, 524288, &MPIR_Allgather_RD_MV2},
410                     {524288, -1, &MPIR_Allgather_Ring_MV2},
411                 },
412             },
413             {
414                 8,
415                 {0,1,0},
416                 2,
417                 {
418                     {0, 32768, &MPIR_Allgather_RD_MV2},
419                     {32768, 524288, &MPIR_Allgather_Ring_MV2},
420                     {524288, -1, &MPIR_Allgather_Ring_MV2},
421                 },
422             },
423             {
424                 16,
425                 {0,1,0},
426                 2,
427                 {
428                     {0, 16384, &MPIR_Allgather_RD_MV2},
429                     {16384, 524288, &MPIR_Allgather_Ring_MV2},
430                     {524288, -1, &MPIR_Allgather_Ring_MV2},
431                 },
432             },
433             {
434                 32,
435                 {1,1,0},
436                 2,
437                 {
438                     {0, 65536, &MPIR_Allgather_RD_MV2},
439                     {65536, 524288, &MPIR_Allgather_Ring_MV2},
440                     {524288, -1, &MPIR_Allgather_Ring_MV2},
441                 },
442             },
443             {
444                 64,
445                 {1,1,0},
446                 2,
447                 {
448                     {0, 32768, &MPIR_Allgather_RD_MV2},
449                     {32768, 524288, &MPIR_Allgather_Ring_MV2},
450                     {524288, -1, &MPIR_Allgather_Ring_MV2},
451                 },
452             },
453             {
454                 128,
455                 {1,1,0},
456                 2,
457                 {
458                     {0, 65536, &MPIR_Allgather_RD_MV2},
459                     {65536, 524288, &MPIR_Allgather_Ring_MV2},
460                     {524288, -1, &MPIR_Allgather_Ring_MV2},
461                 },
462             },
463         };
464         table_ptrs[1] = mv2_tmp_allgather_thresholds_table_2ppn;
465         mv2_allgather_table_ppn_conf[2] = 16;
466         mv2_size_allgather_tuning_table[2] = 6;
467         mv2_allgather_tuning_table mv2_tmp_allgather_thresholds_table_16ppn[] = {
468             {
469                 16,
470                 {0,0},
471                 2,
472                 {
473                     {0, 1024, &MPIR_Allgather_RD_MV2},
474                     {1024, -1, &MPIR_Allgather_Ring_MV2},
475                 },
476             },
477             {
478                 32,
479                 {0,0},
480                 2,
481                 {
482                     {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2},
483                     {1024, -1, &MPIR_Allgather_Ring_MV2},
484                 },
485             },
486             {
487                 64,
488                 {0,0},
489                 2,
490                 {
491                     {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2},
492                     {1024, -1, &MPIR_Allgather_Ring_MV2},
493                 },
494             },
495             {
496                 128,
497                 {0,0},
498                 2,
499                 {
500                     {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2},
501                     {1024, -1, &MPIR_Allgather_Ring_MV2},
502                 },
503             },
504             {
505                 256,
506                 {0,0},
507                 2,
508                 {
509                     {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2},
510                     {1024, -1, &MPIR_Allgather_Ring_MV2},
511                 },
512             },
513             {
514                 512,
515                 {0,0},
516                 2,
517                 {
518                     {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2},
519                     {1024, -1, &MPIR_Allgather_Ring_MV2},
520                 },
521             },
522
523         };
524         table_ptrs[2] = mv2_tmp_allgather_thresholds_table_16ppn;
525         agg_table_sum = 0;
526         for (i = 0; i < mv2_allgather_num_ppn_conf; i++) {
527             agg_table_sum += mv2_size_allgather_tuning_table[i];
528         }
529         mv2_allgather_thresholds_table[0] =
530             malloc(agg_table_sum * sizeof (mv2_allgather_tuning_table));
531         memcpy(mv2_allgather_thresholds_table[0], table_ptrs[0],
532             (sizeof(mv2_allgather_tuning_table)
533                      * mv2_size_allgather_tuning_table[0]));
534         for (i = 1; i < mv2_allgather_num_ppn_conf; i++) {
535             mv2_allgather_thresholds_table[i] =
536             mv2_allgather_thresholds_table[i - 1]
537             + mv2_size_allgather_tuning_table[i - 1];
538             memcpy(mv2_allgather_thresholds_table[i], table_ptrs[i],
539                       (sizeof(mv2_allgather_tuning_table)
540                        * mv2_size_allgather_tuning_table[i]));
541         }
542         free(table_ptrs);
543 }
544
545 int smpi_coll_tuned_allgather_mvapich2(void *sendbuf, int sendcount, MPI_Datatype sendtype,
546                        void *recvbuf, int recvcount, MPI_Datatype recvtype,
547                        MPI_Comm comm)
548 {
549
550     int mpi_errno = MPI_SUCCESS;
551     int nbytes = 0, comm_size, recvtype_size;
552     int range = 0;
553     //int partial_sub_ok = 0;
554     int conf_index = 0;
555     int range_threshold = 0;
556     int is_two_level = 0;
557     //int local_size = -1;
558     //MPI_Comm shmem_comm;
559     //MPI_Comm *shmem_commptr=NULL;
560     /* Get the size of the communicator */
561     comm_size = smpi_comm_size(comm);
562     recvtype_size=smpi_datatype_size(recvtype);
563     nbytes = recvtype_size * recvcount;
564
565     if(mv2_allgather_table_ppn_conf==NULL)
566         init_mv2_allgather_tables_stampede();
567         
568     //int i;
569     /* check if safe to use partial subscription mode */
570   /*  if (comm->ch.shmem_coll_ok == 1 && comm->ch.is_uniform) {
571     
572         shmem_comm = comm->ch.shmem_comm;
573         MPID_Comm_get_ptr(shmem_comm, shmem_commptr);
574         local_size = shmem_commptr->local_size;
575         i = 0;
576         if (mv2_allgather_table_ppn_conf[0] == -1) {
577             // Indicating user defined tuning
578             conf_index = 0;
579             goto conf_check_end;
580         }
581         do {
582             if (local_size == mv2_allgather_table_ppn_conf[i]) {
583                 conf_index = i;
584                 partial_sub_ok = 1;
585                 break;
586             }
587             i++;
588         } while(i < mv2_allgather_num_ppn_conf);
589     }
590
591   conf_check_end:
592     if (partial_sub_ok != 1) {
593         conf_index = 0;
594     }*/
595     /* Search for the corresponding system size inside the tuning table */
596     while ((range < (mv2_size_allgather_tuning_table[conf_index] - 1)) &&
597            (comm_size >
598             mv2_allgather_thresholds_table[conf_index][range].numproc)) {
599         range++;
600     }
601     /* Search for corresponding inter-leader function */
602     while ((range_threshold <
603          (mv2_allgather_thresholds_table[conf_index][range].size_inter_table - 1))
604            && (nbytes > mv2_allgather_thresholds_table[conf_index][range].inter_leader[range_threshold].max)
605            && (mv2_allgather_thresholds_table[conf_index][range].inter_leader[range_threshold].max !=
606                -1)) {
607         range_threshold++;
608     }
609
610     /* Set inter-leader pt */
611     MV2_Allgather_function =
612                           mv2_allgather_thresholds_table[conf_index][range].inter_leader[range_threshold].
613                           MV2_pt_Allgather_function;
614
615     is_two_level =  mv2_allgather_thresholds_table[conf_index][range].two_level[range_threshold];
616
617     /* intracommunicator */
618     if(is_two_level ==1){
619         
620  /*       if(comm->ch.shmem_coll_ok == 1){
621             MPIR_T_PVAR_COUNTER_INC(MV2, mv2_num_shmem_coll_calls, 1);
622            if (1 == comm->ch.is_blocked) {
623                 mpi_errno = MPIR_2lvl_Allgather_MV2(sendbuf, sendcount, sendtype,
624                                                     recvbuf, recvcount, recvtype,
625                                                     comm, errflag);
626            }
627            else {
628                mpi_errno = MPIR_Allgather_intra(sendbuf, sendcount, sendtype,
629                                                 recvbuf, recvcount, recvtype,
630                                                 comm, errflag);
631            }
632         } else {*/
633             mpi_errno = MPIR_Allgather_RD_MV2(sendbuf, sendcount, sendtype,
634                                                 recvbuf, recvcount, recvtype,
635                                                 comm);
636    //     }
637     } else if(MV2_Allgather_function == &MPIR_Allgather_Bruck_MV2 
638             || MV2_Allgather_function == &MPIR_Allgather_RD_MV2
639             || MV2_Allgather_function == &MPIR_Allgather_Ring_MV2) {
640             mpi_errno = MV2_Allgather_function(sendbuf, sendcount, sendtype,
641                                           recvbuf, recvcount, recvtype,
642                                           comm);
643     }else{
644       return MPI_ERR_OTHER;
645     }
646
647     return mpi_errno;
648 }
649
650 static void init_mv2_gather_tables_stampede(){
651
652  mv2_size_gather_tuning_table=7;
653       mv2_gather_thresholds_table = malloc(mv2_size_gather_tuning_table*
654                                                 sizeof (mv2_gather_tuning_table)); 
655       mv2_gather_tuning_table mv2_tmp_gather_thresholds_table[]={
656         {16,
657          2,{{0, 524288, &MPIR_Gather_MV2_Direct},
658             {524288, -1, &MPIR_Gather_intra}},
659          1,{{0, -1, &MPIR_Gather_MV2_Direct}}},
660         {32,
661          3,{{0, 16384, &MPIR_Gather_MV2_Direct}, 
662             {16384, 131072, &MPIR_Gather_intra},
663             {131072, -1, &MPIR_Gather_MV2_two_level_Direct}},
664          1,{{0, -1, &MPIR_Gather_intra}}},
665         {64,
666          3,{{0, 256, &MPIR_Gather_MV2_two_level_Direct}, 
667             {256, 16384, &MPIR_Gather_MV2_Direct},
668             {256, -1, &MPIR_Gather_MV2_two_level_Direct}},
669          1,{{0, -1, &MPIR_Gather_intra}}},
670         {128,
671          3,{{0, 512, &MPIR_Gather_MV2_two_level_Direct}, 
672             {512, 16384, &MPIR_Gather_MV2_Direct},
673             {16384, -1, &MPIR_Gather_MV2_two_level_Direct}},
674          1,{{0, -1, &MPIR_Gather_intra}}},
675         {256,
676          3,{{0, 512, &MPIR_Gather_MV2_two_level_Direct}, 
677             {512, 16384, &MPIR_Gather_MV2_Direct},
678             {16384, -1, &MPIR_Gather_MV2_two_level_Direct}},
679          1,{{0, -1, &MPIR_Gather_intra}}},
680         {512,
681          3,{{0, 512, &MPIR_Gather_MV2_two_level_Direct}, 
682             {512, 16384, &MPIR_Gather_MV2_Direct},
683             {8196, -1, &MPIR_Gather_MV2_two_level_Direct}},
684          1,{{0, -1, &MPIR_Gather_intra}}},
685         {1024,
686          3,{{0, 512, &MPIR_Gather_MV2_two_level_Direct}, 
687             {512, 16384, &MPIR_Gather_MV2_Direct},
688             {8196, -1, &MPIR_Gather_MV2_two_level_Direct}},
689          1,{{0, -1, &MPIR_Gather_intra}}},
690       };
691
692       memcpy(mv2_gather_thresholds_table, mv2_tmp_gather_thresholds_table,
693                   mv2_size_gather_tuning_table * sizeof (mv2_gather_tuning_table));
694
695 }
696
697
698 int smpi_coll_tuned_gather_mvapich2(void *sendbuf,
699                     int sendcnt,
700                     MPI_Datatype sendtype,
701                     void *recvbuf,
702                     int recvcnt,
703                     MPI_Datatype recvtype,
704                     int root, MPI_Comm  comm)
705 {
706     if(mv2_alltoall_table_ppn_conf==NULL)
707         init_mv2_alltoall_tables_stampede();
708         
709     int mpi_errno = MPI_SUCCESS;
710     int range = 0;
711     int range_threshold = 0;
712     int range_intra_threshold = 0;
713     int nbytes = 0;
714     int comm_size = 0;
715     int recvtype_size, sendtype_size;
716     int rank = -1;
717     comm_size = smpi_comm_size(comm);
718     rank = smpi_comm_rank(comm);
719
720     if (rank == root) {
721         recvtype_size=smpi_datatype_size(recvtype);
722         nbytes = recvcnt * recvtype_size;
723     } else {
724         sendtype_size=smpi_datatype_size(sendtype);
725         nbytes = sendcnt * sendtype_size;
726     }
727     
728     /* Search for the corresponding system size inside the tuning table */
729     while ((range < (mv2_size_gather_tuning_table - 1)) &&
730            (comm_size > mv2_gather_thresholds_table[range].numproc)) {
731         range++;
732     }
733     /* Search for corresponding inter-leader function */
734     while ((range_threshold < (mv2_gather_thresholds_table[range].size_inter_table - 1))
735            && (nbytes >
736                mv2_gather_thresholds_table[range].inter_leader[range_threshold].max)
737            && (mv2_gather_thresholds_table[range].inter_leader[range_threshold].max !=
738                -1)) {
739         range_threshold++;
740     }
741
742     /* Search for corresponding intra node function */
743     while ((range_intra_threshold < (mv2_gather_thresholds_table[range].size_intra_table - 1))
744            && (nbytes >
745                mv2_gather_thresholds_table[range].intra_node[range_intra_threshold].max)
746            && (mv2_gather_thresholds_table[range].intra_node[range_intra_threshold].max !=
747                -1)) {
748         range_intra_threshold++;
749     }
750 /*
751     if (comm->ch.is_global_block == 1 && mv2_use_direct_gather == 1 &&
752             mv2_use_two_level_gather == 1 && comm->ch.shmem_coll_ok == 1) {
753         // Set intra-node function pt for gather_two_level 
754         MV2_Gather_intra_node_function = 
755                               mv2_gather_thresholds_table[range].intra_node[range_intra_threshold].
756                               MV2_pt_Gather_function;
757         //Set inter-leader pt 
758         MV2_Gather_inter_leader_function =
759                               mv2_gather_thresholds_table[range].inter_leader[range_threshold].
760                               MV2_pt_Gather_function;
761         // We call Gather function 
762         mpi_errno =
763             MV2_Gather_inter_leader_function(sendbuf, sendcnt, sendtype, recvbuf, recvcnt,
764                                              recvtype, root, comm);
765
766     } else {*/
767     // Indded, direct (non SMP-aware)gather is MPICH one 
768         mpi_errno = smpi_coll_tuned_gather_mpich(sendbuf, sendcnt, sendtype,
769                                       recvbuf, recvcnt, recvtype,
770                                       root, comm);
771     //}
772
773     return mpi_errno;
774 }
775