This source file includes following definitions.
- ompi_netpatterns_setup_recursive_knomial_allgather_tree_node
- ompi_netpatterns_cleanup_recursive_knomial_allgather_tree_node
- ompi_netpatterns_setup_recursive_knomial_tree_node
- ompi_netpatterns_cleanup_recursive_knomial_tree_node
- ompi_netpatterns_setup_recursive_doubling_n_tree_node
- ompi_netpatterns_cleanup_recursive_doubling_tree_node
- ompi_netpatterns_setup_recursive_doubling_tree_node
- ompi_netpatterns_setup_recursive_doubling_n_tree_node
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "ompi_config.h"
18 #ifdef HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif
21 #include <sys/types.h>
22 #ifdef HAVE_SYS_MMAN_H
23 #include <sys/mman.h>
24 #endif
25 #include <fcntl.h>
26 #include <stdlib.h>
27 #include <assert.h>
28
29 #include "ompi/constants.h"
30
31 #include "ompi/mca/rte/rte.h"
32
33 #include "netpatterns.h"
34
35
36
37 OMPI_DECLSPEC int ompi_netpatterns_setup_recursive_knomial_allgather_tree_node(
38 int num_nodes, int node_rank, int tree_order, int *hier_ranks,
39 netpatterns_k_exchange_node_t *exchange_node)
40 {
41
42 int i, j, cnt, i_temp;
43 int knt,knt2,kk, ex_node, stray;
44 int n_levels,pow_k;
45 int k_temp1;
46 int k_temp2;
47 int myid, reindex_myid = 0;
48 int base, peer_base,base_temp;
49 int peer;
50 int *prev_data = NULL;
51 int *current_data = NULL;
52 int *group_info = NULL;
53
54
55 NETPATTERNS_VERBOSE(
56 ("Enter ompi_netpatterns_setup_recursive_knomial_tree_node(num_nodes=%d, node_rank=%d, tree_order=%d)",
57 num_nodes, node_rank, tree_order));
58
59 assert(num_nodes > 1);
60 assert(tree_order > 1);
61 if (tree_order > num_nodes) {
62 tree_order = num_nodes;
63 }
64
65
66 exchange_node->tree_order = tree_order;
67
68
69
70
71
72 n_levels = 0;
73 cnt=1;
74 while ( num_nodes > cnt ) {
75 cnt *= tree_order;
76 n_levels++;
77 }
78
79
80
81
82 pow_k = n_levels;
83
84
85
86 if ( cnt > num_nodes) {
87 cnt /= tree_order;
88 n_levels--;
89 }
90
91
92 exchange_node->log_tree_order = pow_k;
93 exchange_node->n_largest_pow_tree_order = cnt;
94
95
96
97
98 group_info = (int *) calloc(pow_k , sizeof(int));
99 group_info[0] = num_nodes/tree_order;
100
101 for ( i = 1; i < pow_k; i ++) {
102 group_info[i] = group_info[i-1]/tree_order;
103
104
105 }
106
107
108 knt=0;
109 while (knt <= (pow_k - 1) && group_info[knt] > 0) {
110 knt++;
111 }
112 knt--;
113
114
115
116
117 stray = 0;
118
119
120
121
122
123
124 stray = cnt*group_info[knt];
125 exchange_node->k_nomial_stray = stray;
126
127
128
129
130
131
132 exchange_node->reindex_map = (int *) malloc(num_nodes*sizeof(int));
133
134 exchange_node->inv_reindex_map = (int *) malloc(num_nodes*sizeof(int));
135
136
137 if( stray < num_nodes ) {
138
139 peer = stray - cnt;
140
141 for( i = 0; i < peer; i++){
142 exchange_node->reindex_map[i] = i;
143 }
144
145 exchange_node->reindex_map[peer] = peer;
146 for( i = (peer+1); i < (peer + (num_nodes - stray)+1); i++) {
147 exchange_node->reindex_map[i] = exchange_node->reindex_map[i-1] + 2;
148 }
149 i_temp = i;
150 for( i = i_temp; i < stray; i++) {
151 exchange_node->reindex_map[i] = exchange_node->reindex_map[i-1] + 1;
152 }
153
154 exchange_node->reindex_map[stray] = peer + 1;
155 for( i = (stray+1); i < num_nodes; i++) {
156 exchange_node->reindex_map[i] = exchange_node->reindex_map[i-1] + 2;
157 }
158
159
160
161
162
163
164
165 } else {
166
167 for( i = 0; i < num_nodes; i++){
168 exchange_node->reindex_map[i] = i;
169 }
170 }
171
172
173
174 for( i = 0; i < num_nodes; i++ ){
175 if( node_rank == exchange_node->reindex_map[i] ){
176 exchange_node->reindex_myid = i;
177 break;
178 }
179 }
180
181 for( i = 0; i < num_nodes; i++){
182 j = 0;
183 while(exchange_node->reindex_map[j] != i ){
184 j++;
185 }
186 exchange_node->inv_reindex_map[i] = j;
187 }
188
189
190
191
192
193 prev_data = (int *) malloc( num_nodes*sizeof(int) );
194 if( NULL == prev_data ) {
195 goto Error;
196 }
197
198 current_data = (int *) malloc( num_nodes*sizeof(int) );
199 if( NULL == current_data ) {
200 goto Error;
201 }
202
203
204 exchange_node->payload_info = (netpatterns_payload_t **) malloc(sizeof(netpatterns_payload_t *)*pow_k);
205 if( NULL == exchange_node->payload_info) {
206 goto Error;
207 }
208
209 for(i = 0; i < pow_k; i++){
210 exchange_node->payload_info[i] = (netpatterns_payload_t *) malloc(sizeof(netpatterns_payload_t)*(tree_order-1));
211 if( NULL == exchange_node->payload_info[i]) {
212 goto Error;
213 }
214
215 }
216
217
218
219
220
221
222
223
224
225
226 for(i = 0; i < num_nodes; i++){
227 prev_data[i] = hier_ranks[i];
228 current_data[i] = hier_ranks[i];
229 }
230
231
232
233
234 for( myid = 0; myid < num_nodes; myid++) {
235
236 for( j = 0; j < num_nodes; j++ ){
237
238 if( myid == exchange_node->reindex_map[j] ){
239 reindex_myid = j;
240 break;
241 }
242 }
243
244 for( j = stray; j < num_nodes; j++) {
245 if(reindex_myid == ( j - cnt )) {
246
247 prev_data[myid] += prev_data[exchange_node->reindex_map[j]];
248 break;
249 }
250
251 }
252 }
253
254
255
256
257 k_temp1 = tree_order;
258 k_temp2 = 1;
259 peer_base = 0;
260 base_temp = 0;
261 for( i = 0; i < pow_k; i++) {
262
263 for( myid = 0; myid < num_nodes; myid++){
264 current_data[myid] = prev_data[myid];
265
266 for( j = 0; j < num_nodes; j++ ){
267 if( myid == exchange_node->reindex_map[j] ){
268 reindex_myid = j;
269 break;
270 }
271 }
272 if( reindex_myid < stray ) {
273
274 FIND_BASE(base,reindex_myid,i+1,tree_order);
275 for( j = 0; j < ( tree_order - 1 ); j ++ ) {
276 peer = base + (reindex_myid + k_temp2*(j+1))%k_temp1;
277 if( peer < stray ) {
278
279
280 if( node_rank == myid ){
281 exchange_node->payload_info[i][j].r_len = prev_data[exchange_node->reindex_map[peer]];
282
283 if( i > 0 ) {
284
285
286 FIND_BASE(peer_base,peer,i,tree_order);
287
288 ex_node = exchange_node->reindex_map[peer_base];
289
290 knt2 =0;
291 for(kk = 0; kk < ex_node; kk++){
292 knt2 += hier_ranks[kk];
293 }
294 exchange_node->payload_info[i][j].r_offset = knt2;
295
296
297 FIND_BASE(base_temp,reindex_myid,i,tree_order);
298 ex_node = exchange_node->reindex_map[base_temp];
299 knt2 = 0;
300 for( kk = 0; kk < ex_node; kk++){
301 knt2 += hier_ranks[kk];
302 }
303 exchange_node->payload_info[i][j].s_offset =
304 knt2;
305
306 } else {
307 ex_node = exchange_node->reindex_map[peer];
308 knt2 =0;
309 for(kk = 0; kk < ex_node; kk++){
310 knt2 += hier_ranks[kk];
311 }
312 exchange_node->payload_info[i][j].r_offset =
313 knt2;
314
315 knt2 = 0;
316 for(kk = 0; kk < myid; kk++){
317 knt2 += hier_ranks[kk];
318 }
319 exchange_node->payload_info[i][j].s_offset = knt2;
320
321 }
322
323
324 exchange_node->payload_info[i][j].s_len = prev_data[node_rank];
325
326
327
328
329
330
331 }
332
333 current_data[myid] += prev_data[exchange_node->reindex_map[peer]];
334 }
335 }
336 }
337
338
339 }
340 k_temp1 *= tree_order;
341 k_temp2 *= tree_order;
342
343
344 for( j = 0; j < num_nodes; j++){
345
346 prev_data[j] = current_data[j];
347 }
348
349
350 }
351
352
353
354
355 if( exchange_node->reindex_myid >= stray ){
356
357 exchange_node->node_type = EXTRA_NODE;
358 } else {
359 exchange_node->node_type = EXCHANGE_NODE;
360 }
361
362
363
364
365
366
367
368 if (EXCHANGE_NODE == exchange_node->node_type) {
369 exchange_node->n_extra_sources = 0;
370 for( i = stray; i < num_nodes; i++) {
371 if(exchange_node->reindex_myid == ( i - cnt )) {
372
373
374
375 exchange_node->n_extra_sources = 1;
376 break;
377 }
378 }
379
380 if (exchange_node->n_extra_sources > 0) {
381 exchange_node->rank_extra_sources_array = (int *) malloc
382 (exchange_node->n_extra_sources * sizeof(int));
383 if( NULL == exchange_node->rank_extra_sources_array ) {
384 goto Error;
385 }
386
387 exchange_node->rank_extra_sources_array[0] = exchange_node->reindex_map[i];
388 } else {
389 exchange_node->rank_extra_sources_array = NULL;
390 }
391 } else {
392
393 exchange_node->n_extra_sources = 1;
394
395 exchange_node->rank_extra_sources_array = (int *) malloc
396 (exchange_node->n_extra_sources * sizeof(int));
397 if( NULL == exchange_node->rank_extra_sources_array ) {
398 goto Error;
399 }
400 exchange_node->rank_extra_sources_array[0] = exchange_node->reindex_map[exchange_node->reindex_myid - cnt];
401 }
402
403
404
405 if (EXCHANGE_NODE == exchange_node->node_type) {
406
407 exchange_node->n_exchanges = n_levels + 1;
408
409 exchange_node->n_actual_exchanges = 0;
410
411
412 exchange_node->rank_exchanges = (int **) malloc
413 (exchange_node->n_exchanges * sizeof(int *));
414 if(NULL == exchange_node->rank_exchanges) {
415 goto Error;
416 }
417 for (i = 0; i < exchange_node->n_exchanges; i++) {
418 exchange_node->rank_exchanges[i] = (int *) malloc
419 ((tree_order - 1) * sizeof(int));
420 if( NULL == exchange_node->rank_exchanges ) {
421 goto Error;
422 }
423 }
424 k_temp1 = tree_order;
425 k_temp2 = 1;
426
427
428 for( i = 0; i < exchange_node->n_exchanges; i ++) {
429
430
431 FIND_BASE(base,exchange_node->reindex_myid,i+1,tree_order);
432
433 for( j = 0; j < (tree_order-1); j ++ ) {
434 peer = base + (exchange_node->reindex_myid + k_temp2*(j+1))%k_temp1;
435 if ( peer < stray ) {
436 exchange_node->rank_exchanges[i][j] = exchange_node->reindex_map[peer];
437
438
439 } else {
440
441 exchange_node->rank_exchanges[i][j] = -1;
442 }
443
444 }
445 k_temp1 *= tree_order;
446 k_temp2 *= tree_order;
447 }
448 for(i = 0; i < pow_k; i++){
449 for(j = 0; j < (tree_order-1); j++){
450 if(-1 != exchange_node->rank_exchanges[i][j]){
451
452 exchange_node->n_actual_exchanges++;
453 }
454 }
455 }
456
457 } else {
458
459 exchange_node->n_exchanges=0;
460 exchange_node->rank_exchanges=NULL;
461 }
462
463
464
465
466
467
468 exchange_node->n_tags = tree_order * n_levels + 1;
469
470 free(prev_data);
471 free(current_data);
472 free(group_info);
473
474
475 return OMPI_SUCCESS;
476
477 Error:
478
479 if (NULL != exchange_node->rank_extra_sources_array) {
480 free(exchange_node->rank_extra_sources_array);
481 }
482
483 if (NULL != exchange_node->rank_exchanges) {
484 for (i = 0; i < exchange_node->n_exchanges; i++) {
485 if (NULL != exchange_node->rank_exchanges[i]) {
486 free(exchange_node->rank_exchanges[i]);
487 }
488 }
489 free(exchange_node->rank_exchanges);
490 }
491
492 if (NULL != prev_data ){
493 free(prev_data);
494 }
495
496 if(NULL != current_data) {
497 free(current_data);
498 }
499
500 if(NULL != group_info) {
501 free(group_info);
502 }
503
504
505 return OMPI_ERROR;
506 }
507
508 OMPI_DECLSPEC void ompi_netpatterns_cleanup_recursive_knomial_allgather_tree_node(
509 netpatterns_k_exchange_node_t *exchange_node)
510 {
511 int i;
512
513 free(exchange_node->reindex_map);
514 free(exchange_node->inv_reindex_map);
515 if (exchange_node->n_extra_sources > 0) {
516 free(exchange_node->rank_extra_sources_array) ;
517 exchange_node->n_extra_sources = 0;
518 exchange_node->rank_extra_sources_array = NULL;
519 }
520 if (exchange_node->n_exchanges > 0) {
521 for (i=0; i < exchange_node->n_exchanges; i++) {
522 free(exchange_node->rank_exchanges[i]);
523 exchange_node->rank_exchanges[i] = NULL;
524 }
525 free(exchange_node->rank_exchanges);
526 exchange_node->rank_exchanges = NULL;
527 exchange_node->n_exchanges = 0;
528 }
529 for(i = 0; i < exchange_node->log_tree_order; i++){
530 free(exchange_node->payload_info[i]);
531 }
532 free(exchange_node->payload_info);
533 }
534
535 OMPI_DECLSPEC int ompi_netpatterns_setup_recursive_knomial_tree_node(
536 int num_nodes, int node_rank, int tree_order,
537 netpatterns_k_exchange_node_t *exchange_node)
538 {
539
540 int i, j, tmp, cnt;
541 int n_levels;
542 int k_base, kpow_num, peer;
543
544 NETPATTERNS_VERBOSE(
545 ("Enter ompi_netpatterns_setup_recursive_knomial_tree_node(num_nodes=%d, node_rank=%d, tree_order=%d)",
546 num_nodes, node_rank, tree_order));
547
548 assert(num_nodes > 1);
549 assert(tree_order > 1);
550 if (tree_order > num_nodes) {
551 tree_order = num_nodes;
552 }
553
554 exchange_node->tree_order = tree_order;
555
556
557 n_levels = 0;
558
559 cnt=1;
560 while ( num_nodes > cnt ) {
561 cnt *= tree_order;
562 n_levels++;
563 };
564
565
566
567 if ( cnt > num_nodes) {
568 cnt /= tree_order;
569 n_levels--;
570 }
571
572 exchange_node->log_tree_order = n_levels;
573 exchange_node->n_largest_pow_tree_order = cnt;
574
575
576
577
578
579 if (node_rank + 1 > cnt) {
580 exchange_node->node_type = EXTRA_NODE;
581 } else {
582 exchange_node->node_type = EXCHANGE_NODE;
583 }
584
585
586
587
588
589 if (EXCHANGE_NODE == exchange_node->node_type) {
590 exchange_node->n_extra_sources = 0;
591 for (i = 0, tmp = node_rank * (tree_order - 1) + cnt + i;
592 tmp < num_nodes && i < tree_order - 1;
593 ++i, ++tmp) {
594 ++exchange_node->n_extra_sources;
595 }
596
597 assert(exchange_node->n_extra_sources < tree_order);
598
599 if (exchange_node->n_extra_sources > 0) {
600 exchange_node->rank_extra_sources_array = (int *) malloc
601 (exchange_node->n_extra_sources * sizeof(int));
602 if( NULL == exchange_node->rank_extra_sources_array ) {
603 goto Error;
604 }
605 for (i = 0, tmp = node_rank * (tree_order - 1) + cnt;
606 i < tree_order - 1 && tmp < num_nodes; ++i, ++tmp) {
607 NETPATTERNS_VERBOSE(("extra_source#%d = %d", i, tmp));
608 exchange_node->rank_extra_sources_array[i] = tmp;
609 }
610 } else {
611 exchange_node->rank_extra_sources_array = NULL;
612 }
613 } else {
614 exchange_node->n_extra_sources = 1;
615 exchange_node->rank_extra_sources_array = (int *) malloc (sizeof(int));
616 if( NULL == exchange_node->rank_extra_sources_array ) {
617 goto Error;
618 }
619 exchange_node->rank_extra_sources_array[0] = (node_rank - cnt) / (tree_order - 1);
620 NETPATTERNS_VERBOSE(("extra_source#%d = %d", 0,
621 exchange_node->rank_extra_sources_array[0] ));
622 }
623
624
625 if (EXCHANGE_NODE == exchange_node->node_type) {
626 exchange_node->n_exchanges = n_levels;
627
628
629 exchange_node->rank_exchanges = (int **) malloc
630 (exchange_node->n_exchanges * sizeof(int *));
631 if(NULL == exchange_node->rank_exchanges) {
632 goto Error;
633 }
634 for (i = 0; i < exchange_node->n_exchanges; i++) {
635 exchange_node->rank_exchanges[i] = (int *) malloc
636 ((tree_order - 1) * sizeof(int));
637 if( NULL == exchange_node->rank_exchanges ) {
638 goto Error;
639 }
640 }
641
642 for(i = 0, kpow_num = 1; i < exchange_node->n_exchanges;
643 i++, kpow_num *= tree_order) {
644 k_base = node_rank / (kpow_num * tree_order);
645 for(j = 1; j < tree_order; j++) {
646 peer = node_rank + kpow_num * j;
647 if (k_base != peer/(kpow_num * tree_order)) {
648
649 peer = k_base * (kpow_num * tree_order) +
650 peer % (kpow_num * tree_order);
651 }
652 exchange_node->rank_exchanges[i][j - 1] = peer;
653 NETPATTERNS_VERBOSE(("rank_exchanges#(%d,%d)/%d = %d",
654 i, j, tree_order, peer));
655 }
656 }
657 } else {
658 exchange_node->n_exchanges=0;
659 exchange_node->rank_exchanges=NULL;
660 }
661
662
663
664
665
666 exchange_node->n_tags = tree_order * n_levels + 1;
667
668
669 return OMPI_SUCCESS;
670
671 Error:
672
673 ompi_netpatterns_cleanup_recursive_knomial_tree_node (exchange_node);
674
675
676 return OMPI_ERROR;
677 }
678
679 OMPI_DECLSPEC void ompi_netpatterns_cleanup_recursive_knomial_tree_node(
680 netpatterns_k_exchange_node_t *exchange_node)
681 {
682 int i;
683
684 if (exchange_node->n_extra_sources > 0) {
685 free(exchange_node->rank_extra_sources_array);
686 exchange_node->rank_extra_sources_array = NULL;
687 exchange_node->n_extra_sources = 0;
688 }
689 if (exchange_node->n_exchanges > 0) {
690 for (i=0 ; i<exchange_node->n_exchanges; i++) {
691 free(exchange_node->rank_exchanges[i]);
692 exchange_node->rank_exchanges[i] = NULL;
693 }
694 free(exchange_node->rank_exchanges);
695 exchange_node->rank_exchanges = NULL;
696 exchange_node->n_exchanges = 0;
697 }
698 }
699
700 #if 1
701 OMPI_DECLSPEC int ompi_netpatterns_setup_recursive_doubling_n_tree_node(int num_nodes, int node_rank, int tree_order,
702 netpatterns_pair_exchange_node_t *exchange_node)
703 {
704
705 int i, tmp, cnt;
706 int n_levels;
707 int shift, mask;
708
709 NETPATTERNS_VERBOSE(("Enter ompi_netpatterns_setup_recursive_doubling_n_tree_node(num_nodes=%d, node_rank=%d, tree_order=%d)", num_nodes, node_rank, tree_order));
710
711 assert(num_nodes > 1);
712 while (tree_order > num_nodes) {
713 tree_order /= 2;
714 }
715
716 exchange_node->tree_order = tree_order;
717
718 assert(0 == (tree_order & (tree_order - 1)));
719
720
721 n_levels = 0;
722
723 cnt=1;
724 while ( num_nodes > cnt ) {
725 cnt *= tree_order;
726 n_levels++;
727 };
728
729
730
731 if ( cnt > num_nodes) {
732 cnt /= tree_order;
733 n_levels--;
734 }
735 exchange_node->log_tree_order = n_levels;
736 if (2 == tree_order) {
737 exchange_node->log_2 = exchange_node->log_tree_order;
738 }
739
740 tmp=1;
741 for (i=0 ; i < n_levels ; i++ ) {
742 tmp *= tree_order;
743 }
744
745 assert(tmp == cnt);
746
747 exchange_node->n_largest_pow_tree_order = tmp;
748 if (2 == tree_order) {
749 exchange_node->n_largest_pow_2 = exchange_node->n_largest_pow_tree_order;
750 }
751
752
753
754
755
756 if ( node_rank + 1 > cnt ) {
757 exchange_node->node_type = EXTRA_NODE;
758 } else {
759 exchange_node->node_type = EXCHANGE_NODE;
760 }
761
762
763
764
765 if ( EXCHANGE_NODE == exchange_node->node_type ) {
766 exchange_node->n_extra_sources = 0;
767 for (tmp = node_rank + cnt; tmp < num_nodes; tmp += cnt) {
768 ++exchange_node->n_extra_sources;
769 }
770 if (exchange_node->n_extra_sources > 0) {
771 exchange_node->rank_extra_sources_array = (int *) malloc
772 (exchange_node->n_extra_sources * sizeof(int));
773 if( NULL == exchange_node->rank_extra_sources_array ) {
774 goto Error;
775 }
776 for (i = 0, tmp = node_rank + cnt; tmp < num_nodes; ++i, tmp += cnt) {
777 NETPATTERNS_VERBOSE(("extra_source#%d = %d", i, tmp));
778 exchange_node->rank_extra_sources_array[i] = tmp;
779 }
780 } else {
781 exchange_node->rank_extra_sources_array = NULL;
782 }
783 } else {
784 exchange_node->n_extra_sources = 1;
785 exchange_node->rank_extra_sources_array = (int *) malloc (sizeof(int));
786 if( NULL == exchange_node->rank_extra_sources_array ) {
787 goto Error;
788 }
789 exchange_node->rank_extra_sources_array[0] = node_rank & (cnt - 1);
790 NETPATTERNS_VERBOSE(("extra_source#%d = %d", 0, node_rank & (cnt - 1)));
791 }
792
793
794 if (1 == exchange_node->n_extra_sources) {
795 exchange_node->rank_extra_source = exchange_node->rank_extra_sources_array[0];
796 } else {
797 exchange_node->rank_extra_source = -1;
798 }
799
800
801 if ( EXCHANGE_NODE == exchange_node->node_type ) {
802 exchange_node->n_exchanges = n_levels * (tree_order - 1);
803 exchange_node->rank_exchanges = (int *) malloc
804 (exchange_node->n_exchanges * sizeof(int));
805 if( NULL == exchange_node->rank_exchanges ) {
806 goto Error;
807 }
808
809
810 for ( i = 0, shift = 1 ; i < exchange_node->n_exchanges ; shift *= tree_order ) {
811 for ( mask = 1 ; mask < tree_order ; ++mask, ++i ) {
812 exchange_node->rank_exchanges[i] = node_rank ^ (mask * shift);
813 NETPATTERNS_VERBOSE(("rank_exchanges#%d/%d = %d", i, tree_order, node_rank ^ (mask * shift)));
814 }
815 }
816
817 } else {
818
819 exchange_node->n_exchanges=0;
820 exchange_node->rank_exchanges=NULL;
821
822 }
823
824
825
826
827
828 exchange_node->n_tags = tree_order * n_levels + 1;
829
830
831 return OMPI_SUCCESS;
832
833 Error:
834 if (exchange_node->rank_extra_sources_array != NULL) {
835 free(exchange_node->rank_extra_sources_array);
836 }
837
838
839 return OMPI_ERROR;
840 }
841
842 OMPI_DECLSPEC void ompi_netpatterns_cleanup_recursive_doubling_tree_node(
843 netpatterns_pair_exchange_node_t *exchange_node)
844 {
845 NETPATTERNS_VERBOSE(("About to release rank_extra_sources_array and rank_exchanges"));
846 if (exchange_node->rank_extra_sources_array != NULL) {
847 free(exchange_node->rank_extra_sources_array);
848 }
849
850 if (exchange_node->rank_exchanges != NULL) {
851 free(exchange_node->rank_exchanges);
852 }
853 }
854 #endif
855
856 OMPI_DECLSPEC int ompi_netpatterns_setup_recursive_doubling_tree_node(int num_nodes, int node_rank,
857 netpatterns_pair_exchange_node_t *exchange_node)
858 {
859 return ompi_netpatterns_setup_recursive_doubling_n_tree_node(num_nodes, node_rank, 2, exchange_node);
860 }
861
862 #if 0
863
864 OMPI_DECLSPEC int ompi_netpatterns_setup_recursive_doubling_n_tree_node(int num_nodes, int node_rank,int tree_order,
865 netpatterns_pair_exchange_node_t *exchange_node)
866 {
867
868
869 int i,tmp,cnt,result,n_extra_nodes;
870 int n_exchanges;
871
872
873
874 n_exchanges=0;
875 result=num_nodes;
876
877
878 cnt=1;
879 while( num_nodes > cnt ) {
880 cnt*=tree_order;
881 n_exchanges++;
882 };
883
884
885
886 if( cnt > num_nodes) {
887 cnt/=tree_order;
888 n_exchanges--;
889 }
890 exchange_node->log_2=n_exchanges;
891
892 tmp=1;
893 for(i=0 ; i < n_exchanges ; i++ ) {
894 tmp*=2;
895 }
896 exchange_node->n_largest_pow_2=tmp;
897
898
899
900
901
902 if( node_rank+1 > cnt ) {
903 exchange_node->node_type=EXTRA_NODE;
904 } else {
905 exchange_node->node_type=EXCHANGE_NODE;
906 }
907
908
909
910
911 n_extra_nodes=num_nodes-cnt;
912
913 if ( EXCHANGE_NODE == exchange_node->node_type ) {
914
915 if( node_rank < n_extra_nodes ) {
916 exchange_node->n_extra_sources=1;
917 exchange_node->rank_extra_source=cnt+node_rank;
918 } else {
919 exchange_node->n_extra_sources=0;
920 exchange_node->rank_extra_source=-1;
921 }
922
923 } else {
924 exchange_node->n_extra_sources=1;
925 exchange_node->rank_extra_source=node_rank-cnt;
926 }
927
928
929 if( EXCHANGE_NODE == exchange_node->node_type ) {
930
931 exchange_node->n_exchanges=n_exchanges;
932 exchange_node->rank_exchanges=(int *) malloc
933 (n_exchanges*sizeof(int));
934 if( NULL == exchange_node->rank_exchanges ) {
935 goto Error;
936 }
937
938
939 result=1;
940 tmp=node_rank;
941 for( i=0 ; i < n_exchanges ; i++ ) {
942 if(tmp & 1 ) {
943 exchange_node->rank_exchanges[i]=
944 node_rank-result;
945 } else {
946 exchange_node->rank_exchanges[i]=
947 node_rank+result;
948 }
949 result*=2;
950 tmp/=2;
951 }
952
953 } else {
954
955 exchange_node->n_exchanges=0;
956 exchange_node->rank_exchanges=NULL;
957
958 }
959
960
961
962
963 exchange_node->n_tags=2*n_exchanges+1;
964
965
966 exchange_node->rank_extra_sources_array = NULL;
967
968
969 return OMPI_SUCCESS;
970
971 Error:
972
973
974 return OMPI_ERROR;
975 }
976 #endif
977