@@ -1352,12 +1352,180 @@ void prte_hwloc_get_binding_info(hwloc_const_cpuset_t cpuset,
13521352 }
13531353}
13541354
1355+ static int compare_unsigned (const void * a , const void * b )
1356+ {
1357+ return (* (unsigned * )a - * (unsigned * )b );
1358+ }
1359+
1360+ /* generate a logical string output of a hwloc_cpuset_t */
1361+ static bool build_map (char * answer , size_t size ,
1362+ hwloc_const_cpuset_t bitmap ,
1363+ bool use_hwthread_cpus ,
1364+ bool physical , bool bits_as_cores ,
1365+ hwloc_topology_t topo )
1366+ {
1367+ unsigned indices [2048 ], id ;
1368+ int nsites = 0 , n , start , end , idx ;
1369+ hwloc_obj_t pu ;
1370+ char tmp [128 ], * prefix ;
1371+ bool inrange , first , unique ;
1372+ unsigned val ;
1373+
1374+ if (bits_as_cores || !use_hwthread_cpus ) {
1375+ if (physical ) {
1376+ prefix = "core:P" ;
1377+ } else {
1378+ prefix = "core:L" ;
1379+ }
1380+ } else {
1381+ if (physical ) {
1382+ prefix = "hwt:P" ;
1383+ } else {
1384+ prefix = "hwt:L" ;
1385+ }
1386+ }
1387+
1388+ for (id = hwloc_bitmap_first (bitmap );
1389+ id != (unsigned )-1 ;
1390+ id = hwloc_bitmap_next (bitmap , id )) {
1391+ // id is the physical ID for the given PU
1392+ if (bits_as_cores ) {
1393+ pu = hwloc_get_obj_by_type (topo , HWLOC_OBJ_CORE , id );
1394+ } else if (!use_hwthread_cpus ) {
1395+ // the id's are for threads, but we want cores
1396+ pu = hwloc_get_pu_obj_by_os_index (topo , id );
1397+ // go upward to find the core that contains this pu
1398+ while (NULL != pu && pu -> type != HWLOC_OBJ_CORE ) {
1399+ pu = pu -> parent ;
1400+ }
1401+ if (NULL == pu ) {
1402+ return false;
1403+ }
1404+ } else {
1405+ pu = hwloc_get_pu_obj_by_os_index (topo , id );
1406+ }
1407+ if (NULL == pu ) {
1408+ pmix_show_help ("help-prte-hwloc-base.txt" , "pu-not-found" , true, id );
1409+ return false;
1410+ }
1411+ if (physical ) {
1412+ // record the physical site
1413+ val = pu -> os_index ;
1414+ } else {
1415+ // record the logical site
1416+ val = pu -> logical_index ;
1417+ }
1418+ // add it uniquely to the array of indices - it could be a duplicate
1419+ // if we are looking for cores
1420+ unique = true;
1421+ for (n = 0 ; n < nsites ; n ++ ) {
1422+ if (indices [n ] == val ) {
1423+ unique = false;
1424+ break ;
1425+ }
1426+ }
1427+ if (unique ) {
1428+ indices [nsites ] = val ;
1429+ ++ nsites ;
1430+ if (2048 == nsites ) {
1431+ pmix_show_help ("help-prte-hwloc-base.txt" , "too-many-sites" , true);
1432+ return false;
1433+ }
1434+ }
1435+
1436+ }
1437+
1438+ /* this should never happen as it would mean that the bitmap was
1439+ * empty, which is something we checked before calling this function */
1440+ if (0 == nsites ) {
1441+ return false;
1442+ }
1443+
1444+ if (1 == nsites ) {
1445+ // only bound to one location - most common case
1446+ snprintf (answer , size , "%s%u" , prefix , indices [0 ]);
1447+ return true;
1448+ }
1449+
1450+ // sort them
1451+ qsort (indices , nsites , sizeof (unsigned ), compare_unsigned );
1452+
1453+ // parse through and look for ranges
1454+ start = indices [0 ];
1455+ end = indices [0 ];
1456+ inrange = false;
1457+ first = true;
1458+ // prep the answer
1459+ snprintf (answer , size , "%s" , prefix );
1460+ idx = strlen (prefix );
1461+
1462+ for (n = 1 ; n < nsites ; n ++ ) {
1463+ // see if we are in a range
1464+ if (1 == (indices [n ]- end )) {
1465+ inrange = true;
1466+ end = indices [n ];
1467+ continue ;
1468+ }
1469+ // we are not in a range, or we are
1470+ // at the end of a range
1471+ if (inrange ) {
1472+ // we are at the end of the range
1473+ if (start == end ) {
1474+ if (first ) {
1475+ snprintf (tmp , 128 , "%u" , start );
1476+ first = false;
1477+ } else {
1478+ snprintf (tmp , 128 , ",%u" , start );
1479+ }
1480+ memcpy (& answer [idx ], tmp , strlen (tmp ));
1481+ idx += strlen (tmp );
1482+ } else {
1483+ if (first ) {
1484+ snprintf (tmp , 128 , "%u-%u" , start , end );
1485+ first = false;
1486+ } else {
1487+ snprintf (tmp , 128 , ",%u-%u" , start , end );
1488+ }
1489+ memcpy (& answer [idx ], tmp , strlen (tmp ));
1490+ idx += strlen (tmp );
1491+ }
1492+ // mark the end of the range
1493+ inrange = false;
1494+ start = indices [n ];
1495+ end = indices [n ];
1496+ } else {
1497+ inrange = true;
1498+ end = indices [n ];
1499+ }
1500+ }
1501+ // see if we have a dangling entry
1502+ if (start == end ) {
1503+ if (first ) {
1504+ snprintf (tmp , 128 , "%u" , start );
1505+ } else {
1506+ snprintf (tmp , 128 , ",%u" , start );
1507+ }
1508+ memcpy (& answer [idx ], tmp , strlen (tmp ));
1509+ snprintf (tmp , 128 , "%u" , start );
1510+ } else {
1511+ if (first ) {
1512+ snprintf (tmp , 128 , "%u-%u" , start , end );
1513+ first = false;
1514+ } else {
1515+ snprintf (tmp , 128 , ",%u-%u" , start , end );
1516+ }
1517+ memcpy (& answer [idx ], tmp , strlen (tmp ));
1518+ idx += strlen (tmp );
1519+ }
1520+ return true;
1521+ }
13551522
13561523/*
13571524 * Make a prettyprint string for a hwloc_cpuset_t
13581525 */
13591526char * prte_hwloc_base_cset2str (hwloc_const_cpuset_t cpuset ,
13601527 bool use_hwthread_cpus ,
1528+ bool physical ,
13611529 hwloc_topology_t topo )
13621530{
13631531 int n , npkgs , npus , ncores ;
@@ -1366,6 +1534,7 @@ char *prte_hwloc_base_cset2str(hwloc_const_cpuset_t cpuset,
13661534 char * * output = NULL , * result ;
13671535 hwloc_obj_t pkg ;
13681536 bool bits_as_cores = false;
1537+ bool complete ;
13691538
13701539 /* if the cpuset is all zero, then something is wrong */
13711540 if (hwloc_bitmap_iszero (cpuset )) {
@@ -1403,19 +1572,17 @@ char *prte_hwloc_base_cset2str(hwloc_const_cpuset_t cpuset,
14031572 if (hwloc_bitmap_iszero (avail )) {
14041573 continue ;
14051574 }
1406- if (bits_as_cores ) {
1407- /* can just use the hwloc fn directly */
1408- hwloc_bitmap_list_snprintf (tmp , 2048 , avail );
1409- snprintf (ans , 4096 , "package[%d][core:%s]" , n , tmp );
1410- } else if (use_hwthread_cpus ) {
1411- /* can just use the hwloc fn directly */
1412- hwloc_bitmap_list_snprintf (tmp , 2048 , avail );
1413- snprintf (ans , 4096 , "package[%d][hwt:%s]" , n , tmp );
1575+ // build the map for this cpuset
1576+ complete = build_map (tmp , 2048 , avail , use_hwthread_cpus ,
1577+ physical , bits_as_cores , topo );
1578+ if (complete ) {
1579+ if (physical ) {
1580+ snprintf (ans , 4096 , "package[%d][%s]" , n , tmp );
1581+ } else {
1582+ snprintf (ans , 4096 , "package[%d][%s]" , n , tmp );
1583+ }
14141584 } else {
1415- prte_hwloc_build_map (topo , avail , use_hwthread_cpus | bits_as_cores , coreset );
1416- /* now print out the string */
1417- hwloc_bitmap_list_snprintf (tmp , 2048 , coreset );
1418- snprintf (ans , 4096 , "package[%d][core:%s]" , n , tmp );
1585+ snprintf (ans , 4096 , "package[%d][N/A]" , n );
14191586 }
14201587 PMIX_ARGV_APPEND_NOSIZE_COMPAT (& output , ans );
14211588 }
0 commit comments