Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:15

0001 /*
0002  * Copyright © 2013-2023 Inria.  All rights reserved.
0003  * See COPYING in top-level directory.
0004  */
0005 
0006 /** \file
0007  * \brief Topology differences.
0008  */
0009 
0010 #ifndef HWLOC_DIFF_H
0011 #define HWLOC_DIFF_H
0012 
0013 #ifndef HWLOC_H
0014 #error Please include the main hwloc.h instead
0015 #endif
0016 
0017 
0018 #ifdef __cplusplus
0019 extern "C" {
0020 #elif 0
0021 }
0022 #endif
0023 
0024 
0025 /** \defgroup hwlocality_diff Topology differences
0026  *
0027  * Applications that manipulate many similar topologies, for instance
0028  * one for each node of a homogeneous cluster, may want to compress
0029  * topologies to reduce the memory footprint.
0030  *
0031  * This file offers a way to manipulate the difference between topologies
0032  * and export/import it to/from XML.
0033  * Compression may therefore be achieved by storing one topology
0034  * entirely while the others are only described by their differences
0035  * with the former.
0036  * The actual topology can be reconstructed when actually needed by
0037  * applying the precomputed difference to the reference topology.
0038  *
0039  * This interface targets very similar nodes.
0040  * Only very simple differences between topologies are actually
0041  * supported, for instance a change in the memory size, the name
0042  * of the object, or some info attribute.
0043  * More complex differences such as adding or removing objects cannot
0044  * be represented in the difference structures and therefore return
0045  * errors.
0046  * Differences between object sets or topology-wide allowed sets,
0047  * cannot be represented either.
0048  *
0049  * It means that there is no need to apply the difference when
0050  * looking at the tree organization (how many levels, how many
0051  * objects per level, what kind of objects, CPU and node sets, etc)
0052  * and when binding to objects.
0053  * However the difference must be applied when looking at object
0054  * attributes such as the name, the memory size or info attributes.
0055  *
0056  * @{
0057  */
0058 
0059 
0060 /** \brief Type of one object attribute difference.
0061  */
0062 typedef enum hwloc_topology_diff_obj_attr_type_e {
0063   /** \brief The object local memory is modified.
0064    * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_uint64_s
0065    * (and the index field is ignored).
0066    */
0067   HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
0068 
0069   /** \brief The object name is modified.
0070    * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s
0071    * (and the name field is ignored).
0072    */
0073 
0074   HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
0075   /** \brief the value of an info attribute is modified.
0076    * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s.
0077    */
0078   HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO
0079 } hwloc_topology_diff_obj_attr_type_t;
0080 
0081 /** \brief One object attribute difference.
0082  */
0083 union hwloc_topology_diff_obj_attr_u {
0084   struct hwloc_topology_diff_obj_attr_generic_s {
0085     /* each part of the union must start with these */
0086     hwloc_topology_diff_obj_attr_type_t type;
0087   } generic;
0088 
0089   /** \brief Integer attribute modification with an optional index. */
0090   struct hwloc_topology_diff_obj_attr_uint64_s {
0091     /* used for storing integer attributes */
0092     hwloc_topology_diff_obj_attr_type_t type;
0093     hwloc_uint64_t index; /* not used for SIZE */
0094     hwloc_uint64_t oldvalue;
0095     hwloc_uint64_t newvalue;
0096   } uint64;
0097 
0098   /** \brief String attribute modification with an optional name */
0099   struct hwloc_topology_diff_obj_attr_string_s {
0100     /* used for storing name and info pairs */
0101     hwloc_topology_diff_obj_attr_type_t type;
0102     char *name; /* not used for NAME */
0103     char *oldvalue;
0104     char *newvalue;
0105   } string;
0106 };
0107 
0108 
0109 /** \brief Type of one element of a difference list.
0110  */
0111 typedef enum hwloc_topology_diff_type_e {
0112   /** \brief An object attribute was changed.
0113    * The union is a hwloc_topology_diff_u::hwloc_topology_diff_obj_attr_s.
0114    */
0115   HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,
0116 
0117   /** \brief The difference is too complex,
0118    * it cannot be represented. The difference below
0119    * this object has not been checked.
0120    * hwloc_topology_diff_build() will return 1.
0121    *
0122    * The union is a hwloc_topology_diff_u::hwloc_topology_diff_too_complex_s.
0123    */
0124   HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
0125 } hwloc_topology_diff_type_t;
0126 
0127 /** \brief One element of a difference list between two topologies.
0128  */
0129 typedef union hwloc_topology_diff_u {
0130   struct hwloc_topology_diff_generic_s {
0131     /* each part of the union must start with these */
0132     hwloc_topology_diff_type_t type;
0133     union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */
0134   } generic;
0135 
0136   /* A difference in an object attribute. */
0137   struct hwloc_topology_diff_obj_attr_s {
0138     hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
0139     union hwloc_topology_diff_u * next;
0140     /* List of attribute differences for a single object */
0141     int obj_depth;
0142     unsigned obj_index;
0143     union hwloc_topology_diff_obj_attr_u diff;
0144   } obj_attr;
0145 
0146   /* A difference that is too complex. */
0147   struct hwloc_topology_diff_too_complex_s {
0148     hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */
0149     union hwloc_topology_diff_u * next;
0150     /* Where we had to stop computing the diff in the first topology */
0151     int obj_depth;
0152     unsigned obj_index;
0153   } too_complex;
0154 } * hwloc_topology_diff_t;
0155 
0156 
0157 /** \brief Compute the difference between 2 topologies.
0158  *
0159  * The difference is stored as a list of ::hwloc_topology_diff_t entries
0160  * starting at \p diff.
0161  * It is computed by doing a depth-first traversal of both topology trees
0162  * simultaneously.
0163  *
0164  * If the difference between 2 objects is too complex to be represented
0165  * (for instance if some objects have different types, or different numbers
0166  * of children), a special diff entry of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
0167  * is queued.
0168  * The computation of the diff does not continue below these objects.
0169  * So each such diff entry means that the difference between two subtrees
0170  * could not be computed.
0171  *
0172  * \return 0 if the difference can be represented properly.
0173  *
0174  * \return 0 with \p diff pointing to NULL if there is no difference
0175  * between the topologies.
0176  *
0177  * \return 1 if the difference is too complex (see above). Some entries in
0178  * the list will be of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX.
0179  *
0180  * \return -1 on any other error.
0181  *
0182  * \note \p flags is currently not used. It should be 0.
0183  *
0184  * \note The output diff has to be freed with hwloc_topology_diff_destroy().
0185  *
0186  * \note The output diff can only be exported to XML or passed to
0187  * hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type
0188  * ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.
0189  *
0190  * \note The output diff may be modified by removing some entries from
0191  * the list. The removed entries should be freed by passing them to
0192  * to hwloc_topology_diff_destroy() (possible as another list).
0193 */
0194 HWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff);
0195 
0196 /** \brief Flags to be given to hwloc_topology_diff_apply().
0197  */
0198 enum hwloc_topology_diff_apply_flags_e {
0199   /** \brief Apply topology diff in reverse direction.
0200    * \hideinitializer
0201    */
0202   HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0)
0203 };
0204 
0205 /** \brief Apply a topology diff to an existing topology.
0206  *
0207  * \p flags is an OR'ed set of ::hwloc_topology_diff_apply_flags_e.
0208  *
0209  * The new topology is modified in place. hwloc_topology_dup()
0210  * may be used to duplicate it before patching.
0211  *
0212  * If the difference cannot be applied entirely, all previous applied
0213  * elements are unapplied before returning.
0214  *
0215  * \return 0 on success.
0216  *
0217  * \return -N if applying the difference failed while trying
0218  * to apply the N-th part of the difference. For instance -1
0219  * is returned if the very first difference element could not
0220  * be applied.
0221  */
0222 HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags);
0223 
0224 /** \brief Destroy a list of topology differences.
0225  *
0226  * \return 0.
0227  */
0228 HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff);
0229 
0230 /** \brief Load a list of topology differences from a XML file.
0231  *
0232  * If not \c NULL, \p refname will be filled with the identifier
0233  * string of the reference topology for the difference file,
0234  * if any was specified in the XML file.
0235  * This identifier is usually the name of the other XML file
0236  * that contains the reference topology.
0237  *
0238  * \return 0 on success, -1 on error.
0239  *
0240  * \note the pointer returned in refname should later be freed
0241  * by the caller.
0242  */
0243 HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(const char *xmlpath, hwloc_topology_diff_t *diff, char **refname);
0244 
0245 /** \brief Export a list of topology differences to a XML file.
0246  *
0247  * If not \c NULL, \p refname defines an identifier string
0248  * for the reference topology which was used as a base when
0249  * computing this difference.
0250  * This identifier is usually the name of the other XML file
0251  * that contains the reference topology.
0252  * This attribute is given back when reading the diff from XML.
0253  *
0254  * \return 0 on success, -1 on error.
0255  */
0256 HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, const char *refname, const char *xmlpath);
0257 
0258 /** \brief Load a list of topology differences from a XML buffer.
0259  *
0260  * Build a list of differences from the XML memory buffer given
0261  * at \p xmlbuffer and of length \p buflen (including an ending \0).
0262  * This buffer may have been filled earlier with
0263  * hwloc_topology_diff_export_xmlbuffer().
0264  *
0265  * If not \c NULL, \p refname will be filled with the identifier
0266  * string of the reference topology for the difference file,
0267  * if any was specified in the XML file.
0268  * This identifier is usually the name of the other XML file
0269  * that contains the reference topology.
0270  *
0271  * \return 0 on success, -1 on error.
0272  *
0273  * \note the pointer returned in refname should later be freed
0274  * by the caller.
0275   */
0276 HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname);
0277 
0278 /** \brief Export a list of topology differences to a XML buffer.
0279  *
0280  * If not \c NULL, \p refname defines an identifier string
0281  * for the reference topology which was used as a base when
0282  * computing this difference.
0283  * This identifier is usually the name of the other XML file
0284  * that contains the reference topology.
0285  * This attribute is given back when reading the diff from XML.
0286  *
0287  * The returned buffer ends with a \0 that is included in the returned
0288  * length.
0289  *
0290  * \return 0 on success, -1 on error.
0291  *
0292  * \note The XML buffer should later be freed with hwloc_free_xmlbuffer().
0293  */
0294 HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen);
0295 
0296 /** @} */
0297 
0298 
0299 #ifdef __cplusplus
0300 } /* extern "C" */
0301 #endif
0302 
0303 
0304 #endif /* HWLOC_DIFF_H */