Update hwloc to v1.11.12 97/4897/3
authorEvan Ramos <evan@hpccharm.com>
Fri, 11 Jan 2019 20:18:37 +0000 (14:18 -0600)
committerEvan Ramos <evan@hpccharm.com>
Mon, 14 Jan 2019 05:43:03 +0000 (23:43 -0600)
Change-Id: Ia3acd06a3f740c87a95133c002852c6a8bdc86c3

29 files changed:
contrib/hwloc/NEWS
contrib/hwloc/VERSION
contrib/hwloc/config/hwloc.m4
contrib/hwloc/config/hwloc_components.m4
contrib/hwloc/config/hwloc_internal.m4
contrib/hwloc/configure.ac
contrib/hwloc/contrib/hwloc-valgrind.supp
contrib/hwloc/include/Makefile.am
contrib/hwloc/include/hwloc.h
contrib/hwloc/include/hwloc/autogen/config.h.in
contrib/hwloc/include/hwloc/bitmap.h
contrib/hwloc/include/hwloc/diff.h
contrib/hwloc/include/hwloc/rename.h
contrib/hwloc/include/private/autogen/config.h.in
contrib/hwloc/include/private/internal-components.h [new file with mode: 0644]
contrib/hwloc/include/private/misc.h
contrib/hwloc/src/distances.c
contrib/hwloc/src/misc.c
contrib/hwloc/src/topology-linux.c
contrib/hwloc/src/topology-opencl.c
contrib/hwloc/src/topology-pci.c
contrib/hwloc/src/topology-solaris-chiptype.c
contrib/hwloc/src/topology-synthetic.c
contrib/hwloc/src/topology-x86.c
contrib/hwloc/src/topology-xml-libxml.c
contrib/hwloc/src/topology-xml-nolibxml.c
contrib/hwloc/src/topology-xml.c
contrib/hwloc/src/topology.c
contrib/hwloc/src/traversal.c

index cae5c309c864e2f9d7c7f13cf44cdd616d6bea6d..017ad0c1870e4b8574121914b0945df112e32d4b 100644 (file)
@@ -17,6 +17,24 @@ bug fixes (and other actions) for each version of hwloc since version
 in v0.9.1).
 
 
+Version 1.11.12 (also included in 2.0.3)
+---------------
+* Fix a corner case of hwloc_topology_restrict() where children would
+  become out-of-order.
+* Fix the return length of export_xmlbuffer() functions to always
+  include the ending \0.
+
+
+Version 1.11.11 (also included in 2.0.2)
+---------------
+* Add support for Hygon Dhyana processors in the x86 backend,
+  thanks to Pu Wen for the patch.
+* Fix symbol renaming to also rename internal components,
+  thanks to Evan Ramos for the patch.
+* Fix build on HP-UX, thanks to Richard Lloyd for reporting the issues.
+* Detect PCI link speed without being root on Linux >= 4.13.
+
+
 Version 1.11.10 (also included in 2.0.1)
 ---------------
 * Fix detection of cores and hyperthreads on Mac OS X.
index 06399ad408d586be2bec4558c3078171797cc479..5d211b485a636ea55933ce56bb71542ff2bd7a89 100644 (file)
@@ -9,7 +9,7 @@
 
 major=1
 minor=11
-release=10
+release=12
 
 # greek is used for alpha or beta release tags.  If it is non-empty,
 # it will be appended to the version number.  It does not have to be
@@ -22,7 +22,7 @@ greek=
 
 # The date when this release was created
 
-date="Mar 20, 2018"
+date="Dec 13, 2018"
 
 # If snapshot=1, then use the value from snapshot_version as the
 # entire hwloc version (i.e., ignore major, minor, release, and
@@ -41,6 +41,6 @@ snapshot_version=${major}.${minor}.${release}${greek}-git
 # 2. Version numbers are described in the Libtool current:revision:age
 # format.
 
-libhwloc_so_version=12:7:7
+libhwloc_so_version=12:9:7
 
 # Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj
index b059d96a914455eff00fb207a03dd26e141c0383..c5baa345a40e0358c2d29e6011c68a6458a44995 100644 (file)
@@ -369,6 +369,11 @@ EOF])
     AC_CHECK_HEADERS([strings.h])
     AC_CHECK_HEADERS([ctype.h])
 
+    AC_CHECK_FUNCS([strcasecmp], [
+      _HWLOC_CHECK_DECL([strcasecmp], [
+       AC_DEFINE([HWLOC_HAVE_DECL_STRCASECMP], [1], [Define to 1 if function `strcasecmp' is declared by system headers])
+      ])
+    ])
     AC_CHECK_FUNCS([strncasecmp], [
       _HWLOC_CHECK_DECL([strncasecmp], [
        AC_DEFINE([HWLOC_HAVE_DECL_STRNCASECMP], [1], [Define to 1 if function `strncasecmp' is declared by system headers])
@@ -427,8 +432,15 @@ EOF])
 
     AC_CHECK_DECLS([fabsf], [
       AC_CHECK_LIB([m], [fabsf],
-                   [HWLOC_LIBS="-lm $HWLOC_LIBS"])
+                   [need_libm=yes])
+    ], [], [[#include <math.h>]])
+    AC_CHECK_DECLS([modff], [
+      AC_CHECK_LIB([m], [modff],
+                   [need_libm=yes])
     ], [], [[#include <math.h>]])
+    if test x$need_libm = xyes; then
+      HWLOC_LIBS="-lm $HWLOC_LIBS"
+    fi
 
     AC_CHECK_HEADERS([picl.h], [
       AC_CHECK_LIB([picl], [picl_initialize],
@@ -467,7 +479,6 @@ EOF])
     # Needed for Windows in private/misc.h
     AC_CHECK_TYPES([ssize_t])
     AC_CHECK_DECLS([snprintf], [], [], [AC_INCLUDES_DEFAULT])
-    AC_CHECK_DECLS([strcasecmp], [], [], [AC_INCLUDES_DEFAULT])
     # strdup and putenv are declared in windows headers but marked deprecated
     AC_CHECK_DECLS([_strdup], [], [], [AC_INCLUDES_DEFAULT])
     AC_CHECK_DECLS([_putenv], [], [], [AC_INCLUDES_DEFAULT])
@@ -1325,32 +1336,6 @@ AC_DEFUN([HWLOC_DO_AM_CONDITIONALS],[
 
 #-----------------------------------------------------------------------
 
-AC_DEFUN([_HWLOC_CHECK_DIFF_U], [
-  AC_MSG_CHECKING([whether diff accepts -u])
-  if diff -u /dev/null /dev/null 2> /dev/null
-  then
-    HWLOC_DIFF_U="-u"
-  else
-    HWLOC_DIFF_U=""
-  fi
-  AC_SUBST([HWLOC_DIFF_U])
-  AC_MSG_RESULT([$HWLOC_DIFF_U])
-])
-
-AC_DEFUN([_HWLOC_CHECK_DIFF_W], [
-  AC_MSG_CHECKING([whether diff accepts -w])
-  if diff -w /dev/null /dev/null 2> /dev/null
-  then
-    HWLOC_DIFF_W="-w"
-  else
-    HWLOC_DIFF_W=""
-  fi
-  AC_SUBST([HWLOC_DIFF_W])
-  AC_MSG_RESULT([$HWLOC_DIFF_W])
-])
-
-#-----------------------------------------------------------------------
-
 dnl HWLOC_CHECK_DECL
 dnl
 dnl Check that the declaration of the given function has a complete prototype
index 7d5c1fa194d565d03350e6993211e2557045fc59..620cc4d86e584d03991c9700a190929912220865 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright © 2012 Inria.  All rights reserved.
+# Copyright © 2012-2018 Inria.  All rights reserved.
 # See COPYING in top-level directory.
 
 
@@ -50,10 +50,8 @@ done
 # $2 = list of component names
 #
 AC_DEFUN([HWLOC_LIST_STATIC_COMPONENTS], [
-for comp in [$2]; do
-  echo "HWLOC_DECLSPEC extern const struct hwloc_component hwloc_${comp}_component;" >>[$1]
-done
 cat <<EOF >>[$1]
+#include <private/internal-components.h>
 static const struct hwloc_component * hwloc_static_components[[]] = {
 EOF
 for comp in [$2]; do
index ac669a00348534472d2fcc3f08810fde313770e7..b9441095390ef7e4eb8d1647256f231800c492d6 100644 (file)
@@ -197,7 +197,7 @@ EOF
     AC_MSG_CHECKING([whether to enable "picky" compiler mode])
     hwloc_want_picky=0
     AS_IF([test "$hwloc_c_vendor" = "gnu"],
-          [AS_IF([test -d "$srcdir/.hg" -o -d "$srcdir/.git"],
+          [AS_IF([test -e "$srcdir/.git"],
                  [hwloc_want_picky=1])])
     if test "$enable_picky" = "yes"; then
         if test "$GCC" = "yes"; then
@@ -441,3 +441,31 @@ int foo(void) {
        hwloc_config_prefix[tests/ports/topology-gl.c]:hwloc_config_prefix[src/topology-gl.c])
     ])
 ])dnl
+
+#-----------------------------------------------------------------------
+
+AC_DEFUN([_HWLOC_CHECK_DIFF_U], [
+  AC_MSG_CHECKING([whether diff accepts -u])
+  if diff -u /dev/null /dev/null 2> /dev/null
+  then
+    AC_MSG_RESULT([yes])
+    HWLOC_DIFF_U="-u"
+  else
+    AC_MSG_RESULT([no])
+    HWLOC_DIFF_U=""
+  fi
+  AC_SUBST([HWLOC_DIFF_U])
+])
+
+AC_DEFUN([_HWLOC_CHECK_DIFF_W], [
+  AC_MSG_CHECKING([whether diff accepts -w])
+  if diff -w /dev/null /dev/null 2> /dev/null
+  then
+    AC_MSG_RESULT([yes])
+    HWLOC_DIFF_W="-w"
+  else
+    AC_MSG_RESULT([no])
+    HWLOC_DIFF_W=""
+  fi
+  AC_SUBST([HWLOC_DIFF_W])
+])
index 66ff8eb326e0bf8420cda7d733998acf117eca52..c779865f8f6b26c010c528035c9402fc03f35f16 100644 (file)
@@ -1,7 +1,7 @@
 # -*- shell-script -*-
 #
 # Copyright © 2009      CNRS
-# Copyright © 2009-2015 Inria.  All rights reserved.
+# Copyright © 2009-2018 Inria.  All rights reserved.
 # Copyright © 2009, 2011-2012      Université Bordeaux
 # Copyright © 2009-2014 Cisco Systems, Inc.  All rights reserved.
 #
@@ -193,6 +193,8 @@ fi
 # Show which optional support we'll be building
 hwloc_xml_status=basic
 AS_IF([test "$hwloc_libxml2_happy" = "yes"], [hwloc_xml_status=full])
+hwloc_cairo_status=$hwloc_cairo_happy
+AS_IF([test "$enable_embedded_mode" = "yes"], [hwloc_cairo_status="no (disabled in embedded mode)"])
 
 # Prepare the I/O summary
 hwloc_probeio_list=
@@ -219,7 +221,7 @@ cat <<EOF
 Hwloc optional build support status (more details can be found above):
 
 Probe / display I/O devices:$hwloc_probeio_list
-Graphical output (Cairo):    $hwloc_cairo_happy
+Graphical output (Cairo):    $hwloc_cairo_status
 XML input / output:          $hwloc_xml_status
 EOF
 
index e5c3bf3ce47080ac59a20d26f14497f98e7ab124..b57cdb53bd17f054f53483a0d39978a82db3ab06 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright © 2012      Inria.  All rights reserved.
+# Copyright © 2012-2018 Inria.  All rights reserved.
 # See COPYING in top-level directory.
 
 # suppressions file to be passed to valgrind with
    obj:*libatiadl*
 }
 
-# 
+#  libpciaccess global state leak
 {
    libpciaccess_device_name_leak
    Memcheck:Leak
    ...
    fun:pci_device_get_device_name
-   fun:hwloc_look_libpci
+   fun:hwloc_look_pci*
 }
 {
    libpciaccess_leak
    ...
    obj:*libpciaccess*
    ...
-   fun:hwloc_look_libpci
+   fun:hwloc_look_pci*
+}
+
+# libudev global hashes
+{
+   libudev_hashmap_property
+   Memcheck:Leak
+   fun:malloc
+   ...
+   fun:udev_device_get_property_value
+}
+{
+   libudev_hashmap_sysname
+   Memcheck:Leak
+   fun:malloc
+   ...
+   fun:udev_device_new_from_subsystem_sysname
 }
 
index e74fe442f132cb4ec3be35801dcfb82ff99cf47a..fa363164d7336bec695d9182f5912e460b8bb7e0 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright © 2009-2014 Inria.  All rights reserved.
+# Copyright © 2009-2018 Inria.  All rights reserved.
 # Copyright © 2009-2010 Université Bordeaux
 # Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
 # Copyright © 2011      Oracle and/or its affiliates.  All rights reserved.
@@ -35,6 +35,7 @@ noinst_HEADERS = \
         private/misc.h \
         private/xml.h \
         private/components.h \
+        private/internal-components.h \
         private/cpuid-x86.h
 
 if HWLOC_HAVE_LINUX
index a1443cd028e41c4325bf7aaf8ae1e8a2a71e70e6..f96d6ef126fca42278da405d4686f6979b1cb78c 100644 (file)
@@ -1448,10 +1448,13 @@ HWLOC_DECLSPEC void hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const
 
 /** \defgroup hwlocality_cpubinding CPU binding
  *
- * It is often useful to call hwloc_bitmap_singlify() first so that a single CPU
- * remains in the set. This way, the process will not even migrate between
- * different CPUs inside the given set.
- * Some operating systems also only support that kind of binding.
+ * Some operating systems only support binding threads or processes to a single PU.
+ * Others allow binding to larger sets such as entire Cores or Packages or
+ * even random sets of invididual PUs. In such operating system, the scheduler
+ * is free to run the task on one of these PU, then migrate it to another PU, etc.
+ * It is often useful to call hwloc_bitmap_singlify() on the target CPU set before
+ * passing it to the binding function to avoid these expensive migrations.
+ * See the documentation of hwloc_bitmap_singlify() for details.
  *
  * Some operating systems do not provide all hwloc-supported
  * mechanisms to bind processes, threads, etc.
@@ -2427,6 +2430,9 @@ HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const ch
  *
  * This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().
  *
+ * The returned buffer ends with a \0 that is included in the returned
+ * length.
+ *
  * \return -1 if a failure occured.
  *
  * \note See also hwloc_topology_set_userdata_export_callback()
index e101b0a479b25823c31783b5fd80f272731b2ddd..19c2846c4627e1d10575e98c6737c94f82190558 100644 (file)
 # define __hwloc_attribute_pure
 #endif
 
+#ifndef __hwloc_attribute_deprecated /* allow the user to disable these warnings by defining this macro to nothing */
 #ifdef HWLOC_HAVE_ATTRIBUTE_DEPRECATED
 #define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED 
 #elif defined(__GNUC__)
 #else
 # define __hwloc_attribute_deprecated
 #endif
+#endif
 
 #ifdef HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS
 #define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS
index c57ffdbed580cdf8bca43fd78601c1331b7e28f2..b0f42476823982e8ceaf208d399c4c22b8a4b7a1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009 CNRS
- * Copyright © 2009-2017 Inria.  All rights reserved.
+ * Copyright © 2009-2018 Inria.  All rights reserved.
  * Copyright © 2009-2012 Université Bordeaux
  * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
@@ -24,22 +24,34 @@ extern "C" {
 
 /** \defgroup hwlocality_bitmap The bitmap API
  *
- * The ::hwloc_bitmap_t type represents a set of objects, typically OS
- * processors -- which may actually be hardware threads (represented
- * by ::hwloc_cpuset_t, which is a typedef for ::hwloc_bitmap_t) -- or
- * memory nodes (represented by ::hwloc_nodeset_t, which is also a
- * typedef for ::hwloc_bitmap_t).
- *
- * <em>Both CPU and node sets are always indexed by OS physical number.</em>
- *
- * \note CPU sets and nodesets are described in \ref hwlocality_object_sets.
- *
+ * The ::hwloc_bitmap_t type represents a set of integers (positive or null).
  * A bitmap may be of infinite size (all bits are set after some point).
  * A bitmap may even be full if all bits are set.
  *
+ * Bitmaps are used by hwloc for sets of OS processors
+ * (which may actually be hardware threads) as by ::hwloc_cpuset_t
+ * (a typedef for ::hwloc_bitmap_t), or sets of NUMA memory nodes
+ * as ::hwloc_nodeset_t (also a typedef for ::hwloc_bitmap_t).
+ * Those are used for cpuset and nodeset fields in the ::hwloc_obj structure,
+ * see \ref hwlocality_object_sets.
+ *
+ * <em>Both CPU and node sets are always indexed by OS physical number.</em>
+ * However users should usually not build CPU and node sets manually
+ * (e.g. with hwloc_bitmap_set()).
+ * One should rather use existing object sets and combine them with
+ * hwloc_bitmap_or(), etc.
+ * For instance, binding the current thread on a pair of cores may be performed with:
+ * \code
+ * hwloc_obj_t core1 = ... , core2 = ... ;
+ * hwloc_bitmap_t set = hwloc_bitmap_alloc();
+ * hwloc_bitmap_or(set, core1->cpuset, core2->cpuset);
+ * hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD);
+ * hwloc_bitmap_free(set);
+ * \endcode
+ *
  * \note Several examples of using the bitmap API are available under the
  * doc/examples/ directory in the source tree.
- * Regression tests such as tests/hwloc/hwloc_bitmap*.c also make intensive use
+ * Regression tests such as tests/hwloc_bitmap*.c also make intensive use
  * of this API.
  * @{
  */
@@ -213,6 +225,19 @@ HWLOC_DECLSPEC void hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin
  * May be useful before binding so that the process does not
  * have a chance of migrating between multiple logical CPUs
  * in the original mask.
+ * Instead of running the task on any PU inside the given CPU set,
+ * the operating system scheduler will be forced to run it on a single
+ * of these PUs.
+ * It avoids a migration overhead and cache-line ping-pongs between PUs.
+ *
+ * \note This function is NOT meant to distribute multiple processes
+ * within a single CPU set. It always return the same single bit when
+ * called multiple times on the same input set. hwloc_distrib() may
+ * be used for generating CPU sets to distribute multiple tasks below
+ * a single multi-PU object.
+ *
+ * \note This function cannot be applied to an object set directly. It
+ * should be applied to a copy (which may be obtained with hwloc_bitmap_dup()).
  */
 HWLOC_DECLSPEC void hwloc_bitmap_singlify(hwloc_bitmap_t bitmap);
 
@@ -227,13 +252,21 @@ HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ulong(hwloc_const_bitmap_t bitmap)
 /** \brief Convert the \p i -th subset of bitmap \p bitmap into unsigned long mask */
 HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ith_ulong(hwloc_const_bitmap_t bitmap, unsigned i) __hwloc_attribute_pure;
 
-/** \brief Test whether index \p id is part of bitmap \p bitmap */
+/** \brief Test whether index \p id is part of bitmap \p bitmap.
+ *
+ * \return 1 if the bit at index \p id is set in bitmap \p bitmap, 0 otherwise.
+ */
 HWLOC_DECLSPEC int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id) __hwloc_attribute_pure;
 
-/** \brief Test whether bitmap \p bitmap is empty */
+/** \brief Test whether bitmap \p bitmap is empty
+ *
+ * \return 1 if bitmap is empty, 0 otherwise.
+ */
 HWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
 
 /** \brief Test whether bitmap \p bitmap is completely full
+ *
+ * \return 1 if bitmap is full, 0 otherwise.
  *
  * \note A full bitmap is always infinitely set.
  */
@@ -341,22 +374,42 @@ HWLOC_DECLSPEC void hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t b
  * Comparing bitmaps.
  */
 
-/** \brief Test whether bitmaps \p bitmap1 and \p bitmap2 intersects */
+/** \brief Test whether bitmaps \p bitmap1 and \p bitmap2 intersects.
+ *
+ * \return 1 if bitmaps intersect, 0 otherwise.
+ */
 HWLOC_DECLSPEC int hwloc_bitmap_intersects (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
 
 /** \brief Test whether bitmap \p sub_bitmap is part of bitmap \p super_bitmap.
+ *
+ * \return 1 if \p sub_bitmap is included in \p super_bitmap, 0 otherwise.
  *
  * \note The empty bitmap is considered included in any other bitmap.
  */
 HWLOC_DECLSPEC int hwloc_bitmap_isincluded (hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) __hwloc_attribute_pure;
 
-/** \brief Test whether bitmap \p bitmap1 is equal to bitmap \p bitmap2 */
+/** \brief Test whether bitmap \p bitmap1 is equal to bitmap \p bitmap2.
+ *
+ * \return 1 if bitmaps are equal, 0 otherwise.
+ */
 HWLOC_DECLSPEC int hwloc_bitmap_isequal (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
 
 /** \brief Compare bitmaps \p bitmap1 and \p bitmap2 using their lowest index.
  *
- * Smaller least significant bit is smaller.
- * The empty bitmap is considered higher than anything.
+ * A bitmap is considered smaller if its least significant bit is smaller.
+ * The empty bitmap is considered higher than anything (because its least significant bit does not exist).
+ *
+ * \return -1 if \p bitmap1 is considered smaller than \p bitmap2.
+ * \return 1 if \p bitmap1 is considered larger than \p bitmap2.
+ *
+ * For instance comparing binary bitmaps 0011 and 0110 returns -1
+ * (hence 0011 is considered smaller than 0110)
+ * because least significant bit of 0011 (0001) is smaller than least significant bit of 0110 (0010).
+ * Comparing 01001 and 00110 would also return -1 for the same reason.
+ *
+ * \return 0 if bitmaps are considered equal, even if they are not strictly equal.
+ * They just need to have the same least significant bit.
+ * For instance, comparing binary bitmaps 0010 and 0110 returns 0 because they have the same least significant bit.
  */
 HWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
 
@@ -366,6 +419,14 @@ HWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwlo
  * Compare last indexes first, then second, etc.
  * The empty bitmap is considered lower than anything.
  *
+ * \return -1 if \p bitmap1 is considered smaller than \p bitmap2.
+ * \return 1 if \p bitmap1 is considered larger than \p bitmap2.
+ * \return 0 if bitmaps are equal (contrary to hwloc_bitmap_compare_first()).
+ *
+ * For instance comparing binary bitmaps 0011 and 0110 returns -1
+ * (hence 0011 is considered smaller than 0110).
+ * Comparing 00101 and 01010 returns -1 too.
+ *
  * \note This is different from the non-existing hwloc_bitmap_compare_last()
  * which would only compare the highest index of each bitmap.
  */
index 01e3678083494ef7d420c7915dc915859dcd4d11..8424f5f74b738ad8109fe4237cc728fab037f16e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2013-2016 Inria.  All rights reserved.
+ * Copyright © 2013-2018 Inria.  All rights reserved.
  * See COPYING in top-level directory.
  */
 
@@ -43,6 +43,7 @@ extern "C" {
  * More complex differences such as adding or removing objects cannot
  * be represented in the difference structures and therefore return
  * errors.
+ * Differences between object sets cannot be represented either.
  *
  * It means that there is no need to apply the difference when
  * looking at the tree organization (how many levels, how many
@@ -281,6 +282,9 @@ HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(hwloc_topology_t topology,
  * that contains the reference topology.
  * This attribute is given back when reading the diff from XML.
  *
+ * The returned buffer ends with a \0 that is included in the returned
+ * length.
+ *
  * \note The XML buffer should later be freed with hwloc_free_xmlbuffer().
  *
  * \note The \p topology parameter must be a valid topology
index be9d855f004e6fe2f7ac2ca30e0f85107ef3b98f..f05448f691cd9e1cc9fa7fb95992f61ef05af263 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
- * Copyright © 2010-2017 Inria.  All rights reserved.
+ * Copyright © 2010-2018 Inria.  All rights reserved.
  * See COPYING in top-level directory.
  */
 
@@ -489,31 +489,6 @@ extern "C" {
 #define hwloc_component_type_t HWLOC_NAME(component_type_t)
 #define hwloc_component HWLOC_NAME(component)
 
-#define hwloc_aix_component HWLOC_NAME(aix_component)
-#define hwloc_bgq_component HWLOC_NAME(bgq_component)
-#define hwloc_cuda_component HWLOC_NAME(cuda_component)
-#define hwloc_custom_component HWLOC_NAME(custom_component)
-#define hwloc_darwin_component HWLOC_NAME(darwin_component)
-#define hwloc_fake_component HWLOC_NAME(fake_component)
-#define hwloc_freebsd_component HWLOC_NAME(freebsd_component)
-#define hwloc_gl_component HWLOC_NAME(gl_component)
-#define hwloc_hpux_component HWLOC_NAME(hpux_component)
-#define hwloc_linux_component HWLOC_NAME(linux_component)
-#define hwloc_linuxpci_component HWLOC_NAME(linuxpci_component)
-#define hwloc_netbsd_component HWLOC_NAME(netbsd_component)
-#define hwloc_noos_component HWLOC_NAME(noos_component)
-#define hwloc_nvml_component HWLOC_NAME(nvml_component)
-#define hwloc_opencl_component HWLOC_NAME(opencl_component)
-#define hwloc_osf_component HWLOC_NAME(osf_component)
-#define hwloc_pci_component HWLOC_NAME(pci_component)
-#define hwloc_solaris_component HWLOC_NAME(solaris_component)
-#define hwloc_synthetic_component HWLOC_NAME(synthetic_component)
-#define hwloc_windows_component HWLOC_NAME(windows_component)
-#define hwloc_x86_component HWLOC_NAME(x86_component)
-
-#define hwloc_xml_libxml_component HWLOC_NAME(xml_libxml_component)
-#define hwloc_xml_nolibxml_component HWLOC_NAME(xml_nolibxml_component)
-
 #define hwloc_plugin_check_namespace HWLOC_NAME(plugin_check_namespace)
 
 #define hwloc_insert_object_by_cpuset HWLOC_NAME(insert_object_by_cpuset)
@@ -555,6 +530,8 @@ extern "C" {
 #define hwloc_weight_long HWLOC_NAME(weight_long)
 #define hwloc_strncasecmp HWLOC_NAME(strncasecmp)
 
+#define hwloc_linux_pci_link_speed_from_string HWLOC_NAME(linux_pci_link_speed_from_string)
+
 /* private/cpuid-x86.h */
 
 #define hwloc_have_x86_cpuid HWLOC_NAME(have_x86_cpuid)
@@ -589,6 +566,35 @@ extern "C" {
 #define hwloc_components_init HWLOC_NAME(components_init)
 #define hwloc_components_destroy_all HWLOC_NAME(components_destroy_all)
 
+/* private/internal-private.h */
+
+#define hwloc_xml_component HWLOC_NAME(xml_component)
+#define hwloc_synthetic_component HWLOC_NAME(synthetic_component)
+#define hwloc_custom_component HWLOC_NAME(custom_component)
+
+#define hwloc_aix_component HWLOC_NAME(aix_component)
+#define hwloc_bgq_component HWLOC_NAME(bgq_component)
+#define hwloc_darwin_component HWLOC_NAME(darwin_component)
+#define hwloc_freebsd_component HWLOC_NAME(freebsd_component)
+#define hwloc_hpux_component HWLOC_NAME(hpux_component)
+#define hwloc_linux_component HWLOC_NAME(linux_component)
+#define hwloc_netbsd_component HWLOC_NAME(netbsd_component)
+#define hwloc_noos_component HWLOC_NAME(noos_component)
+#define hwloc_osf_component HWLOC_NAME(osf_component)
+#define hwloc_solaris_component HWLOC_NAME(solaris_component)
+#define hwloc_windows_component HWLOC_NAME(windows_component)
+#define hwloc_x86_component HWLOC_NAME(x86_component)
+
+#define hwloc_cuda_component HWLOC_NAME(cuda_component)
+#define hwloc_gl_component HWLOC_NAME(gl_component)
+#define hwloc_linuxpci_component HWLOC_NAME(linuxpci_component)
+#define hwloc_nvml_component HWLOC_NAME(nvml_component)
+#define hwloc_opencl_component HWLOC_NAME(opencl_component)
+#define hwloc_pci_component HWLOC_NAME(pci_component)
+
+#define hwloc_xml_libxml_component HWLOC_NAME(xml_libxml_component)
+#define hwloc_xml_nolibxml_component HWLOC_NAME(xml_nolibxml_component)
+
 /* private/private.h */
 
 #define hwloc_ignore_type_e HWLOC_NAME(ignore_type_e)
index 5133374c23190be426e46cad9f8cb923974ae59e..5d81c3f36057db5f149f531831097b537fe855e8 100644 (file)
    if you don't. */
 #undef HAVE_DECL_LGRP_LATENCY_COOKIE
 
+/* Define to 1 if you have the declaration of `modff', and to 0 if you don't.
+   */
+#undef HAVE_DECL_MODFF
+
 /* Define to 1 if you have the declaration of
    `nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */
 #undef HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION
    don't. */
 #undef HAVE_DECL_SNPRINTF
 
-/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you
-   don't. */
-#undef HAVE_DECL_STRCASECMP
-
 /* Define to 1 if you have the declaration of `strtoull', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRTOULL
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
 /* Define to 1 if you have the `strftime' function. */
 #undef HAVE_STRFTIME
 
 /* Define to 1 if function `flsl' is declared by system headers */
 #undef HWLOC_HAVE_DECL_FLSL
 
+/* Define to 1 if function `strcasecmp' is declared by system headers */
+#undef HWLOC_HAVE_DECL_STRCASECMP
+
 /* Define to 1 if function `strncasecmp' is declared by system headers */
 #undef HWLOC_HAVE_DECL_STRNCASECMP
 
diff --git a/contrib/hwloc/include/private/internal-components.h b/contrib/hwloc/include/private/internal-components.h
new file mode 100644 (file)
index 0000000..11d9c24
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2018 Inria.  All rights reserved.
+ *
+ * See COPYING in top-level directory.
+ */
+
+/* List of components defined inside hwloc */
+
+#ifndef PRIVATE_INTERNAL_COMPONENTS_H
+#define PRIVATE_INTERNAL_COMPONENTS_H
+
+/* global discovery */
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_synthetic_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_custom_component;
+
+/* CPU discovery */
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_aix_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_bgq_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_darwin_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_freebsd_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_hpux_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_linux_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_netbsd_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_noos_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_osf_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_solaris_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_windows_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
+
+/* I/O discovery */
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_cuda_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_linuxpci_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_nvml_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component;
+
+/* XML backend */
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_nolibxml_component;
+HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_libxml_component;
+
+#endif /* PRIVATE_INTERNAL_COMPONENTS_H */
index 46d32f226d01bc72cc1a0fb6355b89748f51d63b..9210a62a5e785b40b6c05245badc78b5709774c2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009 CNRS
- * Copyright © 2009-2017 Inria.  All rights reserved.
+ * Copyright © 2009-2018 Inria.  All rights reserved.
  * Copyright © 2009-2012 Université Bordeaux
  * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
@@ -379,6 +379,33 @@ static __hwloc_inline int hwloc_strncasecmp(const char *s1, const char *s2, size
 #endif
 }
 
+/* Parse a PCI link speed (GT/s) string from Linux sysfs */
+#ifdef HWLOC_LINUX_SYS
+#include <stdlib.h> /* for atof() */
+static __hwloc_inline float
+hwloc_linux_pci_link_speed_from_string(const char *string)
+{
+  /* don't parse Gen1 with atof() since it expects a localized string
+   * while the kernel sysfs files aren't.
+   */
+  if (!strncmp(string, "2.5 ", 4))
+    /* "2.5 GT/s" is Gen1 with 8/10 encoding */
+    return 2.5 * .8;
+
+  /* also hardwire Gen2 since it also has a specific encoding */
+  if (!strncmp(string, "5 ", 2))
+    /* "5 GT/s" is Gen2 with 8/10 encoding */
+    return 5 * .8;
+
+  /* handle Gen3+ in a generic way */
+  return atof(string) * 128./130; /* Gen3+ encoding is 128/130 */
+}
+#endif
+
+#if !HAVE_DECL_MODFF
+#define modff(x,iptr) (float)modf((double)x,(double *)iptr)
+#endif
+
 #ifdef HWLOC_WIN_SYS
 #  ifndef HAVE_SSIZE_T
 typedef SSIZE_T ssize_t;
@@ -392,7 +419,10 @@ typedef SSIZE_T ssize_t;
 #  ifndef S_ISDIR
 #    define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
 #  endif
-#  if !HAVE_DECL_STRCASECMP
+#  ifndef S_IRWXU
+#    define S_IRWXU 00700
+#  endif
+#  ifndef HWLOC_HAVE_DECL_STRCASECMP
 #    define strcasecmp _stricmp
 #  endif
 #  if !HAVE_DECL_SNPRINTF
index 30fd74dfe17a2d97f4585d2cdba3a111d6d04d8a..443526ba587253929916ed6384eb728ca5478471 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2010-2017 Inria.  All rights reserved.
+ * Copyright © 2010-2018 Inria.  All rights reserved.
  * Copyright © 2011-2012 Université Bordeaux
  * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
@@ -520,17 +520,22 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
       hwloc_bitmap_asprintf(&a, cpuset);
       hwloc_bitmap_asprintf(&b, nodeset);
       fprintf(stderr, "****************************************************************************\n");
-      fprintf(stderr, "* hwloc %s has encountered an error when adding a distance matrix to the topology.\n", HWLOC_VERSION);
+      fprintf(stderr, "* hwloc %s failed to add a distance matrix to the topology.\n", HWLOC_VERSION);
       fprintf(stderr, "*\n");
       fprintf(stderr, "* hwloc_distances__finalize_logical() could not find any object covering\n");
       fprintf(stderr, "* cpuset %s and nodeset %s\n", a, b);
       fprintf(stderr, "*\n");
+      fprintf(stderr, "* Please make sure that distances given through the programming API or\n");
+      fprintf(stderr, "* environment variables do not contradict any other topology information.\n");
+      fprintf(stderr, "*\n");
       fprintf(stderr, "* Please report this error message to the hwloc user's mailing list,\n");
 #ifdef HWLOC_LINUX_SYS
       fprintf(stderr, "* along with the files generated by the hwloc-gather-topology script.\n");
 #else
       fprintf(stderr, "* along with any relevant topology information from your platform.\n");
 #endif
+      fprintf(stderr, "* \n");
+      fprintf(stderr, "* hwloc will now ignore this invalid topology information and continue.\n");
       fprintf(stderr, "****************************************************************************\n");
       free(a);
       free(b);
@@ -683,20 +688,22 @@ hwloc_clear_object_distances(hwloc_obj_t obj)
 
 static void hwloc_report_user_distance_error(const char *msg, int line)
 {
-    static int reported = 0;
-
-    if (!reported && !hwloc_hide_errors()) {
-        fprintf(stderr, "****************************************************************************\n");
-        fprintf(stderr, "* hwloc %s has encountered what looks like an error from user-given distances.\n", HWLOC_VERSION);
-        fprintf(stderr, "*\n");
-        fprintf(stderr, "* %s\n", msg);
-        fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
-        fprintf(stderr, "*\n");
-        fprintf(stderr, "* Please make sure that distances given through the interface or environment\n");
-        fprintf(stderr, "* variables do not contradict any other topology information.\n");
-        fprintf(stderr, "****************************************************************************\n");
-        reported = 1;
-    }
+  static int reported = 0;
+
+  if (!reported && !hwloc_hide_errors()) {
+    fprintf(stderr, "****************************************************************************\n");
+    fprintf(stderr, "* hwloc %s was given invalid distances by the user.\n", HWLOC_VERSION);
+    fprintf(stderr, "*\n");
+    fprintf(stderr, "* %s\n", msg);
+    fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
+    fprintf(stderr, "*\n");
+    fprintf(stderr, "* Please make sure that distances given through the programming API or\n");
+    fprintf(stderr, "* environment variables do not contradict any other topology information.\n");
+    fprintf(stderr, "* \n");
+    fprintf(stderr, "* hwloc will now ignore this invalid topology information and continue.\n");
+    fprintf(stderr, "****************************************************************************\n");
+    reported = 1;
+  }
 }
 
 static int hwloc_compare_distances(float a, float b, float accuracy)
index 3da6687d4e940f5ea75a5d4262228db54fbc76fd..4e9d6055be2048b867d6101f62decdc698883345 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright © 2009 CNRS
  * Copyright © 2009-2014 Inria.  All rights reserved.
  * Copyright © 2009-2010 Université Bordeaux
- * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
+ * Copyright © 2009-2018 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
  */
 
@@ -128,18 +128,18 @@ char *
 hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
 {
 #if HAVE_DECL_GETMODULEFILENAME
-  char name[256], *basename;
+  char name[256], *local_basename;
   unsigned res = GetModuleFileName(NULL, name, sizeof(name));
   if (res == sizeof(name) || !res)
     return NULL;
-  basename = strrchr(name, '\\');
-  if (!basename)
-    basename = name;
+  local_basename = strrchr(name, '\\');
+  if (!local_basename)
+    local_basename = name;
   else
-    basename++;
-  return strdup(basename);
+    local_basename++;
+  return strdup(local_basename);
 #else /* !HAVE_GETMODULEFILENAME */
-  const char *name, *basename;
+  const char *name, *local_basename;
 #if HAVE_DECL_GETPROGNAME
   name = getprogname(); /* FreeBSD, NetBSD, some Solaris */
 #elif HAVE_DECL_GETEXECNAME
@@ -156,11 +156,11 @@ hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
 #endif
   if (!name)
     return NULL;
-  basename = strrchr(name, '/');
-  if (!basename)
-    basename = name;
+  local_basename = strrchr(name, '/');
+  if (!local_basename)
+    local_basename = name;
   else
-    basename++;
-  return strdup(basename);
+    local_basename++;
+  return strdup(local_basename);
 #endif /* !HAVE_GETMODULEFILENAME */
 }
index f7153ba8e21ff87754bd14f8cd870cce6f2945f2..c49a7e2a06cff958e80c9eba988e9832977bd703 100644 (file)
@@ -5803,8 +5803,22 @@ hwloc_look_linuxfs_pci(struct hwloc_backend *backend)
 
       /* try to get the link speed */
       offset = hwloc_pci_find_cap(config_space_cache, HWLOC_PCI_CAP_ID_EXP);
-      if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE)
+      if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE) {
        hwloc_pci_find_linkspeed(config_space_cache, offset, &attr->linkspeed);
+      } else {
+       /* if not available from config-space (extended part is root-only), look in sysfs files added in 4.13 */
+       float speed = 0.f;
+       unsigned width = 0;
+       err = snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/current_link_speed", dirent->d_name);
+       if ((size_t) err < sizeof(path)
+           && !hwloc_read_path_by_length(path, value, sizeof(value), root_fd))
+         speed = hwloc_linux_pci_link_speed_from_string(value);
+       err = snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/current_link_width", dirent->d_name);
+       if ((size_t) err < sizeof(path)
+           && !hwloc_read_path_by_length(path, value, sizeof(value), root_fd))
+         width = atoi(value);
+       attr->linkspeed = speed*width/8;
+      }
      }
     }
 
index ecc9f52129257aa654203ac298c46f856fe315a6..16057b94f52bc5976429def917888de3aa6abfed 100644 (file)
@@ -12,6 +12,7 @@
 #include <private/misc.h>
 #include <private/debug.h>
 
+#define CL_TARGET_OPENCL_VERSION 220
 #ifdef __APPLE__
 #include <OpenCL/cl_ext.h>
 #else
index b64e2d379826c65ff5abbb80f6164ac322d732fd..61622baff4438a339d4afda55f466a345c82d1c2 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright © 2009 CNRS
  * Copyright © 2009-2018 Inria.  All rights reserved.
  * Copyright © 2009-2011, 2013 Université Bordeaux
- * Copyright © 2014 Cisco Systems, Inc.  All rights reserved.
+ * Copyright © 2014-2018 Cisco Systems, Inc.  All rights reserved.
  * Copyright © 2015      Research Organization for Information Science
  *                       and Technology (RIST). All rights reserved.
  * See COPYING in top-level directory.
@@ -181,15 +181,15 @@ hwloc_look_pci(struct hwloc_backend *backend)
       char path[64];
       char value[16];
       FILE *file;
-      size_t read;
+      size_t bytes_read;
 
       snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/vendor",
               domain, pcidev->bus, pcidev->dev, pcidev->func);
       file = fopen(path, "r");
       if (file) {
-       read = fread(value, 1, sizeof(value), file);
+       bytes_read = fread(value, 1, sizeof(value), file);
        fclose(file);
-       if (read)
+       if (bytes_read)
          /* fixup the pciaccess struct so that pci_device_get_vendor_name() is correct later. */
           pcidev->vendor_id = strtoul(value, NULL, 16);
       }
@@ -198,9 +198,9 @@ hwloc_look_pci(struct hwloc_backend *backend)
               domain, pcidev->bus, pcidev->dev, pcidev->func);
       file = fopen(path, "r");
       if (file) {
-       read = fread(value, 1, sizeof(value), file);
+       bytes_read = fread(value, 1, sizeof(value), file);
        fclose(file);
-       if (read)
+       if (bytes_read)
          /* fixup the pciaccess struct so that pci_device_get_device_name() is correct later. */
           pcidev->device_id = strtoul(value, NULL, 16);
       }
@@ -223,8 +223,38 @@ hwloc_look_pci(struct hwloc_backend *backend)
     obj->attr->pcidev.linkspeed = 0; /* unknown */
     offset = hwloc_pci_find_cap(config_space_cache, PCI_CAP_ID_EXP);
 
-    if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE)
+    if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE) {
       hwloc_pci_find_linkspeed(config_space_cache, offset, &obj->attr->pcidev.linkspeed);
+#ifdef HWLOC_LINUX_SYS
+    } else {
+      /* if not available from config-space (extended part is root-only), look in Linux sysfs files added in 4.13 */
+      char path[64];
+      char value[16];
+      FILE *file;
+      size_t bytes_read;
+      float speed = 0.f;
+      unsigned width = 0;
+      snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/current_link_speed",
+              domain, pcidev->bus, pcidev->dev, pcidev->func);
+      file = fopen(path, "r");
+      if (file) {
+       bytes_read = fread(value, 1, sizeof(value), file);
+       fclose(file);
+       if (bytes_read)
+         speed = hwloc_linux_pci_link_speed_from_string(value);
+      }
+      snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/current_link_width",
+              domain, pcidev->bus, pcidev->dev, pcidev->func);
+      file = fopen(path, "r");
+      if (file) {
+       bytes_read = fread(value, 1, sizeof(value), file);
+       fclose(file);
+       if (bytes_read)
+         width = atoi(value);
+      }
+      obj->attr->pcidev.linkspeed = speed*width/8;
+#endif
+    }
 
     if (hwloc_pci_prepare_bridge(obj, config_space_cache) < 0)
       continue;
index 1ab85b523c1d07f31c738e69486e2f45dcc83deb..1b8e8331eaa9972e543656a3720d8a1fd1133ea1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2009-2010 Oracle and/or its affiliates.  All rights reserved.
  * Copyright © 2013 Université Bordeaux.  All rights reserved.
- * Copyright © 2016-2017 Inria.  All rights reserved.
+ * Copyright © 2016-2018 Inria.  All rights reserved.
  *
  * $COPYRIGHT$
  *
@@ -150,8 +150,8 @@ Default values are for Unknown so we can build up from there.
 *****************************************************************************/
 
 static int  called_cpu_probe      = 0;
-static char dss_chip_type[PICL_PROPNAMELEN_MAX];
-static char dss_chip_model[PICL_PROPNAMELEN_MAX];
+static char dss_chip_type[PICL_PROPNAMELEN_MAX+1];
+static char dss_chip_model[PICL_PROPNAMELEN_MAX+1];
 static long dss_chip_mode         = MODE_UNKNOWN;
 
 struct hwloc_solaris_chip_info_s chip_info;
@@ -356,7 +356,7 @@ static int probe_cpu(picl_nodehdl_t node_hdl, void* dummy_arg __hwloc_attribute_
   unsigned int    index;
   int             int_val;
   int             val;
-  char            string_val[PICL_PROPNAMELEN_MAX];
+  char            string_val[PICL_PROPNAMELEN_MAX+1];
 
   val = picl_get_first_prop(node_hdl, &p_hdl);
   while (val == PICL_SUCCESS) {
index aaffe74ce8ca74d42b797bbfa5feb52c31ac4856..ffb2ec6156bb0ac74ee0106f0eed230a5a1a2657 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009 CNRS
- * Copyright © 2009-2017 Inria.  All rights reserved.
+ * Copyright © 2009-2018 Inria.  All rights reserved.
  * Copyright © 2009-2010 Université Bordeaux
  * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
@@ -461,7 +461,6 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data,
       errno = EINVAL;
       goto error;
     }
-    data->level[count-1].arity = (unsigned)item;
 
     totalarity *= item;
     data->level[count].totalwidth = totalarity;
@@ -487,6 +486,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data,
       goto error;
     }
 
+    data->level[count-1].arity = (unsigned)item;
     count++;
   }
 
@@ -610,7 +610,7 @@ hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data,
          curlevel->memorysize = 32*1024;
        else
          /* *4 at each level, starting from 1MB for L2, unified */
-         curlevel->memorysize = 256*1024 << (2*curlevel->depth);
+         curlevel->memorysize = 256ULL*1024 << (2*curlevel->depth);
       }
 
     } else if (type == HWLOC_OBJ_NUMANODE && !curlevel->memorysize) {
@@ -945,8 +945,8 @@ static int hwloc_topology_export_synthetic_indexes(struct hwloc_topology * topol
   /* dump all indexes */
   cur = obj;
   while (cur) {
-    res = snprintf(tmp, tmplen, "%u%s", cur->os_index,
-                  cur->next_cousin ? "," : ")");
+    res = hwloc_snprintf(tmp, tmplen, "%u%s", cur->os_index,
+                        cur->next_cousin ? "," : ")");
     if (res < 0)
       return -1;
     ret += res;
@@ -1004,7 +1004,7 @@ static int hwloc_topology_export_synthetic_obj_attr(struct hwloc_topology * topo
     tmplen -= res;
 
     if (needindexes) {
-      res = snprintf(tmp, tmplen, "%sindexes=", prefix);
+      res = hwloc_snprintf(tmp, tmplen, "%sindexes=", prefix);
       if (res < 0)
        return -1;
       ret += res;
index b93a4125632d5b400b15a1c72e3c69b418ced95f..dc45c10c0aedb7462bf2aca54678ebf0c47a06e0 100644 (file)
@@ -77,6 +77,7 @@ enum cpuid_type {
   intel,
   amd,
   zhaoxin,
+  hygon,
   unknown
 };
 
@@ -171,13 +172,13 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
   _extendedmodel  = (eax>>16) & 0xf;
   _family         = (eax>>8) & 0xf;
   _extendedfamily = (eax>>20) & 0xff;
-  if ((cpuid_type == intel || cpuid_type == amd) && _family == 0xf) {
+  if ((cpuid_type == intel || cpuid_type == amd || cpuid_type == hygon) && _family == 0xf) {
     infos->cpufamilynumber = _family + _extendedfamily;
   } else {
     infos->cpufamilynumber = _family;
   }
   if ((cpuid_type == intel && (_family == 0x6 || _family == 0xf))
-      || (cpuid_type == amd && _family == 0xf)
+      || ((cpuid_type == amd || cpuid_type == hygon) && _family == 0xf)
       || (cpuid_type == zhaoxin && (_family == 0x6 || _family == 0x7))) {
     infos->cpumodelnumber = _model + (_extendedmodel << 4);
   } else {
@@ -262,12 +263,13 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
       node_id = 0;
       nodes_per_proc = 1;
     } else {
+      /* AMD other families or Hygon family 18h */
       node_id = ecx & 0xff;
       nodes_per_proc = ((ecx >> 8) & 7) + 1;
     }
     infos->nodeid = node_id;
     if ((infos->cpufamilynumber == 0x15 && nodes_per_proc > 2)
-       || (infos->cpufamilynumber == 0x17 && nodes_per_proc > 4)) {
+       || ((infos->cpufamilynumber == 0x17 || infos->cpufamilynumber == 0x18) && nodes_per_proc > 4)) {
       hwloc_debug("warning: undefined nodes_per_proc value %u, assuming it means %u\n", nodes_per_proc, nodes_per_proc);
     }
 
@@ -361,7 +363,7 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
   /* Get thread/core + cache information from cpuid 0x04
    * (not supported on AMD)
    */
-  if (cpuid_type != amd && highest_cpuid >= 0x04) {
+  if ((cpuid_type != amd && cpuid_type != hygon) && highest_cpuid >= 0x04) {
     unsigned level;
     struct cacheinfo *tmpcaches;
     unsigned oldnumcaches = infos->numcaches; /* in case we got caches above */
@@ -396,7 +398,9 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
     }
 
     tmpcaches = realloc(infos->cache, infos->numcaches * sizeof(*infos->cache));
-    if (tmpcaches) {
+    if (!tmpcaches) {
+     infos->numcaches = oldnumcaches;
+    } else {
      infos->cache = tmpcaches;
      cache = &infos->cache[oldnumcaches];
 
@@ -538,6 +542,15 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
        cache->cacheid = (infos->apicid % infos->max_log_proc) / cache->nbthreads_sharing /* cacheid within the package */
          + 2 * (infos->apicid / infos->max_log_proc); /* add 2 cache per previous package */
       }
+    } else if (cpuid_type == hygon) {
+      if (infos->cpufamilynumber == 0x18
+         && cache->level == 3 && cache->nbthreads_sharing == 6) {
+        /* Hygon family 0x18 always shares L3 between 8 APIC ids,
+         * even when only 6 APIC ids are enabled and reported in nbthreads_sharing
+         * (on 24-core CPUs).
+         */
+        cache->cacheid = infos->apicid / 8;
+      }
     }
   }
 
@@ -704,11 +717,11 @@ static int summarize(struct hwloc_backend *backend, struct procinfo *infos, int
     }
   }
 
-  /* Look for Compute units inside packages */
   if (fulldiscovery) {
     hwloc_bitmap_t unit_cpuset;
     hwloc_obj_t unit;
 
+    /* Look for Compute units inside packages */
     hwloc_bitmap_copy(remaining_cpuset, complete_cpuset);
     while ((i = hwloc_bitmap_first(remaining_cpuset)) != (unsigned) -1) {
       unsigned packageid = infos[i].packageid;
@@ -738,10 +751,9 @@ static int summarize(struct hwloc_backend *backend, struct procinfo *infos, int
           unitid, unit_cpuset);
       hwloc_insert_object_by_cpuset(topology, unit);
     }
-  }
 
-  /* Look for unknown objects */
-  if (infos[one].otherids) {
+   /* Look for unknown objects */
+   if (infos[one].otherids) {
     for (level = infos[one].levels-1; level <= infos[one].levels-1; level--) {
       if (infos[one].otherids[level] != UINT_MAX) {
        hwloc_bitmap_t unknown_cpuset;
@@ -770,6 +782,7 @@ static int summarize(struct hwloc_backend *backend, struct procinfo *infos, int
        }
       }
     }
+   }
   }
 
   /* Look for cores */
@@ -995,6 +1008,12 @@ static void hwloc_x86_os_state_restore(hwloc_x86_os_state_t *state __hwloc_attri
 #define AMD_EDX ('e' | ('n'<<8) | ('t'<<16) | ('i'<<24))
 #define AMD_ECX ('c' | ('A'<<8) | ('M'<<16) | ('D'<<24))
 
+/* HYGON "HygonGenuine" */
+#define HYGON_EBX ('H' | ('y'<<8) | ('g'<<16) | ('o'<<24))
+#define HYGON_EDX ('n' | ('G'<<8) | ('e'<<16) | ('n'<<24))
+#define HYGON_ECX ('u' | ('i'<<8) | ('n'<<16) | ('e'<<24))
+
+/* (Zhaoxin) CentaurHauls */
 #define ZX_EBX ('C' | ('e'<<8) | ('n'<<16) | ('t'<<24))
 #define ZX_EDX ('a' | ('u'<<8) | ('r'<<16) | ('H'<<24))
 #define ZX_ECX ('a' | ('u'<<8) | ('l'<<16) | ('s'<<24))
@@ -1082,6 +1101,8 @@ int hwloc_look_x86(struct hwloc_backend *backend, int fulldiscovery)
     cpuid_type = zhaoxin;
   if (ebx == SH_EBX && ecx == SH_ECX && edx == SH_EDX)
     cpuid_type = zhaoxin;
+  else if (ebx == HYGON_EBX && ecx == HYGON_ECX && edx == HYGON_EDX)
+    cpuid_type = hygon;
 
   hwloc_debug("highest cpuid %x, cpuid type %u\n", highest_cpuid, cpuid_type);
   if (highest_cpuid < 0x01) {
index 0bfe893a8ec6dd6447162136bb91844647b96b22..48691e5657501d5a8cb1abc62d6676c6dfa69e1e 100644 (file)
@@ -447,6 +447,11 @@ hwloc_libxml_export_buffer(hwloc_topology_t topology, char **xmlbuffer, int *buf
   doc = hwloc__libxml2_prepare_export(topology);
   xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
   xmlFreeDoc(doc);
+  if (!*xmlbuffer) {
+    *buflen = 0;
+    return -1;
+  }
+  *buflen += 1; /* ending \0 was added but not counted in the length */
   return 0;
 }
 
@@ -514,6 +519,11 @@ hwloc_libxml_export_diff_buffer(hwloc_topology_diff_t diff, const char *refname,
   doc = hwloc__libxml2_prepare_export_diff(diff, refname);
   xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
   xmlFreeDoc(doc);
+  if (!*xmlbuffer) {
+    *buflen = 0;
+    return -1;
+  }
+  *buflen += 1; /* ending \0 was added but not counted in the length */
   return 0;
 }
 
index db12c4ca8ed68be46db4ec982833ad649bfb054e..d288198ede52ba2cb63d5ec4374f070dc297d912 100644 (file)
@@ -390,11 +390,12 @@ hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
   bdata->data = nbdata;
 
   if (xmlbuffer) {
-    nbdata->buffer = malloc(xmlbuflen);
+    nbdata->buffer = malloc(xmlbuflen+1);
     if (!nbdata->buffer)
       goto out_with_nbdata;
-    nbdata->buflen = xmlbuflen;
+    nbdata->buflen = xmlbuflen+1;
     memcpy(nbdata->buffer, xmlbuffer, xmlbuflen);
+    nbdata->buffer[xmlbuflen] = '\0';
 
   } else {
     int err = hwloc_nolibxml_read_file(xmlpath, &nbdata->buffer, &nbdata->buflen);
@@ -403,9 +404,10 @@ hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
   }
 
   /* allocate a temporary copy buffer that we may modify during parsing */
-  nbdata->copy = malloc(nbdata->buflen);
+  nbdata->copy = malloc(nbdata->buflen+1);
   if (!nbdata->copy)
     goto out_with_buffer;
+  nbdata->copy[nbdata->buflen] = '\0';
 
   bdata->look_init = hwloc_nolibxml_look_init;
   bdata->look_failed = hwloc_nolibxml_look_failed;
@@ -472,7 +474,7 @@ hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
   ret = hwloc__nolibxml_import_find_child(state, &childstate, &tag);
   if (ret < 0)
     goto out_with_buffer;
-  if (strcmp(tag, "topologydiff"))
+  if (!tag || strcmp(tag, "topologydiff"))
     goto out_with_buffer;
 
   while (1) {
@@ -497,6 +499,7 @@ hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
 
 out_with_buffer:
   free(buffer);
+  free(refname);
 out:
   return -1;
 }
@@ -682,7 +685,7 @@ hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int
   hwloc__xml_export_object (&childstate, topology, hwloc_get_root_obj(topology));
   hwloc__nolibxml_export_end_object(&childstate, "topology");
 
-  return ndata->written+1;
+  return ndata->written+1; /* ending \0 */
 }
 
 static int
index 36f786c8997684223298e4baba06882846c24cc5..566cdcc4a883130c39ad2efa3797095bbb36ea8d 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright © 2009 CNRS
  * Copyright © 2009-2018 Inria.  All rights reserved.
  * Copyright © 2009-2011 Université Bordeaux
- * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
+ * Copyright © 2009-2018 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
  */
 
@@ -578,8 +578,11 @@ hwloc__xml_import_distances(struct hwloc_xml_backend_data_s *data,
        latmax = val;
 
       ret = state->global->close_tag(&childstate);
-      if (ret < 0)
+      if (ret < 0) {
+       free(distances->distances.latency);
+       free(distances);
        return -1;
+      }
 
       state->global->close_child(&childstate);
     }
@@ -1121,18 +1124,18 @@ hwloc_topology_diff_load_xml(hwloc_topology_t topology __hwloc_attribute_unused,
   struct hwloc__xml_import_state_s state;
   struct hwloc_xml_backend_data_s fakedata; /* only for storing global info during parsing */
   hwloc_localeswitch_declare;
-  const char *basename;
+  const char *local_basename;
   int force_nolibxml;
   int ret;
 
   state.global = &fakedata;
 
-  basename = strrchr(xmlpath, '/');
-  if (basename)
-    basename++;
+  local_basename = strrchr(xmlpath, '/');
+  if (local_basename)
+    local_basename++;
   else
-    basename = xmlpath;
-  fakedata.msgprefix = strdup(basename);
+    local_basename = xmlpath;
+  fakedata.msgprefix = strdup(local_basename);
 
   if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
     free(fakedata.msgprefix);
@@ -1769,7 +1772,7 @@ hwloc_xml_component_instantiate(struct hwloc_disc_component *component,
   const char * xmlpath = (const char *) _data1;
   const char * xmlbuffer = (const char *) _data2;
   int xmlbuflen = (int)(uintptr_t) _data3;
-  const char *basename;
+  const char *local_basename;
   int err;
 
   if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
@@ -1798,15 +1801,15 @@ hwloc_xml_component_instantiate(struct hwloc_disc_component *component,
   backend->is_thissystem = 0;
 
   if (xmlpath) {
-    basename = strrchr(xmlpath, '/');
-    if (basename)
-      basename++;
+    local_basename = strrchr(xmlpath, '/');
+    if (local_basename)
+      local_basename++;
     else
-      basename = xmlpath;
+      local_basename = xmlpath;
   } else {
-    basename = "xmlbuffer";
+    local_basename = "xmlbuffer";
   }
-  data->msgprefix = strdup(basename);
+  data->msgprefix = strdup(local_basename);
 
   force_nolibxml = hwloc_nolibxml_import();
 retry:
index 9b83f1943716b003eca5c5871be59d85bab3d3bf..1ee1a2fccc950ec6db4bd0f703ac59a348a66bfa 100644 (file)
@@ -69,26 +69,28 @@ int hwloc_hide_errors(void)
 
 void hwloc_report_os_error(const char *msg, int line)
 {
-    static int reported = 0;
-
-    if (!reported && !hwloc_hide_errors()) {
-        fprintf(stderr, "****************************************************************************\n");
-        fprintf(stderr, "* hwloc %s has encountered what looks like an error from the operating system.\n", HWLOC_VERSION);
-        fprintf(stderr, "*\n");
-        fprintf(stderr, "* %s\n", msg);
-        fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
-        fprintf(stderr, "*\n");
-        fprintf(stderr, "* The following FAQ entry in the hwloc documentation may help:\n");
-        fprintf(stderr, "*   What should I do when hwloc reports \"operating system\" warnings?\n");
-        fprintf(stderr, "* Otherwise please report this error message to the hwloc user's mailing list,\n");
+  static int reported = 0;
+
+  if (!reported && !hwloc_hide_errors()) {
+    fprintf(stderr, "****************************************************************************\n");
+    fprintf(stderr, "* hwloc %s received invalid information from the operating system.\n", HWLOC_VERSION);
+    fprintf(stderr, "*\n");
+    fprintf(stderr, "* %s\n", msg);
+    fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
+    fprintf(stderr, "*\n");
+    fprintf(stderr, "* The following FAQ entry in the hwloc documentation may help:\n");
+    fprintf(stderr, "*   What should I do when hwloc reports \"operating system\" warnings?\n");
+    fprintf(stderr, "* Otherwise please report this error message to the hwloc user's mailing list,\n");
 #ifdef HWLOC_LINUX_SYS
-        fprintf(stderr, "* along with the files generated by the hwloc-gather-topology script.\n");
+    fprintf(stderr, "* along with the files generated by the hwloc-gather-topology script.\n");
 #else
-       fprintf(stderr, "* along with any relevant topology information from your platform.\n");
+    fprintf(stderr, "* along with any relevant topology information from your platform.\n");
 #endif
-        fprintf(stderr, "****************************************************************************\n");
-        reported = 1;
-    }
+    fprintf(stderr, "* \n");
+    fprintf(stderr, "* hwloc will now ignore this invalid topology information and continue.\n");
+    fprintf(stderr, "****************************************************************************\n");
+    reported = 1;
+  }
 }
 
 #if defined(HAVE_SYSCTLBYNAME)
@@ -218,7 +220,7 @@ hwloc_setup_pu_level(struct hwloc_topology *topology,
 static void
 hwloc_debug_print_object(int indent __hwloc_attribute_unused, hwloc_obj_t obj)
 {
-  char type[64], idx[10], attr[1024], *cpuset = NULL;
+  char type[64], idx[12], attr[1024], *cpuset = NULL;
   hwloc_debug("%*s", 2*indent, "");
   hwloc_obj_type_snprintf(type, sizeof(type), obj, 1);
   if (obj->os_index != (unsigned) -1)
@@ -1081,7 +1083,7 @@ hwloc___insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t cur
         if (report_error) {
          char childstr[512];
          char objstr[512];
-         char msg[1024];
+         char msg[1100];
          hwloc__report_error_format_obj(objstr, sizeof(objstr), obj);
          hwloc__report_error_format_obj(childstr, sizeof(childstr), child);
          snprintf(msg, sizeof(msg), "%s intersects with %s without inclusion!", objstr, childstr);
@@ -1261,6 +1263,11 @@ hwloc_topology_insert_misc_object_by_cpuset(struct hwloc_topology *topology, hwl
     obj->allowed_nodeset = hwloc_bitmap_dup(obj->parent->allowed_nodeset);
   }
 
+#ifndef HWLOC_DEBUG
+  if (getenv("HWLOC_DEBUG_CHECK"))
+#endif
+    hwloc_topology_check(topology);
+
   return obj;
 }
 
@@ -1282,6 +1289,11 @@ hwloc_topology_insert_misc_object_by_parent(struct hwloc_topology *topology, hwl
   hwloc_connect_children(topology->levels[0][0]);
   /* no need to hwloc_connect_levels() since misc object are not in levels */
 
+#ifndef HWLOC_DEBUG
+  if (getenv("HWLOC_DEBUG_CHECK"))
+#endif
+    hwloc_topology_check(topology);
+
   return obj;
 }
 
@@ -1804,10 +1816,14 @@ restrict_object(hwloc_topology_t topology, unsigned long flags, hwloc_obj_t *pob
     dropping = droppingparent || (obj->cpuset && hwloc_bitmap_iszero(obj->cpuset));
   }
 
-  if (modified)
+  if (modified) {
     for_each_child_safe(child, obj, pchild)
       restrict_object(topology, flags, pchild, droppedcpuset, droppednodeset, dropping);
 
+    /* if some hwloc_bitmap_first(child->complete_cpuset) changed, children might need to be reordered */
+    reorder_children(obj);
+  }
+
   if (dropping) {
     hwloc_debug("%s", "\nRemoving object during restrict");
     hwloc_debug_print_objects(0, obj);
@@ -3098,6 +3114,12 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_cpuset_t cp
   hwloc_distances_restrict(topology, flags);
   hwloc_distances_finalize_os(topology);
   hwloc_distances_finalize_logical(topology);
+
+#ifndef HWLOC_DEBUG
+  if (getenv("HWLOC_DEBUG_CHECK"))
+#endif
+    hwloc_topology_check(topology);
+
   return 0;
 
  out:
index 6a19cfad5973a03e4cb8ab2080a470da1b76e419..df8c1eafd04e4583036ce3a43d08d2dd642ecdce 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2009 CNRS
- * Copyright © 2009-2017 Inria.  All rights reserved.
+ * Copyright © 2009-2018 Inria.  All rights reserved.
  * Copyright © 2009-2010 Université Bordeaux
  * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.
  * See COPYING in top-level directory.
@@ -501,14 +501,14 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
       return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
   case HWLOC_OBJ_BRIDGE:
     if (verbose)
-      return snprintf(string, size, "Bridge %s->%s",
-                     obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCI" : "Host",
-                     "PCI");
+      return hwloc_snprintf(string, size, "Bridge %s->%s",
+                           obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCI" : "Host",
+                           "PCI");
     else
-      return snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge");
+      return hwloc_snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge");
   case HWLOC_OBJ_PCI_DEVICE:
-    return snprintf(string, size, "PCI %04x:%04x",
-                   obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id);
+    return hwloc_snprintf(string, size, "PCI %04x:%04x",
+                         obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id);
   case HWLOC_OBJ_OS_DEVICE:
     switch (obj->attr->osdev.type) {
     case HWLOC_OBJ_OSDEV_BLOCK: return hwloc_snprintf(string, size, "Block");
@@ -618,9 +618,9 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
       snprintf(down, sizeof(down), "buses=%04x:[%02x-%02x]",
               obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus);
       if (*up)
-       res = snprintf(string, size, "%s%s%s", up, separator, down);
+       res = hwloc_snprintf(string, size, "%s%s%s", up, separator, down);
       else
-       res = snprintf(string, size, "%s", down);
+       res = hwloc_snprintf(string, size, "%s", down);
     }
     break;
   case HWLOC_OBJ_PCI_DEVICE:
@@ -632,9 +632,9 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
       if (!hwloc_obj_get_info_by_name(obj, "lstopoCollapse"))
        snprintf(busid, sizeof(busid), "%04x:%02x:%02x.%01x",
                 obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func);
-      res = snprintf(string, size, "busid=%s%sclass=%04x(%s)%s",
-                    busid, separator,
-                    obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
+      res = hwloc_snprintf(string, size, "busid=%s%sclass=%04x(%s)%s",
+                          busid, separator,
+                          obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
     }
     break;
   default: