Hardware Locality (hwloc)  master-20250612.0918.gitdcfc86fb1
Upgrading to the hwloc 3.0 API

The following subsections contain hints to upgrade code from the hwloc 2.x API to the 3.0 API, or to support both APIs simultaneously. They do not document how to migrate from hwloc 1.x to 3.0. It is strongly discouraged to support hwloc APIs from 1.x to 3.0 in the same code. hwloc 2.0 was released more than 6 years ago, its documentation contain a similar page to migrate away from hwloc 1.x API. All users are strong encouraged to stop using hwloc 1.x.

See Compatibility between hwloc versions for detecting the hwloc version that you are compiling and/or running against.

Object types are reordered

Die and MemCache object types are now near their neighbors in the type enum (Die between Package and Core, MemCache after NUMANode). One should use helpers such hwloc_obj_type_is_normal() instead of assumptions about type ordering in the enum.

OS device type is now a bitmask

The OS device "type" attribute is now a bitmask named "types". Instead of a single value, many existing devices now combine two values.

  • "Block" OS devices are now "Storage" (for actual Block devices) and/or "Memory" (for Linux DAX and CXL devices, etc).
  • Some "CoProcessors" are also "GPUs" (e.g. CUDA devices), and some GPUs are also CoProcessors (e.g. RSMI).
  • "OpenFabrics" devices are now also "Network".
  • BXI interfaces are now "Network" instead of "OpenFabrics".

See OS devices for details.

Type hwloc_obj_osdev_type_t is also renamed to hwloc_obj_osdev_types_t. Codes looking OS device types should be updated as follows:

#if HWLOC_API_VERSION >= 0x30000
  if (obj->type == HWLOC_OBJ_OS_DEVICE && (obj->attr->osdev.types & HWLOC_OSDEV_TYPE_GPU))
    /* obj is a 3.x GPU OS device */
#else
  if (obj->type == HWLOC_OBJ_OS_DEVICE && obj->attr->osdev.type == HWLOC_OSDEV_TYPE_GPU)
    /* obj is a 2.x GPU OS device */
#endif

Finding the level depth from a type and some attributes

hwloc_get_type_depth_with_attr() generalizes hwloc_get_type_depth() by using object attributes to disambiguate multiple levels with same type. hwloc_type_sscanf_as_depth() is deprecated in favor of using hwloc_type_sscanf() followed by hwloc_get_type_depth_with_attr():

int my_hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
                                  hwloc_topology_t topology, int *depthp)
{
#if HWLOC_API_VERSION >= 0x30000
  hwloc_obj_type_t type;
  union hwloc_obj_attr_u attr;
  int depth, err;

  err = hwloc_type_sscanf(string, &type, &attr, sizeof(attr));
  if (err < 0)
    return err;
  if (typep)
    *typep = type;
  depth = hwloc_get_type_depth_with_attr(topology, type, &attr, sizeof(attr));
  *depthp = depth;
  return 0;
#else
  return_hwloc_type_sscanf_as_depth(string, typep, topology, depthp);
#endif
}

Info attribute structure

A new structure hwloc_infos_s embeds the pointer and count of struct hwloc_info_s. Former functions such as hwloc_obj_get_info_by_name() still work fine, but any code that manipulates this array and count directly with the 2.x API will fail to build on 3.x.

#if HWLOC_API_VERSION >= 0x30000
  for(i=0; i<obj->infos.count; i++)
    printf("%s = %s\n", obj->infos.array[i].name, obj->infos.array[i].value);
#else
  for(i=0; i<obj->infos_count; i++)
    printf("%s = %s\n", obj->infos[i].name, obj->infos[i].value);
#endif

Functions hwloc_cpukinds_get_info() and hwloc_cpukinds_register() now manipulate infos as such a structure.

Root and topology infos

Info attributes may now be stored directly inside the topology. The array of topology infos may be retrieved with hwloc_topology_get_infos().

Several info attributes previously stored in the root object are now topology attributes (e.g. information about hwloc, about the discovery, operating system information returned by uname). See Custom string infos for details.

Additionally, the "Backend" info attribute of OS devices is now in the topology root object together with other backends instead of in each object.

Distances structure kinds

HWLOC_DISTANCES_KIND_MEANS_LATENCY and HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH are renamed to HWLOC_DISTANCES_KIND_VALUE_LATENCY and HWLOC_DISTANCES_KIND_VALUE_BANDWIDTH.

The XGMIHops distance matrix is now of the new kind HWLOC_DISTANCES_KIND_VALUE_HOPS instead of latency.

XML changes

hwloc 3.x can load XML topology files exported by hwloc 2.x. hwloc 3.x may also export 2.x-compatible topology files (see below).

Moreover hwloc 2.10 is also able to import 3.0 exports. However this convenient transitional feature may break in the future if new features are added in 3.x. Hence developers should not rely on it and rather assume that hwloc 3.x XMLs are not compatible with hwloc 2.x.

Users are advised to negociate hwloc versions between exporter and importer: If the importer isn't 3.x, the exporter should export to 2.x. Otherwise, things should work by default.

Hence hwloc_topology_export_xml() and hwloc_topology_export_xmlbuffer() have a flags argument to force a hwloc-2.x-compatible XML export.

  • If both importer and exporter use hwloc 3.x, do not pass any flag.
  • When the importer uses hwloc 2.x, export with HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V2. Otherwise the importer will fail to import.
  • When the exporter uses hwloc 2.x, a 3.x importer can import without problem.

Here is an example of code for supporting these three cases:

#if HWLOC_API_VERSION >= 0x30000
if (3.x exporter with 2.x importer)
  hwloc_topology_export_xml(...., HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V2);
else /* 3.x exporter with 3.x importer */
  hwloc_topology_export_xml(...., 0);
#else /* 2.x exporter is compatible with both 2.x and 3.x importers */
  hwloc_topology_export_xml(...., 0);
#endif

Note that hwloc v3.x can neither import from nor export to hwloc 1.x.

API Deprecations

API Removals

Functions that were deprecated since 2.0 were removed: