| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- /*
- * Copyright © 2019-2023 Inria. All rights reserved.
- * See COPYING in top-level directory.
- */
- /** \file
- * \brief Memory node attributes.
- */
- #ifndef HWLOC_MEMATTR_H
- #define HWLOC_MEMATTR_H
- #include "hwloc.h"
- #ifdef __cplusplus
- extern "C" {
- #elif 0
- }
- #endif
- /** \defgroup hwlocality_memattrs Comparing memory node attributes for finding where to allocate on
- *
- * Platforms with heterogeneous memory require ways to decide whether
- * a buffer should be allocated on "fast" memory (such as HBM),
- * "normal" memory (DDR) or even "slow" but large-capacity memory
- * (non-volatile memory).
- * These memory nodes are called "Targets" while the CPU accessing them
- * is called the "Initiator". Access performance depends on their
- * locality (NUMA platforms) as well as the intrinsic performance
- * of the targets (heterogeneous platforms).
- *
- * The following attributes describe the performance of memory accesses
- * from an Initiator to a memory Target, for instance their latency
- * or bandwidth.
- * Initiators performing these memory accesses are usually some PUs or Cores
- * (described as a CPU set).
- * Hence a Core may choose where to allocate a memory buffer by comparing
- * the attributes of different target memory nodes nearby.
- *
- * There are also some attributes that are system-wide.
- * Their value does not depend on a specific initiator performing
- * an access.
- * The memory node Capacity is an example of such attribute without
- * initiator.
- *
- * One way to use this API is to start with a cpuset describing the Cores where
- * a program is bound. The best target NUMA node for allocating memory in this
- * program on these Cores may be obtained by passing this cpuset as an initiator
- * to hwloc_memattr_get_best_target() with the relevant memory attribute.
- * For instance, if the code is latency limited, use the Latency attribute.
- *
- * A more flexible approach consists in getting the list of local NUMA nodes
- * by passing this cpuset to hwloc_get_local_numanode_objs().
- * Attribute values for these nodes, if any, may then be obtained with
- * hwloc_memattr_get_value() and manually compared with the desired criteria.
- *
- * \sa An example is available in doc/examples/memory-attributes.c in the source tree.
- *
- * \note The API also supports specific objects as initiator,
- * but it is currently not used internally by hwloc.
- * Users may for instance use it to provide custom performance
- * values for host memory accesses performed by GPUs.
- *
- * \note The interface actually also accepts targets that are not NUMA nodes.
- * @{
- */
- /** \brief Memory node attributes. */
- enum hwloc_memattr_id_e {
- /** \brief
- * The \"Capacity\" is returned in bytes (local_memory attribute in objects).
- *
- * Best capacity nodes are nodes with <b>higher capacity</b>.
- *
- * No initiator is involved when looking at this attribute.
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_CAPACITY = 0,
- /** \brief
- * The \"Locality\" is returned as the number of PUs in that locality
- * (e.g. the weight of its cpuset).
- *
- * Best locality nodes are nodes with <b>smaller locality</b>
- * (nodes that are local to very few PUs).
- * Poor locality nodes are nodes with larger locality
- * (nodes that are local to the entire machine).
- *
- * No initiator is involved when looking at this attribute.
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_LOCALITY = 1,
- /** \brief
- * The \"Bandwidth\" is returned in MiB/s, as seen from the given initiator location.
- *
- * Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
- *
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
- * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
- *
- * This is the average bandwidth for read and write accesses. If the platform
- * provides individual read and write bandwidths but no explicit average value,
- * hwloc computes and returns the average.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_BANDWIDTH = 2,
- /** \brief
- * The \"ReadBandwidth\" is returned in MiB/s, as seen from the given initiator location.
- *
- * Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
- *
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
- * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_READ_BANDWIDTH = 4,
- /** \brief
- * The \"WriteBandwidth\" is returned in MiB/s, as seen from the given initiator location.
- *
- * Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
- *
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
- * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_WRITE_BANDWIDTH = 5,
- /** \brief
- * The \"Latency\" is returned as nanoseconds, as seen from the given initiator location.
- *
- * Best latency nodes are nodes with <b>smaller latency</b>.
- *
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
- * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
- *
- * This is the average latency for read and write accesses. If the platform
- * provides individual read and write latencies but no explicit average value,
- * hwloc computes and returns the average.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_LATENCY = 3,
- /** \brief
- * The \"ReadLatency\" is returned as nanoseconds, as seen from the given initiator location.
- *
- * Best latency nodes are nodes with <b>smaller latency</b>.
- *
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
- * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_READ_LATENCY = 6,
- /** \brief
- * The \"WriteLatency\" is returned as nanoseconds, as seen from the given initiator location.
- *
- * Best latency nodes are nodes with <b>smaller latency</b>.
- *
- * The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
- * and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
- * \hideinitializer
- */
- HWLOC_MEMATTR_ID_WRITE_LATENCY = 7,
- /* TODO persistence? */
- HWLOC_MEMATTR_ID_MAX /**< \private Sentinel value */
- };
- /** \brief A memory attribute identifier.
- * May be either one of ::hwloc_memattr_id_e or a new id returned by hwloc_memattr_register().
- */
- typedef unsigned hwloc_memattr_id_t;
- /** \brief Return the identifier of the memory attribute with the given name.
- *
- * \return 0 on success.
- * \return -1 with errno set to \c EINVAL if no such attribute exists.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_by_name(hwloc_topology_t topology,
- const char *name,
- hwloc_memattr_id_t *id);
- /** \brief Type of location. */
- enum hwloc_location_type_e {
- /** \brief Location is given as a cpuset, in the location cpuset union field. \hideinitializer */
- HWLOC_LOCATION_TYPE_CPUSET = 1,
- /** \brief Location is given as an object, in the location object union field. \hideinitializer */
- HWLOC_LOCATION_TYPE_OBJECT = 0
- };
- /** \brief Where to measure attributes from. */
- struct hwloc_location {
- /** \brief Type of location. */
- enum hwloc_location_type_e type;
- /** \brief Actual location. */
- union hwloc_location_u {
- /** \brief Location as a cpuset, when the location type is ::HWLOC_LOCATION_TYPE_CPUSET. */
- hwloc_cpuset_t cpuset;
- /** \brief Location as an object, when the location type is ::HWLOC_LOCATION_TYPE_OBJECT. */
- hwloc_obj_t object;
- } location;
- };
- /** \brief Flags for selecting target NUMA nodes. */
- enum hwloc_local_numanode_flag_e {
- /** \brief Select NUMA nodes whose locality is larger than the given cpuset.
- * For instance, if a single PU (or its cpuset) is given in \p initiator,
- * select all nodes close to the package that contains this PU.
- * \hideinitializer
- */
- HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY = (1UL<<0),
- /** \brief Select NUMA nodes whose locality is smaller than the given cpuset.
- * For instance, if a package (or its cpuset) is given in \p initiator,
- * also select nodes that are attached to only a half of that package.
- * \hideinitializer
- */
- HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY = (1UL<<1),
- /** \brief Select all NUMA nodes in the topology.
- * The initiator \p initiator is ignored.
- * \hideinitializer
- */
- HWLOC_LOCAL_NUMANODE_FLAG_ALL = (1UL<<2)
- };
- /** \brief Return an array of local NUMA nodes.
- *
- * By default only select the NUMA nodes whose locality is exactly
- * the given \p location. More nodes may be selected if additional flags
- * are given as a OR'ed set of ::hwloc_local_numanode_flag_e.
- *
- * If \p location is given as an explicit object, its CPU set is used
- * to find NUMA nodes with the corresponding locality.
- * If the object does not have a CPU set (e.g. I/O object), the CPU
- * parent (where the I/O object is attached) is used.
- *
- * On input, \p nr points to the number of nodes that may be stored
- * in the \p nodes array.
- * On output, \p nr will be changed to the number of stored nodes,
- * or the number of nodes that would have been stored if there were
- * enough room.
- *
- * \return 0 on success or -1 on error.
- *
- * \note Some of these NUMA nodes may not have any memory attribute
- * values and hence not be reported as actual targets in other functions.
- *
- * \note The number of NUMA nodes in the topology (obtained by
- * hwloc_bitmap_weight() on the root object nodeset) may be used
- * to allocate the \p nodes array.
- *
- * \note When an object CPU set is given as locality, for instance a Package,
- * and when flags contain both ::HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY
- * and ::HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY,
- * the returned array corresponds to the nodeset of that object.
- */
- HWLOC_DECLSPEC int
- hwloc_get_local_numanode_objs(hwloc_topology_t topology,
- struct hwloc_location *location,
- unsigned *nr,
- hwloc_obj_t *nodes,
- unsigned long flags);
- /** \brief Return an attribute value for a specific target NUMA node.
- *
- * If the attribute does not relate to a specific initiator
- * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
- * location \p initiator is ignored and may be \c NULL.
- *
- * \p flags must be \c 0 for now.
- *
- * \return 0 on success.
- * \return -1 on error, for instance with errno set to \c EINVAL if flags
- * are invalid or no such attribute exists.
- *
- * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
- * when refering to accesses performed by CPU cores.
- * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
- * but users may for instance use it to provide custom information about
- * host memory accesses performed by GPUs.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_value(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- hwloc_obj_t target_node,
- struct hwloc_location *initiator,
- unsigned long flags,
- hwloc_uint64_t *value);
- /** \brief Return the best target NUMA node for the given attribute and initiator.
- *
- * If the attribute does not relate to a specific initiator
- * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
- * location \p initiator is ignored and may be \c NULL.
- *
- * If \p value is non \c NULL, the corresponding value is returned there.
- *
- * If multiple targets have the same attribute values, only one is
- * returned (and there is no way to clarify how that one is chosen).
- * Applications that want to detect targets with identical/similar
- * values, or that want to look at values for multiple attributes,
- * should rather get all values using hwloc_memattr_get_value()
- * and manually select the target they consider the best.
- *
- * \p flags must be \c 0 for now.
- *
- * \return 0 on success.
- * \return -1 with errno set to \c ENOENT if there are no matching targets.
- * \return -1 with errno set to \c EINVAL if flags are invalid,
- * or no such attribute exists.
- *
- * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
- * when refering to accesses performed by CPU cores.
- * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
- * but users may for instance use it to provide custom information about
- * host memory accesses performed by GPUs.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_best_target(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- struct hwloc_location *initiator,
- unsigned long flags,
- hwloc_obj_t *best_target, hwloc_uint64_t *value);
- /** \brief Return the best initiator for the given attribute and target NUMA node.
- *
- * If \p value is non \c NULL, the corresponding value is returned there.
- *
- * If multiple initiators have the same attribute values, only one is
- * returned (and there is no way to clarify how that one is chosen).
- * Applications that want to detect initiators with identical/similar
- * values, or that want to look at values for multiple attributes,
- * should rather get all values using hwloc_memattr_get_value()
- * and manually select the initiator they consider the best.
- *
- * The returned initiator should not be modified or freed,
- * it belongs to the topology.
- *
- * \p flags must be \c 0 for now.
- *
- * \return 0 on success.
- * \return -1 with errno set to \c ENOENT if there are no matching initiators.
- * \return -1 with errno set to \c EINVAL if the attribute does not relate to a specific initiator
- * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_best_initiator(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- hwloc_obj_t target,
- unsigned long flags,
- struct hwloc_location *best_initiator, hwloc_uint64_t *value);
- /** @} */
- /** \defgroup hwlocality_memattrs_manage Managing memory attributes
- * @{
- */
- /** \brief Return the name of a memory attribute.
- *
- * \return 0 on success.
- * \return -1 with errno set to \c EINVAL if the attribute does not exist.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_name(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- const char **name);
- /** \brief Return the flags of the given attribute.
- *
- * Flags are a OR'ed set of ::hwloc_memattr_flag_e.
- *
- * \return 0 on success.
- * \return -1 with errno set to \c EINVAL if the attribute does not exist.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_flags(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- unsigned long *flags);
- /** \brief Memory attribute flags.
- * Given to hwloc_memattr_register() and returned by hwloc_memattr_get_flags().
- */
- enum hwloc_memattr_flag_e {
- /** \brief The best nodes for this memory attribute are those with the higher values.
- * For instance Bandwidth.
- */
- HWLOC_MEMATTR_FLAG_HIGHER_FIRST = (1UL<<0),
- /** \brief The best nodes for this memory attribute are those with the lower values.
- * For instance Latency.
- */
- HWLOC_MEMATTR_FLAG_LOWER_FIRST = (1UL<<1),
- /** \brief The value returned for this memory attribute depends on the given initiator.
- * For instance Bandwidth and Latency, but not Capacity.
- */
- HWLOC_MEMATTR_FLAG_NEED_INITIATOR = (1UL<<2)
- };
- /** \brief Register a new memory attribute.
- *
- * Add a specific memory attribute that is not defined in ::hwloc_memattr_id_e.
- * Flags are a OR'ed set of ::hwloc_memattr_flag_e. It must contain at least
- * one of ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST or ::HWLOC_MEMATTR_FLAG_LOWER_FIRST.
- *
- * \return 0 on success.
- * \return -1 with errno set to \c EBUSY if another attribute already uses this name.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_register(hwloc_topology_t topology,
- const char *name,
- unsigned long flags,
- hwloc_memattr_id_t *id);
- /** \brief Set an attribute value for a specific target NUMA node.
- *
- * If the attribute does not relate to a specific initiator
- * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
- * location \p initiator is ignored and may be \c NULL.
- *
- * The initiator will be copied into the topology,
- * the caller should free anything allocated to store the initiator,
- * for instance the cpuset.
- *
- * \p flags must be \c 0 for now.
- *
- * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
- * when referring to accesses performed by CPU cores.
- * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
- * but users may for instance use it to provide custom information about
- * host memory accesses performed by GPUs.
- *
- * \return 0 on success or -1 on error.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_set_value(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- hwloc_obj_t target_node,
- struct hwloc_location *initiator,
- unsigned long flags,
- hwloc_uint64_t value);
- /** \brief Return the target NUMA nodes that have some values for a given attribute.
- *
- * Return targets for the given attribute in the \p targets array
- * (for the given initiator if any).
- * If \p values is not \c NULL, the corresponding attribute values
- * are stored in the array it points to.
- *
- * On input, \p nr points to the number of targets that may be stored
- * in the array \p targets (and \p values).
- * On output, \p nr points to the number of targets (and values) that
- * were actually found, even if some of them couldn't be stored in the array.
- * Targets that couldn't be stored are ignored, but the function still
- * returns success (\c 0). The caller may find out by comparing the value pointed
- * by \p nr before and after the function call.
- *
- * The returned targets should not be modified or freed,
- * they belong to the topology.
- *
- * Argument \p initiator is ignored if the attribute does not relate to a specific
- * initiator (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
- * Otherwise \p initiator may be non \c NULL to report only targets
- * that have a value for that initiator.
- *
- * \p flags must be \c 0 for now.
- *
- * \note This function is meant for tools and debugging (listing internal information)
- * rather than for application queries. Applications should rather select useful
- * NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
- * values.
- *
- * \return 0 on success or -1 on error.
- *
- * \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
- * when referring to accesses performed by CPU cores.
- * ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
- * but users may for instance use it to provide custom information about
- * host memory accesses performed by GPUs.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_targets(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- struct hwloc_location *initiator,
- unsigned long flags,
- unsigned *nr, hwloc_obj_t *targets, hwloc_uint64_t *values);
- /** \brief Return the initiators that have values for a given attribute for a specific target NUMA node.
- *
- * Return initiators for the given attribute and target node in the
- * \p initiators array.
- * If \p values is not \c NULL, the corresponding attribute values
- * are stored in the array it points to.
- *
- * On input, \p nr points to the number of initiators that may be stored
- * in the array \p initiators (and \p values).
- * On output, \p nr points to the number of initiators (and values) that
- * were actually found, even if some of them couldn't be stored in the array.
- * Initiators that couldn't be stored are ignored, but the function still
- * returns success (\c 0). The caller may find out by comparing the value pointed
- * by \p nr before and after the function call.
- *
- * The returned initiators should not be modified or freed,
- * they belong to the topology.
- *
- * \p flags must be \c 0 for now.
- *
- * If the attribute does not relate to a specific initiator
- * (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
- * no initiator is returned.
- *
- * \return 0 on success or -1 on error.
- *
- * \note This function is meant for tools and debugging (listing internal information)
- * rather than for application queries. Applications should rather select useful
- * NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
- * values for some relevant initiators.
- */
- HWLOC_DECLSPEC int
- hwloc_memattr_get_initiators(hwloc_topology_t topology,
- hwloc_memattr_id_t attribute,
- hwloc_obj_t target_node,
- unsigned long flags,
- unsigned *nr, struct hwloc_location *initiators, hwloc_uint64_t *values);
- /** @} */
- #ifdef __cplusplus
- } /* extern "C" */
- #endif
- #endif /* HWLOC_MEMATTR_H */
|