2020 * All rights reserved.
2121 * Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
2222 * Copyright (c) 2019 IBM Corporation. All rights reserved.
23+ * Copyright (c) 2019 Inria. All rights reserved.
2324 * $COPYRIGHT$
2425 *
2526 * Additional copyrights may follow
@@ -1240,16 +1241,84 @@ int opal_hwloc_base_cpu_list_parse(const char *slot_str,
12401241 return OPAL_SUCCESS ;
12411242}
12421243
1244+ static void opal_hwloc_base_get_relative_locality_by_depth (hwloc_topology_t topo , unsigned d ,
1245+ hwloc_cpuset_t loc1 , hwloc_cpuset_t loc2 ,
1246+ opal_hwloc_locality_t * locality , bool * shared )
1247+ {
1248+ unsigned width , w ;
1249+ hwloc_obj_t obj ;
1250+ int sect1 , sect2 ;
1251+
1252+ /* get the width of the topology at this depth */
1253+ width = hwloc_get_nbobjs_by_depth (topo , d );
1254+
1255+ /* scan all objects at this depth to see if
1256+ * our locations overlap with them
1257+ */
1258+ for (w = 0 ; w < width ; w ++ ) {
1259+ /* get the object at this depth/index */
1260+ obj = hwloc_get_obj_by_depth (topo , d , w );
1261+ /* see if our locations intersect with the cpuset for this obj */
1262+ sect1 = hwloc_bitmap_intersects (obj -> cpuset , loc1 );
1263+ sect2 = hwloc_bitmap_intersects (obj -> cpuset , loc2 );
1264+ /* if both intersect, then we share this level */
1265+ if (sect1 && sect2 ) {
1266+ * shared = true;
1267+ switch (obj -> type ) {
1268+ case HWLOC_OBJ_NODE :
1269+ * locality |= OPAL_PROC_ON_NUMA ;
1270+ break ;
1271+ case HWLOC_OBJ_SOCKET :
1272+ * locality |= OPAL_PROC_ON_SOCKET ;
1273+ break ;
1274+ #if HWLOC_API_VERSION < 0x20000
1275+ case HWLOC_OBJ_CACHE :
1276+ if (3 == obj -> attr -> cache .depth ) {
1277+ * locality |= OPAL_PROC_ON_L3CACHE ;
1278+ } else if (2 == obj -> attr -> cache .depth ) {
1279+ * locality |= OPAL_PROC_ON_L2CACHE ;
1280+ } else {
1281+ * locality |= OPAL_PROC_ON_L1CACHE ;
1282+ }
1283+ break ;
1284+ #else
1285+ case HWLOC_OBJ_L3CACHE :
1286+ * locality |= OPAL_PROC_ON_L3CACHE ;
1287+ break ;
1288+ case HWLOC_OBJ_L2CACHE :
1289+ * locality |= OPAL_PROC_ON_L2CACHE ;
1290+ break ;
1291+ case HWLOC_OBJ_L1CACHE :
1292+ * locality |= OPAL_PROC_ON_L1CACHE ;
1293+ break ;
1294+ #endif
1295+ case HWLOC_OBJ_CORE :
1296+ * locality |= OPAL_PROC_ON_CORE ;
1297+ break ;
1298+ case HWLOC_OBJ_PU :
1299+ * locality |= OPAL_PROC_ON_HWTHREAD ;
1300+ break ;
1301+ default :
1302+ /* just ignore it */
1303+ break ;
1304+ }
1305+ break ;
1306+ }
1307+ /* otherwise, we don't share this
1308+ * object - but we still might share another object
1309+ * on this level, so we have to keep searching
1310+ */
1311+ }
1312+ }
1313+
12431314opal_hwloc_locality_t opal_hwloc_base_get_relative_locality (hwloc_topology_t topo ,
12441315 char * cpuset1 , char * cpuset2 )
12451316{
12461317 opal_hwloc_locality_t locality ;
1247- hwloc_obj_t obj ;
1248- unsigned depth , d , width , w ;
1318+ hwloc_cpuset_t loc1 , loc2 ;
1319+ unsigned depth , d ;
12491320 bool shared ;
12501321 hwloc_obj_type_t type ;
1251- int sect1 , sect2 ;
1252- hwloc_cpuset_t loc1 , loc2 ;
12531322
12541323 /* start with what we know - they share a node on a cluster
12551324 * NOTE: we may alter that latter part as hwloc's ability to
@@ -1290,66 +1359,8 @@ opal_hwloc_locality_t opal_hwloc_base_get_relative_locality(hwloc_topology_t top
12901359 HWLOC_OBJ_PU != type ) {
12911360 continue ;
12921361 }
1293- /* get the width of the topology at this depth */
1294- width = hwloc_get_nbobjs_by_depth (topo , d );
1362+ opal_hwloc_base_get_relative_locality_by_depth (topo , d , loc1 , loc2 , & locality , & shared );
12951363
1296- /* scan all objects at this depth to see if
1297- * our locations overlap with them
1298- */
1299- for (w = 0 ; w < width ; w ++ ) {
1300- /* get the object at this depth/index */
1301- obj = hwloc_get_obj_by_depth (topo , d , w );
1302- /* see if our locations intersect with the cpuset for this obj */
1303- sect1 = hwloc_bitmap_intersects (obj -> cpuset , loc1 );
1304- sect2 = hwloc_bitmap_intersects (obj -> cpuset , loc2 );
1305- /* if both intersect, then we share this level */
1306- if (sect1 && sect2 ) {
1307- shared = true;
1308- switch (obj -> type ) {
1309- case HWLOC_OBJ_NODE :
1310- locality |= OPAL_PROC_ON_NUMA ;
1311- break ;
1312- case HWLOC_OBJ_SOCKET :
1313- locality |= OPAL_PROC_ON_SOCKET ;
1314- break ;
1315- #if HWLOC_API_VERSION < 0x20000
1316- case HWLOC_OBJ_CACHE :
1317- if (3 == obj -> attr -> cache .depth ) {
1318- locality |= OPAL_PROC_ON_L3CACHE ;
1319- } else if (2 == obj -> attr -> cache .depth ) {
1320- locality |= OPAL_PROC_ON_L2CACHE ;
1321- } else {
1322- locality |= OPAL_PROC_ON_L1CACHE ;
1323- }
1324- break ;
1325- #else
1326- case HWLOC_OBJ_L3CACHE :
1327- locality |= OPAL_PROC_ON_L3CACHE ;
1328- break ;
1329- case HWLOC_OBJ_L2CACHE :
1330- locality |= OPAL_PROC_ON_L2CACHE ;
1331- break ;
1332- case HWLOC_OBJ_L1CACHE :
1333- locality |= OPAL_PROC_ON_L1CACHE ;
1334- break ;
1335- #endif
1336- case HWLOC_OBJ_CORE :
1337- locality |= OPAL_PROC_ON_CORE ;
1338- break ;
1339- case HWLOC_OBJ_PU :
1340- locality |= OPAL_PROC_ON_HWTHREAD ;
1341- break ;
1342- default :
1343- /* just ignore it */
1344- break ;
1345- }
1346- break ;
1347- }
1348- /* otherwise, we don't share this
1349- * object - but we still might share another object
1350- * on this level, so we have to keep searching
1351- */
1352- }
13531364 /* if we spanned the entire width without finding
13541365 * a point of intersection, then no need to go
13551366 * deeper
@@ -1358,6 +1369,9 @@ opal_hwloc_locality_t opal_hwloc_base_get_relative_locality(hwloc_topology_t top
13581369 break ;
13591370 }
13601371 }
1372+ #if HWLOC_API_VERSION >= 0x20000
1373+ opal_hwloc_base_get_relative_locality_by_depth (topo , HWLOC_TYPE_DEPTH_NUMANODE , loc1 , loc2 , & locality , & shared );
1374+ #endif
13611375
13621376 opal_output_verbose (5 , opal_hwloc_base_framework .framework_output ,
13631377 "locality: %s" ,
@@ -2089,12 +2103,40 @@ char* opal_hwloc_base_get_topo_signature(hwloc_topology_t topo)
20892103 return sig ;
20902104}
20912105
2106+ static int opal_hwloc_base_get_locality_string_by_depth (hwloc_topology_t topo ,
2107+ int d ,
2108+ hwloc_cpuset_t cpuset ,
2109+ hwloc_cpuset_t result )
2110+ {
2111+ hwloc_obj_t obj ;
2112+ unsigned width , w ;
2113+
2114+ /* get the width of the topology at this depth */
2115+ width = hwloc_get_nbobjs_by_depth (topo , d );
2116+ if (0 == width ) {
2117+ return -1 ;
2118+ }
2119+
2120+ /* scan all objects at this depth to see if
2121+ * the location overlaps with them
2122+ */
2123+ for (w = 0 ; w < width ; w ++ ) {
2124+ /* get the object at this depth/index */
2125+ obj = hwloc_get_obj_by_depth (topo , d , w );
2126+ /* see if the location intersects with it */
2127+ if (hwloc_bitmap_intersects (obj -> cpuset , cpuset )) {
2128+ hwloc_bitmap_set (result , w );
2129+ }
2130+ }
2131+
2132+ return 0 ;
2133+ }
2134+
20922135char * opal_hwloc_base_get_locality_string (hwloc_topology_t topo ,
20932136 char * bitmap )
20942137{
2095- hwloc_obj_t obj ;
20962138 char * locality = NULL , * tmp , * t2 ;
2097- unsigned depth , d , width , w ;
2139+ unsigned depth , d ;
20982140 hwloc_cpuset_t cpuset , result ;
20992141 hwloc_obj_type_t type ;
21002142
@@ -2137,28 +2179,15 @@ char* opal_hwloc_base_get_locality_string(hwloc_topology_t topo,
21372179 continue ;
21382180 }
21392181
2140- /* get the width of the topology at this depth */
2141- width = hwloc_get_nbobjs_by_depth (topo , d );
2142- if (0 == width ) {
2182+ if (opal_hwloc_base_get_locality_string_by_depth (topo , d , cpuset , result ) < 0 ) {
21432183 continue ;
21442184 }
21452185
2146- /* scan all objects at this depth to see if
2147- * the location overlaps with them
2148- */
2149- for (w = 0 ; w < width ; w ++ ) {
2150- /* get the object at this depth/index */
2151- obj = hwloc_get_obj_by_depth (topo , d , w );
2152- /* see if the location intersects with it */
2153- if (hwloc_bitmap_intersects (obj -> cpuset , cpuset )) {
2154- hwloc_bitmap_set (result , w );
2155- }
2156- }
21572186 /* it should be impossible, but allow for the possibility
21582187 * that we came up empty at this depth */
21592188 if (!hwloc_bitmap_iszero (result )) {
21602189 hwloc_bitmap_list_asprintf (& tmp , result );
2161- switch (obj -> type ) {
2190+ switch (type ) {
21622191 case HWLOC_OBJ_NODE :
21632192 opal_asprintf (& t2 , "%sNM%s:" , (NULL == locality ) ? "" : locality , tmp );
21642193 if (NULL != locality ) {
@@ -2243,6 +2272,24 @@ char* opal_hwloc_base_get_locality_string(hwloc_topology_t topo,
22432272 }
22442273 hwloc_bitmap_zero (result );
22452274 }
2275+
2276+ #if HWLOC_API_VERSION >= 0x20000
2277+ if (opal_hwloc_base_get_locality_string_by_depth (topo , HWLOC_TYPE_DEPTH_NUMANODE , cpuset , result ) == 0 ) {
2278+ /* it should be impossible, but allow for the possibility
2279+ * that we came up empty at this depth */
2280+ if (!hwloc_bitmap_iszero (result )) {
2281+ hwloc_bitmap_list_asprintf (& tmp , result );
2282+ opal_asprintf (& t2 , "%sNM%s:" , (NULL == locality ) ? "" : locality , tmp );
2283+ if (NULL != locality ) {
2284+ free (locality );
2285+ }
2286+ locality = t2 ;
2287+ free (tmp );
2288+ }
2289+ hwloc_bitmap_zero (result );
2290+ }
2291+ #endif
2292+
22462293 hwloc_bitmap_free (result );
22472294 hwloc_bitmap_free (cpuset );
22482295
0 commit comments