Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-20 09:14:34

0001 /*
0002  * SPDX-License-Identifier: BSD-3-Clause
0003  * Copyright © 2019-2025 Inria.  All rights reserved.
0004  * See COPYING in top-level directory.
0005  */
0006 
0007 /** \file
0008  * \brief Memory node attributes.
0009  */
0010 
0011 #ifndef HWLOC_MEMATTR_H
0012 #define HWLOC_MEMATTR_H
0013 
0014 #include "hwloc.h"
0015 
0016 #ifdef __cplusplus
0017 extern "C" {
0018 #elif 0
0019 }
0020 #endif
0021 
0022 /** \defgroup hwlocality_memattrs Comparing memory node attributes for finding where to allocate on
0023  *
0024  * Platforms with heterogeneous memory require ways to decide whether
0025  * a buffer should be allocated on "fast" memory (such as HBM),
0026  * "normal" memory (DDR) or even "slow" but large-capacity memory
0027  * (non-volatile memory).
0028  * These memory nodes are called "Targets" while the CPU accessing them
0029  * is called the "Initiator". Access performance depends on their
0030  * locality (NUMA platforms) as well as the intrinsic performance
0031  * of the targets (heterogeneous platforms).
0032  *
0033  * The following attributes describe the performance of memory accesses
0034  * from an Initiator to a memory Target, for instance their latency
0035  * or bandwidth.
0036  * Initiators performing these memory accesses are usually some PUs or Cores
0037  * (described as a CPU set).
0038  * Hence a Core may choose where to allocate a memory buffer by comparing
0039  * the attributes of different target memory nodes nearby.
0040  *
0041  * There are also some attributes that are system-wide.
0042  * Their value does not depend on a specific initiator performing
0043  * an access.
0044  * The memory node Capacity is an example of such attribute without
0045  * initiator.
0046  *
0047  * One way to use this API is to start with a cpuset describing the Cores where
0048  * a program is bound. The best target NUMA node for allocating memory in this
0049  * program on these Cores may be obtained by passing this cpuset as an initiator
0050  * to hwloc_memattr_get_best_target() with the relevant memory attribute.
0051  * For instance, if the code is latency limited, use the Latency attribute.
0052  *
0053  * A more flexible approach consists in getting the list of local NUMA nodes
0054  * by passing this cpuset to hwloc_get_local_numanode_objs().
0055  * Attribute values for these nodes, if any, may then be obtained with
0056  * hwloc_memattr_get_value() and manually compared with the desired criteria.
0057  *
0058  * Memory attributes are also used internally to build Memory Tiers which provide
0059  * an easy way to distinguish NUMA nodes of different kinds, as explained
0060  * in \ref heteromem.
0061  *
0062  * Beside tiers, hwloc defines a set of "default" nodes where normal memory
0063  * allocations should be made from (see hwloc_topology_get_default_nodeset()).
0064  * This is also useful for dividing the machine into a set of non-overlapping
0065  * NUMA domains, for instance for binding tasks per domain.
0066  *
0067  * \sa An example is available in doc/examples/memory-attributes.c in the source tree.
0068  *
0069  * \note The API also supports specific objects as initiator,
0070  * but it is currently not used internally by hwloc.
0071  * Users may for instance use it to provide custom performance
0072  * values for host memory accesses performed by GPUs.
0073  *
0074  * \note The interface actually also accepts targets that are not NUMA nodes.
0075  * @{
0076  */
0077 
0078 /** \brief Predefined memory attribute IDs.
0079  * See ::hwloc_memattr_id_t for the generic definition of IDs
0080  * for predefined or custom attributes.
0081  */
0082 enum hwloc_memattr_id_e {
0083   /** \brief
0084    * The \"Capacity\" is returned in bytes (local_memory attribute in objects).
0085    *
0086    * Best capacity nodes are nodes with <b>higher capacity</b>.
0087    *
0088    * No initiator is involved when looking at this attribute.
0089    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
0090    *
0091    * Capacity values may not be modified using hwloc_memattr_set_value().
0092    * \hideinitializer
0093    */
0094   HWLOC_MEMATTR_ID_CAPACITY = 0,
0095 
0096   /** \brief
0097    * The \"Locality\" is returned as the number of PUs in that locality
0098    * (e.g. the weight of its cpuset).
0099    *
0100    * Best locality nodes are nodes with <b>smaller locality</b>
0101    * (nodes that are local to very few PUs).
0102    * Poor locality nodes are nodes with larger locality
0103    * (nodes that are local to the entire machine).
0104    *
0105    * No initiator is involved when looking at this attribute.
0106    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
0107 
0108    * Locality values may not be modified using hwloc_memattr_set_value().
0109    * \hideinitializer
0110    */
0111   HWLOC_MEMATTR_ID_LOCALITY = 1,
0112 
0113   /** \brief
0114    * The \"Bandwidth\" is returned in MiB/s, as seen from the given initiator location.
0115    *
0116    * Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
0117    *
0118    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
0119    * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
0120    *
0121    * This is the average bandwidth for read and write accesses. If the platform
0122    * provides individual read and write bandwidths but no explicit average value,
0123    * hwloc computes and returns the average.
0124    * \hideinitializer
0125    */
0126   HWLOC_MEMATTR_ID_BANDWIDTH = 2,
0127 
0128   /** \brief
0129    * The \"ReadBandwidth\" is returned in MiB/s, as seen from the given initiator location.
0130    *
0131    * Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
0132    *
0133    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
0134    * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
0135    * \hideinitializer
0136    */
0137   HWLOC_MEMATTR_ID_READ_BANDWIDTH = 4,
0138 
0139   /** \brief
0140    * The \"WriteBandwidth\" is returned in MiB/s, as seen from the given initiator location.
0141    *
0142    * Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
0143    *
0144    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
0145    * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
0146    * \hideinitializer
0147    */
0148   HWLOC_MEMATTR_ID_WRITE_BANDWIDTH = 5,
0149 
0150   /** \brief
0151    * The \"Latency\" is returned as nanoseconds, as seen from the given initiator location.
0152    *
0153    * Best latency nodes are nodes with <b>smaller latency</b>.
0154    *
0155    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
0156    * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
0157    *
0158    * This is the average latency for read and write accesses. If the platform
0159    * provides individual read and write latencies but no explicit average value,
0160    * hwloc computes and returns the average.
0161    * \hideinitializer
0162    */
0163   HWLOC_MEMATTR_ID_LATENCY = 3,
0164 
0165   /** \brief
0166    * The \"ReadLatency\" is returned as nanoseconds, as seen from the given initiator location.
0167    *
0168    * Best latency nodes are nodes with <b>smaller latency</b>.
0169    *
0170    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
0171    * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
0172    * \hideinitializer
0173    */
0174   HWLOC_MEMATTR_ID_READ_LATENCY = 6,
0175 
0176   /** \brief
0177    * The \"WriteLatency\" is returned as nanoseconds, as seen from the given initiator location.
0178    *
0179    * Best latency nodes are nodes with <b>smaller latency</b>.
0180    *
0181    * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
0182    * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
0183    * \hideinitializer
0184    */
0185   HWLOC_MEMATTR_ID_WRITE_LATENCY = 7,
0186 
0187   /* TODO persistence? */
0188 
0189   HWLOC_MEMATTR_ID_MAX /**< \private
0190                         * Sentinel value for predefined attributes.
0191                         * Dynamically registered custom attributes start here.
0192                         */
0193 };
0194 
0195 /** \brief A memory attribute identifier.
0196  *
0197  * hwloc predefines some commonly-used attributes in ::hwloc_memattr_id_e.
0198  * One may then dynamically register custom ones with hwloc_memattr_register(),
0199  * they will be assigned IDs immediately after the predefined ones.
0200  * See \ref hwlocality_memattrs_manage for more information about
0201  * existing attribute IDs.
0202  */
0203 typedef unsigned hwloc_memattr_id_t;
0204 
0205 /** \brief Return the identifier of the memory attribute with the given name.
0206  *
0207  * \return 0 on success.
0208  * \return -1 with errno set to \c EINVAL if no such attribute exists.
0209  */
0210 HWLOC_DECLSPEC int
0211 hwloc_memattr_get_by_name(hwloc_topology_t topology,
0212                           const char *name,
0213                           hwloc_memattr_id_t *id);
0214 
0215 
0216 /** \brief Type of location. */
0217 enum hwloc_location_type_e {
0218   /** \brief Location is given as a cpuset, in the location cpuset union field. \hideinitializer */
0219   HWLOC_LOCATION_TYPE_CPUSET = 1,
0220   /** \brief Location is given as an object, in the location object union field. \hideinitializer */
0221   HWLOC_LOCATION_TYPE_OBJECT = 0
0222 };
0223 
0224 /** \brief Where to measure attributes from. */
0225 struct hwloc_location {
0226   /** \brief Type of location. */
0227   enum hwloc_location_type_e type;
0228   /** \brief Actual location. */
0229   union hwloc_location_u {
0230     /** \brief Location as a cpuset, when the location type is ::HWLOC_LOCATION_TYPE_CPUSET. */
0231     hwloc_cpuset_t cpuset;
0232     /** \brief Location as an object, when the location type is ::HWLOC_LOCATION_TYPE_OBJECT. */
0233     hwloc_obj_t object;
0234   } location;
0235 };
0236 
0237 
0238 /** \brief Flags for selecting target NUMA nodes. */
0239 enum hwloc_local_numanode_flag_e {
0240   /** \brief Select NUMA nodes whose locality is larger than the given cpuset.
0241    * For instance, if a single PU (or its cpuset) is given in \p initiator,
0242    * select all nodes close to the package that contains this PU.
0243    * \hideinitializer
0244    */
0245   HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY = (1UL<<0),
0246 
0247   /** \brief Select NUMA nodes whose locality is smaller than the given cpuset.
0248    * For instance, if a package (or its cpuset) is given in \p initiator,
0249    * also select nodes that are attached to only a half of that package.
0250    * \hideinitializer
0251    */
0252   HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY = (1UL<<1),
0253 
0254   /** \brief Select NUMA nodes whose locality intersects the given cpuset.
0255    * This includes larger and smaller localities as well as localities
0256    * that are partially included.
0257    * For instance, if the locality is one core of both packages, a NUMA node
0258    * local to one package is neither larger nor smaller than this locality,
0259    * but it intersects it.
0260    * \hideinitializer
0261    */
0262   HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY = (1UL<<3),
0263 
0264   /** \brief Select all NUMA nodes in the topology.
0265    * The initiator \p initiator is ignored.
0266    * \hideinitializer
0267    */
0268   HWLOC_LOCAL_NUMANODE_FLAG_ALL = (1UL<<2)
0269 };
0270 
0271 /** \brief Return an array of local NUMA nodes.
0272  *
0273  * By default only select the NUMA nodes whose locality is exactly
0274  * the given \p location. More nodes may be selected if additional flags
0275  * are given as a OR'ed set of ::hwloc_local_numanode_flag_e.
0276  *
0277  * If \p location is given as an explicit object, its CPU set is used
0278  * to find NUMA nodes with the corresponding locality.
0279  * If the object does not have a CPU set (e.g. I/O object), the CPU
0280  * parent (where the I/O object is attached) is used.
0281  *
0282  * On input, \p nr points to the number of nodes that may be stored
0283  * in the \p nodes array.
0284  * On output, \p nr will be changed to the number of stored nodes,
0285  * or the number of nodes that would have been stored if there were
0286  * enough room.
0287  *
0288  * \return 0 on success or -1 on error.
0289  *
0290  * \note Some of these NUMA nodes may not have any memory attribute
0291  * values and hence not be reported as actual targets in other functions.
0292  *
0293  * \note The number of NUMA nodes in the topology (obtained by
0294  * hwloc_bitmap_weight() on the root object nodeset) may be used
0295  * to allocate the \p nodes array.
0296  *
0297  * \note When an object CPU set is given as locality, for instance a Package,
0298  * and when flags contain both ::HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY
0299  * and ::HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY,
0300  * the returned array corresponds to the nodeset of that object.
0301  */
0302 HWLOC_DECLSPEC int
0303 hwloc_get_local_numanode_objs(hwloc_topology_t topology,
0304                               struct hwloc_location *location,
0305                               unsigned *nr,
0306                               hwloc_obj_t *nodes,
0307                               unsigned long flags);
0308 
0309 /** \brief Return the set of default NUMA nodes
0310  *
0311  * In machines with heterogeneous memory, some NUMA nodes are considered
0312  * the default ones, i.e. where basic allocations should be made from.
0313  * These are usually DRAM nodes.
0314  *
0315  * Other nodes may be reserved for specific use (I/O device memory, e.g. GPU memory),
0316  * small but high performance (HBM), large but slow memory (NVM), etc.
0317  * Buffers should usually not be allocated from there unless explicitly required.
0318  *
0319  * This function fills \p nodeset with the bits of NUMA nodes considered default.
0320  *
0321  * It is guaranteed that these nodes have non-intersecting CPU sets,
0322  * i.e. cores may not have multiple local NUMA nodes anymore.
0323  * Hence this may be used to iterate over the platform divided into separate
0324  * NUMA localities, for instance for binding one task per NUMA domain.
0325  *
0326  * Any core that had some local NUMA node(s) in the initial topology should
0327  * still have one in the default nodeset. Corner cases where this would be
0328  * wrong consist in asymmetric platforms with missing DRAM nodes, or topologies
0329  * that were already restricted to less NUMA nodes.
0330  *
0331  * The returned nodeset may be passed to hwloc_topology_restrict() with
0332  * ::HWLOC_RESTRICT_FLAG_BYNODESET to remove all non-default nodes from
0333  * the topology. The resulting topology will be easier to use when iterating
0334  * over (now homogeneous) NUMA nodes.
0335  *
0336  * The heuristics for finding default nodes relies on memory tiers and subtypes
0337  * (see \ref heteromem) as well as the assumption that hardware vendors list
0338  * default nodes first in hardware tables.
0339  *
0340  * \p flags must be \c 0 for now.
0341  *
0342  * \return 0 on success.
0343  * \return -1 on error.
0344  *
0345  * \note The returned nodeset usually contains all nodes from a single memory
0346  * tier, likely the DRAM one.
0347  *
0348  * \note The returned nodeset is included in the list of available nodes
0349  * returned by hwloc_topology_get_topology_nodeset(). It is strictly smaller
0350  * if the machine has heterogeneous memory.
0351  *
0352  * \note The heuristics may return a suboptimal set of nodes if hwloc could
0353  * not guess memory types and/or if some default nodes were removed earlier
0354  * from the topology (e.g. with hwloc_topology_restrict()).
0355  */
0356 HWLOC_DECLSPEC int
0357 hwloc_topology_get_default_nodeset(hwloc_topology_t topology,
0358                                    hwloc_nodeset_t nodeset,
0359                                    unsigned long flags);
0360 
0361 /** \brief Return an attribute value for a specific target NUMA node.
0362  *
0363  * If the attribute does not relate to a specific initiator
0364  * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
0365  * location \p initiator is ignored and may be \c NULL.
0366  *
0367  * \p target_node cannot be \c NULL. If \p attribute is ::HWLOC_MEMATTR_ID_CAPACITY,
0368  * \p target_node must be a NUMA node. If it is ::HWLOC_MEMATTR_ID_LOCALITY,
0369  * \p target_node must have a CPU set.
0370  *
0371  * \p flags must be \c 0 for now.
0372  *
0373  * \return 0 on success.
0374  * \return -1 on error, for instance with errno set to \c EINVAL if flags
0375  * are invalid or no such attribute exists.
0376  *
0377  * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
0378  * when refering to accesses performed by CPU cores.
0379  * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
0380  * but users may for instance use it to provide custom information about
0381  * host memory accesses performed by GPUs.
0382  */
0383 HWLOC_DECLSPEC int
0384 hwloc_memattr_get_value(hwloc_topology_t topology,
0385                         hwloc_memattr_id_t attribute,
0386                         hwloc_obj_t target_node,
0387                         struct hwloc_location *initiator,
0388                         unsigned long flags,
0389                         hwloc_uint64_t *value);
0390 
0391 /** \brief Return the best target NUMA node for the given attribute and initiator.
0392  *
0393  * If the attribute does not relate to a specific initiator
0394  * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
0395  * location \p initiator is ignored and may be \c NULL.
0396  *
0397  * If \p value is non \c NULL, the corresponding value is returned there.
0398  *
0399  * If multiple targets have the same attribute values, only one is
0400  * returned (and there is no way to clarify how that one is chosen).
0401  * Applications that want to detect targets with identical/similar
0402  * values, or that want to look at values for multiple attributes,
0403  * should rather get all values using hwloc_memattr_get_value()
0404  * and manually select the target they consider the best.
0405  *
0406  * \p flags must be \c 0 for now.
0407  *
0408  * \return 0 on success.
0409  * \return -1 with errno set to \c ENOENT if there are no matching targets.
0410  * \return -1 with errno set to \c EINVAL if flags are invalid,
0411  * or no such attribute exists.
0412  *
0413  * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
0414  * when refering to accesses performed by CPU cores.
0415  * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
0416  * but users may for instance use it to provide custom information about
0417  * host memory accesses performed by GPUs.
0418  */
0419 HWLOC_DECLSPEC int
0420 hwloc_memattr_get_best_target(hwloc_topology_t topology,
0421                               hwloc_memattr_id_t attribute,
0422                               struct hwloc_location *initiator,
0423                               unsigned long flags,
0424                               hwloc_obj_t *best_target, hwloc_uint64_t *value);
0425 
0426 /** \brief Return the best initiator for the given attribute and target NUMA node.
0427  *
0428  * If \p value is non \c NULL, the corresponding value is returned there.
0429  *
0430  * If multiple initiators have the same attribute values, only one is
0431  * returned (and there is no way to clarify how that one is chosen).
0432  * Applications that want to detect initiators with identical/similar
0433  * values, or that want to look at values for multiple attributes,
0434  * should rather get all values using hwloc_memattr_get_value()
0435  * and manually select the initiator they consider the best.
0436  *
0437  * The returned initiator should not be modified or freed,
0438  * it belongs to the topology.
0439  *
0440  * \p target_node cannot be \c NULL.
0441  *
0442  * \p flags must be \c 0 for now.
0443  *
0444  * \return 0 on success.
0445  * \return -1 with errno set to \c ENOENT if there are no matching initiators.
0446  * \return -1 with errno set to \c EINVAL if the attribute does not relate to a specific initiator
0447  * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
0448  */
0449 HWLOC_DECLSPEC int
0450 hwloc_memattr_get_best_initiator(hwloc_topology_t topology,
0451                                  hwloc_memattr_id_t attribute,
0452                                  hwloc_obj_t target_node,
0453                                  unsigned long flags,
0454                                  struct hwloc_location *best_initiator, hwloc_uint64_t *value);
0455 
0456 /** \brief Return the target NUMA nodes that have some values for a given attribute.
0457  *
0458  * Return targets for the given attribute in the \p targets array
0459  * (for the given initiator if any).
0460  * If \p values is not \c NULL, the corresponding attribute values
0461  * are stored in the array it points to.
0462  *
0463  * On input, \p nr points to the number of targets that may be stored
0464  * in the array \p targets (and \p values).
0465  * On output, \p nr points to the number of targets (and values) that
0466  * were actually found, even if some of them couldn't be stored in the array.
0467  * Targets that couldn't be stored are ignored, but the function still
0468  * returns success (\c 0). The caller may find out by comparing the value pointed
0469  * by \p nr before and after the function call.
0470  *
0471  * The returned targets should not be modified or freed,
0472  * they belong to the topology.
0473  *
0474  * Argument \p initiator is ignored if the attribute does not relate to a specific
0475  * initiator (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
0476  * Otherwise \p initiator may be non \c NULL to report only targets
0477  * that have a value for that initiator.
0478  *
0479  * \p flags must be \c 0 for now.
0480  *
0481  * \note This function is meant for tools and debugging (listing internal information)
0482  * rather than for application queries. Applications should rather select useful
0483  * NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
0484  * values.
0485  *
0486  * \return 0 on success or -1 on error.
0487  *
0488  * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
0489  * when referring to accesses performed by CPU cores.
0490  * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
0491  * but users may for instance use it to provide custom information about
0492  * host memory accesses performed by GPUs.
0493  */
0494 HWLOC_DECLSPEC int
0495 hwloc_memattr_get_targets(hwloc_topology_t topology,
0496                           hwloc_memattr_id_t attribute,
0497                           struct hwloc_location *initiator,
0498                           unsigned long flags,
0499                           unsigned *nr, hwloc_obj_t *targets, hwloc_uint64_t *values);
0500 
0501 /** \brief Return the initiators that have values for a given attribute for a specific target NUMA node.
0502  *
0503  * Return initiators for the given attribute and target node in the
0504  * \p initiators array.
0505  * If \p values is not \c NULL, the corresponding attribute values
0506  * are stored in the array it points to.
0507  *
0508  * On input, \p nr points to the number of initiators that may be stored
0509  * in the array \p initiators (and \p values).
0510  * On output, \p nr points to the number of initiators (and values) that
0511  * were actually found, even if some of them couldn't be stored in the array.
0512  * Initiators that couldn't be stored are ignored, but the function still
0513  * returns success (\c 0). The caller may find out by comparing the value pointed
0514  * by \p nr before and after the function call.
0515  *
0516  * The returned initiators should not be modified or freed,
0517  * they belong to the topology.
0518  *
0519  * \p target_node cannot be \c NULL.
0520  *
0521  * \p flags must be \c 0 for now.
0522  *
0523  * If the attribute does not relate to a specific initiator
0524  * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
0525  * no initiator is returned.
0526  *
0527  * \return 0 on success or -1 on error.
0528  *
0529  * \note This function is meant for tools and debugging (listing internal information)
0530  * rather than for application queries. Applications should rather select useful
0531  * NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
0532  * values for some relevant initiators.
0533  */
0534 HWLOC_DECLSPEC int
0535 hwloc_memattr_get_initiators(hwloc_topology_t topology,
0536                              hwloc_memattr_id_t attribute,
0537                              hwloc_obj_t target_node,
0538                              unsigned long flags,
0539                              unsigned *nr, struct hwloc_location *initiators, hwloc_uint64_t *values);
0540 
0541 /** @} */
0542 
0543 
0544 /** \defgroup hwlocality_memattrs_manage Managing memory attributes
0545  *
0546  * Memory attribues are identified by an ID (::hwloc_memattr_id_t)
0547  * and a name. hwloc_memattr_get_name() and hwloc_memattr_get_by_name()
0548  * convert between them (or return error if the attribute does not exist).
0549  *
0550  * The set of valid ::hwloc_memattr_id_t is a contigous set starting at \c 0.
0551  * It first contains predefined attributes, as listed
0552  * in ::hwloc_memattr_id_e (from \c 0 to \c HWLOC_MEMATTR_ID_MAX-1).
0553  * Then custom attributes may be dynamically registered with
0554  * hwloc_memattr_register(). They will get the following IDs
0555  * (\c HWLOC_MEMATTR_ID_MAX for the first one, etc.).
0556  *
0557  * To iterate over all valid attributes
0558  * (either predefined or dynamically registered custom ones),
0559  * one may iterate over IDs starting from \c 0 until hwloc_memattr_get_name()
0560  * or hwloc_memattr_get_flags() returns an error.
0561  *
0562  * The values for an existing attribute or for custom dynamically registered ones
0563  * may be set or modified with hwloc_memattr_set_value().
0564  *
0565  * @{
0566  */
0567 
0568 /** \brief Return the name of a memory attribute.
0569  *
0570  * The output pointer \p name cannot be \c NULL.
0571  *
0572  * \return 0 on success.
0573  * \return -1 with errno set to \c EINVAL if the attribute does not exist.
0574  */
0575 HWLOC_DECLSPEC int
0576 hwloc_memattr_get_name(hwloc_topology_t topology,
0577                        hwloc_memattr_id_t attribute,
0578                        const char **name);
0579 
0580 /** \brief Return the flags of the given attribute.
0581  *
0582  * Flags are a OR'ed set of ::hwloc_memattr_flag_e.
0583  *
0584  * The output pointer \p flags cannot be \c NULL.
0585  *
0586  * \return 0 on success.
0587  * \return -1 with errno set to \c EINVAL if the attribute does not exist.
0588  */
0589 HWLOC_DECLSPEC int
0590 hwloc_memattr_get_flags(hwloc_topology_t topology,
0591                         hwloc_memattr_id_t attribute,
0592                         unsigned long *flags);
0593 
0594 /** \brief Memory attribute flags.
0595  * Given to hwloc_memattr_register() and returned by hwloc_memattr_get_flags().
0596  */
0597 enum hwloc_memattr_flag_e {
0598   /** \brief The best nodes for this memory attribute are those with the higher values.
0599    * For instance Bandwidth.
0600    */
0601   HWLOC_MEMATTR_FLAG_HIGHER_FIRST = (1UL<<0),
0602   /** \brief The best nodes for this memory attribute are those with the lower values.
0603    * For instance Latency.
0604    */
0605   HWLOC_MEMATTR_FLAG_LOWER_FIRST = (1UL<<1),
0606   /** \brief The value returned for this memory attribute depends on the given initiator.
0607    * For instance Bandwidth and Latency, but not Capacity.
0608    */
0609   HWLOC_MEMATTR_FLAG_NEED_INITIATOR = (1UL<<2)
0610 };
0611 
0612 /** \brief Register a new memory attribute.
0613  *
0614  * Add a new custom memory attribute.
0615  * Flags are a OR'ed set of ::hwloc_memattr_flag_e. It must contain one of
0616  * ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST or ::HWLOC_MEMATTR_FLAG_LOWER_FIRST but not both.
0617  *
0618  * The new attribute \p id is immediately after the last existing attribute ID
0619  * (which is either the ID of the last registered attribute if any,
0620  * or the ID of the last predefined attribute in ::hwloc_memattr_id_e).
0621  *
0622  * \return 0 on success.
0623  * \return -1 with errno set to \c EINVAL if an invalid set of flags is given.
0624  * \return -1 with errno set to \c EBUSY if another attribute already uses this name.
0625  */
0626 HWLOC_DECLSPEC int
0627 hwloc_memattr_register(hwloc_topology_t topology,
0628                        const char *name,
0629                        unsigned long flags,
0630                        hwloc_memattr_id_t *id);
0631 
0632 /** \brief Set an attribute value for a specific target NUMA node.
0633  *
0634  * If the attribute does not relate to a specific initiator
0635  * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
0636  * location \p initiator is ignored and may be \c NULL.
0637  *
0638  * The initiator will be copied into the topology,
0639  * the caller should free anything allocated to store the initiator,
0640  * for instance the cpuset.
0641  *
0642  * \p target_node cannot be \c NULL.
0643  *
0644  * \p attribute cannot be ::HWLOC_MEMATTR_ID_CAPACITY or
0645  * ::HWLOC_MEMATTR_ID_LOCALITY.
0646  *
0647  * \p flags must be \c 0 for now.
0648  *
0649  * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
0650  * when referring to accesses performed by CPU cores.
0651  * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
0652  * but users may for instance use it to provide custom information about
0653  * host memory accesses performed by GPUs.
0654  *
0655  * \return 0 on success or -1 on error.
0656  */
0657 HWLOC_DECLSPEC int
0658 hwloc_memattr_set_value(hwloc_topology_t topology,
0659                         hwloc_memattr_id_t attribute,
0660                         hwloc_obj_t target_node,
0661                         struct hwloc_location *initiator,
0662                         unsigned long flags,
0663                         hwloc_uint64_t value);
0664 
0665 /** @} */
0666 
0667 #ifdef __cplusplus
0668 } /* extern "C" */
0669 #endif
0670 
0671 
0672 #endif /* HWLOC_MEMATTR_H */