Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / src / smpi / colls / smpi_mvapich2_selector_stampede.hpp
1 /* selector for collective algorithms based on mvapich decision logic, with calibration from Stampede cluster at TACC*/
2 /* This is the tuning used by MVAPICH for Stampede platform based on (MV2_ARCH_INTEL_XEON_E5_2680_16,
3  * MV2_HCA_MLX_CX_FDR) */
4
5 /* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved.          */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 /************ Alltoall variables and initializers                        */
11
12 #ifndef SMPI_MVAPICH2_SELECTOR_STAMPEDE_HPP
13 #define SMPI_MVAPICH2_SELECTOR_STAMPEDE_HPP
14
15 #include <algorithm>
16
17 #define MV2_MAX_NB_THRESHOLDS 32
18
19 XBT_PUBLIC void smpi_coll_cleanup_mvapich2();
20
21 struct mv2_alltoall_tuning_element {
22   int min;
23   int max;
24   int (*MV2_pt_Alltoall_function)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
25                                   MPI_Datatype recvtype, MPI_Comm comm_ptr);
26 };
27
28 struct mv2_alltoall_tuning_table {
29   int numproc;
30   int size_table;
31   mv2_alltoall_tuning_element algo_table[MV2_MAX_NB_THRESHOLDS];
32   mv2_alltoall_tuning_element in_place_algo_table[MV2_MAX_NB_THRESHOLDS];
33 };
34
35 int (*MV2_Alltoall_function)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
36                              MPI_Datatype recvtype, MPI_Comm comm_ptr) = nullptr;
37
38 /* Indicates number of processes per node */
39 int* mv2_alltoall_table_ppn_conf = nullptr;
40 /* Indicates total number of configurations */
41 int mv2_alltoall_num_ppn_conf                             = 1;
42 int* mv2_size_alltoall_tuning_table                       = nullptr;
43 mv2_alltoall_tuning_table** mv2_alltoall_thresholds_table = nullptr;
44
45 #define MPIR_Alltoall_bruck_MV2 simgrid::smpi::alltoall__bruck
46 #define MPIR_Alltoall_RD_MV2 simgrid::smpi::alltoall__rdb
47 #define MPIR_Alltoall_Scatter_dest_MV2 simgrid::smpi::alltoall__mvapich2_scatter_dest
48 #define MPIR_Alltoall_pairwise_MV2 simgrid::smpi::alltoall__pair
49 #define MPIR_Alltoall_inplace_MV2 simgrid::smpi::alltoall__ring
50
51 static void init_mv2_alltoall_tables_stampede()
52 {
53   int agg_table_sum                      = 0;
54   mv2_alltoall_tuning_table** table_ptrs = nullptr;
55   mv2_alltoall_num_ppn_conf              = 3;
56   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
57     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
58   mv2_alltoall_thresholds_table                      = new mv2_alltoall_tuning_table*[mv2_alltoall_num_ppn_conf];
59   table_ptrs                                         = new mv2_alltoall_tuning_table*[mv2_alltoall_num_ppn_conf];
60   mv2_size_alltoall_tuning_table                     = new int[mv2_alltoall_num_ppn_conf];
61   mv2_alltoall_table_ppn_conf                        = new int[mv2_alltoall_num_ppn_conf];
62   mv2_alltoall_table_ppn_conf[0]    = 1;
63   mv2_size_alltoall_tuning_table[0] = 6;
64   mv2_alltoall_tuning_table mv2_tmp_alltoall_thresholds_table_1ppn[] = {
65       {
66           2,
67           1,
68           {
69               {0, -1, &MPIR_Alltoall_pairwise_MV2},
70           },
71
72           {
73               {0, -1, &MPIR_Alltoall_inplace_MV2},
74           },
75       },
76
77       {
78           4,
79           2,
80           {
81               {0, 262144, &MPIR_Alltoall_Scatter_dest_MV2}, {262144, -1, &MPIR_Alltoall_pairwise_MV2},
82           },
83
84           {
85               {0, -1, &MPIR_Alltoall_inplace_MV2},
86           },
87       },
88
89       {
90           8,
91           2,
92           {
93               {0, 8, &MPIR_Alltoall_RD_MV2}, {8, -1, &MPIR_Alltoall_Scatter_dest_MV2},
94           },
95
96           {
97               {0, -1, &MPIR_Alltoall_inplace_MV2},
98           },
99       },
100
101       {
102           16,
103           3,
104           {
105               {0, 64, &MPIR_Alltoall_RD_MV2},
106               {64, 512, &MPIR_Alltoall_bruck_MV2},
107               {512, -1, &MPIR_Alltoall_Scatter_dest_MV2},
108           },
109
110           {
111               {0, -1, &MPIR_Alltoall_inplace_MV2},
112           },
113       },
114
115       {
116           32,
117           3,
118           {
119               {0, 32, &MPIR_Alltoall_RD_MV2},
120               {32, 2048, &MPIR_Alltoall_bruck_MV2},
121               {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
122           },
123
124           {
125               {0, -1, &MPIR_Alltoall_inplace_MV2},
126           },
127       },
128
129       {
130           64,
131           3,
132           {
133               {0, 8, &MPIR_Alltoall_RD_MV2},
134               {8, 1024, &MPIR_Alltoall_bruck_MV2},
135               {1024, -1, &MPIR_Alltoall_Scatter_dest_MV2},
136           },
137
138           {
139               {0, -1, &MPIR_Alltoall_inplace_MV2},
140           },
141       },
142   };
143   table_ptrs[0]                                                      = mv2_tmp_alltoall_thresholds_table_1ppn;
144   mv2_alltoall_table_ppn_conf[1]                                     = 2;
145   mv2_size_alltoall_tuning_table[1]                                  = 6;
146   mv2_alltoall_tuning_table mv2_tmp_alltoall_thresholds_table_2ppn[] = {
147       {
148           4,
149           2,
150           {
151               {0, 32, &MPIR_Alltoall_RD_MV2}, {32, -1, &MPIR_Alltoall_Scatter_dest_MV2},
152           },
153
154           {
155               {0, -1, &MPIR_Alltoall_inplace_MV2},
156           },
157       },
158
159       {
160           8,
161           2,
162           {
163               {0, 64, &MPIR_Alltoall_RD_MV2}, {64, -1, &MPIR_Alltoall_Scatter_dest_MV2},
164           },
165
166           {
167               {0, -1, &MPIR_Alltoall_inplace_MV2},
168           },
169       },
170
171       {
172           16,
173           3,
174           {
175               {0, 64, &MPIR_Alltoall_RD_MV2},
176               {64, 2048, &MPIR_Alltoall_bruck_MV2},
177               {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
178           },
179
180           {
181               {0, -1, &MPIR_Alltoall_inplace_MV2},
182           },
183       },
184
185       {
186           32,
187           3,
188           {
189               {0, 16, &MPIR_Alltoall_RD_MV2},
190               {16, 2048, &MPIR_Alltoall_bruck_MV2},
191               {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
192           },
193
194           {
195               {0, -1, &MPIR_Alltoall_inplace_MV2},
196           },
197       },
198
199       {
200           64,
201           3,
202           {
203               {0, 8, &MPIR_Alltoall_RD_MV2},
204               {8, 1024, &MPIR_Alltoall_bruck_MV2},
205               {1024, -1, &MPIR_Alltoall_Scatter_dest_MV2},
206           },
207
208           {
209               {0, -1, &MPIR_Alltoall_inplace_MV2},
210           },
211       },
212
213       {
214           128,
215           3,
216           {
217               {0, 4, &MPIR_Alltoall_RD_MV2},
218               {4, 2048, &MPIR_Alltoall_bruck_MV2},
219               {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
220           },
221
222           {
223               {0, -1, &MPIR_Alltoall_inplace_MV2},
224           },
225       },
226   };
227   table_ptrs[1]                                                       = mv2_tmp_alltoall_thresholds_table_2ppn;
228   mv2_alltoall_table_ppn_conf[2]                                      = 16;
229   mv2_size_alltoall_tuning_table[2]                                   = 7;
230   mv2_alltoall_tuning_table mv2_tmp_alltoall_thresholds_table_16ppn[] = {
231       {
232           16,
233           2,
234           {
235               {0, 2048, &MPIR_Alltoall_bruck_MV2}, {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
236           },
237
238           {
239               {32768, -1, &MPIR_Alltoall_inplace_MV2},
240           },
241       },
242
243       {
244           32,
245           2,
246           {
247               {0, 2048, &MPIR_Alltoall_bruck_MV2}, {2048, -1, &MPIR_Alltoall_Scatter_dest_MV2},
248           },
249
250           {
251               {16384, -1, &MPIR_Alltoall_inplace_MV2},
252           },
253       },
254
255       {
256           64,
257           3,
258           {
259               {0, 2048, &MPIR_Alltoall_bruck_MV2},
260               {2048, 16384, &MPIR_Alltoall_Scatter_dest_MV2},
261               {16384, -1, &MPIR_Alltoall_pairwise_MV2},
262           },
263
264           {
265               {32768, 131072, &MPIR_Alltoall_inplace_MV2},
266           },
267       },
268
269       {
270           128,
271           2,
272           {
273               {0, 2048, &MPIR_Alltoall_bruck_MV2}, {2048, -1, &MPIR_Alltoall_pairwise_MV2},
274           },
275
276           {
277               {16384, 65536, &MPIR_Alltoall_inplace_MV2},
278           },
279       },
280
281       {
282           256,
283           2,
284           {
285               {0, 1024, &MPIR_Alltoall_bruck_MV2}, {1024, -1, &MPIR_Alltoall_pairwise_MV2},
286           },
287
288           {
289               {16384, 65536, &MPIR_Alltoall_inplace_MV2},
290           },
291       },
292
293       {
294           512,
295           2,
296           {
297               {0, 1024, &MPIR_Alltoall_bruck_MV2}, {1024, -1, &MPIR_Alltoall_pairwise_MV2},
298           },
299
300           {
301               {16384, 65536, &MPIR_Alltoall_inplace_MV2},
302           },
303       },
304       {
305           1024,
306           2,
307           {
308               {0, 1024, &MPIR_Alltoall_bruck_MV2}, {1024, -1, &MPIR_Alltoall_pairwise_MV2},
309           },
310
311           {
312               {16384, 65536, &MPIR_Alltoall_inplace_MV2},
313           },
314       },
315
316   };
317   table_ptrs[2] = mv2_tmp_alltoall_thresholds_table_16ppn;
318   agg_table_sum = 0;
319   for (int i = 0; i < mv2_alltoall_num_ppn_conf; i++) {
320     agg_table_sum += mv2_size_alltoall_tuning_table[i];
321   }
322   mv2_alltoall_thresholds_table[0] = new mv2_alltoall_tuning_table[agg_table_sum];
323   std::copy_n(table_ptrs[0], mv2_size_alltoall_tuning_table[0], mv2_alltoall_thresholds_table[0]);
324   for (int i = 1; i < mv2_alltoall_num_ppn_conf; i++) {
325     mv2_alltoall_thresholds_table[i] = mv2_alltoall_thresholds_table[i - 1] + mv2_size_alltoall_tuning_table[i - 1];
326     std::copy_n(table_ptrs[i], mv2_size_alltoall_tuning_table[i], mv2_alltoall_thresholds_table[i]);
327   }
328   delete[] table_ptrs;
329 }
330
331 /************ Allgather variables and initializers                        */
332
333 struct mv2_allgather_tuning_element {
334   int min;
335   int max;
336   int (*MV2_pt_Allgatherction)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
337                                MPI_Datatype recvtype, MPI_Comm comm_ptr);
338 };
339
340 struct mv2_allgather_tuning_table {
341   int numproc;
342   bool two_level[MV2_MAX_NB_THRESHOLDS];
343   int size_inter_table;
344   mv2_allgather_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
345 };
346
347 int (*MV2_Allgatherction)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
348                           MPI_Datatype recvtype, MPI_Comm comm);
349
350 int* mv2_allgather_table_ppn_conf                           = nullptr;
351 int mv2_allgather_num_ppn_conf                              = 1;
352 int* mv2_size_allgather_tuning_table                        = nullptr;
353 mv2_allgather_tuning_table** mv2_allgather_thresholds_table = nullptr;
354
355 static int MPIR_Allgather_RD_Allgather_Comm_MV2(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
356                                                 int recvcount, MPI_Datatype recvtype, MPI_Comm comm_ptr)
357 {
358   return 0;
359 }
360
361 #define MPIR_Allgather_Bruck_MV2 simgrid::smpi::allgather__bruck
362 #define MPIR_Allgather_RD_MV2 simgrid::smpi::allgather__rdb
363 #define MPIR_Allgather_Ring_MV2 simgrid::smpi::allgather__ring
364 #define MPIR_2lvl_Allgather_MV2 simgrid::smpi::allgather__mvapich2_smp
365
366 static void init_mv2_allgather_tables_stampede()
367 {
368   int agg_table_sum = 0;
369
370   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
371     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
372   mv2_allgather_num_ppn_conf                         = 3;
373   mv2_allgather_thresholds_table                     = new mv2_allgather_tuning_table*[mv2_allgather_num_ppn_conf];
374   auto** table_ptrs                                  = new mv2_allgather_tuning_table*[mv2_allgather_num_ppn_conf];
375   mv2_size_allgather_tuning_table                    = new int[mv2_allgather_num_ppn_conf];
376   mv2_allgather_table_ppn_conf                       = new int[mv2_allgather_num_ppn_conf];
377   mv2_allgather_table_ppn_conf[0]    = 1;
378   mv2_size_allgather_tuning_table[0] = 6;
379   mv2_allgather_tuning_table mv2_tmp_allgather_thresholds_table_1ppn[] = {
380       {
381           2,
382           {false},
383           1,
384           {
385               {0, -1, &MPIR_Allgather_Ring_MV2},
386           },
387       },
388       {
389           4,
390           {false, false},
391           2,
392           {
393               {0, 262144, &MPIR_Allgather_RD_MV2}, {262144, -1, &MPIR_Allgather_Ring_MV2},
394           },
395       },
396       {
397           8,
398           {false, false},
399           2,
400           {
401               {0, 131072, &MPIR_Allgather_RD_MV2}, {131072, -1, &MPIR_Allgather_Ring_MV2},
402           },
403       },
404       {
405           16,
406           {false, false},
407           2,
408           {
409               {0, 131072, &MPIR_Allgather_RD_MV2}, {131072, -1, &MPIR_Allgather_Ring_MV2},
410           },
411       },
412       {
413           32,
414           {false, false},
415           2,
416           {
417               {0, 65536, &MPIR_Allgather_RD_MV2}, {65536, -1, &MPIR_Allgather_Ring_MV2},
418           },
419       },
420       {
421           64,
422           {false, false},
423           2,
424           {
425               {0, 32768, &MPIR_Allgather_RD_MV2}, {32768, -1, &MPIR_Allgather_Ring_MV2},
426           },
427       },
428   };
429   table_ptrs[0]                                                        = mv2_tmp_allgather_thresholds_table_1ppn;
430   mv2_allgather_table_ppn_conf[1]                                      = 2;
431   mv2_size_allgather_tuning_table[1]                                   = 6;
432   mv2_allgather_tuning_table mv2_tmp_allgather_thresholds_table_2ppn[] = {
433       {
434           4,
435           {false, false},
436           2,
437           {
438               {0, 524288, &MPIR_Allgather_RD_MV2}, {524288, -1, &MPIR_Allgather_Ring_MV2},
439           },
440       },
441       {
442           8,
443           {false, true, false},
444           2,
445           {
446               {0, 32768, &MPIR_Allgather_RD_MV2},
447               {32768, 524288, &MPIR_Allgather_Ring_MV2},
448               {524288, -1, &MPIR_Allgather_Ring_MV2},
449           },
450       },
451       {
452           16,
453           {false, true, false},
454           2,
455           {
456               {0, 16384, &MPIR_Allgather_RD_MV2},
457               {16384, 524288, &MPIR_Allgather_Ring_MV2},
458               {524288, -1, &MPIR_Allgather_Ring_MV2},
459           },
460       },
461       {
462           32,
463           {true, true, false},
464           2,
465           {
466               {0, 65536, &MPIR_Allgather_RD_MV2},
467               {65536, 524288, &MPIR_Allgather_Ring_MV2},
468               {524288, -1, &MPIR_Allgather_Ring_MV2},
469           },
470       },
471       {
472           64,
473           {true, true, false},
474           2,
475           {
476               {0, 32768, &MPIR_Allgather_RD_MV2},
477               {32768, 524288, &MPIR_Allgather_Ring_MV2},
478               {524288, -1, &MPIR_Allgather_Ring_MV2},
479           },
480       },
481       {
482           128,
483           {true, true, false},
484           2,
485           {
486               {0, 65536, &MPIR_Allgather_RD_MV2},
487               {65536, 524288, &MPIR_Allgather_Ring_MV2},
488               {524288, -1, &MPIR_Allgather_Ring_MV2},
489           },
490       },
491   };
492   table_ptrs[1]                                                         = mv2_tmp_allgather_thresholds_table_2ppn;
493   mv2_allgather_table_ppn_conf[2]                                       = 16;
494   mv2_size_allgather_tuning_table[2]                                    = 6;
495   mv2_allgather_tuning_table mv2_tmp_allgather_thresholds_table_16ppn[] = {
496       {
497           16,
498           {false, false},
499           2,
500           {
501               {0, 1024, &MPIR_Allgather_RD_MV2}, {1024, -1, &MPIR_Allgather_Ring_MV2},
502           },
503       },
504       {
505           32,
506           {false, false},
507           2,
508           {
509               {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2}, {1024, -1, &MPIR_Allgather_Ring_MV2},
510           },
511       },
512       {
513           64,
514           {false, false},
515           2,
516           {
517               {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2}, {1024, -1, &MPIR_Allgather_Ring_MV2},
518           },
519       },
520       {
521           128,
522           {false, false},
523           2,
524           {
525               {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2}, {1024, -1, &MPIR_Allgather_Ring_MV2},
526           },
527       },
528       {
529           256,
530           {false, false},
531           2,
532           {
533               {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2}, {1024, -1, &MPIR_Allgather_Ring_MV2},
534           },
535       },
536       {
537           512,
538           {false, false},
539           2,
540           {
541               {0, 1024, &MPIR_Allgather_RD_Allgather_Comm_MV2}, {1024, -1, &MPIR_Allgather_Ring_MV2},
542           },
543       },
544
545   };
546   table_ptrs[2] = mv2_tmp_allgather_thresholds_table_16ppn;
547   agg_table_sum = 0;
548   for (int i = 0; i < mv2_allgather_num_ppn_conf; i++) {
549     agg_table_sum += mv2_size_allgather_tuning_table[i];
550   }
551   mv2_allgather_thresholds_table[0] = new mv2_allgather_tuning_table[agg_table_sum];
552   std::copy_n(table_ptrs[0], mv2_size_allgather_tuning_table[0], mv2_allgather_thresholds_table[0]);
553   for (int i = 1; i < mv2_allgather_num_ppn_conf; i++) {
554     mv2_allgather_thresholds_table[i] = mv2_allgather_thresholds_table[i - 1] + mv2_size_allgather_tuning_table[i - 1];
555     std::copy_n(table_ptrs[i], mv2_size_allgather_tuning_table[i], mv2_allgather_thresholds_table[i]);
556   }
557   delete[] table_ptrs;
558 }
559
560 /************ Gather variables and initializers                        */
561
562 struct mv2_gather_tuning_element {
563   int min;
564   int max;
565   int (*MV2_pt_Gather_function)(const void* sendbuf, int sendcnt, MPI_Datatype sendtype, void* recvbuf, int recvcnt,
566                                 MPI_Datatype recvtype, int root, MPI_Comm comm_ptr);
567 };
568
569 struct mv2_gather_tuning_table {
570   int numproc;
571   int size_inter_table;
572   mv2_gather_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
573   int size_intra_table;
574   mv2_gather_tuning_element intra_node[MV2_MAX_NB_THRESHOLDS];
575 };
576
577 int mv2_size_gather_tuning_table                     = 7;
578 mv2_gather_tuning_table* mv2_gather_thresholds_table = nullptr;
579
580 typedef int (*MV2_Gather_function_ptr)(const void* sendbuf, int sendcnt, MPI_Datatype sendtype, void* recvbuf, int recvcnt,
581                                        MPI_Datatype recvtype, int root, MPI_Comm comm);
582
583 MV2_Gather_function_ptr MV2_Gather_inter_leader_function = nullptr;
584 MV2_Gather_function_ptr MV2_Gather_intra_node_function   = nullptr;
585
586 #define MPIR_Gather_MV2_Direct simgrid::smpi::gather__ompi_basic_linear
587 #define MPIR_Gather_MV2_two_level_Direct simgrid::smpi::gather__mvapich2_two_level
588 #define MPIR_Gather_intra simgrid::smpi::gather__mpich
589
590 static void init_mv2_gather_tables_stampede()
591 {
592
593   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
594     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
595   mv2_size_gather_tuning_table                       = 7;
596   mv2_gather_thresholds_table                               = new mv2_gather_tuning_table[mv2_size_gather_tuning_table];
597   mv2_gather_tuning_table mv2_tmp_gather_thresholds_table[] = {
598       {16,
599        2,
600        {{0, 524288, &MPIR_Gather_MV2_Direct}, {524288, -1, &MPIR_Gather_intra}},
601        1,
602        {{0, -1, &MPIR_Gather_MV2_Direct}}},
603       {32,
604        3,
605        {{0, 16384, &MPIR_Gather_MV2_Direct},
606         {16384, 131072, &MPIR_Gather_intra},
607         {131072, -1, &MPIR_Gather_MV2_two_level_Direct}},
608        1,
609        {{0, -1, &MPIR_Gather_intra}}},
610       {64,
611        3,
612        {{0, 256, &MPIR_Gather_MV2_two_level_Direct},
613         {256, 16384, &MPIR_Gather_MV2_Direct},
614         {256, -1, &MPIR_Gather_MV2_two_level_Direct}},
615        1,
616        {{0, -1, &MPIR_Gather_intra}}},
617       {128,
618        3,
619        {{0, 512, &MPIR_Gather_MV2_two_level_Direct},
620         {512, 16384, &MPIR_Gather_MV2_Direct},
621         {16384, -1, &MPIR_Gather_MV2_two_level_Direct}},
622        1,
623        {{0, -1, &MPIR_Gather_intra}}},
624       {256,
625        3,
626        {{0, 512, &MPIR_Gather_MV2_two_level_Direct},
627         {512, 16384, &MPIR_Gather_MV2_Direct},
628         {16384, -1, &MPIR_Gather_MV2_two_level_Direct}},
629        1,
630        {{0, -1, &MPIR_Gather_intra}}},
631       {512,
632        3,
633        {{0, 512, &MPIR_Gather_MV2_two_level_Direct},
634         {512, 16384, &MPIR_Gather_MV2_Direct},
635         {8196, -1, &MPIR_Gather_MV2_two_level_Direct}},
636        1,
637        {{0, -1, &MPIR_Gather_intra}}},
638       {1024,
639        3,
640        {{0, 512, &MPIR_Gather_MV2_two_level_Direct},
641         {512, 16384, &MPIR_Gather_MV2_Direct},
642         {8196, -1, &MPIR_Gather_MV2_two_level_Direct}},
643        1,
644        {{0, -1, &MPIR_Gather_intra}}},
645   };
646
647   std::copy_n(mv2_tmp_gather_thresholds_table, mv2_size_gather_tuning_table, mv2_gather_thresholds_table);
648 }
649
650 /************ Allgatherv variables and initializers                        */
651
652 struct mv2_allgatherv_tuning_element {
653   int min;
654   int max;
655   int (*MV2_pt_Allgatherv_function)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int* recvcounts,
656                                     const int* displs, MPI_Datatype recvtype, MPI_Comm commg);
657 };
658
659 struct mv2_allgatherv_tuning_table {
660   int numproc;
661   int size_inter_table;
662   mv2_allgatherv_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
663 };
664
665 int (*MV2_Allgatherv_function)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int* recvcounts,
666                                const int* displs, MPI_Datatype recvtype, MPI_Comm comm);
667
668 int mv2_size_allgatherv_tuning_table                         = 0;
669 mv2_allgatherv_tuning_table* mv2_allgatherv_thresholds_table = nullptr;
670
671 #define MPIR_Allgatherv_Rec_Doubling_MV2 simgrid::smpi::allgatherv__mpich_rdb
672 #define MPIR_Allgatherv_Bruck_MV2 simgrid::smpi::allgatherv__ompi_bruck
673 #define MPIR_Allgatherv_Ring_MV2 simgrid::smpi::allgatherv__mpich_ring
674
675 static void init_mv2_allgatherv_tables_stampede()
676 {
677   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
678     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
679   mv2_size_allgatherv_tuning_table                   = 6;
680   mv2_allgatherv_thresholds_table = new mv2_allgatherv_tuning_table[mv2_size_allgatherv_tuning_table];
681   mv2_allgatherv_tuning_table mv2_tmp_allgatherv_thresholds_table[] = {
682       {
683           16,
684           2,
685           {
686               {0, 512, &MPIR_Allgatherv_Rec_Doubling_MV2}, {512, -1, &MPIR_Allgatherv_Ring_MV2},
687           },
688       },
689       {
690           32,
691           2,
692           {
693               {0, 512, &MPIR_Allgatherv_Rec_Doubling_MV2}, {512, -1, &MPIR_Allgatherv_Ring_MV2},
694           },
695       },
696       {
697           64,
698           2,
699           {
700               {0, 256, &MPIR_Allgatherv_Rec_Doubling_MV2}, {256, -1, &MPIR_Allgatherv_Ring_MV2},
701           },
702       },
703       {
704           128,
705           2,
706           {
707               {0, 256, &MPIR_Allgatherv_Rec_Doubling_MV2}, {256, -1, &MPIR_Allgatherv_Ring_MV2},
708           },
709       },
710       {
711           256,
712           2,
713           {
714               {0, 256, &MPIR_Allgatherv_Rec_Doubling_MV2}, {256, -1, &MPIR_Allgatherv_Ring_MV2},
715           },
716       },
717       {
718           512,
719           2,
720           {
721               {0, 256, &MPIR_Allgatherv_Rec_Doubling_MV2}, {256, -1, &MPIR_Allgatherv_Ring_MV2},
722           },
723       },
724
725   };
726   std::copy_n(mv2_tmp_allgatherv_thresholds_table, mv2_size_allgatherv_tuning_table, mv2_allgatherv_thresholds_table);
727 }
728
729 /************ Allreduce variables and initializers                        */
730
731 struct mv2_allreduce_tuning_element {
732   int min;
733   int max;
734   int (*MV2_pt_Allreducection)(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
735                                MPI_Comm comm);
736 };
737
738 struct mv2_allreduce_tuning_table {
739   int numproc;
740   bool mcast_enabled;
741   bool is_two_level_allreduce[MV2_MAX_NB_THRESHOLDS];
742   int size_inter_table;
743   mv2_allreduce_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
744   int size_intra_table;
745   mv2_allreduce_tuning_element intra_node[MV2_MAX_NB_THRESHOLDS];
746 };
747
748 int (*MV2_Allreducection)(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
749                           MPI_Comm comm) = nullptr;
750
751 int (*MV2_Allreduce_intra_function)(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
752                                     MPI_Comm comm) = nullptr;
753
754 int mv2_size_allreduce_tuning_table                        = 0;
755 mv2_allreduce_tuning_table* mv2_allreduce_thresholds_table = nullptr;
756
757 static int MPIR_Allreduce_mcst_reduce_two_level_helper_MV2(const void* sendbuf, void* recvbuf, int count,
758                                                            MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
759 {
760   return 0;
761 }
762
763 static int MPIR_Allreduce_mcst_reduce_redscat_gather_MV2(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype,
764                                                          MPI_Op op, MPI_Comm comm)
765 {
766   return 0;
767 }
768
769 static int MPIR_Allreduce_reduce_p2p_MV2(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
770                                          MPI_Comm comm)
771 {
772   simgrid::smpi::colls::reduce(sendbuf, recvbuf, count, datatype, op, 0, comm);
773   return MPI_SUCCESS;
774 }
775
776 static int MPIR_Allreduce_reduce_shmem_MV2(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
777                                            MPI_Comm comm)
778 {
779   simgrid::smpi::colls::reduce(sendbuf, recvbuf, count, datatype, op, 0, comm);
780   return MPI_SUCCESS;
781 }
782
783 #define MPIR_Allreduce_pt2pt_rd_MV2 simgrid::smpi::allreduce__rdb
784 #define MPIR_Allreduce_pt2pt_rs_MV2 simgrid::smpi::allreduce__mvapich2_rs
785 #define MPIR_Allreduce_two_level_MV2 simgrid::smpi::allreduce__mvapich2_two_level
786
787 static void init_mv2_allreduce_tables_stampede()
788 {
789   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
790     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
791   mv2_size_allreduce_tuning_table                    = 8;
792   mv2_allreduce_thresholds_table                     = new mv2_allreduce_tuning_table[mv2_size_allreduce_tuning_table];
793   mv2_allreduce_tuning_table mv2_tmp_allreduce_thresholds_table[] = {
794       {
795           16,
796           false,
797           {true, false},
798           2,
799           {
800               {0, 1024, &MPIR_Allreduce_pt2pt_rd_MV2}, {1024, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
801           },
802           2,
803           {
804               {0, 1024, &MPIR_Allreduce_reduce_shmem_MV2}, {1024, -1, &MPIR_Allreduce_reduce_p2p_MV2},
805           },
806       },
807       {
808           32,
809           false,
810           {true, true, false},
811           3,
812           {
813               {0, 1024, &MPIR_Allreduce_pt2pt_rd_MV2},
814               {1024, 16384, &MPIR_Allreduce_pt2pt_rd_MV2},
815               {16384, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
816           },
817           2,
818           {
819               {0, 1024, &MPIR_Allreduce_reduce_shmem_MV2}, {1024, 16384, &MPIR_Allreduce_reduce_p2p_MV2},
820           },
821       },
822       {
823           64,
824           false,
825           {true, true, false},
826           3,
827           {
828               {0, 512, &MPIR_Allreduce_pt2pt_rd_MV2},
829               {512, 16384, &MPIR_Allreduce_pt2pt_rd_MV2},
830               {16384, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
831           },
832           2,
833           {
834               {0, 512, &MPIR_Allreduce_reduce_shmem_MV2}, {512, 16384, &MPIR_Allreduce_reduce_p2p_MV2},
835           },
836       },
837       {
838           128,
839           false,
840           {true, true, false},
841           3,
842           {
843               {0, 512, &MPIR_Allreduce_pt2pt_rd_MV2},
844               {512, 16384, &MPIR_Allreduce_pt2pt_rd_MV2},
845               {16384, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
846           },
847           2,
848           {
849               {0, 512, &MPIR_Allreduce_reduce_shmem_MV2}, {512, 16384, &MPIR_Allreduce_reduce_p2p_MV2},
850           },
851       },
852       {
853           256,
854           false,
855           {true, true, false},
856           3,
857           {
858               {0, 512, &MPIR_Allreduce_pt2pt_rd_MV2},
859               {512, 16384, &MPIR_Allreduce_pt2pt_rd_MV2},
860               {16384, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
861           },
862           2,
863           {
864               {0, 512, &MPIR_Allreduce_reduce_shmem_MV2}, {512, -1, &MPIR_Allreduce_reduce_p2p_MV2},
865           },
866       },
867       {
868           512,
869           false,
870           {true, true, false},
871           3,
872           {
873               {0, 512, &MPIR_Allreduce_pt2pt_rd_MV2},
874               {512, 16384, &MPIR_Allreduce_pt2pt_rd_MV2},
875               {16384, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
876           },
877           2,
878           {
879               {0, 512, &MPIR_Allreduce_reduce_shmem_MV2}, {512, 16384, &MPIR_Allreduce_reduce_p2p_MV2},
880           },
881       },
882       {
883           1024,
884           false,
885           {true, true, true, false},
886           4,
887           {
888               {0, 512, &MPIR_Allreduce_pt2pt_rd_MV2},
889               {512, 8192, &MPIR_Allreduce_pt2pt_rd_MV2},
890               {8192, 65536, &MPIR_Allreduce_pt2pt_rs_MV2},
891               {65536, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
892           },
893           2,
894           {
895               {0, 512, &MPIR_Allreduce_reduce_shmem_MV2}, {512, -1, &MPIR_Allreduce_reduce_p2p_MV2},
896           },
897       },
898       {
899           2048,
900           false,
901           {true, true, true, false},
902           4,
903           {
904               {0, 64, &MPIR_Allreduce_pt2pt_rd_MV2},
905               {64, 512, &MPIR_Allreduce_reduce_p2p_MV2},
906               {512, 4096, &MPIR_Allreduce_mcst_reduce_two_level_helper_MV2},
907               {4096, 16384, &MPIR_Allreduce_pt2pt_rs_MV2},
908               {16384, -1, &MPIR_Allreduce_pt2pt_rs_MV2},
909           },
910           2,
911           {
912               {0, 512, &MPIR_Allreduce_reduce_shmem_MV2}, {512, -1, &MPIR_Allreduce_reduce_p2p_MV2},
913           },
914       },
915
916   };
917   std::copy_n(mv2_tmp_allreduce_thresholds_table, mv2_size_allreduce_tuning_table, mv2_allreduce_thresholds_table);
918 }
919
920 struct mv2_bcast_tuning_element {
921   int min;
922   int max;
923   int (*MV2_pt_Bcast_function)(void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm_ptr);
924   int zcpy_pipelined_knomial_factor;
925 };
926
927 struct mv2_bcast_tuning_table {
928   int numproc;
929   int bcast_segment_size;
930   int intra_node_knomial_factor;
931   int inter_node_knomial_factor;
932   bool is_two_level_bcast[MV2_MAX_NB_THRESHOLDS];
933   int size_inter_table;
934   mv2_bcast_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
935   int size_intra_table;
936   mv2_bcast_tuning_element intra_node[MV2_MAX_NB_THRESHOLDS];
937 };
938
939 int mv2_size_bcast_tuning_table                    = 0;
940 mv2_bcast_tuning_table* mv2_bcast_thresholds_table = nullptr;
941
942 int (*MV2_Bcast_function)(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm_ptr) = nullptr;
943
944 int (*MV2_Bcast_intra_node_function)(void* buffer, int count, MPI_Datatype datatype, int root,
945                                      MPI_Comm comm_ptr) = nullptr;
946
947 int zcpy_knomial_factor               = 2;
948 int mv2_pipelined_zcpy_knomial_factor = -1;
949 int bcast_segment_size                = 8192;
950 int mv2_inter_node_knomial_factor     = 4;
951 int mv2_intra_node_knomial_factor     = 4;
952 #define mv2_bcast_two_level_system_size 64
953 #define mv2_bcast_short_msg 16384
954 #define mv2_bcast_large_msg 512 * 1024
955
956 #define INTRA_NODE_ROOT 0
957
958 #define MPIR_Pipelined_Bcast_Zcpy_MV2 simgrid::smpi::bcast__mpich
959 #define MPIR_Pipelined_Bcast_MV2 simgrid::smpi::bcast__mpich
960 #define MPIR_Bcast_binomial_MV2 simgrid::smpi::bcast__binomial_tree
961 #define MPIR_Bcast_scatter_ring_allgather_shm_MV2 simgrid::smpi::bcast__scatter_LR_allgather
962 #define MPIR_Bcast_scatter_doubling_allgather_MV2 simgrid::smpi::bcast__scatter_rdb_allgather
963 #define MPIR_Bcast_scatter_ring_allgather_MV2 simgrid::smpi::bcast__scatter_LR_allgather
964 #define MPIR_Shmem_Bcast_MV2 simgrid::smpi::bcast__mpich
965 #define MPIR_Bcast_tune_inter_node_helper_MV2 simgrid::smpi::bcast__mvapich2_inter_node
966 #define MPIR_Bcast_inter_node_helper_MV2 simgrid::smpi::bcast__mvapich2_inter_node
967 #define MPIR_Knomial_Bcast_intra_node_MV2 simgrid::smpi::bcast__mvapich2_knomial_intra_node
968 #define MPIR_Bcast_intra_MV2 simgrid::smpi::bcast__mvapich2_intra_node
969
970 static void init_mv2_bcast_tables_stampede()
971 {
972   // Stampede,
973   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
974     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
975   mv2_size_bcast_tuning_table                        = 8;
976   mv2_bcast_thresholds_table                         = new mv2_bcast_tuning_table[mv2_size_bcast_tuning_table];
977
978   mv2_bcast_tuning_table mv2_tmp_bcast_thresholds_table[] = {
979       {16,
980        8192,
981        4,
982        4,
983        {true, true, true, true, true, true, true, true, true, true, true},
984        11,
985        {{0, 8, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
986         {8, 16, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
987         {16, 1024, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
988         {1024, 8192, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
989         {8192, 16384, &MPIR_Bcast_binomial_MV2, -1},
990         {16384, 32768, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
991         {32768, 65536, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
992         {65536, 131072, &MPIR_Bcast_scatter_ring_allgather_shm_MV2, -1},
993         {131072, 262144, &MPIR_Bcast_scatter_ring_allgather_MV2, -1},
994         {262144, 524288, &MPIR_Bcast_scatter_doubling_allgather_MV2, -1},
995         {524288, -1, &MPIR_Bcast_scatter_ring_allgather_MV2, -1}},
996        11,
997        {{0, 8, &MPIR_Shmem_Bcast_MV2, 2},
998         {8, 16, &MPIR_Shmem_Bcast_MV2, 4},
999         {16, 1024, &MPIR_Shmem_Bcast_MV2, 2},
1000         {1024, 8192, &MPIR_Shmem_Bcast_MV2, 4},
1001         {8192, 16384, &MPIR_Shmem_Bcast_MV2, -1},
1002         {16384, 32768, &MPIR_Shmem_Bcast_MV2, 4},
1003         {32768, 65536, &MPIR_Shmem_Bcast_MV2, 2},
1004         {65536, 131072, &MPIR_Shmem_Bcast_MV2, -1},
1005         {131072, 262144, &MPIR_Shmem_Bcast_MV2, -1},
1006         {262144, 524288, &MPIR_Shmem_Bcast_MV2, -1},
1007         {524288, -1, &MPIR_Shmem_Bcast_MV2, -1}}},
1008       {32,
1009        8192,
1010        4,
1011        4,
1012        {true, true, true, true, true, true, true, true},
1013        8,
1014        {{0, 128, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1015         {128, 256, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1016         {256, 32768, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1017         {32768, 65536, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1018         {65536, 131072, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1019         {131072, 262144, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1020         {262144, 524288, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1021         {524288, -1, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8}},
1022        8,
1023        {{0, 128, &MPIR_Shmem_Bcast_MV2, 2},
1024         {128, 256, &MPIR_Shmem_Bcast_MV2, 4},
1025         {256, 32768, &MPIR_Shmem_Bcast_MV2, 2},
1026         {32768, 65536, &MPIR_Shmem_Bcast_MV2, 4},
1027         {65536, 131072, &MPIR_Shmem_Bcast_MV2, 2},
1028         {131072, 262144, &MPIR_Shmem_Bcast_MV2, 8},
1029         {262144, 524288, &MPIR_Shmem_Bcast_MV2, 2},
1030         {524288, -1, &MPIR_Shmem_Bcast_MV2, 8}}},
1031       {64,
1032        8192,
1033        4,
1034        4,
1035        {true, true, true, true, true, true, true, true, true},
1036        9,
1037        {{0, 2, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1038         {2, 4, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1039         {4, 16, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1040         {16, 32, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1041         {32, 128, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1042         {128, 256, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1043         {256, 4096, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1044         {4096, 32768, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1045         {32768, -1, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2}},
1046        9,
1047        {{0, 2, &MPIR_Shmem_Bcast_MV2, 4},
1048         {2, 4, &MPIR_Shmem_Bcast_MV2, 8},
1049         {4, 16, &MPIR_Shmem_Bcast_MV2, 4},
1050         {16, 32, &MPIR_Shmem_Bcast_MV2, 8},
1051         {32, 128, &MPIR_Shmem_Bcast_MV2, 4},
1052         {128, 256, &MPIR_Shmem_Bcast_MV2, 8},
1053         {256, 4096, &MPIR_Shmem_Bcast_MV2, 4},
1054         {4096, 32768, &MPIR_Shmem_Bcast_MV2, 8},
1055         {32768, -1, &MPIR_Shmem_Bcast_MV2, 2}}},
1056       {128,
1057        8192,
1058        4,
1059        4,
1060        {true, true, true, false},
1061        4,
1062        {{0, 8192, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1063         {8192, 16384, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1064         {16384, 524288, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1065         {524288, -1, &MPIR_Bcast_scatter_ring_allgather_MV2, -1}},
1066        4,
1067        {{0, 8192, &MPIR_Shmem_Bcast_MV2, 8},
1068         {8192, 16384, &MPIR_Shmem_Bcast_MV2, 4},
1069         {16384, 524288, &MPIR_Shmem_Bcast_MV2, 2},
1070         {524288, -1, nullptr, -1}}},
1071       {256,
1072        8192,
1073        4,
1074        4,
1075        {true, true, true, true, true},
1076        5,
1077        {{0, 16384, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1078         {16384, 131072, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1079         {131072, 262144, &MPIR_Bcast_scatter_ring_allgather_shm_MV2, -1},
1080         {262144, 524288, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1081         {524288, -1, &MPIR_Bcast_scatter_ring_allgather_shm_MV2, -1}},
1082        5,
1083        {{0, 16384, &MPIR_Shmem_Bcast_MV2, 4},
1084         {16384, 131072, &MPIR_Shmem_Bcast_MV2, 2},
1085         {131072, 262144, &MPIR_Shmem_Bcast_MV2, -1},
1086         {262144, 524288, &MPIR_Shmem_Bcast_MV2, 2},
1087         {524288, -1, &MPIR_Shmem_Bcast_MV2, -1}}},
1088       {512,
1089        8192,
1090        4,
1091        4,
1092        {true, true, true, true, true},
1093        5,
1094        {{0, 4096, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1095         {4096, 16384, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1096         {16384, 131072, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1097         {131072, 262144, &MPIR_Pipelined_Bcast_MV2, -1},
1098         {262144, -1, &MPIR_Bcast_scatter_ring_allgather_shm_MV2, -1}},
1099        5,
1100        {{0, 4096, &MPIR_Shmem_Bcast_MV2, 8},
1101         {4096, 16384, &MPIR_Shmem_Bcast_MV2, 4},
1102         {16384, 131072, &MPIR_Shmem_Bcast_MV2, 2},
1103         {131072, 262144, &MPIR_Shmem_Bcast_MV2, -1},
1104         {262144, -1, &MPIR_Shmem_Bcast_MV2, -1}}},
1105       {1024,
1106        8192,
1107        4,
1108        4,
1109        {true, true, true, true, true},
1110        5,
1111        {{0, 8192, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1112         {8192, 16384, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1113         {16384, 65536, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1114         {65536, 524288, &MPIR_Pipelined_Bcast_MV2, -1},
1115         {524288, -1, &MPIR_Bcast_scatter_ring_allgather_shm_MV2, -1}},
1116        5,
1117        {{0, 8192, &MPIR_Shmem_Bcast_MV2, 8},
1118         {8192, 16384, &MPIR_Shmem_Bcast_MV2, 4},
1119         {16384, 65536, &MPIR_Shmem_Bcast_MV2, 2},
1120         {65536, 524288, &MPIR_Shmem_Bcast_MV2, -1},
1121         {524288, -1, &MPIR_Shmem_Bcast_MV2, -1}}},
1122       {2048,
1123        8192,
1124        4,
1125        4,
1126        {true, true, true, true, true, true, true},
1127        7,
1128        {{0, 16, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1129         {16, 32, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1130         {32, 4096, &MPIR_Pipelined_Bcast_Zcpy_MV2, 8},
1131         {4096, 16384, &MPIR_Pipelined_Bcast_Zcpy_MV2, 4},
1132         {16384, 32768, &MPIR_Pipelined_Bcast_Zcpy_MV2, 2},
1133         {32768, 524288, &MPIR_Pipelined_Bcast_MV2, -1},
1134         {524288, -1, &MPIR_Bcast_scatter_ring_allgather_shm_MV2, -1}},
1135        7,
1136        {{0, 16, &MPIR_Shmem_Bcast_MV2, 8},
1137         {16, 32, &MPIR_Shmem_Bcast_MV2, 4},
1138         {32, 4096, &MPIR_Shmem_Bcast_MV2, 8},
1139         {4096, 16384, &MPIR_Shmem_Bcast_MV2, 4},
1140         {16384, 32768, &MPIR_Shmem_Bcast_MV2, 2},
1141         {32768, 524288, &MPIR_Shmem_Bcast_MV2, -1},
1142         {524288, -1, &MPIR_Shmem_Bcast_MV2, -1}}}};
1143
1144   std::copy_n(mv2_tmp_bcast_thresholds_table, mv2_size_bcast_tuning_table, mv2_bcast_thresholds_table);
1145 }
1146
1147 /************ Reduce variables and initializers                        */
1148
1149 struct mv2_reduce_tuning_element {
1150   int min;
1151   int max;
1152   int (*MV2_pt_Reduce_function)(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root,
1153                                 MPI_Comm comm_ptr);
1154 };
1155
1156 struct mv2_reduce_tuning_table {
1157   int numproc;
1158   int inter_k_degree;
1159   int intra_k_degree;
1160   bool is_two_level_reduce[MV2_MAX_NB_THRESHOLDS];
1161   int size_inter_table;
1162   mv2_reduce_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
1163   int size_intra_table;
1164   mv2_reduce_tuning_element intra_node[MV2_MAX_NB_THRESHOLDS];
1165 };
1166
1167 int mv2_size_reduce_tuning_table                     = 0;
1168 mv2_reduce_tuning_table* mv2_reduce_thresholds_table = nullptr;
1169
1170 int mv2_reduce_intra_knomial_factor = -1;
1171 int mv2_reduce_inter_knomial_factor = -1;
1172
1173 int (*MV2_Reduce_function)(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root,
1174                            MPI_Comm comm_ptr) = nullptr;
1175
1176 int (*MV2_Reduce_intra_function)(const void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
1177                                  int root, MPI_Comm comm_ptr) = nullptr;
1178
1179 #define MPIR_Reduce_inter_knomial_wrapper_MV2 simgrid::smpi::reduce__mvapich2_knomial
1180 #define MPIR_Reduce_intra_knomial_wrapper_MV2 simgrid::smpi::reduce__mvapich2_knomial
1181 #define MPIR_Reduce_binomial_MV2 simgrid::smpi::reduce__binomial
1182 #define MPIR_Reduce_redscat_gather_MV2 simgrid::smpi::reduce__scatter_gather
1183 #define MPIR_Reduce_shmem_MV2 simgrid::smpi::reduce__ompi_basic_linear
1184 #define MPIR_Reduce_two_level_helper_MV2 simgrid::smpi::reduce__mvapich2_two_level
1185
1186 static void init_mv2_reduce_tables_stampede()
1187 {
1188   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
1189     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
1190   /*Stampede*/
1191   mv2_size_reduce_tuning_table = 8;
1192   mv2_reduce_thresholds_table                               = new mv2_reduce_tuning_table[mv2_size_reduce_tuning_table];
1193   mv2_reduce_tuning_table mv2_tmp_reduce_thresholds_table[] = {
1194       {
1195           16,
1196           4,
1197           4,
1198           {true, false, false},
1199           3,
1200           {
1201               {0, 262144, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1202               {262144, 1048576, &MPIR_Reduce_binomial_MV2},
1203               {1048576, -1, &MPIR_Reduce_redscat_gather_MV2},
1204           },
1205           2,
1206           {
1207               {0, 65536, &MPIR_Reduce_shmem_MV2}, {65536, -1, &MPIR_Reduce_binomial_MV2},
1208           },
1209       },
1210       {
1211           32,
1212           4,
1213           4,
1214           {true, true, true, true, false, false, false},
1215           7,
1216           {
1217               {0, 8192, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1218               {8192, 16384, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1219               {16384, 32768, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1220               {32768, 65536, &MPIR_Reduce_binomial_MV2},
1221               {65536, 262144, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1222               {262144, 1048576, &MPIR_Reduce_binomial_MV2},
1223               {1048576, -1, &MPIR_Reduce_redscat_gather_MV2},
1224           },
1225           6,
1226           {
1227               {0, 8192, &MPIR_Reduce_shmem_MV2},
1228               {8192, 16384, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1229               {16384, 32768, &MPIR_Reduce_shmem_MV2},
1230               {32768, 65536, &MPIR_Reduce_shmem_MV2},
1231               {65536, 262144, &MPIR_Reduce_shmem_MV2},
1232               {262144, -1, &MPIR_Reduce_binomial_MV2},
1233           },
1234       },
1235       {
1236           64,
1237           4,
1238           4,
1239           {true, true, true, true, false},
1240           5,
1241           {
1242               {0, 8192, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1243               {8192, 16384, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1244               {16384, 65536, &MPIR_Reduce_binomial_MV2},
1245               {65536, 262144, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1246               {262144, -1, &MPIR_Reduce_redscat_gather_MV2},
1247           },
1248           5,
1249           {
1250               {0, 8192, &MPIR_Reduce_shmem_MV2},
1251               {8192, 16384, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1252               {16384, 65536, &MPIR_Reduce_shmem_MV2},
1253               {65536, 262144, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1254               {262144, -1, &MPIR_Reduce_binomial_MV2},
1255           },
1256       },
1257       {
1258           128,
1259           4,
1260           4,
1261           {true, false, true, false, true, false},
1262           6,
1263           {
1264               {0, 8192, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1265               {8192, 16384, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1266               {16384, 65536, &MPIR_Reduce_binomial_MV2},
1267               {65536, 262144, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1268               {262144, 1048576, &MPIR_Reduce_binomial_MV2},
1269               {1048576, -1, &MPIR_Reduce_redscat_gather_MV2},
1270           },
1271           5,
1272           {
1273               {0, 8192, &MPIR_Reduce_shmem_MV2},
1274               {8192, 16384, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1275               {16384, 65536, &MPIR_Reduce_shmem_MV2},
1276               {65536, 262144, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1277               {262144, -1, &MPIR_Reduce_binomial_MV2},
1278           },
1279       },
1280       {
1281           256,
1282           4,
1283           4,
1284           {true, true, true, false, true, true, false},
1285           7,
1286           {
1287               {0, 8192, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1288               {8192, 16384, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1289               {16384, 32768, &MPIR_Reduce_binomial_MV2},
1290               {32768, 65536, &MPIR_Reduce_binomial_MV2},
1291               {65536, 262144, &MPIR_Reduce_binomial_MV2},
1292               {262144, 1048576, &MPIR_Reduce_binomial_MV2},
1293               {1048576, -1, &MPIR_Reduce_redscat_gather_MV2},
1294           },
1295           6,
1296           {
1297               {0, 8192, &MPIR_Reduce_shmem_MV2},
1298               {8192, 16384, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1299               {16384, 32768, &MPIR_Reduce_shmem_MV2},
1300               {32768, 65536, &MPIR_Reduce_shmem_MV2},
1301               {65536, 262144, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1302               {262144, -1, &MPIR_Reduce_binomial_MV2},
1303           },
1304       },
1305       {
1306           512,
1307           4,
1308           4,
1309           {true, false, true, true, true, false},
1310           6,
1311           {
1312               {0, 8192, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1313               {8192, 16384, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1314               {16384, 65536, &MPIR_Reduce_binomial_MV2},
1315               {65536, 262144, &MPIR_Reduce_binomial_MV2},
1316               {262144, 1048576, &MPIR_Reduce_binomial_MV2},
1317               {1048576, -1, &MPIR_Reduce_redscat_gather_MV2},
1318           },
1319           5,
1320           {
1321               {0, 8192, &MPIR_Reduce_shmem_MV2},
1322               {8192, 16384, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1323               {16384, 65536, &MPIR_Reduce_shmem_MV2},
1324               {65536, 262144, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1325               {262144, -1, &MPIR_Reduce_binomial_MV2},
1326           },
1327       },
1328       {
1329           1024,
1330           4,
1331           4,
1332           {true, false, true, true, true},
1333           5,
1334           {
1335               {0, 8192, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1336               {8192, 16384, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1337               {16384, 65536, &MPIR_Reduce_binomial_MV2},
1338               {65536, 262144, &MPIR_Reduce_binomial_MV2},
1339               {262144, -1, &MPIR_Reduce_binomial_MV2},
1340           },
1341           5,
1342           {
1343               {0, 8192, &MPIR_Reduce_shmem_MV2},
1344               {8192, 16384, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1345               {16384, 65536, &MPIR_Reduce_shmem_MV2},
1346               {65536, 262144, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1347               {262144, -1, &MPIR_Reduce_binomial_MV2},
1348           },
1349       },
1350       {
1351           2048,
1352           4,
1353           4,
1354           {true, false, true, true, true, true},
1355           6,
1356           {
1357               {0, 2048, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1358               {2048, 4096, &MPIR_Reduce_inter_knomial_wrapper_MV2},
1359               {4096, 16384, &MPIR_Reduce_binomial_MV2},
1360               {16384, 65536, &MPIR_Reduce_binomial_MV2},
1361               {65536, 131072, &MPIR_Reduce_binomial_MV2},
1362               {131072, -1, &MPIR_Reduce_binomial_MV2},
1363           },
1364           6,
1365           {
1366               {0, 2048, &MPIR_Reduce_shmem_MV2},
1367               {2048, 4096, &MPIR_Reduce_shmem_MV2},
1368               {4096, 16384, &MPIR_Reduce_shmem_MV2},
1369               {16384, 65536, &MPIR_Reduce_intra_knomial_wrapper_MV2},
1370               {65536, 131072, &MPIR_Reduce_binomial_MV2},
1371               {131072, -1, &MPIR_Reduce_shmem_MV2},
1372           },
1373       },
1374
1375   };
1376   std::copy_n(mv2_tmp_reduce_thresholds_table, mv2_size_reduce_tuning_table, mv2_reduce_thresholds_table);
1377 }
1378
1379 /************ Reduce scatter variables and initializers                        */
1380
1381 struct mv2_red_scat_tuning_element {
1382   int min;
1383   int max;
1384   int (*MV2_pt_Red_scat_function)(const void* sendbuf, void* recvbuf, const int* recvcnts, MPI_Datatype datatype, MPI_Op op,
1385                                   MPI_Comm comm_ptr);
1386 };
1387
1388 struct mv2_red_scat_tuning_table {
1389   int numproc;
1390   int size_inter_table;
1391   mv2_red_scat_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
1392 };
1393
1394 int mv2_size_red_scat_tuning_table                       = 0;
1395 mv2_red_scat_tuning_table* mv2_red_scat_thresholds_table = nullptr;
1396
1397 int (*MV2_Red_scat_function)(const void* sendbuf, void* recvbuf, const int* recvcnts, MPI_Datatype datatype, MPI_Op op,
1398                              MPI_Comm comm_ptr);
1399
1400 static int MPIR_Reduce_Scatter_Basic_MV2(const void* sendbuf, void* recvbuf, const int* recvcnts, MPI_Datatype datatype, MPI_Op op,
1401                                          MPI_Comm comm)
1402 {
1403   simgrid::smpi::reduce_scatter__default(sendbuf, recvbuf, recvcnts, datatype, op, comm);
1404   return MPI_SUCCESS;
1405 }
1406 #define MPIR_Reduce_scatter_non_comm_MV2 simgrid::smpi::reduce_scatter__mpich_noncomm
1407 #define MPIR_Reduce_scatter_Rec_Halving_MV2 simgrid::smpi::reduce_scatter__ompi_basic_recursivehalving
1408 #define MPIR_Reduce_scatter_Pair_Wise_MV2 simgrid::smpi::reduce_scatter__mpich_pair
1409
1410 static void init_mv2_reduce_scatter_tables_stampede()
1411 {
1412   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
1413     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
1414   mv2_size_red_scat_tuning_table                     = 6;
1415   mv2_red_scat_thresholds_table                      = new mv2_red_scat_tuning_table[mv2_size_red_scat_tuning_table];
1416   mv2_red_scat_tuning_table mv2_tmp_red_scat_thresholds_table[] = {
1417       {
1418           16,
1419           3,
1420           {
1421               {0, 64, &MPIR_Reduce_Scatter_Basic_MV2},
1422               {64, 65536, &MPIR_Reduce_scatter_Rec_Halving_MV2},
1423               {65536, -1, &MPIR_Reduce_scatter_Pair_Wise_MV2},
1424           },
1425       },
1426       {
1427           32,
1428           3,
1429           {
1430               {0, 64, &MPIR_Reduce_Scatter_Basic_MV2},
1431               {64, 131072, &MPIR_Reduce_scatter_Rec_Halving_MV2},
1432               {131072, -1, &MPIR_Reduce_scatter_Pair_Wise_MV2},
1433           },
1434       },
1435       {
1436           64,
1437           3,
1438           {
1439               {0, 1024, &MPIR_Reduce_Scatter_Basic_MV2},
1440               {1024, 262144, &MPIR_Reduce_scatter_Rec_Halving_MV2},
1441               {262144, -1, &MPIR_Reduce_scatter_Pair_Wise_MV2},
1442           },
1443       },
1444       {
1445           128,
1446           2,
1447           {
1448               {0, 128, &MPIR_Reduce_Scatter_Basic_MV2}, {128, -1, &MPIR_Reduce_scatter_Rec_Halving_MV2},
1449           },
1450       },
1451       {
1452           256,
1453           2,
1454           {
1455               {0, 128, &MPIR_Reduce_Scatter_Basic_MV2}, {128, -1, &MPIR_Reduce_scatter_Rec_Halving_MV2},
1456           },
1457       },
1458       {
1459           512,
1460           2,
1461           {
1462               {0, 256, &MPIR_Reduce_Scatter_Basic_MV2}, {256, -1, &MPIR_Reduce_scatter_Rec_Halving_MV2},
1463           },
1464       },
1465
1466   };
1467   std::copy_n(mv2_tmp_red_scat_thresholds_table, mv2_size_red_scat_tuning_table, mv2_red_scat_thresholds_table);
1468 }
1469
1470 /************ Scatter variables and initializers                        */
1471
1472 struct mv2_scatter_tuning_element {
1473   int min;
1474   int max;
1475   int (*MV2_pt_Scatter_function)(const void* sendbuf, int sendcnt, MPI_Datatype sendtype, void* recvbuf, int recvcnt,
1476                                  MPI_Datatype recvtype, int root, MPI_Comm comm);
1477 };
1478
1479 struct mv2_scatter_tuning_table {
1480   int numproc;
1481   int size_inter_table;
1482   mv2_scatter_tuning_element inter_leader[MV2_MAX_NB_THRESHOLDS];
1483   int size_intra_table;
1484   mv2_scatter_tuning_element intra_node[MV2_MAX_NB_THRESHOLDS];
1485 };
1486
1487 int* mv2_scatter_table_ppn_conf                         = nullptr;
1488 int mv2_scatter_num_ppn_conf                            = 1;
1489 int* mv2_size_scatter_tuning_table                      = nullptr;
1490 mv2_scatter_tuning_table** mv2_scatter_thresholds_table = nullptr;
1491
1492 int (*MV2_Scatter_function)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
1493                             MPI_Datatype recvtype, int root, MPI_Comm comm) = nullptr;
1494
1495 int (*MV2_Scatter_intra_function)(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
1496                                   int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) = nullptr;
1497 int MPIR_Scatter_mcst_wrap_MV2(const void* sendbuf, int sendcnt, MPI_Datatype sendtype, void* recvbuf, int recvcnt,
1498                                MPI_Datatype recvtype, int root, MPI_Comm comm_ptr);
1499
1500 int MPIR_Scatter_mcst_wrap_MV2(const void* sendbuf, int sendcnt, MPI_Datatype sendtype, void* recvbuf, int recvcnt,
1501                                MPI_Datatype recvtype, int root, MPI_Comm comm_ptr)
1502 {
1503   return 0;
1504 }
1505
1506 #define MPIR_Scatter_MV2_Binomial simgrid::smpi::scatter__ompi_binomial
1507 #define MPIR_Scatter_MV2_Direct simgrid::smpi::scatter__ompi_basic_linear
1508 #define MPIR_Scatter_MV2_two_level_Binomial simgrid::smpi::scatter__mvapich2_two_level_binomial
1509 #define MPIR_Scatter_MV2_two_level_Direct simgrid::smpi::scatter__mvapich2_two_level_direct
1510
1511 static void init_mv2_scatter_tables_stampede()
1512 {
1513   if (simgrid::smpi::colls::smpi_coll_cleanup_callback == nullptr)
1514     simgrid::smpi::colls::smpi_coll_cleanup_callback = &smpi_coll_cleanup_mvapich2;
1515
1516   int agg_table_sum = 0;
1517   mv2_scatter_num_ppn_conf              = 3;
1518   mv2_scatter_thresholds_table          = new mv2_scatter_tuning_table*[mv2_scatter_num_ppn_conf];
1519   auto** table_ptrs                     = new mv2_scatter_tuning_table*[mv2_scatter_num_ppn_conf];
1520   mv2_size_scatter_tuning_table         = new int[mv2_scatter_num_ppn_conf];
1521   mv2_scatter_table_ppn_conf            = new int[mv2_scatter_num_ppn_conf];
1522   mv2_scatter_table_ppn_conf[0]    = 1;
1523   mv2_size_scatter_tuning_table[0] = 6;
1524   mv2_scatter_tuning_table mv2_tmp_scatter_thresholds_table_1ppn[] = {
1525       {
1526           2,
1527           1,
1528           {
1529               {0, -1, &MPIR_Scatter_MV2_Binomial},
1530           },
1531           1,
1532           {
1533               {0, -1, &MPIR_Scatter_MV2_Binomial},
1534           },
1535       },
1536
1537       {
1538           4,
1539           1,
1540           {
1541               {0, -1, &MPIR_Scatter_MV2_Direct},
1542           },
1543           1,
1544           {
1545               {0, -1, &MPIR_Scatter_MV2_Direct},
1546           },
1547       },
1548
1549       {
1550           8,
1551           1,
1552           {
1553               {0, -1, &MPIR_Scatter_MV2_Direct},
1554           },
1555           1,
1556           {
1557               {0, -1, &MPIR_Scatter_MV2_Direct},
1558           },
1559       },
1560
1561       {
1562           16,
1563           1,
1564           {
1565               {0, -1, &MPIR_Scatter_MV2_Direct},
1566           },
1567           1,
1568           {
1569               {0, -1, &MPIR_Scatter_MV2_Direct},
1570           },
1571       },
1572
1573       {
1574           32,
1575           1,
1576           {
1577               {0, -1, &MPIR_Scatter_MV2_Direct},
1578           },
1579           1,
1580           {
1581               {0, -1, &MPIR_Scatter_MV2_Direct},
1582           },
1583       },
1584
1585       {
1586           64,
1587           2,
1588           {
1589               {0, 32, &MPIR_Scatter_MV2_Binomial}, {32, -1, &MPIR_Scatter_MV2_Direct},
1590           },
1591           1,
1592           {
1593               {0, -1, &MPIR_Scatter_MV2_Binomial},
1594           },
1595       },
1596   };
1597   table_ptrs[0]                                                    = mv2_tmp_scatter_thresholds_table_1ppn;
1598   mv2_scatter_table_ppn_conf[1]                                    = 2;
1599   mv2_size_scatter_tuning_table[1]                                 = 6;
1600   mv2_scatter_tuning_table mv2_tmp_scatter_thresholds_table_2ppn[] = {
1601       {
1602           4,
1603           2,
1604           {
1605               {0, 4096, &MPIR_Scatter_MV2_Binomial}, {4096, -1, &MPIR_Scatter_MV2_Direct},
1606           },
1607           1,
1608           {
1609               {0, -1, &MPIR_Scatter_MV2_Direct},
1610           },
1611       },
1612
1613       {
1614           8,
1615           2,
1616           {
1617               {0, 512, &MPIR_Scatter_MV2_two_level_Direct}, {512, -1, &MPIR_Scatter_MV2_Direct},
1618           },
1619           1,
1620           {
1621               {0, -1, &MPIR_Scatter_MV2_Binomial},
1622           },
1623       },
1624
1625       {
1626           16,
1627           2,
1628           {
1629               {0, 2048, &MPIR_Scatter_MV2_two_level_Direct}, {2048, -1, &MPIR_Scatter_MV2_Direct},
1630           },
1631           1,
1632           {
1633               {0, -1, &MPIR_Scatter_MV2_Binomial},
1634           },
1635       },
1636
1637       {
1638           32,
1639           2,
1640           {
1641               {0, 2048, &MPIR_Scatter_MV2_two_level_Direct}, {2048, -1, &MPIR_Scatter_MV2_Direct},
1642           },
1643           1,
1644           {
1645               {0, -1, &MPIR_Scatter_MV2_Binomial},
1646           },
1647       },
1648
1649       {
1650           64,
1651           2,
1652           {
1653               {0, 8192, &MPIR_Scatter_MV2_two_level_Direct}, {8192, -1, &MPIR_Scatter_MV2_Direct},
1654           },
1655           1,
1656           {
1657               {0, -1, &MPIR_Scatter_MV2_Binomial},
1658           },
1659       },
1660
1661       {
1662           128,
1663           4,
1664           {
1665               {0, 16, &MPIR_Scatter_MV2_Binomial},
1666               {16, 128, &MPIR_Scatter_MV2_two_level_Binomial},
1667               {128, 16384, &MPIR_Scatter_MV2_two_level_Direct},
1668               {16384, -1, &MPIR_Scatter_MV2_Direct},
1669           },
1670           1,
1671           {
1672               {0, 128, &MPIR_Scatter_MV2_Direct}, {128, -1, &MPIR_Scatter_MV2_Binomial},
1673           },
1674       },
1675   };
1676   table_ptrs[1]                                                     = mv2_tmp_scatter_thresholds_table_2ppn;
1677   mv2_scatter_table_ppn_conf[2]                                     = 16;
1678   mv2_size_scatter_tuning_table[2]                                  = 8;
1679   mv2_scatter_tuning_table mv2_tmp_scatter_thresholds_table_16ppn[] = {
1680       {
1681           16,
1682           2,
1683           {
1684               {0, 256, &MPIR_Scatter_MV2_Binomial}, {256, -1, &MPIR_Scatter_MV2_Direct},
1685           },
1686           1,
1687           {
1688               {0, -1, &MPIR_Scatter_MV2_Direct},
1689           },
1690       },
1691
1692       {
1693           32,
1694           2,
1695           {
1696               {0, 512, &MPIR_Scatter_MV2_Binomial}, {512, -1, &MPIR_Scatter_MV2_Direct},
1697           },
1698           1,
1699           {
1700               {0, -1, &MPIR_Scatter_MV2_Direct},
1701           },
1702       },
1703
1704       {
1705           64,
1706           2,
1707           {
1708               {0, 1024, &MPIR_Scatter_MV2_two_level_Direct}, {1024, -1, &MPIR_Scatter_MV2_Direct},
1709           },
1710           1,
1711           {
1712               {0, -1, &MPIR_Scatter_MV2_Direct},
1713           },
1714       },
1715
1716       {
1717           128,
1718           4,
1719           {
1720               {0, 16, &MPIR_Scatter_mcst_wrap_MV2},
1721               {0, 16, &MPIR_Scatter_MV2_two_level_Direct},
1722               {16, 2048, &MPIR_Scatter_MV2_two_level_Direct},
1723               {2048, -1, &MPIR_Scatter_MV2_Direct},
1724           },
1725           1,
1726           {
1727               {0, -1, &MPIR_Scatter_MV2_Direct},
1728           },
1729       },
1730
1731       {
1732           256,
1733           4,
1734           {
1735               {0, 16, &MPIR_Scatter_mcst_wrap_MV2},
1736               {0, 16, &MPIR_Scatter_MV2_two_level_Direct},
1737               {16, 2048, &MPIR_Scatter_MV2_two_level_Direct},
1738               {2048, -1, &MPIR_Scatter_MV2_Direct},
1739           },
1740           1,
1741           {
1742               {0, -1, &MPIR_Scatter_MV2_Direct},
1743           },
1744       },
1745
1746       {
1747           512,
1748           4,
1749           {
1750               {0, 16, &MPIR_Scatter_mcst_wrap_MV2},
1751               {16, 16, &MPIR_Scatter_MV2_two_level_Direct},
1752               {16, 4096, &MPIR_Scatter_MV2_two_level_Direct},
1753               {4096, -1, &MPIR_Scatter_MV2_Direct},
1754           },
1755           1,
1756           {
1757               {0, -1, &MPIR_Scatter_MV2_Binomial},
1758           },
1759       },
1760       {
1761           1024,
1762           5,
1763           {
1764               {0, 16, &MPIR_Scatter_mcst_wrap_MV2},
1765               {0, 16, &MPIR_Scatter_MV2_Binomial},
1766               {16, 32, &MPIR_Scatter_MV2_Binomial},
1767               {32, 4096, &MPIR_Scatter_MV2_two_level_Direct},
1768               {4096, -1, &MPIR_Scatter_MV2_Direct},
1769           },
1770           1,
1771           {
1772               {0, -1, &MPIR_Scatter_MV2_Binomial},
1773           },
1774       },
1775       {
1776           2048,
1777           7,
1778           {
1779               {0, 16, &MPIR_Scatter_mcst_wrap_MV2},
1780               {0, 16, &MPIR_Scatter_MV2_two_level_Binomial},
1781               {16, 128, &MPIR_Scatter_MV2_two_level_Binomial},
1782               {128, 1024, &MPIR_Scatter_MV2_two_level_Direct},
1783               {1024, 16384, &MPIR_Scatter_MV2_two_level_Direct},
1784               {16384, 65536, &MPIR_Scatter_MV2_Direct},
1785               {65536, -1, &MPIR_Scatter_MV2_two_level_Direct},
1786           },
1787           6,
1788           {
1789               {0, 16, &MPIR_Scatter_MV2_Binomial},
1790               {16, 128, &MPIR_Scatter_MV2_Binomial},
1791               {128, 1024, &MPIR_Scatter_MV2_Binomial},
1792               {1024, 16384, &MPIR_Scatter_MV2_Direct},
1793               {16384, 65536, &MPIR_Scatter_MV2_Direct},
1794               {65536, -1, &MPIR_Scatter_MV2_Direct},
1795           },
1796       },
1797   };
1798   table_ptrs[2] = mv2_tmp_scatter_thresholds_table_16ppn;
1799   agg_table_sum = 0;
1800   for (int i = 0; i < mv2_scatter_num_ppn_conf; i++) {
1801     agg_table_sum += mv2_size_scatter_tuning_table[i];
1802   }
1803   mv2_scatter_thresholds_table[0] = new mv2_scatter_tuning_table[agg_table_sum];
1804   std::copy_n(table_ptrs[0], mv2_size_scatter_tuning_table[0], mv2_scatter_thresholds_table[0]);
1805   for (int i = 1; i < mv2_scatter_num_ppn_conf; i++) {
1806     mv2_scatter_thresholds_table[i] = mv2_scatter_thresholds_table[i - 1] + mv2_size_scatter_tuning_table[i - 1];
1807     std::copy_n(table_ptrs[i], mv2_size_scatter_tuning_table[i], mv2_scatter_thresholds_table[i]);
1808   }
1809   delete[] table_ptrs;
1810 }
1811
1812 #endif