static int load_recursive_knomial_info(mca_bcol_ptpcoll_module_t *ptpcoll_module) { int rc = OMPI_SUCCESS; rc = netpatterns_setup_recursive_knomial_tree_node( ptpcoll_module->group_size, ptpcoll_module->super.sbgp_partner_module->my_index, mca_bcol_ptpcoll_component.k_nomial_radix, &ptpcoll_module->knomial_exchange_tree); return rc; }
int netpatterns_setup_narray_knomial_tree( int tree_order, int my_rank, int num_nodes, netpatterns_narray_knomial_tree_node_t *my_node) { /* local variables */ int n_levels, result; int my_level_in_tree, cnt ; int lvl,cum_cnt, my_rank_in_my_level,n_lvls_in_tree; int start_index,end_index; int rc; /* sanity check */ if( 1 >= tree_order ) { goto Error; } my_node->my_rank=my_rank; my_node->tree_size=num_nodes; /* figure out number of levels in tree */ n_levels=0; result=num_nodes-1; while (0 < result ) { result/=tree_order; n_levels++; }; /* figure out who my children and parents are */ my_level_in_tree=-1; result=my_rank; /* cnt - number of ranks in given level */ cnt=1; /* cummulative count of ranks */ while( 0 <= result ) { result-=cnt; cnt*=tree_order; my_level_in_tree++; }; /* int my_level_in_tree, n_children, n_parents; */ if( 0 == my_rank ) { my_node->n_parents=0; my_node->parent_rank=-1; my_rank_in_my_level=0; } else { my_node->n_parents=1; cnt=1; cum_cnt=0; for (lvl = 0 ; lvl < my_level_in_tree ; lvl ++ ) { /* cummulative count up to this level */ cum_cnt+=cnt; /* number of ranks in this level */ cnt*=tree_order; } my_node->rank_on_level = my_rank_in_my_level = my_rank-cum_cnt; my_node->level_size = cnt; rc = netpatterns_setup_recursive_knomial_tree_node( my_node->level_size, my_node->rank_on_level, tree_order, &my_node->k_node); if (OMPI_SUCCESS != rc) { goto Error; } /* tree_order consecutive ranks have the same parent */ my_node->parent_rank=cum_cnt-cnt/tree_order+my_rank_in_my_level/tree_order; } /* figure out number of levels in the tree */ n_lvls_in_tree=0; result=num_nodes; /* cnt - number of ranks in given level */ cnt=1; /* cummulative count of ranks */ while( 0 < result ) { result-=cnt; cnt*=tree_order; n_lvls_in_tree++; }; if(result < 0) { /* reset the size on group */ num_nodes = cnt / tree_order; } my_node->children_ranks=(int *)NULL; /* get list of children */ if( my_level_in_tree == (n_lvls_in_tree -1 ) ) { /* last level has no children */ my_node->n_children=0; } else { cum_cnt=0; cnt=1; for( lvl=0 ; lvl <= my_level_in_tree ; lvl++ ) { cum_cnt+=cnt; cnt*=tree_order; } start_index=cum_cnt+my_rank_in_my_level*tree_order; end_index=start_index+tree_order-1; /* don't go out of bounds at the end of the list */ if( end_index >= num_nodes ) { end_index = num_nodes-1; } if( start_index <= (num_nodes-1) ) { my_node->n_children=end_index-start_index+1; } else { my_node->n_children=0; } my_node->children_ranks=NULL; if( 0 < my_node->n_children ) { my_node->children_ranks= (int *)malloc( sizeof(int)*my_node->n_children); if( NULL == my_node->children_ranks) { goto Error; } for (lvl= start_index ; lvl <= end_index ; lvl++ ) { my_node->children_ranks[lvl-start_index]=lvl; } } } /* set node type */ if( 0 == my_node->n_parents ) { my_node->my_node_type=ROOT_NODE; } else if ( 0 == my_node->n_children ) { my_node->my_node_type=LEAF_NODE; } else { my_node->my_node_type=INTERIOR_NODE; } /* successful return */ return OMPI_SUCCESS; Error: /* error return */ return OMPI_ERROR; }