| /* | |
| * Copyright © 2013-2020 Inria. All rights reserved. | |
| * See COPYING in top-level directory. | |
| */ | |
| /** \file | |
| * \brief Topology differences. | |
| */ | |
| extern "C" { | |
| } | |
| /** \defgroup hwlocality_diff Topology differences | |
| * | |
| * Applications that manipulate many similar topologies, for instance | |
| * one for each node of a homogeneous cluster, may want to compress | |
| * topologies to reduce the memory footprint. | |
| * | |
| * This file offers a way to manipulate the difference between topologies | |
| * and export/import it to/from XML. | |
| * Compression may therefore be achieved by storing one topology | |
| * entirely while the others are only described by their differences | |
| * with the former. | |
| * The actual topology can be reconstructed when actually needed by | |
| * applying the precomputed difference to the reference topology. | |
| * | |
| * This interface targets very similar nodes. | |
| * Only very simple differences between topologies are actually | |
| * supported, for instance a change in the memory size, the name | |
| * of the object, or some info attribute. | |
| * More complex differences such as adding or removing objects cannot | |
| * be represented in the difference structures and therefore return | |
| * errors. | |
| * Differences between object sets or topology-wide allowed sets, | |
| * cannot be represented either. | |
| * | |
| * It means that there is no need to apply the difference when | |
| * looking at the tree organization (how many levels, how many | |
| * objects per level, what kind of objects, CPU and node sets, etc) | |
| * and when binding to objects. | |
| * However the difference must be applied when looking at object | |
| * attributes such as the name, the memory size or info attributes. | |
| * | |
| * @{ | |
| */ | |
| /** \brief Type of one object attribute difference. | |
| */ | |
| typedef enum hwloc_topology_diff_obj_attr_type_e { | |
| /** \brief The object local memory is modified. | |
| * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_uint64_s | |
| * (and the index field is ignored). | |
| */ | |
| HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE, | |
| /** \brief The object name is modified. | |
| * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s | |
| * (and the name field is ignored). | |
| */ | |
| HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME, | |
| /** \brief the value of an info attribute is modified. | |
| * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s. | |
| */ | |
| HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO | |
| } hwloc_topology_diff_obj_attr_type_t; | |
| /** \brief One object attribute difference. | |
| */ | |
| union hwloc_topology_diff_obj_attr_u { | |
| struct hwloc_topology_diff_obj_attr_generic_s { | |
| /* each part of the union must start with these */ | |
| hwloc_topology_diff_obj_attr_type_t type; | |
| } generic; | |
| /** \brief Integer attribute modification with an optional index. */ | |
| struct hwloc_topology_diff_obj_attr_uint64_s { | |
| /* used for storing integer attributes */ | |
| hwloc_topology_diff_obj_attr_type_t type; | |
| hwloc_uint64_t index; /* not used for SIZE */ | |
| hwloc_uint64_t oldvalue; | |
| hwloc_uint64_t newvalue; | |
| } uint64; | |
| /** \brief String attribute modification with an optional name */ | |
| struct hwloc_topology_diff_obj_attr_string_s { | |
| /* used for storing name and info pairs */ | |
| hwloc_topology_diff_obj_attr_type_t type; | |
| char *name; /* not used for NAME */ | |
| char *oldvalue; | |
| char *newvalue; | |
| } string; | |
| }; | |
| /** \brief Type of one element of a difference list. | |
| */ | |
| typedef enum hwloc_topology_diff_type_e { | |
| /** \brief An object attribute was changed. | |
| * The union is a hwloc_topology_diff_u::hwloc_topology_diff_obj_attr_s. | |
| */ | |
| HWLOC_TOPOLOGY_DIFF_OBJ_ATTR, | |
| /** \brief The difference is too complex, | |
| * it cannot be represented. The difference below | |
| * this object has not been checked. | |
| * hwloc_topology_diff_build() will return 1. | |
| * | |
| * The union is a hwloc_topology_diff_u::hwloc_topology_diff_too_complex_s. | |
| */ | |
| HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX | |
| } hwloc_topology_diff_type_t; | |
| /** \brief One element of a difference list between two topologies. | |
| */ | |
| typedef union hwloc_topology_diff_u { | |
| struct hwloc_topology_diff_generic_s { | |
| /* each part of the union must start with these */ | |
| hwloc_topology_diff_type_t type; | |
| union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */ | |
| } generic; | |
| /* A difference in an object attribute. */ | |
| struct hwloc_topology_diff_obj_attr_s { | |
| hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */ | |
| union hwloc_topology_diff_u * next; | |
| /* List of attribute differences for a single object */ | |
| int obj_depth; | |
| unsigned obj_index; | |
| union hwloc_topology_diff_obj_attr_u diff; | |
| } obj_attr; | |
| /* A difference that is too complex. */ | |
| struct hwloc_topology_diff_too_complex_s { | |
| hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */ | |
| union hwloc_topology_diff_u * next; | |
| /* Where we had to stop computing the diff in the first topology */ | |
| int obj_depth; | |
| unsigned obj_index; | |
| } too_complex; | |
| } * hwloc_topology_diff_t; | |
| /** \brief Compute the difference between 2 topologies. | |
| * | |
| * The difference is stored as a list of ::hwloc_topology_diff_t entries | |
| * starting at \p diff. | |
| * It is computed by doing a depth-first traversal of both topology trees | |
| * simultaneously. | |
| * | |
| * If the difference between 2 objects is too complex to be represented | |
| * (for instance if some objects have different types, or different numbers | |
| * of children), a special diff entry of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX | |
| * is queued. | |
| * The computation of the diff does not continue below these objects. | |
| * So each such diff entry means that the difference between two subtrees | |
| * could not be computed. | |
| * | |
| * \return 0 if the difference can be represented properly. | |
| * | |
| * \return 0 with \p diff pointing to NULL if there is no difference | |
| * between the topologies. | |
| * | |
| * \return 1 if the difference is too complex (see above). Some entries in | |
| * the list will be of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX. | |
| * | |
| * \return -1 on any other error. | |
| * | |
| * \note \p flags is currently not used. It should be 0. | |
| * | |
| * \note The output diff has to be freed with hwloc_topology_diff_destroy(). | |
| * | |
| * \note The output diff can only be exported to XML or passed to | |
| * hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type | |
| * ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed. | |
| * | |
| * \note The output diff may be modified by removing some entries from | |
| * the list. The removed entries should be freed by passing them to | |
| * to hwloc_topology_diff_destroy() (possible as another list). | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff); | |
| /** \brief Flags to be given to hwloc_topology_diff_apply(). | |
| */ | |
| enum hwloc_topology_diff_apply_flags_e { | |
| /** \brief Apply topology diff in reverse direction. | |
| * \hideinitializer | |
| */ | |
| HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0) | |
| }; | |
| /** \brief Apply a topology diff to an existing topology. | |
| * | |
| * \p flags is an OR'ed set of ::hwloc_topology_diff_apply_flags_e. | |
| * | |
| * The new topology is modified in place. hwloc_topology_dup() | |
| * may be used to duplicate it before patching. | |
| * | |
| * If the difference cannot be applied entirely, all previous applied | |
| * elements are unapplied before returning. | |
| * | |
| * \return 0 on success. | |
| * | |
| * \return -N if applying the difference failed while trying | |
| * to apply the N-th part of the difference. For instance -1 | |
| * is returned if the very first difference element could not | |
| * be applied. | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags); | |
| /** \brief Destroy a list of topology differences. | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff); | |
| /** \brief Load a list of topology differences from a XML file. | |
| * | |
| * If not \c NULL, \p refname will be filled with the identifier | |
| * string of the reference topology for the difference file, | |
| * if any was specified in the XML file. | |
| * This identifier is usually the name of the other XML file | |
| * that contains the reference topology. | |
| * | |
| * \note the pointer returned in refname should later be freed | |
| * by the caller. | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(const char *xmlpath, hwloc_topology_diff_t *diff, char **refname); | |
| /** \brief Export a list of topology differences to a XML file. | |
| * | |
| * If not \c NULL, \p refname defines an identifier string | |
| * for the reference topology which was used as a base when | |
| * computing this difference. | |
| * This identifier is usually the name of the other XML file | |
| * that contains the reference topology. | |
| * This attribute is given back when reading the diff from XML. | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, const char *refname, const char *xmlpath); | |
| /** \brief Load a list of topology differences from a XML buffer. | |
| * | |
| * If not \c NULL, \p refname will be filled with the identifier | |
| * string of the reference topology for the difference file, | |
| * if any was specified in the XML file. | |
| * This identifier is usually the name of the other XML file | |
| * that contains the reference topology. | |
| * | |
| * \note the pointer returned in refname should later be freed | |
| * by the caller. | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname); | |
| /** \brief Export a list of topology differences to a XML buffer. | |
| * | |
| * If not \c NULL, \p refname defines an identifier string | |
| * for the reference topology which was used as a base when | |
| * computing this difference. | |
| * This identifier is usually the name of the other XML file | |
| * that contains the reference topology. | |
| * This attribute is given back when reading the diff from XML. | |
| * | |
| * The returned buffer ends with a \0 that is included in the returned | |
| * length. | |
| * | |
| * \note The XML buffer should later be freed with hwloc_free_xmlbuffer(). | |
| */ | |
| HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen); | |
| /** @} */ | |
| } /* extern "C" */ | |