/* * get size of tree */ size_t opal_tree_get_size(opal_tree_t* tree) { #if OPAL_ENABLE_DEBUG /* not sure if we really want this running in devel, as it does * slow things down. Wanted for development of splice / join to * make sure length was reset properly */ size_t check_len = 0; opal_tree_item_t *root; if (!opal_tree_is_empty(tree)) { /* tree has entries so count up items */ root = opal_tree_get_root(tree); check_len = count_descendants(root); } if (check_len != tree->opal_tree_num_items) { fprintf(stderr," Error :: opal_tree_get_size - opal_tree_num_items does not match actual tree length\n"); fflush(stderr); abort(); } #endif return tree->opal_tree_num_items; }
/* * return next tree item that matches key */ opal_tree_item_t *opal_tree_find_with(opal_tree_item_t *item, void *key) { opal_tree_item_t *root, *curr_item = item, *result = NULL; if (!opal_tree_is_empty(item->opal_tree_container)) { /* check my descendant for a match */ result = find_in_descendants(opal_tree_get_first_child(item), key); if (!result) { /* check my siblings for match */ if (NULL != (curr_item = opal_tree_get_next_sibling(curr_item))) { result = find_in_descendants(curr_item, key); } } /* check my ancestors (uncles) for match */ root = opal_tree_get_root(item->opal_tree_container); curr_item = item; while (!result && curr_item && curr_item->opal_tree_num_ancestors > 0){ curr_item = opal_tree_get_next_sibling(item->opal_tree_parent); while (NULL == curr_item && item->opal_tree_parent->opal_tree_num_ancestors > 0) { item = item->opal_tree_parent; curr_item = opal_tree_get_next_sibling(item->opal_tree_parent); } if (curr_item) { /* search ancestors descendants for match */ result = find_in_descendants(curr_item, key); } } } return(result); }
/********************************* * Pretty Print Functions *********************************/ void rmaps_lama_max_tree_pretty_print_tree(opal_tree_t *tree) { if( NULL == tree ) { return; } if( opal_tree_is_empty(tree) ) { return; } pretty_print_subtree(tree, opal_tree_get_root(tree), 0); return; }
/* * remove item and all items below it from tree and return it to the caller */ opal_tree_item_t *opal_tree_remove_subtree(opal_tree_item_t *item) { #if OPAL_ENABLE_DEBUG /* validate that item does exist on tree */ if (NULL != item->opal_tree_container) { /* we point to a container, check if we can find item in tree */ if (!item_in_tree(opal_tree_get_root(item->opal_tree_container), item)) { return(NULL); } } else { return (NULL); } #endif /* remove from parent */ if (item->opal_tree_parent->opal_tree_first_child == item) { item->opal_tree_parent->opal_tree_first_child = item->opal_tree_next_sibling; } if (item->opal_tree_parent->opal_tree_last_child == item) { item->opal_tree_parent->opal_tree_last_child = item->opal_tree_prev_sibling; } item->opal_tree_parent->opal_tree_num_children--; /* remove from sibling pointers */ if (NULL != item->opal_tree_prev_sibling) { item->opal_tree_prev_sibling->opal_tree_next_sibling= item->opal_tree_next_sibling; } if (NULL != item->opal_tree_next_sibling) { item->opal_tree_next_sibling->opal_tree_prev_sibling= item->opal_tree_prev_sibling; } item->opal_tree_prev_sibling = NULL; item->opal_tree_next_sibling = NULL; /* adjust items relating to container */ item->opal_tree_container->opal_tree_num_items -= count_descendants(item); item->opal_tree_container = NULL; return(item); }
static int rmaps_lama_convert_hwloc_tree_to_opal_tree(opal_tree_t *opal_tree, hwloc_topology_t *hwloc_topo) { hwloc_obj_t topo_root; if( 15 <= opal_output_get_verbosity(orte_rmaps_base_framework.framework_output) ) { opal_output_verbose(15, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- Converting Topology:"); /* opal_dss.dump(0, opal_hwloc_topology, OPAL_HWLOC_TOPO); */ opal_dss.dump(0, *hwloc_topo, OPAL_HWLOC_TOPO); } topo_root = hwloc_get_root_obj(*hwloc_topo); rmaps_lama_convert_hwloc_subtree(topo_root, opal_tree_get_root(opal_tree)); return ORTE_SUCCESS; }
/********************************* * Function Defintions *********************************/ int rmaps_lama_build_max_tree(orte_job_t *jdata, opal_list_t *node_list, opal_tree_t * max_tree, bool *is_homogeneous) { int ret; opal_tree_t *tmp_tree = NULL; hwloc_topology_t topo, *last_topo = NULL; orte_node_t *cur_node = NULL; opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ---------------------------------"); opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- Building the Max Tree..."); opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ---------------------------------"); /* * Assume homogeneous system, unless otherwise noted */ *is_homogeneous = true; /* * Process all other unique trees from remote daemons who are in * this allocation */ for(cur_node = (orte_node_t*)opal_list_get_first(node_list); cur_node != (orte_node_t*)opal_list_get_end(node_list); cur_node = (orte_node_t*)opal_list_get_next(cur_node) ) { if (NULL == (topo = cur_node->topology)) { opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- No Tree Available: %s (skipping)", cur_node->name); } opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- Converting Remote Tree: %s", cur_node->name); /* * Convert to opal_tree */ tmp_tree = rmaps_lama_create_empty_max_tree(); rmaps_lama_convert_hwloc_tree_to_opal_tree(tmp_tree, &topo); if( 11 <= opal_output_get_verbosity(orte_rmaps_base_framework.framework_output) ) { rmaps_lama_max_tree_pretty_print_tree(tmp_tree); } /* * Compare the current and last topologies if we are still considering * this max tree to represent a homogeneous system. */ if( *is_homogeneous ) { if( NULL == last_topo ) { last_topo = &topo; } else { if( 0 != rmaps_lama_hwloc_compare_topos(last_topo, &topo) ) { *is_homogeneous = false; } } } /* * Prune the input tree so that is only contains levels that the user * asked for. */ if( 11 <= opal_output_get_verbosity(orte_rmaps_base_framework.framework_output) ) { opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ---------------------------------"); opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- Pruning input Tree..."); } if( ORTE_SUCCESS != (ret = rmaps_lama_prune_max_tree(tmp_tree, opal_tree_get_root(tmp_tree))) ) { return ret; } if( 11 <= opal_output_get_verbosity(orte_rmaps_base_framework.framework_output) ) { opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- Input Tree... - Post Prune"); rmaps_lama_max_tree_pretty_print_tree(tmp_tree); } /* * Merge into max_tree */ if( opal_tree_is_empty(max_tree) ) { opal_tree_dup(tmp_tree, max_tree); } else { if( ORTE_SUCCESS != (ret = rmaps_lama_merge_trees(tmp_tree, max_tree, opal_tree_get_root(tmp_tree), opal_tree_get_root(max_tree) ))) { return ret; } } /* * Release and move on... */ OBJ_RELEASE(tmp_tree); tmp_tree = NULL; } /* * Fill out the MPPR accounting information for each node */ for(cur_node = (orte_node_t*)opal_list_get_first(node_list); cur_node != (orte_node_t*)opal_list_get_end(node_list); cur_node = (orte_node_t*)opal_list_get_next(cur_node) ) { if( ORTE_SUCCESS != (ret = rmaps_lama_annotate_node_for_mppr(cur_node, hwloc_get_obj_by_depth(cur_node->topology, 0, 0))) ) { ORTE_ERROR_LOG(ret); return ret; } } /* * JJH: NEEDS TESTING * Note: This check is in place, but not used at the moment due to lack of * system availability. Pending system availability and further testing, * just assume heterogeneous. */ *is_homogeneous = false; /* * Display the final Max Tree */ opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ----- Final Max Tree... - %s system", (*is_homogeneous ? "Homogeneous" : "Heterogeneous") ); if( 11 <= opal_output_get_verbosity(orte_rmaps_base_framework.framework_output) ) { rmaps_lama_max_tree_pretty_print_tree(max_tree); } opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:lama: ---------------------------------"); return ORTE_SUCCESS; }