void diy::detail::KDTreeSamplingPartition<Block,Point>:: split_to_neighbors(Block* b, const diy::ReduceProxy& srp, int dim) const { int lid = srp.master()->lid(srp.gid()); RCLink* link = static_cast<RCLink*>(srp.master()->link(lid)); // determine split float split = find_split(link->core(), link->bounds()); for (int i = 0; i < link->size(); ++i) { srp.enqueue(link->target(i), split); srp.enqueue(link->target(i), link->direction(i)); } }
static hwloc_obj_t find_split(hwloc_topology_t topo, hwloc_obj_t obj) { unsigned k; hwloc_obj_t nxt; if (1 < obj->arity) { return obj; } for (k=0; k < obj->arity; k++) { nxt = find_split(topo, obj->children[k]); if (NULL != nxt) { return nxt; } } return NULL; }
tree_t *convert_to_bst(int arr[], int start, int end) { tree_t *n = NULL; int split; if (start > end) { return (NULL); } if (start == end) { n = create_new_node(arr[start]); return (n); } split = find_split(start, end); printf("convert_to_bst (start, end, split) : %d, %d, %d\n", start, end, split); n = create_new_node(arr[split]); n->right = convert_to_bst(arr, start, split - 1); n->left = convert_to_bst(arr, split + 1, end); return (n); }
/* recursively climb the topology, pruning procs beyond that allowed * by the given ppr */ static void prune(orte_jobid_t jobid, orte_app_idx_t app_idx, orte_node_t *node, opal_hwloc_level_t *level, orte_vpid_t *nmapped) { hwloc_obj_t obj, top; unsigned int i, nobjs; hwloc_obj_type_t lvl; unsigned cache_level = 0, k; int nprocs; hwloc_cpuset_t avail, cpus, childcpus; int n, limit, nmax, nunder, idx, idxmax = 0; orte_proc_t *proc, *pptr, *procmax; opal_hwloc_level_t ll; char dang[64]; hwloc_obj_t locale; opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:ppr: pruning level %d", *level); /* convenience */ ll = *level; /* convenience */ lvl = opal_hwloc_levels[ll]; limit = ppr[ll]; if (0 == limit) { /* no limit at this level, so move up if necessary */ if (0 == ll) { /* done */ return; } --(*level); prune(jobid, app_idx, node, level, nmapped); return; } /* handle the darn cache thing again */ if (OPAL_HWLOC_L3CACHE_LEVEL == ll) { cache_level = 3; } else if (OPAL_HWLOC_L2CACHE_LEVEL == ll) { cache_level = 2; } else if (OPAL_HWLOC_L1CACHE_LEVEL == ll) { cache_level = 1; } /* get the number of resources at this level on this node */ nobjs = opal_hwloc_base_get_nbobjs_by_type(node->topology, lvl, cache_level, OPAL_HWLOC_AVAILABLE); /* for each resource, compute the number of procs sitting * underneath it and check against the limit */ for (i=0; i < nobjs; i++) { obj = opal_hwloc_base_get_obj_by_type(node->topology, lvl, cache_level, i, OPAL_HWLOC_AVAILABLE); /* get the available cpuset */ avail = opal_hwloc_base_get_available_cpus(node->topology, obj); /* look at the intersection of this object's cpuset and that * of each proc in the job/app - if they intersect, then count this proc * against the limit */ nprocs = 0; for (n=0; n < node->procs->size; n++) { if (NULL == (proc = (orte_proc_t*)opal_pointer_array_get_item(node->procs, n))) { continue; } if (proc->name.jobid != jobid || proc->app_idx != app_idx) { continue; } locale = NULL; if (orte_get_attribute(&proc->attributes, ORTE_PROC_HWLOC_LOCALE, (void**)&locale, OPAL_PTR)) { ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND); return; } cpus = opal_hwloc_base_get_available_cpus(node->topology, locale); if (hwloc_bitmap_intersects(avail, cpus)) { nprocs++; } } opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:ppr: found %d procs limit %d", nprocs, limit); /* check against the limit */ while (limit < nprocs) { /* need to remove procs - do this in a semi-intelligent * manner to provide a little load balancing by cycling * across the objects beneath this one, removing procs * in a round-robin fashion until the limit is satisfied * * NOTE: I'm sure someone more knowledgeable with hwloc * will come up with a more efficient way to do this, so * consider this is a starting point */ /* find the first level that has more than * one child beneath it - if all levels * have only one child, then return this * object */ top = find_split(node->topology, obj); hwloc_obj_type_snprintf(dang, 64, top, 1); opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:ppr: SPLIT AT LEVEL %s", dang); /* cycle across the children of this object */ nmax = 0; procmax = NULL; idx = 0; /* find the child with the most procs underneath it */ for (k=0; k < top->arity && limit < nprocs; k++) { /* get this object's available cpuset */ childcpus = opal_hwloc_base_get_available_cpus(node->topology, top->children[k]); nunder = 0; pptr = NULL; for (n=0; n < node->procs->size; n++) { if (NULL == (proc = (orte_proc_t*)opal_pointer_array_get_item(node->procs, n))) { continue; } if (proc->name.jobid != jobid || proc->app_idx != app_idx) { continue; } locale = NULL; if (orte_get_attribute(&proc->attributes, ORTE_PROC_HWLOC_LOCALE, (void**)&locale, OPAL_PTR)) { ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND); return; } cpus = opal_hwloc_base_get_available_cpus(node->topology, locale); if (hwloc_bitmap_intersects(childcpus, cpus)) { nunder++; if (NULL == pptr) { /* save the location of the first proc under this object */ pptr = proc; idx = n; } } } if (nmax < nunder) { opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:ppr: PROCS UNDER CHILD %d %d MAX %d", k, nunder, nmax); nmax = nunder; procmax = pptr; idxmax = idx; } } if (NULL == procmax) { /* can't find anything to remove - error out */ goto error; } /* remove it */ opal_output_verbose(5, orte_rmaps_base_framework.framework_output, "mca:rmaps:ppr: removing proc at posn %d", idxmax); opal_pointer_array_set_item(node->procs, idxmax, NULL); node->num_procs--; node->slots_inuse--; if (node->slots_inuse < 0) { node->slots_inuse = 0; } nprocs--; *nmapped -= 1; OBJ_RELEASE(procmax); } } /* finished with this level - move up if necessary */ if (0 == ll) { return; } --(*level); prune(jobid, app_idx, node, level, nmapped); return; error: opal_output(0, "INFINITE LOOP"); }
void diy::detail::KDTreeSamplingPartition<Block,Point>:: update_links(Block* b, const diy::ReduceProxy& srp, int dim, int round, int rounds, bool wrap, const Bounds& domain) const { auto log = get_logger(); int gid = srp.gid(); int lid = srp.master()->lid(gid); RCLink* link = static_cast<RCLink*>(srp.master()->link(lid)); // (gid, dir) -> i std::map<std::pair<int,diy::Direction>, int> link_map; for (int i = 0; i < link->size(); ++i) link_map[std::make_pair(link->target(i).gid, link->direction(i))] = i; // NB: srp.enqueue(..., ...) should match the link std::vector<float> splits(link->size()); for (int i = 0; i < link->size(); ++i) { float split; diy::Direction dir; int in_gid = link->target(i).gid; while(srp.incoming(in_gid)) { srp.dequeue(in_gid, split); srp.dequeue(in_gid, dir); // reverse dir for (int j = 0; j < dim_; ++j) dir[j] = -dir[j]; int k = link_map[std::make_pair(in_gid, dir)]; log->trace("{} {} {} -> {}", in_gid, dir, split, k); splits[k] = split; } } RCLink new_link(dim_, link->core(), link->core()); bool lower = !(gid & (1 << (rounds - 1 - round))); // fill out the new link for (int i = 0; i < link->size(); ++i) { diy::Direction dir = link->direction(i); //diy::Direction wrap_dir = link->wrap(i); // we don't use existing wrap, but restore it from scratch if (dir[dim] != 0) { if ((dir[dim] < 0 && lower) || (dir[dim] > 0 && !lower)) { int nbr_gid = divide_gid(link->target(i).gid, !lower, round, rounds); diy::BlockID nbr = { nbr_gid, srp.assigner().rank(nbr_gid) }; new_link.add_neighbor(nbr); new_link.add_direction(dir); Bounds bounds = link->bounds(i); update_neighbor_bounds(bounds, splits[i], dim, !lower); new_link.add_bounds(bounds); if (wrap) new_link.add_wrap(find_wrap(new_link.bounds(), bounds, domain)); else new_link.add_wrap(diy::Direction()); } } else // non-aligned side { for (int j = 0; j < 2; ++j) { int nbr_gid = divide_gid(link->target(i).gid, j == 0, round, rounds); Bounds bounds = link->bounds(i); update_neighbor_bounds(bounds, splits[i], dim, j == 0); if (intersects(bounds, new_link.bounds(), dim, wrap, domain)) { diy::BlockID nbr = { nbr_gid, srp.assigner().rank(nbr_gid) }; new_link.add_neighbor(nbr); new_link.add_direction(dir); new_link.add_bounds(bounds); if (wrap) new_link.add_wrap(find_wrap(new_link.bounds(), bounds, domain)); else new_link.add_wrap(diy::Direction()); } } } } // add link to the dual block int dual_gid = divide_gid(gid, !lower, round, rounds); diy::BlockID dual = { dual_gid, srp.assigner().rank(dual_gid) }; new_link.add_neighbor(dual); Bounds nbr_bounds = link->bounds(); // old block bounds update_neighbor_bounds(nbr_bounds, find_split(new_link.bounds(), nbr_bounds), dim, !lower); new_link.add_bounds(nbr_bounds); new_link.add_wrap(diy::Direction()); // dual block cannot be wrapped if (lower) { diy::Direction right; right[dim] = 1; new_link.add_direction(right); } else { diy::Direction left; left[dim] = -1; new_link.add_direction(left); } // update the link; notice that this won't conflict with anything since // reduce is using its own notion of the link constructed through the // partners link->swap(new_link); }
/** * Parse XML transaction node and fill a ImportTransaction with results. * * \param transaction_node XML transaction node to parse. */ void recuperation_donnees_gnucash_transaction ( xmlNodePtr transaction_node ) { struct ImportTransaction * transaction; struct ImportAccount * account = NULL; struct gnucash_split * split; gchar * date_string, *space, *tiers; GDate * date; xmlNodePtr splits, split_node, date_node; GSList * split_list = NULL; GsbReal total = { 0 , 0 }; /* Transaction amount, category, account, etc.. */ splits = get_child ( transaction_node, "splits" ); split_node = splits -> children; while ( split_node ) { struct ImportAccount * split_account = NULL; struct gnucash_category * categ = NULL; gint p_r = OPERATION_NORMALE; GsbReal amount; /** * Gnucash transactions are in fact "splits", much like grisbi's * splits of transactions. We need to parse all splits and * see whether they are transfers to real accounts or transfers * to category accounts. In that case, we only create one * transactions. The other is discarded as grisbi is not a * double part financial engine. */ if ( node_strcmp ( split_node, "split" ) ) { gchar * account_name = NULL, * categ_name = NULL; split_account = find_imported_account_by_uid ( child_content ( split_node, "account" ) ); categ = find_imported_categ_by_uid ( child_content ( split_node, "account" ) ); amount = gnucash_value ( child_content(split_node, "value") ); if ( categ ) categ_name = categ -> name; if ( split_account ) { /* All of this stuff is here since we are dealing with the account split, not the category one */ account_name = split_account -> nom_de_compte; total = gsb_real_add ( total, amount ); if ( strcmp(child_content(split_node, "reconciled-state"), "n") ) p_r = OPERATION_RAPPROCHEE; } split = find_split ( split_list, amount, split_account, categ ); if ( split ) { update_split ( split, amount, account_name, categ_name ); } else { split = new_split ( amount, account_name, categ_name ); split_list = g_slist_append ( split_list, split ); split -> notes = child_content(split_node, "memo"); } if ( p_r != OPERATION_NORMALE ) split -> p_r = p_r; } split_node = split_node -> next; } if ( ! split_list ) return; /* Transaction date */ date_node = get_child ( transaction_node, "date-posted" ); date_string = child_content (date_node, "date"); space = strchr ( date_string, ' ' ); if ( space ) *space = 0; date = g_date_new (); g_date_set_parse ( date, date_string ); if ( !g_date_valid ( date )) fprintf ( stderr, "grisbi: Can't parse date %s\n", date_string ); /* Tiers */ tiers = child_content ( transaction_node, "description" ); /* Create transaction */ split = split_list -> data; transaction = new_transaction_from_split ( split, tiers, date ); transaction -> operation_ventilee = 0; transaction -> ope_de_ventilation = 0; account = find_imported_account_by_name ( split -> account ); if ( account ) account -> operations_importees = g_slist_append ( account -> operations_importees, transaction ); /** Splits of transactions are handled the same way, we process them if we find more than one split in transaction node. */ if ( g_slist_length ( split_list ) > 1 ) { transaction -> operation_ventilee = 1; transaction -> montant = total; while ( split_list ) { split = split_list -> data; account = NULL; transaction = new_transaction_from_split ( split, tiers, date ); transaction -> ope_de_ventilation = 1; account = find_imported_account_by_name ( split -> account ); if ( account ) account -> operations_importees = g_slist_append ( account -> operations_importees, transaction ); split_list = split_list -> next; } } }
void Search_Range::nearest_sphere_recurse( One_Tree *tree ) { Near_Workspace &ws = near_workspace; // debug const bool debug = false; assert(ws._num_calls < num_nodes() ); ++ws._num_calls; const size_t d = tree->_d; double x_lo, x_hi; old_lo_hi(d, x_lo, x_hi); // walk until the path to x_lo and x_hi diverge // this might update x_lo and x_hi with a new closest Tree_Node *n = find_split( tree, x_lo, x_hi, true ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << "Diverges at node "; Range_Tree::print_single_node( n, tree ); // std::cout << std::endl; } // never split, nothing is in range if (!n) { if (debug) std::cout << " no nearest sphere was in range." << std::endl; return; } // If n is a leaf, then immediately recurse by dimension on its subtree. // For efficiency we just check the distance immediately, since the result is the same. if (n->is_leaf()) { if (debug) std::cout << " fathomed at leaf node." << std::endl; new_lo_hi( n->_sphere, d, x_lo, x_hi); return; } // go down right and left sides, checking subtrees // right { if (debug) { std::cout << " Searching Right subtree " << std::endl; } Tree_Node * r = n->_right; while( r ) { new_old_lo_hi( r->_sphere, d, x_lo, x_hi); const double &x = _spheres[ r->_sphere ][ d ]; if ( r->is_leaf() ) break; // discard right->right? if ( x > x_hi ) r = r->_left; else { // recurse on left if (r->_left->_subtree) { if (debug) std::cout << "recursively searching left subtree. " << std::endl; nearest_sphere_recurse( r->_left->_subtree ); } // fathomed at last dimension else { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Nearest all leaves, left subtree, rooted at node "; print_single_node(r->_left, tree); std::cout << std::endl; } assert( last_dimension(tree) || r->_left->is_leaf() ); // go down left (recurse) but with current dimension nearest_sphere_leaves( r->_left, d ); } r = r->_right; } } } // left { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << "Searching Left subtree " << std::endl; } Tree_Node * lft = n->_left; while( lft ) { new_old_lo_hi( lft->_sphere, d, x_lo, x_hi); if (lft->is_leaf()) break; const double &x = _spheres[ lft->_sphere ][ tree->_d ]; if ( x_lo > x ) lft = lft->_right; else { // right tree is (was) in the range if ( lft->_right ) { if ( lft->_right->_subtree ) nearest_sphere_recurse( lft->_right->_subtree ); // fathomed at last dimension else { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Nearest all leaves, right subtree, rooted at node "; print_single_node(lft->_right, tree); std::cout << std::endl; } assert( last_dimension(tree) || lft->_right->is_leaf() ); // go down right (recurse) but with current dimension nearest_sphere_leaves( lft->_right, d ); } } lft = lft->_left; // null if it was a leaf } } } }
void Search_Range::trim_line_anchored_recurse( One_Tree *tree ) { // walk until the path to x_lo and x_hi diverge double x_lo, x_hi; Tree_Node *n = find_split( tree, x_lo, x_hi ); // nothing was in range, no spheres near enough to possibly trim the line segment if (!n) return; // leaf, only one sphere in range, trim with it now if (n->is_leaf()) { trim_leaf( n->_sphere ); return; } // go down right and left sides // right { Tree_Node * r = n->_right; while( r ) { assert( r->is_wellformed() ); const double &x = _spheres[ r->_sphere ][ tree->_d ]; if ( x_hi > x ) { // left tree is in the range if ( r->_left ) { assert( r->_left->is_wellformed() ); if (r->_left->_subtree) trim_line_anchored_recurse( r->_left->_subtree ); // fathomed at last dimension else { assert( last_dimension(tree) ); trim_all_leaves( r->_left ); get_line_neighborhood( tree->_d, x_lo, x_hi ); } } // leaf else { assert( r->is_leaf() ); trim_leaf( r->_sphere ); get_line_neighborhood( tree->_d, x_lo, x_hi ); } r = r->_right; // null if it was a leaf } else r = r->_left; // if r == 0, then its parent was a leaf and out of range } } // left { Tree_Node * lft = n->_left; while( lft ) { assert( lft->is_wellformed() ); const double &x = _spheres[ lft->_sphere ][ tree->_d ]; if ( x_lo <= x ) { // right tree is in the range if ( lft->_right ) { assert( lft->_right->is_wellformed() ); if ( lft->_right->_subtree ) trim_line_anchored_recurse( lft->_right->_subtree ); // fathomed at last dimension else { assert( last_dimension(tree) ); trim_all_leaves( lft->_right ); get_line_neighborhood( tree->_d, x_lo, x_hi ); } } // leaf else { assert( lft->is_leaf() ); trim_leaf( lft->_sphere ); get_line_neighborhood( tree->_d, x_lo, x_hi ); } lft = lft->_left; // null if it was a leaf } else { lft = lft->_right; // if lft == 0, then its old value (parent) was a leaf and out of range } } } }
bool Search_Range::no_near_spheres_recurse( One_Tree *tree ) { Near_Workspace &ws = near_workspace; // debug assert(ws._num_calls <= num_nodes() ); ++ws._num_calls; double x_lo = ws._p[tree->_d] - ws._thresh; double x_hi = ws._p[tree->_d] + ws._thresh; // walk until the path to x_lo and x_hi diverge Tree_Node *n = find_split( tree, x_lo, x_hi); // nothing in range if (!n) return true; // only one sphere in range, check it now if (n->is_leaf()) return no_near_leaf(n->_sphere); // go down right and left sides // right { Tree_Node * r = n->_right; while( r ) { assert( r->is_wellformed() ); const double &x = _spheres[ r->_sphere ][ tree->_d ]; if ( x_hi > x ) { // left tree is in the range if ( r->_left ) { assert( r->_left->is_wellformed() ); if (r->_left->_subtree) { if (!no_near_spheres_recurse( r->_left->_subtree )) return false; } // fathomed at last dimension else { assert( last_dimension(tree) ); // check entire subtree explicitly if (!no_near_leaves( r->_left )) return false; } } // leaf else { // check leaf sphere assert(r->is_leaf()); if (!no_near_leaf( r->_sphere )) return false; } r = r->_right; // null if it was a leaf } else r = r->_left; // if r == 0, then its parent was a leaf and out of range } } // left { Tree_Node * lft = n->_left; while( lft ) { assert( lft->is_wellformed() ); const double &x = _spheres[ lft->_sphere ][ tree->_d ]; if ( x_lo <= x ) { // right tree is in the range if ( lft->_right ) { assert( lft->is_wellformed() ); if ( lft->_right->_subtree ) { if (!no_near_spheres_recurse( lft->_right->_subtree )) return false; } // fathomed at last dimension else { assert( last_dimension(tree) ); if (!no_near_leaves( lft->_right )) return false; } } // leaf else { assert( lft->is_leaf() ); if (!no_near_leaf( lft->_sphere )) return false; } lft = lft->_left; // null if it was a leaf } else { lft = lft->_right; // if lft == 0, then its old value (parent) was a leaf and out of range } } } return true; }
void Search_Range::all_near_spheres_recurse( One_Tree *tree ) { const bool debug = false; Near_Workspace &ws = near_workspace; // debug assert(ws._num_calls < num_nodes() ); ++ws._num_calls; const size_t d = tree->_d; double x_lo = ws._p[d] - ws._thresh; double x_hi = ws._p[d] + ws._thresh; // walk until the path to x_lo and x_hi diverge Tree_Node *n = find_split( tree, x_lo, x_hi ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << "Diverges at node "; Range_Tree::print_single_node( n, tree ); // std::cout << std::endl; } // never split, nothing is in range if (!n) { if (debug) std::cout << " no spheres were in range." << std::endl; return; } // If n is a leaf, then immediately recurse by dimension on its subtree. // For efficiency we just check the distance immediately, since the result is the same. if (n->is_leaf()) { if (debug) std::cout << " fathomed at leaf node." << std::endl; add_leaf(n->_sphere); return; } // go down right and left sides, reporting subtrees // right { if (debug) { std::cout << " Searching Right subtree " << std::endl; } Tree_Node * r = n->_right; while( r ) { const double &x = _spheres[ r->_sphere ][ d ]; if ( x_hi > x ) { // left tree is in the range if ( r->_left ) { if (r->_left->_subtree) all_near_spheres_recurse( r->_left->_subtree ); // fathomed at last dimension else { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding left subtree rooted at node "; print_single_node(r->_left, tree); std::cout << std::endl; } assert( last_dimension(tree) || r->_left->is_leaf() ); add_all_leaves( r->_left ); } } // leaf else { assert( r->is_leaf() ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding leaf node "; print_single_node(r, tree); std::cout << std::endl; } add_leaf( r->_sphere ); } r = r->_right; // null if it was a leaf } else r = r->_left; // if r == 0, then its parent was a leaf and out of range } } // left { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << "Searching Left subtree " << std::endl; } Tree_Node * lft = n->_left; while( lft ) { const double &x = _spheres[ lft->_sphere ][ tree->_d ]; if ( x_lo <= x ) { // right tree is in the range if ( lft->_right ) { if ( lft->_right->_subtree ) all_near_spheres_recurse( lft->_right->_subtree ); // fathomed at last dimension else { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding right subtree rooted at node "; print_single_node(lft->_right, tree); std::cout << std::endl; } assert( last_dimension(tree) || lft->_right->is_leaf() ); add_all_leaves( lft->_right ); } } // leaf else { assert( lft->is_leaf() ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding leaf node "; print_single_node(lft, tree); std::cout << std::endl; } add_leaf( lft->_sphere ); } lft = lft->_left; // null if it was a leaf } else { lft = lft->_right; // if lft == 0, then its old value (parent) was a leaf and out of range } } } }