1919 * Copyright (C) 2018 Mellanox Technologies, Ltd.
2020 * All rights reserved.
2121 * Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
22- * Copyright (c) 2019 IBM Corporation. All rights reserved.
22+ * Copyright (c) 2019 IBM Corporation. All rights reserved.
23+ * Copyright (c) 2019-2020 Inria. All rights reserved.
24+ * Copyright (c) 2020 Triad National Security, LLC. All rights reserved.
2325 * $COPYRIGHT$
2426 *
2527 * Additional copyrights may follow
5860
5961#include "opal/mca/hwloc/hwloc-internal.h"
6062#include "opal/mca/hwloc/base/base.h"
63+ #include "opal/util/printf.h"
6164
6265static bool topo_in_shmem = false;
6366
@@ -1215,16 +1218,84 @@ int opal_hwloc_base_cpu_list_parse(const char *slot_str,
12151218 return OPAL_SUCCESS ;
12161219}
12171220
1221+ static void opal_hwloc_base_get_relative_locality_by_depth (hwloc_topology_t topo , unsigned d ,
1222+ hwloc_cpuset_t loc1 , hwloc_cpuset_t loc2 ,
1223+ opal_hwloc_locality_t * locality , bool * shared )
1224+ {
1225+ unsigned width , w ;
1226+ hwloc_obj_t obj ;
1227+ int sect1 , sect2 ;
1228+
1229+ /* get the width of the topology at this depth */
1230+ width = hwloc_get_nbobjs_by_depth (topo , d );
1231+
1232+ /* scan all objects at this depth to see if
1233+ * our locations overlap with them
1234+ */
1235+ for (w = 0 ; w < width ; w ++ ) {
1236+ /* get the object at this depth/index */
1237+ obj = hwloc_get_obj_by_depth (topo , d , w );
1238+ /* see if our locations intersect with the cpuset for this obj */
1239+ sect1 = hwloc_bitmap_intersects (obj -> cpuset , loc1 );
1240+ sect2 = hwloc_bitmap_intersects (obj -> cpuset , loc2 );
1241+ /* if both intersect, then we share this level */
1242+ if (sect1 && sect2 ) {
1243+ * shared = true;
1244+ switch (obj -> type ) {
1245+ case HWLOC_OBJ_NODE :
1246+ * locality |= OPAL_PROC_ON_NUMA ;
1247+ break ;
1248+ case HWLOC_OBJ_SOCKET :
1249+ * locality |= OPAL_PROC_ON_SOCKET ;
1250+ break ;
1251+ #if HWLOC_API_VERSION < 0x20000
1252+ case HWLOC_OBJ_CACHE :
1253+ if (3 == obj -> attr -> cache .depth ) {
1254+ * locality |= OPAL_PROC_ON_L3CACHE ;
1255+ } else if (2 == obj -> attr -> cache .depth ) {
1256+ * locality |= OPAL_PROC_ON_L2CACHE ;
1257+ } else {
1258+ * locality |= OPAL_PROC_ON_L1CACHE ;
1259+ }
1260+ break ;
1261+ #else
1262+ case HWLOC_OBJ_L3CACHE :
1263+ * locality |= OPAL_PROC_ON_L3CACHE ;
1264+ break ;
1265+ case HWLOC_OBJ_L2CACHE :
1266+ * locality |= OPAL_PROC_ON_L2CACHE ;
1267+ break ;
1268+ case HWLOC_OBJ_L1CACHE :
1269+ * locality |= OPAL_PROC_ON_L1CACHE ;
1270+ break ;
1271+ #endif
1272+ case HWLOC_OBJ_CORE :
1273+ * locality |= OPAL_PROC_ON_CORE ;
1274+ break ;
1275+ case HWLOC_OBJ_PU :
1276+ * locality |= OPAL_PROC_ON_HWTHREAD ;
1277+ break ;
1278+ default :
1279+ /* just ignore it */
1280+ break ;
1281+ }
1282+ break ;
1283+ }
1284+ /* otherwise, we don't share this
1285+ * object - but we still might share another object
1286+ * on this level, so we have to keep searching
1287+ */
1288+ }
1289+ }
1290+
12181291opal_hwloc_locality_t opal_hwloc_base_get_relative_locality (hwloc_topology_t topo ,
12191292 char * cpuset1 , char * cpuset2 )
12201293{
12211294 opal_hwloc_locality_t locality ;
1222- hwloc_obj_t obj ;
1223- unsigned depth , d , width , w ;
1295+ hwloc_cpuset_t loc1 , loc2 ;
1296+ unsigned depth , d ;
12241297 bool shared ;
12251298 hwloc_obj_type_t type ;
1226- int sect1 , sect2 ;
1227- hwloc_cpuset_t loc1 , loc2 ;
12281299
12291300 /* start with what we know - they share a node on a cluster
12301301 * NOTE: we may alter that latter part as hwloc's ability to
@@ -1265,66 +1336,8 @@ opal_hwloc_locality_t opal_hwloc_base_get_relative_locality(hwloc_topology_t top
12651336 HWLOC_OBJ_PU != type ) {
12661337 continue ;
12671338 }
1268- /* get the width of the topology at this depth */
1269- width = hwloc_get_nbobjs_by_depth (topo , d );
1339+ opal_hwloc_base_get_relative_locality_by_depth (topo , d , loc1 , loc2 , & locality , & shared );
12701340
1271- /* scan all objects at this depth to see if
1272- * our locations overlap with them
1273- */
1274- for (w = 0 ; w < width ; w ++ ) {
1275- /* get the object at this depth/index */
1276- obj = hwloc_get_obj_by_depth (topo , d , w );
1277- /* see if our locations intersect with the cpuset for this obj */
1278- sect1 = hwloc_bitmap_intersects (obj -> cpuset , loc1 );
1279- sect2 = hwloc_bitmap_intersects (obj -> cpuset , loc2 );
1280- /* if both intersect, then we share this level */
1281- if (sect1 && sect2 ) {
1282- shared = true;
1283- switch (obj -> type ) {
1284- case HWLOC_OBJ_NODE :
1285- locality |= OPAL_PROC_ON_NUMA ;
1286- break ;
1287- case HWLOC_OBJ_SOCKET :
1288- locality |= OPAL_PROC_ON_SOCKET ;
1289- break ;
1290- #if HWLOC_API_VERSION < 0x20000
1291- case HWLOC_OBJ_CACHE :
1292- if (3 == obj -> attr -> cache .depth ) {
1293- locality |= OPAL_PROC_ON_L3CACHE ;
1294- } else if (2 == obj -> attr -> cache .depth ) {
1295- locality |= OPAL_PROC_ON_L2CACHE ;
1296- } else {
1297- locality |= OPAL_PROC_ON_L1CACHE ;
1298- }
1299- break ;
1300- #else
1301- case HWLOC_OBJ_L3CACHE :
1302- locality |= OPAL_PROC_ON_L3CACHE ;
1303- break ;
1304- case HWLOC_OBJ_L2CACHE :
1305- locality |= OPAL_PROC_ON_L2CACHE ;
1306- break ;
1307- case HWLOC_OBJ_L1CACHE :
1308- locality |= OPAL_PROC_ON_L1CACHE ;
1309- break ;
1310- #endif
1311- case HWLOC_OBJ_CORE :
1312- locality |= OPAL_PROC_ON_CORE ;
1313- break ;
1314- case HWLOC_OBJ_PU :
1315- locality |= OPAL_PROC_ON_HWTHREAD ;
1316- break ;
1317- default :
1318- /* just ignore it */
1319- break ;
1320- }
1321- break ;
1322- }
1323- /* otherwise, we don't share this
1324- * object - but we still might share another object
1325- * on this level, so we have to keep searching
1326- */
1327- }
13281341 /* if we spanned the entire width without finding
13291342 * a point of intersection, then no need to go
13301343 * deeper
@@ -1333,6 +1346,9 @@ opal_hwloc_locality_t opal_hwloc_base_get_relative_locality(hwloc_topology_t top
13331346 break ;
13341347 }
13351348 }
1349+ #if HWLOC_API_VERSION >= 0x20000
1350+ opal_hwloc_base_get_relative_locality_by_depth (topo , HWLOC_TYPE_DEPTH_NUMANODE , loc1 , loc2 , & locality , & shared );
1351+ #endif
13361352
13371353 opal_output_verbose (5 , opal_hwloc_base_framework .framework_output ,
13381354 "locality: %s" ,
@@ -1349,9 +1365,10 @@ opal_hwloc_locality_t opal_hwloc_base_get_relative_locality(hwloc_topology_t top
13491365 */
13501366char * opal_hwloc_base_find_coprocessors (hwloc_topology_t topo )
13511367{
1368+ #if HAVE_DECL_HWLOC_OBJ_OSDEV_COPROC
13521369 hwloc_obj_t osdev ;
1353- unsigned i ;
13541370 char * * cps = NULL ;
1371+ #endif
13551372 char * cpstring = NULL ;
13561373 int depth ;
13571374
@@ -1369,6 +1386,7 @@ char* opal_hwloc_base_find_coprocessors(hwloc_topology_t topo)
13691386 while (NULL != osdev ) {
13701387 if (HWLOC_OBJ_OSDEV_COPROC == osdev -> attr -> osdev .type ) {
13711388 /* got one! find and save its serial number */
1389+ unsigned i ;
13721390 for (i = 0 ; i < osdev -> infos_count ; i ++ ) {
13731391 if (0 == strncmp (osdev -> infos [i ].name , "MICSerialNumber" , strlen ("MICSerialNumber" ))) {
13741392 OPAL_OUTPUT_VERBOSE ((5 , opal_hwloc_base_framework .framework_output ,
@@ -2063,12 +2081,40 @@ char* opal_hwloc_base_get_topo_signature(hwloc_topology_t topo)
20632081 return sig ;
20642082}
20652083
2084+ static int opal_hwloc_base_get_locality_string_by_depth (hwloc_topology_t topo ,
2085+ int d ,
2086+ hwloc_cpuset_t cpuset ,
2087+ hwloc_cpuset_t result )
2088+ {
2089+ hwloc_obj_t obj ;
2090+ unsigned width , w ;
2091+
2092+ /* get the width of the topology at this depth */
2093+ width = hwloc_get_nbobjs_by_depth (topo , d );
2094+ if (0 == width ) {
2095+ return -1 ;
2096+ }
2097+
2098+ /* scan all objects at this depth to see if
2099+ * the location overlaps with them
2100+ */
2101+ for (w = 0 ; w < width ; w ++ ) {
2102+ /* get the object at this depth/index */
2103+ obj = hwloc_get_obj_by_depth (topo , d , w );
2104+ /* see if the location intersects with it */
2105+ if (hwloc_bitmap_intersects (obj -> cpuset , cpuset )) {
2106+ hwloc_bitmap_set (result , w );
2107+ }
2108+ }
2109+
2110+ return 0 ;
2111+ }
2112+
20662113char * opal_hwloc_base_get_locality_string (hwloc_topology_t topo ,
20672114 char * bitmap )
20682115{
2069- hwloc_obj_t obj ;
20702116 char * locality = NULL , * tmp , * t2 ;
2071- unsigned depth , d , width , w ;
2117+ unsigned depth , d ;
20722118 hwloc_cpuset_t cpuset , result ;
20732119 hwloc_obj_type_t type ;
20742120
@@ -2111,28 +2157,15 @@ char* opal_hwloc_base_get_locality_string(hwloc_topology_t topo,
21112157 continue ;
21122158 }
21132159
2114- /* get the width of the topology at this depth */
2115- width = hwloc_get_nbobjs_by_depth (topo , d );
2116- if (0 == width ) {
2160+ if (opal_hwloc_base_get_locality_string_by_depth (topo , d , cpuset , result ) < 0 ) {
21172161 continue ;
21182162 }
21192163
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- }
21312164 /* it should be impossible, but allow for the possibility
21322165 * that we came up empty at this depth */
21332166 if (!hwloc_bitmap_iszero (result )) {
21342167 hwloc_bitmap_list_asprintf (& tmp , result );
2135- switch (obj -> type ) {
2168+ switch (type ) {
21362169 case HWLOC_OBJ_NODE :
21372170 asprintf (& t2 , "%sNM%s:" , (NULL == locality ) ? "" : locality , tmp );
21382171 if (NULL != locality ) {
@@ -2148,15 +2181,16 @@ char* opal_hwloc_base_get_locality_string(hwloc_topology_t topo,
21482181 locality = t2 ;
21492182 break ;
21502183#if HWLOC_API_VERSION < 0x20000
2151- case HWLOC_OBJ_CACHE :
2152- if (3 == obj -> attr -> cache .depth ) {
2184+ case HWLOC_OBJ_CACHE : {
2185+ unsigned cachedepth = hwloc_get_obj_by_depth (topo , d , 0 )-> attr -> cache .depth ;
2186+ if (3 == cachedepth ) {
21532187 asprintf (& t2 , "%sL3%s:" , (NULL == locality ) ? "" : locality , tmp );
21542188 if (NULL != locality ) {
21552189 free (locality );
21562190 }
21572191 locality = t2 ;
21582192 break ;
2159- } else if (2 == obj -> attr -> cache . depth ) {
2193+ } else if (2 == cachedepth ) {
21602194 asprintf (& t2 , "%sL2%s:" , (NULL == locality ) ? "" : locality , tmp );
21612195 if (NULL != locality ) {
21622196 free (locality );
@@ -2172,6 +2206,7 @@ char* opal_hwloc_base_get_locality_string(hwloc_topology_t topo,
21722206 break ;
21732207 }
21742208 break ;
2209+ }
21752210#else
21762211 case HWLOC_OBJ_L3CACHE :
21772212 asprintf (& t2 , "%sL3%s:" , (NULL == locality ) ? "" : locality , tmp );
@@ -2217,6 +2252,24 @@ char* opal_hwloc_base_get_locality_string(hwloc_topology_t topo,
22172252 }
22182253 hwloc_bitmap_zero (result );
22192254 }
2255+
2256+ #if HWLOC_API_VERSION >= 0x20000
2257+ if (opal_hwloc_base_get_locality_string_by_depth (topo , HWLOC_TYPE_DEPTH_NUMANODE , cpuset , result ) == 0 ) {
2258+ /* it should be impossible, but allow for the possibility
2259+ * that we came up empty at this depth */
2260+ if (!hwloc_bitmap_iszero (result )) {
2261+ hwloc_bitmap_list_asprintf (& tmp , result );
2262+ asprintf (& t2 , "%sNM%s:" , (NULL == locality ) ? "" : locality , tmp );
2263+ if (NULL != locality ) {
2264+ free (locality );
2265+ }
2266+ locality = t2 ;
2267+ free (tmp );
2268+ }
2269+ hwloc_bitmap_zero (result );
2270+ }
2271+ #endif
2272+
22202273 hwloc_bitmap_free (result );
22212274 hwloc_bitmap_free (cpuset );
22222275
0 commit comments