1 /*
2  * Copyright © 2020 Inria.  All rights reserved.
3  * See COPYING in top-level directory.
4  */
5 
6 /** \file
7  * \brief Kinds of CPU cores.
8  */
9 
10 #ifndef HWLOC_CPUKINDS_H
11 #define HWLOC_CPUKINDS_H
12 
13 #include "hwloc.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #elif 0
18 }
19 #endif
20 
21 /** \defgroup hwlocality_cpukinds Kinds of CPU cores
22  *
23  * Platforms with heterogeneous CPUs may have some cores with
24  * different features or frequencies.
25  * This API exposes identical PUs in sets called CPU kinds.
26  * Each PU of the topology may only be in a single kind.
27  *
28  * The number of kinds may be obtained with hwloc_cpukinds_get_nr().
29  * If the platform is homogeneous, there may be a single kind
30  * with all PUs.
31  * If the platform or operating system does not expose any
32  * information about CPU cores, there may be no kind at all.
33  *
34  * The index of the kind that describes a given CPU set
35  * (if any, and not partially)
36  * may be obtained with hwloc_cpukinds_get_by_cpuset().
37  *
38  * From the index of a kind, it is possible to retrieve information
39  * with hwloc_cpukinds_get_info():
40  * an abstracted efficiency value,
41  * and an array of info attributes
42  * (for instance the "CoreType" and "FrequencyMaxMHz",
43  *  see \ref topoattrs_cpukinds).
44  *
45  * A higher efficiency value means intrinsic greater performance
46  * (and possibly less performance/power efficiency).
47  * Kinds with lower efficiency are ranked first:
48  * Passing 0 as \p kind_index to hwloc_cpukinds_get_info() will
49  * return information about the less efficient CPU kind.
50  *
51  * When available, efficiency values are gathered from the operating
52  * system (when \p cpukind_efficiency is set in the
53  * struct hwloc_topology_discovery_support array, only on Windows 10 for now).
54  * Otherwise hwloc tries to compute efficiencies
55  * by comparing CPU kinds using frequencies (on ARM),
56  * or core types and frequencies (on other architectures).
57  * The environment variable HWLOC_CPUKINDS_RANKING may be used
58  * to change this heuristics, see \ref envvar.
59  *
60  * If hwloc fails to rank any kind, for instance because the operating
61  * system does not expose efficiencies and core frequencies,
62  * all kinds will have an unknown efficiency (\c -1),
63  * and they are not indexed/ordered in any specific way.
64  *
65  * @{
66  */
67 
68 /** \brief Get the number of different kinds of CPU cores in the topology.
69  *
70  * \p flags must be \c 0 for now.
71  *
72  * \return The number of CPU kinds (positive integer) on success.
73  * \return \c 0 if no information about kinds was found.
74  * \return \c -1 with \p errno set to \c EINVAL if \p flags is invalid.
75  */
76 HWLOC_DECLSPEC int
77 hwloc_cpukinds_get_nr(hwloc_topology_t topology,
78                       unsigned long flags);
79 
80 /** \brief Get the index of the CPU kind that contains CPUs listed in \p cpuset.
81  *
82  * \p flags must be \c 0 for now.
83  *
84  * \return The index of the CPU kind (positive integer or 0) on success.
85  * \return \c -1 with \p errno set to \c EXDEV if \p cpuset is
86  * only partially included in the some kind.
87  * \return \c -1 with \p errno set to \c ENOENT if \p cpuset is
88  * not included in any kind, even partially.
89  * \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
90  */
91 HWLOC_DECLSPEC int
92 hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
93                              hwloc_const_bitmap_t cpuset,
94                              unsigned long flags);
95 
96 /** \brief Get the CPU set and infos about a CPU kind in the topology.
97  *
98  * \p kind_index identifies one kind of CPU between 0 and the number
99  * of kinds returned by hwloc_cpukinds_get_nr() minus 1.
100  *
101  * If not \c NULL, the bitmap \p cpuset will be filled with
102  * the set of PUs of this kind.
103  *
104  * The integer pointed by \p efficiency, if not \c NULL will, be filled
105  * with the ranking of this kind of CPU in term of efficiency (see above).
106  * It ranges from \c 0 to the number of kinds
107  * (as reported by hwloc_cpukinds_get_nr()) minus 1.
108  *
109  * Kinds with lower efficiency are reported first.
110  *
111  * If there is a single kind in the topology, its efficiency \c 0.
112  * If the efficiency of some kinds of cores is unknown,
113  * the efficiency of all kinds is set to \c -1,
114  * and kinds are reported in no specific order.
115  *
116  * The array of info attributes (for instance the "CoreType",
117  * "FrequencyMaxMHz" or "FrequencyBaseMHz", see \ref topoattrs_cpukinds)
118  * and its length are returned in \p infos or \p nr_infos.
119  * The array belongs to the topology, it should not be freed or modified.
120  *
121  * If \p nr_infos or \p infos is \c NULL, no info is returned.
122  *
123  * \p flags must be \c 0 for now.
124  *
125  * \return \c 0 on success.
126  * \return \c -1 with \p errno set to \c ENOENT if \p kind_index does not match any CPU kind.
127  * \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
128  */
129 HWLOC_DECLSPEC int
130 hwloc_cpukinds_get_info(hwloc_topology_t topology,
131                         unsigned kind_index,
132                         hwloc_bitmap_t cpuset,
133                         int *efficiency,
134                         unsigned *nr_infos, struct hwloc_info_s **infos,
135                         unsigned long flags);
136 
137 /** \brief Register a kind of CPU in the topology.
138  *
139  * Mark the PUs listed in \p cpuset as being of the same kind
140  * with respect to the given attributes.
141  *
142  * \p forced_efficiency should be \c -1 if unknown.
143  * Otherwise it is an abstracted efficiency value to enforce
144  * the ranking of all kinds if all of them have valid (and
145  * different) efficiencies.
146  *
147  * The array \p infos of size \p nr_infos may be used to provide
148  * info names and values describing this kind of PUs.
149  *
150  * \p flags must be \c 0 for now.
151  *
152  * Parameters \p cpuset and \p infos will be duplicated internally,
153  * the caller is responsible for freeing them.
154  *
155  * If \p cpuset overlaps with some existing kinds, those might get
156  * modified or split. For instance if existing kind A contains
157  * PUs 0 and 1, and one registers another kind for PU 1 and 2,
158  * there will be 3 resulting kinds:
159  * existing kind A is restricted to only PU 0;
160  * new kind B contains only PU 1 and combines information from A
161  * and from the newly-registered kind;
162  * new kind C contains only PU 2 and only gets information from
163  * the newly-registered kind.
164  *
165  * \note The efficiency \p forced_efficiency provided to this function
166  * may be different from the one reported later by hwloc_cpukinds_get_info()
167  * because hwloc will scale efficiency values down to
168  * between 0 and the number of kinds minus 1.
169  *
170  * \return \c 0 on success.
171  * \return \c -1 with \p errno set to \c EINVAL if some parameters are invalid,
172  * for instance if \p cpuset is \c NULL or empty.
173  */
174 HWLOC_DECLSPEC int
175 hwloc_cpukinds_register(hwloc_topology_t topology,
176                         hwloc_bitmap_t cpuset,
177                         int forced_efficiency,
178                         unsigned nr_infos, struct hwloc_info_s *infos,
179                         unsigned long flags);
180 
181 /** @} */
182 
183 #ifdef __cplusplus
184 } /* extern "C" */
185 #endif
186 
187 
188 #endif /* HWLOC_CPUKINDS_H */
189