REDACTED-rig/src/3rdparty/hwloc/include/hwloc.h
2024-10-21 08:31:52 +07:00

2872 lines
120 KiB
C

/*
* Copyright © 2009 CNRS
* Copyright © 2009-2024 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/*=====================================================================
* PLEASE GO READ THE DOCUMENTATION!
* ------------------------------------------------
* $tarball_directory/doc/doxygen-doc/
* or
* https://www.open-mpi.org/projects/hwloc/doc/
*=====================================================================
*
* FAIR WARNING: Do NOT expect to be able to figure out all the
* subtleties of hwloc by simply reading function prototypes and
* constant descrptions here in this file.
*
* Hwloc has wonderful documentation in both PDF and HTML formats for
* your reading pleasure. The formal documentation explains a LOT of
* hwloc-specific concepts, provides definitions, and discusses the
* "big picture" for many of the things that you'll find here in this
* header file.
*
* The PDF/HTML documentation was generated via Doxygen; much of what
* you'll see in there is also here in this file. BUT THERE IS A LOT
* THAT IS IN THE PDF/HTML THAT IS ***NOT*** IN hwloc.h!
*
* There are entire paragraph-length descriptions, discussions, and
* pretty pictures to explain subtle corner cases, provide concrete
* examples, etc.
*
* Please, go read the documentation. :-)
*
* Moreover there are several examples of hwloc use under doc/examples
* in the source tree.
*
*=====================================================================*/
/** \file
* \brief The hwloc API.
*
* See hwloc/bitmap.h for bitmap specific macros.
* See hwloc/helper.h for high-level topology traversal helpers.
* See hwloc/inlines.h for the actual inline code of some functions below.
* See hwloc/export.h for exporting topologies to XML or to synthetic descriptions.
* See hwloc/distances.h for querying and modifying distances between objects.
* See hwloc/diff.h for manipulating differences between similar topologies.
*/
#ifndef HWLOC_H
#define HWLOC_H
#include "hwloc/autogen/config.h"
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
/*
* Symbol transforms
*/
#include "hwloc/rename.h"
/*
* Bitmap definitions
*/
#include "hwloc/bitmap.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_api_error_reporting Error reporting in the API
* @{
* Most functions in the hwloc API return an integer value.
* Unless documentated differently, they return 0 on success
* and -1 on error.
* Functions that return a pointer type return \c NULL on error.
*
* \p errno will be set to a meaningful value whenever possible.
* This includes the usual \c EINVAL when invalid function parameters are passed
* or \c ENOMEM when an internal allocation fails.
* Some specific \c errno value are also used, for instance for binding
* errors as documented in \ref hwlocality_cpubinding.
*
* Some modules describe return values of their functions
* in their introduction, for instance in \ref hwlocality_bitmap.
* @}
*/
/** \defgroup hwlocality_api_version API version
* @{
*/
/** \brief Indicate at build time which hwloc API version is being used.
*
* This number is updated to (X<<16)+(Y<<8)+Z when a new release X.Y.Z
* actually modifies the API.
*
* Users may check for available features at build time using this number
* (see \ref faq_version_api).
*
* \note This should not be confused with HWLOC_VERSION, the library version.
* Two stable releases of the same series usually have the same ::HWLOC_API_VERSION
* even if their HWLOC_VERSION are different.
*/
#define HWLOC_API_VERSION 0x00020b00
/** \brief Indicate at runtime which hwloc API version was used at build time.
*
* Should be ::HWLOC_API_VERSION if running on the same version.
*
* \return the build-time version number.
*/
HWLOC_DECLSPEC unsigned hwloc_get_api_version(void);
/** \brief Current component and plugin ABI version (see hwloc/plugins.h) */
#define HWLOC_COMPONENT_ABI 7
/** @} */
/** \defgroup hwlocality_object_sets Object Sets (hwloc_cpuset_t and hwloc_nodeset_t)
*
* Hwloc uses bitmaps to represent two distinct kinds of object sets:
* CPU sets (::hwloc_cpuset_t) and NUMA node sets (::hwloc_nodeset_t).
* These types are both typedefs to a common back end type
* (::hwloc_bitmap_t), and therefore all the hwloc bitmap functions
* are applicable to both ::hwloc_cpuset_t and ::hwloc_nodeset_t (see
* \ref hwlocality_bitmap).
*
* The rationale for having two different types is that even though
* the actions one wants to perform on these types are the same (e.g.,
* enable and disable individual items in the set/mask), they're used
* in very different contexts: one for specifying which processors to
* use and one for specifying which NUMA nodes to use. Hence, the
* name difference is really just to reflect the intent of where the
* type is used.
*
* @{
*/
/** \brief A CPU set is a bitmap whose bits are set according to CPU
* physical OS indexes.
*
* It may be consulted and modified with the bitmap API as any
* ::hwloc_bitmap_t (see hwloc/bitmap.h).
*
* Each bit may be converted into a PU object using
* hwloc_get_pu_obj_by_os_index().
*/
typedef hwloc_bitmap_t hwloc_cpuset_t;
/** \brief A non-modifiable ::hwloc_cpuset_t. */
typedef hwloc_const_bitmap_t hwloc_const_cpuset_t;
/** \brief A node set is a bitmap whose bits are set according to NUMA
* memory node physical OS indexes.
*
* It may be consulted and modified with the bitmap API as any
* ::hwloc_bitmap_t (see hwloc/bitmap.h).
* Each bit may be converted into a NUMA node object using
* hwloc_get_numanode_obj_by_os_index().
*
* When binding memory on a system without any NUMA node,
* the single main memory bank is considered as NUMA node #0.
*
* See also \ref hwlocality_helper_nodeset_convert.
*/
typedef hwloc_bitmap_t hwloc_nodeset_t;
/** \brief A non-modifiable ::hwloc_nodeset_t.
*/
typedef hwloc_const_bitmap_t hwloc_const_nodeset_t;
/** @} */
/** \defgroup hwlocality_object_types Object Types
* @{
*/
/** \brief Type of topology object.
*
* \note Do not rely on the ordering or completeness of the values as new ones
* may be defined in the future! If you need to compare types, use
* hwloc_compare_types() instead.
*/
typedef enum {
/** \cond */
#define HWLOC_OBJ_TYPE_MIN HWLOC_OBJ_MACHINE /* Sentinel value */
/** \endcond */
HWLOC_OBJ_MACHINE, /**< \brief Machine.
* A set of processors and memory with cache
* coherency.
*
* This type is always used for the root object of a topology,
* and never used anywhere else.
* Hence its parent is always \c NULL.
*/
HWLOC_OBJ_PACKAGE, /**< \brief Physical package.
* The physical package that usually gets inserted
* into a socket on the motherboard.
* A processor package usually contains multiple cores,
* and possibly some dies.
*/
HWLOC_OBJ_CORE, /**< \brief Core.
* A computation unit (may be shared by several
* PUs, aka logical processors).
*/
HWLOC_OBJ_PU, /**< \brief Processing Unit, or (Logical) Processor.
* An execution unit (may share a core with some
* other logical processors, e.g. in the case of
* an SMT core).
*
* This is the smallest object representing CPU resources,
* it cannot have any child except Misc objects.
*
* Objects of this kind are always reported and can
* thus be used as fallback when others are not.
*/
HWLOC_OBJ_L1CACHE, /**< \brief Level 1 Data (or Unified) Cache. */
HWLOC_OBJ_L2CACHE, /**< \brief Level 2 Data (or Unified) Cache. */
HWLOC_OBJ_L3CACHE, /**< \brief Level 3 Data (or Unified) Cache. */
HWLOC_OBJ_L4CACHE, /**< \brief Level 4 Data (or Unified) Cache. */
HWLOC_OBJ_L5CACHE, /**< \brief Level 5 Data (or Unified) Cache. */
HWLOC_OBJ_L1ICACHE, /**< \brief Level 1 instruction Cache (filtered out by default). */
HWLOC_OBJ_L2ICACHE, /**< \brief Level 2 instruction Cache (filtered out by default). */
HWLOC_OBJ_L3ICACHE, /**< \brief Level 3 instruction Cache (filtered out by default). */
HWLOC_OBJ_GROUP, /**< \brief Group objects.
* Objects which do not fit in the above but are
* detected by hwloc and are useful to take into
* account for affinity. For instance, some operating systems
* expose their arbitrary processors aggregation this
* way. And hwloc may insert such objects to group
* NUMA nodes according to their distances.
* See also \ref faq_groups.
*
* These objects are removed when they do not bring
* any structure (see ::HWLOC_TYPE_FILTER_KEEP_STRUCTURE).
*/
HWLOC_OBJ_NUMANODE, /**< \brief NUMA node.
* An object that contains memory that is directly
* and byte-accessible to the host processors.
* It is usually close to some cores (the corresponding objects
* are descendants of the NUMA node object in the hwloc tree).
*
* This is the smallest object representing Memory resources,
* it cannot have any child except Misc objects.
* However it may have Memory-side cache parents.
*
* NUMA nodes may correspond to different kinds of memory
* (DRAM, HBM, CXL-DRAM, etc.). When hwloc is able to guess
* that kind, it is specified in the subtype field of the object.
* See also \ref attributes_normal in the main documentation.
*
* There is always at least one such object in the topology
* even if the machine is not NUMA.
*
* Memory objects are not listed in the main children list,
* but rather in the dedicated Memory children list.
*
* NUMA nodes have a special depth ::HWLOC_TYPE_DEPTH_NUMANODE
* instead of a normal depth just like other objects in the
* main tree.
*/
HWLOC_OBJ_BRIDGE, /**< \brief Bridge (filtered out by default).
* Any bridge (or PCI switch) that connects the host or an I/O bus,
* to another I/O bus.
*
* Bridges are not added to the topology unless their
* filtering is changed (see hwloc_topology_set_type_filter()
* and hwloc_topology_set_io_types_filter()).
*
* I/O objects are not listed in the main children list,
* but rather in the dedicated io children list.
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_PCI_DEVICE, /**< \brief PCI device (filtered out by default).
*
* PCI devices are not added to the topology unless their
* filtering is changed (see hwloc_topology_set_type_filter()
* and hwloc_topology_set_io_types_filter()).
*
* I/O objects are not listed in the main children list,
* but rather in the dedicated io children list.
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_OS_DEVICE, /**< \brief Operating system device (filtered out by default).
*
* OS devices are not added to the topology unless their
* filtering is changed (see hwloc_topology_set_type_filter()
* and hwloc_topology_set_io_types_filter()).
*
* I/O objects are not listed in the main children list,
* but rather in the dedicated io children list.
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_MISC, /**< \brief Miscellaneous objects (filtered out by default).
* Objects without particular meaning, that can e.g. be
* added by the application for its own use, or by hwloc
* for miscellaneous objects such as MemoryModule (DIMMs).
*
* They are not added to the topology unless their filtering
* is changed (see hwloc_topology_set_type_filter()).
*
* These objects are not listed in the main children list,
* but rather in the dedicated misc children list.
* Misc objects may only have Misc objects as children,
* and those are in the dedicated misc children list as well.
* Misc objects have NULL CPU and node sets.
*/
HWLOC_OBJ_MEMCACHE, /**< \brief Memory-side cache (filtered out by default).
* A cache in front of a specific NUMA node.
*
* This object always has at least one NUMA node as a memory child.
*
* Memory objects are not listed in the main children list,
* but rather in the dedicated Memory children list.
*
* Memory-side cache have a special depth ::HWLOC_TYPE_DEPTH_MEMCACHE
* instead of a normal depth just like other objects in the
* main tree.
*/
HWLOC_OBJ_DIE, /**< \brief Die within a physical package.
* A subpart of the physical package, that contains multiple cores.
*
* Some operating systems (e.g. Linux) may expose a single die per package
* even if the hardware does not support dies at all. To avoid showing
* such non-existing dies, the corresponding hwloc backend may filter them out.
* This is functionally equivalent to ::HWLOC_TYPE_FILTER_KEEP_STRUCTURE
* being enforced.
*/
HWLOC_OBJ_TYPE_MAX /**< \private Sentinel value */
} hwloc_obj_type_t;
/** \brief Cache type. */
typedef enum hwloc_obj_cache_type_e {
HWLOC_OBJ_CACHE_UNIFIED, /**< \brief Unified cache. */
HWLOC_OBJ_CACHE_DATA, /**< \brief Data cache. */
HWLOC_OBJ_CACHE_INSTRUCTION /**< \brief Instruction cache (filtered out by default). */
} hwloc_obj_cache_type_t;
/** \brief Type of one side (upstream or downstream) of an I/O bridge. */
typedef enum hwloc_obj_bridge_type_e {
HWLOC_OBJ_BRIDGE_HOST, /**< \brief Host-side of a bridge, only possible upstream. */
HWLOC_OBJ_BRIDGE_PCI /**< \brief PCI-side of a bridge. */
} hwloc_obj_bridge_type_t;
/** \brief Type of a OS device. */
typedef enum hwloc_obj_osdev_type_e {
HWLOC_OBJ_OSDEV_BLOCK, /**< \brief Operating system block device, or non-volatile memory device.
* For instance "sda" or "dax2.0" on Linux. */
HWLOC_OBJ_OSDEV_GPU, /**< \brief Operating system GPU device.
* For instance ":0.0" for a GL display,
* "card0" for a Linux DRM device. */
HWLOC_OBJ_OSDEV_NETWORK, /**< \brief Operating system network device.
* For instance the "eth0" interface on Linux. */
HWLOC_OBJ_OSDEV_OPENFABRICS, /**< \brief Operating system openfabrics device.
* For instance the "mlx4_0" InfiniBand HCA,
* "hfi1_0" Omni-Path interface,
* or "bxi0" Atos/Bull BXI HCA on Linux. */
HWLOC_OBJ_OSDEV_DMA, /**< \brief Operating system dma engine device.
* For instance the "dma0chan0" DMA channel on Linux. */
HWLOC_OBJ_OSDEV_COPROC /**< \brief Operating system co-processor device.
* For instance "opencl0d0" for a OpenCL device,
* "cuda0" for a CUDA device. */
} hwloc_obj_osdev_type_t;
/** \brief Compare the depth of two object types
*
* Types shouldn't be compared as they are, since newer ones may be added in
* the future.
*
* \return A negative integer if \p type1 objects usually include \p type2 objects.
* \return A positive integer if \p type1 objects are usually included in \p type2 objects.
* \return 0 if \p type1 and \p type2 objects are the same.
* \return ::HWLOC_TYPE_UNORDERED if objects cannot be compared
* (because neither is usually contained in the other).
*
* \note Object types containing CPUs can always be compared
* (usually, a machine contains packages, which contain caches,
* which contain cores, which contain PUs).
*
* \note ::HWLOC_OBJ_PU will always be the deepest,
* while ::HWLOC_OBJ_MACHINE is always the highest.
*
* \note This does not mean that the actual topology will respect that order:
* e.g. as of today cores may also contain caches, and packages may also contain
* nodes. This is thus just to be seen as a fallback comparison method.
*/
HWLOC_DECLSPEC int hwloc_compare_types (hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const;
/** \brief Value returned by hwloc_compare_types() when types can not be compared. \hideinitializer */
#define HWLOC_TYPE_UNORDERED INT_MAX
/** @} */
/** \defgroup hwlocality_objects Object Structure and Attributes
* @{
*/
union hwloc_obj_attr_u;
/** \brief Structure of a topology object
*
* Applications must not modify any field except \p hwloc_obj.userdata.
*/
struct hwloc_obj {
/* physical information */
hwloc_obj_type_t type; /**< \brief Type of object */
char *subtype; /**< \brief Subtype string to better describe the type field. */
unsigned os_index; /**< \brief OS-provided physical index number.
* It is not guaranteed unique across the entire machine,
* except for PUs and NUMA nodes.
* Set to HWLOC_UNKNOWN_INDEX if unknown or irrelevant for this object.
*/
#define HWLOC_UNKNOWN_INDEX (unsigned)-1
char *name; /**< \brief Object-specific name if any.
* Mostly used for identifying OS devices and Misc objects where
* a name string is more useful than numerical indexes.
*/
hwloc_uint64_t total_memory; /**< \brief Total memory (in bytes) in NUMA nodes below this object. */
union hwloc_obj_attr_u *attr; /**< \brief Object type-specific Attributes,
* may be \c NULL if no attribute value was found */
/* global position */
int depth; /**< \brief Vertical index in the hierarchy.
*
* For normal objects, this is the depth of the horizontal level
* that contains this object and its cousins of the same type.
* If the topology is symmetric, this is equal to the parent depth
* plus one, and also equal to the number of parent/child links
* from the root object to here.
*
* For special objects (NUMA nodes, I/O and Misc) that are not
* in the main tree, this is a special negative value that
* corresponds to their dedicated level,
* see hwloc_get_type_depth() and ::hwloc_get_type_depth_e.
* Those special values can be passed to hwloc functions such
* hwloc_get_nbobjs_by_depth() as usual.
*/
unsigned logical_index; /**< \brief Horizontal index in the whole list of similar objects,
* hence guaranteed unique across the entire machine.
* Could be a "cousin_rank" since it's the rank within the "cousin" list below
* Note that this index may change when restricting the topology
* or when inserting a group.
*/
/* cousins are all objects of the same type (and depth) across the entire topology */
struct hwloc_obj *next_cousin; /**< \brief Next object of same type and depth */
struct hwloc_obj *prev_cousin; /**< \brief Previous object of same type and depth */
/* children of the same parent are siblings, even if they may have different type and depth */
struct hwloc_obj *parent; /**< \brief Parent, \c NULL if root (Machine object) */
unsigned sibling_rank; /**< \brief Index in parent's \c children[] array. Or the index in parent's Memory, I/O or Misc children list. */
struct hwloc_obj *next_sibling; /**< \brief Next object below the same parent (inside the same list of children). */
struct hwloc_obj *prev_sibling; /**< \brief Previous object below the same parent (inside the same list of children). */
/** @name List and array of normal children below this object (except Memory, I/O and Misc children). */
/**@{*/
unsigned arity; /**< \brief Number of normal children.
* Memory, Misc and I/O children are not listed here
* but rather in their dedicated children list.
*/
struct hwloc_obj **children; /**< \brief Normal children, \c children[0 .. arity -1] */
struct hwloc_obj *first_child; /**< \brief First normal child */
struct hwloc_obj *last_child; /**< \brief Last normal child */
/**@}*/
int symmetric_subtree; /**< \brief Set if the subtree of normal objects below this object is symmetric,
* which means all normal children and their children have identical subtrees.
*
* Memory, I/O and Misc children are ignored.
*
* If set in the topology root object, lstopo may export the topology
* as a synthetic string.
*/
/** @name List of Memory children below this object. */
/**@{*/
unsigned memory_arity; /**< \brief Number of Memory children.
* These children are listed in \p memory_first_child.
*/
struct hwloc_obj *memory_first_child; /**< \brief First Memory child.
* NUMA nodes and Memory-side caches are listed here
* (\p memory_arity and \p memory_first_child)
* instead of in the normal children list.
* See also hwloc_obj_type_is_memory().
*
* A memory hierarchy starts from a normal CPU-side object
* (e.g. Package) and ends with NUMA nodes as leaves.
* There might exist some memory-side caches between them
* in the middle of the memory subtree.
*/
/**@}*/
/** @name List of I/O children below this object. */
/**@{*/
unsigned io_arity; /**< \brief Number of I/O children.
* These children are listed in \p io_first_child.
*/
struct hwloc_obj *io_first_child; /**< \brief First I/O child.
* Bridges, PCI and OS devices are listed here (\p io_arity and \p io_first_child)
* instead of in the normal children list.
* See also hwloc_obj_type_is_io().
*/
/**@}*/
/** @name List of Misc children below this object. */
/**@{*/
unsigned misc_arity; /**< \brief Number of Misc children.
* These children are listed in \p misc_first_child.
*/
struct hwloc_obj *misc_first_child; /**< \brief First Misc child.
* Misc objects are listed here (\p misc_arity and \p misc_first_child)
* instead of in the normal children list.
*/
/**@}*/
/* cpusets and nodesets */
hwloc_cpuset_t cpuset; /**< \brief CPUs covered by this object
*
* This is the set of CPUs for which there are PU objects in the topology
* under this object, i.e. which are known to be physically contained in this
* object and known how (the children path between this object and the PU
* objects).
*
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
* some of these CPUs may be online but not allowed for binding,
* see hwloc_topology_get_allowed_cpuset().
*
* \note All objects have non-NULL CPU and node sets except Misc and I/O objects.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_cpuset_t complete_cpuset; /**< \brief The complete CPU set of processors of this object,
*
* This may include not only the same as the cpuset field, but also some CPUs for
* which topology information is unknown or incomplete, some offlines CPUs, and
* the CPUs that are ignored when the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED flag
* is not set.
* Thus no corresponding PU object may be found in the topology, because the
* precise position is undefined. It is however known that it would be somewhere
* under this object.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_nodeset_t nodeset; /**< \brief NUMA nodes covered by this object or containing this object
*
* This is the set of NUMA nodes for which there are NUMA node objects in the
* topology under or above this object, i.e. which are known to be physically
* contained in this object or containing it and known how (the children path
* between this object and the NUMA node objects).
*
* In the end, these nodes are those that are close to the current object.
* Function hwloc_get_local_numanode_objs() may be used to list those NUMA
* nodes more precisely.
*
* If the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED configuration flag is set,
* some of these nodes may be online but not allowed for allocation,
* see hwloc_topology_get_allowed_nodeset().
*
* If there are no NUMA nodes in the machine, all the memory is close to this
* object, so only the first bit may be set in \p nodeset.
*
* \note All objects have non-NULL CPU and node sets except Misc and I/O objects.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_nodeset_t complete_nodeset; /**< \brief The complete NUMA node set of this object,
*
* This may include not only the same as the nodeset field, but also some NUMA
* nodes for which topology information is unknown or incomplete, some offlines
* nodes, and the nodes that are ignored when the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED
* flag is not set.
* Thus no corresponding NUMA node object may be found in the topology, because the
* precise position is undefined. It is however known that it would be
* somewhere under this object.
*
* If there are no NUMA nodes in the machine, all the memory is close to this
* object, so only the first bit is set in \p complete_nodeset.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
struct hwloc_info_s *infos; /**< \brief Array of info attributes (name and value strings). */
unsigned infos_count; /**< \brief Size of infos array. */
/* misc */
void *userdata; /**< \brief Application-given private data pointer,
* initialized to \c NULL, use it as you wish.
* See hwloc_topology_set_userdata_export_callback() in hwloc/export.h
* if you wish to export this field to XML. */
hwloc_uint64_t gp_index; /**< \brief Global persistent index.
* Generated by hwloc, unique across the topology (contrary to os_index)
* and persistent across topology changes (contrary to logical_index).
* Mostly used internally, but could also be used by application to identify objects.
*/
};
/**
* \brief Convenience typedef; a pointer to a struct hwloc_obj.
*/
typedef struct hwloc_obj * hwloc_obj_t;
/** \brief Object type-specific Attributes */
union hwloc_obj_attr_u {
/** \brief NUMA node-specific Object Attributes */
struct hwloc_numanode_attr_s {
hwloc_uint64_t local_memory; /**< \brief Local memory (in bytes) */
unsigned page_types_len; /**< \brief Size of array \p page_types */
/** \brief Array of local memory page types, \c NULL if no local memory and \p page_types is 0.
*
* The array is sorted by increasing \p size fields.
* It contains \p page_types_len slots.
*/
struct hwloc_memory_page_type_s {
hwloc_uint64_t size; /**< \brief Size of pages */
hwloc_uint64_t count; /**< \brief Number of pages of this size */
} * page_types;
} numanode;
/** \brief Cache-specific Object Attributes */
struct hwloc_cache_attr_s {
hwloc_uint64_t size; /**< \brief Size of cache in bytes */
unsigned depth; /**< \brief Depth of cache (e.g., L1, L2, ...etc.) */
unsigned linesize; /**< \brief Cache-line size in bytes. 0 if unknown */
int associativity; /**< \brief Ways of associativity,
* -1 if fully associative, 0 if unknown */
hwloc_obj_cache_type_t type; /**< \brief Cache type */
} cache;
/** \brief Group-specific Object Attributes */
struct hwloc_group_attr_s {
unsigned depth; /**< \brief Depth of group object.
* It may change if intermediate Group objects are added. */
unsigned kind; /**< \brief Internally-used kind of group. */
unsigned subkind; /**< \brief Internally-used subkind to distinguish different levels of groups with same kind */
unsigned char dont_merge; /**< \brief Flag preventing groups from being automatically merged with identical parent or children. */
} group;
/** \brief PCI Device specific Object Attributes */
struct hwloc_pcidev_attr_s {
#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN
unsigned short domain; /**< \brief Domain number (xxxx in the PCI BDF notation xxxx:yy:zz.t).
* Only 16bits PCI domains are supported by default. */
#else
unsigned int domain; /**< \brief Domain number (xxxx in the PCI BDF notation xxxx:yy:zz.t).
* 32bits PCI domain support break the library ABI, hence it's disabled by default. */
#endif
unsigned char bus; /**< \brief Bus number (yy in the PCI BDF notation xxxx:yy:zz.t). */
unsigned char dev; /**< \brief Device number (zz in the PCI BDF notation xxxx:yy:zz.t). */
unsigned char func; /**< \brief Function number (t in the PCI BDF notation xxxx:yy:zz.t). */
unsigned short class_id; /**< \brief The class number (first two bytes, without the prog_if). */
unsigned short vendor_id; /**< \brief Vendor ID (xxxx in [xxxx:yyyy]). */
unsigned short device_id; /**< \brief Device ID (yyyy in [xxxx:yyyy]). */
unsigned short subvendor_id; /**< \brief Sub-Vendor ID. */
unsigned short subdevice_id; /**< \brief Sub-Device ID. */
unsigned char revision; /**< \brief Revision number. */
float linkspeed; /**< \brief Link speed in GB/s.
* This datarate is the currently configured speed of the entire PCI link
* (sum of the bandwidth of all PCI lanes in that link).
* It may change during execution since some devices are able to
* slow their PCI links down when idle.
*/
} pcidev;
/** \brief Bridge specific Object Attributes */
struct hwloc_bridge_attr_s {
union {
struct hwloc_pcidev_attr_s pci; /**< \brief PCI attribute of the upstream part as a PCI device. */
} upstream;
hwloc_obj_bridge_type_t upstream_type; /**< \brief Upstream Bridge type. */
union {
struct {
#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN
unsigned short domain; /**< \brief Domain number the downstream PCI buses.
* Only 16bits PCI domains are supported by default. */
#else
unsigned int domain; /**< \brief Domain number the downstream PCI buses.
* 32bits PCI domain support break the library ABI, hence it's disabled by default */
#endif
unsigned char secondary_bus; /**< \brief First PCI bus number below the bridge. */
unsigned char subordinate_bus; /**< \brief Highest PCI bus number below the bridge. */
} pci;
} downstream;
hwloc_obj_bridge_type_t downstream_type; /**< \brief Downstream Bridge type. */
unsigned depth;
} bridge;
/** \brief OS Device specific Object Attributes */
struct hwloc_osdev_attr_s {
hwloc_obj_osdev_type_t type;
} osdev;
};
/** \brief Object info attribute (name and value strings)
*
* \sa hwlocality_info_attr
*/
struct hwloc_info_s {
char *name; /**< \brief Info name */
char *value; /**< \brief Info value */
};
/** @} */
/** \defgroup hwlocality_creation Topology Creation and Destruction
* @{
*/
struct hwloc_topology;
/** \brief Topology context
*
* To be initialized with hwloc_topology_init() and built with hwloc_topology_load().
*/
typedef struct hwloc_topology * hwloc_topology_t;
/** \brief Allocate a topology context.
*
* \param[out] topologyp is assigned a pointer to the new allocated context.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_init (hwloc_topology_t *topologyp);
/** \brief Build the actual topology
*
* Build the actual topology once initialized with hwloc_topology_init() and
* tuned with \ref hwlocality_configuration and \ref hwlocality_setsource routines.
* No other routine may be called earlier using this topology context.
*
* \param topology is the topology to be loaded with objects.
*
* \return 0 on success, -1 on error.
*
* \note On failure, the topology is reinitialized. It should be either
* destroyed with hwloc_topology_destroy() or configured and loaded again.
*
* \note This function may be called only once per topology.
*
* \note The binding of the current thread or process may temporarily change
* during this call but it will be restored before it returns.
*
* \sa hwlocality_configuration and hwlocality_setsource
*/
HWLOC_DECLSPEC int hwloc_topology_load(hwloc_topology_t topology);
/** \brief Terminate and free a topology context
*
* \param topology is the topology to be freed
*/
HWLOC_DECLSPEC void hwloc_topology_destroy (hwloc_topology_t topology);
/** \brief Duplicate a topology.
*
* The entire topology structure as well as its objects
* are duplicated into a new one.
*
* This is useful for keeping a backup while modifying a topology.
*
* \return 0 on success, -1 on error.
*
* \note Object userdata is not duplicated since hwloc does not know what it point to.
* The objects of both old and new topologies will point to the same userdata.
*/
HWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);
/** \brief Verify that the topology is compatible with the current hwloc library.
*
* This is useful when using the same topology structure (in memory)
* in different libraries that may use different hwloc installations
* (for instance if one library embeds a specific version of hwloc,
* while another library uses a default system-wide hwloc installation).
*
* If all libraries/programs use the same hwloc installation, this function
* always returns success.
*
* \return \c 0 on success.
*
* \return \c -1 with \p errno set to \c EINVAL if incompatible.
*
* \note If sharing between processes with hwloc_shmem_topology_write(),
* the relevant check is already performed inside hwloc_shmem_topology_adopt().
*/
HWLOC_DECLSPEC int hwloc_topology_abi_check(hwloc_topology_t topology);
/** \brief Run internal checks on a topology structure
*
* The program aborts if an inconsistency is detected in the given topology.
*
* \param topology is the topology to be checked
*
* \note This routine is only useful to developers.
*
* \note The input topology should have been previously loaded with
* hwloc_topology_load().
*/
HWLOC_DECLSPEC void hwloc_topology_check(hwloc_topology_t topology);
/** @} */
/** \defgroup hwlocality_levels Object levels, depths and types
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one
* package has fewer caches than its peers.
*/
/** \brief Get the depth of the hierarchical tree of objects.
*
* This is the depth of ::HWLOC_OBJ_PU objects plus one.
*
* \return the depth of the object tree.
*
* \note NUMA nodes, I/O and Misc objects are ignored when computing
* the depth of the tree (they are placed on special levels).
*/
HWLOC_DECLSPEC int hwloc_topology_get_depth(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
/** \brief Returns the depth of objects of type \p type.
*
* \return The depth of objects of type \p type.
*
* \return A negative virtual depth if a NUMA node, I/O or Misc object type is given.
* These objects are stored in special levels that are not CPU-related.
* This virtual depth may be passed to other hwloc functions such as
* hwloc_get_obj_by_depth() but it should not be considered as an actual
* depth by the application. In particular, it should not be compared with
* any other object depth or with the entire topology depth.
*
* \return ::HWLOC_TYPE_DEPTH_UNKNOWN
* if no object of this type is present on the underlying architecture,
* or if the OS doesn't provide this kind of information.
*
* \return ::HWLOC_TYPE_DEPTH_MULTIPLE if type ::HWLOC_OBJ_GROUP is given
* and multiple levels of Groups exist.
*
* \note If the type is absent but a similar type is acceptable, see also
* hwloc_get_type_or_below_depth() and hwloc_get_type_or_above_depth().
*
* \sa hwloc_get_memory_parents_depth() for managing the depth of memory objects.
*
* \sa hwloc_type_sscanf_as_depth() for returning the depth of objects
* whose type is given as a string.
*/
HWLOC_DECLSPEC int hwloc_get_type_depth (hwloc_topology_t topology, hwloc_obj_type_t type);
enum hwloc_get_type_depth_e {
HWLOC_TYPE_DEPTH_UNKNOWN = -1, /**< \brief No object of given type exists in the topology. \hideinitializer */
HWLOC_TYPE_DEPTH_MULTIPLE = -2, /**< \brief Objects of given type exist at different depth in the topology (only for Groups). \hideinitializer */
HWLOC_TYPE_DEPTH_NUMANODE = -3, /**< \brief Virtual depth for NUMA nodes. \hideinitializer */
HWLOC_TYPE_DEPTH_BRIDGE = -4, /**< \brief Virtual depth for bridge object level. \hideinitializer */
HWLOC_TYPE_DEPTH_PCI_DEVICE = -5, /**< \brief Virtual depth for PCI device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_OS_DEVICE = -6, /**< \brief Virtual depth for software device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_MISC = -7, /**< \brief Virtual depth for Misc object. \hideinitializer */
HWLOC_TYPE_DEPTH_MEMCACHE = -8 /**< \brief Virtual depth for MemCache object. \hideinitializer */
};
/** \brief Return the depth of parents where memory objects are attached.
*
* Memory objects have virtual negative depths because they are not part of
* the main CPU-side hierarchy of objects. This depth should not be compared
* with other level depths.
*
* If all Memory objects are attached to Normal parents at the same depth,
* this parent depth may be compared to other as usual, for instance
* for knowing whether NUMA nodes is attached above or below Packages.
*
* \return The depth of Normal parents of all memory children
* if all these parents have the same depth. For instance the depth of
* the Package level if all NUMA nodes are attached to Package objects.
*
* \return ::HWLOC_TYPE_DEPTH_MULTIPLE if Normal parents of all
* memory children do not have the same depth. For instance if some
* NUMA nodes are attached to Packages while others are attached to
* Groups.
*/
HWLOC_DECLSPEC int hwloc_get_memory_parents_depth (hwloc_topology_t topology);
/** \brief Returns the depth of objects of type \p type or below
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically found
* inside \p type.
*
* This function is only meaningful for normal object types.
* If a memory, I/O or Misc object type is given, the corresponding virtual
* depth is always returned (see hwloc_get_type_depth()).
*
* May return ::HWLOC_TYPE_DEPTH_MULTIPLE for ::HWLOC_OBJ_GROUP just like
* hwloc_get_type_depth().
*/
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the depth of objects of type \p type or above
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically
* containing \p type.
*
* This function is only meaningful for normal object types.
* If a memory, I/O or Misc object type is given, the corresponding virtual
* depth is always returned (see hwloc_get_type_depth()).
*
* May return ::HWLOC_TYPE_DEPTH_MULTIPLE for ::HWLOC_OBJ_GROUP just like
* hwloc_get_type_depth().
*/
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the type of objects at depth \p depth.
*
* \p depth should between 0 and hwloc_topology_get_depth()-1,
* or a virtual depth such as ::HWLOC_TYPE_DEPTH_NUMANODE.
*
* \return The type of objects at depth \p depth.
* \return (hwloc_obj_type_t)-1 if depth \p depth does not exist.
*/
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_get_depth_type (hwloc_topology_t topology, int depth) __hwloc_attribute_pure;
/** \brief Returns the width of level at depth \p depth.
*
* \return The number of objects at topology depth \p depth.
* \return 0 if there are no objects at depth \p depth.
*/
HWLOC_DECLSPEC unsigned hwloc_get_nbobjs_by_depth (hwloc_topology_t topology, int depth) __hwloc_attribute_pure;
/** \brief Returns the width of level type \p type
*
* \return The number of objects of type \p type.
* \return -1 if there are multiple levels with objects of that type, e.g. ::HWLOC_OBJ_GROUP.
* \return 0 if there are no objects at depth \p depth.
*/
static __hwloc_inline int
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the top-object of the topology-tree.
*
* Its type is ::HWLOC_OBJ_MACHINE.
*
* This function cannot return \c NULL.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx from depth \p depth
*
* \return The object if it exists.
* \return \c NULL if there is no object with this index and depth.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, int depth, unsigned idx) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx with type \p type
*
* \return The object if it exists.
* \return \c NULL if there is no object with this index and type.
* \return \c NULL if there are multiple levels with objects of that type (e.g. ::HWLOC_OBJ_GROUP),
* the caller may fallback to hwloc_get_obj_by_depth().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
/** \brief Returns the next object at depth \p depth.
*
* \return The first object at depth \p depth if \p prev is \c NULL.
* \return The object after \p prev at depth \p depth if \p prev is not \c NULL.
* \return \c NULL if there is no such object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, int depth, hwloc_obj_t prev);
/** \brief Returns the next object of type \p type.
*
* \return The first object of type \p type if \p prev is \c NULL.
* \return The object after \p prev of type \p type if \p prev is not \c NULL.
* \return \c NULL if there is no such object.
* \return \c NULL if there are multiple levels with objects of that type (e.g. ::HWLOC_OBJ_GROUP),
* the caller may fallback to hwloc_get_obj_by_depth().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev);
/** @} */
/** \defgroup hwlocality_object_strings Converting between Object Types and Attributes, and Strings
* @{
*/
/** \brief Return a constant stringified object type.
*
* This function is the basic way to convert a generic type into a string.
* The output string may be parsed back by hwloc_type_sscanf().
*
* hwloc_obj_type_snprintf() may return a more precise output for a specific
* object, but it requires the caller to provide the output buffer.
*
* \return A constant string containing the object type name or \c "Unknown".
*/
HWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwloc_attribute_const;
/** \brief Stringify the type of a given topology object into a human-readable form.
*
* Contrary to hwloc_obj_type_string(), this function includes object-specific
* attributes (such as the Group depth, the Bridge type, or OS device type)
* in the output, and it requires the caller to provide the output buffer.
*
* The output is guaranteed to be the same for all objects of a same topology level.
*
* If \p verbose is 1, longer type names are used, e.g. L1Cache instead of L1.
*
* The output string may be parsed back by hwloc_type_sscanf().
*
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_obj_t obj,
int verbose);
/** \brief Stringify the attributes of a given topology object into a human-readable form.
*
* Attribute values are separated by \p separator.
*
* Only the major attributes are printed in non-verbose mode.
*
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_obj_t obj, const char * __hwloc_restrict separator,
int verbose);
/** \brief Return an object type and attributes from a type string.
*
* Convert strings such as "Package" or "L1iCache" into the corresponding types.
* Matching is case-insensitive, and only the first letters are actually
* required to match.
*
* The matched object type is set in \p typep (which cannot be \c NULL).
*
* Type-specific attributes, for instance Cache type, Cache depth, Group depth,
* Bridge type or OS Device type may be returned in \p attrp.
* Attributes that are not specified in the string (for instance "Group"
* without a depth, or "L2Cache" without a cache type) are set to -1.
*
* \p attrp is only filled if not \c NULL and if its size specified in \p attrsize
* is large enough. It should be at least as large as union hwloc_obj_attr_u.
*
* \return 0 if a type was correctly identified, otherwise -1.
*
* \note This function is guaranteed to match any string returned by
* hwloc_obj_type_string() or hwloc_obj_type_snprintf().
*
* \note This is an extended version of the now deprecated hwloc_obj_type_sscanf().
*/
HWLOC_DECLSPEC int hwloc_type_sscanf(const char *string,
hwloc_obj_type_t *typep,
union hwloc_obj_attr_u *attrp, size_t attrsize);
/** \brief Return an object type and its level depth from a type string.
*
* Convert strings such as "Package" or "L1iCache" into the corresponding types
* and return in \p depthp the depth of the corresponding level in the
* topology \p topology.
*
* If no object of this type is present on the underlying architecture,
* ::HWLOC_TYPE_DEPTH_UNKNOWN is returned.
*
* If multiple such levels exist (for instance if giving Group without any depth),
* the function may return ::HWLOC_TYPE_DEPTH_MULTIPLE instead.
*
* The matched object type is set in \p typep if \p typep is non \c NULL.
*
* \note This function is similar to hwloc_type_sscanf() followed
* by hwloc_get_type_depth() but it also automatically disambiguates
* multiple group levels etc.
*
* \note This function is guaranteed to match any string returned by
* hwloc_obj_type_string() or hwloc_obj_type_snprintf().
*/
HWLOC_DECLSPEC int hwloc_type_sscanf_as_depth(const char *string,
hwloc_obj_type_t *typep,
hwloc_topology_t topology, int *depthp);
/** @} */
/** \defgroup hwlocality_info_attr Consulting and Adding Info Attributes
*
* @{
*/
/** \brief Search the given name in object infos and return the corresponding value.
*
* If multiple info attributes match the given name, only the first one is returned.
*
* \return A pointer to the value string if it exists.
* \return \c NULL if no such info attribute exists.
*
* \note The string should not be freed by the caller, it belongs to the hwloc library.
*/
static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name) __hwloc_attribute_pure;
/** \brief Add the given name and value pair to the given object info attributes.
*
* The info pair is appended to the existing info array even if another pair
* with the same name already exists.
*
* The input strings are copied before being added in the object infos.
*
* \return \c 0 on success, \c -1 on error.
*
* \note This function may be used to enforce object colors in the lstopo
* graphical output by adding "lstopoStyle" as a name and "Background=#rrggbb"
* as a value. See CUSTOM COLORS in the lstopo(1) manpage for details.
*
* \note If \p name or \p value contain some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml() in hwloc/export.h.
*/
HWLOC_DECLSPEC int hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const char *value);
/** \brief Set (or replace) the subtype of an object.
*
* The given \p subtype is copied internally, the caller is responsible
* for freeing the original \p subtype if needed.
*
* If another subtype already exists in \p object, it is replaced.
* The given \p subtype may be \c NULL to remove the existing subtype.
*
* \note This function is mostly meant to initialize the subtype of user-added
* objects such as groups with hwloc_topology_alloc_group_object().
*
* \return \c 0 on success.
* \return \c -1 with \p errno set to \c ENOMEM on failure to allocate memory.
*/
HWLOC_DECLSPEC int hwloc_obj_set_subtype(hwloc_topology_t topology, hwloc_obj_t obj, const char *subtype);
/** @} */
/** \defgroup hwlocality_cpubinding CPU 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 individual 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.
* hwloc_topology_get_support() may be used to query about the actual CPU
* binding support in the currently used operating system.
*
* When the requested binding operation is not available and the
* ::HWLOC_CPUBIND_STRICT flag was passed, the function returns -1.
* \p errno is set to \c ENOSYS when it is not possible to bind the requested kind of object
* processes/threads. errno is set to \c EXDEV when the requested cpuset
* can not be enforced (e.g. some systems only allow one CPU, and some
* other systems only allow one NUMA node).
*
* If ::HWLOC_CPUBIND_STRICT was not passed, the function may fail as well,
* or the operating system may use a slightly different operation
* (with side-effects, smaller binding set, etc.)
* when the requested operation is not exactly supported.
*
* The most portable version that should be preferred over the others,
* whenever possible, is the following one which just binds the current program,
* assuming it is single-threaded:
*
* \code
* hwloc_set_cpubind(topology, set, 0),
* \endcode
*
* If the program may be multithreaded, the following one should be preferred
* to only bind the current thread:
*
* \code
* hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD),
* \endcode
*
* \sa Some example codes are available under doc/examples/ in the source tree.
*
* \note To unbind, just call the binding function with either a full cpuset or
* a cpuset equal to the system cpuset.
*
* \note On some operating systems, CPU binding may have effects on memory binding, see
* ::HWLOC_CPUBIND_NOMEMBIND
*
* \note Running lstopo \--top or hwloc-ps can be a very convenient tool to check
* how binding actually happened.
* @{
*/
/** \brief Process/Thread binding flags.
*
* These bit flags can be used to refine the binding policy.
*
* The default (0) is to bind the current process, assumed to be
* single-threaded, in a non-strict way. This is the most portable
* way to bind as all operating systems usually provide it.
*
* \note Not all systems support all kinds of binding. See the
* "Detailed Description" section of \ref hwlocality_cpubinding for a
* description of errors that can occur.
*/
typedef enum {
/** \brief Bind all threads of the current (possibly) multithreaded process.
* \hideinitializer */
HWLOC_CPUBIND_PROCESS = (1<<0),
/** \brief Bind current thread of current process.
* \hideinitializer */
HWLOC_CPUBIND_THREAD = (1<<1),
/** \brief Request for strict binding from the OS.
*
* By default, when the designated CPUs are all busy while other
* CPUs are idle, operating systems may execute the thread/process
* on those other CPUs instead of the designated CPUs, to let them
* progress anyway. Strict binding means that the thread/process
* will _never_ execute on other CPUs than the designated CPUs, even
* when those are busy with other tasks and other CPUs are idle.
*
* \note Depending on the operating system, strict binding may not
* be possible (e.g., the OS does not implement it) or not allowed
* (e.g., for an administrative reasons), and the function will fail
* in that case.
*
* When retrieving the binding of a process, this flag checks
* whether all its threads actually have the same binding. If the
* flag is not given, the binding of each thread will be
* accumulated.
*
* \note This flag is meaningless when retrieving the binding of a
* thread.
* \hideinitializer
*/
HWLOC_CPUBIND_STRICT = (1<<2),
/** \brief Avoid any effect on memory binding
*
* On some operating systems, some CPU binding function would also
* bind the memory on the corresponding NUMA node. It is often not
* a problem for the application, but if it is, setting this flag
* will make hwloc avoid using OS functions that would also bind
* memory. This will however reduce the support of CPU bindings,
* i.e. potentially return -1 with errno set to \c ENOSYS in some
* cases.
*
* This flag is only meaningful when used with functions that set
* the CPU binding. It is ignored when used with functions that get
* CPU binding information.
* \hideinitializer
*/
HWLOC_CPUBIND_NOMEMBIND = (1<<3)
} hwloc_cpubind_flags_t;
/** \brief Bind current process or thread on CPUs given in physical bitmap \p set.
*
* \return 0 on success.
* \return -1 with errno set to \c ENOSYS if the action is not supported.
* \return -1 with errno set to \c EXDEV if the binding cannot be enforced.
*/
HWLOC_DECLSPEC int hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
/** \brief Get current process or thread binding.
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the list of PUs which the process or
* thread (according to \e flags) was last bound to.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_get_cpubind(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
/** \brief Bind a process \p pid on CPUs given in physical bitmap \p set.
*
* \return 0 on success, -1 on error.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note As a special case on Linux, if a tid (thread ID) is supplied
* instead of a pid (process ID) and ::HWLOC_CPUBIND_THREAD is passed in flags,
* the binding is applied to that specific thread.
*
* \note On non-Linux systems, ::HWLOC_CPUBIND_THREAD can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);
/** \brief Get the current physical binding of process \p pid.
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the list of PUs which the process
* was last bound to.
*
* \return 0 on success, -1 on error.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note As a special case on Linux, if a tid (thread ID) is supplied
* instead of a pid (process ID) and HWLOC_CPUBIND_THREAD is passed in flags,
* the binding for that specific thread is returned.
*
* \note On non-Linux systems, HWLOC_CPUBIND_THREAD can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
#ifdef hwloc_thread_t
/** \brief Bind a thread \p thread on CPUs given in physical bitmap \p set.
*
* \return 0 on success, -1 on error.
*
* \note \p hwloc_thread_t is \p pthread_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note ::HWLOC_CPUBIND_PROCESS can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t thread, hwloc_const_cpuset_t set, int flags);
#endif
#ifdef hwloc_thread_t
/** \brief Get the current physical binding of thread \p tid.
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the list of PUs which the thread
* was last bound to.
*
* \return 0 on success, -1 on error.
*
* \note \p hwloc_thread_t is \p pthread_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note ::HWLOC_CPUBIND_PROCESS can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t thread, hwloc_cpuset_t set, int flags);
#endif
/** \brief Get the last physical CPU where the current process or thread ran.
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the list of PUs which the process or
* thread (according to \e flags) last ran on.
*
* The operating system may move some tasks from one processor
* to another at any time according to their binding,
* so this function may return something that is already
* outdated.
*
* \p flags can include either ::HWLOC_CPUBIND_PROCESS or ::HWLOC_CPUBIND_THREAD to
* specify whether the query should be for the whole process (union of all CPUs
* on which all threads are running), or only the current thread. If the
* process is single-threaded, flags can be set to zero to let hwloc use
* whichever method is available on the underlying OS.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
/** \brief Get the last physical CPU where a process ran.
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the list of PUs which the process
* last ran on.
*
* The operating system may move some tasks from one processor
* to another at any time according to their binding,
* so this function may return something that is already
* outdated.
*
* \return 0 on success, -1 on error.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note As a special case on Linux, if a tid (thread ID) is supplied
* instead of a pid (process ID) and ::HWLOC_CPUBIND_THREAD is passed in flags,
* the last CPU location of that specific thread is returned.
*
* \note On non-Linux systems, ::HWLOC_CPUBIND_THREAD can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
/** @} */
/** \defgroup hwlocality_membinding Memory binding
*
* Memory binding can be done three ways:
*
* - explicit memory allocation thanks to hwloc_alloc_membind() and friends:
* the binding will have effect on the memory allocated by these functions.
* - implicit memory binding through binding policy: hwloc_set_membind() and
* friends only define the current policy of the process, which will be
* applied to the subsequent calls to malloc() and friends.
* - migration of existing memory ranges, thanks to hwloc_set_area_membind()
* and friends, which move already-allocated data.
*
* Not all operating systems support all three ways.
* hwloc_topology_get_support() may be used to query about the actual memory
* binding support in the currently used operating system.
*
* When the requested binding operation is not available and the
* ::HWLOC_MEMBIND_STRICT flag was passed, the function returns -1.
* \p errno will be set to \c ENOSYS when the system does support
* the specified action or policy
* (e.g., some systems only allow binding memory on a per-thread
* basis, whereas other systems only allow binding memory for all
* threads in a process).
* \p errno will be set to \c EXDEV when the requested set can not be enforced
* (e.g., some systems only allow binding memory to a single NUMA node).
*
* If ::HWLOC_MEMBIND_STRICT was not passed, the function may fail as well,
* or the operating system may use a slightly different operation
* (with side-effects, smaller binding set, etc.)
* when the requested operation is not exactly supported.
*
* The most portable form that should be preferred over the others
* whenever possible is as follows.
* It allocates some memory hopefully bound to the specified set.
* To do so, hwloc will possibly have to change the current memory
* binding policy in order to actually get the memory bound, if the OS
* does not provide any other way to simply allocate bound memory
* without changing the policy for all allocations. That is the
* difference with hwloc_alloc_membind(), which will never change the
* current memory binding policy.
*
* \code
* hwloc_alloc_membind_policy(topology, size, set,
* HWLOC_MEMBIND_BIND, 0);
* \endcode
*
* Each hwloc memory binding function takes a bitmap argument that
* is a CPU set by default, or a NUMA memory node set if the flag
* ::HWLOC_MEMBIND_BYNODESET is specified.
* See \ref hwlocality_object_sets and \ref hwlocality_bitmap for a
* discussion of CPU sets and NUMA memory node sets.
* It is also possible to convert between CPU set and node set using
* hwloc_cpuset_to_nodeset() or hwloc_cpuset_from_nodeset().
*
* Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.
* Binding by nodeset should therefore be preferred whenever possible.
*
* \sa Some example codes are available under doc/examples/ in the source tree.
*
* \note On some operating systems, memory binding affects the CPU
* binding; see ::HWLOC_MEMBIND_NOCPUBIND
* @{
*/
/** \brief Memory binding policy.
*
* These constants can be used to choose the binding policy. Only one policy can
* be used at a time (i.e., the values cannot be OR'ed together).
*
* Not all systems support all kinds of binding.
* hwloc_topology_get_support() may be used to query about the actual memory
* binding policy support in the currently used operating system.
* See the "Detailed Description" section of \ref hwlocality_membinding
* for a description of errors that can occur.
*/
typedef enum {
/** \brief Reset the memory allocation policy to the system default.
* Depending on the operating system, this may correspond to
* ::HWLOC_MEMBIND_FIRSTTOUCH (Linux, FreeBSD),
* or ::HWLOC_MEMBIND_BIND (AIX, HP-UX, Solaris, Windows).
* This policy is never returned by get membind functions.
* The nodeset argument is ignored.
* \hideinitializer */
HWLOC_MEMBIND_DEFAULT = 0,
/** \brief Allocate each memory page individually on the local NUMA
* node of the thread that touches it.
*
* The given nodeset should usually be hwloc_topology_get_topology_nodeset()
* so that the touching thread may run and allocate on any node in the system.
*
* On AIX, if the nodeset is smaller, pages are allocated locally (if the local
* node is in the nodeset) or from a random non-local node (otherwise).
* \hideinitializer */
HWLOC_MEMBIND_FIRSTTOUCH = 1,
/** \brief Allocate memory on the specified nodes.
*
* The actual behavior may slightly vary between operating systems,
* especially when (some of) the requested nodes are full.
* On Linux, by default, the MPOL_PREFERRED_MANY (or MPOL_PREFERRED) policy
* is used. However, if the hwloc strict flag is also given, the Linux
* MPOL_BIND policy is rather used.
* \hideinitializer */
HWLOC_MEMBIND_BIND = 2,
/** \brief Allocate memory on the given nodes in an interleaved
* / round-robin manner. The precise layout of the memory across
* multiple NUMA nodes is OS/system specific. Interleaving can be
* useful when threads distributed across the specified NUMA nodes
* will all be accessing the whole memory range concurrently, since
* the interleave will then balance the memory references.
* \hideinitializer */
HWLOC_MEMBIND_INTERLEAVE = 3,
/** \brief Allocate memory on the given nodes in an interleaved
* / weighted manner. The precise layout of the memory across
* multiple NUMA nodes is OS/system specific. Weighted interleaving
* can be useful when threads distributed across the specified NUMA
* nodes with different bandwidth capabilities will all be accessing
* the whole memory range concurrently, since the interleave will then
* balance the memory references.
* \hideinitializer */
HWLOC_MEMBIND_WEIGHTED_INTERLEAVE = 5,
/** \brief For each page bound with this policy, by next time
* it is touched (and next time only), it is moved from its current
* location to the local NUMA node of the thread where the memory
* reference occurred (if it needs to be moved at all).
* \hideinitializer */
HWLOC_MEMBIND_NEXTTOUCH = 4,
/** \brief Returned by get_membind() functions when multiple
* threads or parts of a memory area have differing memory binding
* policies.
* Also returned when binding is unknown because binding hooks are empty
* when the topology is loaded from XML without HWLOC_THISSYSTEM=1, etc.
* \hideinitializer */
HWLOC_MEMBIND_MIXED = -1
} hwloc_membind_policy_t;
/** \brief Memory binding flags.
*
* These flags can be used to refine the binding policy.
* All flags can be logically OR'ed together with the exception of
* ::HWLOC_MEMBIND_PROCESS and ::HWLOC_MEMBIND_THREAD;
* these two flags are mutually exclusive.
*
* Not all systems support all kinds of binding.
* hwloc_topology_get_support() may be used to query about the actual memory
* binding support in the currently used operating system.
* See the "Detailed Description" section of \ref hwlocality_membinding
* for a description of errors that can occur.
*/
typedef enum {
/** \brief Set policy for all threads of the specified (possibly
* multithreaded) process. This flag is mutually exclusive with
* ::HWLOC_MEMBIND_THREAD.
* \hideinitializer */
HWLOC_MEMBIND_PROCESS = (1<<0),
/** \brief Set policy for a specific thread of the current process.
* This flag is mutually exclusive with ::HWLOC_MEMBIND_PROCESS.
* \hideinitializer */
HWLOC_MEMBIND_THREAD = (1<<1),
/** Request strict binding from the OS. The function will fail if
* the binding can not be guaranteed / completely enforced.
*
* This flag has slightly different meanings depending on which
* function it is used with.
* \hideinitializer */
HWLOC_MEMBIND_STRICT = (1<<2),
/** \brief Migrate existing allocated memory. If the memory cannot
* be migrated and the ::HWLOC_MEMBIND_STRICT flag is passed, an error
* will be returned.
* \hideinitializer */
HWLOC_MEMBIND_MIGRATE = (1<<3),
/** \brief Avoid any effect on CPU binding.
*
* On some operating systems, some underlying memory binding
* functions also bind the application to the corresponding CPU(s).
* Using this flag will cause hwloc to avoid using OS functions that
* could potentially affect CPU bindings. Note, however, that using
* NOCPUBIND may reduce hwloc's overall memory binding
* support. Specifically: some of hwloc's memory binding functions
* may fail with errno set to \c ENOSYS when used with NOCPUBIND.
* \hideinitializer
*/
HWLOC_MEMBIND_NOCPUBIND = (1<<4),
/** \brief Consider the bitmap argument as a nodeset.
*
* The bitmap argument is considered a nodeset if this flag is given,
* or a cpuset otherwise by default.
*
* Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.
* Binding by nodeset should therefore be preferred whenever possible.
* \hideinitializer
*/
HWLOC_MEMBIND_BYNODESET = (1<<5)
} hwloc_membind_flags_t;
/** \brief Set the default memory binding policy of the current
* process or thread to prefer the NUMA node(s) specified by \p set
*
* If neither ::HWLOC_MEMBIND_PROCESS nor ::HWLOC_MEMBIND_THREAD is
* specified, the current process is assumed to be single-threaded.
* This is the most portable form as it permits hwloc to use either
* process-based OS functions or thread-based OS functions, depending
* on which are available.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* \return 0 on success.
* \return -1 with errno set to \c ENOSYS if the action is not supported.
* \return -1 with errno set to \c EXDEV if the binding cannot be enforced.
*/
HWLOC_DECLSPEC int hwloc_set_membind(hwloc_topology_t topology, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags);
/** \brief Query the default memory binding policy and physical locality of the
* current process or thread.
*
* The bitmap \p set (previously allocated by the caller)
* is filled with the process or thread memory binding.
*
* This function has two output parameters: \p set and \p policy.
* The values returned in these parameters depend on both the \p flags
* passed in and the current memory binding policies and nodesets in
* the queried target.
*
* Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query
* target is the current policies and nodesets for all the threads in
* the current process. Passing ::HWLOC_MEMBIND_THREAD specifies that
* the query target is the current policy and nodeset for only the
* thread invoking this function.
*
* If neither of these flags are passed (which is the most portable
* method), the process is assumed to be single threaded. This allows
* hwloc to use either process-based OS functions or thread-based OS
* functions, depending on which are available.
*
* ::HWLOC_MEMBIND_STRICT is only meaningful when ::HWLOC_MEMBIND_PROCESS
* is also specified. In this case, hwloc will check the default
* memory policies and nodesets for all threads in the process. If
* they are not identical, -1 is returned and errno is set to \c EXDEV.
* If they are identical, the values are returned in \p set and \p
* policy.
*
* Otherwise, if ::HWLOC_MEMBIND_PROCESS is specified (and
* ::HWLOC_MEMBIND_STRICT is \em not specified), the default set
* from each thread is logically OR'ed together.
* If all threads' default policies are the same, \p policy is set to
* that policy. If they are different, \p policy is set to
* ::HWLOC_MEMBIND_MIXED.
*
* In the ::HWLOC_MEMBIND_THREAD case (or when neither
* ::HWLOC_MEMBIND_PROCESS or ::HWLOC_MEMBIND_THREAD is specified), there
* is only one set and policy; they are returned in \p set and
* \p policy, respectively.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* If any other flags are specified, -1 is returned and errno is set
* to \c EINVAL.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags);
/** \brief Set the default memory binding policy of the specified
* process to prefer the NUMA node(s) specified by \p set
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* \return 0 on success.
* \return -1 with errno set to \c ENOSYS if the action is not supported.
* \return -1 with errno set to \c EXDEV if the binding cannot be enforced.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*/
HWLOC_DECLSPEC int hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags);
/** \brief Query the default memory binding policy and physical locality of the
* specified process.
*
* The bitmap \p set (previously allocated by the caller)
* is filled with the process memory binding.
*
* This function has two output parameters: \p set and \p policy.
* The values returned in these parameters depend on both the \p flags
* passed in and the current memory binding policies and nodesets in
* the queried target.
*
* Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query
* target is the current policies and nodesets for all the threads in
* the specified process. If ::HWLOC_MEMBIND_PROCESS is not specified
* (which is the most portable method), the process is assumed to be
* single threaded. This allows hwloc to use either process-based OS
* functions or thread-based OS functions, depending on which are
* available.
*
* Note that it does not make sense to pass ::HWLOC_MEMBIND_THREAD to
* this function.
*
* If ::HWLOC_MEMBIND_STRICT is specified, hwloc will check the default
* memory policies and nodesets for all threads in the specified
* process. If they are not identical, -1 is returned and errno is
* set to \c EXDEV. If they are identical, the values are returned in \p
* set and \p policy.
*
* Otherwise, \p set is set to the logical OR of all threads'
* default set. If all threads' default policies
* are the same, \p policy is set to that policy. If they are
* different, \p policy is set to ::HWLOC_MEMBIND_MIXED.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* If any other flags are specified, -1 is returned and errno is set
* to \c EINVAL.
*
* \return 0 on success, -1 on error.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*/
HWLOC_DECLSPEC int hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags);
/** \brief Bind the already-allocated memory identified by (addr, len)
* to the NUMA node(s) specified by \p set.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* \return 0 on success or if \p len is 0.
* \return -1 with errno set to \c ENOSYS if the action is not supported.
* \return -1 with errno set to \c EXDEV if the binding cannot be enforced.
*/
HWLOC_DECLSPEC int hwloc_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags);
/** \brief Query the CPUs near the physical NUMA node(s) and binding policy of
* the memory identified by (\p addr, \p len ).
*
* The bitmap \p set (previously allocated by the caller)
* is filled with the memory area binding.
*
* This function has two output parameters: \p set and \p policy.
* The values returned in these parameters depend on both the \p flags
* passed in and the memory binding policies and nodesets of the pages
* in the address range.
*
* If ::HWLOC_MEMBIND_STRICT is specified, the target pages are first
* checked to see if they all have the same memory binding policy and
* nodeset. If they do not, -1 is returned and errno is set to \c EXDEV.
* If they are identical across all pages, the set and policy are
* returned in \p set and \p policy, respectively.
*
* If ::HWLOC_MEMBIND_STRICT is not specified, the union of all NUMA
* node(s) containing pages in the address range is calculated.
* If all pages in the target have the same policy, it is returned in
* \p policy. Otherwise, \p policy is set to ::HWLOC_MEMBIND_MIXED.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* If any other flags are specified, -1 is returned and errno is set
* to \c EINVAL.
*
* \return 0 on success.
* \return -1 with errno set to \c EINVAL if \p len is 0.
*/
HWLOC_DECLSPEC int hwloc_get_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags);
/** \brief Get the NUMA nodes where memory identified by (\p addr, \p len ) is physically allocated.
*
* The bitmap \p set (previously allocated by the caller)
* is filled according to the NUMA nodes where the memory area pages
* are physically allocated. If no page is actually allocated yet,
* \p set may be empty.
*
* If pages spread to multiple nodes, it is not specified whether they spread
* equitably, or whether most of them are on a single node, etc.
*
* The operating system may move memory pages from one processor
* to another at any time according to their binding,
* so this function may return something that is already
* outdated.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified in \p flags, set is
* considered a nodeset. Otherwise it's a cpuset.
*
* If \p len is 0, \p set is emptied.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_get_area_memlocation(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, int flags);
/** \brief Allocate some memory
*
* This is equivalent to malloc(), except that it tries to allocate
* page-aligned memory from the OS.
*
* \return a pointer to the allocated area, or \c NULL on error.
*
* \note The allocated memory should be freed with hwloc_free().
*/
HWLOC_DECLSPEC void *hwloc_alloc(hwloc_topology_t topology, size_t len);
/** \brief Allocate some memory on NUMA memory nodes specified by \p set
*
* \return a pointer to the allocated area.
* \return NULL with errno set to \c ENOSYS if the action is not supported
* and ::HWLOC_MEMBIND_STRICT is given.
* \return NULL with errno set to \c EXDEV if the binding cannot be enforced
* and ::HWLOC_MEMBIND_STRICT is given.
* \return NULL with errno set to \c ENOMEM if the memory allocation failed
* even before trying to bind.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* \note The allocated memory should be freed with hwloc_free().
*/
HWLOC_DECLSPEC void *hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;
/** \brief Allocate some memory on NUMA memory nodes specified by \p set
*
* First, try to allocate properly with hwloc_alloc_membind().
* On failure, the current process or thread memory binding policy
* is changed with hwloc_set_membind() before allocating memory.
* Thus this function works in more cases, at the expense of changing
* the current state (possibly affecting future allocations that
* would not specify any policy).
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
*
* \return a pointer to the allocated area, or \c NULL on error.
*/
static __hwloc_inline void *
hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;
/** \brief Free memory that was previously allocated by hwloc_alloc()
* or hwloc_alloc_membind().
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_free(hwloc_topology_t topology, void *addr, size_t len);
/** @} */
/** \defgroup hwlocality_setsource Changing the Source of Topology Discovery
*
* These functions must be called between hwloc_topology_init() and hwloc_topology_load().
* Otherwise, they will return -1 with errno set to \c EBUSY.
*
* If none of the functions below is called, the default is to detect all the objects
* of the machine that the caller is allowed to access.
*
* This default behavior may also be modified through environment variables
* if the application did not modify it already.
* Setting HWLOC_XMLFILE in the environment enforces the discovery from a XML
* file as if hwloc_topology_set_xml() had been called.
* Setting HWLOC_SYNTHETIC enforces a synthetic topology as if
* hwloc_topology_set_synthetic() had been called.
*
* Finally, HWLOC_THISSYSTEM enforces the return value of
* hwloc_topology_is_thissystem().
*
* @{
*/
/** \brief Change which process the topology is viewed from.
*
* On some systems, processes may have different views of the machine, for
* instance the set of allowed CPUs. By default, hwloc exposes the view from
* the current process. Calling hwloc_topology_set_pid() permits to make it
* expose the topology of the machine from the point of view of another
* process.
*
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note -1 is returned and errno is set to \c ENOSYS on platforms that do not
* support this feature.
*
* \note The PID will not actually be used until hwloc_topology_load().
* If the corresponding process exits in the meantime, hwloc will ignore the PID.
* If another process reuses the PID, the view of that process will be used.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_set_pid(hwloc_topology_t __hwloc_restrict topology, hwloc_pid_t pid);
/** \brief Enable synthetic topology.
*
* Gather topology information from the given \p description,
* a space-separated string of <type:number> describing
* the object type and arity at each level.
* All types may be omitted (space-separated string of numbers) so that
* hwloc chooses all types according to usual topologies.
* See also the \ref synthetic.
*
* Setting the environment variable HWLOC_SYNTHETIC
* may also result in this behavior.
*
* If \p description was properly parsed and describes a valid topology
* configuration, this function returns 0.
* Otherwise -1 is returned and errno is set to \c EINVAL.
*
* Note that this function does not actually load topology
* information; it just tells hwloc where to load it from. You'll
* still need to invoke hwloc_topology_load() to actually load the
* topology information.
*
* \return 0 on success.
* \return -1 with errno set to \c EINVAL if the description was invalid.
*
* \note For convenience, this backend provides empty binding hooks which just
* return success.
*
* \note On success, the synthetic component replaces the previously enabled
* component (if any), but the topology is not actually modified until
* hwloc_topology_load().
*/
HWLOC_DECLSPEC int hwloc_topology_set_synthetic(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict description);
/** \brief Enable XML-file based topology.
*
* Gather topology information from the XML file given at \p xmlpath.
* Setting the environment variable HWLOC_XMLFILE may also result in this behavior.
* This file may have been generated earlier with hwloc_topology_export_xml() in hwloc/export.h,
* or lstopo file.xml.
*
* Note that this function does not actually load topology
* information; it just tells hwloc where to load it from. You'll
* still need to invoke hwloc_topology_load() to actually load the
* topology information.
*
* \return 0 on success.
* \return -1 with errno set to \c EINVAL on failure to read the XML file.
*
* \note See also hwloc_topology_set_userdata_import_callback()
* for importing application-specific object userdata.
*
* \note For convenience, this backend provides empty binding hooks which just
* return success. To have hwloc still actually call OS-specific hooks, the
* ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM has to be set to assert that the loaded
* file is really the underlying system.
*
* \note On success, the XML component replaces the previously enabled
* component (if any), but the topology is not actually modified until
* hwloc_topology_load().
*
* \note If an invalid XML input file is given, the error may be reported
* either here or later by hwloc_topology_load() depending on the XML library
* used by hwloc.
*/
HWLOC_DECLSPEC int hwloc_topology_set_xml(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict xmlpath);
/** \brief Enable XML based topology using a memory buffer (instead of
* a file, as with hwloc_topology_set_xml()).
*
* Gather topology information from the XML memory buffer given at
* \p buffer and of length \p size (including an ending \0).
* This buffer may have been filled earlier with
* hwloc_topology_export_xmlbuffer() in hwloc/export.h.
*
* Note that this function does not actually load topology
* information; it just tells hwloc where to load it from. You'll
* still need to invoke hwloc_topology_load() to actually load the
* topology information.
*
* \return 0 on success.
* \return -1 with errno set to \c EINVAL on failure to read the XML buffer.
*
* \note See also hwloc_topology_set_userdata_import_callback()
* for importing application-specific object userdata.
*
* \note For convenience, this backend provides empty binding hooks which just
* return success. To have hwloc still actually call OS-specific hooks, the
* ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM has to be set to assert that the loaded
* file is really the underlying system.
*
* \note On success, the XML component replaces the previously enabled
* component (if any), but the topology is not actually modified until
* hwloc_topology_load().
*
* \note If an invalid XML input file is given, the error may be reported
* either here or later by hwloc_topology_load() depending on the XML library
* used by hwloc.
*/
HWLOC_DECLSPEC int hwloc_topology_set_xmlbuffer(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict buffer, int size);
/** \brief Flags to be passed to hwloc_topology_set_components()
*/
enum hwloc_topology_components_flag_e {
/** \brief Blacklist the target component from being used.
* \hideinitializer
*/
HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST = (1UL<<0)
};
/** \brief Prevent a discovery component from being used for a topology.
*
* \p name is the name of the discovery component that should not be used
* when loading topology \p topology. The name is a string such as "cuda".
*
* For components with multiple phases, it may also be suffixed with the name
* of a phase, for instance "linux:io".
*
* \p flags should be ::HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST.
*
* This may be used to avoid expensive parts of the discovery process.
* For instance, CUDA-specific discovery may be expensive and unneeded
* while generic I/O discovery could still be useful.
*
* \return 0 on success.
* \return -1 on error, for instance if flags are invalid.
*/
HWLOC_DECLSPEC int hwloc_topology_set_components(hwloc_topology_t __hwloc_restrict topology, unsigned long flags, const char * __hwloc_restrict name);
/** @} */
/** \defgroup hwlocality_configuration Topology Detection Configuration and Query
*
* Several functions can optionally be called between hwloc_topology_init() and
* hwloc_topology_load() to configure how the detection should be performed,
* e.g. to ignore some objects types, define a synthetic topology, etc.
*
* @{
*/
/** \brief Flags to be set onto a topology context before load.
*
* Flags should be given to hwloc_topology_set_flags().
* They may also be returned by hwloc_topology_get_flags().
*/
enum hwloc_topology_flags_e {
/** \brief Detect the whole system, ignore reservations, include disallowed objects.
*
* Gather all online resources, even if some were disabled by the administrator.
* For instance, ignore Linux Cgroup/Cpusets and gather all processors and memory nodes.
* However offline PUs and NUMA nodes are still ignored.
*
* When this flag is not set, PUs and NUMA nodes that are disallowed are not added to the topology.
* Parent objects (package, core, cache, etc.) are added only if some of their children are allowed.
* All existing PUs and NUMA nodes in the topology are allowed.
* hwloc_topology_get_allowed_cpuset() and hwloc_topology_get_allowed_nodeset()
* are equal to the root object cpuset and nodeset.
*
* When this flag is set, the actual sets of allowed PUs and NUMA nodes are given
* by hwloc_topology_get_allowed_cpuset() and hwloc_topology_get_allowed_nodeset().
* They may be smaller than the root object cpuset and nodeset.
*
* If the current topology is exported to XML and reimported later, this flag
* should be set again in the reimported topology so that disallowed resources
* are reimported as well.
* \hideinitializer
*/
HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED = (1UL<<0),
/** \brief Assume that the selected backend provides the topology for the
* system on which we are running.
*
* This forces hwloc_topology_is_thissystem() to return 1, i.e. makes hwloc assume that
* the selected backend provides the topology for the system on which we are running,
* even if it is not the OS-specific backend but the XML backend for instance.
* This means making the binding functions actually call the OS-specific
* system calls and really do binding, while the XML backend would otherwise
* provide empty hooks just returning success.
*
* Setting the environment variable HWLOC_THISSYSTEM may also result in the
* same behavior.
*
* This can be used for efficiency reasons to first detect the topology once,
* save it to an XML file, and quickly reload it later through the XML
* backend, but still having binding functions actually do bind.
* \hideinitializer
*/
HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM = (1UL<<1),
/** \brief Get the set of allowed resources from the local operating system even if the topology was loaded from XML or synthetic description.
*
* If the topology was loaded from XML or from a synthetic string,
* restrict it by applying the current process restrictions such as
* Linux Cgroup/Cpuset.
*
* This is useful when the topology is not loaded directly from
* the local machine (e.g. for performance reason) and it comes
* with all resources, while the running process is restricted
* to only parts of the machine.
*
* This flag is ignored unless ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM is
* also set since the loaded topology must match the underlying machine
* where restrictions will be gathered from.
*
* Setting the environment variable HWLOC_THISSYSTEM_ALLOWED_RESOURCES
* would result in the same behavior.
* \hideinitializer
*/
HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES = (1UL<<2),
/** \brief Import support from the imported topology.
*
* When importing a XML topology from a remote machine, binding is
* disabled by default (see ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM).
* This disabling is also marked by putting zeroes in the corresponding
* supported feature bits reported by hwloc_topology_get_support().
*
* The flag ::HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT actually imports
* support bits from the remote machine. It also sets the flag
* \p imported_support in the struct hwloc_topology_misc_support array.
* If the imported XML did not contain any support information
* (exporter hwloc is too old), this flag is not set.
*
* Note that these supported features are only relevant for the hwloc
* installation that actually exported the XML topology
* (it may vary with the operating system, or with how hwloc was compiled).
*
* Note that setting this flag however does not enable binding for the
* locally imported hwloc topology, it only reports what the remote
* hwloc and machine support.
*
*/
HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT = (1UL<<3),
/** \brief Do not consider resources outside of the process CPU binding.
*
* If the binding of the process is limited to a subset of cores,
* ignore the other cores during discovery.
*
* The resulting topology is identical to what a call to hwloc_topology_restrict()
* would generate, but this flag also prevents hwloc from ever touching other
* resources during the discovery.
*
* This flag especially tells the x86 backend to never temporarily
* rebind a thread on any excluded core. This is useful on Windows
* because such temporary rebinding can change the process binding.
* Another use-case is to avoid cores that would not be able to
* perform the hwloc discovery anytime soon because they are busy
* executing some high-priority real-time tasks.
*
* If process CPU binding is not supported,
* the thread CPU binding is considered instead if supported,
* or the flag is ignored.
*
* This flag requires ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM as well
* since binding support is required.
*/
HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING = (1UL<<4),
/** \brief Do not consider resources outside of the process memory binding.
*
* If the binding of the process is limited to a subset of NUMA nodes,
* ignore the other NUMA nodes during discovery.
*
* The resulting topology is identical to what a call to hwloc_topology_restrict()
* would generate, but this flag also prevents hwloc from ever touching other
* resources during the discovery.
*
* This flag is meant to be used together with
* ::HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING when both cores
* and NUMA nodes should be ignored outside of the process binding.
*
* If process memory binding is not supported,
* the thread memory binding is considered instead if supported,
* or the flag is ignored.
*
* This flag requires ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM as well
* since binding support is required.
*/
HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING = (1UL<<5),
/** \brief Do not ever modify the process or thread binding during discovery.
*
* This flag disables all hwloc discovery steps that require a change of
* the process or thread binding. This currently only affects the x86
* backend which gets entirely disabled.
*
* This is useful when hwloc_topology_load() is called while the
* application also creates additional threads or modifies the binding.
*
* This flag is also a strict way to make sure the process binding will
* not change to due thread binding changes on Windows
* (see ::HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING).
*/
HWLOC_TOPOLOGY_FLAG_DONT_CHANGE_BINDING = (1UL<<6),
/** \brief Ignore distances.
*
* Ignore distance information from the operating systems (and from XML)
* and hence do not use distances for grouping.
*/
HWLOC_TOPOLOGY_FLAG_NO_DISTANCES = (1UL<<7),
/** \brief Ignore memory attributes and tiers.
*
* Ignore memory attribues from the operating systems (and from XML)
* Hence also do not try to build memory tiers.
*/
HWLOC_TOPOLOGY_FLAG_NO_MEMATTRS = (1UL<<8),
/** \brief Ignore CPU Kinds.
*
* Ignore CPU kind information from the operating systems (and from XML).
*/
HWLOC_TOPOLOGY_FLAG_NO_CPUKINDS = (1UL<<9)
};
/** \brief Set OR'ed flags to non-yet-loaded topology.
*
* Set a OR'ed set of ::hwloc_topology_flags_e onto a topology that was not yet loaded.
*
* If this function is called multiple times, the last invocation will erase
* and replace the set of flags that was previously set.
*
* By default, no flags are set (\c 0).
*
* The flags set in a topology may be retrieved with hwloc_topology_get_flags().
*
* \return 0 on success.
* \return -1 on error, for instance if flags are invalid.
*/
HWLOC_DECLSPEC int hwloc_topology_set_flags (hwloc_topology_t topology, unsigned long flags);
/** \brief Get OR'ed flags of a topology.
*
* Get the OR'ed set of ::hwloc_topology_flags_e of a topology.
*
* If hwloc_topology_set_flags() was not called earlier,
* no flags are set (\c 0 is returned).
*
* \return the flags previously set with hwloc_topology_set_flags().
*
* \note This function may also be called after hwloc_topology_load().
*/
HWLOC_DECLSPEC unsigned long hwloc_topology_get_flags (hwloc_topology_t topology);
/** \brief Does the topology context come from this system?
*
* \return 1 if this topology context was built using the system
* running this program.
* \return 0 instead (for instance if using another file-system root,
* a XML topology file, or a synthetic topology).
*
* \note This function may also be called after hwloc_topology_load().
*/
HWLOC_DECLSPEC int hwloc_topology_is_thissystem(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
/** \brief Flags describing actual discovery support for this topology. */
struct hwloc_topology_discovery_support {
/** \brief Detecting the number of PU objects is supported. */
unsigned char pu;
/** \brief Detecting the number of NUMA nodes is supported. */
unsigned char numa;
/** \brief Detecting the amount of memory in NUMA nodes is supported. */
unsigned char numa_memory;
/** \brief Detecting and identifying PU objects that are not available to the current process is supported. */
unsigned char disallowed_pu;
/** \brief Detecting and identifying NUMA nodes that are not available to the current process is supported. */
unsigned char disallowed_numa;
/** \brief Detecting the efficiency of CPU kinds is supported, see \ref hwlocality_cpukinds. */
unsigned char cpukind_efficiency;
};
/** \brief Flags describing actual PU binding support for this topology.
*
* A flag may be set even if the feature isn't supported in all cases
* (e.g. binding to random sets of non-contiguous objects).
*/
struct hwloc_topology_cpubind_support {
/** Binding the whole current process is supported. */
unsigned char set_thisproc_cpubind;
/** Getting the binding of the whole current process is supported. */
unsigned char get_thisproc_cpubind;
/** Binding a whole given process is supported. */
unsigned char set_proc_cpubind;
/** Getting the binding of a whole given process is supported. */
unsigned char get_proc_cpubind;
/** Binding the current thread only is supported. */
unsigned char set_thisthread_cpubind;
/** Getting the binding of the current thread only is supported. */
unsigned char get_thisthread_cpubind;
/** Binding a given thread only is supported. */
unsigned char set_thread_cpubind;
/** Getting the binding of a given thread only is supported. */
unsigned char get_thread_cpubind;
/** Getting the last processors where the whole current process ran is supported */
unsigned char get_thisproc_last_cpu_location;
/** Getting the last processors where a whole process ran is supported */
unsigned char get_proc_last_cpu_location;
/** Getting the last processors where the current thread ran is supported */
unsigned char get_thisthread_last_cpu_location;
};
/** \brief Flags describing actual memory binding support for this topology.
*
* A flag may be set even if the feature isn't supported in all cases
* (e.g. binding to random sets of non-contiguous objects).
*/
struct hwloc_topology_membind_support {
/** Binding the whole current process is supported. */
unsigned char set_thisproc_membind;
/** Getting the binding of the whole current process is supported. */
unsigned char get_thisproc_membind;
/** Binding a whole given process is supported. */
unsigned char set_proc_membind;
/** Getting the binding of a whole given process is supported. */
unsigned char get_proc_membind;
/** Binding the current thread only is supported. */
unsigned char set_thisthread_membind;
/** Getting the binding of the current thread only is supported. */
unsigned char get_thisthread_membind;
/** Binding a given memory area is supported. */
unsigned char set_area_membind;
/** Getting the binding of a given memory area is supported. */
unsigned char get_area_membind;
/** Allocating a bound memory area is supported. */
unsigned char alloc_membind;
/** First-touch policy is supported. */
unsigned char firsttouch_membind;
/** Bind policy is supported. */
unsigned char bind_membind;
/** Interleave policy is supported. */
unsigned char interleave_membind;
/** Next-touch migration policy is supported. */
unsigned char nexttouch_membind;
/** Migration flags is supported. */
unsigned char migrate_membind;
/** Getting the last NUMA nodes where a memory area was allocated is supported */
unsigned char get_area_memlocation;
/** Weighted interleave policy is supported. */
unsigned char weighted_interleave_membind;
};
/** \brief Flags describing miscellaneous features.
*/
struct hwloc_topology_misc_support {
/** Support was imported when importing another topology, see ::HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT. */
unsigned char imported_support;
};
/** \brief Set of flags describing actual support for this topology.
*
* This is retrieved with hwloc_topology_get_support() and will be valid until
* the topology object is destroyed. Note: the values are correct only after
* discovery.
*/
struct hwloc_topology_support {
struct hwloc_topology_discovery_support *discovery;
struct hwloc_topology_cpubind_support *cpubind;
struct hwloc_topology_membind_support *membind;
struct hwloc_topology_misc_support *misc;
};
/** \brief Retrieve the topology support.
*
* Each flag indicates whether a feature is supported.
* If set to 0, the feature is not supported.
* If set to 1, the feature is supported, but the corresponding
* call may still fail in some corner cases.
*
* These features are also listed by hwloc-info \--support
*
* The reported features are what the current topology supports
* on the current machine. If the topology was exported to XML
* from another machine and later imported here, support still
* describes what is supported for this imported topology after
* import. By default, binding will be reported as unsupported
* in this case (see ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM).
*
* Topology flag ::HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT may be used
* to report the supported features of the original remote machine
* instead. If it was successfully imported, \p imported_support
* will be set in the struct hwloc_topology_misc_support array.
*
* \return A pointer to a support structure.
*
* \note The function cannot return \c NULL.
* \note The returned pointer should not be freed, it belongs to the hwloc library.
*
* \note This function may be called before or after hwloc_topology_load()
* but the support structure only contains valid information after.
*/
HWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(hwloc_topology_t __hwloc_restrict topology);
/** \brief Type filtering flags.
*
* By default, most objects are kept (::HWLOC_TYPE_FILTER_KEEP_ALL).
* Instruction caches, memory-side caches, I/O and Misc objects are ignored by default (::HWLOC_TYPE_FILTER_KEEP_NONE).
* Group levels are ignored unless they bring structure (::HWLOC_TYPE_FILTER_KEEP_STRUCTURE).
*
* Note that group objects are also ignored individually (without the entire level)
* when they do not bring structure.
*/
enum hwloc_type_filter_e {
/** \brief Keep all objects of this type.
*
* Cannot be set for ::HWLOC_OBJ_GROUP (groups are designed only to add more structure to the topology).
* \hideinitializer
*/
HWLOC_TYPE_FILTER_KEEP_ALL = 0,
/** \brief Ignore all objects of this type.
*
* The bottom-level type ::HWLOC_OBJ_PU, the ::HWLOC_OBJ_NUMANODE type, and
* the top-level type ::HWLOC_OBJ_MACHINE may not be ignored.
* \hideinitializer
*/
HWLOC_TYPE_FILTER_KEEP_NONE = 1,
/** \brief Only ignore objects if their entire level does not bring any structure.
*
* Keep the entire level of objects if at least one of these objects adds
* structure to the topology. An object brings structure when it has multiple
* children and it is not the only child of its parent.
*
* If all objects in the level are the only child of their parent, and if none
* of them has multiple children, the entire level is removed.
*
* Cannot be set for I/O and Misc objects since the topology structure does not matter there.
* \hideinitializer
*/
HWLOC_TYPE_FILTER_KEEP_STRUCTURE = 2,
/** \brief Only keep likely-important objects of the given type.
*
* It is only useful for I/O object types.
* For ::HWLOC_OBJ_PCI_DEVICE and ::HWLOC_OBJ_OS_DEVICE, it means that only objects
* of major/common kinds are kept (storage, network, OpenFabrics, CUDA,
* OpenCL, RSMI, NVML, and displays).
* Also, only OS devices directly attached on PCI (e.g. no USB) are reported.
* For ::HWLOC_OBJ_BRIDGE, it means that bridges are kept only if they have children.
*
* This flag equivalent to ::HWLOC_TYPE_FILTER_KEEP_ALL for Normal, Memory and Misc types
* since they are likely important.
* \hideinitializer
*/
HWLOC_TYPE_FILTER_KEEP_IMPORTANT = 3
};
/** \brief Set the filtering for the given object type.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_set_type_filter(hwloc_topology_t topology, hwloc_obj_type_t type, enum hwloc_type_filter_e filter);
/** \brief Get the current filtering for the given object type.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_get_type_filter(hwloc_topology_t topology, hwloc_obj_type_t type, enum hwloc_type_filter_e *filter);
/** \brief Set the filtering for all object types.
*
* If some types do not support this filtering, they are silently ignored.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_set_all_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the filtering for all CPU cache object types.
*
* Memory-side caches are not involved since they are not CPU caches.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_set_cache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the filtering for all CPU instruction cache object types.
*
* Memory-side caches are not involved since they are not CPU caches.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_set_icache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the filtering for all I/O object types.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_topology_set_io_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the topology-specific userdata pointer.
*
* Each topology may store one application-given private data pointer.
* It is initialized to \c NULL.
* hwloc will never modify it.
*
* Use it as you wish, after hwloc_topology_init() and until hwloc_topolog_destroy().
*
* This pointer is not exported to XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata(hwloc_topology_t topology, const void *userdata);
/** \brief Retrieve the topology-specific userdata pointer.
*
* Retrieve the application-given private data pointer that was
* previously set with hwloc_topology_set_userdata().
*
* \return A pointer to the private-data if any.
* \return \c NULL if no private-data was previoulsy set.
*/
HWLOC_DECLSPEC void * hwloc_topology_get_userdata(hwloc_topology_t topology);
/** @} */
/** \defgroup hwlocality_tinker Modifying a loaded Topology
* @{
*/
/** \brief Flags to be given to hwloc_topology_restrict(). */
enum hwloc_restrict_flags_e {
/** \brief Remove all objects that became CPU-less.
* By default, only objects that contain no PU and no memory are removed.
* This flag may not be used with ::HWLOC_RESTRICT_FLAG_BYNODESET.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_REMOVE_CPULESS = (1UL<<0),
/** \brief Restrict by nodeset instead of CPU set.
* Only keep objects whose nodeset is included or partially included in the given set.
* This flag may not be used with ::HWLOC_RESTRICT_FLAG_REMOVE_CPULESS.
*/
HWLOC_RESTRICT_FLAG_BYNODESET = (1UL<<3),
/** \brief Remove all objects that became Memory-less.
* By default, only objects that contain no PU and no memory are removed.
* This flag may only be used with ::HWLOC_RESTRICT_FLAG_BYNODESET.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS = (1UL<<4),
/** \brief Move Misc objects to ancestors if their parents are removed during restriction.
* If this flag is not set, Misc objects are removed when their parents are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_MISC = (1UL<<1),
/** \brief Move I/O objects to ancestors if their parents are removed during restriction.
* If this flag is not set, I/O devices and bridges are removed when their parents are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_IO = (1UL<<2)
};
/** \brief Restrict the topology to the given CPU set or nodeset.
*
* Topology \p topology is modified so as to remove all objects that
* are not included (or partially included) in the CPU set \p set.
* All objects CPU and node sets are restricted accordingly.
*
* By default, \p set is a CPU set. It means that the set of PUs in
* the topology is restricted. Once some PUs got removed, their parents
* may also get removed recursively if they became child-less.
*
* If ::HWLOC_RESTRICT_FLAG_BYNODESET is passed in \p flags,
* \p set is considered a nodeset instead of a CPU set.
* It means that the set of NUMA nodes in the topology is restricted
* (instead of PUs). Once some NUMA nodes got removed, their parents
* may also get removed recursively if they became child-less.
*
* \p flags is a OR'ed set of ::hwloc_restrict_flags_e.
*
* \note Restricting the topology removes some locality information,
* hence the remaining objects may get reordered (including PUs and NUMA nodes),
* and their logical indexes may change.
*
* \note This call may not be reverted by restricting back to a larger
* set. Once dropped during restriction, objects may not be brought
* back, except by loading another topology with hwloc_topology_load().
*
* \return 0 on success.
*
* \return -1 with errno set to \c EINVAL if the input set is invalid.
* The topology is not modified in this case.
*
* \return -1 with errno set to \c ENOMEM on failure to allocate internal data.
* The topology is reinitialized in this case. It should be either
* destroyed with hwloc_topology_destroy() or configured and loaded again.
*/
HWLOC_DECLSPEC int hwloc_topology_restrict(hwloc_topology_t __hwloc_restrict topology, hwloc_const_bitmap_t set, unsigned long flags);
/** \brief Flags to be given to hwloc_topology_allow(). */
enum hwloc_allow_flags_e {
/** \brief Mark all objects as allowed in the topology.
*
* \p cpuset and \p nođeset given to hwloc_topology_allow() must be \c NULL.
* \hideinitializer */
HWLOC_ALLOW_FLAG_ALL = (1UL<<0),
/** \brief Only allow objects that are available to the current process.
*
* The topology must have ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM so that the set
* of available resources can actually be retrieved from the operating system.
*
* \p cpuset and \p nođeset given to hwloc_topology_allow() must be \c NULL.
* \hideinitializer */
HWLOC_ALLOW_FLAG_LOCAL_RESTRICTIONS = (1UL<<1),
/** \brief Allow a custom set of objects, given to hwloc_topology_allow() as \p cpuset and/or \p nodeset parameters.
* \hideinitializer */
HWLOC_ALLOW_FLAG_CUSTOM = (1UL<<2)
};
/** \brief Change the sets of allowed PUs and NUMA nodes in the topology.
*
* This function only works if the ::HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED
* was set on the topology. It does not modify any object, it only changes
* the sets returned by hwloc_topology_get_allowed_cpuset() and
* hwloc_topology_get_allowed_nodeset().
*
* It is notably useful when importing a topology from another process
* running in a different Linux Cgroup.
*
* \p flags must be set to one flag among ::hwloc_allow_flags_e.
*
* \return 0 on success, -1 on error.
*
* \note Removing objects from a topology should rather be performed with
* hwloc_topology_restrict().
*/
HWLOC_DECLSPEC int hwloc_topology_allow(hwloc_topology_t __hwloc_restrict topology, hwloc_const_cpuset_t cpuset, hwloc_const_nodeset_t nodeset, unsigned long flags);
/** \brief Add a MISC object as a leaf of the topology
*
* A new MISC object will be created and inserted into the topology at the
* position given by parent. It is appended to the list of existing Misc children,
* without ever adding any intermediate hierarchy level. This is useful for
* annotating the topology without actually changing the hierarchy.
*
* \p name is supposed to be unique across all Misc objects in the topology.
* It will be duplicated to setup the new object attributes.
*
* The new leaf object will not have any \p cpuset.
*
* The \p subtype object attribute may be defined with hwloc_obj_set_subtype()
* after successful insertion.
*
* \return the newly-created object
*
* \return \c NULL on error.
*
* \return \c NULL if Misc objects are filtered-out of the topology (::HWLOC_TYPE_FILTER_KEEP_NONE).
*
* \note If \p name contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml() in hwloc/export.h.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object(hwloc_topology_t topology, hwloc_obj_t parent, const char *name);
/** \brief Allocate a Group object to insert later with hwloc_topology_insert_group_object().
*
* This function returns a new Group object.
*
* The caller should (at least) initialize its sets before inserting
* the object in the topology, see hwloc_topology_insert_group_object().
* Or it may decide not to insert and just free the group object
* by calling hwloc_topology_free_group_object().
*
* \return The allocated object on success.
* \return \c NULL on error.
*
* \note If successfully inserted by hwloc_topology_insert_group_object(),
* the object will be freed when the entire topology is freed.
* If insertion failed (e.g. \c NULL or empty CPU and node-sets),
* it is freed before returning the error.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_alloc_group_object(hwloc_topology_t topology);
/** \brief Free a group object allocated with hwloc_topology_alloc_group_object().
*
* This function is only useful if the group object was not given
* to hwloc_topology_insert_group_object() as planned.
*
* \note \p topology must be the same as the one previously passed
* to hwloc_topology_alloc_group_object().
*
* \return \c 0 on success.
* \return \c -1 on error, for instance if an invalid topology is given.
*/
HWLOC_DECLSPEC int hwloc_topology_free_group_object(hwloc_topology_t topology, hwloc_obj_t group);
/** \brief Add more structure to the topology by adding an intermediate Group
*
* The caller should first allocate a new Group object with hwloc_topology_alloc_group_object().
* Then it must setup at least one of its CPU or node sets to specify
* the final location of the Group in the topology.
* Then the object can be passed to this function for actual insertion in the topology.
*
* The main use case for this function is to group a subset of
* siblings among the list of children below a single parent.
* For instance, if grouping 4 cores out of a 8-core socket,
* the logical list of cores will be reordered so that the 4 grouped
* ones are consecutive.
* Then, if needed, a new depth is added between the parent and those
* children, and the Group is inserted there.
* At the end, the 4 grouped cores are now children of the Group,
* which replaces them as a child of the original parent.
*
* In practice, the grouped objects are specified through cpusets
* and/or nodesets, for instance using hwloc_obj_add_other_obj_sets()
* iteratively.
* Hence it is possible to group objects that are not children of the
* same parent, for instance some PUs below the 4 cores in example above.
* However this general case may fail if the expected Group conflicts
* with the existing hierarchy.
* For instance if each core has two PUs, it is not possible to insert
* a Group containing a single PU of each core.
*
* To specify the objects to group, either the cpuset or nodeset field
* (or both, if compatible) must be set to a non-empty bitmap.
* The complete_cpuset or complete_nodeset may be set instead if
* inserting with respect to the complete topology
* (including disallowed, offline or unknown objects).
* These sets cannot be larger than the current topology, or they would get
* restricted silently.
* The core will setup the other sets after actual insertion.
*
* The \p subtype object attribute may be defined with hwloc_obj_set_subtype()
* to display something else than "Group" as the type name for this object in lstopo.
* Custom name-value info pairs may be added with hwloc_obj_add_info() after
* insertion.
*
* The group \p dont_merge attribute may be set to \c 1 to prevent
* the hwloc core from ever merging this object with another
* hierarchically-identical object.
* This is useful when the Group itself describes an important feature
* that cannot be exposed anywhere else in the hierarchy.
*
* The group \p kind attribute may be set to a high value such
* as \c 0xffffffff to tell hwloc that this new Group should always
* be discarded in favor of any existing Group with the same locality.
*
* \note Inserting a group adds some locality information to the topology,
* hence the existing objects may get reordered (including PUs and NUMA nodes),
* and their logical indexes may change.
*
* \note If the insertion fails, the input group object is freed.
*
* \note If the group object should be discarded instead of inserted,
* it may be passed to hwloc_topology_free_group_object() instead.
*
* \note \p topology must be the same as the one previously passed
* to hwloc_topology_alloc_group_object().
*
* \return The inserted object if it was properly inserted.
*
* \return An existing object if the Group was merged or discarded
* because the topology already contained an object at the same
* location (the Group did not add any hierarchy information).
*
* \return \c NULL if the insertion failed because of conflicting sets in topology tree.
*
* \return \c NULL if Group objects are filtered-out of the topology (::HWLOC_TYPE_FILTER_KEEP_NONE).
*
* \return \c NULL if the object was discarded because no set was
* initialized in the Group before insert, or all of them were empty.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_group_object(hwloc_topology_t topology, hwloc_obj_t group);
/** \brief Setup object cpusets/nodesets by OR'ing another object's sets.
*
* For each defined cpuset or nodeset in \p src, allocate the corresponding set
* in \p dst and add \p src to it by OR'ing sets.
*
* This function is convenient between hwloc_topology_alloc_group_object()
* and hwloc_topology_insert_group_object(). It builds the sets of the new Group
* that will be inserted as a new intermediate parent of several objects.
*
* \return 0 on success.
* \return -1 with errno set to \c ENOMEM if some internal reallocation failed.
*/
HWLOC_DECLSPEC int hwloc_obj_add_other_obj_sets(hwloc_obj_t dst, hwloc_obj_t src);
/** \brief Refresh internal structures after topology modification.
*
* Modifying the topology (by restricting, adding objects, modifying structures
* such as distances or memory attributes, etc.) may cause some internal caches
* to become invalid. These caches are automatically refreshed when accessed
* but this refreshing is not thread-safe.
*
* This function is not thread-safe either, but it is a good way to end a
* non-thread-safe phase of topology modification. Once this refresh is done,
* multiple threads may concurrently consult the topology, objects, distances,
* attributes, etc.
*
* See also \ref threadsafety
*
* \return 0 on success.
* \return -1 on error, for instance if some internal reallocation failed.
*/
HWLOC_DECLSPEC int hwloc_topology_refresh(hwloc_topology_t topology);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
/* high-level helpers */
#include "hwloc/helper.h"
/* inline code of some functions above */
#include "hwloc/inlines.h"
/* memory attributes */
#include "hwloc/memattrs.h"
/* kinds of CPU cores */
#include "hwloc/cpukinds.h"
/* exporting to XML or synthetic */
#include "hwloc/export.h"
/* distances */
#include "hwloc/distances.h"
/* topology diffs */
#include "hwloc/diff.h"
/* deprecated headers */
#include "hwloc/deprecated.h"
#endif /* HWLOC_H */