1 /* 2 * Copyright © 2010-2017 Inria. All rights reserved. 3 * See COPYING in top-level directory. 4 */ 5 6 /** \file 7 * \brief Object distances. 8 */ 9 10 #ifndef HWLOC_DISTANCES_H 11 #define HWLOC_DISTANCES_H 12 13 #ifndef HWLOC_H 14 #error Please include the main hwloc.h instead 15 #endif 16 17 18 #ifdef __cplusplus 19 extern "C" { 20 #elif 0 21 } 22 #endif 23 24 25 /** \defgroup hwlocality_distances_get Retrieve distances between objects 26 * @{ 27 */ 28 29 /** \brief Matrix of distances between a set of objects. 30 * 31 * This matrix often contains latencies between NUMA nodes 32 * (as reported in the System Locality Distance Information Table (SLIT) 33 * in the ACPI specification), which may or may not be physically accurate. 34 * It corresponds to the latency for accessing the memory of one node 35 * from a core in another node. 36 * The corresponding kind is ::HWLOC_DISTANCES_KIND_FROM_OS | ::HWLOC_DISTANCES_KIND_FROM_USER. 37 * 38 * The matrix may also contain bandwidths between random sets of objects, 39 * possibly provided by the user, as specified in the \p kind attribute. 40 */ 41 struct hwloc_distances_s { 42 unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */ 43 hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix. 44 * These objects are not in any particular order, 45 * see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values() 46 * for easy ways to find objects in this array and their corresponding values. 47 */ 48 unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */ 49 hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array. 50 * 51 * Distance from i-th to j-th object is stored in slot i*nbobjs+j. 52 * The meaning of the value depends on the \p kind attribute. 53 */ 54 }; 55 56 /** \brief Kinds of distance matrices. 57 * 58 * The \p kind attribute of struct hwloc_distances_s is a OR'ed set 59 * of kinds. 60 * 61 * A kind of format HWLOC_DISTANCES_KIND_FROM_* specifies where the 62 * distance information comes from, if known. 63 * 64 * A kind of format HWLOC_DISTANCES_KIND_MEANS_* specifies whether 65 * values are latencies or bandwidths, if applicable. 66 */ 67 enum hwloc_distances_kind_e { 68 /** \brief These distances were obtained from the operating system or hardware. 69 * \hideinitializer 70 */ 71 HWLOC_DISTANCES_KIND_FROM_OS = (1UL<<0), 72 /** \brief These distances were provided by the user. 73 * \hideinitializer 74 */ 75 HWLOC_DISTANCES_KIND_FROM_USER = (1UL<<1), 76 77 /** \brief Distance values are similar to latencies between objects. 78 * Values are smaller for closer objects, hence minimal on the diagonal 79 * of the matrix (distance between an object and itself). 80 * It could also be the number of network hops between objects, etc. 81 * \hideinitializer 82 */ 83 HWLOC_DISTANCES_KIND_MEANS_LATENCY = (1UL<<2), 84 /** \brief Distance values are similar to bandwidths between objects. 85 * Values are higher for closer objects, hence maximal on the diagonal 86 * of the matrix (distance between an object and itself). 87 * Such values are currently ignored for distance-based grouping. 88 * \hideinitializer 89 */ 90 HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH = (1UL<<3) 91 }; 92 93 /** \brief Retrieve distance matrices. 94 * 95 * Retrieve distance matrices from the topology into the \p distances array. 96 * 97 * \p flags is currently unused, should be \c 0. 98 * 99 * \p kind serves as a filter. If \c 0, all distance matrices are returned. 100 * If it contains some HWLOC_DISTANCES_KIND_FROM_*, only distances whose kind 101 * matches one of these are returned. 102 * If it contains some HWLOC_DISTANCES_KIND_MEANS_*, only distances whose kind 103 * matches one of these are returned. 104 * 105 * On input, \p nr points to the number of distances that may be stored in \p distances. 106 * On output, \p nr points to the number of distances that were actually found, 107 * even if some of them couldn't be stored in \p distances. 108 * Distances that couldn't be stored are ignored, but the function still returns 109 * success (\c 0). The caller may find out by comparing the value pointed by \p nr 110 * before and after the function call. 111 * 112 * Each distance structure returned in the \p distances array should be released 113 * by the caller using hwloc_distances_release(). 114 */ 115 HWLOC_DECLSPEC int 116 hwloc_distances_get(hwloc_topology_t topology, 117 unsigned *nr, struct hwloc_distances_s **distances, 118 unsigned long kind, unsigned long flags); 119 120 /** \brief Retrieve distance matrices for object at a specific depth in the topology. 121 * 122 * Identical to hwloc_distances_get() with the additional \p depth filter. 123 */ 124 HWLOC_DECLSPEC int 125 hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth, 126 unsigned *nr, struct hwloc_distances_s **distances, 127 unsigned long kind, unsigned long flags); 128 129 /** \brief Retrieve distance matrices for object of a specific type. 130 * 131 * Identical to hwloc_distances_get() with the additional \p type filter. 132 */ 133 static __hwloc_inline int 134 hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, 135 unsigned *nr, struct hwloc_distances_s **distances, 136 unsigned long kind, unsigned long flags) 137 { 138 int depth = hwloc_get_type_depth(topology, type); 139 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) { 140 *nr = 0; 141 return 0; 142 } 143 return hwloc_distances_get_by_depth(topology, depth, nr, distances, kind, flags); 144 } 145 146 /** \brief Release a distance structure previously returned by hwloc_distances_get(). */ 147 HWLOC_DECLSPEC void 148 hwloc_distances_release(hwloc_topology_t topology, struct hwloc_distances_s *distances); 149 150 /** @} */ 151 152 153 154 /** \defgroup hwlocality_distances_consult Helpers for consulting distances structures 155 * @{ 156 */ 157 158 /** \brief Find the index of an object in a distances structure. 159 * 160 * \return -1 if object \p obj is not involved in structure \p distances. 161 */ 162 static __hwloc_inline int 163 hwloc_distances_obj_index(struct hwloc_distances_s *distances, hwloc_obj_t obj) 164 { 165 unsigned i; 166 for(i=0; i<distances->nbobjs; i++) 167 if (distances->objs[i] == obj) 168 return (int)i; 169 return -1; 170 } 171 172 /** \brief Find the values between two objects in a distances structure. 173 * 174 * The distance from \p obj1 to \p obj2 is stored in the value pointed by 175 * \p value1to2 and reciprocally. 176 * 177 * \return -1 if object \p obj1 or \p obj2 is not involved in structure \p distances. 178 */ 179 static __hwloc_inline int 180 hwloc_distances_obj_pair_values(struct hwloc_distances_s *distances, 181 hwloc_obj_t obj1, hwloc_obj_t obj2, 182 hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1) 183 { 184 int i1 = hwloc_distances_obj_index(distances, obj1); 185 int i2 = hwloc_distances_obj_index(distances, obj2); 186 if (i1 < 0 || i2 < 0) 187 return -1; 188 *value1to2 = distances->values[i1 * distances->nbobjs + i2]; 189 *value2to1 = distances->values[i2 * distances->nbobjs + i1]; 190 return 0; 191 } 192 193 /** @} */ 194 195 196 197 /** \defgroup hwlocality_distances_add Add or remove distances between objects 198 * @{ 199 */ 200 201 /** \brief Flags for adding a new distances to a topology. */ 202 enum hwloc_distances_add_flag_e { 203 /** \brief Try to group objects based on the newly provided distance information. 204 * \hideinitializer 205 */ 206 HWLOC_DISTANCES_ADD_FLAG_GROUP = (1UL<<0), 207 /** \brief If grouping, consider the distance values as inaccurate and relax the 208 * comparisons during the grouping algorithms. The actual accuracy may be modified 209 * through the HWLOC_GROUPING_ACCURACY environment variable (see \ref envvar). 210 * \hideinitializer 211 */ 212 HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE = (1UL<<1) 213 }; 214 215 /** \brief Provide a distance matrix. 216 * 217 * Provide the matrix of distances between a set of objects given by \p nbobjs 218 * and the \p objs array. \p nbobjs must be at least 2. 219 * The distances are stored as a one-dimension array in \p values. 220 * The distance from object i to object j is in slot i*nbobjs+j. 221 * 222 * \p kind specifies the kind of distance as a OR'ed set of ::hwloc_distances_kind_e. 223 * 224 * \p flags configures the behavior of the function using an optional OR'ed set of 225 * ::hwloc_distances_add_flag_e. 226 * 227 * Objects must be of the same type. They cannot be of type Group. 228 */ 229 HWLOC_DECLSPEC int hwloc_distances_add(hwloc_topology_t topology, 230 unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values, 231 unsigned long kind, unsigned long flags); 232 233 /** \brief Remove all distance matrices from a topology. 234 * 235 * Remove all distance matrices, either provided by the user or 236 * gathered through the OS. 237 * 238 * If these distances were used to group objects, these additional 239 *Group objects are not removed from the topology. 240 */ 241 HWLOC_DECLSPEC int hwloc_distances_remove(hwloc_topology_t topology); 242 243 /** \brief Remove distance matrices for objects at a specific depth in the topology. 244 * 245 * Identical to hwloc_distances_remove() but only applies to one level of the topology. 246 */ 247 HWLOC_DECLSPEC int hwloc_distances_remove_by_depth(hwloc_topology_t topology, int depth); 248 249 /** \brief Remove distance matrices for objects of a specific type in the topology. 250 * 251 * Identical to hwloc_distances_remove() but only applies to one level of the topology. 252 */ 253 static __hwloc_inline int 254 hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type) 255 { 256 int depth = hwloc_get_type_depth(topology, type); 257 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) 258 return 0; 259 return hwloc_distances_remove_by_depth(topology, depth); 260 } 261 262 /** @} */ 263 264 265 #ifdef __cplusplus 266 } /* extern "C" */ 267 #endif 268 269 270 #endif /* HWLOC_DISTANCES_H */