diff.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Copyright © 2013-2023 Inria. All rights reserved.
  3. * See COPYING in top-level directory.
  4. */
  5. /** \file
  6. * \brief Topology differences.
  7. */
  8. #ifndef HWLOC_DIFF_H
  9. #define HWLOC_DIFF_H
  10. #ifndef HWLOC_H
  11. #error Please include the main hwloc.h instead
  12. #endif
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #elif 0
  16. }
  17. #endif
  18. /** \defgroup hwlocality_diff Topology differences
  19. *
  20. * Applications that manipulate many similar topologies, for instance
  21. * one for each node of a homogeneous cluster, may want to compress
  22. * topologies to reduce the memory footprint.
  23. *
  24. * This file offers a way to manipulate the difference between topologies
  25. * and export/import it to/from XML.
  26. * Compression may therefore be achieved by storing one topology
  27. * entirely while the others are only described by their differences
  28. * with the former.
  29. * The actual topology can be reconstructed when actually needed by
  30. * applying the precomputed difference to the reference topology.
  31. *
  32. * This interface targets very similar nodes.
  33. * Only very simple differences between topologies are actually
  34. * supported, for instance a change in the memory size, the name
  35. * of the object, or some info attribute.
  36. * More complex differences such as adding or removing objects cannot
  37. * be represented in the difference structures and therefore return
  38. * errors.
  39. * Differences between object sets or topology-wide allowed sets,
  40. * cannot be represented either.
  41. *
  42. * It means that there is no need to apply the difference when
  43. * looking at the tree organization (how many levels, how many
  44. * objects per level, what kind of objects, CPU and node sets, etc)
  45. * and when binding to objects.
  46. * However the difference must be applied when looking at object
  47. * attributes such as the name, the memory size or info attributes.
  48. *
  49. * @{
  50. */
  51. /** \brief Type of one object attribute difference.
  52. */
  53. typedef enum hwloc_topology_diff_obj_attr_type_e {
  54. /** \brief The object local memory is modified.
  55. * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_uint64_s
  56. * (and the index field is ignored).
  57. */
  58. HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
  59. /** \brief The object name is modified.
  60. * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s
  61. * (and the name field is ignored).
  62. */
  63. HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
  64. /** \brief the value of an info attribute is modified.
  65. * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s.
  66. */
  67. HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO
  68. } hwloc_topology_diff_obj_attr_type_t;
  69. /** \brief One object attribute difference.
  70. */
  71. union hwloc_topology_diff_obj_attr_u {
  72. struct hwloc_topology_diff_obj_attr_generic_s {
  73. /* each part of the union must start with these */
  74. hwloc_topology_diff_obj_attr_type_t type;
  75. } generic;
  76. /** \brief Integer attribute modification with an optional index. */
  77. struct hwloc_topology_diff_obj_attr_uint64_s {
  78. /* used for storing integer attributes */
  79. hwloc_topology_diff_obj_attr_type_t type;
  80. hwloc_uint64_t index; /* not used for SIZE */
  81. hwloc_uint64_t oldvalue;
  82. hwloc_uint64_t newvalue;
  83. } uint64;
  84. /** \brief String attribute modification with an optional name */
  85. struct hwloc_topology_diff_obj_attr_string_s {
  86. /* used for storing name and info pairs */
  87. hwloc_topology_diff_obj_attr_type_t type;
  88. char *name; /* not used for NAME */
  89. char *oldvalue;
  90. char *newvalue;
  91. } string;
  92. };
  93. /** \brief Type of one element of a difference list.
  94. */
  95. typedef enum hwloc_topology_diff_type_e {
  96. /** \brief An object attribute was changed.
  97. * The union is a hwloc_topology_diff_u::hwloc_topology_diff_obj_attr_s.
  98. */
  99. HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,
  100. /** \brief The difference is too complex,
  101. * it cannot be represented. The difference below
  102. * this object has not been checked.
  103. * hwloc_topology_diff_build() will return 1.
  104. *
  105. * The union is a hwloc_topology_diff_u::hwloc_topology_diff_too_complex_s.
  106. */
  107. HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
  108. } hwloc_topology_diff_type_t;
  109. /** \brief One element of a difference list between two topologies.
  110. */
  111. typedef union hwloc_topology_diff_u {
  112. struct hwloc_topology_diff_generic_s {
  113. /* each part of the union must start with these */
  114. hwloc_topology_diff_type_t type;
  115. union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */
  116. } generic;
  117. /* A difference in an object attribute. */
  118. struct hwloc_topology_diff_obj_attr_s {
  119. hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
  120. union hwloc_topology_diff_u * next;
  121. /* List of attribute differences for a single object */
  122. int obj_depth;
  123. unsigned obj_index;
  124. union hwloc_topology_diff_obj_attr_u diff;
  125. } obj_attr;
  126. /* A difference that is too complex. */
  127. struct hwloc_topology_diff_too_complex_s {
  128. hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */
  129. union hwloc_topology_diff_u * next;
  130. /* Where we had to stop computing the diff in the first topology */
  131. int obj_depth;
  132. unsigned obj_index;
  133. } too_complex;
  134. } * hwloc_topology_diff_t;
  135. /** \brief Compute the difference between 2 topologies.
  136. *
  137. * The difference is stored as a list of ::hwloc_topology_diff_t entries
  138. * starting at \p diff.
  139. * It is computed by doing a depth-first traversal of both topology trees
  140. * simultaneously.
  141. *
  142. * If the difference between 2 objects is too complex to be represented
  143. * (for instance if some objects have different types, or different numbers
  144. * of children), a special diff entry of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
  145. * is queued.
  146. * The computation of the diff does not continue below these objects.
  147. * So each such diff entry means that the difference between two subtrees
  148. * could not be computed.
  149. *
  150. * \return 0 if the difference can be represented properly.
  151. *
  152. * \return 0 with \p diff pointing to NULL if there is no difference
  153. * between the topologies.
  154. *
  155. * \return 1 if the difference is too complex (see above). Some entries in
  156. * the list will be of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX.
  157. *
  158. * \return -1 on any other error.
  159. *
  160. * \note \p flags is currently not used. It should be 0.
  161. *
  162. * \note The output diff has to be freed with hwloc_topology_diff_destroy().
  163. *
  164. * \note The output diff can only be exported to XML or passed to
  165. * hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type
  166. * ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.
  167. *
  168. * \note The output diff may be modified by removing some entries from
  169. * the list. The removed entries should be freed by passing them to
  170. * to hwloc_topology_diff_destroy() (possible as another list).
  171. */
  172. HWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff);
  173. /** \brief Flags to be given to hwloc_topology_diff_apply().
  174. */
  175. enum hwloc_topology_diff_apply_flags_e {
  176. /** \brief Apply topology diff in reverse direction.
  177. * \hideinitializer
  178. */
  179. HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0)
  180. };
  181. /** \brief Apply a topology diff to an existing topology.
  182. *
  183. * \p flags is an OR'ed set of ::hwloc_topology_diff_apply_flags_e.
  184. *
  185. * The new topology is modified in place. hwloc_topology_dup()
  186. * may be used to duplicate it before patching.
  187. *
  188. * If the difference cannot be applied entirely, all previous applied
  189. * elements are unapplied before returning.
  190. *
  191. * \return 0 on success.
  192. *
  193. * \return -N if applying the difference failed while trying
  194. * to apply the N-th part of the difference. For instance -1
  195. * is returned if the very first difference element could not
  196. * be applied.
  197. */
  198. HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags);
  199. /** \brief Destroy a list of topology differences.
  200. *
  201. * \return 0.
  202. */
  203. HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff);
  204. /** \brief Load a list of topology differences from a XML file.
  205. *
  206. * If not \c NULL, \p refname will be filled with the identifier
  207. * string of the reference topology for the difference file,
  208. * if any was specified in the XML file.
  209. * This identifier is usually the name of the other XML file
  210. * that contains the reference topology.
  211. *
  212. * \return 0 on success, -1 on error.
  213. *
  214. * \note the pointer returned in refname should later be freed
  215. * by the caller.
  216. */
  217. HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(const char *xmlpath, hwloc_topology_diff_t *diff, char **refname);
  218. /** \brief Export a list of topology differences to a XML file.
  219. *
  220. * If not \c NULL, \p refname defines an identifier string
  221. * for the reference topology which was used as a base when
  222. * computing this difference.
  223. * This identifier is usually the name of the other XML file
  224. * that contains the reference topology.
  225. * This attribute is given back when reading the diff from XML.
  226. *
  227. * \return 0 on success, -1 on error.
  228. */
  229. HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, const char *refname, const char *xmlpath);
  230. /** \brief Load a list of topology differences from a XML buffer.
  231. *
  232. * If not \c NULL, \p refname will be filled with the identifier
  233. * string of the reference topology for the difference file,
  234. * if any was specified in the XML file.
  235. * This identifier is usually the name of the other XML file
  236. * that contains the reference topology.
  237. *
  238. * \return 0 on success, -1 on error.
  239. *
  240. * \note the pointer returned in refname should later be freed
  241. * by the caller.
  242. */
  243. HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname);
  244. /** \brief Export a list of topology differences to a XML buffer.
  245. *
  246. * If not \c NULL, \p refname defines an identifier string
  247. * for the reference topology which was used as a base when
  248. * computing this difference.
  249. * This identifier is usually the name of the other XML file
  250. * that contains the reference topology.
  251. * This attribute is given back when reading the diff from XML.
  252. *
  253. * The returned buffer ends with a \0 that is included in the returned
  254. * length.
  255. *
  256. * \return 0 on success, -1 on error.
  257. *
  258. * \note The XML buffer should later be freed with hwloc_free_xmlbuffer().
  259. */
  260. HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen);
  261. /** @} */
  262. #ifdef __cplusplus
  263. } /* extern "C" */
  264. #endif
  265. #endif /* HWLOC_DIFF_H */