163
165
<p>The basic interface is available in <a class="el" href="hwloc_8h_source.html" title="The hwloc API.">hwloc.h</a>. It mostly offers low-level routines for advanced programmers that want to manually manipulate objects and follow links between them. Developers should look at <a class="el" href="helper_8h_source.html" title="High-level hwloc traversal helpers.">hwloc/helper.h</a>, which provides good higher-level topology traversal examples.</p>
164
166
<p>Each object contains a cpuset describing the list of processors that it contains. These cpusets may be used for <a class="el" href="group__hwlocality__binding.html">Binding</a>. hwloc offers an extensive cpuset manipulation interface in <a class="el" href="cpuset_8h_source.html" title="The Cpuset API, for use in hwloc itself.">hwloc/cpuset.h</a>.</p>
165
167
<p>Moreover, hwloc also comes with additional helpers for interoperability with several commonly used environments. For Linux, some specific helpers are available in <a class="el" href="linux_8h_source.html" title="Macros to help interaction between hwloc and Linux.">hwloc/linux.h</a>, and <a class="el" href="linux-libnuma_8h_source.html" title="Macros to help interaction between hwloc and Linux libnuma.">hwloc/linux-libnuma.h</a> if using libnuma. On glibc-based systems, additional helpers are available in <a class="el" href="glibc-sched_8h_source.html" title="Macros to help interaction between hwloc and glibc scheduling routines.">hwloc/glibc-sched.h</a>. For Linux systems with the OpenFabrics verbs library, some dedicated helpers are provided in <a class="el" href="openfabrics-verbs_8h_source.html" title="Macros to help interaction between hwloc and OpenFabrics verbs.">hwloc/openfabrics-verbs.h</a> (this helper file is not yet useful on non-Linux systems with the OpenFabrics verbs library).</p>
166
<p>To precisely define the vocabulary used by hwloc, a <a class="el" href="glossary.html">Glossary</a> is available and should probably be read first.</p>
168
<p>To precisely define the vocabulary used by hwloc, a <a class="el" href="index.html#glossary">Glossary</a> is available and should probably be read first.</p>
167
169
<p>Further documentation is available in a full set of HTML pages, man pages, and self-contained PDF files (formatted for both both US letter and A4 formats) in the source tarball in doc/doxygen-doc/. If you are building from a Subversion checkout, you will need to have Doxygen and pdflatex installed -- the documentation will be built during the normal "make" process. The documentation is installed during "make
168
170
install" to $prefix/share/doc/hwloc/ and your systems default man page tree (under $prefix, of course).</p>
169
171
<p>The following section presents an example of API usage.</p>
170
172
<h2><a class="anchor" id="interface_example">
171
Interface example</a></h2>
172
<p>This section shows how to use hwloc with an small example <code>hwloc-hello.c</code> that just prints the topology and binds itself to the first processor of the second core of the machine.</p>
173
<p>Hardware Location provides a pkg-config object, so compiling the example boils down to</p>
174
<div class="fragment"><pre class="fragment">
175
CFLAGS += $(pkg-config --cflags hwloc)
176
LDLIBS += $(pkg-config --libs hwloc)
177
cc hwloc-hello.c $(CFLAGS) -o hwloc-hello $(LDLIBS)
178
</pre></div><div class="fragment"><pre class="fragment"><span class="comment">/* Example hwloc API program.</span>
174
<p>The following small C example (named ``hwloc-hello.c'') prints the topology of the machine and bring the process to the first processor of the second core of the machine.</p>
175
<div class="fragment"><pre class="fragment"><span class="comment">/* Example hwloc API program.</span>
179
176
<span class="comment"> *</span>
180
177
<span class="comment"> * Copyright © 2009 INRIA, Université Bordeaux 1</span>
178
<span class="comment"> * Copyright © 2009 Cisco Systems, Inc. All rights reserved.</span>
181
179
<span class="comment"> *</span>
182
<span class="comment"> * topo-hello.c </span>
180
<span class="comment"> * hwloc-hello.c </span>
183
181
<span class="comment"> */</span>
185
183
<span class="preprocessor">#include <hwloc.h></span>
187
<span class="keyword">static</span> <span class="keywordtype">void</span> print_children(<a class="code" href="group__hwlocality__topology.html#ga9d1e76ee15a7dee158b786c30b6a6e38" title="Topology context.">hwloc_topology_t</a> topology, <a class="code" href="structhwloc__obj.html" title="Structure of a topology object.">hwloc_obj_t</a> obj, <span class="keywordtype">int</span> depth)
185
<span class="keyword">static</span> <span class="keywordtype">void</span> print_children(<a class="code" href="group__hwlocality__topology.html#ga9d1e76ee15a7dee158b786c30b6a6e38" title="Topology context.">hwloc_topology_t</a> topology, <a class="code" href="structhwloc__obj.html" title="Structure of a topology object.">hwloc_obj_t</a> obj,
186
<span class="keywordtype">int</span> depth)
189
<span class="keywordtype">char</span> <span class="keywordtype">string</span>[128];
190
<span class="keywordtype">int</span> i;
188
<span class="keywordtype">char</span> <span class="keywordtype">string</span>[128];
189
<span class="keywordtype">int</span> i;
192
<a class="code" href="group__hwlocality__conversion.html#ga612dc210053b65d2466ac7ad39db92a4" title="Stringify a given topology object into a human-readable form.">hwloc_obj_snprintf</a>(<span class="keywordtype">string</span>, <span class="keyword">sizeof</span>(<span class="keywordtype">string</span>), topology, obj, <span class="stringliteral">"#"</span>, 0);
193
printf(<span class="stringliteral">"%*s%s\n"</span>, 2*depth, <span class="stringliteral">""</span>, <span class="keywordtype">string</span>);
194
<span class="keywordflow">for</span> (i = 0; i < obj-><a class="code" href="structhwloc__obj.html#aac3f6da35c9b57599909a44ce2b716c1" title="Number of children.">arity</a>; i++)
195
print_children(topology, obj-><a class="code" href="structhwloc__obj.html#a04d05403da37bfe17cd63b7c7dd07b1f" title="Children, children[0 .. arity -1].">children</a>[i], depth + 1);
191
<a class="code" href="group__hwlocality__conversion.html#ga612dc210053b65d2466ac7ad39db92a4" title="Stringify a given topology object into a human-readable form.">hwloc_obj_snprintf</a>(<span class="keywordtype">string</span>, <span class="keyword">sizeof</span>(<span class="keywordtype">string</span>), topology, obj, <span class="stringliteral">"#"</span>, 0);
192
printf(<span class="stringliteral">"%*s%s\n"</span>, 2*depth, <span class="stringliteral">""</span>, <span class="keywordtype">string</span>);
193
<span class="keywordflow">for</span> (i = 0; i < obj-><a class="code" href="structhwloc__obj.html#aac3f6da35c9b57599909a44ce2b716c1" title="Number of children.">arity</a>; i++) {
194
print_children(topology, obj-><a class="code" href="structhwloc__obj.html#a04d05403da37bfe17cd63b7c7dd07b1f" title="Children, children[0 .. arity -1].">children</a>[i], depth + 1);
198
<span class="keywordtype">int</span> main(<span class="keywordtype">void</span>)
198
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
200
<span class="comment">/* Topology object */</span>
201
<a class="code" href="group__hwlocality__topology.html#ga9d1e76ee15a7dee158b786c30b6a6e38" title="Topology context.">hwloc_topology_t</a> topology;
203
<span class="comment">/* Allocate and initialize topology object. */</span>
204
<a class="code" href="group__hwlocality__creation.html#ga03fd4a16d8b9ee1ffc32b25fd2f6bdfa" title="Allocate a topology context.">hwloc_topology_init</a>(&topology);
206
<span class="comment">/* ... Optionally, put detection configuration here to e.g. ignore some</span>
207
<span class="comment"> objects types, define a synthetic topology, etc.... The default is</span>
208
<span class="comment"> to detect all the objects of the machine that the caller is allowed</span>
209
<span class="comment"> to access.</span>
210
<span class="comment"> See Configure Topology Detection. */</span>
212
<span class="comment">/* Perform the topology detection. */</span>
213
<a class="code" href="group__hwlocality__creation.html#gabdf58d87ad77f6615fccdfe0535ff826" title="Build the actual topology.">hwloc_topology_load</a>(topology);
216
<span class="comment">/* Optionally, get some additional topology information</span>
217
<span class="comment"> * in case we need the topology depth later.</span>
218
<span class="comment"> */</span>
219
<span class="keywordtype">unsigned</span> topodepth = <a class="code" href="group__hwlocality__information.html#ga3cc2255e237b751a6c8efa8703b3daf5" title="Get the depth of the hierachical tree of objects.">hwloc_topology_get_depth</a>(topology);
222
<span class="comment">/* Walk the topology with an array style, from level 0 (always the</span>
223
<span class="comment"> * system level) to the lowest level (always the proc level). */</span>
224
<span class="keywordtype">int</span> depth, i;
225
<span class="keywordtype">char</span> <span class="keywordtype">string</span>[128];
226
<span class="keywordflow">for</span> (depth = 0; depth < topodepth; depth++) {
227
<span class="keywordflow">for</span> (i = 0; i < <a class="code" href="group__hwlocality__information.html#gab17065e3d53455973844568d9f21c72c" title="Returns the width of level at depth depth.">hwloc_get_nbobjs_by_depth</a>(topology, depth); i++) {
228
<a class="code" href="group__hwlocality__conversion.html#ga612dc210053b65d2466ac7ad39db92a4" title="Stringify a given topology object into a human-readable form.">hwloc_obj_snprintf</a>(<span class="keywordtype">string</span>, <span class="keyword">sizeof</span>(<span class="keywordtype">string</span>), topology,
229
<a class="code" href="group__hwlocality__traversal.html#gabf8a98ad085460a4982cc7b74c344b71" title="Returns the topology object at index index from depth depth.">hwloc_get_obj_by_depth</a>(topology, depth, i), <span class="stringliteral">"#"</span>, 0);
230
printf(<span class="stringliteral">"%s\n"</span>, <span class="keywordtype">string</span>);
200
<span class="keywordtype">int</span> depth, i;
201
<span class="keywordtype">char</span> <span class="keywordtype">string</span>[128];
202
<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> topodepth;
203
<a class="code" href="group__hwlocality__topology.html#ga9d1e76ee15a7dee158b786c30b6a6e38" title="Topology context.">hwloc_topology_t</a> topology;
204
<a class="code" href="group__hwlocality__cpuset.html#ga7366332f7090f5b54d4b25a0c2c4b411" title="Set of CPUs represented as an opaque pointer to an internal bitmask.">hwloc_cpuset_t</a> cpuset;
205
<a class="code" href="structhwloc__obj.html" title="Structure of a topology object.">hwloc_obj_t</a> obj;
207
<span class="comment">/* Allocate and initialize topology object. */</span>
208
<a class="code" href="group__hwlocality__creation.html#ga03fd4a16d8b9ee1ffc32b25fd2f6bdfa" title="Allocate a topology context.">hwloc_topology_init</a>(&topology);
210
<span class="comment">/* ... Optionally, put detection configuration here to e.g. ignore</span>
211
<span class="comment"> some objects types, define a synthetic topology, etc.... </span>
212
<span class="comment"></span>
213
<span class="comment"> The default is to detect all the objects of the machine that</span>
214
<span class="comment"> the caller is allowed to access. See Configure Topology</span>
215
<span class="comment"> Detection. */</span>
217
<span class="comment">/* Perform the topology detection. */</span>
218
<a class="code" href="group__hwlocality__creation.html#gabdf58d87ad77f6615fccdfe0535ff826" title="Build the actual topology.">hwloc_topology_load</a>(topology);
220
<span class="comment">/* Optionally, get some additional topology information</span>
221
<span class="comment"> in case we need the topology depth later. */</span>
222
topodepth = <a class="code" href="group__hwlocality__information.html#ga3cc2255e237b751a6c8efa8703b3daf5" title="Get the depth of the hierachical tree of objects.">hwloc_topology_get_depth</a>(topology);
224
<span class="comment">/* Walk the topology with an array style, from level 0 (always the</span>
225
<span class="comment"> system level) to the lowest level (always the proc level). */</span>
226
<span class="keywordflow">for</span> (depth = 0; depth < topodepth; depth++) {
227
printf(<span class="stringliteral">"*** Objects at level %d\n"</span>, depth);
228
<span class="keywordflow">for</span> (i = 0; i < <a class="code" href="group__hwlocality__information.html#gab17065e3d53455973844568d9f21c72c" title="Returns the width of level at depth depth.">hwloc_get_nbobjs_by_depth</a>(topology, depth);
230
<a class="code" href="group__hwlocality__conversion.html#ga612dc210053b65d2466ac7ad39db92a4" title="Stringify a given topology object into a human-readable form.">hwloc_obj_snprintf</a>(<span class="keywordtype">string</span>, <span class="keyword">sizeof</span>(<span class="keywordtype">string</span>), topology,
231
<a class="code" href="group__hwlocality__traversal.html#gabf8a98ad085460a4982cc7b74c344b71" title="Returns the topology object at index index from depth depth.">hwloc_get_obj_by_depth</a>(topology, depth, i),
232
<span class="stringliteral">"#"</span>, 0);
233
printf(<span class="stringliteral">"Index %d: %s\n"</span>, i, <span class="keywordtype">string</span>);
234
<span class="comment">/* Walk the topology with a tree style. */</span>
235
print_children(topology, <a class="code" href="group__hwlocality__helper__traversal__basic.html#gab39658e42f1046db0f8870a0d0ba9f42" title="Returns the top-object of the topology-tree. Its type is HWLOC_OBJ_SYSTEM.">hwloc_get_system_obj</a>(topology), 0);
238
<span class="comment">/* Print the number of sockets. */</span>
239
depth = <a class="code" href="group__hwlocality__information.html#ga8bec782e21be313750da70cf7428b374" title="Returns the depth of objects of type type.">hwloc_get_type_depth</a>(topology, <a class="code" href="group__hwlocality__types.html#ggacd37bb612667dc437d66bfb175a8dc55a1ac6e07775ae4324b3fe9dbd72c785ec" title="Socket, physical package, or chip. In the physical meaning, i.e. that you can add...">HWLOC_OBJ_SOCKET</a>);
240
<span class="keywordflow">if</span> (depth == <a class="code" href="group__hwlocality__information.html#ga9e86ce528f626330de2da7adb6c4e02e" title="No object of given type exists in the topology.">HWLOC_TYPE_DEPTH_UNKNOWN</a>)
241
printf(<span class="stringliteral">"The number of sockets is unknown\n"</span>);
242
<span class="keywordflow">else</span>
243
printf(<span class="stringliteral">"%u socket(s)\n"</span>, <a class="code" href="group__hwlocality__information.html#gab17065e3d53455973844568d9f21c72c" title="Returns the width of level at depth depth.">hwloc_get_nbobjs_by_depth</a>(topology, depth));
246
<span class="comment">/* Find out where cores are, or else smaller sets of CPUs if the OS</span>
247
<span class="comment"> * doesn't have the notion of core. */</span>
248
depth = <a class="code" href="group__hwlocality__helper__types.html#gaa0835c86ef2ce8c62637d61a1cf134f9" title="Returns the depth of objects of type type or below.">hwloc_get_type_or_below_depth</a>(topology, <a class="code" href="group__hwlocality__types.html#ggacd37bb612667dc437d66bfb175a8dc55ac793958f330bca371aa1535de8aff45f" title="Core. A computation unit (may be shared by several logical processors).">HWLOC_OBJ_CORE</a>);
250
<span class="comment">/* Get last one. */</span>
251
<a class="code" href="structhwloc__obj.html" title="Structure of a topology object.">hwloc_obj_t</a> obj = <a class="code" href="group__hwlocality__traversal.html#gabf8a98ad085460a4982cc7b74c344b71" title="Returns the topology object at index index from depth depth.">hwloc_get_obj_by_depth</a>(topology, depth, <a class="code" href="group__hwlocality__information.html#gab17065e3d53455973844568d9f21c72c" title="Returns the width of level at depth depth.">hwloc_get_nbobjs_by_depth</a>(topology, depth) - 1);
252
<span class="keywordflow">if</span> (!obj)
253
<span class="keywordflow">return</span> 0;
255
<span class="comment">/* Get a copy of its cpuset that we may modify. */</span>
256
<a class="code" href="group__hwlocality__cpuset.html#ga7366332f7090f5b54d4b25a0c2c4b411" title="Set of CPUs represented as an opaque pointer to an internal bitmask.">hwloc_cpuset_t</a> cpuset = <a class="code" href="group__hwlocality__cpuset.html#ga19d8c163e4834ba69c808560aa5a89b3" title="Duplicate CPU set set by allocating a new CPU set and copying its contents.">hwloc_cpuset_dup</a>(obj-><a class="code" href="structhwloc__obj.html#a67925e0f2c47f50408fbdb9bddd0790f" title="CPUs covered by this object.">cpuset</a>);
258
<span class="comment">/* Get only one logical processor (in case the core is SMT/hyperthreaded). */</span>
237
<span class="comment">/* Walk the topology with a tree style. */</span>
238
printf(<span class="stringliteral">"*** Printing overall tree\n"</span>);
239
print_children(topology, <a class="code" href="group__hwlocality__helper__traversal__basic.html#gab39658e42f1046db0f8870a0d0ba9f42" title="Returns the top-object of the topology-tree. Its type is HWLOC_OBJ_SYSTEM.">hwloc_get_system_obj</a>(topology), 0);
241
<span class="comment">/* Print the number of sockets. */</span>
242
depth = <a class="code" href="group__hwlocality__information.html#ga8bec782e21be313750da70cf7428b374" title="Returns the depth of objects of type type.">hwloc_get_type_depth</a>(topology, <a class="code" href="group__hwlocality__types.html#ggacd37bb612667dc437d66bfb175a8dc55a1ac6e07775ae4324b3fe9dbd72c785ec" title="Socket, physical package, or chip. In the physical meaning, i.e. that you can add...">HWLOC_OBJ_SOCKET</a>);
243
<span class="keywordflow">if</span> (depth == <a class="code" href="group__hwlocality__information.html#ga9e86ce528f626330de2da7adb6c4e02e" title="No object of given type exists in the topology.">HWLOC_TYPE_DEPTH_UNKNOWN</a>) {
244
printf(<span class="stringliteral">"*** The number of sockets is unknown\n"</span>);
245
} <span class="keywordflow">else</span> {
246
printf(<span class="stringliteral">"*** %u socket(s)\n"</span>,
247
<a class="code" href="group__hwlocality__information.html#gab17065e3d53455973844568d9f21c72c" title="Returns the width of level at depth depth.">hwloc_get_nbobjs_by_depth</a>(topology, depth));
250
<span class="comment">/* Find out where cores are, or else smaller sets of CPUs if </span>
251
<span class="comment"> the OS doesn't have the notion of a "core". */</span>
252
depth = <a class="code" href="group__hwlocality__helper__types.html#gaa0835c86ef2ce8c62637d61a1cf134f9" title="Returns the depth of objects of type type or below.">hwloc_get_type_or_below_depth</a>(topology, <a class="code" href="group__hwlocality__types.html#ggacd37bb612667dc437d66bfb175a8dc55ac793958f330bca371aa1535de8aff45f" title="Core. A computation unit (may be shared by several logical processors).">HWLOC_OBJ_CORE</a>);
254
<span class="comment">/* Get last level. */</span>
255
obj = <a class="code" href="group__hwlocality__traversal.html#gabf8a98ad085460a4982cc7b74c344b71" title="Returns the topology object at index index from depth depth.">hwloc_get_obj_by_depth</a>(topology, depth,
256
<a class="code" href="group__hwlocality__information.html#gab17065e3d53455973844568d9f21c72c" title="Returns the width of level at depth depth.">hwloc_get_nbobjs_by_depth</a>(topology, depth) - 1);
257
<span class="keywordflow">if</span> (obj) {
258
<span class="comment">/* Get a copy of its cpuset that we may modify. */</span>
259
cpuset = <a class="code" href="group__hwlocality__cpuset.html#ga19d8c163e4834ba69c808560aa5a89b3" title="Duplicate CPU set set by allocating a new CPU set and copying its contents.">hwloc_cpuset_dup</a>(obj-><a class="code" href="structhwloc__obj.html#a67925e0f2c47f50408fbdb9bddd0790f" title="CPUs covered by this object.">cpuset</a>);
261
<span class="comment">/* Get only one logical processor (in case the core is</span>
262
<span class="comment"> SMT/hyperthreaded). */</span>
259
263
<a class="code" href="group__hwlocality__cpuset.html#ga548a6620cce008fc5b1e2110d25135fe" title="Keep a single CPU among those set in CPU set set.">hwloc_cpuset_singlify</a>(cpuset);
261
<span class="comment">/* And try to bind ourself there. */</span>
265
<span class="comment">/* And try to bind ourself there. */</span>
262
266
<span class="keywordflow">if</span> (<a class="code" href="group__hwlocality__binding.html#ga47053da286384d86ec3e4fb3fe148dae" title="Bind current process or thread on cpus given in cpuset set.">hwloc_set_cpubind</a>(topology, cpuset, 0)) {
263
<span class="keywordtype">char</span> *str = NULL;
264
<a class="code" href="group__hwlocality__cpuset.html#ga29160016d2e89318b5db99046d93dc0a" title="Stringify a cpuset into a newly allocated string.">hwloc_cpuset_asprintf</a>(&str, obj-><a class="code" href="structhwloc__obj.html#a67925e0f2c47f50408fbdb9bddd0790f" title="CPUs covered by this object.">cpuset</a>);
265
printf(<span class="stringliteral">"Couldn't bind to cpuset %s\n"</span>, str);
267
<span class="keywordtype">char</span> *str;
268
<a class="code" href="group__hwlocality__cpuset.html#ga29160016d2e89318b5db99046d93dc0a" title="Stringify a cpuset into a newly allocated string.">hwloc_cpuset_asprintf</a>(&str, obj-><a class="code" href="structhwloc__obj.html#a67925e0f2c47f50408fbdb9bddd0790f" title="CPUs covered by this object.">cpuset</a>);
269
printf(<span class="stringliteral">"Couldn't bind to cpuset %s\n"</span>, str);
269
273
<span class="comment">/* Free our cpuset copy */</span>
270
274
<a class="code" href="group__hwlocality__cpuset.html#gaf5d5a9e082a43f8311fdcff55e611b23" title="Free CPU set set.">hwloc_cpuset_free</a>(cpuset);
272
<span class="comment">/* Destroy topology object. */</span>
273
<a class="code" href="group__hwlocality__creation.html#ga9f34a640b6fd28d23699d4d084667b15" title="Terminate and free a topology context.">hwloc_topology_destroy</a>(topology);
275
<span class="keywordflow">return</span> 0;
277
<span class="comment">/* Destroy topology object. */</span>
278
<a class="code" href="group__hwlocality__creation.html#ga9f34a640b6fd28d23699d4d084667b15" title="Terminate and free a topology context.">hwloc_topology_destroy</a>(topology);
280
<span class="keywordflow">return</span> 0;
282
</pre></div><p>hwloc provides a <code>pkg-config</code> executable to obtain relevant compiler and linker flags. For example, it can be used thusly to compile applications that utilize the hwloc library (assuming GNU Make):</p>
283
<div class="fragment"><pre class="fragment">
284
CFLAGS += $(pkg-config --cflags hwloc)
285
LDLIBS += $(pkg-config --libs hwloc)
286
cc hwloc-hello.c $(CFLAGS) -o hwloc-hello $(LDLIBS)
287
</pre></div><p>On a machine with 4GB of RAM and 2 processor sockets -- each socket of which has two processor cores -- the output from running <code>hwloc-hello</code> could be something like the following:</p>
288
<div class="fragment"><pre class="fragment">
290
*** Objects at level 0
291
Index 0: System(3938MB)
292
*** Objects at level 1
295
*** Objects at level 2
300
*** Objects at level 3
305
*** Printing overall tree
278
320
</div><div class="section" id="bugs">
279
321
<h2><a class="anchor" id="bugs">