hwloc: core: reorder children in merge_useless_child() as well
When ignore_keep_structure is enabled, intermediate level can disappear between parent and child, making the new child complete_cpuset smaller, causing the child list to require a reorder just like in remove_ignored(). (cherry picked from commit open-mpi/hwloc@88afbe6b62) Embed this related commit: core: abstract out reorder_children(), needed when merging modifies the list of children (cherry picked from commit open-mpi/hwloc@14db82d391) Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
Этот коммит содержится в:
родитель
77978a846e
Коммит
fff1bb5dcd
@ -1635,6 +1635,28 @@ unlink_and_free_single_object(hwloc_obj_t *pparent)
|
|||||||
hwloc_free_unlinked_object(parent);
|
hwloc_free_unlinked_object(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reorder_children(hwloc_obj_t parent)
|
||||||
|
{
|
||||||
|
/* move the children list on the side */
|
||||||
|
hwloc_obj_t *prev, child, children = parent->first_child;
|
||||||
|
parent->first_child = NULL;
|
||||||
|
while (children) {
|
||||||
|
/* dequeue child */
|
||||||
|
child = children;
|
||||||
|
children = child->next_sibling;
|
||||||
|
/* find where to enqueue it */
|
||||||
|
prev = &parent->first_child;
|
||||||
|
while (*prev
|
||||||
|
&& (!child->cpuset || !(*prev)->cpuset
|
||||||
|
|| hwloc__object_cpusets_compare_first(child, *prev) > 0))
|
||||||
|
prev = &((*prev)->next_sibling);
|
||||||
|
/* enqueue */
|
||||||
|
child->next_sibling = *prev;
|
||||||
|
*prev = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove all ignored objects. */
|
/* Remove all ignored objects. */
|
||||||
static int
|
static int
|
||||||
remove_ignored(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
remove_ignored(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
||||||
@ -1656,25 +1678,8 @@ remove_ignored(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
|||||||
dropped = 1;
|
dropped = 1;
|
||||||
|
|
||||||
} else if (dropped_children) {
|
} else if (dropped_children) {
|
||||||
/* we keep this object but its children changed, reorder them by cpuset */
|
/* we keep this object but its children changed, reorder them by complete_cpuset */
|
||||||
|
reorder_children(parent);
|
||||||
/* move the children list on the side */
|
|
||||||
hwloc_obj_t *prev, children = parent->first_child;
|
|
||||||
parent->first_child = NULL;
|
|
||||||
while (children) {
|
|
||||||
/* dequeue child */
|
|
||||||
child = children;
|
|
||||||
children = child->next_sibling;
|
|
||||||
/* find where to enqueue it */
|
|
||||||
prev = &parent->first_child;
|
|
||||||
while (*prev
|
|
||||||
&& (!child->cpuset || !(*prev)->cpuset
|
|
||||||
|| hwloc__object_cpusets_compare_first(child, *prev) > 0))
|
|
||||||
prev = &((*prev)->next_sibling);
|
|
||||||
/* enqueue */
|
|
||||||
child->next_sibling = *prev;
|
|
||||||
*prev = child;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dropped;
|
return dropped;
|
||||||
@ -1804,20 +1809,23 @@ can_merge_group(hwloc_topology_t topology, hwloc_obj_t obj)
|
|||||||
* Merge with the only child if either the parent or the child has a type to be
|
* Merge with the only child if either the parent or the child has a type to be
|
||||||
* ignored while keeping structure
|
* ignored while keeping structure
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
merge_useless_child(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
merge_useless_child(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
||||||
{
|
{
|
||||||
hwloc_obj_t parent = *pparent, child, *pchild, ios;
|
hwloc_obj_t parent = *pparent, child, *pchild, ios;
|
||||||
int replacechild = 0, replaceparent = 0;
|
int replacechild = 0, replaceparent = 0, droppedchildren = 0;
|
||||||
|
|
||||||
|
if (!parent->first_child)
|
||||||
|
/* There are no child, nothing to merge. */
|
||||||
|
return 0;
|
||||||
|
|
||||||
for_each_child_safe(child, parent, pchild)
|
for_each_child_safe(child, parent, pchild)
|
||||||
merge_useless_child(topology, pchild);
|
droppedchildren += merge_useless_child(topology, pchild);
|
||||||
|
|
||||||
|
if (droppedchildren)
|
||||||
|
reorder_children(parent);
|
||||||
|
|
||||||
child = parent->first_child;
|
child = parent->first_child;
|
||||||
if (!child)
|
|
||||||
/* There are no child, nothing to merge. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* we don't merge if there are multiple "important" children.
|
/* we don't merge if there are multiple "important" children.
|
||||||
* non-important ones are at the end of the list.
|
* non-important ones are at the end of the list.
|
||||||
* look at the second child to find out.
|
* look at the second child to find out.
|
||||||
@ -1828,7 +1836,7 @@ merge_useless_child(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
|||||||
/* Misc objects without cpuset may be ignored as well */
|
/* Misc objects without cpuset may be ignored as well */
|
||||||
&& !(child->next_sibling->type == HWLOC_OBJ_MISC && !child->next_sibling->cpuset))
|
&& !(child->next_sibling->type == HWLOC_OBJ_MISC && !child->next_sibling->cpuset))
|
||||||
/* There are several children that prevent from merging */
|
/* There are several children that prevent from merging */
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
/* There is one important child, and some children that may be ignored
|
/* There is one important child, and some children that may be ignored
|
||||||
* during merging because they can be attached to anything with the same locality.
|
* during merging because they can be attached to anything with the same locality.
|
||||||
@ -1886,6 +1894,8 @@ merge_useless_child(hwloc_topology_t topology, hwloc_obj_t *pparent)
|
|||||||
pchild = &((*pchild)->next_sibling);
|
pchild = &((*pchild)->next_sibling);
|
||||||
*pchild = ios;
|
*pchild = ios;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return replaceparent ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user