1
1

Merge pull request #642 from rhc54/topic/hwloc

Update hwloc to 1.11.0
Этот коммит содержится в:
rhc54 2015-06-13 12:09:58 -07:00
родитель 4384131e65 ff92781ec4
Коммит adbff46a13
113 изменённых файлов: 5121 добавлений и 59627 удалений

Просмотреть файл

@ -1,6 +1,6 @@
# #
# Copyright (c) 2011-2014 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2011-2014 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2014 Intel, Inc. All right reserved. # Copyright (c) 2014-2015 Intel, Inc. All right reserved.
# $COPYRIGHT$ # $COPYRIGHT$
# #
# Additional copyrights may follow # Additional copyrights may follow
@ -25,16 +25,16 @@ EXTRA_DIST = \
SUBDIRS = hwloc SUBDIRS = hwloc
# Headers and sources # Headers and sources
headers = hwloc191.h headers = hwloc1110.h
sources = hwloc191_component.c sources = hwloc1110_component.c
# We only ever build this component statically # We only ever build this component statically
noinst_LTLIBRARIES = libmca_hwloc_hwloc191.la noinst_LTLIBRARIES = libmca_hwloc_hwloc1110.la
libmca_hwloc_hwloc191_la_SOURCES = $(headers) $(sources) libmca_hwloc_hwloc1110_la_SOURCES = $(headers) $(sources)
nodist_libmca_hwloc_hwloc191_la_SOURCES = $(nodist_headers) nodist_libmca_hwloc_hwloc1110_la_SOURCES = $(nodist_headers)
libmca_hwloc_hwloc191_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc191_LDFLAGS) libmca_hwloc_hwloc1110_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc1110_LDFLAGS)
libmca_hwloc_hwloc191_la_LIBADD = $(opal_hwloc_hwloc191_LIBS) libmca_hwloc_hwloc1110_la_LIBADD = $(opal_hwloc_hwloc1110_LIBS)
libmca_hwloc_hwloc191_la_DEPENDENCIES = \ libmca_hwloc_hwloc1110_la_DEPENDENCIES = \
$(HWLOC_top_builddir)/src/libhwloc_embedded.la $(HWLOC_top_builddir)/src/libhwloc_embedded.la
# Since the rest of the code base includes the underlying hwloc.h, we # Since the rest of the code base includes the underlying hwloc.h, we

170
opal/mca/hwloc/hwloc1110/configure.m4 Обычный файл
Просмотреть файл

@ -0,0 +1,170 @@
# -*- shell-script -*-
#
# Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
#
# Priority
#
AC_DEFUN([MCA_opal_hwloc_hwloc1110_PRIORITY], [90])
#
# Force this component to compile in static-only mode
#
AC_DEFUN([MCA_opal_hwloc_hwloc1110_COMPILE_MODE], [
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
$4="static"
AC_MSG_RESULT([$$4])
])
# Include hwloc m4 files
m4_include(opal/mca/hwloc/hwloc1110/hwloc/config/hwloc.m4)
m4_include(opal/mca/hwloc/hwloc1110/hwloc/config/hwloc_pkg.m4)
m4_include(opal/mca/hwloc/hwloc1110/hwloc/config/hwloc_check_attributes.m4)
m4_include(opal/mca/hwloc/hwloc1110/hwloc/config/hwloc_check_visibility.m4)
m4_include(opal/mca/hwloc/hwloc1110/hwloc/config/hwloc_check_vendor.m4)
m4_include(opal/mca/hwloc/hwloc1110/hwloc/config/hwloc_components.m4)
# MCA_hwloc_hwloc1110_POST_CONFIG()
# ---------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc1110_POST_CONFIG],[
OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc1110_basedir])
# If we won, then do all the rest of the setup
AS_IF([test "$1" = "1" && test "$opal_hwloc_hwloc1110_support" = "yes"],
[
# Set this variable so that the framework m4 knows what
# file to include in opal/mca/hwloc/hwloc.h
opal_hwloc_hwloc1110_basedir=opal/mca/hwloc/hwloc1110
opal_hwloc_base_include="$opal_hwloc_hwloc1110_basedir/hwloc1110.h"
# Add some stuff to CPPFLAGS so that the rest of the source
# tree can be built
file=$opal_hwloc_hwloc1110_basedir/hwloc
CPPFLAGS="$CPPFLAGS -I$OPAL_TOP_SRCDIR/$file/include"
AS_IF([test "$OPAL_TOP_BUILDDIR" != "$OPAL_TOP_SRCDIR"],
[CPPFLAGS="$CPPFLAGS -I$OPAL_TOP_BUILDDIR/$file/include"])
unset file
])
OPAL_VAR_SCOPE_POP
# This must be run unconditionally
HWLOC_DO_AM_CONDITIONALS
])dnl
# MCA_hwloc_hwloc1110_CONFIG([action-if-found], [action-if-not-found])
# --------------------------------------------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc1110_CONFIG],[
# Hwloc needs to know if we have Verbs support
AC_REQUIRE([OPAL_CHECK_VERBS_DIR])
AC_CONFIG_FILES([opal/mca/hwloc/hwloc1110/Makefile])
OPAL_VAR_SCOPE_PUSH([HWLOC_VERSION opal_hwloc_hwloc1110_save_CPPFLAGS opal_hwloc_hwloc1110_save_LDFLAGS opal_hwloc_hwloc1110_save_LIBS opal_hwloc_hwloc1110_save_cairo opal_hwloc_hwloc1110_save_xml opal_hwloc_hwloc1110_basedir opal_hwloc_hwloc1110_file opal_hwloc_hwloc1110_save_cflags CPPFLAGS_save LIBS_save])
# default to this component not providing support
opal_hwloc_hwloc1110_basedir=opal/mca/hwloc/hwloc1110
opal_hwloc_hwloc1110_support=no
if test "$with_hwloc" = "internal" -o "$with_hwloc" = "" -o "$with_hwloc" = "yes"; then
opal_hwloc_hwloc1110_save_CPPFLAGS=$CPPFLAGS
opal_hwloc_hwloc1110_save_LDFLAGS=$LDFLAGS
opal_hwloc_hwloc1110_save_LIBS=$LIBS
# Run the hwloc configuration - set the prefix to minimize
# the chance that someone will use the internal symbols
HWLOC_SET_SYMBOL_PREFIX([opal_hwloc1110_])
# save XML or graphical options
opal_hwloc_hwloc1110_save_cairo=$enable_cairo
opal_hwloc_hwloc1110_save_xml=$enable_xml
opal_hwloc_hwloc1110_save_static=$enable_static
opal_hwloc_hwloc1110_save_shared=$enable_shared
opal_hwloc_hwloc1110_save_plugins=$enable_plugins
# never enable hwloc's graphical option
enable_cairo=no
# never enable hwloc's plugin system
enable_plugins=no
enable_static=yes
enable_shared=no
# Override -- disable hwloc's libxml2 support, but enable the
# native hwloc XML support
enable_libxml2=no
enable_xml=yes
# hwloc checks for compiler visibility, and its needs to do
# this without "picky" flags.
opal_hwloc_hwloc1110_save_cflags=$CFLAGS
CFLAGS=$OPAL_CFLAGS_BEFORE_PICKY
HWLOC_SETUP_CORE([opal/mca/hwloc/hwloc1110/hwloc],
[AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([yes])
HWLOC_VERSION="internal v`$srcdir/$opal_hwloc_hwloc1110_basedir/hwloc/config/hwloc_get_version.sh $srcdir/$opal_hwloc_hwloc1110_basedir/hwloc/VERSION`"
# Build flags for our Makefile.am
opal_hwloc_hwloc1110_LDFLAGS='$(HWLOC_EMBEDDED_LDFLAGS)'
opal_hwloc_hwloc1110_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_hwloc_hwloc1110_basedir"'/hwloc/src/libhwloc_embedded.la $(HWLOC_EMBEDDED_LIBS)'
opal_hwloc_hwloc1110_support=yes
AC_DEFINE_UNQUOTED([HWLOC_HWLOC1110_HWLOC_VERSION],
["$HWLOC_VERSION"],
[Version of hwloc])
# Do we have verbs support?
CPPFLAGS_save=$CPPFLAGS
AS_IF([test "$opal_want_verbs" = "yes"],
[CPPFLAGS="-I$opal_verbs_dir/include $CPPFLAGS"])
AC_CHECK_HEADERS([infiniband/verbs.h])
CPPFLAGS=$CPPFLAGS_save
],
[AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([no])
opal_hwloc_hwloc1110_support=no])
CFLAGS=$opal_hwloc_hwloc1110_save_cflags
# Restore some env variables, if necessary
AS_IF([test -n "$opal_hwloc_hwloc1110_save_cairo"],
[enable_cairo=$opal_hwloc_hwloc1110_save_cairo])
AS_IF([test -n "$opal_hwloc_hwloc1110_save_xml"],
[enable_xml=$opal_hwloc_hwloc1110_save_xml])
AS_IF([test -n "$opal_hwloc_hwloc1110_save_static"],
[enable_static=$opal_hwloc_hwloc1110_save_static])
AS_IF([test -n "$opal_hwloc_hwloc1110_save_shared"],
[enable_shared=$opal_hwloc_hwloc1110_save_shared])
AS_IF([test -n "$opal_hwloc_hwloc1110_save_plugins"],
[enable_plugins=$opal_hwloc_hwloc1110_save_shared])
CPPFLAGS=$opal_hwloc_hwloc1110_save_CPPFLAGS
LDFLAGS=$opal_hwloc_hwloc1110_save_LDFLAGS
LIBS=$opal_hwloc_hwloc1110_save_LIBS
AC_SUBST([opal_hwloc_hwloc1110_CFLAGS])
AC_SUBST([opal_hwloc_hwloc1110_CPPFLAGS])
AC_SUBST([opal_hwloc_hwloc1110_LDFLAGS])
AC_SUBST([opal_hwloc_hwloc1110_LIBS])
# Finally, add some flags to the wrapper compiler so that our
# headers can be found.
hwloc_hwloc1110_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS"
hwloc_hwloc1110_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS"
hwloc_hwloc1110_WRAPPER_EXTRA_CPPFLAGS='-I${includedir}/openmpi/'"$opal_hwloc_hwloc1110_basedir/hwloc/include"
fi
# Done!
AS_IF([test "$opal_hwloc_hwloc1110_support" = "yes"],
[$1],
[$2])
OPAL_VAR_SCOPE_POP
])dnl

Просмотреть файл

@ -1,6 +1,6 @@
Copyright © 2009 CNRS Copyright © 2009 CNRS
Copyright © 2009 inria. All rights reserved. Copyright © 2009 inria. All rights reserved.
Copyright © 2009 Université Bordeaux 1 Copyright © 2009 Université Bordeaux
Copyright © 2009 Cisco Systems, Inc. All rights reserved. Copyright © 2009 Cisco Systems, Inc. All rights reserved.
Copyright © 2012 Blue Brain Project, EPFL. All rights reserved. Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
See COPYING in top-level directory. See COPYING in top-level directory.

Просмотреть файл

@ -1,5 +1,5 @@
# Copyright © 2009-2014 Inria. All rights reserved. # Copyright © 2009-2015 Inria. All rights reserved.
# Copyright © 2009 Université Bordeaux 1 # Copyright © 2009 Université Bordeaux
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory. # See COPYING in top-level directory.
@ -9,7 +9,7 @@ ACLOCAL_AMFLAGS = -I ./config
SUBDIRS = src include SUBDIRS = src include
if HWLOC_BUILD_STANDALONE if HWLOC_BUILD_STANDALONE
SUBDIRS += utils tests SUBDIRS += tests utils
# We need doc/ if HWLOC_BUILD_DOXYGEN, or during make install if HWLOC_INSTALL_DOXYGEN. # We need doc/ if HWLOC_BUILD_DOXYGEN, or during make install if HWLOC_INSTALL_DOXYGEN.
# There's no INSTALL_SUBDIRS, so always enter doc/ and check HWLOC_BUILD/INSTALL_DOXYGEN there # There's no INSTALL_SUBDIRS, so always enter doc/ and check HWLOC_BUILD/INSTALL_DOXYGEN there
SUBDIRS += doc SUBDIRS += doc

Просмотреть файл

@ -1,6 +1,6 @@
Copyright © 2009 CNRS Copyright © 2009 CNRS
Copyright © 2009-2014 Inria. All rights reserved. Copyright © 2009-2015 Inria. All rights reserved.
Copyright © 2009-2013 Université Bordeaux 1 Copyright © 2009-2013 Université Bordeaux
Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
$COPYRIGHT$ $COPYRIGHT$
@ -17,12 +17,168 @@ bug fixes (and other actions) for each version of hwloc since version
in v0.9.1). in v0.9.1).
Version 1.9.2 Version 1.11.0
------------- --------------
* Fix some build failures in private/misc.h. * API
Thanks to Pavan Balaji and Ralph Castain for the reports. + Socket objects are renamed into Package to align with the terminology
* Fix failures to detect X11/Xutil.h on some Solaris platforms. used by processor vendors. The old HWLOC_OBJ_SOCKET type and "Socket"
Thanks to Siegmar Gross for reporting the failure. name are still supported for backward compatibility.
+ HWLOC_OBJ_NODE is replaced with HWLOC_OBJ_NUMANODE for clarification.
HWLOC_OBJ_NODE is still supported for backward compatibility.
"Node" and "NUMANode" strings are supported as in earlier releases.
* Detection improvements
+ Add support for Intel Knights Landing Xeon Phi.
Thanks to Grzegorz Andrejczuk and Lukasz Anaczkowski.
+ Add Vendor, Model, Revision, SerialNumber, Type and LinuxDeviceID
info attributes to Block OS devices on Linux. Thanks to Vineet Pedaballe
for the help.
- Add --disable-libudev to avoid dependency on the libudev library.
+ Add "MemoryDevice" Misc objects with information about DIMMs, on Linux
when privileged and when I/O is enabled.
Thanks to Vineet Pedaballe for the help.
+ Add a PCISlot attribute to PCI devices on Linux when supported to
identify the physical PCI slot where the board is plugged.
+ Add CPUStepping info attribute on x86 processors,
thanks to Thomas Röhl for the suggestion.
+ Ignore the device-tree on non-Power architectures to avoid buggy
detection on ARM. Thanks to Orion Poplawski for reporting the issue.
+ Work-around buggy Xeon E5v3 BIOS reporting invalid PCI-NUMA affinity
for the PCI links on the second processor.
+ Add support for CUDA compute capability 5.x, thanks Benjamin Worpitz.
+ Many fixes to the x86 backend
- Add L1i and fix L2/L3 type on old AMD processors without topoext support.
- Fix Intel CPU family and model numbers when basic family isn't 6 or 15.
- Fix package IDs on recent AMD processors.
- Fix misc issues due to incomplete APIC IDs on x2APIC processors.
- Avoid buggy discovery on old SGI Altix UVs with non-unique APIC IDs.
+ Gather total machine memory on NetBSD.
* Tools
+ lstopo
- Collapse identical PCI devices unless --no-collapse is given.
This avoids gigantic outputs when a PCI device contains dozens of
identical virtual functions.
- The ASCII art output is now called "ascii", for instance in
"lstopo -.ascii".
The former "txt" extension is retained for backward compatibility.
- Automatically scales graphical box width to the inner text in Cairo,
ASCII and Windows outputs.
- Add --rect to lstopo to force rectangular layout even for NUMA nodes.
- Objects may have a Type info attribute to specific a better type name
and display it in lstopo.
+ hwloc-annotate
- May now operate on all types of objects, including I/O.
- May now insert Misc objects in the topology.
- Do not drop instruction caches and I/O devices from the output anymore.
+ Fix lstopo path in hwloc-gather-topology after install.
* Misc
+ Fix hwloc/cudart.h for machines with multiple PCI domains,
thanks to Imre Kerr for reporting the problem.
+ Fix PCI Bridge-specific depth attribute.
+ Fix hwloc_bitmap_intersect() for two infinite bitmaps.
+ Improve the performance of object insertion by cpuset for large
topologies.
+ Prefix verbose XML import errors with the source name.
+ Improve pkg-config checks and error messages.
+ Fix excluding after a component with an argument in the HWLOC_COMPONENTS
environment variable.
+ Fix the recommended way in documentation and examples to allocate memory
on some node, it should use HWLOC_MEMBIND_BIND.
Thanks to Nicolas Bouzat for reporting the issue.
+ Add a "Miscellaneous objects" section in the documentation.
+ Add a FAQ entry "What happens to my topology if I disable symmetric
multithreading, hyper-threading, etc. ?" to the documentation.
Version 1.10.1
--------------
* Actually remove disallowed NUMA nodes from nodesets when the whole-system
flag isn't enabled.
* Fix the gathering of PCI domains. Thanks to James Custer for reporting
the issue and providing a patch.
* Fix the merging of identical parent and child in presence of Misc objects.
Thanks to Dave Love for reporting the issue.
* Fix some misordering of children when merging with ignore_keep_structure()
in partially allowed topologies.
* Fix an overzealous assertion in the debug code when running on a single-PU
host with I/O. Thanks to Thomas Van Doren for reporting the issue.
* Don't forget to setup NUMA node object nodesets in x86 backend (for BSDs)
and OSF/Tru64 backend.
* Fix cpuid-x86 build error with gcc -O3 on x86-32. Thanks to Thomas Van Doren
for reporting the issue.
* Fix support for future very large caches in the x86 backend.
* Fix vendor/device names for SR-IOV PCI devices on Linux.
* Fix an unlikely crash in case of buggy hierarchical distance matrix.
* Fix PU os_index on some AIX releases. Thanks to Hendryk Bockelmann and
Erik Schnetter for helping debugging.
* Fix hwloc_bitmap_isincluded() in case of infinite sets.
* Change hwloc-ls.desktop into a lstopo.desktop and only install it if
lstopo is built with Cairo/X11 support. It cannot work with a non-graphical
lstopo or hwloc-ls.
* Add support for the renaming of Socket into Package in future releases.
* Add support for the replacement of HWLOC_OBJ_NODE with HWLOC_OBJ_NUMANODE
in future releases.
* Clarify the documentation of distance matrices in hwloc.h and in the manpage
of the hwloc-distances. Thanks to Dave Love for the suggestion.
* Improve some error messages by displaying more information about the
hwloc library in use.
* Document how to deal with the ABI break when upgrading to the upcoming 2.0
See "How do I handle ABI breaks and API upgrades ?" in the FAQ.
Version 1.10.0
--------------
* API
+ Add hwloc_topology_export_synthetic() to export a topology to a
synthetic string without using lstopo. See the Synthetic topologies
section in the documentation.
+ Add hwloc_topology_set/get_userdata() to let the application save
a private pointer in the topology whenever it needs a way to find
its own object corresponding to a topology.
+ Add hwloc_get_numanode_obj_by_os_index() and document that this function
as well as hwloc_get_pu_obj_by_os_index() are good at converting
nodesets and cpusets into objects.
+ hwloc_distrib() does not ignore any objects anymore when there are
too many of them. They get merged with others instead.
Thanks to Tim Creech for reporting the issue.
* Tools
+ hwloc-bind --get <command-line> now executes the command after displaying
the binding instead of ignoring the command entirely.
Thanks to John Donners for the suggestion.
+ Clarify that memory sizes shown in lstopo are local by default
unless specified (total memory added in the root object).
* Synthetic topologies
+ Synthetic topology descriptions may now specify attributes such as
memory sizes and OS indexes. See the Synthetic topologies section
in the documentation.
+ lstopo now exports in this fully-detailed format by default.
The new option --export-synthetic-flags may be used to revert
back the old format.
* Documentation
+ Add the doc/examples/ subdirectory with several real-life examples,
including the already existing hwloc-hello.C for basics.
Thanks to Rob Aulwes for the suggestion.
+ Improve the documentation of CPU and memory binding in the API.
+ Add a FAQ entry about operating system errors, especially on AMD
platforms with buggy cache information.
+ Add a FAQ entry about loading many topologies in a single program.
* Misc
+ Work around buggy Linux kernels reporting 2 sockets instead
1 socket with 2 NUMA nodes for each Xeon E5 v3 (Haswell) processor.
+ pciutils/libpci support is now removed since libpciaccess works
well and there's also a Linux-specific PCI backend. For the record,
pciutils was GPL and therefore disabled by default since v1.6.2.
+ Add --disable-cpuid configure flag to work around buggy processor
simulators reporting invalid CPUID information.
Thanks for Andrew Friedley for reporting the issue.
+ Fix a racy use of libltdl when manipulating multiple topologies in
different threads.
Thanks to Andra Hugo for reporting the issue and testing patches.
+ Fix some build failures in private/misc.h.
Thanks to Pavan Balaji and Ralph Castain for the reports.
+ Fix failures to detect X11/Xutil.h on some Solaris platforms.
Thanks to Siegmar Gross for reporting the failure.
+ The plugin ABI has changed, this release will not load plugins
built against previous hwloc releases.
Version 1.9.1 Version 1.9.1
@ -384,7 +540,7 @@ Version 1.5.0
------------- -------------
* Backends * Backends
+ Do not limit the number of processors to 1024 on Solaris anymore. + Do not limit the number of processors to 1024 on Solaris anymore.
+ Gather total machine memory on FreeBSD. + Gather total machine memory on FreeBSD. Thanks to Cyril Roelandt.
+ XML topology files do not depend on the locale anymore. Float numbers + XML topology files do not depend on the locale anymore. Float numbers
such as NUMA distances or PCI link speeds now always use a dot as a such as NUMA distances or PCI link speeds now always use a dot as a
decimal separator. decimal separator.

446
opal/mca/hwloc/hwloc1110/hwloc/README Обычный файл
Просмотреть файл

@ -0,0 +1,446 @@
Introduction
hwloc provides command line tools and a C API to obtain the
hierarchical map of key computing elements, such as: NUMA memory nodes,
shared caches, processor packages, processor cores, processing units
(logical processors or "threads") and even I/O devices. hwloc also
gathers various attributes such as cache and memory information, and is
portable across a variety of different operating systems and platforms.
Additionally it may assemble the topologies of multiple machines into a
single one so as to let applications consult the topology of an entire
fabric or cluster at once.
hwloc primarily aims at helping high-performance computing (HPC)
applications, but is also applicable to any project seeking to exploit
code and/or data locality on modern computing platforms.
Note that the hwloc project represents the merger of the libtopology
project from inria and the Portable Linux Processor Affinity (PLPA)
sub-project from Open MPI. Both of these prior projects are now
deprecated. The first hwloc release was essentially a "re-branding" of
the libtopology code base, but with both a few genuinely new features
and a few PLPA-like features added in. Prior releases of hwloc included
documentation about switching from PLPA to hwloc; this documentation
has been dropped on the assumption that everyone who was using PLPA has
already switched to hwloc.
hwloc supports the following operating systems:
* Linux (including old kernels not having sysfs topology information,
with knowledge of cpusets, offline CPUs, ScaleMP vSMP, NumaScale
NumaConnect, and Kerrighed support) on all supported hardware,
including Intel Xeon Phi (either standalone or as a coprocessor).
* Solaris
* AIX
* Darwin / OS X
* FreeBSD and its variants (such as kFreeBSD/GNU)
* NetBSD
* OSF/1 (a.k.a., Tru64)
* HP-UX
* Microsoft Windows
* IBM BlueGene/Q Compute Node Kernel (CNK)
Since it uses standard Operating System information, hwloc's support is
mostly independant from the processor type (x86, powerpc, ...) and just
relies on the Operating System support. The only exception to this is
kFreeBSD, which does not support topology information, and hwloc thus
uses an x86-only CPUID-based backend (which can be used for other OSes
too, see the Components and plugins section).
To check whether hwloc works on a particular machine, just try to build
it and run lstopo or lstopo-no-graphics. If some things do not look
right (e.g. bogus or missing cache information), see Questions and Bugs
below.
hwloc only reports the number of processors on unsupported operating
systems; no topology information is available.
For development and debugging purposes, hwloc also offers the ability
to work on "fake" topologies:
* Symmetrical tree of resources generated from a list of level
arities
* Remote machine simulation through the gathering of Linux sysfs
topology files
hwloc can display the topology in a human-readable format, either in
graphical mode (X11), or by exporting in one of several different
formats, including: plain text, PDF, PNG, and FIG (see CLI Examples
below). Note that some of the export formats require additional support
libraries.
hwloc offers a programming interface for manipulating topologies and
objects. It also brings a powerful CPU bitmap API that is used to
describe topology objects location on physical/logical processors. See
the Programming Interface below. It may also be used to binding
applications onto certain cores or memory nodes. Several utility
programs are also provided to ease command-line manipulation of
topology objects, binding of processes, and so on.
Perl bindings are available from Bernd Kallies on CPAN.
Python bindings are available from Guy Streeter:
* Fedora RPM and tarball.
* git tree (html).
Installation
hwloc (http://www.open-mpi.org/projects/hwloc/) is available under the
BSD license. It is hosted as a sub-project of the overall Open MPI
project (http://www.open-mpi.org/). Note that hwloc does not require
any functionality from Open MPI -- it is a wholly separate (and much
smaller!) project and code base. It just happens to be hosted as part
of the overall Open MPI project.
Nightly development snapshots are available on the web site.
Additionally, the code can be directly cloned from Git:
shell$ git clone https://github.com/open-mpi/hwloc.git
shell$ cd hwloc
shell$ ./autogen.sh
Note that GNU Autoconf >=2.63, Automake >=1.10 and Libtool >=2.2.6 are
required when building from a Git clone.
Installation by itself is the fairly common GNU-based process:
shell$ ./configure --prefix=...
shell$ make
shell$ make install
The hwloc command-line tool "lstopo" produces human-readable topology
maps, as mentioned above. It can also export maps to the "fig" file
format. Support for PDF, Postscript, and PNG exporting is provided if
the "Cairo" development package (usually cairo-devel or libcairo2-dev)
can be found in "lstopo" when hwloc is configured and build.
The hwloc core may also benefit from the following development
packages:
* libnuma for memory binding and migration support on Linux
(numactl-devel or libnuma-dev package).
* libpciaccess for full I/O device discovery (libpciaccess-devel or
libpciaccess-dev package). On Linux, PCI discovery may still be
performed (without vendor/device names) even if libpciaccess cannot
be used.
* the AMD OpenCL implementation for OpenCL device discovery.
* the NVIDIA CUDA Toolkit for CUDA device discovery.
* the NVIDIA Tesla Development Kit for NVML device discovery.
* the NV-CONTROL X extension library (NVCtrl) for NVIDIA display
discovery.
* libxml2 for full XML import/export support (otherwise, the internal
minimalistic parser will only be able to import XML files that were
exported by the same hwloc release). See Importing and exporting
topologies from/to XML files for details. The relevant development
package is usually libxml2-devel or libxml2-dev.
* libudev on Linux for easier discovery of OS device information
(otherwise hwloc will try to manually parse udev raw files). The
relevant development package is usually libudev-devel or
libudev-dev.
* libtool's ltdl library for dynamic plugin loading. The relevant
development package is usually libtool-ltdl-devel or libltdl-dev.
PCI and XML support may be statically built inside the main hwloc
library, or as separate dynamically-loaded plugins (see the Components
and plugins section).
Note that because of the possibility of GPL taint, the pciutils library
libpci will not be used (remember that hwloc is BSD-licensed).
Also note that if you install supplemental libraries in non-standard
locations, hwloc's configure script may not be able to find them
without some help. You may need to specify additional CPPFLAGS,
LDFLAGS, or PKG_CONFIG_PATH values on the configure command line.
For example, if libpciaccess was installed into /opt/pciaccess, hwloc's
configure script may not find it be default. Try adding PKG_CONFIG_PATH
to the ./configure command line, like this:
./configure PKG_CONFIG_PATH=/opt/pciaccess/lib/pkgconfig ...
CLI Examples
On a 4-package 2-core machine with hyper-threading, the lstopo tool may
show the following graphical output:
dudley.png
Here's the equivalent output in textual form:
Machine (16GB)
Package L#0 + L3 L#0 (4096KB)
L2 L#0 (1024KB) + L1 L#0 (16KB) + Core L#0
PU L#0 (P#0)
PU L#1 (P#8)
L2 L#1 (1024KB) + L1 L#1 (16KB) + Core L#1
PU L#2 (P#4)
PU L#3 (P#12)
Package L#1 + L3 L#1 (4096KB)
L2 L#2 (1024KB) + L1 L#2 (16KB) + Core L#2
PU L#4 (P#1)
PU L#5 (P#9)
L2 L#3 (1024KB) + L1 L#3 (16KB) + Core L#3
PU L#6 (P#5)
PU L#7 (P#13)
Package L#2 + L3 L#2 (4096KB)
L2 L#4 (1024KB) + L1 L#4 (16KB) + Core L#4
PU L#8 (P#2)
PU L#9 (P#10)
L2 L#5 (1024KB) + L1 L#5 (16KB) + Core L#5
PU L#10 (P#6)
PU L#11 (P#14)
Package L#3 + L3 L#3 (4096KB)
L2 L#6 (1024KB) + L1 L#6 (16KB) + Core L#6
PU L#12 (P#3)
PU L#13 (P#11)
L2 L#7 (1024KB) + L1 L#7 (16KB) + Core L#7
PU L#14 (P#7)
PU L#15 (P#15)
Note that there is also an equivalent output in XML that is meant for
exporting/importing topologies but it is hardly readable to
human-beings (see Importing and exporting topologies from/to XML files
for details).
On a 4-package 2-core Opteron NUMA machine, the lstopo tool may show
the following graphical output:
hagrid.png
Here's the equivalent output in textual form:
Machine (32GB)
NUMANode L#0 (P#0 8190MB) + Package L#0
L2 L#0 (1024KB) + L1 L#0 (64KB) + Core L#0 + PU L#0 (P#0)
L2 L#1 (1024KB) + L1 L#1 (64KB) + Core L#1 + PU L#1 (P#1)
NUMANode L#1 (P#1 8192MB) + Package L#1
L2 L#2 (1024KB) + L1 L#2 (64KB) + Core L#2 + PU L#2 (P#2)
L2 L#3 (1024KB) + L1 L#3 (64KB) + Core L#3 + PU L#3 (P#3)
NUMANode L#2 (P#2 8192MB) + Package L#2
L2 L#4 (1024KB) + L1 L#4 (64KB) + Core L#4 + PU L#4 (P#4)
L2 L#5 (1024KB) + L1 L#5 (64KB) + Core L#5 + PU L#5 (P#5)
NUMANode L#3 (P#3 8192MB) + Package L#3
L2 L#6 (1024KB) + L1 L#6 (64KB) + Core L#6 + PU L#6 (P#6)
L2 L#7 (1024KB) + L1 L#7 (64KB) + Core L#7 + PU L#7 (P#7)
On a 2-package quad-core Xeon (pre-Nehalem, with 2 dual-core dies into
each package):
emmett.png
Here's the same output in textual form:
Machine (16GB)
Package L#0
L2 L#0 (4096KB)
L1 L#0 (32KB) + Core L#0 + PU L#0 (P#0)
L1 L#1 (32KB) + Core L#1 + PU L#1 (P#4)
L2 L#1 (4096KB)
L1 L#2 (32KB) + Core L#2 + PU L#2 (P#2)
L1 L#3 (32KB) + Core L#3 + PU L#3 (P#6)
Package L#1
L2 L#2 (4096KB)
L1 L#4 (32KB) + Core L#4 + PU L#4 (P#1)
L1 L#5 (32KB) + Core L#5 + PU L#5 (P#5)
L2 L#3 (4096KB)
L1 L#6 (32KB) + Core L#6 + PU L#6 (P#3)
L1 L#7 (32KB) + Core L#7 + PU L#7 (P#7)
Programming Interface
The basic interface is available in hwloc.h. Some higher-level
functions are available in hwloc/helper.h to reduce the need to
manually manipulate objects and follow links between them.
Documentation for all these is provided later in this document.
Developers may also want to look at hwloc/inlines.h which contains the
actual inline code of some hwloc.h routines, and at this document,
which provides good higher-level topology traversal examples.
To precisely define the vocabulary used by hwloc, a Terms and
Definitions section is available and should probably be read first.
Each hwloc object contains a cpuset describing the list of processing
units that it contains. These bitmaps may be used for CPU binding and
Memory binding. hwloc offers an extensive bitmap manipulation interface
in hwloc/bitmap.h.
Moreover, hwloc also comes with additional helpers for interoperability
with several commonly used environments. See the Interoperability With
Other Software section for details.
The complete API 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/.
NOTE: If you are building the documentation from a Git clone, 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 install" to $prefix/share/doc/hwloc/ and your
systems default man page tree (under $prefix, of course).
Portability
As shown in CLI Examples, hwloc can obtain information on a wide
variety of hardware topologies. However, some platforms and/or
operating system versions will only report a subset of this
information. For example, on an PPC64-based system with 32 cores (each
with 2 hardware threads) running a default 2.6.18-based kernel from
RHEL 5.4, hwloc is only able to glean information about NUMA nodes and
processor units (PUs). No information about caches, packages, or cores
is available.
Similarly, Operating System have varying support for CPU and memory
binding, e.g. while some Operating Systems provide interfaces for all
kinds of CPU and memory bindings, some others provide only interfaces
for a limited number of kinds of CPU and memory binding, and some do
not provide any binding interface at all. Hwloc's binding functions
would then simply return the ENOSYS error (Function not implemented),
meaning that the underlying Operating System does not provide any
interface for them. CPU binding and Memory binding provide more
information on which hwloc binding functions should be preferred
because interfaces for them are usually available on the supported
Operating Systems.
Here's the graphical output from lstopo on this platform when
Simultaneous Multi-Threading (SMT) is enabled:
ppc64-with-smt.png
And here's the graphical output from lstopo on this platform when SMT
is disabled:
ppc64-without-smt.png
Notice that hwloc only sees half the PUs when SMT is disabled. PU #15,
for example, seems to change location from NUMA node #0 to #1. In
reality, no PUs "moved" -- they were simply re-numbered when hwloc only
saw half as many. Hence, PU #15 in the SMT-disabled picture probably
corresponds to PU #30 in the SMT-enabled picture.
This same "PUs have disappeared" effect can be seen on other platforms
-- even platforms / OSs that provide much more information than the
above PPC64 system. This is an unfortunate side-effect of how operating
systems report information to hwloc.
Note that upgrading the Linux kernel on the same PPC64 system mentioned
above to 2.6.34, hwloc is able to discover all the topology
information. The following picture shows the entire topology layout
when SMT is enabled:
ppc64-full-with-smt.png
Developers using the hwloc API or XML output for portable applications
should therefore be extremely careful to not make any assumptions about
the structure of data that is returned. For example, per the above
reported PPC topology, it is not safe to assume that PUs will always be
descendants of cores.
Additionally, future hardware may insert new topology elements that are
not available in this version of hwloc. Long-lived applications that
are meant to span multiple different hardware platforms should also be
careful about making structure assumptions. For example, there may
someday be an element "lower" than a PU, or perhaps a new element may
exist between a core and a PU.
API Example
The following small C example (named ``hwloc-hello.c'') prints the
topology of the machine and bring the process to the first logical
processor of the second core of the machine. More examples are
available in the doc/examples/ directory of the source tree.
hwloc provides a pkg-config 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):
CFLAGS += $(pkg-config --cflags hwloc)
LDLIBS += $(pkg-config --libs hwloc)
cc hwloc-hello.c $(CFLAGS) -o hwloc-hello $(LDLIBS)
On a machine with 4GB of RAM and 2 processor packages -- each package
of which has two processing cores -- the output from running
hwloc-hello could be something like the following:
shell$ ./hwloc-hello
*** Objects at level 0
Index 0: Machine(3938MB)
*** Objects at level 1
Index 0: Package#0
Index 1: Package#1
*** Objects at level 2
Index 0: Core#0
Index 1: Core#1
Index 2: Core#3
Index 3: Core#2
*** Objects at level 3
Index 0: PU#0
Index 1: PU#1
Index 2: PU#2
Index 3: PU#3
*** Printing overall tree
Machine(3938MB)
Package#0
Core#0
PU#0
Core#1
PU#1
Package#1
Core#3
PU#2
Core#2
PU#3
*** 2 package(s)
shell$
Questions and Bugs
Questions should be sent to the devel mailing list
(http://www.open-mpi.org/community/lists/hwloc.php). Bug reports should
be reported in the tracker (https://git.open-mpi.org/trac/hwloc/).
If hwloc discovers an incorrect topology for your machine, the very
first thing you should check is to ensure that you have the most recent
updates installed for your operating system. Indeed, most of hwloc
topology discovery relies on hardware information retrieved through the
operation system (e.g., via the /sys virtual filesystem of the Linux
kernel). If upgrading your OS or Linux kernel does not solve your
problem, you may also want to ensure that you are running the most
recent version of the BIOS for your machine.
If those things fail, contact us on the mailing list for additional
help. Please attach the output of lstopo after having given the
--enable-debug option to ./configure and rebuilt completely, to get
debugging output. Also attach the /proc + /sys tarball generated by the
installed script hwloc-gather-topology when submitting problems about
Linux, or send the output of kstat cpu_info in the Solaris case, or the
output of sysctl hw in the Darwin or BSD cases.
History / Credits
hwloc is the evolution and merger of the libtopology
(http://runtime.bordeaux.inria.fr/libtopology/) project and the
Portable Linux Processor Affinity (PLPA)
(http://www.open-mpi.org/projects/plpa/) project. Because of functional
and ideological overlap, these two code bases and ideas were merged and
released under the name "hwloc" as an Open MPI sub-project.
libtopology was initially developed by the inria Runtime Team-Project
(http://runtime.bordeaux.inria.fr/) (headed by Raymond Namyst
(http://dept-info.labri.fr/~namyst/). PLPA was initially developed by
the Open MPI development team as a sub-project. Both are now deprecated
in favor of hwloc, which is distributed as an Open MPI sub-project.
Further Reading
The documentation chapters include
* Terms and Definitions
* Command-Line Tools
* Environment Variables
* CPU and Memory Binding Overview
* I/O Devices
* Miscellaneous objects
* Multi-node Topologies
* Object attributes
* Importing and exporting topologies from/to XML files
* Synthetic topologies
* Interoperability With Other Software
* Thread Safety
* Components and plugins
* Embedding hwloc in Other Software
* Frequently Asked Questions
Make sure to have had a look at those too!
__________________________________________________________________
Generated on 5 Jun 2015 for Hardware Locality (hwloc) by doxygen
1.6.1

Просмотреть файл

@ -2,18 +2,12 @@
# of hwloc in this distribution. The various components of the version # of hwloc in this distribution. The various components of the version
# number below are combined to form a single version number string. # number below are combined to form a single version number string.
# If snapshot=1, then use the value from snapshot_version as the
# entire hwloc version (i.e., ignore major, minor, release, and
# greek). This is only set to 1 when making snapshot tarballs.
snapshot=0
snapshot_version=gitclone
# major, minor, and release are generally combined in the form # major, minor, and release are generally combined in the form
# <major>.<minor>.<release>. If release is zero, then it is omitted. # <major>.<minor>.<release>. If release is zero, then it is omitted.
major=1 major=1
minor=9 minor=11
release=2 release=0
# greek is used for alpha or beta release tags. If it is non-empty, # greek is used for alpha or beta release tags. If it is non-empty,
# it will be appended to the version number. It does not have to be # it will be appended to the version number. It does not have to be
@ -22,11 +16,17 @@ release=2
# requirement is that it must be entirely printable ASCII characters # requirement is that it must be entirely printable ASCII characters
# and have no white space. # and have no white space.
greek= greek=rc2
# The date when this release was created # The date when this release was created
date="Aug 25, 2014" date="Unreleased developer copy"
# If snapshot=1, then use the value from snapshot_version as the
# entire hwloc version (i.e., ignore major, minor, release, and
# greek). This is only set to 1 when making snapshot tarballs.
snapshot=1
snapshot_version=dev-450-g1cc3012
# The shared library version of hwloc's public library. This version # The shared library version of hwloc's public library. This version
# is maintained in accordance with the "Library Interface Versions" # is maintained in accordance with the "Library Interface Versions"
@ -39,4 +39,4 @@ date="Aug 25, 2014"
# 2. Version numbers are described in the Libtool current:revision:age # 2. Version numbers are described in the Libtool current:revision:age
# format. # format.
libhwloc_so_version=10:1:5 libhwloc_so_version=11:6:6

Просмотреть файл

@ -1,14 +1,14 @@
#!/bin/sh -f #!/bin/sh -f
# #
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana # Copyright © 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology # University Research and Technology
# Corporation. All rights reserved. # Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University # Copyright © 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights # of Tennessee Research Foundation. All rights
# reserved. # reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, # Copyright © 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright © 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# Copyright © 2010-2014 Inria. All rights reserved. # Copyright © 2010-2014 Inria. All rights reserved.
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.

Просмотреть файл

@ -1,15 +1,15 @@
dnl -*- Autoconf -*- dnl -*- Autoconf -*-
dnl dnl
dnl Copyright © 2009-2014 Inria. All rights reserved. dnl Copyright © 2009-2015 Inria. All rights reserved.
dnl Copyright (c) 2009-2012 Université Bordeaux 1 dnl Copyright © 2009-2012 Université Bordeaux
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology dnl University Research and Technology
dnl Corporation. All rights reserved. dnl Corporation. All rights reserved.
dnl Copyright (c) 2004-2012 The Regents of the University of California. dnl Copyright © 2004-2012 The Regents of the University of California.
dnl All rights reserved. dnl All rights reserved.
dnl Copyright (c) 2004-2008 High Performance Computing Center Stuttgart, dnl Copyright © 2004-2008 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved. dnl University of Stuttgart. All rights reserved.
dnl Copyright © 2006-2013 Cisco Systems, Inc. All rights reserved. dnl Copyright © 2006-2015 Cisco Systems, Inc. All rights reserved.
dnl Copyright © 2012 Blue Brain Project, BBP/EPFL. All rights reserved. dnl Copyright © 2012 Blue Brain Project, BBP/EPFL. All rights reserved.
dnl Copyright © 2012 Oracle and/or its affiliates. All rights reserved. dnl Copyright © 2012 Oracle and/or its affiliates. All rights reserved.
dnl See COPYING in top-level directory. dnl See COPYING in top-level directory.
@ -36,7 +36,7 @@ AC_DEFUN([HWLOC_SETUP_CORE],[
EOF]) EOF])
# If no prefix was defined, set a good value # If no prefix was defined, set a good value
m4_ifval([$1], m4_ifval([$1],
[m4_define([hwloc_config_prefix],[$1/])], [m4_define([hwloc_config_prefix],[$1/])],
[m4_define([hwloc_config_prefix], [])]) [m4_define([hwloc_config_prefix], [])])
@ -78,6 +78,19 @@ EOF])
AC_MSG_NOTICE([Detected VPATH build]) AC_MSG_NOTICE([Detected VPATH build])
fi fi
# Get the version of hwloc that we are installing
AC_MSG_CHECKING([for hwloc version])
HWLOC_VERSION="`$HWLOC_top_srcdir/config/hwloc_get_version.sh $HWLOC_top_srcdir/VERSION`"
if test "$?" != "0"; then
AC_MSG_ERROR([Cannot continue])
fi
HWLOC_RELEASE_DATE="`$HWLOC_top_srcdir/config/hwloc_get_version.sh $HWLOC_top_srcdir/VERSION --release-date`"
AC_SUBST(HWLOC_VERSION)
AC_DEFINE_UNQUOTED([HWLOC_VERSION], ["$HWLOC_VERSION"],
[The library version, always available, even in embedded mode, contrary to VERSION])
AC_SUBST(HWLOC_RELEASE_DATE)
AC_MSG_RESULT([$HWLOC_VERSION])
# Debug mode? # Debug mode?
AC_MSG_CHECKING([if want hwloc maintainer support]) AC_MSG_CHECKING([if want hwloc maintainer support])
hwloc_debug= hwloc_debug=
@ -151,9 +164,9 @@ EOF])
#endif #endif
]) ])
AC_DEFINE([_HPUX_SOURCE], [1], [Are we building for HP-UX?]) AC_DEFINE([_HPUX_SOURCE], [1], [Are we building for HP-UX?])
AC_LANG_PUSH([C]) AC_LANG_PUSH([C])
# Check to see if we're producing a 32 or 64 bit executable by # Check to see if we're producing a 32 or 64 bit executable by
# checking the sizeof void*. Note that AC CHECK_SIZEOF even works # checking the sizeof void*. Note that AC CHECK_SIZEOF even works
# when cross compiling (!), according to the AC 2.64 docs. This # when cross compiling (!), according to the AC 2.64 docs. This
@ -188,7 +201,7 @@ EOF])
hwloc_components="$hwloc_components linuxpci" hwloc_components="$hwloc_components linuxpci"
AC_DEFINE(HWLOC_HAVE_LINUXPCI, 1, [Define to 1 if building the Linux PCI component]) AC_DEFINE(HWLOC_HAVE_LINUXPCI, 1, [Define to 1 if building the Linux PCI component])
hwloc_linuxpci_happy=yes hwloc_linuxpci_happy=yes
fi fi
;; ;;
*-*-irix*) *-*-irix*)
AC_DEFINE(HWLOC_IRIX_SYS, 1, [Define to 1 on Irix]) AC_DEFINE(HWLOC_IRIX_SYS, 1, [Define to 1 on Irix])
@ -290,7 +303,7 @@ EOF])
;; ;;
esac esac
AC_SUBST(HWLOC_MS_LIB_ARCH) AC_SUBST(HWLOC_MS_LIB_ARCH)
AC_CHECK_SIZEOF([unsigned long]) AC_CHECK_SIZEOF([unsigned long])
AC_DEFINE_UNQUOTED([HWLOC_SIZEOF_UNSIGNED_LONG], $ac_cv_sizeof_unsigned_long, [The size of `unsigned long', as computed by sizeof]) AC_DEFINE_UNQUOTED([HWLOC_SIZEOF_UNSIGNED_LONG], $ac_cv_sizeof_unsigned_long, [The size of `unsigned long', as computed by sizeof])
AC_CHECK_SIZEOF([unsigned int]) AC_CHECK_SIZEOF([unsigned int])
@ -363,12 +376,12 @@ EOF])
AC_CHECK_FUNCS([strftime]) AC_CHECK_FUNCS([strftime])
AC_CHECK_FUNCS([setlocale]) AC_CHECK_FUNCS([setlocale])
AC_CHECK_HEADER([stdint.h], [ AC_CHECK_HEADER([stdint.h], [
AC_DEFINE([HWLOC_HAVE_STDINT_H], [1], [Define to 1 if you have the <stdint.h> header file.]) AC_DEFINE([HWLOC_HAVE_STDINT_H], [1], [Define to 1 if you have the <stdint.h> header file.])
]) ])
AC_CHECK_HEADERS([sys/mman.h]) AC_CHECK_HEADERS([sys/mman.h])
old_CPPFLAGS="$CPPFLAGS" old_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0601" CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0601"
AC_CHECK_TYPES([KAFFINITY, AC_CHECK_TYPES([KAFFINITY,
@ -391,18 +404,18 @@ EOF])
AC_CHECK_LIB([gdi32], [main], AC_CHECK_LIB([gdi32], [main],
[HWLOC_LIBS="-lgdi32 $HWLOC_LIBS" [HWLOC_LIBS="-lgdi32 $HWLOC_LIBS"
AC_DEFINE([HAVE_LIBGDI32], 1, [Define to 1 if we have -lgdi32])]) AC_DEFINE([HAVE_LIBGDI32], 1, [Define to 1 if we have -lgdi32])])
AC_CHECK_HEADER([windows.h], [ AC_CHECK_HEADER([windows.h], [
AC_DEFINE([HWLOC_HAVE_WINDOWS_H], [1], [Define to 1 if you have the `windows.h' header.]) AC_DEFINE([HWLOC_HAVE_WINDOWS_H], [1], [Define to 1 if you have the `windows.h' header.])
]) ])
AC_CHECK_HEADERS([sys/lgrp_user.h], [ AC_CHECK_HEADERS([sys/lgrp_user.h], [
AC_CHECK_LIB([lgrp], [lgrp_latency_cookie], AC_CHECK_LIB([lgrp], [lgrp_latency_cookie],
[HWLOC_LIBS="-llgrp $HWLOC_LIBS" [HWLOC_LIBS="-llgrp $HWLOC_LIBS"
AC_DEFINE([HAVE_LIBLGRP], 1, [Define to 1 if we have -llgrp])]) AC_DEFINE([HAVE_LIBLGRP], 1, [Define to 1 if we have -llgrp])])
]) ])
AC_CHECK_HEADERS([kstat.h], [ AC_CHECK_HEADERS([kstat.h], [
AC_CHECK_LIB([kstat], [main], AC_CHECK_LIB([kstat], [main],
[HWLOC_LIBS="-lkstat $HWLOC_LIBS" [HWLOC_LIBS="-lkstat $HWLOC_LIBS"
AC_DEFINE([HAVE_LIBKSTAT], 1, [Define to 1 if we have -lkstat])]) AC_DEFINE([HAVE_LIBKSTAT], 1, [Define to 1 if we have -lkstat])])
]) ])
@ -423,7 +436,7 @@ EOF])
_SC_PAGESIZE, _SC_PAGESIZE,
_SC_PAGE_SIZE, _SC_PAGE_SIZE,
_SC_LARGE_PAGESIZE],,[:],[[#include <unistd.h>]]) _SC_LARGE_PAGESIZE],,[:],[[#include <unistd.h>]])
AC_HAVE_HEADERS([mach/mach_host.h]) AC_HAVE_HEADERS([mach/mach_host.h])
AC_HAVE_HEADERS([mach/mach_init.h], [ AC_HAVE_HEADERS([mach/mach_init.h], [
AC_CHECK_FUNCS([host_info]) AC_CHECK_FUNCS([host_info])
@ -468,6 +481,33 @@ EOF])
[return sysctlbyname(NULL,NULL,NULL,NULL,0);], [return sysctlbyname(NULL,NULL,NULL,NULL,0);],
AC_DEFINE([HAVE_SYSCTLBYNAME],[1],[Define to '1' if sysctlbyname is present and usable])) AC_DEFINE([HAVE_SYSCTLBYNAME],[1],[Define to '1' if sysctlbyname is present and usable]))
AC_CHECK_DECLS([getprogname], [], [], [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([getexecname], [], [], [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([GetModuleFileName], [], [], [#include <windows.h>])
# program_invocation_name and __progname may be available but not exported in headers
AC_MSG_CHECKING([for program_invocation_name])
AC_TRY_LINK([
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
extern char *program_invocation_name;
],[
return printf("%s\n", program_invocation_name);
],
[AC_DEFINE([HAVE_PROGRAM_INVOCATION_NAME], [1], [Define to '1' if program_invocation_name is present and usable])
AC_MSG_RESULT([yes])
],[AC_MSG_RESULT([no])])
AC_MSG_CHECKING([for __progname])
AC_TRY_LINK([
#include <stdio.h>
extern char *__progname;
],[
return printf("%s\n", __progname);
],
[AC_DEFINE([HAVE___PROGNAME], [1], [Define to '1' if __progname is present and usable])
AC_MSG_RESULT([yes])
],[AC_MSG_RESULT([no])])
case ${target} in case ${target} in
*-*-mingw*|*-*-cygwin*) *-*-mingw*|*-*-cygwin*)
hwloc_pid_t=HANDLE hwloc_pid_t=HANDLE
@ -482,7 +522,7 @@ EOF])
if test "x$hwloc_thread_t" != "x" ; then if test "x$hwloc_thread_t" != "x" ; then
AC_DEFINE_UNQUOTED(hwloc_thread_t, $hwloc_thread_t, [Define this to the thread ID type]) AC_DEFINE_UNQUOTED(hwloc_thread_t, $hwloc_thread_t, [Define this to the thread ID type])
fi fi
_HWLOC_CHECK_DECL([sched_setaffinity], [ _HWLOC_CHECK_DECL([sched_setaffinity], [
AC_DEFINE([HWLOC_HAVE_SCHED_SETAFFINITY], [1], [Define to 1 if glibc provides a prototype of sched_setaffinity()]) AC_DEFINE([HWLOC_HAVE_SCHED_SETAFFINITY], [1], [Define to 1 if glibc provides a prototype of sched_setaffinity()])
AS_IF([test "$HWLOC_STRICT_ARGS_CFLAGS" = "FAIL"],[ AS_IF([test "$HWLOC_STRICT_ARGS_CFLAGS" = "FAIL"],[
@ -507,7 +547,7 @@ EOF])
#define _GNU_SOURCE #define _GNU_SOURCE
#include <sched.h> #include <sched.h>
]]) ]])
AC_MSG_CHECKING([for working CPU_SET]) AC_MSG_CHECKING([for working CPU_SET])
AC_LINK_IFELSE([ AC_LINK_IFELSE([
AC_LANG_PROGRAM([[ AC_LANG_PROGRAM([[
@ -517,7 +557,7 @@ EOF])
[AC_DEFINE([HWLOC_HAVE_CPU_SET], [1], [Define to 1 if the CPU_SET macro works]) [AC_DEFINE([HWLOC_HAVE_CPU_SET], [1], [Define to 1 if the CPU_SET macro works])
AC_MSG_RESULT([yes])], AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]) [AC_MSG_RESULT([no])])
AC_MSG_CHECKING([for working CPU_SET_S]) AC_MSG_CHECKING([for working CPU_SET_S])
AC_LINK_IFELSE([ AC_LINK_IFELSE([
AC_LANG_PROGRAM([[ AC_LANG_PROGRAM([[
@ -549,13 +589,13 @@ EOF])
# to pass in an empty 3rd argument, but we trust the output of # to pass in an empty 3rd argument, but we trust the output of
# pkg-config, so just give it a value that will always work: # pkg-config, so just give it a value that will always work:
# printf. # printf.
HWLOC_PKG_CHECK_MODULES([KERRIGHED], [kerrighed >= 2.0], [printf], [], [:]) HWLOC_PKG_CHECK_MODULES([KERRIGHED], [kerrighed >= 2.0], [printf], [stdio.h], [], [:])
AC_PATH_PROGS([HWLOC_MS_LIB], [lib]) AC_PATH_PROGS([HWLOC_MS_LIB], [lib])
AC_ARG_VAR([HWLOC_MS_LIB], [Path to Microsoft's Visual Studio `lib' tool]) AC_ARG_VAR([HWLOC_MS_LIB], [Path to Microsoft's Visual Studio `lib' tool])
AC_PATH_PROG([BASH], [bash]) AC_PATH_PROG([BASH], [bash])
AC_CHECK_FUNCS([ffs], [ AC_CHECK_FUNCS([ffs], [
_HWLOC_CHECK_DECL([ffs],[ _HWLOC_CHECK_DECL([ffs],[
AC_DEFINE([HWLOC_HAVE_DECL_FFS], [1], [Define to 1 if function `ffs' is declared by system headers]) AC_DEFINE([HWLOC_HAVE_DECL_FFS], [1], [Define to 1 if function `ffs' is declared by system headers])
@ -568,10 +608,10 @@ EOF])
dnl We can't use AC_TRY_LINK because the failure does not appear until dnl We can't use AC_TRY_LINK because the failure does not appear until
dnl run/load time and there is currently no precedent for AC_TRY_RUN dnl run/load time and there is currently no precedent for AC_TRY_RUN
dnl use in hwloc. --PHH dnl use in hwloc. --PHH
dnl For now, we're going with "all gccfss compilers are broken". dnl For now, we're going with "all gccfss compilers are broken".
dnl Better to be safe and correct; it's not like this is dnl Better to be safe and correct; it's not like this is
dnl performance-critical code, after all. dnl performance-critical code, after all.
AC_DEFINE([HWLOC_HAVE_BROKEN_FFS], [1], AC_DEFINE([HWLOC_HAVE_BROKEN_FFS], [1],
[Define to 1 if your `ffs' function is known to be broken.]) [Define to 1 if your `ffs' function is known to be broken.])
fi fi
]) ])
@ -581,7 +621,7 @@ EOF])
]) ])
AC_DEFINE([HWLOC_HAVE_FFSL], [1], [Define to 1 if you have the `ffsl' function.]) AC_DEFINE([HWLOC_HAVE_FFSL], [1], [Define to 1 if you have the `ffsl' function.])
]) ])
AC_CHECK_FUNCS([fls], [ AC_CHECK_FUNCS([fls], [
_HWLOC_CHECK_DECL([fls],[ _HWLOC_CHECK_DECL([fls],[
AC_DEFINE([HWLOC_HAVE_DECL_FLS], [1], [Define to 1 if function `fls' is declared by system headers]) AC_DEFINE([HWLOC_HAVE_DECL_FLS], [1], [Define to 1 if function `fls' is declared by system headers])
@ -594,7 +634,7 @@ EOF])
]) ])
AC_DEFINE([HWLOC_HAVE_FLSL], [1], [Define to 1 if you have the `flsl' function.]) AC_DEFINE([HWLOC_HAVE_FLSL], [1], [Define to 1 if you have the `flsl' function.])
]) ])
AC_CHECK_FUNCS([clz], [ AC_CHECK_FUNCS([clz], [
_HWLOC_CHECK_DECL([clz],[ _HWLOC_CHECK_DECL([clz],[
AC_DEFINE([HWLOC_HAVE_DECL_CLZ], [1], [Define to 1 if function `clz' is declared by system headers]) AC_DEFINE([HWLOC_HAVE_DECL_CLZ], [1], [Define to 1 if function `clz' is declared by system headers])
@ -607,7 +647,7 @@ EOF])
]) ])
AC_DEFINE([HWLOC_HAVE_CLZL], [1], [Define to 1 if you have the `clzl' function.]) AC_DEFINE([HWLOC_HAVE_CLZL], [1], [Define to 1 if you have the `clzl' function.])
]) ])
AC_CHECK_FUNCS([openat], [hwloc_have_openat=yes]) AC_CHECK_FUNCS([openat], [hwloc_have_openat=yes])
AC_CHECK_HEADERS([malloc.h]) AC_CHECK_HEADERS([malloc.h])
@ -672,126 +712,42 @@ EOF])
LIBS="$tmp_save_LIBS" LIBS="$tmp_save_LIBS"
fi fi
# PCI support # Linux libudev support
if test "x$enable_libudev" != xno; then
AC_CHECK_HEADERS([libudev.h], [
AC_CHECK_LIB([udev], [udev_device_new_from_subsystem_sysname], [HWLOC_LIBS="$HWLOC_LIBS -ludev"])
])
fi
# PCI support via libpciaccess. NOTE: we do not support
# libpci/pciutils because that library is GPL and is incompatible
# with our BSD license.
hwloc_pci_happy=no hwloc_pci_happy=no
if test "x$enable_pci" != xno -a "x$enable_libpci" != "xyes"; then if test "x$enable_pci" != xno; then
hwloc_pci_happy=yes hwloc_pci_happy=yes
HWLOC_PKG_CHECK_MODULES([PCIACCESS], [pciaccess], [pci_slot_match_iterator_create], [:], [hwloc_pci_happy=no]) HWLOC_PKG_CHECK_MODULES([PCIACCESS], [pciaccess], [pci_slot_match_iterator_create], [pciaccess.h], [:], [hwloc_pci_happy=no])
if test x$hwloc_pci_happy = xyes; then hwloc_pci_lib=pciaccess; fi
# Just for giggles, if we didn't find a pciaccess pkg-config,
# just try looking for its header file and library.
AS_IF([test "$hwloc_pci_happy" != "yes"],
[AC_CHECK_HEADER([pciaccess.h],
[AC_CHECK_LIB([pciaccess], [pci_slot_match_iterator_create],
[hwloc_pci_happy=yes
HWLOC_PCIACCESS_LIBS="-lpciaccess"])
])
])
AS_IF([test "$hwloc_pci_happy" = "yes"],
[HWLOC_PCIACCESS_REQUIRES=pciaccess
hwloc_pci_lib=pciaccess
hwloc_components="$hwloc_components pci"
hwloc_pci_component_maybeplugin=1])
fi fi
# PCI support with pciutils instead of pciaccess
if test "x$enable_pci" != "xno" -a "x$hwloc_pci_lib" != "xpciaccess"; then
hwloc_pci_happy=yes
HWLOC_PKG_CHECK_MODULES([PCIUTILS], [libpci], [pci_cleanup], [:], [
# manually check pciutils in case a old one without .pc is installed
AC_CHECK_HEADERS([pci/pci.h], [
# try first without -lz, it's not always needed (RHEL5, Debian Etch)
AC_CHECK_LIB([pci], [pci_init], [
HWLOC_PCIUTILS_LIBS="-lpci"
], [
# try again with -lz because it's needed sometimes (FC7).
# don't use AC_CHECK_LIB again because the cache would
# return "no" without actually rechecking
AC_MSG_CHECKING([for pci_init in -lpci with -lz])
tmp_save_LIBS=$LIBS
LIBS="-lpci -lz $LIBS"
AC_LINK_IFELSE([AC_LANG_CALL([], [pci_init])],
[HWLOC_PCIUTILS_LIBS="-lpci -lz"
HWLOC_PCIUTILS_ADDITIONAL_LIBS="-lz"
AC_MSG_RESULT(yes)],
[hwloc_pci_happy=no
AC_MSG_RESULT(no)])
LIBS=$tmp_save_LIBS])
# Also check with pci_lookup_name, because that sometimes
# requires -lresolv (RHEL5.6). don't use AC_CHECK_LIB twice
# because the cache would return "no" without actually rechecking
AC_CHECK_LIB([pci], [pci_lookup_name], [],
[AC_CHECK_LIB([resolv], [inet_ntoa],
[AC_MSG_CHECKING([for pci_lookup_name in -lpci with -lresolv])
tmp_save_LIBS=$LIBS
LIBS="-lpci -lresolv $LIBS $HWLOC_PCIUTILS_ADDITIONAL_LIBS"
AC_LINK_IFELSE([AC_LANG_CALL([], [pci_lookup_name])],
[HWLOC_PCIUTILS_LIBS="$HWLOC_PCIUTILS_LIBS -lresolv"
HWLOC_PCIUTILS_ADDITIONAL_LIBS="$HWLOC_PCIUTILS_ADDITIONAL_LIBS -lresolv"
AC_MSG_RESULT(yes)],
[hwloc_pci_happy=no
AC_MSG_RESULT(no)])
LIBS=$tmp_save_LIBS],
[hwloc_pci_happy=no])])
], [hwloc_pci_happy=no])
])
if test x$hwloc_pci_happy = xyes; then
# pciutils could be used, but we don't want to force use it since it may GPL-taint hwloc
if test x$enable_libpci = xyes; then
hwloc_pci_lib=pciutils
else
# user didn't explicit request pciutils, disable PCI and warn the user
hwloc_pci_happy=no
hwloc_warn_may_use_libpci=yes
fi
else
# pciutils not found, error out if it was requested
if test x$enable_libpci = xyes; then
AC_MSG_WARN([Specified --enable-libpci switch, but could not])
AC_MSG_WARN([find appropriate support])
AC_MSG_ERROR([Cannot continue])
fi
fi
fi
AC_SUBST(HWLOC_PCIUTILS_LIBS)
# If we asked for pci support but couldn't deliver, fail # If we asked for pci support but couldn't deliver, fail
AS_IF([test "$enable_pci" = "yes" -a "$hwloc_pci_happy" = "no" -a "$hwloc_warn_may_use_libpci" != "yes"], AS_IF([test "$enable_pci" = "yes" -a "$hwloc_pci_happy" = "no"],
[AC_MSG_WARN([Specified --enable-pci switch, but could not]) [AC_MSG_WARN([Specified --enable-pci switch, but could not])
AC_MSG_WARN([find appropriate support]) AC_MSG_WARN([find appropriate support])
AC_MSG_ERROR([Cannot continue])]) AC_MSG_ERROR([Cannot continue])])
# pciaccess specific enabling
if test "x$hwloc_pci_lib" = "xpciaccess"; then
HWLOC_PCIACCESS_REQUIRES=pciaccess
AC_DEFINE([HWLOC_HAVE_LIBPCIACCESS], [1], [Define to 1 if you have the `libpciaccess' library.])
fi
# pciutils specific checks and enabling
if test "x$hwloc_pci_lib" = "xpciutils"; then
tmp_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $HWLOC_PCIUTILS_CFLAGS"
tmp_save_LIBS="$LIBS"
LIBS="$LIBS $HWLOC_PCIUTILS_LIBS"
AC_CHECK_DECLS([PCI_LOOKUP_NO_NUMBERS],,[:],[[#include <pci/pci.h>]])
AC_CHECK_DECLS([PCI_LOOKUP_NO_NUMBERS],,[:],[[#include <pci/pci.h>]])
AC_CHECK_LIB([pci], [pci_find_cap], [enable_pci_caps=yes], [enable_pci_caps=no], [$HWLOC_PCIUTILS_ADDITIONAL_LIBS])
if test "x$enable_pci_caps" = "xyes"; then
AC_DEFINE([HWLOC_HAVE_PCI_FIND_CAP], [1], [Define to 1 if `libpci' has the `pci_find_cap' function.])
fi
AC_MSG_CHECKING(whether struct pci_dev has a device_class field)
AC_TRY_COMPILE([#include <pci/pci.h>],
[int f(struct pci_dev *dev) { return dev->device_class; }],
[pcidev_device_class=yes], [pcidev_device_class=no])
AC_MSG_RESULT([$pcidev_device_class])
if test x$pcidev_device_class = xyes; then
AC_DEFINE([HWLOC_HAVE_PCIDEV_DEVICE_CLASS], [1], [Define to 1 if `libpci' struct pci_dev has a `device_class' field.])
fi
AC_MSG_CHECKING(whether struct pci_dev has a domain field)
AC_TRY_COMPILE([#include <pci/pci.h>],
[int f(struct pci_dev *dev) { return dev->domain; }],
[pcidev_domain=yes], [pcidev_domain=no])
AC_MSG_RESULT([$pcidev_domain])
if test x$pcidev_domain = xyes; then
AC_DEFINE([HWLOC_HAVE_PCIDEV_DOMAIN], [1], [Define to 1 if `libpci' struct pci_dev has a `domain' field.])
fi
CFLAGS="$tmp_save_CFLAGS"
LIBS="$tmp_save_LIBS"
HWLOC_PCIUTILS_REQUIRES=libpci
AC_DEFINE([HWLOC_HAVE_PCIUTILS], [1], [Define to 1 if you have the pciutils `libpci' library.])
fi
# final common PCI enabling
if test "x$hwloc_pci_happy" = "xyes"; then
hwloc_components="$hwloc_components pci"
hwloc_pci_component_maybeplugin=1
fi
# don't add LIBS/CFLAGS/REQUIRES yet, depends on plugins # don't add LIBS/CFLAGS/REQUIRES yet, depends on plugins
# OpenCL support # OpenCL support
@ -937,7 +893,7 @@ EOF])
CPPFLAGS=$CPPFLAGS_save CPPFLAGS=$CPPFLAGS_save
LIBS=$LIBS_save LIBS=$LIBS_save
# GL Support # GL Support
hwloc_gl_happy=no hwloc_gl_happy=no
if test "x$enable_gl" != "xno"; then if test "x$enable_gl" != "xno"; then
hwloc_gl_happy=yes hwloc_gl_happy=yes
@ -964,15 +920,15 @@ EOF])
AC_MSG_WARN([find appropriate support]) AC_MSG_WARN([find appropriate support])
AC_MSG_ERROR([Cannot continue]) AC_MSG_ERROR([Cannot continue])
]) ])
fi fi
fi fi
# don't add LIBS/CFLAGS yet, depends on plugins # don't add LIBS/CFLAGS yet, depends on plugins
# libxml2 support # libxml2 support
hwloc_libxml2_happy= hwloc_libxml2_happy=
if test "x$enable_libxml2" != "xno"; then if test "x$enable_libxml2" != "xno"; then
HWLOC_PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], [xmlNewDoc], HWLOC_PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], [xmlNewDoc], [libxml/parser.h],
[hwloc_libxml2_happy=yes], [hwloc_libxml2_happy=yes],
[hwloc_libxml2_happy=no]) [hwloc_libxml2_happy=no])
fi fi
if test "x$hwloc_libxml2_happy" = "xyes"; then if test "x$hwloc_libxml2_happy" = "xyes"; then
@ -991,44 +947,46 @@ EOF])
# don't add LIBS/CFLAGS/REQUIRES yet, depends on plugins # don't add LIBS/CFLAGS/REQUIRES yet, depends on plugins
# Try to compile the x86 cpuid inlines # Try to compile the x86 cpuid inlines
AC_MSG_CHECKING([for x86 cpuid]) if test "x$enable_cpuid" != "xno"; then
old_CPPFLAGS="$CPPFLAGS" AC_MSG_CHECKING([for x86 cpuid])
CPPFLAGS="$CPPFLAGS -I$HWLOC_top_srcdir/include" old_CPPFLAGS="$CPPFLAGS"
# We need hwloc_uint64_t but we can't use hwloc/autogen/config.h before configure ends. CPPFLAGS="$CPPFLAGS -I$HWLOC_top_srcdir/include"
# So pass #include/#define manually here for now. # We need hwloc_uint64_t but we can't use hwloc/autogen/config.h before configure ends.
CPUID_CHECK_HEADERS= # So pass #include/#define manually here for now.
CPUID_CHECK_DEFINE= CPUID_CHECK_HEADERS=
if test "x$hwloc_windows" = xyes; then CPUID_CHECK_DEFINE=
X86_CPUID_CHECK_HEADERS="#include <windows.h>" if test "x$hwloc_windows" = xyes; then
X86_CPUID_CHECK_DEFINE="#define hwloc_uint64_t DWORDLONG" X86_CPUID_CHECK_HEADERS="#include <windows.h>"
else X86_CPUID_CHECK_DEFINE="#define hwloc_uint64_t DWORDLONG"
X86_CPUID_CHECK_DEFINE="#define hwloc_uint64_t uint64_t" else
if test "x$ac_cv_header_stdint_h" = xyes; then X86_CPUID_CHECK_DEFINE="#define hwloc_uint64_t uint64_t"
X86_CPUID_CHECK_HEADERS="#include <stdint.h>" if test "x$ac_cv_header_stdint_h" = xyes; then
fi X86_CPUID_CHECK_HEADERS="#include <stdint.h>"
fi
fi
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
$X86_CPUID_CHECK_HEADERS
$X86_CPUID_CHECK_DEFINE
#define __hwloc_inline
#include <private/cpuid-x86.h>
]], [[
if (hwloc_have_x86_cpuid()) {
unsigned eax = 0, ebx, ecx = 0, edx;
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
printf("highest x86 cpuid %x\n", eax);
return 0;
}
]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HWLOC_HAVE_X86_CPUID, 1, [Define to 1 if you have x86 cpuid])
hwloc_have_x86_cpuid=yes],
[AC_MSG_RESULT([no])])
if test "x$hwloc_have_x86_cpuid" = xyes; then
hwloc_components="$hwloc_components x86"
fi
CPPFLAGS="$old_CPPFLAGS"
fi fi
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
$X86_CPUID_CHECK_HEADERS
$X86_CPUID_CHECK_DEFINE
#define __hwloc_inline
#include <private/cpuid-x86.h>
]], [[
if (hwloc_have_x86_cpuid()) {
unsigned eax = 0, ebx, ecx = 0, edx;
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
printf("highest x86 cpuid %x\n", eax);
return 0;
}
]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HWLOC_HAVE_X86_CPUID, 1, [Define to 1 if you have x86 cpuid])
hwloc_have_x86_cpuid=yes],
[AC_MSG_RESULT([no])])
if test "x$hwloc_have_x86_cpuid" = xyes; then
hwloc_components="$hwloc_components x86"
fi
CPPFLAGS="$old_CPPFLAGS"
# Components require pthread_mutex, see if it needs -lpthread # Components require pthread_mutex, see if it needs -lpthread
hwloc_pthread_mutex_happy=no hwloc_pthread_mutex_happy=no
@ -1122,9 +1080,9 @@ EOF])
AC_MSG_RESULT([$hwloc_plugin_components]) AC_MSG_RESULT([$hwloc_plugin_components])
AS_IF([test "$hwloc_pci_component" = "static"], AS_IF([test "$hwloc_pci_component" = "static"],
[HWLOC_LIBS="$HWLOC_LIBS $HWLOC_PCIUTILS_LIBS $HWLOC_PCIACCESS_LIBS" [HWLOC_LIBS="$HWLOC_LIBS $HWLOC_PCIACCESS_LIBS"
HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_PCIUTILS_CFLAGS $HWLOC_PCIACCESS_CFLAGS" HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_PCIACCESS_CFLAGS"
HWLOC_REQUIRES="$HWLOC_PCIUTILS_REQUIRES $HWLOC_PCIACCESS_REQUIRES $HWLOC_REQUIRES"]) HWLOC_REQUIRES="$HWLOC_PCIACCESS_REQUIRES $HWLOC_REQUIRES"])
AS_IF([test "$hwloc_opencl_component" = "static"], AS_IF([test "$hwloc_opencl_component" = "static"],
[HWLOC_LIBS="$HWLOC_LIBS $HWLOC_OPENCL_LIBS" [HWLOC_LIBS="$HWLOC_LIBS $HWLOC_OPENCL_LIBS"
HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_OPENCL_CFLAGS" HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_OPENCL_CFLAGS"
@ -1214,7 +1172,7 @@ AC_DEFUN([HWLOC_DO_AM_CONDITIONALS],[
[test "x$hwloc_have_sched_setaffinity" = "xyes"]) [test "x$hwloc_have_sched_setaffinity" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_PTHREAD], AM_CONDITIONAL([HWLOC_HAVE_PTHREAD],
[test "x$hwloc_have_pthread" = "xyes"]) [test "x$hwloc_have_pthread" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_LIBIBVERBS], AM_CONDITIONAL([HWLOC_HAVE_LIBIBVERBS],
[test "x$hwloc_have_libibverbs" = "xyes"]) [test "x$hwloc_have_libibverbs" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_CUDA], AM_CONDITIONAL([HWLOC_HAVE_CUDA],
[test "x$hwloc_have_cuda" = "xyes"]) [test "x$hwloc_have_cuda" = "xyes"])
@ -1235,9 +1193,9 @@ AC_DEFUN([HWLOC_DO_AM_CONDITIONALS],[
AM_CONDITIONAL([HWLOC_BUILD_DOXYGEN], AM_CONDITIONAL([HWLOC_BUILD_DOXYGEN],
[test "x$hwloc_generate_doxs" = "xyes"]) [test "x$hwloc_generate_doxs" = "xyes"])
AM_CONDITIONAL([HWLOC_BUILD_README], AM_CONDITIONAL([HWLOC_BUILD_README],
[test "x$hwloc_generate_readme" = "xyes" -a \( "x$hwloc_install_doxs" = "xyes" -o "x$hwloc_generate_doxs" = "xyes" \) ]) [test "x$hwloc_generate_readme" = "xyes" -a \( "x$hwloc_install_doxs" = "xyes" -o "x$hwloc_generate_doxs" = "xyes" \) ])
AM_CONDITIONAL([HWLOC_INSTALL_DOXYGEN], AM_CONDITIONAL([HWLOC_INSTALL_DOXYGEN],
[test "x$hwloc_install_doxs" = "xyes"]) [test "x$hwloc_install_doxs" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_LINUX], [test "x$hwloc_linux" = "xyes"]) AM_CONDITIONAL([HWLOC_HAVE_LINUX], [test "x$hwloc_linux" = "xyes"])
@ -1307,8 +1265,8 @@ AC_DEFUN([_HWLOC_CHECK_DECL], [
AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_CC])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM( AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[AC_INCLUDES_DEFAULT([$4]) [AC_INCLUDES_DEFAULT([$4])
$1(int,long,int,long,int,long,int,long,int,long);], void * $1;],
[$1(1,2,3,4,5,6,7,8,9,10);])], )],
[AC_MSG_RESULT([no]) [AC_MSG_RESULT([no])
$3], $3],
[AC_MSG_RESULT([yes]) [AC_MSG_RESULT([yes])

Просмотреть файл

@ -1,43 +1,43 @@
# This macro set originally copied from Open MPI: # This macro set originally copied from Open MPI:
# Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana # Copyright © 2004-2007 The Trustees of Indiana University and Indiana
# University Research and Technology # University Research and Technology
# Corporation. All rights reserved. # Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University # Copyright © 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights # of Tennessee Research Foundation. All rights
# reserved. # reserved.
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart, # Copyright © 2004-2007 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright © 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# and renamed for hwloc: # and renamed for hwloc:
# Copyright (c) 2009 inria. All rights reserved. # Copyright © 2009 Inria. All rights reserved.
# Copyright (c) 2009 Université Bordeaux 1 # Copyright © 2009 Université Bordeaux
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright © 2010 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory. # See COPYING in top-level directory.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are # modification, are permitted provided that the following conditions are
# met: # met:
# #
# - Redistributions of source code must retain the above copyright # - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer. # notice, this list of conditions and the following disclaimer.
# #
# - Redistributions in binary form must reproduce the above copyright # - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer listed # notice, this list of conditions and the following disclaimer listed
# in this license in the documentation and/or other materials # in this license in the documentation and/or other materials
# provided with the distribution. # provided with the distribution.
# #
# - Neither the name of the copyright holders nor the names of its # - Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from # contributors may be used to endorse or promote products derived from
# this software without specific prior written permission. # this software without specific prior written permission.
# #
# The copyright holders provide no reassurances that the source code # The copyright holders provide no reassurances that the source code
# provided does not infringe any patent, copyright, or any other # provided does not infringe any patent, copyright, or any other
# intellectual property rights of third parties. The copyright holders # intellectual property rights of third parties. The copyright holders
# disclaim any liability to any recipient for claims brought against # disclaim any liability to any recipient for claims brought against
# recipient by any third party for infringement of that parties # recipient by any third party for infringement of that parties
# intellectual property rights. # intellectual property rights.
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@ -52,14 +52,14 @@
# #
# #
# Search the generated warnings for # Search the generated warnings for
# keywords regarding skipping or ignoring certain attributes # keywords regarding skipping or ignoring certain attributes
# Intel: ignore # Intel: ignore
# Sun C++: skip # Sun C++: skip
# #
AC_DEFUN([_HWLOC_ATTRIBUTE_FAIL_SEARCH],[ AC_DEFUN([_HWLOC_ATTRIBUTE_FAIL_SEARCH],[
# Be safe for systems that have ancient Autoconf's (e.g., RHEL5) # Be safe for systems that have ancient Autoconf's (e.g., RHEL5)
m4_ifdef([AC_PROG_GREP], m4_ifdef([AC_PROG_GREP],
[AC_REQUIRE([AC_PROG_GREP])], [AC_REQUIRE([AC_PROG_GREP])],
[GREP=grep]) [GREP=grep])
@ -86,7 +86,7 @@ AC_DEFUN([_HWLOC_ATTRIBUTE_FAIL_SEARCH],[
# regarding unused function in main file) # regarding unused function in main file)
# static int usage (int * argument); # static int usage (int * argument);
# #
# The last argument is for specific CFLAGS, that need to be set # The last argument is for specific CFLAGS, that need to be set
# for the compiler to generate a warning on the cross-check. # for the compiler to generate a warning on the cross-check.
# This may need adaption for future compilers / CFLAG-settings. # This may need adaption for future compilers / CFLAG-settings.
# #
@ -107,7 +107,7 @@ AC_DEFUN([_HWLOC_CHECK_SPECIFIC_ATTRIBUTE], [
_HWLOC_ATTRIBUTE_FAIL_SEARCH([$1]) _HWLOC_ATTRIBUTE_FAIL_SEARCH([$1])
], ],
[hwloc_cv___attribute__[$1]=0]) [hwloc_cv___attribute__[$1]=0])
# #
# If the attribute is supported by both compilers, # If the attribute is supported by both compilers,
# try to recompile a *cross-check*, IFF defined. # try to recompile a *cross-check*, IFF defined.
@ -154,7 +154,7 @@ AC_DEFUN([_HWLOC_CHECK_SPECIFIC_ATTRIBUTE], [
# attribute most often fail with a warning (when the warning # attribute most often fail with a warning (when the warning
# level is set). # level is set).
# The compilers output is parsed in _HWLOC_ATTRIBUTE_FAIL_SEARCH # The compilers output is parsed in _HWLOC_ATTRIBUTE_FAIL_SEARCH
# #
# To add a new attributes __NAME__ add the # To add a new attributes __NAME__ add the
# hwloc_cv___attribute__NAME # hwloc_cv___attribute__NAME
# add a new check with _HWLOC_CHECK_SPECIFIC_ATTRIBUTE (possibly with a cross-check) # add a new check with _HWLOC_CHECK_SPECIFIC_ATTRIBUTE (possibly with a cross-check)

Просмотреть файл

@ -1,20 +1,20 @@
dnl -*- shell-script -*- dnl -*- shell-script -*-
dnl dnl
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology dnl University Research and Technology
dnl Corporation. All rights reserved. dnl Corporation. All rights reserved.
dnl Copyright (c) 2004-2005 The University of Tennessee and The University dnl Copyright © 2004-2005 The University of Tennessee and The University
dnl of Tennessee Research Foundation. All rights dnl of Tennessee Research Foundation. All rights
dnl reserved. dnl reserved.
dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, dnl Copyright © 2004-2005 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved. dnl University of Stuttgart. All rights reserved.
dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl Copyright © 2004-2005 The Regents of the University of California.
dnl All rights reserved. dnl All rights reserved.
dnl Copyright (c) 2011 Cisco Systems, Inc. All rights reserved. dnl Copyright © 2011 Cisco Systems, Inc. All rights reserved.
dnl $COPYRIGHT$ dnl $COPYRIGHT$
dnl dnl
dnl Additional copyrights may follow dnl Additional copyrights may follow
dnl dnl
dnl $HEADER$ dnl $HEADER$
dnl dnl
@ -48,7 +48,7 @@ AC_DEFUN([_HWLOC_C_COMPILER_VENDOR], [
m4_ifndef([AC_LANG_DEFINES_PROVIDED], m4_ifndef([AC_LANG_DEFINES_PROVIDED],
[m4_define([AC_LANG_DEFINES_PROVIDED])]) [m4_define([AC_LANG_DEFINES_PROVIDED])])
# HWLOC_IFDEF_IFELSE(symbol, [action-if-defined], # HWLOC_IFDEF_IFELSE(symbol, [action-if-defined],
# [action-if-not-defined]) # [action-if-not-defined])
# ---------------------------------------------- # ----------------------------------------------
# Run compiler to determine if preprocessor symbol "symbol" is # Run compiler to determine if preprocessor symbol "symbol" is
@ -61,7 +61,7 @@ choke me
#endif], [$2], [$3])]) #endif], [$2], [$3])])
# HWLOC_IF_IFELSE(symbol, [action-if-defined], # HWLOC_IF_IFELSE(symbol, [action-if-defined],
# [action-if-not-defined]) # [action-if-not-defined])
# ---------------------------------------------- # ----------------------------------------------
# Run compiler to determine if preprocessor symbol "symbol" is # Run compiler to determine if preprocessor symbol "symbol" is
@ -91,27 +91,27 @@ AC_DEFUN([_HWLOC_CHECK_COMPILER_VENDOR], [
# Intel # Intel
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__INTEL_COMPILER) || defined(__ICC)], [HWLOC_IF_IFELSE([defined(__INTEL_COMPILER) || defined(__ICC)],
[hwloc_check_compiler_vendor_result="intel"])]) [hwloc_check_compiler_vendor_result="intel"])])
# GNU # GNU
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__GNUC__], [HWLOC_IFDEF_IFELSE([__GNUC__],
[hwloc_check_compiler_vendor_result="gnu"])]) [hwloc_check_compiler_vendor_result="gnu"])])
# Borland Turbo C # Borland Turbo C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__TURBOC__], [HWLOC_IFDEF_IFELSE([__TURBOC__],
[hwloc_check_compiler_vendor_result="borland"])]) [hwloc_check_compiler_vendor_result="borland"])])
# Borland C++ # Borland C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__BORLANDC__], [HWLOC_IFDEF_IFELSE([__BORLANDC__],
[hwloc_check_compiler_vendor_result="borland"])]) [hwloc_check_compiler_vendor_result="borland"])])
# Comeau C++ # Comeau C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__COMO__], [HWLOC_IFDEF_IFELSE([__COMO__],
[hwloc_check_compiler_vendor_result="comeau"])]) [hwloc_check_compiler_vendor_result="comeau"])])
# Compaq C/C++ # Compaq C/C++
@ -125,12 +125,12 @@ AC_DEFUN([_HWLOC_CHECK_COMPILER_VENDOR], [
# Cray C/C++ # Cray C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([_CRAYC], [HWLOC_IFDEF_IFELSE([_CRAYC],
[hwloc_check_compiler_vendor_result="cray"])]) [hwloc_check_compiler_vendor_result="cray"])])
# Diab C/C++ # Diab C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__DCC__], [HWLOC_IFDEF_IFELSE([__DCC__],
[hwloc_check_compiler_vendor_result="diab"])]) [hwloc_check_compiler_vendor_result="diab"])])
# Digital Mars # Digital Mars
@ -172,20 +172,20 @@ AC_DEFUN([_HWLOC_CHECK_COMPILER_VENDOR], [
# MIPSpro (SGI) # MIPSpro (SGI)
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(sgi) || defined(__sgi)], [HWLOC_IF_IFELSE([defined(sgi) || defined(__sgi)],
[hwloc_check_compiler_vendor_result="sgi"])]) [hwloc_check_compiler_vendor_result="sgi"])])
# MPW C++ # MPW C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__MRC__) || defined(MPW_C) || defined(MPW_CPLUS)], [HWLOC_IF_IFELSE([defined(__MRC__) || defined(MPW_C) || defined(MPW_CPLUS)],
[hwloc_check_compiler_vendor_result="mpw"])]) [hwloc_check_compiler_vendor_result="mpw"])])
# Microsoft # Microsoft
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[# Always use C compiler when checking for Microsoft, as [# Always use C compiler when checking for Microsoft, as
# Visual C++ doesn't recognize .cc as a C++ file. # Visual C++ doesn't recognize .cc as a C++ file.
AC_LANG_PUSH(C) AC_LANG_PUSH(C)
HWLOC_IF_IFELSE([defined(_MSC_VER) || defined(__MSC_VER)], HWLOC_IF_IFELSE([defined(_MSC_VER) || defined(__MSC_VER)],
[hwloc_check_compiler_vendor_result="microsoft"]) [hwloc_check_compiler_vendor_result="microsoft"])
AC_LANG_POP(C)]) AC_LANG_POP(C)])
@ -201,7 +201,7 @@ AC_DEFUN([_HWLOC_CHECK_COMPILER_VENDOR], [
# Portland Group # Portland Group
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"], AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__PGI], [HWLOC_IFDEF_IFELSE([__PGI],
[hwloc_check_compiler_vendor_result="portland group"])]) [hwloc_check_compiler_vendor_result="portland group"])])
# SAS/C # SAS/C

Просмотреть файл

@ -1,44 +1,44 @@
# This macro set originally copied from Open MPI: # This macro set originally copied from Open MPI:
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana # Copyright © 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology # University Research and Technology
# Corporation. All rights reserved. # Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University # Copyright © 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights # of Tennessee Research Foundation. All rights
# reserved. # reserved.
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart, # Copyright © 2004-2007 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright © 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved. # Copyright © 2006-2007 Cisco Systems, Inc. All rights reserved.
# and renamed/modified for hwloc: # and renamed/modified for hwloc:
# Copyright (c) 2009 inria. All rights reserved. # Copyright © 2009 Inria. All rights reserved.
# Copyright (c) 2009-2010 Université Bordeaux 1 # Copyright © 2009-2010 Université Bordeaux
# Copyright © 2010-2012 Cisco Systems, Inc. All rights reserved. # Copyright © 2010-2012 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory. # See COPYING in top-level directory.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are # modification, are permitted provided that the following conditions are
# met: # met:
# #
# - Redistributions of source code must retain the above copyright # - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer. # notice, this list of conditions and the following disclaimer.
# #
# - Redistributions in binary form must reproduce the above copyright # - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer listed # notice, this list of conditions and the following disclaimer listed
# in this license in the documentation and/or other materials # in this license in the documentation and/or other materials
# provided with the distribution. # provided with the distribution.
# #
# - Neither the name of the copyright holders nor the names of its # - Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from # contributors may be used to endorse or promote products derived from
# this software without specific prior written permission. # this software without specific prior written permission.
# #
# The copyright holders provide no reassurances that the source code # The copyright holders provide no reassurances that the source code
# provided does not infringe any patent, copyright, or any other # provided does not infringe any patent, copyright, or any other
# intellectual property rights of third parties. The copyright holders # intellectual property rights of third parties. The copyright holders
# disclaim any liability to any recipient for claims brought against # disclaim any liability to any recipient for claims brought against
# recipient by any third party for infringement of that parties # recipient by any third party for infringement of that parties
# intellectual property rights. # intellectual property rights.
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@ -56,13 +56,13 @@
# -------------------------------------------------------- # --------------------------------------------------------
AC_DEFUN([_HWLOC_CHECK_VISIBILITY],[ AC_DEFUN([_HWLOC_CHECK_VISIBILITY],[
# Be safe for systems that have ancient Autoconf's (e.g., RHEL5) # Be safe for systems that have ancient Autoconf's (e.g., RHEL5)
m4_ifdef([AC_PROG_GREP], m4_ifdef([AC_PROG_GREP],
[AC_REQUIRE([AC_PROG_GREP])], [AC_REQUIRE([AC_PROG_GREP])],
[GREP=grep]) [GREP=grep])
# Check if the compiler has support for visibility, like some # Check if the compiler has support for visibility, like some
# versions of gcc, icc, Sun Studio cc. # versions of gcc, icc, Sun Studio cc.
AC_ARG_ENABLE(visibility, AC_ARG_ENABLE(visibility,
AC_HELP_STRING([--enable-visibility], AC_HELP_STRING([--enable-visibility],
[enable visibility feature of certain compilers/linkers (default: enabled on platforms that support it)])) [enable visibility feature of certain compilers/linkers (default: enabled on platforms that support it)]))
@ -76,7 +76,7 @@ AC_DEFUN([_HWLOC_CHECK_VISIBILITY],[
hwloc_msg="whether to enable symbol visibility" hwloc_msg="whether to enable symbol visibility"
if test "$enable_visibility" = "no"; then if test "$enable_visibility" = "no"; then
AC_MSG_CHECKING([$hwloc_msg]) AC_MSG_CHECKING([$hwloc_msg])
AC_MSG_RESULT([no (disabled)]) AC_MSG_RESULT([no (disabled)])
else else
CFLAGS_orig=$CFLAGS CFLAGS_orig=$CFLAGS
@ -116,14 +116,14 @@ AC_DEFUN([_HWLOC_CHECK_VISIBILITY],[
if test "$hwloc_add" != "" ; then if test "$hwloc_add" != "" ; then
hwloc_visibility_define=1 hwloc_visibility_define=1
AC_MSG_CHECKING([$hwloc_msg]) AC_MSG_CHECKING([$hwloc_msg])
AC_MSG_RESULT([yes (via $hwloc_add)]) AC_MSG_RESULT([yes (via $hwloc_add)])
elif test "$enable_visibility" = "yes"; then elif test "$enable_visibility" = "yes"; then
AC_MSG_ERROR([Symbol visibility support requested but compiler does not seem to support it. Aborting]) AC_MSG_ERROR([Symbol visibility support requested but compiler does not seem to support it. Aborting])
else else
AC_MSG_CHECKING([$hwloc_msg]) AC_MSG_CHECKING([$hwloc_msg])
AC_MSG_RESULT([no (unsupported)]) AC_MSG_RESULT([no (unsupported)])
fi fi
unset hwloc_add unset hwloc_add
fi fi
AC_DEFINE_UNQUOTED([HWLOC_C_HAVE_VISIBILITY], [$hwloc_visibility_define], AC_DEFINE_UNQUOTED([HWLOC_C_HAVE_VISIBILITY], [$hwloc_visibility_define],

Просмотреть файл

@ -1,16 +1,17 @@
#!/bin/sh #!/bin/sh
# #
# Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana # Copyright © 2004-2006 The Trustees of Indiana University and Indiana
# University Research and Technology # University Research and Technology
# Corporation. All rights reserved. # Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University # Copyright © 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights # of Tennessee Research Foundation. All rights
# reserved. # reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, # Copyright © 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved. # University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California. # Copyright © 2004-2005 The Regents of the University of California.
# All rights reserved. # All rights reserved.
# Copyright © 2008-2013 Cisco Systems, Inc. All rights reserved. # Copyright © 2008-2014 Cisco Systems, Inc. All rights reserved.
# Copyright © 2014 Inria. All rights reserved.
# $COPYRIGHT$ # $COPYRIGHT$
# #
# Additional copyrights may follow # Additional copyrights may follow
@ -34,6 +35,10 @@ else
s/^minor/HWLOC_MINOR_VERSION/ s/^minor/HWLOC_MINOR_VERSION/
s/^release/HWLOC_RELEASE_VERSION/ s/^release/HWLOC_RELEASE_VERSION/
s/^greek/HWLOC_GREEK_VERSION/ s/^greek/HWLOC_GREEK_VERSION/
s/\\\${major}/\\\${HWLOC_MAJOR_VERSION}/
s/\\\${minor}/\\\${HWLOC_MINOR_VERSION}/
s/\\\${release}/\\\${HWLOC_RELEASE_VERSION}/
s/\\\${greek}/\\\${HWLOC_GREEK_VERSION}/
s/^date/HWLOC_RELEASE_DATE/ s/^date/HWLOC_RELEASE_DATE/
s/^snapshot_version/HWLOC_SNAPSHOT_VERSION/ s/^snapshot_version/HWLOC_SNAPSHOT_VERSION/
s/^snapshot/HWLOC_SNAPSHOT/ s/^snapshot/HWLOC_SNAPSHOT/
@ -43,13 +48,7 @@ else
p" < "$srcfile"` p" < "$srcfile"`
eval "$ompi_vers" eval "$ompi_vers"
# Only include the release version if it isn't 0 HWLOC_VERSION="$HWLOC_MAJOR_VERSION.$HWLOC_MINOR_VERSION.$HWLOC_RELEASE_VERSION${HWLOC_GREEK_VERSION}"
if test $HWLOC_RELEASE_VERSION -ne 0 ; then
HWLOC_VERSION="$HWLOC_MAJOR_VERSION.$HWLOC_MINOR_VERSION.$HWLOC_RELEASE_VERSION"
else
HWLOC_VERSION="$HWLOC_MAJOR_VERSION.$HWLOC_MINOR_VERSION"
fi
HWLOC_VERSION="${HWLOC_VERSION}${HWLOC_GREEK_VERSION}"
# If HWLOC_SNAPSHOT=1, then use HWLOC_SNAPSHOT_VERSION # If HWLOC_SNAPSHOT=1, then use HWLOC_SNAPSHOT_VERSION
if test "$HWLOC_SNAPSHOT" = "1"; then if test "$HWLOC_SNAPSHOT" = "1"; then

Просмотреть файл

@ -1,16 +1,16 @@
dnl -*- Autoconf -*- dnl -*- Autoconf -*-
dnl dnl
dnl Copyright (c) 2009-2014 Inria. All rights reserved. dnl Copyright © 2009-2014 Inria. All rights reserved.
dnl Copyright (c) 2009, 2011 Université Bordeaux 1 dnl Copyright © 2009, 2011 Université Bordeaux
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology dnl University Research and Technology
dnl Corporation. All rights reserved. dnl Corporation. All rights reserved.
dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl Copyright © 2004-2005 The Regents of the University of California.
dnl All rights reserved. dnl All rights reserved.
dnl Copyright (c) 2004-2008 High Performance Computing Center Stuttgart, dnl Copyright © 2004-2008 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved. dnl University of Stuttgart. All rights reserved.
dnl Copyright © 2010-2014 Inria. All rights reserved. dnl Copyright © 2010-2015 Inria. All rights reserved.
dnl Copyright © 2006-2011 Cisco Systems, Inc. All rights reserved. dnl Copyright © 2006-2014 Cisco Systems, Inc. All rights reserved.
dnl dnl
dnl See COPYING in top-level directory. dnl See COPYING in top-level directory.
@ -52,21 +52,23 @@ AC_DEFUN([HWLOC_DEFINE_ARGS],[
# Cairo? # Cairo?
AC_ARG_ENABLE([cairo], AC_ARG_ENABLE([cairo],
AS_HELP_STRING([--disable-cairo], AS_HELP_STRING([--disable-cairo],
[Disable the Cairo back-end of hwloc's lstopo command])) [Disable the Cairo back-end of hwloc's lstopo command]))
# CPUID
AC_ARG_ENABLE([cpuid],
AS_HELP_STRING([--disable-cpuid],
[Disable the cpuid-based architecture specific support (x86 component)]))
# XML using libxml2? # XML using libxml2?
AC_ARG_ENABLE([libxml2], AC_ARG_ENABLE([libxml2],
AS_HELP_STRING([--disable-libxml2], AS_HELP_STRING([--disable-libxml2],
[Do not use libxml2 for XML support, use a custom minimalistic support])) [Do not use libxml2 for XML support, use a custom minimalistic support]))
# PCI? # PCI?
AC_ARG_ENABLE([pci], AC_ARG_ENABLE([pci],
AS_HELP_STRING([--disable-pci], AS_HELP_STRING([--disable-pci],
[Disable the PCI device discovery])) [Disable the PCI device discovery]))
AC_ARG_ENABLE([libpci],
AS_HELP_STRING([--enable-libpci],
[Use libpci for PCI support. Note that hwloc may be tainted by the pciutils GPL license.]))
# OpenCL? # OpenCL?
AC_ARG_ENABLE([opencl], AC_ARG_ENABLE([opencl],
@ -93,6 +95,11 @@ AC_DEFUN([HWLOC_DEFINE_ARGS],[
AS_HELP_STRING([--disable-libnuma], AS_HELP_STRING([--disable-libnuma],
[Disable the Linux libnuma])) [Disable the Linux libnuma]))
# LibUdev
AC_ARG_ENABLE([libudev],
AS_HELP_STRING([--disable-libudev],
[Disable the Linux libudev]))
# Plugins # Plugins
AC_ARG_ENABLE([plugins], AC_ARG_ENABLE([plugins],
AS_HELP_STRING([--enable-plugins=name,...], AS_HELP_STRING([--enable-plugins=name,...],
@ -121,22 +128,22 @@ EOF
test "x$enable_doxygen" = x && enable_doxygen=no], test "x$enable_doxygen" = x && enable_doxygen=no],
[AC_MSG_RESULT([yes]) [AC_MSG_RESULT([yes])
test "x$enable_doxygen" = x && enable_doxygen=yes]) test "x$enable_doxygen" = x && enable_doxygen=yes])
# Generating the doxygen output requires a few tools. If we # Generating the doxygen output requires a few tools. If we
# don't have all of them, refuse the build the docs. # don't have all of them, refuse the build the docs.
AC_ARG_VAR([DOXYGEN], [Location of the doxygen program (required for building the hwloc doxygen documentation)]) AC_ARG_VAR([DOXYGEN], [Location of the doxygen program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([DOXYGEN], [doxygen]) AC_PATH_TOOL([DOXYGEN], [doxygen])
HWLOC_DOXYGEN_VERSION=`doxygen --version 2> /dev/null` HWLOC_DOXYGEN_VERSION=`doxygen --version 2> /dev/null`
AC_ARG_VAR([PDFLATEX], [Location of the pdflatex program (required for building the hwloc doxygen documentation)]) AC_ARG_VAR([PDFLATEX], [Location of the pdflatex program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([PDFLATEX], [pdflatex]) AC_PATH_TOOL([PDFLATEX], [pdflatex])
AC_ARG_VAR([MAKEINDEX], [Location of the makeindex program (required for building the hwloc doxygen documentation)]) AC_ARG_VAR([MAKEINDEX], [Location of the makeindex program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([MAKEINDEX], [makeindex]) AC_PATH_TOOL([MAKEINDEX], [makeindex])
AC_ARG_VAR([FIG2DEV], [Location of the fig2dev program (required for building the hwloc doxygen documentation)]) AC_ARG_VAR([FIG2DEV], [Location of the fig2dev program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([FIG2DEV], [fig2dev]) AC_PATH_TOOL([FIG2DEV], [fig2dev])
AC_ARG_VAR([GS], [Location of the gs program (required for building the hwloc doxygen documentation)]) AC_ARG_VAR([GS], [Location of the gs program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([GS], [gs]) AC_PATH_TOOL([GS], [gs])
@ -149,29 +156,15 @@ EOF
AC_MSG_RESULT([$hwloc_generate_doxs]) AC_MSG_RESULT([$hwloc_generate_doxs])
AS_IF([test "x$hwloc_generate_doxs" = xyes -a "x$HWLOC_DOXYGEN_VERSION" = x1.6.2], AS_IF([test "x$hwloc_generate_doxs" = xyes -a "x$HWLOC_DOXYGEN_VERSION" = x1.6.2],
[hwloc_generate_doxs="no"; AC_MSG_WARN([doxygen 1.6.2 has broken short name support, disabling])]) [hwloc_generate_doxs="no"; AC_MSG_WARN([doxygen 1.6.2 has broken short name support, disabling])])
# Linux and OS X take different sed arguments. AC_REQUIRE([AC_PROG_SED])
AC_PROG_SED
AC_MSG_CHECKING([if the sed -i option requires an argument])
rm -f conftest
cat > conftest <<EOF
hello
EOF
$SED -i -e s/hello/goodbye/ conftest 2> /dev/null
AS_IF([test -f conftest-e],
[SED_I="$SED -i ''"
AC_MSG_RESULT([yes])],
[SED_I="$SED -i"
AC_MSG_RESULT([no])])
rm -f conftest conftest-e
AC_SUBST([SED_I])
# Making the top-level README requires w3m or lynx. # Making the top-level README requires w3m or lynx.
AC_ARG_VAR([W3M], [Location of the w3m program (required to building the top-level hwloc README file)]) AC_ARG_VAR([W3M], [Location of the w3m program (required to building the top-level hwloc README file)])
AC_PATH_TOOL([W3M], [w3m]) AC_PATH_TOOL([W3M], [w3m])
AC_ARG_VAR([LYNX], [Location of the lynx program (required to building the top-level hwloc README file)]) AC_ARG_VAR([LYNX], [Location of the lynx program (required to building the top-level hwloc README file)])
AC_PATH_TOOL([LYNX], [lynx]) AC_PATH_TOOL([LYNX], [lynx])
AC_MSG_CHECKING([if can build top-level README]) AC_MSG_CHECKING([if can build top-level README])
AS_IF([test "x$W3M" != "x"], AS_IF([test "x$W3M" != "x"],
[hwloc_generate_readme=yes [hwloc_generate_readme=yes
@ -182,13 +175,13 @@ EOF
[hwloc_generate_readme=no])]) [hwloc_generate_readme=no])])
AC_SUBST(HWLOC_W3_GENERATOR) AC_SUBST(HWLOC_W3_GENERATOR)
AC_MSG_RESULT([$hwloc_generate_readme]) AC_MSG_RESULT([$hwloc_generate_readme])
# If any one of the above tools is missing, we will refuse to make dist. # If any one of the above tools is missing, we will refuse to make dist.
AC_MSG_CHECKING([if will build doxygen docs]) AC_MSG_CHECKING([if will build doxygen docs])
AS_IF([test "x$hwloc_generate_doxs" = "xyes" -a "x$enable_doxygen" != "xno"], AS_IF([test "x$hwloc_generate_doxs" = "xyes" -a "x$enable_doxygen" != "xno"],
[], [hwloc_generate_doxs=no]) [], [hwloc_generate_doxs=no])
AC_MSG_RESULT([$hwloc_generate_doxs]) AC_MSG_RESULT([$hwloc_generate_doxs])
# See if we want to install the doxygen docs # See if we want to install the doxygen docs
AC_MSG_CHECKING([if will install doxygen docs]) AC_MSG_CHECKING([if will install doxygen docs])
AS_IF([test "x$hwloc_generate_doxs" = "xyes" -o \ AS_IF([test "x$hwloc_generate_doxs" = "xyes" -o \
@ -198,7 +191,7 @@ EOF
[hwloc_install_doxs=yes], [hwloc_install_doxs=yes],
[hwloc_install_doxs=no]) [hwloc_install_doxs=no])
AC_MSG_RESULT([$hwloc_install_doxs]) AC_MSG_RESULT([$hwloc_install_doxs])
# For the common developer case, if we're in a developer checkout and # For the common developer case, if we're in a developer checkout and
# using the GNU compilers, turn on maximum warnings unless # using the GNU compilers, turn on maximum warnings unless
# specifically disabled by the user. # specifically disabled by the user.
@ -237,6 +230,7 @@ EOF
# Generate some files for the docs # Generate some files for the docs
AC_CONFIG_FILES( AC_CONFIG_FILES(
hwloc_config_prefix[doc/Makefile] hwloc_config_prefix[doc/Makefile]
hwloc_config_prefix[doc/examples/Makefile]
hwloc_config_prefix[doc/doxygen-config.cfg]) hwloc_config_prefix[doc/doxygen-config.cfg])
]) ])
@ -251,14 +245,16 @@ AC_DEFUN([HWLOC_SETUP_UTILS],[
### ###
EOF EOF
AC_REQUIRE([AC_PROG_SED])
# Cairo support # Cairo support
hwloc_cairo_happy=no hwloc_cairo_happy=no
if test "x$enable_cairo" != "xno"; then if test "x$enable_cairo" != "xno"; then
HWLOC_PKG_CHECK_MODULES([CAIRO], [cairo], [cairo_fill], HWLOC_PKG_CHECK_MODULES([CAIRO], [cairo], [cairo_fill], [cairo.h],
[hwloc_cairo_happy=yes], [hwloc_cairo_happy=yes],
[hwloc_cairo_happy=no]) [hwloc_cairo_happy=no])
fi fi
if test "x$hwloc_cairo_happy" = "xyes"; then if test "x$hwloc_cairo_happy" = "xyes"; then
AC_DEFINE([HWLOC_HAVE_CAIRO], [1], [Define to 1 if you have the `cairo' library.]) AC_DEFINE([HWLOC_HAVE_CAIRO], [1], [Define to 1 if you have the `cairo' library.])
else else
@ -317,6 +313,8 @@ EOF
# Only generate this if we're building the utilities # Only generate this if we're building the utilities
AC_CONFIG_FILES( AC_CONFIG_FILES(
hwloc_config_prefix[utils/Makefile] hwloc_config_prefix[utils/Makefile]
hwloc_config_prefix[utils/hwloc/Makefile]
hwloc_config_prefix[utils/lstopo/Makefile]
hwloc_config_prefix[hwloc.pc]) hwloc_config_prefix[hwloc.pc])
])dnl ])dnl
@ -380,25 +378,25 @@ int foo(void) {
hwloc_config_prefix[tests/xml/Makefile] hwloc_config_prefix[tests/xml/Makefile]
hwloc_config_prefix[tests/ports/Makefile] hwloc_config_prefix[tests/ports/Makefile]
hwloc_config_prefix[tests/rename/Makefile] hwloc_config_prefix[tests/rename/Makefile]
hwloc_config_prefix[tests/linux/hwloc-gather-topology]
hwloc_config_prefix[tests/linux/gather/test-gather-topology.sh] hwloc_config_prefix[tests/linux/gather/test-gather-topology.sh]
hwloc_config_prefix[tests/linux/test-topology.sh] hwloc_config_prefix[tests/linux/test-topology.sh]
hwloc_config_prefix[tests/xml/test-topology.sh] hwloc_config_prefix[tests/xml/test-topology.sh]
hwloc_config_prefix[tests/wrapper.sh] hwloc_config_prefix[tests/wrapper.sh]
hwloc_config_prefix[utils/hwloc-assembler-remote] hwloc_config_prefix[utils/hwloc/hwloc-assembler-remote]
hwloc_config_prefix[utils/hwloc-compress-dir] hwloc_config_prefix[utils/hwloc/hwloc-compress-dir]
hwloc_config_prefix[utils/test-hwloc-annotate.sh] hwloc_config_prefix[utils/hwloc/hwloc-gather-topology]
hwloc_config_prefix[utils/test-hwloc-assembler.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-annotate.sh]
hwloc_config_prefix[utils/test-hwloc-calc.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-assembler.sh]
hwloc_config_prefix[utils/test-hwloc-compress-dir.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-calc.sh]
hwloc_config_prefix[utils/test-hwloc-diffpatch.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-compress-dir.sh]
hwloc_config_prefix[utils/test-hwloc-distances.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-diffpatch.sh]
hwloc_config_prefix[utils/test-hwloc-distrib.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-distances.sh]
hwloc_config_prefix[utils/test-hwloc-info.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-distrib.sh]
hwloc_config_prefix[utils/test-hwloc-ls.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-info.sh]
hwloc_config_prefix[utils/test-fake-plugin.sh]) hwloc_config_prefix[utils/hwloc/test-fake-plugin.sh]
hwloc_config_prefix[utils/lstopo/test-hwloc-ls.sh])
AC_CONFIG_COMMANDS([chmoding-scripts], [chmod +x ]hwloc_config_prefix[tests/linux/test-topology.sh ]hwloc_config_prefix[tests/xml/test-topology.sh ]hwloc_config_prefix[tests/linux/hwloc-gather-topology ]hwloc_config_prefix[tests/linux/gather/test-gather-topology.sh ]hwloc_config_prefix[tests/wrapper.sh ]hwloc_config_prefix[utils/hwloc-assembler-remote ]hwloc_config_prefix[utils/hwloc-compress-dir ]hwloc_config_prefix[utils/test-hwloc-annotate.sh ]hwloc_config_prefix[utils/test-hwloc-assembler.sh ]hwloc_config_prefix[utils/test-hwloc-calc.sh ]hwloc_config_prefix[utils/test-hwloc-compress-dir.sh ]hwloc_config_prefix[utils/test-hwloc-diffpatch.sh ]hwloc_config_prefix[utils/test-hwloc-distances.sh ]hwloc_config_prefix[utils/test-hwloc-distrib.sh ]hwloc_config_prefix[utils/test-hwloc-info.sh ]hwloc_config_prefix[utils/test-hwloc-ls.sh ]hwloc_config_prefix[utils/test-fake-plugin.sh]) AC_CONFIG_COMMANDS([chmoding-scripts], [chmod +x ]hwloc_config_prefix[tests/linux/test-topology.sh ]hwloc_config_prefix[tests/xml/test-topology.sh ]hwloc_config_prefix[tests/linux/gather/test-gather-topology.sh ]hwloc_config_prefix[tests/wrapper.sh ]hwloc_config_prefix[utils/hwloc/hwloc-assembler-remote ]hwloc_config_prefix[utils/hwloc/hwloc-compress-dir ]hwloc_config_prefix[utils/hwloc/hwloc-gather-topology ]hwloc_config_prefix[utils/hwloc/test-hwloc-annotate.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-assembler.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-calc.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-compress-dir.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-diffpatch.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-distances.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-distrib.sh ]hwloc_config_prefix[utils/hwloc/test-hwloc-info.sh ]hwloc_config_prefix[utils/hwloc/test-fake-plugin.sh ]hwloc_config_prefix[utils/lstopo/test-hwloc-ls.sh])
# These links are only needed in standalone mode. It would # These links are only needed in standalone mode. It would
# be nice to m4 foreach this somehow, but whenever I tried # be nice to m4 foreach this somehow, but whenever I tried

Просмотреть файл

@ -1,4 +1,5 @@
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. # Copyright © 2010 Cisco Systems, Inc. All rights reserved.
# Copyright © 2015 Inria. All rights reserved.
# See COPYING in top-level directory. # See COPYING in top-level directory.
# #
# hwloc modification to the following PKG_* macros -- add HWLOC_ # hwloc modification to the following PKG_* macros -- add HWLOC_
@ -7,7 +8,7 @@
# license below. # license below.
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# #
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. # Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -56,7 +57,7 @@ if test -n "$PKG_CONFIG"; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
PKG_CONFIG="" PKG_CONFIG=""
fi fi
fi[]dnl fi[]dnl
])# HWLOC_PKG_PROG_PKG_CONFIG ])# HWLOC_PKG_PROG_PKG_CONFIG
@ -108,7 +109,7 @@ fi[]dnl
])# _HWLOC_PKG_SHORT_ERRORS_SUPPORTED ])# _HWLOC_PKG_SHORT_ERRORS_SUPPORTED
# HWLOC_PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # HWLOC_PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, FUNCTION, HEADER, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND]) # [ACTION-IF-NOT-FOUND])
# #
# #
@ -138,13 +139,13 @@ See the pkg-config man page for more details.])
_HWLOC_PKG_SHORT_ERRORS_SUPPORTED _HWLOC_PKG_SHORT_ERRORS_SUPPORTED
if test $HWLOC_pkg_short_errors_supported = yes; then if test $HWLOC_pkg_short_errors_supported = yes; then
HWLOC_[]$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2" 2>&1` HWLOC_[]$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2" 2>&1`
else else
HWLOC_[]$1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2" 2>&1` HWLOC_[]$1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2" 2>&1`
fi fi
# Put the nasty error message in config.log where it belongs # Put the nasty error message in config.log where it belongs
echo "$HWLOC_[]$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD echo "$HWLOC_[]$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
ifelse([$5], , [AC_MSG_ERROR(dnl ifelse([$6], , [AC_MSG_ERROR(dnl
[Package requirements ($2) were not met: [Package requirements ($2) were not met:
$HWLOC_$1_PKG_ERRORS $HWLOC_$1_PKG_ERRORS
@ -155,9 +156,9 @@ installed software in a non-standard prefix.
_HWLOC_PKG_TEXT _HWLOC_PKG_TEXT
])], ])],
[AC_MSG_RESULT([no]) [AC_MSG_RESULT([no])
$5]) $6])
elif test $HWLOC_pkg_failed = untried; then elif test $HWLOC_pkg_failed = untried; then
ifelse([$5], , [AC_MSG_FAILURE(dnl ifelse([$6], , [AC_MSG_FAILURE(dnl
[The pkg-config script could not be found or is too old. Make sure it [The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config. path to pkg-config.
@ -166,7 +167,7 @@ _HWLOC_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])], To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
[AC_MSG_RESULT([cannot check without pkg-config]) [AC_MSG_RESULT([cannot check without pkg-config])
$5]) $6])
else else
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
@ -177,21 +178,30 @@ To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
# with CFLAGS=-m32 LDFLAGS=-m32. pkg-config gave us valid # with CFLAGS=-m32 LDFLAGS=-m32. pkg-config gave us valid
# results, but we'll fail if we try to link. So detect that # results, but we'll fail if we try to link. So detect that
# failure now. # failure now.
# There are also cases on Mac where pkg-config returns paths
# that do not actually exists until some magic is applied.
# http://www.open-mpi.org/community/lists/hwloc-devel/2015/03/4402.php
# So check whether we find the header as well.
hwloc_cflags_save=$CFLAGS hwloc_cflags_save=$CFLAGS
hwloc_cppflags_save=$CPPFLAGS
hwloc_libs_save=$LIBS hwloc_libs_save=$LIBS
CFLAGS="$CFLAGS $HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS" CFLAGS="$CFLAGS $HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS"
CPPFLAGS="$CPPFLAGS $HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS"
LIBS="$LIBS $HWLOC_pkg_cv_HWLOC_[]$1[]_LIBS" LIBS="$LIBS $HWLOC_pkg_cv_HWLOC_[]$1[]_LIBS"
AC_CHECK_FUNC([$3], [hwloc_result=yes], [hwloc_result=no]) AC_CHECK_HEADER([$4], [
AC_CHECK_FUNC([$3], [hwloc_result=yes], [hwloc_result=no])
], [hwloc_result=no])
CFLAGS=$hwloc_cflags_save CFLAGS=$hwloc_cflags_save
CPPFLAGS=$hwloc_cppflags_save
LIBS=$hwloc_libs_save LIBS=$hwloc_libs_save
AC_MSG_CHECKING([for final $1 support]) AC_MSG_CHECKING([for final $1 support])
AS_IF([test "$hwloc_result" = "yes"], AS_IF([test "$hwloc_result" = "yes"],
[HWLOC_[]$1[]_CFLAGS=$HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS [HWLOC_[]$1[]_CFLAGS=$HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS
HWLOC_[]$1[]_LIBS=$HWLOC_pkg_cv_HWLOC_[]$1[]_LIBS HWLOC_[]$1[]_LIBS=$HWLOC_pkg_cv_HWLOC_[]$1[]_LIBS
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
ifelse([$4], , :, [$4])], ifelse([$5], , :, [$5])],
[AC_MSG_RESULT([no]) [AC_MSG_RESULT([no])
ifelse([$5], , :, [$5])]) ifelse([$6], , :, [$6])])
fi[]dnl fi[]dnl
])# HWLOC_PKG_CHECK_MODULES ])# HWLOC_PKG_CHECK_MODULES

Просмотреть файл

@ -3,7 +3,7 @@
scriptversion=2013-07-13.22; # UTC scriptversion=2013-07-13.22; # UTC
# Copyright (C) 2011-2013 Free Software Foundation, Inc. # Copyright (C) 2011-2014 Free Software Foundation, Inc.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -106,11 +106,14 @@ trap "st=143; $do_exit" 15
# Test script is run here. # Test script is run here.
"$@" >$log_file 2>&1 "$@" >$log_file 2>&1
estatus=$? estatus=$?
if test $enable_hard_errors = no && test $estatus -eq 99; then if test $enable_hard_errors = no && test $estatus -eq 99; then
estatus=1 tweaked_estatus=1
else
tweaked_estatus=$estatus
fi fi
case $estatus:$expect_failure in case $tweaked_estatus:$expect_failure in
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
0:*) col=$grn res=PASS recheck=no gcopy=no;; 0:*) col=$grn res=PASS recheck=no gcopy=no;;
77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
@ -119,6 +122,12 @@ case $estatus:$expect_failure in
*:*) col=$red res=FAIL recheck=yes gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
esac esac
# Report the test outcome and exit status in the logs, so that one can
# know whether the test passed or failed simply by looking at the '.log'
# file, without the need of also peaking into the corresponding '.trs'
# file (automake bug#11814).
echo "$res $test_name (exit status: $estatus)" >>$log_file
# Report outcome to console. # Report outcome to console.
echo "${col}${res}${std}: $test_name" echo "${col}${res}${std}: $test_name"

Просмотреть файл

@ -1,18 +1,22 @@
# -*- shell-script -*- # -*- shell-script -*-
# #
# Copyright © 2009 CNRS # Copyright © 2009 CNRS
# Copyright © 2009-2013 Inria. All rights reserved. # Copyright © 2009-2015 Inria. All rights reserved.
# Copyright © 2009, 2011-2012 Université Bordeaux 1 # Copyright © 2009, 2011-2012 Université Bordeaux
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# #
# See COPYING in top-level directory. # See COPYING in top-level directory.
# #
# Additional copyrights may follow # Additional copyrights may follow
# #
# $HEADER$ # $HEADER$
# #
AC_INIT([hwloc], ####################################################################
# Autoconf, Automake, and Libtool bootstrapping
####################################################################
AC_INIT([hwloc],
[m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --version]))], [m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --version]))],
[http://www.open-mpi.org/projects/hwloc/], [hwloc]) [http://www.open-mpi.org/projects/hwloc/], [hwloc])
AC_PREREQ(2.63) AC_PREREQ(2.63)
@ -36,7 +40,7 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([1.11 dist-bzip2 subdir-objects foreign tar-ustar parallel-tests -Wall -Werror]) AM_INIT_AUTOMAKE([1.11 dist-bzip2 subdir-objects foreign tar-ustar parallel-tests -Wall -Werror])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# We want new Libtool. None of that old stuff. Pfft. # We want new Libtool. None of that old stuff. Pfft.
m4_ifdef([LT_PREREQ], [], m4_ifdef([LT_PREREQ], [],
[m4_fatal([libtool version 2.2.6 or higher is required], [63])]) [m4_fatal([libtool version 2.2.6 or higher is required], [63])])
LT_PREREQ([2.2.6]) LT_PREREQ([2.2.6])
@ -44,45 +48,18 @@ LT_PREREQ([2.2.6])
AC_LANG([C]) AC_LANG([C])
AC_USE_SYSTEM_EXTENSIONS AC_USE_SYSTEM_EXTENSIONS
# Make configure depend on the VERSION file, since it's used in AC_INIT ####################################################################
AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/VERSION']) # Setup the configure-results header file
####################################################################
# Get the version of hwloc that we are installing
AC_MSG_CHECKING([for hwloc version])
HWLOC_VERSION="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION`"
if test "$?" != "0"; then
AC_MSG_ERROR([Cannot continue])
fi
HWLOC_RELEASE_DATE="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --release-date`"
AC_SUBST(HWLOC_VERSION)
AC_SUBST(HWLOC_RELEASE_DATE)
AC_MSG_RESULT([$HWLOC_VERSION])
# Override/fixup the version numbers set by AC_INIT, since on
# developer builds, there's no good way to know what the version is
# before running configure :(. We only use the base version number
# for the version set in AC_INIT. This will always match reality
# because we add the VERSION file (the only way to change the
# major.minor.release{greek}) into the configure dependencies.
PACKAGE_VERSION="$HWLOC_VERSION"
PACKAGE_STRING="${PACKAGE_NAME} ${PACKAGE_VERSION}"
VERSION="${PACKAGE_VERSION}"
# For standalone configurations, we also include a .so version number.
. $srcdir/VERSION
AC_SUBST([libhwloc_so_version])
# Setup the header file
AH_TOP([/* -*- c -*- AH_TOP([/* -*- c -*-
* *
* Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux 1 All rights reserved. * Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux All rights reserved.
* Copyright © 2009 Cisco Systems, Inc. All rights reserved. * Copyright © 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
* *
* $HEADER$ * $HEADER$
* *
* This file is automatically generated by configure. Edits will be lost * This file is automatically generated by configure. Edits will be lost
@ -96,7 +73,9 @@ AH_BOTTOM([
#endif /* HWLOC_CONFIGURE_H */ #endif /* HWLOC_CONFIGURE_H */
]) ])
####################################################################
# Setup C compiler # Setup C compiler
####################################################################
CFLAGS_save="$CFLAGS" CFLAGS_save="$CFLAGS"
AC_PROG_CC AC_PROG_CC
@ -112,6 +91,10 @@ AS_IF([test -z "$CC_FOR_BUILD"],[
AC_SUBST([CC_FOR_BUILD], [$CC]) AC_SUBST([CC_FOR_BUILD], [$CC])
]) ])
####################################################################
# CLI arguments
####################################################################
# Define hwloc's configure arguments # Define hwloc's configure arguments
HWLOC_DEFINE_ARGS HWLOC_DEFINE_ARGS
@ -129,6 +112,10 @@ AS_IF([test "$enable_embedded_mode" != "yes"],
AC_MSG_ERROR([Cannot build standalone hwloc])], AC_MSG_ERROR([Cannot build standalone hwloc])],
[HWLOC_BUILD_STANDALONE])]) [HWLOC_BUILD_STANDALONE])])
####################################################################
# Setup for the hwloc API
####################################################################
# Setup the hwloc core # Setup the hwloc core
HWLOC_SETUP_CORE([], [], [AC_MSG_ERROR([Cannot build hwloc core])], [1]) HWLOC_SETUP_CORE([], [], [AC_MSG_ERROR([Cannot build hwloc core])], [1])
@ -148,6 +135,35 @@ EOF
# Run the AM_CONDITIONALs # Run the AM_CONDITIONALs
HWLOC_DO_AM_CONDITIONALS HWLOC_DO_AM_CONDITIONALS
####################################################################
# Version information
####################################################################
# HWLOC_VERSION was setup by HWLOC_SETUP_CORE above.
# Make configure depend on the VERSION file, since it's used in AC_INIT
AC_SUBST([CONFIGURE_DEPENDENCIES], ['$(top_srcdir)/VERSION'])
# Override/fixup the version numbers set by AC_INIT, since on
# developer builds, there's no good way to know what the version is
# before running configure :(. We only use the base version number
# for the version set in AC_INIT. This will always match reality
# because we add the VERSION file (the only way to change the
# major.minor.release{greek}) into the configure dependencies.
PACKAGE_VERSION="$HWLOC_VERSION"
PACKAGE_STRING="${PACKAGE_NAME} ${PACKAGE_VERSION}"
VERSION="${PACKAGE_VERSION}"
# For standalone configurations, we also include a .so version number.
. $srcdir/VERSION
AC_SUBST([libhwloc_so_version])
####################################################################
# Final output
####################################################################
# Set the final flags # Set the final flags
CFLAGS="$HWLOC_EMBEDDED_CFLAGS $CFLAGS" CFLAGS="$HWLOC_EMBEDDED_CFLAGS $CFLAGS"
CPPFLAGS="$HWLOC_EMBEDDED_CPPFLAGS $CPPFLAGS" CPPFLAGS="$HWLOC_EMBEDDED_CPPFLAGS $CPPFLAGS"
@ -160,42 +176,18 @@ AM_DISABLE_STATIC
AM_PROG_LIBTOOL([dlopen win32-dll]) AM_PROG_LIBTOOL([dlopen win32-dll])
LT_LANG([C]) LT_LANG([C])
# Party on # Party on
AC_OUTPUT AC_OUTPUT
# Create a comma-delimited list in an environment variable. # Warn if we didn't have pkg-config
# $1 = variable name if test "x$PKG_CONFIG" = x; then
# $2 = value to append cat << EOF
append_env() {
# Tricky shell/m4 quoting here -- not for the meek.
var=[$]1
# Note: quotes *NOT* needed in this assignment
eval initial_value=\$$var
AS_IF([test "$initial_value" != ""], ************************************************************************
[new_value="$initial_value, [$]2"], Could not detect/enable some features such as libxml2 and Cairo support
[new_value="[$]2]") because pkg-config isn't available.
eval "[$]1=\"$new_value\"" ************************************************************************
} EOF
# Warn about PCI support
if test x$hwloc_warn_may_use_libpci = xyes; then
echo
echo "***********************************************************************"
if test "x$hwloc_linuxpci_happy" = "xyes"; then
echo "Full PCI support could not be enabled because libpciaccess is not available."
else
echo "PCI support could not be enabled because libpciaccess is not available."
fi
echo "libpci could be used instead but hwloc may be tainted by the GPL"
echo "license of pciutils. Add --enable-libpci to enable it."
if test "x$hwloc_linuxpci_happy" = "xyes"; then
echo "Only the Linux-specific PCI (linuxpci component) is enabled for now."
echo "It misses device names."
fi
echo "***********************************************************************"
fi fi
# Show which optional support we'll be building # Show which optional support we'll be building

Просмотреть файл

@ -1,5 +1,5 @@
# Copyright © 2009-2014 Inria. All rights reserved. # Copyright © 2009-2014 Inria. All rights reserved.
# Copyright © 2009-2010 Université Bordeaux 1 # Copyright © 2009-2010 Université Bordeaux
# Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
# Copyright © 2011 Oracle and/or its affiliates. All rights reserved. # Copyright © 2011 Oracle and/or its affiliates. All rights reserved.
# See COPYING in top-level directory. # See COPYING in top-level directory.
@ -27,7 +27,7 @@ include_hwloc_HEADERS = \
hwloc/rename.h \ hwloc/rename.h \
hwloc/deprecated.h hwloc/deprecated.h
include_hwloc_autogendir = $(includedir)/hwloc/autogen include_hwloc_autogendir = $(includedir)/hwloc/autogen
nodist_include_hwloc_autogen_HEADERS = hwloc/autogen/config.h nodist_include_hwloc_autogen_HEADERS = hwloc/autogen/config.h
noinst_HEADERS = \ noinst_HEADERS = \
private/private.h \ private/private.h \

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -10,7 +10,7 @@
* PLEASE GO READ THE DOCUMENTATION! * PLEASE GO READ THE DOCUMENTATION!
* ------------------------------------------------ * ------------------------------------------------
* $tarball_directory/doc/doxygen-doc/ * $tarball_directory/doc/doxygen-doc/
* or * or
* http://www.open-mpi.org/projects/hwloc/doc/ * http://www.open-mpi.org/projects/hwloc/doc/
*===================================================================== *=====================================================================
* *
@ -34,6 +34,9 @@
* *
* Please, go read the documentation. :-) * Please, go read the documentation. :-)
* *
* Moreover there are several examples of hwloc use under doc/examples
* in the source tree.
*
*=====================================================================*/ *=====================================================================*/
/** \file /** \file
@ -75,13 +78,13 @@ extern "C" {
*/ */
/** \brief Indicate at build time which hwloc API version is being used. */ /** \brief Indicate at build time which hwloc API version is being used. */
#define HWLOC_API_VERSION 0x00010900 #define HWLOC_API_VERSION 0x00010b00
/** \brief Indicate at runtime which hwloc API version was used at build time. */ /** \brief Indicate at runtime which hwloc API version was used at build time. */
HWLOC_DECLSPEC unsigned hwloc_get_api_version(void); HWLOC_DECLSPEC unsigned hwloc_get_api_version(void);
/** \brief Current component and plugin ABI version (see hwloc/plugins.h) */ /** \brief Current component and plugin ABI version (see hwloc/plugins.h) */
#define HWLOC_COMPONENT_ABI 3 #define HWLOC_COMPONENT_ABI 4
/** @} */ /** @} */
@ -112,6 +115,9 @@ HWLOC_DECLSPEC unsigned hwloc_get_api_version(void);
* *
* It may be consulted and modified with the bitmap API as any * It may be consulted and modified with the bitmap API as any
* ::hwloc_bitmap_t (see hwloc/bitmap.h). * ::hwloc_bitmap_t (see hwloc/bitmap.h).
*
* Each bit may be converted into a PU object using
* hwloc_get_pu_obj_by_os_index().
*/ */
typedef hwloc_bitmap_t hwloc_cpuset_t; typedef hwloc_bitmap_t hwloc_cpuset_t;
/** \brief A non-modifiable ::hwloc_cpuset_t. */ /** \brief A non-modifiable ::hwloc_cpuset_t. */
@ -122,6 +128,8 @@ typedef hwloc_const_bitmap_t hwloc_const_cpuset_t;
* *
* It may be consulted and modified with the bitmap API as any * It may be consulted and modified with the bitmap API as any
* ::hwloc_bitmap_t (see hwloc/bitmap.h). * ::hwloc_bitmap_t (see hwloc/bitmap.h).
* Each bit may be converted into a NUMA node object using
* hwloc_get_numanode_obj_by_os_index().
* *
* When binding memory on a system without any NUMA node * When binding memory on a system without any NUMA node
* (when the whole memory is considered as a single memory bank), * (when the whole memory is considered as a single memory bank),
@ -169,11 +177,11 @@ typedef enum {
* A set of processors and memory with cache * A set of processors and memory with cache
* coherency. * coherency.
*/ */
HWLOC_OBJ_NODE, /**< \brief NUMA node. HWLOC_OBJ_NUMANODE, /**< \brief NUMA node.
* A set of processors around memory which the * A set of processors around memory which the
* processors can directly access. * processors can directly access.
*/ */
HWLOC_OBJ_SOCKET, /**< \brief Socket, physical package, or chip. HWLOC_OBJ_PACKAGE, /**< \brief Physical package, what goes into a socket.
* In the physical meaning, i.e. that you can add * In the physical meaning, i.e. that you can add
* or remove physically. * or remove physically.
*/ */
@ -207,7 +215,8 @@ typedef enum {
HWLOC_OBJ_MISC, /**< \brief Miscellaneous objects. HWLOC_OBJ_MISC, /**< \brief Miscellaneous objects.
* Objects without particular meaning, that can e.g. be * Objects without particular meaning, that can e.g. be
* added by the application for its own use. * added by the application for its own use, or by hwloc
* for miscellaneous objects such as MemoryDevice.
*/ */
HWLOC_OBJ_BRIDGE, /**< \brief Bridge. HWLOC_OBJ_BRIDGE, /**< \brief Bridge.
@ -282,12 +291,12 @@ typedef enum hwloc_obj_osdev_type_e {
* can not be compared (because neither is usually contained in the other), * can not be compared (because neither is usually contained in the other),
* HWLOC_TYPE_UNORDERED is returned. Object types containing CPUs can always * HWLOC_TYPE_UNORDERED is returned. Object types containing CPUs can always
* be compared (usually, a system contains machines which contain nodes which * be compared (usually, a system contains machines which contain nodes which
* contain sockets which contain caches, which contain cores, which contain * contain packages which contain caches, which contain cores, which contain
* processors). * processors).
* *
* \note HWLOC_OBJ_PU will always be the deepest. * \note HWLOC_OBJ_PU will always be the deepest.
* \note This does not mean that the actual topology will respect that order: * \note This does not mean that the actual topology will respect that order:
* e.g. as of today cores may also contain caches, and sockets may also contain * e.g. as of today cores may also contain caches, and packages may also contain
* nodes. This is thus just to be seen as a fallback comparison method. * nodes. This is thus just to be seen as a fallback comparison method.
*/ */
HWLOC_DECLSPEC int hwloc_compare_types (hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const; HWLOC_DECLSPEC int hwloc_compare_types (hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const;
@ -534,8 +543,7 @@ union hwloc_obj_attr_u {
* distances are available for all objects in the machine. * distances are available for all objects in the machine.
* *
* If the \p latency pointer is not \c NULL, the pointed array contains * If the \p latency pointer is not \c NULL, the pointed array contains
* memory latencies (non-zero values), as defined by the ACPI SLIT * memory latencies (non-zero values), see below.
* specification.
* *
* In the future, some other types of distances may be considered. * In the future, some other types of distances may be considered.
* In these cases, \p latency may be \c NULL. * In these cases, \p latency may be \c NULL.
@ -546,10 +554,17 @@ struct hwloc_distances_s {
unsigned nbobjs; /**< \brief Number of objects considered in the matrix. unsigned nbobjs; /**< \brief Number of objects considered in the matrix.
* It is the number of descendant objects at \p relative_depth * It is the number of descendant objects at \p relative_depth
* below the containing object. * below the containing object.
* It corresponds to the result of hwloc_get_nbobjs_inside_cpuset_by_depth. */ * It corresponds to the result of hwloc_get_nbobjs_inside_cpuset_by_depth(). */
float *latency; /**< \brief Matrix of latencies between objects, stored as a one-dimension array. float *latency; /**< \brief Matrix of latencies between objects, stored as a one-dimension array.
* May be \c NULL if the distances considered here are not latencies. * May be \c NULL if the distances considered here are not latencies.
*
* Unless defined by the user, this currently contains latencies
* between NUMA nodes (as reported in the System Locality Distance Information Table
* (SLIT) in the ACPI specification), which may or may not be accurate.
* It corresponds to the latency for accessing the memory of one node
* from a core in another node.
*
* Values are normalized to get 1.0 as the minimal value in the matrix. * Values are normalized to get 1.0 as the minimal value in the matrix.
* Latency from i-th to j-th object is stored in slot i*nbobjs+j. * Latency from i-th to j-th object is stored in slot i*nbobjs+j.
*/ */
@ -614,6 +629,15 @@ HWLOC_DECLSPEC int hwloc_topology_load(hwloc_topology_t topology);
*/ */
HWLOC_DECLSPEC void hwloc_topology_destroy (hwloc_topology_t topology); HWLOC_DECLSPEC void hwloc_topology_destroy (hwloc_topology_t topology);
/** \brief Duplicate a topology.
*
* The entire topology structure as well as its objects
* are duplicated into a new one.
*
* This is useful for keeping a backup while modifying a topology.
*/
HWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);
/** \brief Run internal checks on a topology structure /** \brief Run internal checks on a topology structure
* *
* The program aborts if an inconsistency is detected in the given topology. * The program aborts if an inconsistency is detected in the given topology.
@ -658,6 +682,8 @@ HWLOC_DECLSPEC void hwloc_topology_check(hwloc_topology_t topology);
* The bottom-level type HWLOC_OBJ_PU may not be ignored. * The bottom-level type HWLOC_OBJ_PU may not be ignored.
* The top-level object of the hierarchy will never be ignored, even if this function * The top-level object of the hierarchy will never be ignored, even if this function
* succeeds. * succeeds.
* Group objects are always ignored if they do not bring any structure
* since they are designed to add structure to the topology.
* I/O objects may not be ignored, topology flags should be used to configure * I/O objects may not be ignored, topology flags should be used to configure
* their discovery instead. * their discovery instead.
*/ */
@ -691,7 +717,7 @@ enum hwloc_topology_flags_e {
/** \brief Detect the whole system, ignore reservations and offline settings. /** \brief Detect the whole system, ignore reservations and offline settings.
* *
* Gather all resources, even if some were disabled by the administrator. * Gather all resources, even if some were disabled by the administrator.
* For instance, ignore Linux Cpusets and gather all processors and memory nodes, * For instance, ignore Linux Cgroup/Cpusets and gather all processors and memory nodes,
* and ignore the fact that some resources may be offline. * and ignore the fact that some resources may be offline.
* \hideinitializer * \hideinitializer
*/ */
@ -723,6 +749,7 @@ enum hwloc_topology_flags_e {
* detection using the pci backend. Only the common PCI devices (GPUs, * detection using the pci backend. Only the common PCI devices (GPUs,
* NICs, block devices, ...) and host bridges (objects that connect the host * NICs, block devices, ...) and host bridges (objects that connect the host
* objects to an I/O subsystem) will be added to the topology. * objects to an I/O subsystem) will be added to the topology.
* Additionally it also enables MemoryDevice misc objects.
* Uncommon devices and other bridges (such as PCI-to-PCI bridges) will be * Uncommon devices and other bridges (such as PCI-to-PCI bridges) will be
* ignored. * ignored.
* \hideinitializer * \hideinitializer
@ -743,6 +770,7 @@ enum hwloc_topology_flags_e {
* This flag enables detection of all I/O devices (even the uncommon ones) * This flag enables detection of all I/O devices (even the uncommon ones)
* and bridges (even those that have no device behind them) using the pci * and bridges (even those that have no device behind them) using the pci
* backend. * backend.
* This implies HWLOC_TOPOLOGY_FLAG_IO_DEVICES.
* \hideinitializer * \hideinitializer
*/ */
HWLOC_TOPOLOGY_FLAG_WHOLE_IO = (1UL<<4), HWLOC_TOPOLOGY_FLAG_WHOLE_IO = (1UL<<4),
@ -1037,6 +1065,25 @@ struct hwloc_topology_support {
/** \brief Retrieve the topology support. */ /** \brief Retrieve the topology support. */
HWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(hwloc_topology_t __hwloc_restrict topology); HWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(hwloc_topology_t __hwloc_restrict topology);
/** \brief Set the topology-specific userdata pointer.
*
* Each topology may store one application-given private data pointer.
* It is initialized to \c NULL.
* hwloc will never modify it.
*
* Use it as you wish, after hwloc_topology_init() and until hwloc_topolog_destroy().
*
* This pointer is not exported to XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata(hwloc_topology_t topology, const void *userdata);
/** \brief Retrieve the topology-specific userdata pointer.
*
* Retrieve the application-given private data pointer that was
* previously set with hwloc_topology_set_userdata().
*/
HWLOC_DECLSPEC void * hwloc_topology_get_userdata(hwloc_topology_t topology);
/** @} */ /** @} */
@ -1047,7 +1094,7 @@ HWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(h
* Be sure to see the figure in \ref termsanddefs that shows a * Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin * complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one * relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers. * package has fewer caches than its peers.
*/ */
/** \brief Get the depth of the hierarchical tree of objects. /** \brief Get the depth of the hierarchical tree of objects.
@ -1180,7 +1227,7 @@ HWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwlo
/** \brief Return an object type and attributes from a type string. /** \brief Return an object type and attributes from a type string.
* *
* Convert strings such as "socket" or "cache" into the corresponding types. * Convert strings such as "Package" or "Cache" into the corresponding types.
* Matching is case-insensitive, and only the first letters are actually * Matching is case-insensitive, and only the first letters are actually
* required to match. * required to match.
* *
@ -1278,31 +1325,42 @@ HWLOC_DECLSPEC void hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const
* *
* It is often useful to call hwloc_bitmap_singlify() first so that a single CPU * It is often useful to call hwloc_bitmap_singlify() first so that a single CPU
* remains in the set. This way, the process will not even migrate between * remains in the set. This way, the process will not even migrate between
* different CPUs. Some operating systems also only support that kind of binding. * different CPUs inside the given set.
* Some operating systems also only support that kind of binding.
* *
* \note Some operating systems do not provide all hwloc-supported * Some operating systems do not provide all hwloc-supported
* mechanisms to bind processes, threads, etc. and the corresponding * mechanisms to bind processes, threads, etc.
* binding functions may fail. -1 is returned and errno is set to * hwloc_topology_get_support() may be used to query about the actual CPU
* ENOSYS when it is not possible to bind the requested kind of object * binding support in the currently used operating system.
* processes/threads. errno is set to EXDEV when the requested cpuset *
* When the requested binding operation is not available and the
* ::HWLOC_CPUBIND_STRICT flag was passed, the function returns -1.
* \p errno is set to \c ENOSYS when it is not possible to bind the requested kind of object
* processes/threads. errno is set to \c EXDEV when the requested cpuset
* can not be enforced (e.g. some systems only allow one CPU, and some * can not be enforced (e.g. some systems only allow one CPU, and some
* other systems only allow one NUMA node). * other systems only allow one NUMA node).
* *
* The most portable version that should be preferred over the others, whenever * If ::HWLOC_CPUBIND_STRICT was not passed, the function may fail as well,
* possible, is * or the operating system may use a slightly different operation
* (with side-effects, smaller binding set, etc.)
* when the requested operation is not exactly supported.
*
* The most portable version that should be preferred over the others,
* whenever possible, is the following one which just binds the current program,
* assuming it is single-threaded:
* *
* \code * \code
* hwloc_set_cpubind(topology, set, 0), * hwloc_set_cpubind(topology, set, 0),
* \endcode * \endcode
* *
* as it just binds the current program, assuming it is single-threaded, or * If the program may be multithreaded, the following one should be preferred
* to only bind the current thread:
* *
* \code * \code
* hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD), * hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD),
* \endcode * \endcode
* *
* which binds the current thread of the current program (which may be * \sa Some example codes are available under doc/examples/ in the source tree.
* multithreaded).
* *
* \note To unbind, just call the binding function with either a full cpuset or * \note To unbind, just call the binding function with either a full cpuset or
* a cpuset equal to the system cpuset. * a cpuset equal to the system cpuset.
@ -1310,8 +1368,8 @@ HWLOC_DECLSPEC void hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const
* \note On some operating systems, CPU binding may have effects on memory binding, see * \note On some operating systems, CPU binding may have effects on memory binding, see
* ::HWLOC_CPUBIND_NOMEMBIND * ::HWLOC_CPUBIND_NOMEMBIND
* *
* Running lstopo --top can be a very convenient tool to check how binding * \note Running lstopo --top or hwloc-ps can be a very convenient tool to check
* actually happened. * how binding actually happened.
* @{ * @{
*/ */
@ -1482,42 +1540,47 @@ HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, h
* *
* Memory binding can be done three ways: * Memory binding can be done three ways:
* *
* - explicit memory allocation thanks to hwloc_alloc_membind and friends: the * - explicit memory allocation thanks to hwloc_alloc_membind() and friends:
* binding will have effect on the memory allocated by these functions. * the binding will have effect on the memory allocated by these functions.
* - implicit memory binding through binding policy: hwloc_set_membind and * - implicit memory binding through binding policy: hwloc_set_membind() and
* friends only define the current policy of the process, which will be * friends only define the current policy of the process, which will be
* applied to the subsequent calls to malloc() and friends. * applied to the subsequent calls to malloc() and friends.
* - migration of existing memory ranges, thanks to hwloc_set_area_membind() * - migration of existing memory ranges, thanks to hwloc_set_area_membind()
* and friends, which move already-allocated data. * and friends, which move already-allocated data.
* *
* \note Not all operating systems support all three ways Using a binding flag * Not all operating systems support all three ways.
* or policy that is not supported by the underlying OS will cause hwloc's * hwloc_topology_get_support() may be used to query about the actual memory
* binding functions to fail and return -1. errno will be set to * binding support in the currently used operating system.
* ENOSYS when the system does support the specified action or policy *
* When the requested binding operation is not available and the
* ::HWLOC_MEMBIND_STRICT flag was passed, the function returns -1.
* \p errno will be set to \c ENOSYS when the system does support
* the specified action or policy
* (e.g., some systems only allow binding memory on a per-thread * (e.g., some systems only allow binding memory on a per-thread
* basis, whereas other systems only allow binding memory for all * basis, whereas other systems only allow binding memory for all
* threads in a process). errno will be set to EXDEV when the * threads in a process).
* requested cpuset can not be enforced (e.g., some systems only allow * \p errno will be set to EXDEV when the requested cpuset can not be enforced
* binding memory to a single NUMA node). * (e.g., some systems only allow binding memory to a single NUMA node).
*
* If ::HWLOC_MEMBIND_STRICT was not passed, the function may fail as well,
* or the operating system may use a slightly different operation
* (with side-effects, smaller binding set, etc.)
* when the requested operation is not exactly supported.
* *
* The most portable form that should be preferred over the others * The most portable form that should be preferred over the others
* whenever possible is as follows: * whenever possible is as follows.
* * It allocates some memory hopefully bound to the specified set.
* \code
* hwloc_alloc_membind_policy(topology, size, set,
* HWLOC_MEMBIND_DEFAULT, 0);
* \endcode
*
* This will allocate some memory hopefully bound to the specified set.
* To do so, hwloc will possibly have to change the current memory * To do so, hwloc will possibly have to change the current memory
* binding policy in order to actually get the memory bound, if the OS * binding policy in order to actually get the memory bound, if the OS
* does not provide any other way to simply allocate bound memory * does not provide any other way to simply allocate bound memory
* without changing the policy for all allocations. That is the * without changing the policy for all allocations. That is the
* difference with hwloc_alloc_membind(), which will never change the * difference with hwloc_alloc_membind(), which will never change the
* current memory binding policy. Note that since HWLOC_MEMBIND_STRICT * current memory binding policy.
* was not specified, failures to bind will not be reported -- *
* generally, only memory allocation failures will be reported (e.g., * \code
* even a plain malloc() would have failed with ENOMEM). * hwloc_alloc_membind_policy(topology, size, set,
* HWLOC_MEMBIND_BIND, 0);
* \endcode
* *
* Each hwloc memory binding function is available in two forms: one * Each hwloc memory binding function is available in two forms: one
* that takes a CPU set argument and another that takes a NUMA memory * that takes a CPU set argument and another that takes a NUMA memory
@ -1527,8 +1590,10 @@ HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, h
* possible to convert between CPU set and node set using * possible to convert between CPU set and node set using
* hwloc_cpuset_to_nodeset() or hwloc_cpuset_from_nodeset(). * hwloc_cpuset_to_nodeset() or hwloc_cpuset_from_nodeset().
* *
* \sa Some example codes are available under doc/examples/ in the source tree.
*
* \note On some operating systems, memory binding affects the CPU * \note On some operating systems, memory binding affects the CPU
* binding; see ::HWLOC_MEMBIND_NOCPUBIND * binding; see ::HWLOC_MEMBIND_NOCPUBIND
* @{ * @{
*/ */
@ -1537,12 +1602,17 @@ HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, h
* These constants can be used to choose the binding policy. Only one policy can * These constants can be used to choose the binding policy. Only one policy can
* be used at a time (i.e., the values cannot be OR'ed together). * be used at a time (i.e., the values cannot be OR'ed together).
* *
* \note Not all systems support all kinds of binding. See the * Not all systems support all kinds of binding.
* "Detailed Description" section of \ref hwlocality_membinding for a * hwloc_topology_get_support() may be used to query about the actual memory
* description of errors that can occur. * binding policy support in the currently used operating system.
* See the "Detailed Description" section of \ref hwlocality_membinding
* for a description of errors that can occur.
*/ */
typedef enum { typedef enum {
/** \brief Reset the memory allocation policy to the system default. /** \brief Reset the memory allocation policy to the system default.
* Depending on the operating system, this may correspond to
* HWLOC_MEMBIND_FIRSTTOUCH (Linux),
* or HWLOC_MEMBIND_BIND (AIX, HP-UX, OSF, Solaris, Windows).
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_DEFAULT = 0, HWLOC_MEMBIND_DEFAULT = 0,
@ -1589,33 +1659,35 @@ typedef enum {
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_NEXTTOUCH = 5, HWLOC_MEMBIND_NEXTTOUCH = 5,
/** \brief Returned by hwloc_get_membind*() functions when multiple /** \brief Returned by get_membind() functions when multiple
* threads or parts of a memory area have differing memory binding * threads or parts of a memory area have differing memory binding
* policies. * policies.
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_MIXED = -1 HWLOC_MEMBIND_MIXED = -1
} hwloc_membind_policy_t; } hwloc_membind_policy_t;
/** \brief Memory binding flags. /** \brief Memory binding flags.
* *
* These flags can be used to refine the binding policy. All flags * These flags can be used to refine the binding policy.
* can be logically OR'ed together with the exception of * All flags can be logically OR'ed together with the exception of
* HWLOC_MEMBIND_PROCESS and HWLOC_MEMBIND_THREAD; these two flags are * ::HWLOC_MEMBIND_PROCESS and ::HWLOC_MEMBIND_THREAD;
* mutually exclusive. * these two flags are mutually exclusive.
* *
* \note Not all systems support all kinds of binding. See the * Not all systems support all kinds of binding.
* "Detailed Description" section of \ref hwlocality_membinding for a * hwloc_topology_get_support() may be used to query about the actual memory
* description of errors that can occur. * binding support in the currently used operating system.
* See the "Detailed Description" section of \ref hwlocality_membinding
* for a description of errors that can occur.
*/ */
typedef enum { typedef enum {
/** \brief Set policy for all threads of the specified (possibly /** \brief Set policy for all threads of the specified (possibly
* multithreaded) process. This flag is mutually exclusive with * multithreaded) process. This flag is mutually exclusive with
* HWLOC_MEMBIND_THREAD. * ::HWLOC_MEMBIND_THREAD.
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_PROCESS = (1<<0), HWLOC_MEMBIND_PROCESS = (1<<0),
/** \brief Set policy for a specific thread of the current process. /** \brief Set policy for a specific thread of the current process.
* This flag is mutually exclusive with HWLOC_MEMBIND_PROCESS. * This flag is mutually exclusive with ::HWLOC_MEMBIND_PROCESS.
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_THREAD = (1<<1), HWLOC_MEMBIND_THREAD = (1<<1),
@ -1623,12 +1695,12 @@ typedef enum {
* the binding can not be guaranteed / completely enforced. * the binding can not be guaranteed / completely enforced.
* *
* This flag has slightly different meanings depending on which * This flag has slightly different meanings depending on which
* function it is used with. * function it is used with.
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_STRICT = (1<<2), HWLOC_MEMBIND_STRICT = (1<<2),
/** \brief Migrate existing allocated memory. If the memory cannot /** \brief Migrate existing allocated memory. If the memory cannot
* be migrated and the HWLOC_MEMBIND_STRICT flag is passed, an error * be migrated and the ::HWLOC_MEMBIND_STRICT flag is passed, an error
* will be returned. * will be returned.
* \hideinitializer */ * \hideinitializer */
HWLOC_MEMBIND_MIGRATE = (1<<3), HWLOC_MEMBIND_MIGRATE = (1<<3),
@ -1650,7 +1722,7 @@ typedef enum {
/** \brief Set the default memory binding policy of the current /** \brief Set the default memory binding policy of the current
* process or thread to prefer the NUMA node(s) specified by physical \p nodeset * process or thread to prefer the NUMA node(s) specified by physical \p nodeset
* *
* If neither HWLOC_MEMBIND_PROCESS nor HWLOC_MEMBIND_THREAD is * If neither ::HWLOC_MEMBIND_PROCESS nor ::HWLOC_MEMBIND_THREAD is
* specified, the current process is assumed to be single-threaded. * specified, the current process is assumed to be single-threaded.
* This is the most portable form as it permits hwloc to use either * This is the most portable form as it permits hwloc to use either
* process-based OS functions or thread-based OS functions, depending * process-based OS functions or thread-based OS functions, depending
@ -1665,7 +1737,7 @@ HWLOC_DECLSPEC int hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_co
* process or thread to prefer the NUMA node(s) near the specified physical \p * process or thread to prefer the NUMA node(s) near the specified physical \p
* cpuset * cpuset
* *
* If neither HWLOC_MEMBIND_PROCESS nor HWLOC_MEMBIND_THREAD is * If neither ::HWLOC_MEMBIND_PROCESS nor ::HWLOC_MEMBIND_THREAD is
* specified, the current process is assumed to be single-threaded. * specified, the current process is assumed to be single-threaded.
* This is the most portable form as it permits hwloc to use either * This is the most portable form as it permits hwloc to use either
* process-based OS functions or thread-based OS functions, depending * process-based OS functions or thread-based OS functions, depending
@ -1684,9 +1756,9 @@ HWLOC_DECLSPEC int hwloc_set_membind(hwloc_topology_t topology, hwloc_const_cpus
* passed in and the current memory binding policies and nodesets in * passed in and the current memory binding policies and nodesets in
* the queried target. * the queried target.
* *
* Passing the HWLOC_MEMBIND_PROCESS flag specifies that the query * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query
* target is the current policies and nodesets for all the threads in * target is the current policies and nodesets for all the threads in
* the current process. Passing HWLOC_MEMBIND_THREAD specifies that * the current process. Passing ::HWLOC_MEMBIND_THREAD specifies that
* the query target is the current policy and nodeset for only the * the query target is the current policy and nodeset for only the
* thread invoking this function. * thread invoking this function.
* *
@ -1695,21 +1767,21 @@ HWLOC_DECLSPEC int hwloc_set_membind(hwloc_topology_t topology, hwloc_const_cpus
* hwloc to use either process-based OS functions or thread-based OS * hwloc to use either process-based OS functions or thread-based OS
* functions, depending on which are available. * functions, depending on which are available.
* *
* HWLOC_MEMBIND_STRICT is only meaningful when HWLOC_MEMBIND_PROCESS * ::HWLOC_MEMBIND_STRICT is only meaningful when ::HWLOC_MEMBIND_PROCESS
* is also specified. In this case, hwloc will check the default * is also specified. In this case, hwloc will check the default
* memory policies and nodesets for all threads in the process. If * memory policies and nodesets for all threads in the process. If
* they are not identical, -1 is returned and errno is set to EXDEV. * they are not identical, -1 is returned and errno is set to EXDEV.
* If they are identical, the values are returned in \p nodeset and \p * If they are identical, the values are returned in \p nodeset and \p
* policy. * policy.
* *
* Otherwise, if HWLOC_MEMBIND_PROCESS is specified (and * Otherwise, if ::HWLOC_MEMBIND_PROCESS is specified (and
* HWLOC_MEMBIND_STRICT is \em not specified), \p nodeset is set to * ::HWLOC_MEMBIND_STRICT is \em not specified), \p nodeset is set to
* the logical OR of all threads' default nodeset. If all threads' * the logical OR of all threads' default nodeset. If all threads'
* default policies are the same, \p policy is set to that policy. If * default policies are the same, \p policy is set to that policy. If
* they are different, \p policy is set to HWLOC_MEMBIND_MIXED. * they are different, \p policy is set to ::HWLOC_MEMBIND_MIXED.
* *
* In the HWLOC_MEMBIND_THREAD case (or when neither * In the ::HWLOC_MEMBIND_THREAD case (or when neither
* HWLOC_MEMBIND_PROCESS or HWLOC_MEMBIND_THREAD is specified), there * ::HWLOC_MEMBIND_PROCESS or ::HWLOC_MEMBIND_THREAD is specified), there
* is only one nodeset and policy; they are returned in \p nodeset and * is only one nodeset and policy; they are returned in \p nodeset and
* \p policy, respectively. * \p policy, respectively.
* *
@ -1727,9 +1799,9 @@ HWLOC_DECLSPEC int hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_no
* passed in and the current memory binding policies and nodesets in * passed in and the current memory binding policies and nodesets in
* the queried target. * the queried target.
* *
* Passing the HWLOC_MEMBIND_PROCESS flag specifies that the query * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query
* target is the current policies and nodesets for all the threads in * target is the current policies and nodesets for all the threads in
* the current process. Passing HWLOC_MEMBIND_THREAD specifies that * the current process. Passing ::HWLOC_MEMBIND_THREAD specifies that
* the query target is the current policy and nodeset for only the * the query target is the current policy and nodeset for only the
* thread invoking this function. * thread invoking this function.
* *
@ -1738,7 +1810,7 @@ HWLOC_DECLSPEC int hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_no
* hwloc to use either process-based OS functions or thread-based OS * hwloc to use either process-based OS functions or thread-based OS
* functions, depending on which are available. * functions, depending on which are available.
* *
* HWLOC_MEMBIND_STRICT is only meaningful when HWLOC_MEMBIND_PROCESS * ::HWLOC_MEMBIND_STRICT is only meaningful when ::HWLOC_MEMBIND_PROCESS
* is also specified. In this case, hwloc will check the default * is also specified. In this case, hwloc will check the default
* memory policies and nodesets for all threads in the process. If * memory policies and nodesets for all threads in the process. If
* they are not identical, -1 is returned and errno is set to EXDEV. * they are not identical, -1 is returned and errno is set to EXDEV.
@ -1746,16 +1818,16 @@ HWLOC_DECLSPEC int hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_no
* cpuset is set to the union of CPUs near the NUMA node(s) in the * cpuset is set to the union of CPUs near the NUMA node(s) in the
* nodeset. * nodeset.
* *
* Otherwise, if HWLOC_MEMBIND_PROCESS is specified (and * Otherwise, if ::HWLOC_MEMBIND_PROCESS is specified (and
* HWLOC_MEMBIND_STRICT is \em not specified), the default nodeset * ::HWLOC_MEMBIND_STRICT is \em not specified), the default nodeset
* from each thread is logically OR'ed together. \p cpuset is set to * from each thread is logically OR'ed together. \p cpuset is set to
* the union of CPUs near the NUMA node(s) in the resulting nodeset. * the union of CPUs near the NUMA node(s) in the resulting nodeset.
* If all threads' default policies are the same, \p policy is set to * If all threads' default policies are the same, \p policy is set to
* that policy. If they are different, \p policy is set to * that policy. If they are different, \p policy is set to
* HWLOC_MEMBIND_MIXED. * ::HWLOC_MEMBIND_MIXED.
* *
* In the HWLOC_MEMBIND_THREAD case (or when neither * In the ::HWLOC_MEMBIND_THREAD case (or when neither
* HWLOC_MEMBIND_PROCESS or HWLOC_MEMBIND_THREAD is specified), there * ::HWLOC_MEMBIND_PROCESS or ::HWLOC_MEMBIND_THREAD is specified), there
* is only one nodeset and policy. The policy is returned in \p * is only one nodeset and policy. The policy is returned in \p
* policy; \p cpuset is set to the union of CPUs near the NUMA node(s) * policy; \p cpuset is set to the union of CPUs near the NUMA node(s)
* in the \p nodeset. * in the \p nodeset.
@ -1795,18 +1867,18 @@ HWLOC_DECLSPEC int hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t
* passed in and the current memory binding policies and nodesets in * passed in and the current memory binding policies and nodesets in
* the queried target. * the queried target.
* *
* Passing the HWLOC_MEMBIND_PROCESS flag specifies that the query * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query
* target is the current policies and nodesets for all the threads in * target is the current policies and nodesets for all the threads in
* the specified process. If HWLOC_MEMBIND_PROCESS is not specified * the specified process. If ::HWLOC_MEMBIND_PROCESS is not specified
* (which is the most portable method), the process is assumed to be * (which is the most portable method), the process is assumed to be
* single threaded. This allows hwloc to use either process-based OS * single threaded. This allows hwloc to use either process-based OS
* functions or thread-based OS functions, depending on which are * functions or thread-based OS functions, depending on which are
* available. * available.
* *
* Note that it does not make sense to pass HWLOC_MEMBIND_THREAD to * Note that it does not make sense to pass ::HWLOC_MEMBIND_THREAD to
* this function. * this function.
* *
* If HWLOC_MEMBIND_STRICT is specified, hwloc will check the default * If ::HWLOC_MEMBIND_STRICT is specified, hwloc will check the default
* memory policies and nodesets for all threads in the specified * memory policies and nodesets for all threads in the specified
* process. If they are not identical, -1 is returned and errno is * process. If they are not identical, -1 is returned and errno is
* set to EXDEV. If they are identical, the values are returned in \p * set to EXDEV. If they are identical, the values are returned in \p
@ -1815,7 +1887,7 @@ HWLOC_DECLSPEC int hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t
* Otherwise, \p nodeset is set to the logical OR of all threads' * Otherwise, \p nodeset is set to the logical OR of all threads'
* default nodeset. If all threads' default policies are the same, \p * default nodeset. If all threads' default policies are the same, \p
* policy is set to that policy. If they are different, \p policy is * policy is set to that policy. If they are different, \p policy is
* set to HWLOC_MEMBIND_MIXED. * set to ::HWLOC_MEMBIND_MIXED.
* *
* If any other flags are specified, -1 is returned and errno is set * If any other flags are specified, -1 is returned and errno is set
* to EINVAL. * to EINVAL.
@ -1834,18 +1906,18 @@ HWLOC_DECLSPEC int hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwl
* passed in and the current memory binding policies and nodesets in * passed in and the current memory binding policies and nodesets in
* the queried target. * the queried target.
* *
* Passing the HWLOC_MEMBIND_PROCESS flag specifies that the query * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query
* target is the current policies and nodesets for all the threads in * target is the current policies and nodesets for all the threads in
* the specified process. If HWLOC_MEMBIND_PROCESS is not specified * the specified process. If ::HWLOC_MEMBIND_PROCESS is not specified
* (which is the most portable method), the process is assumed to be * (which is the most portable method), the process is assumed to be
* single threaded. This allows hwloc to use either process-based OS * single threaded. This allows hwloc to use either process-based OS
* functions or thread-based OS functions, depending on which are * functions or thread-based OS functions, depending on which are
* available. * available.
* *
* Note that it does not make sense to pass HWLOC_MEMBIND_THREAD to * Note that it does not make sense to pass ::HWLOC_MEMBIND_THREAD to
* this function. * this function.
* *
* If HWLOC_MEMBIND_STRICT is specified, hwloc will check the default * If ::HWLOC_MEMBIND_STRICT is specified, hwloc will check the default
* memory policies and nodesets for all threads in the specified * memory policies and nodesets for all threads in the specified
* process. If they are not identical, -1 is returned and errno is * process. If they are not identical, -1 is returned and errno is
* set to EXDEV. If they are identical, the policy is returned in \p * set to EXDEV. If they are identical, the policy is returned in \p
@ -1856,7 +1928,7 @@ HWLOC_DECLSPEC int hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwl
* together. \p cpuset is set to the union of CPUs near the NUMA * together. \p cpuset is set to the union of CPUs near the NUMA
* node(s) in the resulting nodeset. If all threads' default policies * node(s) in the resulting nodeset. If all threads' default policies
* are the same, \p policy is set to that policy. If they are * are the same, \p policy is set to that policy. If they are
* different, \p policy is set to HWLOC_MEMBIND_MIXED. * different, \p policy is set to ::HWLOC_MEMBIND_MIXED.
* *
* If any other flags are specified, -1 is returned and errno is set * If any other flags are specified, -1 is returned and errno is set
* to EINVAL. * to EINVAL.
@ -1890,16 +1962,16 @@ HWLOC_DECLSPEC int hwloc_set_area_membind(hwloc_topology_t topology, const void
* passed in and the memory binding policies and nodesets of the pages * passed in and the memory binding policies and nodesets of the pages
* in the address range. * in the address range.
* *
* If HWLOC_MEMBIND_STRICT is specified, the target pages are first * If ::HWLOC_MEMBIND_STRICT is specified, the target pages are first
* checked to see if they all have the same memory binding policy and * checked to see if they all have the same memory binding policy and
* nodeset. If they do not, -1 is returned and errno is set to EXDEV. * nodeset. If they do not, -1 is returned and errno is set to EXDEV.
* If they are identical across all pages, the nodeset and policy are * If they are identical across all pages, the nodeset and policy are
* returned in \p nodeset and \p policy, respectively. * returned in \p nodeset and \p policy, respectively.
* *
* If HWLOC_MEMBIND_STRICT is not specified, \p nodeset is set to the * If ::HWLOC_MEMBIND_STRICT is not specified, \p nodeset is set to the
* union of all NUMA node(s) containing pages in the address range. * union of all NUMA node(s) containing pages in the address range.
* If all pages in the target have the same policy, it is returned in * If all pages in the target have the same policy, it is returned in
* \p policy. Otherwise, \p policy is set to HWLOC_MEMBIND_MIXED. * \p policy. Otherwise, \p policy is set to ::HWLOC_MEMBIND_MIXED.
* *
* If any other flags are specified, -1 is returned and errno is set * If any other flags are specified, -1 is returned and errno is set
* to EINVAL. * to EINVAL.
@ -1914,18 +1986,18 @@ HWLOC_DECLSPEC int hwloc_get_area_membind_nodeset(hwloc_topology_t topology, con
* passed in and the memory binding policies and nodesets of the pages * passed in and the memory binding policies and nodesets of the pages
* in the address range. * in the address range.
* *
* If HWLOC_MEMBIND_STRICT is specified, the target pages are first * If ::HWLOC_MEMBIND_STRICT is specified, the target pages are first
* checked to see if they all have the same memory binding policy and * checked to see if they all have the same memory binding policy and
* nodeset. If they do not, -1 is returned and errno is set to EXDEV. * nodeset. If they do not, -1 is returned and errno is set to EXDEV.
* If they are identical across all pages, the policy is returned in * If they are identical across all pages, the policy is returned in
* \p policy. \p cpuset is set to the union of CPUs near the NUMA * \p policy. \p cpuset is set to the union of CPUs near the NUMA
* node(s) in the nodeset. * node(s) in the nodeset.
* *
* If HWLOC_MEMBIND_STRICT is not specified, the union of all NUMA * If ::HWLOC_MEMBIND_STRICT is not specified, the union of all NUMA
* node(s) containing pages in the address range is calculated. \p * node(s) containing pages in the address range is calculated. \p
* cpuset is then set to the CPUs near the NUMA node(s) in this union. * cpuset is then set to the CPUs near the NUMA node(s) in this union.
* If all pages in the target have the same policy, it is returned in * If all pages in the target have the same policy, it is returned in
* \p policy. Otherwise, \p policy is set to HWLOC_MEMBIND_MIXED. * \p policy. Otherwise, \p policy is set to ::HWLOC_MEMBIND_MIXED.
* *
* If any other flags are specified, -1 is returned and errno is set * If any other flags are specified, -1 is returned and errno is set
* to EINVAL. * to EINVAL.
@ -1944,9 +2016,11 @@ HWLOC_DECLSPEC void *hwloc_alloc(hwloc_topology_t topology, size_t len);
/** \brief Allocate some memory on the given physical nodeset \p nodeset /** \brief Allocate some memory on the given physical nodeset \p nodeset
* *
* \return NULL with errno set to ENOSYS if the action is not supported * \return NULL with errno set to ENOSYS if the action is not supported
* and HWLOC_MEMBIND_STRICT is given * and ::HWLOC_MEMBIND_STRICT is given
* \return NULL with errno set to EXDEV if the binding cannot be enforced * \return NULL with errno set to EXDEV if the binding cannot be enforced
* and HWLOC_MEMBIND_STRICT is given * and ::HWLOC_MEMBIND_STRICT is given
* \return NULL with errno set to ENOMEM if the memory allocation failed
* even before trying to bind.
* *
* \note The allocated memory should be freed with hwloc_free(). * \note The allocated memory should be freed with hwloc_free().
*/ */
@ -1955,9 +2029,11 @@ HWLOC_DECLSPEC void *hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size
/** \brief Allocate some memory on memory nodes near the given physical cpuset \p cpuset /** \brief Allocate some memory on memory nodes near the given physical cpuset \p cpuset
* *
* \return NULL with errno set to ENOSYS if the action is not supported * \return NULL with errno set to ENOSYS if the action is not supported
* and HWLOC_MEMBIND_STRICT is given * and ::HWLOC_MEMBIND_STRICT is given
* \return NULL with errno set to EXDEV if the binding cannot be enforced * \return NULL with errno set to EXDEV if the binding cannot be enforced
* and HWLOC_MEMBIND_STRICT is given * and ::HWLOC_MEMBIND_STRICT is given
* \return NULL with errno set to ENOMEM if the memory allocation failed
* even before trying to bind.
* *
* \note The allocated memory should be freed with hwloc_free(). * \note The allocated memory should be freed with hwloc_free().
*/ */
@ -2069,15 +2145,6 @@ enum hwloc_restrict_flags_e {
*/ */
HWLOC_DECLSPEC int hwloc_topology_restrict(hwloc_topology_t __hwloc_restrict topology, hwloc_const_cpuset_t cpuset, unsigned long flags); HWLOC_DECLSPEC int hwloc_topology_restrict(hwloc_topology_t __hwloc_restrict topology, hwloc_const_cpuset_t cpuset, unsigned long flags);
/** \brief Duplicate a topology.
*
* The entire topology structure as well as its objects
* are duplicated into a new one.
*
* This is useful for keeping a backup while modifying a topology.
*/
HWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);
/** @} */ /** @} */
@ -2153,6 +2220,8 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_custom_insert_group_object_by_parent(hwloc_topo
* \note See also hwloc_topology_set_userdata_export_callback() * \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific object userdata. * for exporting application-specific object userdata.
* *
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*
* \note Only printable characters may be exported to XML string attributes. * \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently * Any other character, especially any non-ASCII character, will be silently
* dropped. * dropped.
@ -2173,6 +2242,8 @@ HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const ch
* \note See also hwloc_topology_set_userdata_export_callback() * \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific object userdata. * for exporting application-specific object userdata.
* *
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*
* \note Only printable characters may be exported to XML string attributes. * \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently * Any other character, especially any non-ASCII character, will be silently
* dropped. * dropped.
@ -2197,6 +2268,8 @@ HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuf
* something to XML (possibly multiple times per object). * something to XML (possibly multiple times per object).
* *
* \p export_cb may be set to \c NULL if userdata should not be exported to XML. * \p export_cb may be set to \c NULL if userdata should not be exported to XML.
*
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*/ */
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology, HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj)); void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
@ -2262,6 +2335,8 @@ HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topolo
* \note \p buffer contains \p length characters followed by a null byte ('\0'). * \note \p buffer contains \p length characters followed by a null byte ('\0').
* *
* \note This function should be called before hwloc_topology_load(). * \note This function should be called before hwloc_topology_load().
*
* \note The topology-specific userdata pointer is ignored when importing from XML.
*/ */
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology, HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length)); void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
@ -2269,6 +2344,54 @@ HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t
/** @} */ /** @} */
/** \defgroup hwlocality_syntheticexport Exporting Topologies to Synthetic
* @{
*/
/** \brief Flags for exporting synthetic topologies.
*
* Flags to be given as a OR'ed set to hwloc_topology_export_synthetic().
*/
enum hwloc_topology_export_synthetic_flags_e {
/** \brief Export extended types such as L2dcache as basic types such as Cache.
*
* This is required if loading the synthetic description with hwloc < 1.9.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES = (1UL<<0),
/** \brief Do not export level attributes.
*
* Ignore level attributes such as memory/cache sizes or PU indexes.
* This is required if loading the synthetic description with hwloc < 1.10.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS = (1UL<<1)
};
/** \brief Export the topology as a synthetic string.
*
* At most \p buflen characters will be written in \p buffer,
* including the terminating \0.
*
* This exported string may be given back to hwloc_topology_set_synthetic().
*
* \p flags is a OR'ed set of hwloc_topology_export_synthetic_flags_e.
*
* \return The number of characters that were written,
* not including the terminating \0.
*
* \return -1 if the topology could not be exported,
* for instance if it is not symmetric.
*
* \note A 1024-byte buffer should be large enough for exporting
* topologies in the vast majority of cases.
*/
HWLOC_DECLSPEC int hwloc_topology_export_synthetic(hwloc_topology_t topology, char *buffer, size_t buflen, unsigned long flags);
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- c -*- /* -*- c -*-
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2010 inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -133,6 +133,19 @@
# define __hwloc_attribute_deprecated # define __hwloc_attribute_deprecated
#endif #endif
#ifdef HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS
#define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS (GXX_ABOVE_3_4 || GCC_ABOVE_3_3)
#else
# define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS
# define __hwloc_attribute_may_alias __attribute__((__may_alias__))
#else
# define __hwloc_attribute_may_alias
#endif
#ifdef HWLOC_C_HAVE_VISIBILITY #ifdef HWLOC_C_HAVE_VISIBILITY
# if HWLOC_C_HAVE_VISIBILITY # if HWLOC_C_HAVE_VISIBILITY
# define HWLOC_DECLSPEC __attribute__((__visibility__("default"))) # define HWLOC_DECLSPEC __attribute__((__visibility__("default")))

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2011 inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -28,13 +28,18 @@ extern "C" {
* processors -- which may actually be hardware threads (represented * processors -- which may actually be hardware threads (represented
* by ::hwloc_cpuset_t, which is a typedef for ::hwloc_bitmap_t) -- or * by ::hwloc_cpuset_t, which is a typedef for ::hwloc_bitmap_t) -- or
* memory nodes (represented by ::hwloc_nodeset_t, which is also a * memory nodes (represented by ::hwloc_nodeset_t, which is also a
* typedef for ::hwloc_bitmap_t). * typedef for ::hwloc_bitmap_t).
* *
* <em>Both CPU and node sets are always indexed by OS physical number.</em> * <em>Both CPU and node sets are always indexed by OS physical number.</em>
* *
* \note CPU sets and nodesets are described in \ref hwlocality_object_sets. * \note CPU sets and nodesets are described in \ref hwlocality_object_sets.
* *
* A bitmap may be of infinite size. * A bitmap may be of infinite size.
*
* \note Several examples of using the bitmap API are available under the
* doc/examples/ directory in the source tree.
* Regression tests such as tests/hwloc_bitmap*.c also make intensive use
* of this API.
* @{ * @{
*/ */
@ -332,10 +337,14 @@ HWLOC_DECLSPEC int hwloc_bitmap_isequal (hwloc_const_bitmap_t bitmap1, hwloc_con
*/ */
HWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure; HWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 using their highest index. /** \brief Compare bitmaps \p bitmap1 and \p bitmap2 in lexicographic order.
* *
* Higher most significant bit is higher. * Lexicographic comparison of bitmaps, starting for their highest indexes.
* Compare last indexes first, then second, etc.
* The empty bitmap is considered lower than anything. * The empty bitmap is considered lower than anything.
*
* \note This is different from the non-existing hwloc_bitmap_compare_last()
* which would only compare the highest index of each bitmap.
*/ */
HWLOC_DECLSPEC int hwloc_bitmap_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure; HWLOC_DECLSPEC int hwloc_bitmap_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2010-2013 Inria. All rights reserved. * Copyright © 2010-2015 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux 1 * Copyright © 2010-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -49,7 +49,7 @@ hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused
{ {
CUresult cres; CUresult cres;
#ifdef CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID #if CUDA_VERSION >= 4000
cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice); cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
if (cres != CUDA_SUCCESS) { if (cres != CUDA_SUCCESS) {
errno = ENOSYS; errno = ENOSYS;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2010-2013 Inria. All rights reserved. * Copyright © 2010-2015 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux 1 * Copyright © 2010-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -23,6 +23,7 @@
#include <hwloc/linux.h> #include <hwloc/linux.h>
#endif #endif
#include <cuda.h> /* for CUDA_VERSION */
#include <cuda_runtime_api.h> #include <cuda_runtime_api.h>
@ -56,7 +57,7 @@ hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unus
return -1; return -1;
} }
#ifdef CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID #if CUDA_VERSION >= 4000
*domain = prop.pciDomainID; *domain = prop.pciDomainID;
#else #else
*domain = 0; *domain = 0;

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -21,11 +21,16 @@
extern "C" { extern "C" {
#endif #endif
/* backward compat with v1.10 before Socket->Package renaming */
#define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE
/* backward compat with v1.10 before Node->NUMANode clarification */
#define HWLOC_OBJ_NODE HWLOC_OBJ_NUMANODE
/** \brief Return an object type from the string /** \brief Return an object type from the string
* *
* \return -1 if unrecognized. * \return -1 if unrecognized.
*/ */
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_obj_type_of_string (const char * string) __hwloc_attribute_pure; HWLOC_DECLSPEC hwloc_obj_type_t hwloc_obj_type_of_string (const char * string) __hwloc_attribute_pure __hwloc_attribute_deprecated;
/** \brief Stringify a given topology object into a human-readable form. /** \brief Stringify a given topology object into a human-readable form.
* *
@ -49,7 +54,7 @@ HWLOC_DECLSPEC hwloc_obj_type_t hwloc_obj_type_of_string (const char * string) _
*/ */
HWLOC_DECLSPEC int hwloc_obj_snprintf(char * __hwloc_restrict string, size_t size, HWLOC_DECLSPEC int hwloc_obj_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_topology_t topology, hwloc_obj_t obj, hwloc_topology_t topology, hwloc_obj_t obj,
const char * __hwloc_restrict indexprefix, int verbose); const char * __hwloc_restrict indexprefix, int verbose) __hwloc_attribute_deprecated;
/** \brief Distribute \p n items over the topology under \p root /** \brief Distribute \p n items over the topology under \p root
* *
@ -67,6 +72,8 @@ HWLOC_DECLSPEC int hwloc_obj_snprintf(char * __hwloc_restrict string, size_t siz
* \note This function requires the \p root object to have a CPU set. * \note This function requires the \p root object to have a CPU set.
*/ */
static __hwloc_inline void static __hwloc_inline void
hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until) __hwloc_attribute_deprecated;
static __hwloc_inline void
hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until) hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until)
{ {
hwloc_distrib(topology, &root, 1, set, n, until, 0); hwloc_distrib(topology, &root, 1, set, n, until, 0);
@ -80,6 +87,8 @@ hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *se
* \note This function requires the \p roots objects to have a CPU set. * \note This function requires the \p roots objects to have a CPU set.
*/ */
static __hwloc_inline void static __hwloc_inline void
hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until) __hwloc_attribute_deprecated;
static __hwloc_inline void
hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until) hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until)
{ {
hwloc_distrib(topology, roots, n_roots, set, n, until, 0); hwloc_distrib(topology, roots, n_roots, set, n, until, 0);

Просмотреть файл

@ -184,7 +184,7 @@ typedef union hwloc_topology_diff_u {
* \note The output diff can only be exported to XML or passed to * \note The output diff can only be exported to XML or passed to
* hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type * hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type
* HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed. * HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.
* *
* \note The output diff may be modified by removing some entries from * \note The output diff may be modified by removing some entries from
* the list. The removed entries should be freed by passing them to * the list. The removed entries should be freed by passing them to
* to hwloc_topology_diff_destroy() (possible as another list). * to hwloc_topology_diff_destroy() (possible as another list).

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2013 inria. All rights reserved. * Copyright © 2009-2013 inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -350,7 +350,7 @@ hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_cons
* Be sure to see the figure in \ref termsanddefs that shows a * Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin * complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one * relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers. * package has fewer caches than its peers.
*/ */
/** \brief Returns the ancestor object of \p obj at depth \p depth. */ /** \brief Returns the ancestor object of \p obj at depth \p depth. */
@ -538,16 +538,17 @@ hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute
* Be sure to see the figure in \ref termsanddefs that shows a * Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin * complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one * relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers. * package has fewer caches than its peers.
*/ */
/** \brief Returns the object of type ::HWLOC_OBJ_PU with \p os_index. /** \brief Returns the object of type ::HWLOC_OBJ_PU with \p os_index.
* *
* \note The \p os_index field of object should most of the times only be * This function is useful for converting a CPU set into the PU
* used for pretty-printing purpose. Type ::HWLOC_OBJ_PU is the only case * objects it contains.
* where \p os_index could actually be useful, when manually binding to * When retrieving the current binding (e.g. with hwloc_get_cpubind()),
* processors. * one may iterate over the bits of the resulting CPU set with
* However, using CPU sets to hide this complexity should often be preferred. * hwloc_bitmap_foreach_begin(), and find the corresponding PUs
* with this function.
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure; hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
@ -561,6 +562,27 @@ hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
return NULL; return NULL;
} }
/** \brief Returns the object of type ::HWLOC_OBJ_NUMANODE with \p os_index.
*
* This function is useful for converting a nodeset into the NUMA node
* objects it contains.
* When retrieving the current binding (e.g. with hwloc_get_membind_nodeset()),
* one may iterate over the bits of the resulting nodeset with
* hwloc_bitmap_foreach_begin(), and find the corresponding NUMA nodes
* with this function.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
{
hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)
if (obj->os_index == os_index)
return obj;
return NULL;
}
/** \brief Do a depth-first traversal of the topology to find and sort /** \brief Do a depth-first traversal of the topology to find and sort
* *
* all objects that are at the same depth than \p src. * all objects that are at the same depth than \p src.
@ -582,8 +604,8 @@ HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc
* object of type \p type2 and logical index \p idx2. Indexes are specified * object of type \p type2 and logical index \p idx2. Indexes are specified
* within the parent, not withing the entire system. * within the parent, not withing the entire system.
* *
* For instance, if type1 is SOCKET, idx1 is 2, type2 is CORE and idx2 * For instance, if type1 is PACKAGE, idx1 is 2, type2 is CORE and idx2
* is 3, return the fourth core object below the third socket. * is 3, return the fourth core object below the third package.
* *
* \note This function requires these objects to have a CPU set. * \note This function requires these objects to have a CPU set.
*/ */
@ -614,9 +636,9 @@ hwloc_get_obj_below_by_type (hwloc_topology_t topology,
* object to find the index-th object of the given type. * object to find the index-th object of the given type.
* Indexes are specified within the parent, not withing the entire system. * Indexes are specified within the parent, not withing the entire system.
* *
* For instance, if nr is 3, typev contains NODE, SOCKET and CORE, * For instance, if nr is 3, typev contains NODE, PACKAGE and CORE,
* and idxv contains 0, 1 and 2, return the third core object below * and idxv contains 0, 1 and 2, return the third core object below
* the second socket below the first NUMA node. * the second package below the first NUMA node.
* *
* \note This function requires all these objects and the root object * \note This function requires all these objects and the root object
* to have a CPU set. * to have a CPU set.
@ -685,6 +707,7 @@ hwloc_distrib(hwloc_topology_t topology,
{ {
unsigned i; unsigned i;
unsigned tot_weight; unsigned tot_weight;
unsigned given, givenweight;
hwloc_cpuset_t *cpusetp = set; hwloc_cpuset_t *cpusetp = set;
if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) { if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
@ -697,23 +720,41 @@ hwloc_distrib(hwloc_topology_t topology,
if (roots[i]->cpuset) if (roots[i]->cpuset)
tot_weight += hwloc_bitmap_weight(roots[i]->cpuset); tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
for (i = 0; i < n_roots && tot_weight; i++) { for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {
/* Give to roots[] a portion proportional to its weight */ unsigned chunk, weight;
hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i]; hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
unsigned weight = root->cpuset ? hwloc_bitmap_weight(root->cpuset) : 0; hwloc_cpuset_t cpuset = root->cpuset;
unsigned chunk = (n * weight + tot_weight-1) / tot_weight; if (!cpuset)
if (!root->arity || chunk == 1 || root->depth >= until) { continue;
/* Got to the bottom, we can't split any more, put everything there. */ weight = hwloc_bitmap_weight(cpuset);
unsigned j; if (!weight)
for (j=0; j<n; j++) continue;
cpusetp[j] = hwloc_bitmap_dup(root->cpuset); /* Give to root a chunk proportional to its weight.
* If previous chunks got rounded-up, we may get a bit less. */
chunk = (( (givenweight+weight) * n + tot_weight-1) / tot_weight)
- (( givenweight * n + tot_weight-1) / tot_weight);
if (!root->arity || chunk <= 1 || root->depth >= until) {
/* We can't split any more, put everything there. */
if (chunk) {
/* Fill cpusets with ours */
unsigned j;
for (j=0; j < chunk; j++)
cpusetp[j] = hwloc_bitmap_dup(cpuset);
} else {
/* We got no chunk, just merge our cpuset to a previous one
* (the first chunk cannot be empty)
* so that this root doesn't get ignored.
*/
assert(given);
hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
}
} else { } else {
/* Still more to distribute, recurse into children */ /* Still more to distribute, recurse into children */
hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags); hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
} }
cpusetp += chunk; cpusetp += chunk;
tot_weight -= weight; given += chunk;
n -= chunk; givenweight += weight;
} }
return 0; return 0;
@ -880,7 +921,7 @@ hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
static __hwloc_inline void static __hwloc_inline void
hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj; hwloc_obj_t obj;
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) { if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
@ -908,7 +949,7 @@ hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset,
static __hwloc_inline void static __hwloc_inline void
hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj; hwloc_obj_t obj;
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
return; return;
@ -929,7 +970,7 @@ hwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpus
static __hwloc_inline void static __hwloc_inline void
hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj; hwloc_obj_t obj;
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) { if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {
@ -960,7 +1001,7 @@ hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwl
static __hwloc_inline void static __hwloc_inline void
hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj; hwloc_obj_t obj;
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN )
return; return;

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved. * Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1 * Copyright © 2009-2010, 2012 Université Bordeaux
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -27,7 +27,7 @@ extern "C" {
/** \defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks /** \defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks
* *
* This interface helps converting between Linux libnuma unsigned long masks * This interface helps converting between Linux libnuma unsigned long masks
* and hwloc cpusets and nodesets. * and hwloc cpusets and nodesets.
* *
* It also offers a consistent behavior on non-NUMA machines * It also offers a consistent behavior on non-NUMA machines
* or non-NUMA-aware kernels by assuming that the machines have a single * or non-NUMA-aware kernels by assuming that the machines have a single
@ -58,7 +58,7 @@ static __hwloc_inline int
hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
unsigned long *mask, unsigned long *maxnode) unsigned long *mask, unsigned long *maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1; unsigned long outmaxnode = -1;
/* round-up to the next ulong and clear all bytes */ /* round-up to the next ulong and clear all bytes */
@ -101,7 +101,7 @@ static __hwloc_inline int
hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
unsigned long *mask, unsigned long *maxnode) unsigned long *mask, unsigned long *maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1; unsigned long outmaxnode = -1;
/* round-up to the next ulong and clear all bytes */ /* round-up to the next ulong and clear all bytes */
@ -145,7 +145,7 @@ static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const unsigned long *mask, unsigned long maxnode) const unsigned long *mask, unsigned long maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) { if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;
@ -178,7 +178,7 @@ static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const unsigned long *mask, unsigned long maxnode) const unsigned long *mask, unsigned long maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) { if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;
@ -205,7 +205,7 @@ hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset
/** \defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask /** \defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask
* *
* This interface helps converting between Linux libnuma bitmasks * This interface helps converting between Linux libnuma bitmasks
* and hwloc cpusets and nodesets. * and hwloc cpusets and nodesets.
* *
* It also offers a consistent behavior on non-NUMA machines * It also offers a consistent behavior on non-NUMA machines
* or non-NUMA-aware kernels by assuming that the machines have a single * or non-NUMA-aware kernels by assuming that the machines have a single
@ -236,7 +236,7 @@ hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpu
static __hwloc_inline struct bitmask * static __hwloc_inline struct bitmask *
hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
struct bitmask *bitmask = numa_allocate_cpumask(); struct bitmask *bitmask = numa_allocate_cpumask();
if (!bitmask) if (!bitmask)
return NULL; return NULL;
@ -269,7 +269,7 @@ hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_no
static __hwloc_inline struct bitmask * static __hwloc_inline struct bitmask *
hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
struct bitmask *bitmask = numa_allocate_cpumask(); struct bitmask *bitmask = numa_allocate_cpumask();
if (!bitmask) if (!bitmask)
return NULL; return NULL;
@ -297,7 +297,7 @@ static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const struct bitmask *bitmask) const struct bitmask *bitmask)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) { if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;
@ -325,7 +325,7 @@ static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const struct bitmask *bitmask) const struct bitmask *bitmask)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) { if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved. * Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2010-2013 Inria. All rights reserved. * Copyright © 2010-2014 Inria. All rights reserved.
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -65,7 +65,7 @@ hwloc_mx_board_get_device_cpuset(hwloc_topology_t topology,
if (out != (uint32_t) -1) { if (out != (uint32_t) -1) {
hwloc_obj_t obj = NULL; hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, obj)) != NULL) while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)
if (obj->os_index == out) { if (obj->os_index == out) {
hwloc_bitmap_copy(set, obj->cpuset); hwloc_bitmap_copy(set, obj->cpuset);
goto out; goto out;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2012-2013 Inria. All rights reserved. * Copyright © 2012-2013 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux 1. All right reserved. * Copyright © 2013 Université Bordeaux. All right reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved. * Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1 * Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2013-2014 Inria. All rights reserved. * Copyright © 2013-2015 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -216,6 +216,38 @@ struct hwloc_component {
/** \brief Component ABI version, set to HWLOC_COMPONENT_ABI */ /** \brief Component ABI version, set to HWLOC_COMPONENT_ABI */
unsigned abi; unsigned abi;
/** \brief Process-wide component initialization callback.
*
* This optional callback is called when the component is registered
* to the hwloc core (after loading the plugin).
*
* When the component is built as a plugin, this callback
* should call hwloc_check_plugin_namespace()
* and return an negative error code on error.
*
* \p flags is always 0 for now.
*
* \return 0 on success, or a negative code on error.
*
* \note If the component uses ltdl for loading its own plugins,
* it should load/unload them only in init() and finalize(),
* to avoid race conditions with hwloc's use of ltdl.
*/
int (*init)(unsigned long flags);
/** \brief Process-wide component termination callback.
*
* This optional callback is called after unregistering the component
* from the hwloc core (before unloading the plugin).
*
* \p flags is always 0 for now.
*
* \note If the component uses ltdl for loading its own plugins,
* it should load/unload them only in init() and finalize(),
* to avoid race conditions with hwloc's use of ltdl.
*/
void (*finalize)(unsigned long flags);
/** \brief Component type */ /** \brief Component type */
hwloc_component_type_t type; hwloc_component_type_t type;
@ -276,6 +308,10 @@ HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_top
* The cpuset is completely ignored, so strange objects such as I/O devices should * The cpuset is completely ignored, so strange objects such as I/O devices should
* preferably be inserted with this. * preferably be inserted with this.
* *
* When used for "normal" children with cpusets (when importing from XML
* when duplicating a topology), the caller should make sure children are inserted
* in order.
*
* The given object may have children. * The given object may have children.
* *
* Remember to call topology_connect() afterwards to fix handy pointers. * Remember to call topology_connect() afterwards to fix handy pointers.
@ -312,12 +348,19 @@ HWLOC_DECLSPEC int hwloc_fill_object_sets(hwloc_obj_t obj);
* This may fail (and abort the program) if libhwloc symbols are in a * This may fail (and abort the program) if libhwloc symbols are in a
* private namespace. * private namespace.
* *
* Plugins should call this function as an early sanity check to avoid * \return 0 on success.
* \return -1 if the plugin cannot be successfully loaded. The caller
* plugin init() callback should return a negative error code as well.
*
* Plugins should call this function in their init() callback to avoid
* later crashes if lazy symbol resolution is used by the upper layer that * later crashes if lazy symbol resolution is used by the upper layer that
* loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY). * loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
* *
* \note The build system must define HWLOC_INSIDE_PLUGIN if and only if * \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
* building the caller as a plugin. * building the caller as a plugin.
*
* \note This function should remain inline so plugins can call it even
* when they cannot find libhwloc symbols.
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused) hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
@ -335,7 +378,7 @@ hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, co
static int verboseenv_checked = 0; static int verboseenv_checked = 0;
static int verboseenv_value = 0; static int verboseenv_value = 0;
if (!verboseenv_checked) { if (!verboseenv_checked) {
char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE"); const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
verboseenv_value = atoi(verboseenv); verboseenv_value = atoi(verboseenv);
verboseenv_checked = 1; verboseenv_checked = 1;
} }

Просмотреть файл

@ -49,8 +49,8 @@ extern "C" {
#define HWLOC_OBJ_SYSTEM HWLOC_NAME_CAPS(OBJ_SYSTEM) #define HWLOC_OBJ_SYSTEM HWLOC_NAME_CAPS(OBJ_SYSTEM)
#define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE) #define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE)
#define HWLOC_OBJ_NODE HWLOC_NAME_CAPS(OBJ_NODE) #define HWLOC_OBJ_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE)
#define HWLOC_OBJ_SOCKET HWLOC_NAME_CAPS(OBJ_SOCKET) #define HWLOC_OBJ_PACKAGE HWLOC_NAME_CAPS(OBJ_PACKAGE)
#define HWLOC_OBJ_CACHE HWLOC_NAME_CAPS(OBJ_CACHE) #define HWLOC_OBJ_CACHE HWLOC_NAME_CAPS(OBJ_CACHE)
#define HWLOC_OBJ_CORE HWLOC_NAME_CAPS(OBJ_CORE) #define HWLOC_OBJ_CORE HWLOC_NAME_CAPS(OBJ_CORE)
#define HWLOC_OBJ_PU HWLOC_NAME_CAPS(OBJ_PU) #define HWLOC_OBJ_PU HWLOC_NAME_CAPS(OBJ_PU)
@ -106,6 +106,7 @@ extern "C" {
#define hwloc_topology_init HWLOC_NAME(topology_init) #define hwloc_topology_init HWLOC_NAME(topology_init)
#define hwloc_topology_load HWLOC_NAME(topology_load) #define hwloc_topology_load HWLOC_NAME(topology_load)
#define hwloc_topology_destroy HWLOC_NAME(topology_destroy) #define hwloc_topology_destroy HWLOC_NAME(topology_destroy)
#define hwloc_topology_dup HWLOC_NAME(topology_dup)
#define hwloc_topology_check HWLOC_NAME(topology_check) #define hwloc_topology_check HWLOC_NAME(topology_check)
#define hwloc_topology_ignore_type HWLOC_NAME(topology_ignore_type) #define hwloc_topology_ignore_type HWLOC_NAME(topology_ignore_type)
#define hwloc_topology_ignore_type_keep_structure HWLOC_NAME(topology_ignore_type_keep_structure) #define hwloc_topology_ignore_type_keep_structure HWLOC_NAME(topology_ignore_type_keep_structure)
@ -134,6 +135,9 @@ extern "C" {
#define hwloc_topology_membind_support HWLOC_NAME(topology_membind_support) #define hwloc_topology_membind_support HWLOC_NAME(topology_membind_support)
#define hwloc_topology_support HWLOC_NAME(topology_support) #define hwloc_topology_support HWLOC_NAME(topology_support)
#define hwloc_topology_get_support HWLOC_NAME(topology_get_support) #define hwloc_topology_get_support HWLOC_NAME(topology_get_support)
#define hwloc_topology_set_userdata HWLOC_NAME(topology_set_userdata)
#define hwloc_topology_get_userdata HWLOC_NAME(topology_get_userdata)
#define hwloc_topology_export_xml HWLOC_NAME(topology_export_xml) #define hwloc_topology_export_xml HWLOC_NAME(topology_export_xml)
#define hwloc_topology_export_xmlbuffer HWLOC_NAME(topology_export_xmlbuffer) #define hwloc_topology_export_xmlbuffer HWLOC_NAME(topology_export_xmlbuffer)
#define hwloc_free_xmlbuffer HWLOC_NAME(free_xmlbuffer) #define hwloc_free_xmlbuffer HWLOC_NAME(free_xmlbuffer)
@ -142,6 +146,11 @@ extern "C" {
#define hwloc_export_obj_userdata_base64 HWLOC_NAME(export_obj_userdata_base64) #define hwloc_export_obj_userdata_base64 HWLOC_NAME(export_obj_userdata_base64)
#define hwloc_topology_set_userdata_import_callback HWLOC_NAME(topology_set_userdata_import_callback) #define hwloc_topology_set_userdata_import_callback HWLOC_NAME(topology_set_userdata_import_callback)
#define hwloc_topology_export_synthetic_flags_e HWLOC_NAME(topology_export_synthetic_flags_e)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)
#define hwloc_topology_export_synthetic HWLOC_NAME(topology_export_synthetic)
#define hwloc_topology_insert_misc_object_by_cpuset HWLOC_NAME(topology_insert_misc_object_by_cpuset) #define hwloc_topology_insert_misc_object_by_cpuset HWLOC_NAME(topology_insert_misc_object_by_cpuset)
#define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent) #define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent)
@ -153,7 +162,6 @@ extern "C" {
#define HWLOC_RESTRICT_FLAG_ADAPT_MISC HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_MISC) #define HWLOC_RESTRICT_FLAG_ADAPT_MISC HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_MISC)
#define HWLOC_RESTRICT_FLAG_ADAPT_IO HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_IO) #define HWLOC_RESTRICT_FLAG_ADAPT_IO HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_IO)
#define hwloc_topology_restrict HWLOC_NAME(topology_restrict) #define hwloc_topology_restrict HWLOC_NAME(topology_restrict)
#define hwloc_topology_dup HWLOC_NAME(topology_dup)
#define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth) #define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth)
#define hwloc_get_type_depth HWLOC_NAME(get_type_depth) #define hwloc_get_type_depth HWLOC_NAME(get_type_depth)
@ -307,6 +315,7 @@ extern "C" {
#define hwloc_get_next_obj_by_depth HWLOC_NAME(get_next_obj_by_depth) #define hwloc_get_next_obj_by_depth HWLOC_NAME(get_next_obj_by_depth)
#define hwloc_get_next_obj_by_type HWLOC_NAME(get_next_obj_by_type) #define hwloc_get_next_obj_by_type HWLOC_NAME(get_next_obj_by_type)
#define hwloc_get_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index) #define hwloc_get_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index)
#define hwloc_get_numanode_obj_by_os_index HWLOC_NAME(get_numanode_obj_by_os_index)
#define hwloc_get_next_child HWLOC_NAME(get_next_child) #define hwloc_get_next_child HWLOC_NAME(get_next_child)
#define hwloc_get_common_ancestor_obj HWLOC_NAME(get_common_ancestor_obj) #define hwloc_get_common_ancestor_obj HWLOC_NAME(get_common_ancestor_obj)
#define hwloc_obj_is_in_subtree HWLOC_NAME(obj_is_in_subtree) #define hwloc_obj_is_in_subtree HWLOC_NAME(obj_is_in_subtree)
@ -570,6 +579,8 @@ extern "C" {
#define hwloc_connect_children HWLOC_NAME(connect_children) #define hwloc_connect_children HWLOC_NAME(connect_children)
#define hwloc_connect_levels HWLOC_NAME(connect_levels) #define hwloc_connect_levels HWLOC_NAME(connect_levels)
#define hwloc__object_cpusets_compare_first HWLOC_NAME(_object_cpusets_compare_first)
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults) #define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
#define hwloc_topology_clear HWLOC_NAME(topology_clear) #define hwloc_topology_clear HWLOC_NAME(topology_clear)
@ -620,6 +631,10 @@ extern "C" {
#define hwloc_obj_add_info_nodup HWLOC_NAME(obj_add_info_nodup) #define hwloc_obj_add_info_nodup HWLOC_NAME(obj_add_info_nodup)
#define hwloc_progname HWLOC_NAME(progname)
#define hwloc_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)
/* private/solaris-chiptype.h */ /* private/solaris-chiptype.h */
#define hwloc_solaris_get_chip_type HWLOC_NAME(solaris_get_chip_type) #define hwloc_solaris_get_chip_type HWLOC_NAME(solaris_get_chip_type)

Просмотреть файл

@ -2,12 +2,12 @@
/* -*- c -*- /* -*- c -*-
* *
* Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux 1 All rights reserved. * Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux All rights reserved.
* Copyright © 2009 Cisco Systems, Inc. All rights reserved. * Copyright © 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
* *
* $HEADER$ * $HEADER$
* *
* This file is automatically generated by configure. Edits will be lost * This file is automatically generated by configure. Edits will be lost
@ -39,6 +39,9 @@
/* Define to 1 if you have the `cpuset_setid' function. */ /* Define to 1 if you have the `cpuset_setid' function. */
#undef HAVE_CPUSET_SETID #undef HAVE_CPUSET_SETID
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if we have -lcuda */ /* Define to 1 if we have -lcuda */
#undef HAVE_CUDA #undef HAVE_CUDA
@ -60,6 +63,18 @@
*/ */
#undef HAVE_DECL_FABSF #undef HAVE_DECL_FABSF
/* Define to 1 if you have the declaration of `getexecname', and to 0 if you
don't. */
#undef HAVE_DECL_GETEXECNAME
/* Define to 1 if you have the declaration of `GetModuleFileName', and to 0 if
you don't. */
#undef HAVE_DECL_GETMODULEFILENAME
/* Define to 1 if you have the declaration of `getprogname', and to 0 if you
don't. */
#undef HAVE_DECL_GETPROGNAME
/* Define to 1 if you have the declaration of `HW_NCPU', and to 0 if you /* Define to 1 if you have the declaration of `HW_NCPU', and to 0 if you
don't. */ don't. */
#undef HAVE_DECL_HW_NCPU #undef HAVE_DECL_HW_NCPU
@ -68,10 +83,6 @@
`nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */ `nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */
#undef HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION #undef HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION
/* Define to 1 if you have the declaration of `PCI_LOOKUP_NO_NUMBERS', and to
0 if you don't. */
#undef HAVE_DECL_PCI_LOOKUP_NO_NUMBERS
/* Define to 1 if you have the declaration of `pthread_getaffinity_np', and to /* Define to 1 if you have the declaration of `pthread_getaffinity_np', and to
0 if you don't. */ 0 if you don't. */
#undef HAVE_DECL_PTHREAD_GETAFFINITY_NP #undef HAVE_DECL_PTHREAD_GETAFFINITY_NP
@ -169,8 +180,8 @@
/* Define to 1 if we have -llgrp */ /* Define to 1 if we have -llgrp */
#undef HAVE_LIBLGRP #undef HAVE_LIBLGRP
/* Define to 1 if you have the `pci' library (-lpci). */ /* Define to 1 if you have the <libudev.h> header file. */
#undef HAVE_LIBPCI #undef HAVE_LIBUDEV_H
/* Define to 1 if you have the <locale.h> header file. */ /* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H #undef HAVE_LOCALE_H
@ -217,9 +228,6 @@
/* Define to 1 if you have the `openat' function. */ /* Define to 1 if you have the `openat' function. */
#undef HAVE_OPENAT #undef HAVE_OPENAT
/* Define to 1 if you have the <pci/pci.h> header file. */
#undef HAVE_PCI_PCI_H
/* Define to 1 if you have the <picl.h> header file. */ /* Define to 1 if you have the <picl.h> header file. */
#undef HAVE_PICL_H #undef HAVE_PICL_H
@ -235,6 +243,9 @@
/* Define to 1 if the system has the type `PROCESSOR_RELATIONSHIP'. */ /* Define to 1 if the system has the type `PROCESSOR_RELATIONSHIP'. */
#undef HAVE_PROCESSOR_RELATIONSHIP #undef HAVE_PROCESSOR_RELATIONSHIP
/* Define to '1' if program_invocation_name is present and usable */
#undef HAVE_PROGRAM_INVOCATION_NAME
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_BLOCK'. */ /* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_BLOCK'. */
#undef HAVE_PSAPI_WORKING_SET_EX_BLOCK #undef HAVE_PSAPI_WORKING_SET_EX_BLOCK
@ -337,6 +348,9 @@
/* Define to 1 if you have the <xlocale.h> header file. */ /* Define to 1 if you have the <xlocale.h> header file. */
#undef HAVE_XLOCALE_H #undef HAVE_XLOCALE_H
/* Define to '1' if __progname is present and usable */
#undef HAVE___PROGNAME
/* Define to 1 on AIX */ /* Define to 1 on AIX */
#undef HWLOC_AIX_SYS #undef HWLOC_AIX_SYS
@ -469,9 +483,6 @@
/* Define to 1 if you have the GL module components. */ /* Define to 1 if you have the GL module components. */
#undef HWLOC_HAVE_GL #undef HWLOC_HAVE_GL
/* Define to 1 if you have the `libpciaccess' library. */
#undef HWLOC_HAVE_LIBPCIACCESS
/* Define to 1 if you have a library providing the termcap interface */ /* Define to 1 if you have a library providing the termcap interface */
#undef HWLOC_HAVE_LIBTERMCAP #undef HWLOC_HAVE_LIBTERMCAP
@ -497,18 +508,6 @@
/* Define to 1 if you have the `OpenCL' library. */ /* Define to 1 if you have the `OpenCL' library. */
#undef HWLOC_HAVE_OPENCL #undef HWLOC_HAVE_OPENCL
/* Define to 1 if `libpci' struct pci_dev has a `device_class' field. */
#undef HWLOC_HAVE_PCIDEV_DEVICE_CLASS
/* Define to 1 if `libpci' struct pci_dev has a `domain' field. */
#undef HWLOC_HAVE_PCIDEV_DOMAIN
/* Define to 1 if you have the pciutils `libpci' library. */
#undef HWLOC_HAVE_PCIUTILS
/* Define to 1 if `libpci' has the `pci_find_cap' function. */
#undef HWLOC_HAVE_PCI_FIND_CAP
/* Define to 1 if the hwloc library should support dynamically-loaded plugins /* Define to 1 if the hwloc library should support dynamically-loaded plugins
*/ */
#undef HWLOC_HAVE_PLUGINS #undef HWLOC_HAVE_PLUGINS
@ -579,6 +578,10 @@
/* Define to 1 if ncurses works, preferred over curses */ /* Define to 1 if ncurses works, preferred over curses */
#undef HWLOC_USE_NCURSES #undef HWLOC_USE_NCURSES
/* The library version, always available, even in embedded mode, contrary to
VERSION */
#undef HWLOC_VERSION
/* Define to 1 on WINDOWS */ /* Define to 1 on WINDOWS */
#undef HWLOC_WIN_SYS #undef HWLOC_WIN_SYS
@ -588,8 +591,7 @@
/* Define to 1 on x86_64 */ /* Define to 1 on x86_64 */
#undef HWLOC_X86_64_ARCH #undef HWLOC_X86_64_ARCH
/* Define to the sub-directory in which libtool stores uninstalled libraries. /* Define to the sub-directory where libtool stores uninstalled libraries. */
*/
#undef LT_OBJDIR #undef LT_OBJDIR
/* Name of package */ /* Name of package */

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2010-2012 Université Bordeaux 1 * Copyright © 2010-2012, 2014 Université Bordeaux
* Copyright © 2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2010 Cisco Systems, Inc. All rights reserved.
* Copyright © 2014 Inria. All rights reserved. * Copyright © 2014 Inria. All rights reserved.
* *

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009, 2011 Université Bordeaux 1 * Copyright © 2009, 2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -13,7 +13,6 @@
#include <hwloc/autogen/config.h> #include <hwloc/autogen/config.h>
#include <private/autogen/config.h> #include <private/autogen/config.h>
#include <ctype.h>
#ifdef HWLOC_HAVE_DECL_STRNCASECMP #ifdef HWLOC_HAVE_DECL_STRNCASECMP
#ifdef HAVE_STRINGS_H #ifdef HAVE_STRINGS_H

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* *
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -58,6 +58,7 @@ struct hwloc_topology {
int is_thissystem; int is_thissystem;
int is_loaded; int is_loaded;
hwloc_pid_t pid; /* Process ID the topology is view from, 0 for self */ hwloc_pid_t pid; /* Process ID the topology is view from, 0 for self */
void *userdata;
unsigned bridge_nbobjects; unsigned bridge_nbobjects;
struct hwloc_obj **bridge_level; struct hwloc_obj **bridge_level;
@ -136,6 +137,8 @@ extern unsigned hwloc_fallback_nbprocessors(struct hwloc_topology *topology);
extern void hwloc_connect_children(hwloc_obj_t obj); extern void hwloc_connect_children(hwloc_obj_t obj);
extern int hwloc_connect_levels(hwloc_topology_t topology); extern int hwloc_connect_levels(hwloc_topology_t topology);
extern int hwloc__object_cpusets_compare_first(hwloc_obj_t obj1, hwloc_obj_t obj2);
extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology); extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology);
extern void hwloc_topology_clear(struct hwloc_topology *topology); extern void hwloc_topology_clear(struct hwloc_topology *topology);
@ -299,10 +302,29 @@ extern int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n
# define __hwloc_attribute_format(type, str, arg) # define __hwloc_attribute_format(type, str, arg)
#endif #endif
#define hwloc_memory_size_printf_value(_size, _verbose) \
((_size) < (10ULL<<20) || _verbose ? (((_size)>>9)+1)>>1 : (_size) < (10ULL<<30) ? (((_size)>>19)+1)>>1 : (_size) < (10ULL<<40) ? (((_size)>>29)+1)>>1 : (((_size)>>39)+1)>>1)
#define hwloc_memory_size_printf_unit(_size, _verbose) \
((_size) < (10ULL<<20) || _verbose ? "KB" : (_size) < (10ULL<<30) ? "MB" : (_size) < (10ULL<<40) ? "GB" : "TB")
/* On some systems, snprintf returns the size of written data, not the actually /* On some systems, snprintf returns the size of written data, not the actually
* required size. hwloc_snprintf always report the actually required size. */ * required size. hwloc_snprintf always report the actually required size. */
extern int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4); extern int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4);
extern void hwloc_obj_add_info_nodup(hwloc_obj_t obj, const char *name, const char *value, int nodup); extern void hwloc_obj_add_info_nodup(hwloc_obj_t obj, const char *name, const char *value, int nodup);
/* Return the name of the currently running program, if supported.
* If not NULL, must be freed by the caller.
*/
extern char * hwloc_progname(struct hwloc_topology *topology);
#define HWLOC_BITMAP_EQUAL 0 /* Bitmaps are equal */
#define HWLOC_BITMAP_INCLUDED 1 /* First bitmap included in second */
#define HWLOC_BITMAP_CONTAINS 2 /* First bitmap contains second */
#define HWLOC_BITMAP_INTERSECTS 3 /* Bitmaps intersect without any inclusion */
#define HWLOC_BITMAP_DIFFERENT 4 /* Bitmaps do not intersect */
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 from an inclusion point of view.
*/
HWLOC_DECLSPEC int hwloc_bitmap_compare_inclusion(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
#endif /* HWLOC_PRIVATE_H */ #endif /* HWLOC_PRIVATE_H */

Просмотреть файл

@ -1,10 +1,10 @@
/* /*
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved. * Copyright © 2009-2010 Oracle and/or its affiliates. All rights reserved.
* *
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
* *
* $HEADER$ * $HEADER$
*/ */

Просмотреть файл

@ -12,15 +12,15 @@
HWLOC_DECLSPEC int hwloc__xml_verbose(void); HWLOC_DECLSPEC int hwloc__xml_verbose(void);
/**************
* XML import *
**************/
typedef struct hwloc__xml_import_state_s { typedef struct hwloc__xml_import_state_s {
struct hwloc__xml_import_state_s *parent; struct hwloc__xml_import_state_s *parent;
int (*next_attr)(struct hwloc__xml_import_state_s * state, char **namep, char **valuep); /* globals shared because the entire stack of states during import */
int (*find_child)(struct hwloc__xml_import_state_s * state, struct hwloc__xml_import_state_s * childstate, char **tagp); struct hwloc_xml_backend_data_s *global;
int (*close_tag)(struct hwloc__xml_import_state_s * state); /* look for an explicit closing tag </name> */
void (*close_child)(struct hwloc__xml_import_state_s * state);
int (*get_content)(struct hwloc__xml_import_state_s * state, char **beginp, size_t expected_length);
void (*close_content)(struct hwloc__xml_import_state_s * state);
/* opaque data used to store backend-specific data. /* opaque data used to store backend-specific data.
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs. * statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
@ -35,6 +35,13 @@ struct hwloc_xml_backend_data_s {
int (*look_init)(struct hwloc_xml_backend_data_s *bdata, struct hwloc__xml_import_state_s *state); int (*look_init)(struct hwloc_xml_backend_data_s *bdata, struct hwloc__xml_import_state_s *state);
void (*look_failed)(struct hwloc_xml_backend_data_s *bdata); void (*look_failed)(struct hwloc_xml_backend_data_s *bdata);
void (*backend_exit)(struct hwloc_xml_backend_data_s *bdata); void (*backend_exit)(struct hwloc_xml_backend_data_s *bdata);
int (*next_attr)(struct hwloc__xml_import_state_s * state, char **namep, char **valuep);
int (*find_child)(struct hwloc__xml_import_state_s * state, struct hwloc__xml_import_state_s * childstate, char **tagp);
int (*close_tag)(struct hwloc__xml_import_state_s * state); /* look for an explicit closing tag </name> */
void (*close_child)(struct hwloc__xml_import_state_s * state);
int (*get_content)(struct hwloc__xml_import_state_s * state, char **beginp, size_t expected_length);
void (*close_content)(struct hwloc__xml_import_state_s * state);
char * msgprefix;
void *data; /* libxml2 doc, or nolibxml buffer */ void *data; /* libxml2 doc, or nolibxml buffer */
struct hwloc_xml_imported_distances_s { struct hwloc_xml_imported_distances_s {
hwloc_obj_t root; hwloc_obj_t root;
@ -43,6 +50,10 @@ struct hwloc_xml_backend_data_s {
} *first_distances, *last_distances; } *first_distances, *last_distances;
}; };
/**************
* XML export *
**************/
typedef struct hwloc__xml_export_state_s { typedef struct hwloc__xml_export_state_s {
struct hwloc__xml_export_state_s *parent; struct hwloc__xml_export_state_s *parent;
@ -70,7 +81,7 @@ struct hwloc_xml_callbacks {
int (*export_file)(struct hwloc_topology *topology, const char *filename); int (*export_file)(struct hwloc_topology *topology, const char *filename);
int (*export_buffer)(struct hwloc_topology *topology, char **xmlbuffer, int *buflen); int (*export_buffer)(struct hwloc_topology *topology, char **xmlbuffer, int *buflen);
void (*free_buffer)(void *xmlbuffer); void (*free_buffer)(void *xmlbuffer);
int (*import_diff)(const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *diff, char **refnamep); int (*import_diff)(struct hwloc__xml_import_state_s *state, const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *diff, char **refnamep);
int (*export_diff_file)(union hwloc_topology_diff_u *diff, const char *refname, const char *filename); int (*export_diff_file)(union hwloc_topology_diff_u *diff, const char *refname, const char *filename);
int (*export_diff_buffer)(union hwloc_topology_diff_u *diff, const char *refname, char **xmlbuffer, int *buflen); int (*export_diff_buffer)(union hwloc_topology_diff_u *diff, const char *refname, char **xmlbuffer, int *buflen);
}; };

Просмотреть файл

@ -1,6 +1,6 @@
# Copyright © 2009-2014 Inria. All rights reserved. # Copyright © 2009-2014 Inria. All rights reserved.
# Copyright © 2009-2012 Université Bordeaux 1 # Copyright © 2009-2012 Université Bordeaux
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# Copyright © 2011-2012 Oracle and/or its affiliates. All rights reserved. # Copyright © 2011-2012 Oracle and/or its affiliates. All rights reserved.
# See COPYING in top-level directory. # See COPYING in top-level directory.
@ -20,7 +20,7 @@ noinst_LTLIBRARIES = libhwloc_embedded.la
endif endif
pluginsdir = @HWLOC_PLUGINS_DIR@ pluginsdir = @HWLOC_PLUGINS_DIR@
plugins_LTLIBRARIES = plugins_LTLIBRARIES =
plugins_ldflags = -module -avoid-version -lltdl plugins_ldflags = -module -avoid-version -lltdl
AM_CPPFLAGS += -DHWLOC_PLUGINS_PATH=\"$(HWLOC_PLUGINS_PATH)\" AM_CPPFLAGS += -DHWLOC_PLUGINS_PATH=\"$(HWLOC_PLUGINS_PATH)\"
@ -63,8 +63,8 @@ sources += topology-pci.c
else else
plugins_LTLIBRARIES += hwloc_pci.la plugins_LTLIBRARIES += hwloc_pci.la
hwloc_pci_la_SOURCES = topology-pci.c hwloc_pci_la_SOURCES = topology-pci.c
hwloc_pci_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_PCIUTILS_CFLAGS) $(HWLOC_PCIACCESS_CFLAGS) -DHWLOC_INSIDE_PLUGIN hwloc_pci_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_PCIACCESS_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_pci_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_PCIUTILS_LIBS) $(HWLOC_PCIACCESS_LIBS) hwloc_pci_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_PCIACCESS_LIBS)
endif endif
endif HWLOC_HAVE_PCI endif HWLOC_HAVE_PCI

Просмотреть файл

@ -106,9 +106,9 @@ static const char Pad64 = '=';
end of the data is performed using the '=' character. end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the Since all base64 input is an integral number of octets, only the
------------------------------------------------- -------------------------------------------------
following cases can arise: following cases can arise:
(1) the final quantum of encoding input is an integral (1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters output will be an integral multiple of 4 characters
@ -153,14 +153,14 @@ hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t t
target[datalength++] = Base64[output[2]]; target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]]; target[datalength++] = Base64[output[3]];
} }
/* Now we worry about padding. */ /* Now we worry about padding. */
if (0 != srclength) { if (0 != srclength) {
/* Get what's left. */ /* Get what's left. */
input[0] = input[1] = input[2] = '\0'; input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++) for (i = 0; i < srclength; i++)
input[i] = *src++; input[i] = *src++;
output[0] = input[0] >> 2; output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2011 inria. All rights reserved. * Copyright © 2009-2011 inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1 * Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2015 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -244,12 +244,20 @@ int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, const stru
res = size>0 ? size - 1 : 0; res = size>0 ? size - 1 : 0;
tmp += res; tmp += res;
size -= res; size -= res;
/* optimize a common case: full bitmap should appear as 0xf...f instead of 0xf...f,0xffffffff */
if (set->ulongs_count == 1 && set->ulongs[0] == HWLOC_SUBBITMAP_FULL)
return ret;
} }
i=set->ulongs_count-1; i=set->ulongs_count-1;
if (set->infinite) {
/* ignore starting FULL since we have 0xf...f already */
while (i>=0 && set->ulongs[i] == HWLOC_SUBBITMAP_FULL)
i--;
} else {
/* ignore starting ZERO except the last one */
while (i>=0 && set->ulongs[i] == HWLOC_SUBBITMAP_ZERO)
i--;
}
while (i>=0 || accumed) { while (i>=0 || accumed) {
/* Refill accumulator */ /* Refill accumulator */
if (!accumed) { if (!accumed) {
@ -289,6 +297,14 @@ int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, const stru
size -= res; size -= res;
} }
/* if didn't display anything, display 0x0 */
if (!ret) {
res = hwloc_snprintf(tmp, size, "0x0");
if (res < 0)
return -1;
ret += res;
}
return ret; return ret;
} }
@ -513,12 +529,20 @@ int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, co
res = size>0 ? size - 1 : 0; res = size>0 ? size - 1 : 0;
tmp += res; tmp += res;
size -= res; size -= res;
/* optimize a common case: full bitmap should appear as 0xf...f instead of 0xf...fffffffff */
if (set->ulongs_count == 1 && set->ulongs[0] == HWLOC_SUBBITMAP_FULL)
return ret;
} }
i=set->ulongs_count-1; i=set->ulongs_count-1;
if (set->infinite) {
/* ignore starting FULL since we have 0xf...f already */
while (i>=0 && set->ulongs[i] == HWLOC_SUBBITMAP_FULL)
i--;
} else {
/* ignore starting ZERO except the last one */
while (i>=1 && set->ulongs[i] == HWLOC_SUBBITMAP_ZERO)
i--;
}
while (i>=0) { while (i>=0) {
unsigned long val = set->ulongs[i--]; unsigned long val = set->ulongs[i--];
if (started) { if (started) {
@ -543,6 +567,14 @@ int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, co
size -= res; size -= res;
} }
/* if didn't display anything, display 0x0 */
if (!ret) {
res = hwloc_snprintf(tmp, size, "0x0");
if (res < 0)
return -1;
ret += res;
}
return ret; return ret;
} }
@ -864,15 +896,31 @@ int hwloc_bitmap_isfull(const struct hwloc_bitmap_s *set)
int hwloc_bitmap_isequal (const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2) int hwloc_bitmap_isequal (const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2)
{ {
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned min_count = count1 < count2 ? count1 : count2;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
for(i=0; i<set1->ulongs_count || i<set2->ulongs_count; i++) for(i=0; i<min_count; i++)
if (HWLOC_SUBBITMAP_READULONG(set1, i) != HWLOC_SUBBITMAP_READULONG(set2, i)) if (set1->ulongs[i] != set2->ulongs[i])
return 0; return 0;
if (count1 != count2) {
unsigned long w1 = set1->infinite ? HWLOC_SUBBITMAP_FULL : HWLOC_SUBBITMAP_ZERO;
unsigned long w2 = set2->infinite ? HWLOC_SUBBITMAP_FULL : HWLOC_SUBBITMAP_ZERO;
for(i=min_count; i<count1; i++) {
if (set1->ulongs[i] != w2)
return 0;
}
for(i=min_count; i<count2; i++) {
if (set2->ulongs[i] != w1)
return 0;
}
}
if (set1->infinite != set2->infinite) if (set1->infinite != set2->infinite)
return 0; return 0;
@ -881,32 +929,62 @@ int hwloc_bitmap_isequal (const struct hwloc_bitmap_s *set1, const struct hwloc_
int hwloc_bitmap_intersects (const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2) int hwloc_bitmap_intersects (const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2)
{ {
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned min_count = count1 < count2 ? count1 : count2;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
for(i=0; i<set1->ulongs_count || i<set2->ulongs_count; i++) for(i=0; i<min_count; i++)
if ((HWLOC_SUBBITMAP_READULONG(set1, i) & HWLOC_SUBBITMAP_READULONG(set2, i)) != HWLOC_SUBBITMAP_ZERO) if (set1->ulongs[i] & set2->ulongs[i])
return 1; return 1;
if (count1 != count2) {
if (set2->infinite) {
for(i=min_count; i<set1->ulongs_count; i++)
if (set1->ulongs[i])
return 1;
}
if (set1->infinite) {
for(i=min_count; i<set2->ulongs_count; i++)
if (set2->ulongs[i])
return 1;
}
}
if (set1->infinite && set2->infinite) if (set1->infinite && set2->infinite)
return 0; return 1;
return 0; return 0;
} }
int hwloc_bitmap_isincluded (const struct hwloc_bitmap_s *sub_set, const struct hwloc_bitmap_s *super_set) int hwloc_bitmap_isincluded (const struct hwloc_bitmap_s *sub_set, const struct hwloc_bitmap_s *super_set)
{ {
unsigned super_count = super_set->ulongs_count;
unsigned sub_count = sub_set->ulongs_count;
unsigned min_count = super_count < sub_count ? super_count : sub_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(sub_set); HWLOC__BITMAP_CHECK(sub_set);
HWLOC__BITMAP_CHECK(super_set); HWLOC__BITMAP_CHECK(super_set);
for(i=0; i<sub_set->ulongs_count || i<super_set->ulongs_count; i++) for(i=0; i<min_count; i++)
if (HWLOC_SUBBITMAP_READULONG(super_set, i) != (HWLOC_SUBBITMAP_READULONG(super_set, i) | HWLOC_SUBBITMAP_READULONG(sub_set, i))) if (super_set->ulongs[i] != (super_set->ulongs[i] | sub_set->ulongs[i]))
return 0; return 0;
if (super_count != sub_count) {
if (!super_set->infinite)
for(i=min_count; i<sub_count; i++)
if (sub_set->ulongs[i])
return 0;
if (sub_set->infinite)
for(i=min_count; i<super_count; i++)
if (super_set->ulongs[i] != HWLOC_SUBBITMAP_FULL)
return 0;
}
if (sub_set->infinite && !super_set->infinite) if (sub_set->infinite && !super_set->infinite)
return 0; return 0;
@ -915,83 +993,166 @@ int hwloc_bitmap_isincluded (const struct hwloc_bitmap_s *sub_set, const struct
void hwloc_bitmap_or (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2) void hwloc_bitmap_or (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2)
{ {
const struct hwloc_bitmap_s *largest = set1->ulongs_count > set2->ulongs_count ? set1 : set2; /* cache counts so that we can reset res even if it's also set1 or set2 */
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned max_count = count1 > count2 ? count1 : count2;
unsigned min_count = count1 + count2 - max_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(res); HWLOC__BITMAP_CHECK(res);
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
hwloc_bitmap_realloc_by_ulongs(res, largest->ulongs_count); /* cannot reset since the output may also be an input */ hwloc_bitmap_reset_by_ulongs(res, max_count);
for(i=0; i<res->ulongs_count; i++) for(i=0; i<min_count; i++)
res->ulongs[i] = HWLOC_SUBBITMAP_READULONG(set1, i) | HWLOC_SUBBITMAP_READULONG(set2, i); res->ulongs[i] = set1->ulongs[i] | set2->ulongs[i];
if (count1 != count2) {
if (min_count < count1) {
if (set2->infinite) {
res->ulongs_count = min_count;
} else {
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set1->ulongs[i];
}
} else {
if (set1->infinite) {
res->ulongs_count = min_count;
} else {
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set2->ulongs[i];
}
}
}
res->infinite = set1->infinite || set2->infinite; res->infinite = set1->infinite || set2->infinite;
} }
void hwloc_bitmap_and (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2) void hwloc_bitmap_and (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2)
{ {
const struct hwloc_bitmap_s *largest = set1->ulongs_count > set2->ulongs_count ? set1 : set2; /* cache counts so that we can reset res even if it's also set1 or set2 */
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned max_count = count1 > count2 ? count1 : count2;
unsigned min_count = count1 + count2 - max_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(res); HWLOC__BITMAP_CHECK(res);
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
hwloc_bitmap_realloc_by_ulongs(res, largest->ulongs_count); /* cannot reset since the output may also be an input */ hwloc_bitmap_reset_by_ulongs(res, max_count);
for(i=0; i<res->ulongs_count; i++) for(i=0; i<min_count; i++)
res->ulongs[i] = HWLOC_SUBBITMAP_READULONG(set1, i) & HWLOC_SUBBITMAP_READULONG(set2, i); res->ulongs[i] = set1->ulongs[i] & set2->ulongs[i];
if (count1 != count2) {
if (min_count < count1) {
if (set2->infinite) {
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set1->ulongs[i];
} else {
res->ulongs_count = min_count;
}
} else {
if (set1->infinite) {
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set2->ulongs[i];
} else {
res->ulongs_count = min_count;
}
}
}
res->infinite = set1->infinite && set2->infinite; res->infinite = set1->infinite && set2->infinite;
} }
void hwloc_bitmap_andnot (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2) void hwloc_bitmap_andnot (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2)
{ {
const struct hwloc_bitmap_s *largest = set1->ulongs_count > set2->ulongs_count ? set1 : set2; /* cache counts so that we can reset res even if it's also set1 or set2 */
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned max_count = count1 > count2 ? count1 : count2;
unsigned min_count = count1 + count2 - max_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(res); HWLOC__BITMAP_CHECK(res);
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
hwloc_bitmap_realloc_by_ulongs(res, largest->ulongs_count); /* cannot reset since the output may also be an input */ hwloc_bitmap_reset_by_ulongs(res, max_count);
for(i=0; i<res->ulongs_count; i++) for(i=0; i<min_count; i++)
res->ulongs[i] = HWLOC_SUBBITMAP_READULONG(set1, i) & ~HWLOC_SUBBITMAP_READULONG(set2, i); res->ulongs[i] = set1->ulongs[i] & ~set2->ulongs[i];
if (count1 != count2) {
if (min_count < count1) {
if (!set2->infinite) {
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set1->ulongs[i];
} else {
res->ulongs_count = min_count;
}
} else {
if (set1->infinite) {
for(i=min_count; i<max_count; i++)
res->ulongs[i] = ~set2->ulongs[i];
} else {
res->ulongs_count = min_count;
}
}
}
res->infinite = set1->infinite && !set2->infinite; res->infinite = set1->infinite && !set2->infinite;
} }
void hwloc_bitmap_xor (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2) void hwloc_bitmap_xor (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set1, const struct hwloc_bitmap_s *set2)
{ {
const struct hwloc_bitmap_s *largest = set1->ulongs_count > set2->ulongs_count ? set1 : set2; /* cache counts so that we can reset res even if it's also set1 or set2 */
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned max_count = count1 > count2 ? count1 : count2;
unsigned min_count = count1 + count2 - max_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(res); HWLOC__BITMAP_CHECK(res);
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
hwloc_bitmap_realloc_by_ulongs(res, largest->ulongs_count); /* cannot reset since the output may also be an input */ hwloc_bitmap_reset_by_ulongs(res, max_count);
for(i=0; i<res->ulongs_count; i++) for(i=0; i<min_count; i++)
res->ulongs[i] = HWLOC_SUBBITMAP_READULONG(set1, i) ^ HWLOC_SUBBITMAP_READULONG(set2, i); res->ulongs[i] = set1->ulongs[i] ^ set2->ulongs[i];
if (count1 != count2) {
if (min_count < count1) {
unsigned long w2 = set2->infinite ? HWLOC_SUBBITMAP_FULL : HWLOC_SUBBITMAP_ZERO;
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set1->ulongs[i] ^ w2;
} else {
unsigned long w1 = set1->infinite ? HWLOC_SUBBITMAP_FULL : HWLOC_SUBBITMAP_ZERO;
for(i=min_count; i<max_count; i++)
res->ulongs[i] = set2->ulongs[i] ^ w1;
}
}
res->infinite = (!set1->infinite) != (!set2->infinite); res->infinite = (!set1->infinite) != (!set2->infinite);
} }
void hwloc_bitmap_not (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set) void hwloc_bitmap_not (struct hwloc_bitmap_s *res, const struct hwloc_bitmap_s *set)
{ {
unsigned count = set->ulongs_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(res); HWLOC__BITMAP_CHECK(res);
HWLOC__BITMAP_CHECK(set); HWLOC__BITMAP_CHECK(set);
hwloc_bitmap_realloc_by_ulongs(res, set->ulongs_count); /* cannot reset since the output may also be an input */ hwloc_bitmap_reset_by_ulongs(res, count);
for(i=0; i<res->ulongs_count; i++) for(i=0; i<count; i++)
res->ulongs[i] = ~HWLOC_SUBBITMAP_READULONG(set, i); res->ulongs[i] = ~set->ulongs[i];
res->infinite = !set->infinite; res->infinite = !set->infinite;
} }
@ -1102,14 +1263,18 @@ void hwloc_bitmap_singlify(struct hwloc_bitmap_s * set)
int hwloc_bitmap_compare_first(const struct hwloc_bitmap_s * set1, const struct hwloc_bitmap_s * set2) int hwloc_bitmap_compare_first(const struct hwloc_bitmap_s * set1, const struct hwloc_bitmap_s * set2)
{ {
unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned max_count = count1 > count2 ? count1 : count2;
unsigned min_count = count1 + count2 - max_count;
unsigned i; unsigned i;
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2); HWLOC__BITMAP_CHECK(set2);
for(i=0; i<set1->ulongs_count || i<set2->ulongs_count; i++) { for(i=0; i<min_count; i++) {
unsigned long w1 = HWLOC_SUBBITMAP_READULONG(set1, i); unsigned long w1 = set1->ulongs[i];
unsigned long w2 = HWLOC_SUBBITMAP_READULONG(set2, i); unsigned long w2 = set2->ulongs[i];
if (w1 || w2) { if (w1 || w2) {
int _ffs1 = hwloc_ffsl(w1); int _ffs1 = hwloc_ffsl(w1);
int _ffs2 = hwloc_ffsl(w2); int _ffs2 = hwloc_ffsl(w2);
@ -1120,14 +1285,36 @@ int hwloc_bitmap_compare_first(const struct hwloc_bitmap_s * set1, const struct
return _ffs2-_ffs1; return _ffs2-_ffs1;
} }
} }
if ((!set1->infinite) != (!set2->infinite))
return !!set1->infinite - !!set2->infinite; if (count1 != count2) {
return 0; if (min_count < count2) {
for(i=min_count; i<count2; i++) {
unsigned long w2 = set2->ulongs[i];
if (set1->infinite)
return -!(w2 & 1);
else if (w2)
return 1;
}
} else {
for(i=min_count; i<count1; i++) {
unsigned long w1 = set1->ulongs[i];
if (set2->infinite)
return !(w1 & 1);
else if (w1)
return -1;
}
}
}
return !!set1->infinite - !!set2->infinite;
} }
int hwloc_bitmap_compare(const struct hwloc_bitmap_s * set1, const struct hwloc_bitmap_s * set2) int hwloc_bitmap_compare(const struct hwloc_bitmap_s * set1, const struct hwloc_bitmap_s * set2)
{ {
const struct hwloc_bitmap_s *largest = set1->ulongs_count > set2->ulongs_count ? set1 : set2; unsigned count1 = set1->ulongs_count;
unsigned count2 = set2->ulongs_count;
unsigned max_count = count1 > count2 ? count1 : count2;
unsigned min_count = count1 + count2 - max_count;
int i; int i;
HWLOC__BITMAP_CHECK(set1); HWLOC__BITMAP_CHECK(set1);
@ -1136,9 +1323,29 @@ int hwloc_bitmap_compare(const struct hwloc_bitmap_s * set1, const struct hwloc_
if ((!set1->infinite) != (!set2->infinite)) if ((!set1->infinite) != (!set2->infinite))
return !!set1->infinite - !!set2->infinite; return !!set1->infinite - !!set2->infinite;
for(i=largest->ulongs_count-1; i>=0; i--) { if (count1 != count2) {
unsigned long val1 = HWLOC_SUBBITMAP_READULONG(set1, (unsigned) i); if (min_count < count2) {
unsigned long val2 = HWLOC_SUBBITMAP_READULONG(set2, (unsigned) i); unsigned long val1 = set1->infinite ? HWLOC_SUBBITMAP_FULL : HWLOC_SUBBITMAP_ZERO;
for(i=max_count-1; i>=(signed) min_count; i--) {
unsigned long val2 = set2->ulongs[i];
if (val1 == val2)
continue;
return val1 < val2 ? -1 : 1;
}
} else {
unsigned long val2 = set2->infinite ? HWLOC_SUBBITMAP_FULL : HWLOC_SUBBITMAP_ZERO;
for(i=max_count-1; i>=(signed) min_count; i--) {
unsigned long val1 = set1->ulongs[i];
if (val1 == val2)
continue;
return val1 < val2 ? -1 : 1;
}
}
}
for(i=min_count-1; i>=0; i--) {
unsigned long val1 = set1->ulongs[i];
unsigned long val2 = set2->ulongs[i];
if (val1 == val2) if (val1 == val2)
continue; continue;
return val1 < val2 ? -1 : 1; return val1 < val2 ? -1 : 1;
@ -1161,3 +1368,118 @@ int hwloc_bitmap_weight(const struct hwloc_bitmap_s * set)
weight += hwloc_weight_long(set->ulongs[i]); weight += hwloc_weight_long(set->ulongs[i]);
return weight; return weight;
} }
int hwloc_bitmap_compare_inclusion(const struct hwloc_bitmap_s * set1, const struct hwloc_bitmap_s * set2)
{
unsigned max_count = set1->ulongs_count > set2->ulongs_count ? set1->ulongs_count : set2->ulongs_count;
int result = HWLOC_BITMAP_EQUAL; /* means empty sets return equal */
int empty1 = 1;
int empty2 = 1;
unsigned i;
HWLOC__BITMAP_CHECK(set1);
HWLOC__BITMAP_CHECK(set2);
for(i=0; i<max_count; i++) {
unsigned long val1 = HWLOC_SUBBITMAP_READULONG(set1, (unsigned) i);
unsigned long val2 = HWLOC_SUBBITMAP_READULONG(set2, (unsigned) i);
if (!val1) {
if (!val2)
/* both empty, no change */
continue;
/* val1 empty, val2 not */
if (result == HWLOC_BITMAP_CONTAINS) {
if (!empty2)
return HWLOC_BITMAP_INTERSECTS;
result = HWLOC_BITMAP_DIFFERENT;
} else if (result == HWLOC_BITMAP_EQUAL) {
result = HWLOC_BITMAP_INCLUDED;
}
/* no change otherwise */
} else if (!val2) {
/* val2 empty, val1 not */
if (result == HWLOC_BITMAP_INCLUDED) {
if (!empty1)
return HWLOC_BITMAP_INTERSECTS;
result = HWLOC_BITMAP_DIFFERENT;
} else if (result == HWLOC_BITMAP_EQUAL) {
result = HWLOC_BITMAP_CONTAINS;
}
/* no change otherwise */
} else if (val1 == val2) {
/* equal and not empty */
if (result == HWLOC_BITMAP_DIFFERENT)
return HWLOC_BITMAP_INTERSECTS;
/* equal/contains/included unchanged */
} else if ((val1 & val2) == val1) {
/* included and not empty */
if (result == HWLOC_BITMAP_CONTAINS || result == HWLOC_BITMAP_DIFFERENT)
return HWLOC_BITMAP_INTERSECTS;
/* equal/included unchanged */
result = HWLOC_BITMAP_INCLUDED;
} else if ((val1 & val2) == val2) {
/* contains and not empty */
if (result == HWLOC_BITMAP_INCLUDED || result == HWLOC_BITMAP_DIFFERENT)
return HWLOC_BITMAP_INTERSECTS;
/* equal/contains unchanged */
result = HWLOC_BITMAP_CONTAINS;
} else if ((val1 & val2) != 0) {
/* intersects and not empty */
return HWLOC_BITMAP_INTERSECTS;
} else {
/* different and not empty */
/* equal/included/contains with non-empty sets means intersects */
if (result == HWLOC_BITMAP_EQUAL && !empty1 /* implies !empty2 */)
return HWLOC_BITMAP_INTERSECTS;
if (result == HWLOC_BITMAP_INCLUDED && !empty1)
return HWLOC_BITMAP_INTERSECTS;
if (result == HWLOC_BITMAP_CONTAINS && !empty2)
return HWLOC_BITMAP_INTERSECTS;
/* otherwise means different */
result = HWLOC_BITMAP_DIFFERENT;
}
empty1 &= !val1;
empty2 &= !val2;
}
if (!set1->infinite) {
if (set2->infinite) {
/* set2 infinite only */
if (result == HWLOC_BITMAP_CONTAINS) {
if (!empty2)
return HWLOC_BITMAP_INTERSECTS;
result = HWLOC_BITMAP_DIFFERENT;
} else if (result == HWLOC_BITMAP_EQUAL) {
result = HWLOC_BITMAP_INCLUDED;
}
/* no change otherwise */
}
} else if (!set2->infinite) {
/* set1 infinite only */
if (result == HWLOC_BITMAP_INCLUDED) {
if (!empty1)
return HWLOC_BITMAP_INTERSECTS;
result = HWLOC_BITMAP_DIFFERENT;
} else if (result == HWLOC_BITMAP_EQUAL) {
result = HWLOC_BITMAP_CONTAINS;
}
/* no change otherwise */
} else {
/* both infinite */
if (result == HWLOC_BITMAP_DIFFERENT)
return HWLOC_BITMAP_INTERSECTS;
/* equal/contains/included unchanged */
}
return result;
}

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2012 Université Bordeau 1 * Copyright © 2012 Université Bordeau 1
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -26,6 +26,12 @@ static int hwloc_components_verbose = 0;
static int hwloc_plugins_verbose = 0; static int hwloc_plugins_verbose = 0;
#endif #endif
/* hwloc_components_mutex serializes:
* - loading/unloading plugins, and modifications of the hwloc_plugins list
* - calls to ltdl, including in hwloc_check_plugin_namespace()
* - registration of components with hwloc_disc_component_register()
* and hwloc_xml_callbacks_register()
*/
#ifdef HWLOC_WIN_SYS #ifdef HWLOC_WIN_SYS
/* Basic mutex on top of InterlockedCompareExchange() on windows, /* Basic mutex on top of InterlockedCompareExchange() on windows,
* Far from perfect, but easy to maintain, and way enough given that this code will never be needed for real. */ * Far from perfect, but easy to maintain, and way enough given that this code will never be needed for real. */
@ -183,9 +189,9 @@ hwloc_plugins_exit(void)
static int static int
hwloc_plugins_init(void) hwloc_plugins_init(void)
{ {
char *verboseenv; const char *verboseenv;
char *path = HWLOC_PLUGINS_PATH; char *path = HWLOC_PLUGINS_PATH;
char *env; const char *env;
int err; int err;
verboseenv = getenv("HWLOC_PLUGINS_VERBOSE"); verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
@ -297,13 +303,16 @@ hwloc_disc_component_register(struct hwloc_disc_component *component,
#include <static-components.h> #include <static-components.h>
static void (**hwloc_component_finalize_cbs)(unsigned long);
static unsigned hwloc_component_finalize_cb_count;
void void
hwloc_components_init(struct hwloc_topology *topology __hwloc_attribute_unused) hwloc_components_init(struct hwloc_topology *topology __hwloc_attribute_unused)
{ {
#ifdef HWLOC_HAVE_PLUGINS #ifdef HWLOC_HAVE_PLUGINS
struct hwloc__plugin_desc *desc; struct hwloc__plugin_desc *desc;
#endif #endif
char *verboseenv; const char *verboseenv;
unsigned i; unsigned i;
HWLOC_COMPONENTS_LOCK(); HWLOC_COMPONENTS_LOCK();
@ -320,6 +329,23 @@ hwloc_components_init(struct hwloc_topology *topology __hwloc_attribute_unused)
hwloc_plugins_init(); hwloc_plugins_init();
#endif #endif
hwloc_component_finalize_cbs = NULL;
hwloc_component_finalize_cb_count = 0;
/* count the max number of finalize callbacks */
for(i=0; NULL != hwloc_static_components[i]; i++)
hwloc_component_finalize_cb_count++;
#ifdef HWLOC_HAVE_PLUGINS
for(desc = hwloc_plugins; NULL != desc; desc = desc->next)
hwloc_component_finalize_cb_count++;
#endif
if (hwloc_component_finalize_cb_count) {
hwloc_component_finalize_cbs = calloc(hwloc_component_finalize_cb_count,
sizeof(*hwloc_component_finalize_cbs));
assert(hwloc_component_finalize_cbs);
/* forget that max number and recompute the real one below */
hwloc_component_finalize_cb_count = 0;
}
/* hwloc_static_components is created by configure in static-components.h */ /* hwloc_static_components is created by configure in static-components.h */
for(i=0; NULL != hwloc_static_components[i]; i++) { for(i=0; NULL != hwloc_static_components[i]; i++) {
if (hwloc_static_components[i]->flags) { if (hwloc_static_components[i]->flags) {
@ -327,6 +353,18 @@ hwloc_components_init(struct hwloc_topology *topology __hwloc_attribute_unused)
hwloc_static_components[i]->flags); hwloc_static_components[i]->flags);
continue; continue;
} }
/* initialize the component */
if (hwloc_static_components[i]->init && hwloc_static_components[i]->init(0) < 0) {
if (hwloc_components_verbose)
fprintf(stderr, "Ignoring static component, failed to initialize\n");
continue;
}
/* queue ->finalize() callback if any */
if (hwloc_static_components[i]->finalize)
hwloc_component_finalize_cbs[hwloc_component_finalize_cb_count++] = hwloc_static_components[i]->finalize;
/* register for real now */
if (HWLOC_COMPONENT_TYPE_DISC == hwloc_static_components[i]->type) if (HWLOC_COMPONENT_TYPE_DISC == hwloc_static_components[i]->type)
hwloc_disc_component_register(hwloc_static_components[i]->data, NULL); hwloc_disc_component_register(hwloc_static_components[i]->data, NULL);
else if (HWLOC_COMPONENT_TYPE_XML == hwloc_static_components[i]->type) else if (HWLOC_COMPONENT_TYPE_XML == hwloc_static_components[i]->type)
@ -343,6 +381,18 @@ hwloc_components_init(struct hwloc_topology *topology __hwloc_attribute_unused)
desc->name, desc->component->flags); desc->name, desc->component->flags);
continue; continue;
} }
/* initialize the component */
if (desc->component->init && desc->component->init(0) < 0) {
if (hwloc_components_verbose)
fprintf(stderr, "Ignoring plugin `%s', failed to initialize\n", desc->name);
continue;
}
/* queue ->finalize() callback if any */
if (desc->component->finalize)
hwloc_component_finalize_cbs[hwloc_component_finalize_cb_count++] = desc->component->finalize;
/* register for real now */
if (HWLOC_COMPONENT_TYPE_DISC == desc->component->type) if (HWLOC_COMPONENT_TYPE_DISC == desc->component->type)
hwloc_disc_component_register(desc->component->data, desc->filename); hwloc_disc_component_register(desc->component->data, desc->filename);
else if (HWLOC_COMPONENT_TYPE_XML == desc->component->type) else if (HWLOC_COMPONENT_TYPE_XML == desc->component->type)
@ -445,9 +495,11 @@ hwloc_disc_components_enable_others(struct hwloc_topology *topology)
struct hwloc_backend *backend; struct hwloc_backend *backend;
unsigned excludes = 0; unsigned excludes = 0;
int tryall = 1; int tryall = 1;
char *env; const char *_env;
char *env; /* we'll to modify the env value, so duplicate it */
env = getenv("HWLOC_COMPONENTS"); _env = getenv("HWLOC_COMPONENTS");
env = _env ? strdup(_env) : NULL;
/* compute current excludes */ /* compute current excludes */
backend = topology->backends; backend = topology->backends;
@ -465,7 +517,7 @@ hwloc_disc_components_enable_others(struct hwloc_topology *topology)
s = strcspn(curenv, HWLOC_COMPONENT_SEPS); s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
if (s) { if (s) {
char *arg; char *arg;
char c; char c, d;
/* replace libpci with pci for backward compatibility with v1.6 */ /* replace libpci with pci for backward compatibility with v1.6 */
if (!strncmp(curenv, "libpci", s)) { if (!strncmp(curenv, "libpci", s)) {
@ -495,19 +547,21 @@ hwloc_disc_components_enable_others(struct hwloc_topology *topology)
arg = strchr(curenv, '='); arg = strchr(curenv, '=');
if (arg) { if (arg) {
d = *arg;
*arg = '\0'; *arg = '\0';
arg++;
} }
comp = hwloc_disc_component_find(-1, curenv); comp = hwloc_disc_component_find(-1, curenv);
if (comp) { if (comp) {
hwloc_disc_component_try_enable(topology, comp, arg, &excludes, 1 /* envvar forced */, 1 /* envvar forced need warnings */); hwloc_disc_component_try_enable(topology, comp, arg ? arg+1 : NULL, &excludes, 1 /* envvar forced */, 1 /* envvar forced need warnings */);
} else { } else {
fprintf(stderr, "Cannot find discovery component `%s'\n", curenv); fprintf(stderr, "Cannot find discovery component `%s'\n", curenv);
} }
/* restore last char (the second loop below needs env to be unmodified) */ /* restore chars (the second loop below needs env to be unmodified) */
curenv[s] = c; curenv[s] = c;
if (arg)
*arg = d;
} }
nextname: nextname:
@ -559,11 +613,16 @@ nextcomp:
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
if (env)
free(env);
} }
void void
hwloc_components_destroy_all(struct hwloc_topology *topology __hwloc_attribute_unused) hwloc_components_destroy_all(struct hwloc_topology *topology __hwloc_attribute_unused)
{ {
unsigned i;
HWLOC_COMPONENTS_LOCK(); HWLOC_COMPONENTS_LOCK();
assert(0 != hwloc_components_users); assert(0 != hwloc_components_users);
if (0 != --hwloc_components_users) { if (0 != --hwloc_components_users) {
@ -571,6 +630,12 @@ hwloc_components_destroy_all(struct hwloc_topology *topology __hwloc_attribute_u
return; return;
} }
for(i=0; i<hwloc_component_finalize_cb_count; i++)
hwloc_component_finalize_cbs[hwloc_component_finalize_cb_count-i-1](0);
free(hwloc_component_finalize_cbs);
hwloc_component_finalize_cbs = NULL;
hwloc_component_finalize_cb_count = 0;
/* no need to unlink/free the list of components, they'll be unloaded below */ /* no need to unlink/free the list of components, they'll be unloaded below */
hwloc_disc_components = NULL; hwloc_disc_components = NULL;
@ -658,7 +723,7 @@ void
hwloc_backends_is_thissystem(struct hwloc_topology *topology) hwloc_backends_is_thissystem(struct hwloc_topology *topology)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
char *local_env; const char *local_env;
/* Apply is_thissystem topology flag before we enforce envvar backends. /* Apply is_thissystem topology flag before we enforce envvar backends.
* If the application changed the backend with set_foo(), * If the application changed the backend with set_foo(),

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2013 Inria. All rights reserved. * Copyright © 2013-2014 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -98,7 +98,7 @@ static int hwloc_append_diff_obj_attr_string(hwloc_obj_t obj,
static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj, static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type, hwloc_topology_diff_obj_attr_type_t type,
hwloc_uint64_t index, hwloc_uint64_t idx,
hwloc_uint64_t oldvalue, hwloc_uint64_t oldvalue,
hwloc_uint64_t newvalue, hwloc_uint64_t newvalue,
hwloc_topology_diff_t *firstdiffp, hwloc_topology_diff_t *firstdiffp,
@ -118,7 +118,7 @@ static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj,
newdiff->obj_attr.obj_depth = obj->depth; newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index; newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.uint64.type = type; newdiff->obj_attr.diff.uint64.type = type;
newdiff->obj_attr.diff.uint64.index = index; newdiff->obj_attr.diff.uint64.index = idx;
newdiff->obj_attr.diff.uint64.oldvalue = oldvalue; newdiff->obj_attr.diff.uint64.oldvalue = oldvalue;
newdiff->obj_attr.diff.uint64.newvalue = newvalue; newdiff->obj_attr.diff.uint64.newvalue = newvalue;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp); hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
@ -140,6 +140,8 @@ hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
goto out_too_complex; goto out_too_complex;
if (obj1->os_index != obj2->os_index) if (obj1->os_index != obj2->os_index)
/* we could allow different os_index for non-PU non-NUMAnode objects
* but it's likely useless anyway */
goto out_too_complex; goto out_too_complex;
#define _SETS_DIFFERENT(_set1, _set2) \ #define _SETS_DIFFERENT(_set1, _set2) \
@ -155,7 +157,8 @@ hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
|| SETS_DIFFERENT(allowed_nodeset, obj1, obj2)) || SETS_DIFFERENT(allowed_nodeset, obj1, obj2))
goto out_too_complex; goto out_too_complex;
/* no need to check logical_index, sibling_rank, symmetric_subtree */ /* no need to check logical_index, sibling_rank, symmetric_subtree,
* the parents did it */
if ((!obj1->name) != (!obj2->name) if ((!obj1->name) != (!obj2->name)
|| (obj1->name && strcmp(obj1->name, obj2->name))) { || (obj1->name && strcmp(obj1->name, obj2->name))) {

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2010-2015 Inria. All rights reserved. * Copyright © 2010-2015 Inria. All rights reserved.
* Copyright © 2011-2012 Université Bordeaux 1 * Copyright © 2011-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -119,12 +119,12 @@ static int hwloc_distances__check_matrix(hwloc_topology_t __hwloc_restrict topol
} }
static void hwloc_distances__set_from_string(struct hwloc_topology *topology, static void hwloc_distances__set_from_string(struct hwloc_topology *topology,
hwloc_obj_type_t type, char *string) hwloc_obj_type_t type, const char *string)
{ {
/* the string format is: "index[0],...,index[N-1]:distance[0],...,distance[N*N-1]" /* the string format is: "index[0],...,index[N-1]:distance[0],...,distance[N*N-1]"
* or "index[0],...,index[N-1]:X*Y" or "index[0],...,index[N-1]:X*Y*Z" * or "index[0],...,index[N-1]:X*Y" or "index[0],...,index[N-1]:X*Y*Z"
*/ */
char *tmp = string, *next; const char *tmp = string, *next;
unsigned *indexes; unsigned *indexes;
float *distances; float *distances;
unsigned nbobjs = 0, i, j, x, y, z; unsigned nbobjs = 0, i, j, x, y, z;
@ -173,10 +173,10 @@ static void hwloc_distances__set_from_string(struct hwloc_topology *topology,
indexes = calloc(nbobjs, sizeof(unsigned)); indexes = calloc(nbobjs, sizeof(unsigned));
distances = calloc(nbobjs*nbobjs, sizeof(float)); distances = calloc(nbobjs*nbobjs, sizeof(float));
tmp = string; tmp = string;
/* parse indexes */ /* parse indexes */
for(i=0; i<nbobjs; i++) { for(i=0; i<nbobjs; i++) {
indexes[i] = strtoul(tmp, &next, 0); indexes[i] = strtoul(tmp, (char **) &next, 0);
tmp = next+1; tmp = next+1;
} }
} }
@ -238,7 +238,8 @@ void hwloc_distances_set_from_env(struct hwloc_topology *topology)
{ {
hwloc_obj_type_t type; hwloc_obj_type_t type;
for(type = HWLOC_OBJ_SYSTEM; type < HWLOC_OBJ_TYPE_MAX; type++) { for(type = HWLOC_OBJ_SYSTEM; type < HWLOC_OBJ_TYPE_MAX; type++) {
char *env, envname[64]; const char *env;
char envname[64];
snprintf(envname, sizeof(envname), "HWLOC_%s_DISTANCES", hwloc_obj_type_string(type)); snprintf(envname, sizeof(envname), "HWLOC_%s_DISTANCES", hwloc_obj_type_string(type));
env = getenv(envname); env = getenv(envname);
if (env) { if (env) {
@ -449,34 +450,6 @@ void hwloc_distances_finalize_os(struct hwloc_topology *topology)
* into exported logical distances attached to objects * into exported logical distances attached to objects
*/ */
static hwloc_obj_t
hwloc_get_obj_covering_cpuset_nodeset(struct hwloc_topology *topology,
hwloc_const_cpuset_t cpuset,
hwloc_const_nodeset_t nodeset)
{
hwloc_obj_t parent = hwloc_get_root_obj(topology), child;
assert(cpuset);
assert(nodeset);
assert(hwloc_bitmap_isincluded(cpuset, parent->cpuset));
assert(!nodeset || hwloc_bitmap_isincluded(nodeset, parent->nodeset));
trychildren:
child = parent->first_child;
while (child) {
/* look for a child with a cpuset containing ours.
* if it has a nodeset, it must also contain ours.
*/
if (child->cpuset && hwloc_bitmap_isincluded(cpuset, child->cpuset)
&& (!child->nodeset || hwloc_bitmap_isincluded(nodeset, child->nodeset))) {
parent = child;
goto trychildren;
}
child = child->next_sibling;
}
return parent;
}
static void static void
hwloc_distances__finalize_logical(struct hwloc_topology *topology, hwloc_distances__finalize_logical(struct hwloc_topology *topology,
unsigned nbobjs, unsigned nbobjs,
@ -486,21 +459,33 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
float min = FLT_MAX, max = FLT_MIN; float min = FLT_MAX, max = FLT_MIN;
hwloc_obj_t root; hwloc_obj_t root;
float *matrix; float *matrix;
hwloc_cpuset_t cpuset; hwloc_cpuset_t cpuset, complete_cpuset;
hwloc_nodeset_t nodeset; hwloc_nodeset_t nodeset, complete_nodeset;
unsigned relative_depth; unsigned relative_depth;
int idx; int idx;
/* find the root */ /* find the root */
cpuset = hwloc_bitmap_alloc(); cpuset = hwloc_bitmap_alloc();
complete_cpuset = hwloc_bitmap_alloc();
nodeset = hwloc_bitmap_alloc(); nodeset = hwloc_bitmap_alloc();
complete_nodeset = hwloc_bitmap_alloc();
for(i=0; i<nbobjs; i++) { for(i=0; i<nbobjs; i++) {
hwloc_bitmap_or(cpuset, cpuset, objs[i]->cpuset); hwloc_bitmap_or(cpuset, cpuset, objs[i]->cpuset);
if (objs[i]->complete_cpuset)
hwloc_bitmap_or(complete_cpuset, complete_cpuset, objs[i]->complete_cpuset);
if (objs[i]->nodeset) if (objs[i]->nodeset)
hwloc_bitmap_or(nodeset, nodeset, objs[i]->nodeset); hwloc_bitmap_or(nodeset, nodeset, objs[i]->nodeset);
if (objs[i]->complete_nodeset)
hwloc_bitmap_or(complete_nodeset, complete_nodeset, objs[i]->complete_nodeset);
} }
/* find the object covering cpuset AND nodeset (can't use hwloc_get_obj_covering_cpuset()) */ /* find the object covering cpuset, we'll take care of the nodeset later */
root = hwloc_get_obj_covering_cpuset_nodeset(topology, cpuset, nodeset); root = hwloc_get_obj_covering_cpuset(topology, cpuset);
/* walk up to find a parent that also covers the nodeset */
while (root &&
(!hwloc_bitmap_isincluded(nodeset, root->nodeset)
|| !hwloc_bitmap_isincluded(complete_nodeset, root->complete_nodeset)
|| !hwloc_bitmap_isincluded(complete_cpuset, root->complete_cpuset)))
root = root->parent;
if (!root) { if (!root) {
/* should not happen, ignore the distance matrix and report an error. */ /* should not happen, ignore the distance matrix and report an error. */
if (!hwloc_hide_errors()) { if (!hwloc_hide_errors()) {
@ -508,7 +493,7 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
hwloc_bitmap_asprintf(&a, cpuset); hwloc_bitmap_asprintf(&a, cpuset);
hwloc_bitmap_asprintf(&b, nodeset); hwloc_bitmap_asprintf(&b, nodeset);
fprintf(stderr, "****************************************************************************\n"); fprintf(stderr, "****************************************************************************\n");
fprintf(stderr, "* hwloc has encountered an error when adding a distance matrix to the topology.\n"); fprintf(stderr, "* hwloc %s has encountered an error when adding a distance matrix to the topology.\n", HWLOC_VERSION);
fprintf(stderr, "*\n"); fprintf(stderr, "*\n");
fprintf(stderr, "* hwloc_distances__finalize_logical() could not find any object covering\n"); fprintf(stderr, "* hwloc_distances__finalize_logical() could not find any object covering\n");
fprintf(stderr, "* cpuset %s and nodeset %s\n", a, b); fprintf(stderr, "* cpuset %s and nodeset %s\n", a, b);
@ -524,7 +509,9 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
free(b); free(b);
} }
hwloc_bitmap_free(cpuset); hwloc_bitmap_free(cpuset);
hwloc_bitmap_free(complete_cpuset);
hwloc_bitmap_free(nodeset); hwloc_bitmap_free(nodeset);
hwloc_bitmap_free(complete_nodeset);
return; return;
} }
/* don't attach to Misc objects */ /* don't attach to Misc objects */
@ -533,9 +520,13 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
/* ideally, root has the exact cpuset and nodeset. /* ideally, root has the exact cpuset and nodeset.
* but ignoring or other things that remove objects may cause the object array to reduce */ * but ignoring or other things that remove objects may cause the object array to reduce */
assert(hwloc_bitmap_isincluded(cpuset, root->cpuset)); assert(hwloc_bitmap_isincluded(cpuset, root->cpuset));
assert(hwloc_bitmap_isincluded(complete_cpuset, root->complete_cpuset));
assert(hwloc_bitmap_isincluded(nodeset, root->nodeset)); assert(hwloc_bitmap_isincluded(nodeset, root->nodeset));
assert(hwloc_bitmap_isincluded(complete_nodeset, root->complete_nodeset));
hwloc_bitmap_free(cpuset); hwloc_bitmap_free(cpuset);
hwloc_bitmap_free(complete_cpuset);
hwloc_bitmap_free(nodeset); hwloc_bitmap_free(nodeset);
hwloc_bitmap_free(complete_nodeset);
if (root->depth >= objs[0]->depth) { if (root->depth >= objs[0]->depth) {
/* strange topology led us to find invalid relative depth, ignore */ /* strange topology led us to find invalid relative depth, ignore */
return; return;
@ -653,7 +644,7 @@ static void hwloc_report_user_distance_error(const char *msg, int line)
if (!reported && !hwloc_hide_errors()) { if (!reported && !hwloc_hide_errors()) {
fprintf(stderr, "****************************************************************************\n"); fprintf(stderr, "****************************************************************************\n");
fprintf(stderr, "* hwloc has encountered what looks like an error from user-given distances.\n"); fprintf(stderr, "* hwloc %s has encountered what looks like an error from user-given distances.\n", HWLOC_VERSION);
fprintf(stderr, "*\n"); fprintf(stderr, "*\n");
fprintf(stderr, "* %s\n", msg); fprintf(stderr, "* %s\n", msg);
fprintf(stderr, "* Error occurred in topology.c line %d\n", line); fprintf(stderr, "* Error occurred in topology.c line %d\n", line);
@ -942,12 +933,13 @@ hwloc_group_by_distances(struct hwloc_topology *topology)
{ {
unsigned nbobjs; unsigned nbobjs;
struct hwloc_os_distances_s * osdist; struct hwloc_os_distances_s * osdist;
char *env; const char *env;
float accuracies[5] = { 0.0f, 0.01f, 0.02f, 0.05f, 0.1f }; float accuracies[5] = { 0.0f, 0.01f, 0.02f, 0.05f, 0.1f };
unsigned nbaccuracies = 5; unsigned nbaccuracies = 5;
hwloc_obj_t group_obj; hwloc_obj_t group_obj;
int verbose = 0; int verbose = 0;
unsigned i; unsigned i;
hwloc_localeswitch_declare;
#ifdef HWLOC_DEBUG #ifdef HWLOC_DEBUG
unsigned j; unsigned j;
#endif #endif
@ -959,6 +951,7 @@ hwloc_group_by_distances(struct hwloc_topology *topology)
if (getenv("HWLOC_IGNORE_DISTANCES")) if (getenv("HWLOC_IGNORE_DISTANCES"))
return; return;
hwloc_localeswitch_init();
env = getenv("HWLOC_GROUPING_ACCURACY"); env = getenv("HWLOC_GROUPING_ACCURACY");
if (!env) { if (!env) {
/* only use 0.0 */ /* only use 0.0 */
@ -968,6 +961,7 @@ hwloc_group_by_distances(struct hwloc_topology *topology)
nbaccuracies = 1; nbaccuracies = 1;
accuracies[0] = (float) atof(env); accuracies[0] = (float) atof(env);
} /* otherwise try all values */ } /* otherwise try all values */
hwloc_localeswitch_fini();
#ifdef HWLOC_DEBUG #ifdef HWLOC_DEBUG
verbose = 1; verbose = 1;

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009 inria. All rights reserved. * Copyright © 2009 inria. All rights reserved.
* Copyright © 2009, 2012 Université Bordeaux 1 * Copyright © 2009, 2012 Université Bordeaux
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */

Просмотреть файл

@ -1,7 +1,7 @@
<!-- <!--
Copyright © 2009 CNRS Copyright © 2009 CNRS
Copyright © 2009-2013 Inria. All rights reserved. Copyright © 2009-2014 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux 1. Copyright © 2009-2011 Université Bordeaux.
See COPYING in top-level directory. See COPYING in top-level directory.
--> -->
@ -9,7 +9,7 @@
<!ELEMENT root (object)+> <!ELEMENT root (object)+>
<!ELEMENT object (page_type*,info*,distances*,userdata*,object*)> <!ELEMENT object (page_type*,info*,distances*,userdata*,object*)>
<!ATTLIST object type (System | Machine | Misc | Group | NUMANode | Socket| Cache | Core | PU | Bridge | PCIDev | OSDev) #REQUIRED> <!ATTLIST object type (System | Machine | Misc | Group | NUMANode | Package | Cache | Core | PU | Bridge | PCIDev | OSDev) #REQUIRED>
<!ATTLIST object os_level CDATA "-1" > <!ATTLIST object os_level CDATA "-1" >
<!ATTLIST object os_index CDATA "-1" > <!ATTLIST object os_index CDATA "-1" >
<!ATTLIST object name CDATA "" > <!ATTLIST object name CDATA "" >

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1 * Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -20,6 +20,14 @@
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#ifdef HAVE_PROGRAM_INVOCATION_NAME
#include <errno.h>
extern char *program_invocation_name;
#endif
#ifdef HAVE___PROGNAME
extern char *__progname;
#endif
int hwloc_snprintf(char *str, size_t size, const char *format, ...) int hwloc_snprintf(char *str, size_t size, const char *format, ...)
{ {
int ret; int ret;
@ -115,3 +123,44 @@ void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unus
hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine); hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine);
#endif /* HAVE_UNAME */ #endif /* HAVE_UNAME */
} }
char *
hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
{
#if HAVE_DECL_GETMODULEFILENAME
char name[256], *basename;
unsigned res = GetModuleFileName(NULL, name, sizeof(name));
if (res == sizeof(name) || !res)
return NULL;
basename = strrchr(name, '\\');
if (!basename)
basename = name;
else
basename++;
return strdup(basename);
#else /* !HAVE_GETMODULEFILENAME */
const char *name, *basename;
#if HAVE_DECL_GETPROGNAME
name = getprogname(); /* FreeBSD, NetBSD, some Solaris */
#elif HAVE_DECL_GETEXECNAME
name = getexecname(); /* Solaris */
#elif defined HAVE_PROGRAM_INVOCATION_NAME
name = program_invocation_name; /* Glibc. BGQ CNK. */
/* could use program_invocation_short_name directly, but we have the code to remove the path below anyway */
#elif defined HAVE___PROGNAME
name = __progname; /* fallback for most unix, used for OpenBSD */
#else
/* TODO: _NSGetExecutablePath(path, &size) on Darwin */
/* TODO: AIX, HPUX, OSF */
name = NULL;
#endif
if (!name)
return NULL;
basename = strrchr(name, '/');
if (!basename)
basename = name;
else
basename++;
return strdup(basename);
#endif /* !HAVE_GETMODULEFILENAME */
}

Просмотреть файл

@ -8,32 +8,43 @@
#include <hwloc/plugins.h> #include <hwloc/plugins.h>
#include <private/debug.h> #include <private/debug.h>
#ifdef HWLOC_DEBUG
static void static void
hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused, hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused,
struct hwloc_obj *pcidev, int depth __hwloc_attribute_unused) struct hwloc_obj *pcidev)
{ {
char busid[14]; char busid[14];
hwloc_obj_t parent;
/* indent */
parent = pcidev->parent;
while (parent) {
hwloc_debug("%s", " ");
parent = parent->parent;
}
snprintf(busid, sizeof(busid), "%04x:%02x:%02x.%01x", snprintf(busid, sizeof(busid), "%04x:%02x:%02x.%01x",
pcidev->attr->pcidev.domain, pcidev->attr->pcidev.bus, pcidev->attr->pcidev.dev, pcidev->attr->pcidev.func); pcidev->attr->pcidev.domain, pcidev->attr->pcidev.bus, pcidev->attr->pcidev.dev, pcidev->attr->pcidev.func);
if (pcidev->type == HWLOC_OBJ_BRIDGE) { if (pcidev->type == HWLOC_OBJ_BRIDGE) {
if (pcidev->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST) if (pcidev->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST)
hwloc_debug("%*s HostBridge", depth, ""); hwloc_debug("HostBridge");
else else
hwloc_debug("%*s %s Bridge [%04x:%04x]", depth, "", busid, hwloc_debug("Bridge [%04x:%04x]", busid,
pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id); pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id);
hwloc_debug(" to %04x:[%02x:%02x]\n", hwloc_debug(" to %04x:[%02x:%02x]\n",
pcidev->attr->bridge.downstream.pci.domain, pcidev->attr->bridge.downstream.pci.secondary_bus, pcidev->attr->bridge.downstream.pci.subordinate_bus); pcidev->attr->bridge.downstream.pci.domain, pcidev->attr->bridge.downstream.pci.secondary_bus, pcidev->attr->bridge.downstream.pci.subordinate_bus);
} else } else
hwloc_debug("%*s %s Device [%04x:%04x (%04x:%04x) rev=%02x class=%04x]\n", depth, "", busid, hwloc_debug("%s Device [%04x:%04x (%04x:%04x) rev=%02x class=%04x]\n", busid,
pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id, pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id,
pcidev->attr->pcidev.subvendor_id, pcidev->attr->pcidev.subdevice_id, pcidev->attr->pcidev.subvendor_id, pcidev->attr->pcidev.subdevice_id,
pcidev->attr->pcidev.revision, pcidev->attr->pcidev.class_id); pcidev->attr->pcidev.revision, pcidev->attr->pcidev.class_id);
} }
#endif /* HWLOC_DEBUG */
static void static void
hwloc_pci_traverse_lookuposdevices_cb(void * cbdata, hwloc_pci_traverse_lookuposdevices_cb(void * cbdata,
struct hwloc_obj *pcidev, int depth __hwloc_attribute_unused) struct hwloc_obj *pcidev)
{ {
struct hwloc_backend *backend = cbdata; struct hwloc_backend *backend = cbdata;
@ -45,23 +56,22 @@ hwloc_pci_traverse_lookuposdevices_cb(void * cbdata,
static void static void
hwloc_pci__traverse(void * cbdata, struct hwloc_obj *root, hwloc_pci__traverse(void * cbdata, struct hwloc_obj *root,
void (*cb)(void * cbdata, struct hwloc_obj *, int depth), void (*cb)(void * cbdata, struct hwloc_obj *))
int depth)
{ {
struct hwloc_obj *child = root->first_child; struct hwloc_obj *child = root->first_child;
while (child) { while (child) {
cb(cbdata, child, depth); cb(cbdata, child);
if (child->type == HWLOC_OBJ_BRIDGE) if (child->type == HWLOC_OBJ_BRIDGE)
hwloc_pci__traverse(cbdata, child, cb, depth+1); hwloc_pci__traverse(cbdata, child, cb);
child = child->next_sibling; child = child->next_sibling;
} }
} }
static void static void
hwloc_pci_traverse(void * cbdata, struct hwloc_obj *root, hwloc_pci_traverse(void * cbdata, struct hwloc_obj *root,
void (*cb)(void * cbdata, struct hwloc_obj *, int depth)) void (*cb)(void * cbdata, struct hwloc_obj *))
{ {
hwloc_pci__traverse(cbdata, root, cb, 0); hwloc_pci__traverse(cbdata, root, cb);
} }
enum hwloc_pci_busid_comparison_e { enum hwloc_pci_busid_comparison_e {
@ -71,7 +81,7 @@ enum hwloc_pci_busid_comparison_e {
HWLOC_PCI_BUSID_SUPERSET HWLOC_PCI_BUSID_SUPERSET
}; };
static enum hwloc_pci_busid_comparison_e static enum hwloc_pci_busid_comparison_e
hwloc_pci_compare_busids(struct hwloc_obj *a, struct hwloc_obj *b) hwloc_pci_compare_busids(struct hwloc_obj *a, struct hwloc_obj *b)
{ {
if (a->type == HWLOC_OBJ_BRIDGE) if (a->type == HWLOC_OBJ_BRIDGE)
@ -131,6 +141,8 @@ hwloc_pci_add_child_before(struct hwloc_obj *root, struct hwloc_obj *child, stru
else else
root->first_child = new; root->first_child = new;
new->next_sibling = child; new->next_sibling = child;
new->parent = root; /* so that hwloc_pci_traverse_print_cb() can indent by depth */
} }
static void static void
@ -203,21 +215,63 @@ hwloc_pci_add_object(struct hwloc_obj *root, struct hwloc_obj *new)
hwloc_pci_add_child_before(root, NULL, new); hwloc_pci_add_child_before(root, NULL, new);
} }
static struct hwloc_obj *
hwloc_pci_fixup_hostbridge_parent(struct hwloc_topology *topology __hwloc_attribute_unused,
struct hwloc_obj *hostbridge,
struct hwloc_obj *parent)
{
/* Xeon E5v3 in cluster-on-die mode only have PCI on the first NUMA node of each package.
* but many dual-processor host report the second PCI hierarchy on 2nd NUMA of first package.
*/
if (parent->depth >= 2
&& parent->type == HWLOC_OBJ_NUMANODE
&& parent->sibling_rank == 1 && parent->parent->arity == 2
&& parent->parent->type == HWLOC_OBJ_PACKAGE
&& parent->parent->sibling_rank == 0 && parent->parent->parent->arity == 2) {
const char *cpumodel = hwloc_obj_get_info_by_name(parent->parent, "CPUModel");
if (cpumodel && strstr(cpumodel, "Xeon")) {
if (!hwloc_hide_errors()) {
fprintf(stderr, "****************************************************************************\n");
fprintf(stderr, "* hwloc %s has encountered an incorrect PCI locality information.\n", HWLOC_VERSION);
fprintf(stderr, "* PCI bus %04x:%02x is supposedly close to 2nd NUMA node of 1st package,\n",
hostbridge->first_child->attr->pcidev.domain, hostbridge->first_child->attr->pcidev.bus);
fprintf(stderr, "* however hwloc believes this is impossible on this architecture.\n");
fprintf(stderr, "* Therefore the PCI bus will be moved to 1st NUMA node of 2nd package.\n");
fprintf(stderr, "*\n");
fprintf(stderr, "* If you feel this fixup is wrong, disable it by setting in your environment\n");
fprintf(stderr, "* HWLOC_PCI_%04x_%02x_LOCALCPUS= (empty value), and report the problem\n",
hostbridge->first_child->attr->pcidev.domain, hostbridge->first_child->attr->pcidev.bus);
fprintf(stderr, "* to the hwloc's user mailing list together with the XML output of lstopo.\n");
fprintf(stderr, "*\n");
fprintf(stderr, "* You may silence this message by setting HWLOC_HIDE_ERRORS=1 in your environment.\n");
fprintf(stderr, "****************************************************************************\n");
}
return parent->parent->next_sibling->first_child;
}
}
return parent;
}
static struct hwloc_obj * static struct hwloc_obj *
hwloc_pci_find_hostbridge_parent(struct hwloc_topology *topology, struct hwloc_backend *backend, hwloc_pci_find_hostbridge_parent(struct hwloc_topology *topology, struct hwloc_backend *backend,
struct hwloc_obj *hostbridge) struct hwloc_obj *hostbridge)
{ {
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc(); hwloc_bitmap_t cpuset = hwloc_bitmap_alloc();
struct hwloc_obj *parent; struct hwloc_obj *parent;
char *env; const char *env;
int err; int err;
/* override the cpuset with the environment if given */ /* override the cpuset with the environment if given */
int forced = 0;
char envname[256]; char envname[256];
snprintf(envname, sizeof(envname), "HWLOC_PCI_%04x_%02x_LOCALCPUS", snprintf(envname, sizeof(envname), "HWLOC_PCI_%04x_%02x_LOCALCPUS",
hostbridge->first_child->attr->pcidev.domain, hostbridge->first_child->attr->pcidev.bus); hostbridge->first_child->attr->pcidev.domain, hostbridge->first_child->attr->pcidev.bus);
env = getenv(envname); env = getenv(envname);
if (env) { if (env)
/* if env exists but is empty, don't let quirks change what the OS reports */
forced = 1;
if (env && *env) {
/* force the hostbridge cpuset */ /* force the hostbridge cpuset */
hwloc_debug("Overriding localcpus using %s in the environment\n", envname); hwloc_debug("Overriding localcpus using %s in the environment\n", envname);
hwloc_bitmap_sscanf(cpuset, env); hwloc_bitmap_sscanf(cpuset, env);
@ -250,6 +304,10 @@ hwloc_pci_find_hostbridge_parent(struct hwloc_topology *topology, struct hwloc_b
*/ */
while (parent->parent && hwloc_bitmap_isequal(parent->cpuset, parent->parent->cpuset)) while (parent->parent && hwloc_bitmap_isequal(parent->cpuset, parent->parent->cpuset))
parent = parent->parent; parent = parent->parent;
if (!forced)
parent = hwloc_pci_fixup_hostbridge_parent(topology, hostbridge, parent);
} else { } else {
/* the object we found is too large, insert an intermediate group */ /* the object we found is too large, insert an intermediate group */
hwloc_obj_t group_obj = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, -1); hwloc_obj_t group_obj = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, -1);
@ -286,6 +344,7 @@ hwloc_insert_pci_device_list(struct hwloc_backend *backend,
return 0; return 0;
/* first, organise object as tree under a fake parent object */ /* first, organise object as tree under a fake parent object */
fakeparent.parent = NULL;
fakeparent.first_child = NULL; fakeparent.first_child = NULL;
fakeparent.last_child = NULL; fakeparent.last_child = NULL;
while (first_obj) { while (first_obj) {
@ -294,8 +353,11 @@ hwloc_insert_pci_device_list(struct hwloc_backend *backend,
hwloc_pci_add_object(&fakeparent, obj); hwloc_pci_add_object(&fakeparent, obj);
} }
#ifdef HWLOC_DEBUG
hwloc_debug("%s", "\nPCI hierarchy under fake parent:\n"); hwloc_debug("%s", "\nPCI hierarchy under fake parent:\n");
hwloc_pci_traverse(NULL, &fakeparent, hwloc_pci_traverse_print_cb); hwloc_pci_traverse(NULL, &fakeparent, hwloc_pci_traverse_print_cb);
hwloc_debug("%s", "\n");
#endif
/* walk the hierarchy, and lookup OS devices */ /* walk the hierarchy, and lookup OS devices */
hwloc_pci_traverse(backend, &fakeparent, hwloc_pci_traverse_lookuposdevices_cb); hwloc_pci_traverse(backend, &fakeparent, hwloc_pci_traverse_lookuposdevices_cb);

Просмотреть файл

@ -404,7 +404,7 @@ hwloc_aix_get_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who,
int res = -1; int res = -1;
int depth, n, i; int depth, n, i;
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth < 0) { if (depth < 0) {
errno = EXDEV; errno = EXDEV;
return -1; return -1;
@ -610,7 +610,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
for (i = 0; i < nbnodes; i++) { for (i = 0; i < nbnodes; i++) {
hwloc_bitmap_t cpuset; hwloc_bitmap_t cpuset;
unsigned os_index = (unsigned) -1; /* no os_index except for PU and NODE below */ unsigned os_index = (unsigned) -1; /* no os_index except for PU and NUMANODE below */
if (rs_getrad(rset, rad, sdl, i, 0)) { if (rs_getrad(rset, rad, sdl, i, 0)) {
fprintf(stderr,"rs_getrad(%d) failed: %s\n", i, strerror(errno)); fprintf(stderr,"rs_getrad(%d) failed: %s\n", i, strerror(errno));
@ -630,7 +630,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
os_index = hwloc_bitmap_first(cpuset); os_index = hwloc_bitmap_first(cpuset);
hwloc_debug("Found PU #%u inside node %d for sdl %d\n", os_index, i, sdl); hwloc_debug("Found PU #%u inside node %d for sdl %d\n", os_index, i, sdl);
assert(hwloc_bitmap_weight(cpuset) == 1); assert(hwloc_bitmap_weight(cpuset) == 1);
} else if (type == HWLOC_OBJ_NODE) { } else if (type == HWLOC_OBJ_NUMANODE) {
/* NUMA node os_index isn't used for binding, just use the rad number to get unique values. /* NUMA node os_index isn't used for binding, just use the rad number to get unique values.
* Note that we'll use that fact in hwloc_aix_prepare_membind(). */ * Note that we'll use that fact in hwloc_aix_prepare_membind(). */
os_index = i; os_index = i;
@ -642,7 +642,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
obj->os_level = sdl; obj->os_level = sdl;
switch(type) { switch(type) {
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, i); hwloc_bitmap_set(obj->nodeset, i);
obj->memory.local_memory = 0; /* TODO: odd, rs_getinfo(rad, R_MEMSIZE, 0) << 10 returns the total memory ... */ obj->memory.local_memory = 0; /* TODO: odd, rs_getinfo(rad, R_MEMSIZE, 0) << 10 returns the total memory ... */
@ -752,7 +752,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
if (i == rs_getinfo(NULL, R_MCMSDL, 0)) if (i == rs_getinfo(NULL, R_MCMSDL, 0))
{ {
hwloc_debug("looking AIX node sdl %d\n", i); hwloc_debug("looking AIX node sdl %d\n", i);
look_rset(i, HWLOC_OBJ_NODE, topology, i); look_rset(i, HWLOC_OBJ_NUMANODE, topology, i);
known = 1; known = 1;
} }
# ifdef R_L2CSDL # ifdef R_L2CSDL
@ -865,6 +865,7 @@ static struct hwloc_disc_component hwloc_aix_disc_component = {
const struct hwloc_component hwloc_aix_component = { const struct hwloc_component hwloc_aix_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_aix_disc_component &hwloc_aix_disc_component

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2013-2014 Inria. All rights reserved. * Copyright © 2013-2015 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -20,7 +20,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
unsigned i; unsigned i;
char *env; const char *env;
if (!topology->levels[0][0]->cpuset) { if (!topology->levels[0][0]->cpuset) {
/* Nobody created objects yet, setup everything */ /* Nobody created objects yet, setup everything */
@ -49,8 +49,8 @@ hwloc_look_bgq(struct hwloc_backend *backend)
topology->levels[0][0]->nodeset = set; topology->levels[0][0]->nodeset = set;
topology->levels[0][0]->memory.local_memory = 16ULL*1024*1024*1024ULL; topology->levels[0][0]->memory.local_memory = 16ULL*1024*1024*1024ULL;
/* socket */ /* package */
obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, 0); obj = hwloc_alloc_setup_object(HWLOC_OBJ_PACKAGE, 0);
set = hwloc_bitmap_alloc(); set = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(set, 0, HWLOC_BGQ_CORES*4-1); hwloc_bitmap_set_range(set, 0, HWLOC_BGQ_CORES*4-1);
obj->cpuset = set; obj->cpuset = set;
@ -202,7 +202,7 @@ hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
{ {
struct utsname utsname; struct utsname utsname;
struct hwloc_backend *backend; struct hwloc_backend *backend;
char *env; const char *env;
int err; int err;
env = getenv("HWLOC_FORCE_BGQ"); env = getenv("HWLOC_FORCE_BGQ");
@ -234,6 +234,7 @@ static struct hwloc_disc_component hwloc_bgq_disc_component = {
const struct hwloc_component hwloc_bgq_component = { const struct hwloc_component hwloc_bgq_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_bgq_disc_component &hwloc_bgq_disc_component

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2011 Université Bordeaux 1 * Copyright © 2011 Université Bordeaux
* Copyright © 2012-2014 Inria. All rights reserved. * Copyright © 2012-2014 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -84,6 +84,8 @@ static unsigned hwloc_cuda_cores_per_MP(int major, int minor)
break; break;
case 3: case 3:
return 192; return 192;
case 5:
return 128;
} }
hwloc_debug("unknown compute capability %u.%u, disabling core display.\n", major, minor); hwloc_debug("unknown compute capability %u.%u, disabling core display.\n", major, minor);
return 0; return 0;
@ -192,9 +194,6 @@ hwloc_cuda_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend; struct hwloc_backend *backend;
struct hwloc_cuda_backend_data_s *data; struct hwloc_cuda_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */ /* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -226,12 +225,23 @@ static struct hwloc_disc_component hwloc_cuda_disc_component = {
NULL NULL
}; };
static int
hwloc_cuda_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("cuda", "hwloc_backend_alloc") < 0)
return -1;
return 0;
}
#ifdef HWLOC_INSIDE_PLUGIN #ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_cuda_component; HWLOC_DECLSPEC extern const struct hwloc_component hwloc_cuda_component;
#endif #endif
const struct hwloc_component hwloc_cuda_component = { const struct hwloc_component hwloc_cuda_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_cuda_component_init, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_cuda_disc_component &hwloc_cuda_disc_component

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2011-2012 Inria. All rights reserved. * Copyright © 2011-2014 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -93,6 +93,7 @@ static struct hwloc_disc_component hwloc_custom_disc_component = {
const struct hwloc_component hwloc_custom_component = { const struct hwloc_component hwloc_custom_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_custom_disc_component &hwloc_custom_disc_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2013 Université Bordeaux 1 * Copyright © 2009-2013 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -75,7 +75,7 @@ hwloc_look_darwin(struct hwloc_backend *backend)
if (nprocs == npackages * logical_per_package) if (nprocs == npackages * logical_per_package)
for (i = 0; i < npackages; i++) { for (i = 0; i < npackages; i++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, i); obj = hwloc_alloc_setup_object(HWLOC_OBJ_PACKAGE, i);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
for (cpu = i*logical_per_package; cpu < (i+1)*logical_per_package; cpu++) for (cpu = i*logical_per_package; cpu < (i+1)*logical_per_package; cpu++)
hwloc_bitmap_set(obj->cpuset, cpu); hwloc_bitmap_set(obj->cpuset, cpu);
@ -190,7 +190,7 @@ hwloc_look_darwin(struct hwloc_backend *backend)
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
/* cacheconfig tells us how many cpus share it, let's iterate on each cache */ /* cacheconfig tells us how many cpus share it, let's iterate on each cache */
for (j = 0; j < (nprocs / cacheconfig[i]); j++) { for (j = 0; j < (nprocs / cacheconfig[i]); j++) {
obj = hwloc_alloc_setup_object(i?HWLOC_OBJ_CACHE:HWLOC_OBJ_NODE, j); obj = hwloc_alloc_setup_object(i?HWLOC_OBJ_CACHE:HWLOC_OBJ_NUMANODE, j);
if (!i) { if (!i) {
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, j); hwloc_bitmap_set(obj->nodeset, j);
@ -300,6 +300,7 @@ static struct hwloc_disc_component hwloc_darwin_disc_component = {
const struct hwloc_component hwloc_darwin_component = { const struct hwloc_component hwloc_darwin_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_darwin_disc_component &hwloc_darwin_disc_component

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2012 Inria. All rights reserved. * Copyright © 2012-2014 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -15,8 +15,6 @@ hwloc_fake_component_instantiate(struct hwloc_disc_component *component __hwloc_
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
if (hwloc_plugin_check_namespace("fake", "hwloc_backend_alloc") < 0)
return NULL;
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT")) if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component instantiated\n"); printf("fake component instantiated\n");
return NULL; return NULL;
@ -31,10 +29,32 @@ static struct hwloc_disc_component hwloc_fake_disc_component = {
NULL NULL
}; };
static int
hwloc_fake_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("fake", "hwloc_backend_alloc") < 0)
return -1;
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component initialized\n");
return 0;
}
static void
hwloc_fake_component_finalize(unsigned long flags)
{
if (flags)
return;
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component finalized\n");
}
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_fake_component; /* never linked statically in the core */ HWLOC_DECLSPEC extern const struct hwloc_component hwloc_fake_component; /* never linked statically in the core */
const struct hwloc_component hwloc_fake_component = { const struct hwloc_component hwloc_fake_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_fake_component_init, hwloc_fake_component_finalize,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_fake_disc_component &hwloc_fake_disc_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1 * Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -169,8 +169,10 @@ static void
hwloc_freebsd_node_meminfo_info(struct hwloc_topology *topology) hwloc_freebsd_node_meminfo_info(struct hwloc_topology *topology)
{ {
int mib[2] = { CTL_HW, HW_PHYSMEM }; int mib[2] = { CTL_HW, HW_PHYSMEM };
size_t len = sizeof(topology->levels[0][0]->memory.local_memory); unsigned long physmem;
sysctl(mib, 2, &topology->levels[0][0]->memory.local_memory, &len, NULL, 0); size_t len = sizeof(physmem);
sysctl(mib, 2, &physmem, &len, NULL, 0);
topology->levels[0][0]->memory.local_memory = physmem;
} }
#endif #endif
@ -244,6 +246,7 @@ static struct hwloc_disc_component hwloc_freebsd_disc_component = {
const struct hwloc_component hwloc_freebsd_component = { const struct hwloc_component hwloc_freebsd_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_freebsd_disc_component &hwloc_freebsd_disc_component

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2012-2013 Blue Brain Project, BBP/EPFL. All rights reserved. * Copyright © 2012-2013 Blue Brain Project, BBP/EPFL. All rights reserved.
* Copyright © 2012-2013 Inria. All rights reserved. * Copyright © 2012-2014 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -218,9 +218,6 @@ hwloc_gl_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend; struct hwloc_backend *backend;
struct hwloc_gl_backend_data_s *data; struct hwloc_gl_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */ /* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -251,12 +248,23 @@ static struct hwloc_disc_component hwloc_gl_disc_component = {
NULL NULL
}; };
static int
hwloc_gl_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("gl", "hwloc_backend_alloc") < 0)
return -1;
return 0;
}
#ifdef HWLOC_INSIDE_PLUGIN #ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component; HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component;
#endif #endif
const struct hwloc_component hwloc_gl_component = { const struct hwloc_component hwloc_gl_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_gl_component_init, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_gl_disc_component &hwloc_gl_disc_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2010, 2013 Université Bordeaux 1 * Copyright © 2009-2010, 2013 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -47,7 +47,7 @@ hwloc_hpux_find_ldom(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set)
/* Does not correspond to exactly one node */ /* Does not correspond to exactly one node */
return -1; return -1;
/* obj is the highest possibly matching object, but some (single) child (with same cpuset) could match too */ /* obj is the highest possibly matching object, but some (single) child (with same cpuset) could match too */
while (obj->type != HWLOC_OBJ_NODE) { while (obj->type != HWLOC_OBJ_NUMANODE) {
/* try the first child, in case it has the same cpuset */ /* try the first child, in case it has the same cpuset */
if (!obj->first_child if (!obj->first_child
|| !obj->first_child->cpuset || !obj->first_child->cpuset
@ -198,7 +198,7 @@ hwloc_look_hpux(struct hwloc_backend *backend)
MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0); MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0);
while (currentnode != -1 && i < nbnodes) { while (currentnode != -1 && i < nbnodes) {
hwloc_debug("node %d is %d\n", i, currentnode); hwloc_debug("node %d is %d\n", i, currentnode);
nodes[i] = obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, currentnode); nodes[i] = obj = hwloc_alloc_setup_object(HWLOC_OBJ_NUMANODE, currentnode);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, currentnode); hwloc_bitmap_set(obj->nodeset, currentnode);
@ -304,6 +304,7 @@ static struct hwloc_disc_component hwloc_hpux_disc_component = {
const struct hwloc_component hwloc_hpux_component = { const struct hwloc_component hwloc_hpux_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_hpux_disc_component &hwloc_hpux_disc_component

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2012 Aleksej Saushev, The NetBSD Foundation * Copyright © 2012 Aleksej Saushev, The NetBSD Foundation
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1 * Copyright © 2009-2010 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -16,6 +16,9 @@
#include <sys/param.h> #include <sys/param.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include <hwloc.h> #include <hwloc.h>
#include <private/private.h> #include <private/private.h>
@ -130,6 +133,18 @@ hwloc_netbsd_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hw
return hwloc_netbsd_get_thread_cpubind(topology, pthread_self(), hwloc_cpuset, flags); return hwloc_netbsd_get_thread_cpubind(topology, pthread_self(), hwloc_cpuset, flags);
} }
#if (defined HAVE_SYSCTL) && (defined HAVE_SYS_SYSCTL_H)
static void
hwloc_netbsd_node_meminfo_info(struct hwloc_topology *topology)
{
int mib[2] = { CTL_HW, HW_PHYSMEM64 };
unsigned long physmem;
size_t len = sizeof(physmem);
sysctl(mib, 2, &physmem, &len, NULL, 0);
topology->levels[0][0]->memory.local_memory = physmem;
}
#endif
static int static int
hwloc_look_netbsd(struct hwloc_backend *backend) hwloc_look_netbsd(struct hwloc_backend *backend)
{ {
@ -143,8 +158,9 @@ hwloc_look_netbsd(struct hwloc_backend *backend)
} }
/* Add NetBSD specific information */ /* Add NetBSD specific information */
#if (defined HAVE_SYSCTL) && (defined HAVE_SYS_SYSCTL_H)
hwloc_netbsd_node_meminfo_info(topology);
#endif
hwloc_obj_add_info(topology->levels[0][0], "Backend", "NetBSD"); hwloc_obj_add_info(topology->levels[0][0], "Backend", "NetBSD");
if (topology->is_thissystem) if (topology->is_thissystem)
hwloc_add_uname_info(topology, NULL); hwloc_add_uname_info(topology, NULL);
@ -191,6 +207,7 @@ static struct hwloc_disc_component hwloc_netbsd_disc_component = {
const struct hwloc_component hwloc_netbsd_component = { const struct hwloc_component hwloc_netbsd_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_netbsd_disc_component &hwloc_netbsd_disc_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -51,6 +51,7 @@ static struct hwloc_disc_component hwloc_noos_disc_component = {
const struct hwloc_component hwloc_noos_component = { const struct hwloc_component hwloc_noos_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_noos_disc_component &hwloc_noos_disc_component

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2012 Inria. All rights reserved. * Copyright © 2012-2014 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -185,9 +185,6 @@ hwloc_nvml_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend; struct hwloc_backend *backend;
struct hwloc_nvml_backend_data_s *data; struct hwloc_nvml_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */ /* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -219,14 +216,24 @@ static struct hwloc_disc_component hwloc_nvml_disc_component = {
NULL NULL
}; };
static int
hwloc_nvml_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("nvml", "hwloc_backend_alloc") < 0)
return -1;
return 0;
}
#ifdef HWLOC_INSIDE_PLUGIN #ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_nvml_component; HWLOC_DECLSPEC extern const struct hwloc_component hwloc_nvml_component;
#endif #endif
const struct hwloc_component hwloc_nvml_component = { const struct hwloc_component hwloc_nvml_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_nvml_component_init, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_nvml_disc_component &hwloc_nvml_disc_component
}; };

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2012-2014 Inria. All rights reserved. * Copyright © 2012-2014 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux 1. All right reserved. * Copyright © 2013 Université Bordeaux. All right reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -292,9 +292,6 @@ hwloc_opencl_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend; struct hwloc_backend *backend;
struct hwloc_opencl_backend_data_s *data; struct hwloc_opencl_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */ /* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -326,12 +323,23 @@ static struct hwloc_disc_component hwloc_opencl_disc_component = {
NULL NULL
}; };
static int
hwloc_opencl_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("opencl", "hwloc_backend_alloc") < 0)
return -1;
return 0;
}
#ifdef HWLOC_INSIDE_PLUGIN #ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component; HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
#endif #endif
const struct hwloc_component hwloc_opencl_component = { const struct hwloc_component hwloc_opencl_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_opencl_component_init, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_opencl_disc_component &hwloc_opencl_disc_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -282,7 +282,7 @@ hwloc_look_osf(struct hwloc_backend *backend)
} }
indexes[radid] = radid; indexes[radid] = radid;
nodes[radid] = obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, radid); nodes[radid] = obj = hwloc_alloc_setup_object(HWLOC_OBJ_NUMANODE, radid);
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, radid); hwloc_bitmap_set(obj->nodeset, radid);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
@ -327,7 +327,7 @@ hwloc_look_osf(struct hwloc_backend *backend)
} }
} }
hwloc_distances_set(topology, HWLOC_OBJ_NODE, nbnodes, indexes, nodes, distances, 0 /* OS cannot force */); hwloc_distances_set(topology, HWLOC_OBJ_NUMANODE, nbnodes, indexes, nodes, distances, 0 /* OS cannot force */);
} }
radsetdestroy(&radset2); radsetdestroy(&radset2);
radsetdestroy(&radset); radsetdestroy(&radset);
@ -385,6 +385,7 @@ static struct hwloc_disc_component hwloc_osf_disc_component = {
const struct hwloc_component hwloc_osf_component = { const struct hwloc_component hwloc_osf_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_osf_disc_component &hwloc_osf_disc_component

Просмотреть файл

@ -1,7 +1,8 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2015 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux 1 * Copyright © 2009-2011, 2013 Université Bordeaux
* Copyright © 2014 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -20,18 +21,11 @@
#include <assert.h> #include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#include <setjmp.h> #include <setjmp.h>
#ifdef HWLOC_LINUX_SYS
#if (defined HWLOC_HAVE_LIBPCIACCESS) && (defined HWLOC_HAVE_PCIUTILS) #include <dirent.h>
#error Cannot have both LIBPCIACCESS and PCIUTILS enabled simultaneously
#elif (!defined HWLOC_HAVE_LIBPCIACCESS) && (!defined HWLOC_HAVE_PCIUTILS)
#error Cannot have neither LIBPCIACCESS nor PCIUTILS enabled simultaneously
#endif #endif
#ifdef HWLOC_HAVE_LIBPCIACCESS
#include <pciaccess.h> #include <pciaccess.h>
#else /* HWLOC_HAVE_PCIUTILS */
#include <pci/pci.h>
#endif
#ifndef PCI_HEADER_TYPE #ifndef PCI_HEADER_TYPE
#define PCI_HEADER_TYPE 0x0e #define PCI_HEADER_TYPE 0x0e
@ -79,39 +73,16 @@
#define CONFIG_SPACE_CACHESIZE 256 #define CONFIG_SPACE_CACHESIZE 256
#ifdef HWLOC_HAVE_PCIUTILS
/* Avoid letting libpci call exit(1) when no PCI bus is available. */
static jmp_buf err_buf;
static void
hwloc_pci_error(char *msg, ...)
{
va_list args;
va_start(args, msg);
fprintf(stderr, "pcilib: ");
vfprintf(stderr, msg, args);
fprintf(stderr, "\n");
longjmp(err_buf, 1);
}
static void
hwloc_pci_warning(char *msg __hwloc_attribute_unused, ...)
{
}
#endif
static int static int
hwloc_look_pci(struct hwloc_backend *backend) hwloc_look_pci(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
struct hwloc_obj *first_obj = NULL, *last_obj = NULL; struct hwloc_obj *first_obj = NULL, *last_obj = NULL;
#ifdef HWLOC_HAVE_LIBPCIACCESS
int ret; int ret;
struct pci_device_iterator *iter; struct pci_device_iterator *iter;
struct pci_device *pcidev; struct pci_device *pcidev;
#else /* HWLOC_HAVE_PCIUTILS */ #ifdef HWLOC_LINUX_SYS
struct pci_access *pciaccess; DIR *dir;
struct pci_dev *pcidev;
#endif #endif
if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO))) if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
@ -130,7 +101,6 @@ hwloc_look_pci(struct hwloc_backend *backend)
hwloc_debug("%s", "\nScanning PCI buses...\n"); hwloc_debug("%s", "\nScanning PCI buses...\n");
/* initialize PCI scanning */ /* initialize PCI scanning */
#ifdef HWLOC_HAVE_LIBPCIACCESS
ret = pci_system_init(); ret = pci_system_init();
if (ret) { if (ret) {
hwloc_debug("%s", "Can not initialize libpciaccess\n"); hwloc_debug("%s", "Can not initialize libpciaccess\n");
@ -138,30 +108,11 @@ hwloc_look_pci(struct hwloc_backend *backend)
} }
iter = pci_slot_match_iterator_create(NULL); iter = pci_slot_match_iterator_create(NULL);
#else /* HWLOC_HAVE_PCIUTILS */
pciaccess = pci_alloc();
pciaccess->error = hwloc_pci_error;
pciaccess->warning = hwloc_pci_warning;
if (setjmp(err_buf)) {
pci_cleanup(pciaccess);
return -1;
}
pci_init(pciaccess);
pci_scan_bus(pciaccess);
#endif
/* iterate over devices */ /* iterate over devices */
#ifdef HWLOC_HAVE_LIBPCIACCESS
for (pcidev = pci_device_next(iter); for (pcidev = pci_device_next(iter);
pcidev; pcidev;
pcidev = pci_device_next(iter)) pcidev = pci_device_next(iter))
#else /* HWLOC_HAVE_PCIUTILS */
for (pcidev = pciaccess->devices;
pcidev;
pcidev = pcidev->next)
#endif
{ {
const char *vendorname, *devicename, *fullname; const char *vendorname, *devicename, *fullname;
unsigned char config_space_cache[CONFIG_SPACE_CACHESIZE]; unsigned char config_space_cache[CONFIG_SPACE_CACHESIZE];
@ -172,36 +123,17 @@ hwloc_look_pci(struct hwloc_backend *backend)
unsigned short tmp16; unsigned short tmp16;
char name[128]; char name[128];
unsigned offset; unsigned offset;
#ifdef HWLOC_HAVE_PCI_FIND_CAP
struct pci_cap *cap;
#endif
/* initialize the config space in case we fail to read it (missing permissions, etc). */ /* initialize the config space in case we fail to read it (missing permissions, etc). */
memset(config_space_cache, 0xff, CONFIG_SPACE_CACHESIZE); memset(config_space_cache, 0xff, CONFIG_SPACE_CACHESIZE);
#ifdef HWLOC_HAVE_LIBPCIACCESS
pci_device_probe(pcidev); pci_device_probe(pcidev);
pci_device_cfg_read(pcidev, config_space_cache, 0, CONFIG_SPACE_CACHESIZE, NULL); pci_device_cfg_read(pcidev, config_space_cache, 0, CONFIG_SPACE_CACHESIZE, NULL);
#else /* HWLOC_HAVE_PCIUTILS */
pci_read_block(pcidev, 0, config_space_cache, CONFIG_SPACE_CACHESIZE); /* doesn't even tell how much it actually reads */
#endif
/* try to read the domain */ /* try to read the domain */
#if (defined HWLOC_HAVE_LIBPCIACCESS) || (defined HWLOC_HAVE_PCIDEV_DOMAIN)
domain = pcidev->domain; domain = pcidev->domain;
#else
domain = 0; /* default domain number */
#endif
/* try to read the device_class */ /* try to read the device_class */
#ifdef HWLOC_HAVE_LIBPCIACCESS
device_class = pcidev->device_class >> 8; device_class = pcidev->device_class >> 8;
#else /* HWLOC_HAVE_PCIUTILS */
#ifdef HWLOC_HAVE_PCIDEV_DEVICE_CLASS
device_class = pcidev->device_class;
#else
device_class = config_space_cache[PCI_CLASS_DEVICE] | (config_space_cache[PCI_CLASS_DEVICE+1] << 8);
#endif
#endif
/* fixup SR-IOV buggy VF device/vendor IDs */ /* fixup SR-IOV buggy VF device/vendor IDs */
if (0xffff == pcidev->vendor_id && 0xffff == pcidev->device_id) { if (0xffff == pcidev->vendor_id && 0xffff == pcidev->device_id) {
@ -269,12 +201,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
obj->attr->pcidev.revision = config_space_cache[PCI_REVISION_ID]; obj->attr->pcidev.revision = config_space_cache[PCI_REVISION_ID];
obj->attr->pcidev.linkspeed = 0; /* unknown */ obj->attr->pcidev.linkspeed = 0; /* unknown */
#ifdef HWLOC_HAVE_PCI_FIND_CAP
cap = pci_find_cap(pcidev, PCI_CAP_ID_EXP, PCI_CAP_NORMAL);
offset = cap ? cap->addr : 0;
#else
offset = hwloc_pci_find_cap(config_space_cache, PCI_CAP_ID_EXP); offset = hwloc_pci_find_cap(config_space_cache, PCI_CAP_ID_EXP);
#endif /* HWLOC_HAVE_PCI_FIND_CAP */
if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE) if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE)
hwloc_pci_find_linkspeed(config_space_cache, offset, &obj->attr->pcidev.linkspeed); hwloc_pci_find_linkspeed(config_space_cache, offset, &obj->attr->pcidev.linkspeed);
@ -293,46 +220,17 @@ hwloc_look_pci(struct hwloc_backend *backend)
*/ */
} }
/* starting from pciutils 2.2, pci_lookup_name() takes a variable number
* of arguments, and supports the PCI_LOOKUP_NO_NUMBERS flag.
*/
/* get the vendor name */ /* get the vendor name */
#ifdef HWLOC_HAVE_LIBPCIACCESS
vendorname = pci_device_get_vendor_name(pcidev); vendorname = pci_device_get_vendor_name(pcidev);
#else /* HWLOC_HAVE_PCIUTILS */
vendorname = pci_lookup_name(pciaccess, name, sizeof(name),
#if HAVE_DECL_PCI_LOOKUP_NO_NUMBERS
PCI_LOOKUP_VENDOR|PCI_LOOKUP_NO_NUMBERS,
pcidev->vendor_id
#else
PCI_LOOKUP_VENDOR,
pcidev->vendor_id, 0, 0, 0
#endif
);
#endif /* HWLOC_HAVE_PCIUTILS */
if (vendorname && *vendorname) if (vendorname && *vendorname)
hwloc_obj_add_info(obj, "PCIVendor", vendorname); hwloc_obj_add_info(obj, "PCIVendor", vendorname);
/* get the device name */ /* get the device name */
#ifdef HWLOC_HAVE_LIBPCIACCESS
devicename = pci_device_get_device_name(pcidev); devicename = pci_device_get_device_name(pcidev);
#else /* HWLOC_HAVE_PCIUTILS */
devicename = pci_lookup_name(pciaccess, name, sizeof(name),
#if HAVE_DECL_PCI_LOOKUP_NO_NUMBERS
PCI_LOOKUP_DEVICE|PCI_LOOKUP_NO_NUMBERS,
pcidev->vendor_id, pcidev->device_id
#else
PCI_LOOKUP_DEVICE,
pcidev->vendor_id, pcidev->device_id, 0, 0
#endif
);
#endif /* HWLOC_HAVE_PCIUTILS */
if (devicename && *devicename) if (devicename && *devicename)
hwloc_obj_add_info(obj, "PCIDevice", devicename); hwloc_obj_add_info(obj, "PCIDevice", devicename);
/* generate or get the fullname */ /* generate or get the fullname */
#ifdef HWLOC_HAVE_LIBPCIACCESS
snprintf(name, sizeof(name), "%s%s%s", snprintf(name, sizeof(name), "%s%s%s",
vendorname ? vendorname : "", vendorname ? vendorname : "",
vendorname && devicename ? " " : "", vendorname && devicename ? " " : "",
@ -340,19 +238,6 @@ hwloc_look_pci(struct hwloc_backend *backend)
fullname = name; fullname = name;
if (*name) if (*name)
obj->name = strdup(name); obj->name = strdup(name);
#else /* HWLOC_HAVE_PCIUTILS */
fullname = pci_lookup_name(pciaccess, name, sizeof(name),
#if HAVE_DECL_PCI_LOOKUP_NO_NUMBERS
PCI_LOOKUP_VENDOR|PCI_LOOKUP_DEVICE|PCI_LOOKUP_NO_NUMBERS,
pcidev->vendor_id, pcidev->device_id
#else
PCI_LOOKUP_VENDOR|PCI_LOOKUP_DEVICE,
pcidev->vendor_id, pcidev->device_id, 0, 0
#endif
);
if (fullname && *fullname)
obj->name = strdup(fullname);
#endif /* HWLOC_HAVE_PCIUTILS */
hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s\n", hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s\n",
domain, pcidev->bus, pcidev->dev, pcidev->func, domain, pcidev->bus, pcidev->dev, pcidev->func,
device_class, pcidev->vendor_id, pcidev->device_id, device_class, pcidev->vendor_id, pcidev->device_id,
@ -367,11 +252,40 @@ hwloc_look_pci(struct hwloc_backend *backend)
} }
/* finalize device scanning */ /* finalize device scanning */
#ifdef HWLOC_HAVE_LIBPCIACCESS
pci_iterator_destroy(iter); pci_iterator_destroy(iter);
pci_system_cleanup(); pci_system_cleanup();
#else /* HWLOC_HAVE_PCIUTILS */
pci_cleanup(pciaccess); #ifdef HWLOC_LINUX_SYS
dir = opendir("/sys/bus/pci/slots/");
if (dir) {
struct dirent *dirent;
while ((dirent = readdir(dir)) != NULL) {
char path[64];
FILE *file;
if (dirent->d_name[0] == '.')
continue;
snprintf(path, sizeof(path), "/sys/bus/pci/slots/%s/address", dirent->d_name);
file = fopen(path, "r");
if (file) {
unsigned domain, bus, dev;
if (fscanf(file, "%x:%x:%x", &domain, &bus, &dev) == 3) {
hwloc_obj_t obj = first_obj;
while (obj) {
if (obj->attr->pcidev.domain == domain
&& obj->attr->pcidev.bus == bus
&& obj->attr->pcidev.dev == dev
&& obj->attr->pcidev.func == 0) {
hwloc_obj_add_info(obj, "PCISlot", dirent->d_name);
break;
}
obj = obj->next_sibling;
}
}
fclose(file);
}
}
closedir(dir);
}
#endif #endif
return hwloc_insert_pci_device_list(backend, first_obj); return hwloc_insert_pci_device_list(backend, first_obj);
@ -385,9 +299,6 @@ hwloc_pci_component_instantiate(struct hwloc_disc_component *component,
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */ /* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -407,12 +318,23 @@ static struct hwloc_disc_component hwloc_pci_disc_component = {
NULL NULL
}; };
static int
hwloc_pci_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("pci", "hwloc_backend_alloc") < 0)
return -1;
return 0;
}
#ifdef HWLOC_INSIDE_PLUGIN #ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component; HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component;
#endif #endif
const struct hwloc_component hwloc_pci_component = { const struct hwloc_component hwloc_pci_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_pci_component_init, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_pci_disc_component &hwloc_pci_disc_component

Просмотреть файл

@ -1,11 +1,11 @@
/* /*
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved. * Copyright © 2009-2010 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 Université Bordeaux 1. All rights reserved. * Copyright © 2013 Université Bordeaux. All rights reserved.
* *
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
* *
* $HEADER$ * $HEADER$
*/ */
@ -261,9 +261,9 @@ static int probe_cpu(picl_nodehdl_t node_hdl, void* dummy_arg __hwloc_attribute_
if (p_info.type == PICL_PTYPE_CHARSTRING) { if (p_info.type == PICL_PTYPE_CHARSTRING) {
val = picl_get_propval(p_hdl, &string_val, sizeof(string_val)); val = picl_get_propval(p_hdl, &string_val, sizeof(string_val));
if (val == PICL_SUCCESS) { if (val == PICL_SUCCESS) {
} }
} }
} }
} }
} }
@ -316,10 +316,10 @@ Initializes, gets the root, then walks the picl tree looking for information
Currently, the "core" class is only needed for OPL systems Currently, the "core" class is only needed for OPL systems
*****************************************************************************/ *****************************************************************************/
char *hwloc_solaris_get_chip_model(void) { char *hwloc_solaris_get_chip_model(void) {
if (called_cpu_probe) { if (called_cpu_probe) {
if (dss_chip_mode != MODE_UNKNOWN) { /* SPARC chip */ if (dss_chip_mode != MODE_UNKNOWN) { /* SPARC chip */
strncpy(dss_chip_model, sparc_modes[dss_chip_mode], strncpy(dss_chip_model, sparc_modes[dss_chip_mode],
PICL_PROPNAMELEN_MAX); PICL_PROPNAMELEN_MAX);
} }
} else { } else {

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2011 Oracle and/or its affiliates. All rights reserved. * Copyright © 2011 Oracle and/or its affiliates. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -49,7 +49,7 @@ hwloc_solaris_set_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t i
return -1; return -1;
#ifdef HAVE_LIBLGRP #ifdef HAVE_LIBLGRP
if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) { if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth >= 0) { if (depth >= 0) {
int n = hwloc_get_nbobjs_by_depth(topology, depth); int n = hwloc_get_nbobjs_by_depth(topology, depth);
int i; int i;
@ -66,7 +66,7 @@ hwloc_solaris_set_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t i
#ifdef HAVE_LIBLGRP #ifdef HAVE_LIBLGRP
if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) { if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth >= 0) { if (depth >= 0) {
int n = hwloc_get_nbobjs_by_depth(topology, depth); int n = hwloc_get_nbobjs_by_depth(topology, depth);
int i; int i;
@ -141,7 +141,7 @@ static int
hwloc_solaris_get_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused) hwloc_solaris_get_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{ {
processorid_t binding; processorid_t binding;
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
int n; int n;
int i; int i;
@ -214,7 +214,7 @@ hwloc_solaris_set_sth_membind(hwloc_topology_t topology, idtype_t idtype, id_t i
return -1; return -1;
} }
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
if (depth < 0) { if (depth < 0) {
errno = EXDEV; errno = EXDEV;
return -1; return -1;
@ -257,7 +257,7 @@ hwloc_solaris_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_node
static int static int
hwloc_solaris_get_sth_membind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags __hwloc_attribute_unused) hwloc_solaris_get_sth_membind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags __hwloc_attribute_unused)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
int n; int n;
int i; int i;
@ -304,7 +304,7 @@ hwloc_solaris_get_thisthread_membind(hwloc_topology_t topology, hwloc_nodeset_t
#endif /* HAVE_LIBLGRP */ #endif /* HAVE_LIBLGRP */
#ifdef MADV_ACCESS_LWP #ifdef MADV_ACCESS_LWP
static int static int
hwloc_solaris_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags __hwloc_attribute_unused) hwloc_solaris_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags __hwloc_attribute_unused)
{ {
@ -361,7 +361,7 @@ browse(struct hwloc_topology *topology, lgrp_cookie_t cookie, lgrp_id_t lgrp, hw
cpuids = malloc(sizeof(processorid_t) * n); cpuids = malloc(sizeof(processorid_t) * n);
assert(cpuids != NULL); assert(cpuids != NULL);
obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, lgrp); obj = hwloc_alloc_setup_object(HWLOC_OBJ_NUMANODE, lgrp);
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, lgrp); hwloc_bitmap_set(obj->nodeset, lgrp);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
@ -439,7 +439,7 @@ hwloc_look_lgrp(struct hwloc_topology *topology)
for (j = 0; j < curlgrp; j++) for (j = 0; j < curlgrp; j++)
distances[i*curlgrp+j] = (float) lgrp_latency_cookie(cookie, glob_lgrps[i]->os_index, glob_lgrps[j]->os_index, LGRP_LAT_CPU_TO_MEM); distances[i*curlgrp+j] = (float) lgrp_latency_cookie(cookie, glob_lgrps[i]->os_index, glob_lgrps[j]->os_index, LGRP_LAT_CPU_TO_MEM);
} }
hwloc_distances_set(topology, HWLOC_OBJ_NODE, curlgrp, indexes, glob_lgrps, distances, 0 /* OS cannot force */); hwloc_distances_set(topology, HWLOC_OBJ_NUMANODE, curlgrp, indexes, glob_lgrps, distances, 0 /* OS cannot force */);
} }
#endif /* HAVE_LGRP_LATENCY_COOKIE */ #endif /* HAVE_LGRP_LATENCY_COOKIE */
} }
@ -452,7 +452,7 @@ hwloc_look_lgrp(struct hwloc_topology *topology)
static int static int
hwloc_look_kstat(struct hwloc_topology *topology) hwloc_look_kstat(struct hwloc_topology *topology)
{ {
/* FIXME this assumes that all sockets are identical */ /* FIXME this assumes that all packages are identical */
char *CPUType = hwloc_solaris_get_chip_type(); char *CPUType = hwloc_solaris_get_chip_type();
char *CPUModel = hwloc_solaris_get_chip_model(); char *CPUModel = hwloc_solaris_get_chip_model();
@ -464,7 +464,7 @@ hwloc_look_kstat(struct hwloc_topology *topology)
unsigned Pproc_max = 0; unsigned Pproc_max = 0;
unsigned Pproc_alloc = 256; unsigned Pproc_alloc = 256;
struct hwloc_solaris_Pproc { struct hwloc_solaris_Pproc {
unsigned Lsock, Psock, Lcore, Lproc; unsigned Lpkg, Ppkg, Lcore, Lproc;
} * Pproc = malloc(Pproc_alloc * sizeof(*Pproc)); } * Pproc = malloc(Pproc_alloc * sizeof(*Pproc));
unsigned Lproc_num = 0; unsigned Lproc_num = 0;
@ -476,22 +476,22 @@ hwloc_look_kstat(struct hwloc_topology *topology)
unsigned Lcore_num = 0; unsigned Lcore_num = 0;
unsigned Lcore_alloc = 256; unsigned Lcore_alloc = 256;
struct hwloc_solaris_Lcore { struct hwloc_solaris_Lcore {
unsigned Pcore, Psock; unsigned Pcore, Ppkg;
} * Lcore = malloc(Lcore_alloc * sizeof(*Lcore)); } * Lcore = malloc(Lcore_alloc * sizeof(*Lcore));
unsigned Lsock_num = 0; unsigned Lpkg_num = 0;
unsigned Lsock_alloc = 256; unsigned Lpkg_alloc = 256;
struct hwloc_solaris_Lsock { struct hwloc_solaris_Lpkg {
unsigned Psock; unsigned Ppkg;
} * Lsock = malloc(Lsock_alloc * sizeof(*Lsock)); } * Lpkg = malloc(Lpkg_alloc * sizeof(*Lpkg));
unsigned sockid, coreid, cpuid; unsigned pkgid, coreid, cpuid;
unsigned i; unsigned i;
for (i = 0; i < Pproc_alloc; i++) { for (i = 0; i < Pproc_alloc; i++) {
Pproc[i].Lproc = -1; Pproc[i].Lproc = -1;
Pproc[i].Lsock = -1; Pproc[i].Lpkg = -1;
Pproc[i].Psock = -1; Pproc[i].Ppkg = -1;
Pproc[i].Lcore = -1; Pproc[i].Lcore = -1;
} }
@ -500,7 +500,7 @@ hwloc_look_kstat(struct hwloc_topology *topology)
free(Pproc); free(Pproc);
free(Lproc); free(Lproc);
free(Lcore); free(Lcore);
free(Lsock); free(Lpkg);
return 0; return 0;
} }
@ -524,8 +524,8 @@ hwloc_look_kstat(struct hwloc_topology *topology)
Pproc = realloc(Pproc, Pproc_alloc * sizeof(*Pproc)); Pproc = realloc(Pproc, Pproc_alloc * sizeof(*Pproc));
for(i = Pproc_alloc/2; i < Pproc_alloc; i++) { for(i = Pproc_alloc/2; i < Pproc_alloc; i++) {
Pproc[i].Lproc = -1; Pproc[i].Lproc = -1;
Pproc[i].Lsock = -1; Pproc[i].Lpkg = -1;
Pproc[i].Psock = -1; Pproc[i].Ppkg = -1;
Pproc[i].Lcore = -1; Pproc[i].Lcore = -1;
} }
} }
@ -559,26 +559,26 @@ hwloc_look_kstat(struct hwloc_topology *topology)
stat = (kstat_named_t *) kstat_data_lookup(ksp, "chip_id"); stat = (kstat_named_t *) kstat_data_lookup(ksp, "chip_id");
if (!stat) if (!stat)
{ {
if (Lsock_num) if (Lpkg_num)
fprintf(stderr, "could not read socket id for CPU%u: %s\n", cpuid, strerror(errno)); fprintf(stderr, "could not read package id for CPU%u: %s\n", cpuid, strerror(errno));
else else
hwloc_debug("could not read socket id for CPU%u: %s\n", cpuid, strerror(errno)); hwloc_debug("could not read package id for CPU%u: %s\n", cpuid, strerror(errno));
look_chips = 0; look_chips = 0;
continue; continue;
} }
switch (stat->data_type) { switch (stat->data_type) {
case KSTAT_DATA_INT32: case KSTAT_DATA_INT32:
sockid = stat->value.i32; pkgid = stat->value.i32;
break; break;
case KSTAT_DATA_UINT32: case KSTAT_DATA_UINT32:
sockid = stat->value.ui32; pkgid = stat->value.ui32;
break; break;
#ifdef _INT64_TYPE #ifdef _INT64_TYPE
case KSTAT_DATA_UINT64: case KSTAT_DATA_UINT64:
sockid = stat->value.ui64; pkgid = stat->value.ui64;
break; break;
case KSTAT_DATA_INT64: case KSTAT_DATA_INT64:
sockid = stat->value.i64; pkgid = stat->value.i64;
break; break;
#endif #endif
default: default:
@ -586,18 +586,18 @@ hwloc_look_kstat(struct hwloc_topology *topology)
look_chips = 0; look_chips = 0;
continue; continue;
} }
Pproc[cpuid].Psock = sockid; Pproc[cpuid].Ppkg = pkgid;
for (i = 0; i < Lsock_num; i++) for (i = 0; i < Lpkg_num; i++)
if (sockid == Lsock[i].Psock) if (pkgid == Lpkg[i].Ppkg)
break; break;
Pproc[cpuid].Lsock = i; Pproc[cpuid].Lpkg = i;
hwloc_debug("%u on socket %u (%u)\n", cpuid, i, sockid); hwloc_debug("%u on package %u (%u)\n", cpuid, i, pkgid);
if (i == Lsock_num) { if (i == Lpkg_num) {
if (Lsock_num == Lsock_alloc) { if (Lpkg_num == Lpkg_alloc) {
Lsock_alloc *= 2; Lpkg_alloc *= 2;
Lsock = realloc(Lsock, Lsock_alloc * sizeof(*Lsock)); Lpkg = realloc(Lpkg, Lpkg_alloc * sizeof(*Lpkg));
} }
Lsock[Lsock_num++].Psock = sockid; Lpkg[Lpkg_num++].Ppkg = pkgid;
} }
} while(0); } while(0);
@ -634,7 +634,7 @@ hwloc_look_kstat(struct hwloc_topology *topology)
continue; continue;
} }
for (i = 0; i < Lcore_num; i++) for (i = 0; i < Lcore_num; i++)
if (coreid == Lcore[i].Pcore && Pproc[cpuid].Psock == Lcore[i].Psock) if (coreid == Lcore[i].Pcore && Pproc[cpuid].Ppkg == Lcore[i].Ppkg)
break; break;
Pproc[cpuid].Lcore = i; Pproc[cpuid].Lcore = i;
hwloc_debug("%u on core %u (%u)\n", cpuid, i, coreid); hwloc_debug("%u on core %u (%u)\n", cpuid, i, coreid);
@ -643,7 +643,7 @@ hwloc_look_kstat(struct hwloc_topology *topology)
Lcore_alloc *= 2; Lcore_alloc *= 2;
Lcore = realloc(Lcore, Lcore_alloc * sizeof(*Lcore)); Lcore = realloc(Lcore, Lcore_alloc * sizeof(*Lcore));
} }
Lcore[Lcore_num].Psock = Pproc[cpuid].Psock; Lcore[Lcore_num].Ppkg = Pproc[cpuid].Ppkg;
Lcore[Lcore_num++].Pcore = coreid; Lcore[Lcore_num++].Pcore = coreid;
} }
} while(0); } while(0);
@ -656,18 +656,18 @@ hwloc_look_kstat(struct hwloc_topology *topology)
if (look_chips) { if (look_chips) {
struct hwloc_obj *obj; struct hwloc_obj *obj;
unsigned j,k; unsigned j,k;
hwloc_debug("%d Sockets\n", Lsock_num); hwloc_debug("%d Packages\n", Lpkg_num);
for (j = 0; j < Lsock_num; j++) { for (j = 0; j < Lpkg_num; j++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, Lsock[j].Psock); obj = hwloc_alloc_setup_object(HWLOC_OBJ_PACKAGE, Lpkg[j].Ppkg);
if (CPUType) if (CPUType)
hwloc_obj_add_info(obj, "CPUType", CPUType); hwloc_obj_add_info(obj, "CPUType", CPUType);
if (CPUModel) if (CPUModel)
hwloc_obj_add_info(obj, "CPUModel", CPUModel); hwloc_obj_add_info(obj, "CPUModel", CPUModel);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
for(k=0; k<Pproc_max; k++) for(k=0; k<Pproc_max; k++)
if (Pproc[k].Lsock == j) if (Pproc[k].Lpkg == j)
hwloc_bitmap_set(obj->cpuset, k); hwloc_bitmap_set(obj->cpuset, k);
hwloc_debug_1arg_bitmap("Socket %d has cpuset %s\n", j, obj->cpuset); hwloc_debug_1arg_bitmap("Package %d has cpuset %s\n", j, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
hwloc_debug("%s", "\n"); hwloc_debug("%s", "\n");
@ -709,7 +709,7 @@ hwloc_look_kstat(struct hwloc_topology *topology)
free(Pproc); free(Pproc);
free(Lproc); free(Lproc);
free(Lcore); free(Lcore);
free(Lsock); free(Lpkg);
return Lproc_num > 0; return Lproc_num > 0;
} }
@ -763,7 +763,7 @@ hwloc_set_solaris_hooks(struct hwloc_binding_hooks *hooks,
hooks->get_thisproc_membind = hwloc_solaris_get_thisproc_membind; hooks->get_thisproc_membind = hwloc_solaris_get_thisproc_membind;
hooks->get_thisthread_membind = hwloc_solaris_get_thisthread_membind; hooks->get_thisthread_membind = hwloc_solaris_get_thisthread_membind;
#endif /* HAVE_LIBLGRP */ #endif /* HAVE_LIBLGRP */
#ifdef MADV_ACCESS_LWP #ifdef MADV_ACCESS_LWP
hooks->set_area_membind = hwloc_solaris_set_area_membind; hooks->set_area_membind = hwloc_solaris_set_area_membind;
support->membind->firsttouch_membind = 1; support->membind->firsttouch_membind = 1;
support->membind->bind_membind = 1; support->membind->bind_membind = 1;
@ -797,6 +797,7 @@ static struct hwloc_disc_component hwloc_solaris_disc_component = {
const struct hwloc_component hwloc_solaris_component = { const struct hwloc_component hwloc_solaris_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_solaris_disc_component &hwloc_solaris_disc_component

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1 * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -533,11 +533,11 @@ hwloc_look_windows(struct hwloc_backend *backend)
id = -1; id = -1;
switch (procInfo[i].Relationship) { switch (procInfo[i].Relationship) {
case RelationNumaNode: case RelationNumaNode:
type = HWLOC_OBJ_NODE; type = HWLOC_OBJ_NUMANODE;
id = procInfo[i].NumaNode.NodeNumber; id = procInfo[i].NumaNode.NodeNumber;
break; break;
case RelationProcessorPackage: case RelationProcessorPackage:
type = HWLOC_OBJ_SOCKET; type = HWLOC_OBJ_PACKAGE;
break; break;
case RelationCache: case RelationCache:
type = HWLOC_OBJ_CACHE; type = HWLOC_OBJ_CACHE;
@ -559,7 +559,7 @@ hwloc_look_windows(struct hwloc_backend *backend)
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset); hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) { switch (type) {
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
{ {
ULONGLONG avail; ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
@ -644,13 +644,13 @@ hwloc_look_windows(struct hwloc_backend *backend)
id = -1; id = -1;
switch (procInfo->Relationship) { switch (procInfo->Relationship) {
case RelationNumaNode: case RelationNumaNode:
type = HWLOC_OBJ_NODE; type = HWLOC_OBJ_NUMANODE;
num = 1; num = 1;
GroupMask = &procInfo->NumaNode.GroupMask; GroupMask = &procInfo->NumaNode.GroupMask;
id = procInfo->NumaNode.NodeNumber; id = procInfo->NumaNode.NodeNumber;
break; break;
case RelationProcessorPackage: case RelationProcessorPackage:
type = HWLOC_OBJ_SOCKET; type = HWLOC_OBJ_PACKAGE;
num = procInfo->Processor.GroupCount; num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask; GroupMask = procInfo->Processor.GroupMask;
break; break;
@ -695,7 +695,7 @@ hwloc_look_windows(struct hwloc_backend *backend)
hwloc_debug("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset); hwloc_debug("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) { switch (type) {
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
{ {
ULONGLONG avail; ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
@ -715,7 +715,6 @@ hwloc_look_windows(struct hwloc_backend *backend)
} }
case HWLOC_OBJ_CACHE: case HWLOC_OBJ_CACHE:
obj->attr->cache.size = procInfo->Cache.CacheSize; obj->attr->cache.size = procInfo->Cache.CacheSize;
obj->attr->cache.associativity = procInfo->Cache.Associativity;
obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ; obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ;
obj->attr->cache.linesize = procInfo->Cache.LineSize; obj->attr->cache.linesize = procInfo->Cache.LineSize;
obj->attr->cache.depth = procInfo->Cache.Level; obj->attr->cache.depth = procInfo->Cache.Level;
@ -806,6 +805,7 @@ static struct hwloc_disc_component hwloc_windows_disc_component = {
const struct hwloc_component hwloc_windows_component = { const struct hwloc_component hwloc_windows_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_windows_disc_component &hwloc_windows_disc_component

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2010-2014 Inria. All rights reserved. * Copyright © 2010-2015 Inria. All rights reserved.
* Copyright © 2010-2013 Université Bordeaux 1 * Copyright © 2010-2013 Université Bordeaux
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
* *
@ -22,7 +22,14 @@
#include <private/cpuid-x86.h> #include <private/cpuid-x86.h>
struct hwloc_x86_backend_data_s {
unsigned nbprocs;
hwloc_bitmap_t apicid_set;
int apicid_unique;
};
#define has_topoext(features) ((features)[6] & (1 << 22)) #define has_topoext(features) ((features)[6] & (1 << 22))
#define has_x2apic(features) ((features)[4] & (1 << 21))
struct cacheinfo { struct cacheinfo {
unsigned type; unsigned type;
@ -42,7 +49,7 @@ struct procinfo {
unsigned max_log_proc; unsigned max_log_proc;
unsigned max_nbcores; unsigned max_nbcores;
unsigned max_nbthreads; unsigned max_nbthreads;
unsigned socketid; unsigned packageid;
unsigned nodeid; unsigned nodeid;
unsigned unitid; unsigned unitid;
unsigned logprocid; unsigned logprocid;
@ -54,6 +61,7 @@ struct procinfo {
struct cacheinfo *cache; struct cacheinfo *cache;
char cpuvendor[13]; char cpuvendor[13];
char cpumodel[3*4*4+1]; char cpumodel[3*4*4+1];
unsigned cpustepping;
unsigned cpumodelnumber; unsigned cpumodelnumber;
unsigned cpufamilynumber; unsigned cpufamilynumber;
}; };
@ -64,7 +72,7 @@ enum cpuid_type {
unknown unknown
}; };
static void fill_amd_cache(struct procinfo *infos, unsigned level, unsigned cpuid) static void fill_amd_cache(struct procinfo *infos, unsigned level, int type, unsigned cpuid)
{ {
struct cacheinfo *cache; struct cacheinfo *cache;
unsigned cachenum; unsigned cachenum;
@ -83,7 +91,7 @@ static void fill_amd_cache(struct procinfo *infos, unsigned level, unsigned cpui
infos->cache = realloc(infos->cache, infos->numcaches*sizeof(*infos->cache)); infos->cache = realloc(infos->cache, infos->numcaches*sizeof(*infos->cache));
cache = &infos->cache[cachenum]; cache = &infos->cache[cachenum];
cache->type = 1; cache->type = type;
cache->level = level; cache->level = level;
if (level <= 2) if (level <= 2)
cache->nbthreads_sharing = 1; cache->nbthreads_sharing = 1;
@ -109,8 +117,9 @@ static void fill_amd_cache(struct procinfo *infos, unsigned level, unsigned cpui
/* Fetch information from the processor itself thanks to cpuid and store it in /* Fetch information from the processor itself thanks to cpuid and store it in
* infos for summarize to analyze them globally */ * infos for summarize to analyze them globally */
static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned highest_ext_cpuid, unsigned *features, enum cpuid_type cpuid_type) static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, unsigned highest_cpuid, unsigned highest_ext_cpuid, unsigned *features, enum cpuid_type cpuid_type)
{ {
struct hwloc_x86_backend_data_s *data = backend->private_data;
unsigned eax, ebx, ecx = 0, edx; unsigned eax, ebx, ecx = 0, edx;
unsigned cachenum; unsigned cachenum;
struct cacheinfo *cache; struct cacheinfo *cache;
@ -119,6 +128,17 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
infos->present = 1; infos->present = 1;
/* on return from this function, the following fields must be set in infos:
* packageid, nodeid, unitid, coreid, threadid, or -1
* apicid
* levels and levels slots in otherids[]
* numcaches and numcaches slots in caches[]
*
* max_log_proc, max_nbthreads, max_nbcores, logprocid
* are only used temporarily inside this function and its callees.
*/
/* Get apicid, max_log_proc, packageid, logprocid from cpuid 0x01 */
eax = 0x01; eax = 0x01;
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx); hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
infos->apicid = ebx >> 24; infos->apicid = ebx >> 24;
@ -127,32 +147,36 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
else else
infos->max_log_proc = 1; infos->max_log_proc = 1;
hwloc_debug("APIC ID 0x%02x max_log_proc %u\n", infos->apicid, infos->max_log_proc); hwloc_debug("APIC ID 0x%02x max_log_proc %u\n", infos->apicid, infos->max_log_proc);
infos->socketid = infos->apicid / infos->max_log_proc; infos->packageid = infos->apicid / infos->max_log_proc;
infos->logprocid = infos->apicid % infos->max_log_proc; infos->logprocid = infos->apicid % infos->max_log_proc;
hwloc_debug("phys %u thread %u\n", infos->socketid, infos->logprocid); hwloc_debug("phys %u thread %u\n", infos->packageid, infos->logprocid);
/* Get cpu model/family/stepping numbers from same cpuid */
_model = (eax>>4) & 0xf;
_extendedmodel = (eax>>16) & 0xf;
_family = (eax>>8) & 0xf;
_extendedfamily = (eax>>20) & 0xff;
if ((cpuid_type == intel || cpuid_type == amd) && _family == 0xf) {
infos->cpufamilynumber = _family + _extendedfamily;
} else {
infos->cpufamilynumber = _family;
}
if ((cpuid_type == intel && (_family == 0x6 || _family == 0xf))
|| (cpuid_type == amd && _family == 0xf)) {
infos->cpumodelnumber = _model + (_extendedmodel << 4);
} else {
infos->cpumodelnumber = _model;
}
infos->cpustepping = eax & 0xf;
/* Get cpu vendor string from cpuid 0x00 */
memset(regs, 0, sizeof(regs)); memset(regs, 0, sizeof(regs));
regs[0] = 0; regs[0] = 0;
hwloc_x86_cpuid(&regs[0], &regs[1], &regs[3], &regs[2]); hwloc_x86_cpuid(&regs[0], &regs[1], &regs[3], &regs[2]);
memcpy(infos->cpuvendor, regs+1, 4*3); memcpy(infos->cpuvendor, regs+1, 4*3);
infos->cpuvendor[12] = '\0'; /* infos was calloc'ed, already ends with \0 */
memset(regs, 0, sizeof(regs));
regs[0] = 1;
hwloc_x86_cpuid(&regs[0], &regs[1], &regs[2], &regs[3]);
_model = (regs[0]>>4) & 0xf;
_extendedmodel = (regs[0]>>16) & 0xf;
_family = (regs[0]>>8) & 0xf;
_extendedfamily = (regs[0]>>20) & 0xff;
if (!strncmp(infos->cpuvendor, "Genu", 4)
|| (!strncmp(infos->cpuvendor, "Auth", 4) && _family == 0xf)) {
infos->cpufamilynumber = _family + _extendedfamily;
infos->cpumodelnumber = _model + (_extendedmodel << 4);
} else {
infos->cpufamilynumber = _family;
infos->cpumodelnumber = _model;
}
/* Get cpu model string from cpuid 0x80000002-4 */
if (highest_ext_cpuid >= 0x80000004) { if (highest_ext_cpuid >= 0x80000004) {
memset(regs, 0, sizeof(regs)); memset(regs, 0, sizeof(regs));
regs[0] = 0x80000002; regs[0] = 0x80000002;
@ -164,11 +188,12 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
regs[0] = 0x80000004; regs[0] = 0x80000004;
hwloc_x86_cpuid(&regs[0], &regs[1], &regs[2], &regs[3]); hwloc_x86_cpuid(&regs[0], &regs[1], &regs[2], &regs[3]);
memcpy(infos->cpumodel + 4*4*2, regs, 4*4); memcpy(infos->cpumodel + 4*4*2, regs, 4*4);
infos->cpumodel[3*4*4] = 0; /* infos was calloc'ed, already ends with \0 */
} else }
infos->cpumodel[0] = 0;
/* Intel doesn't actually provide 0x80000008 information */ /* Get core/thread information from cpuid 0x80000008
* (not supported on Intel)
*/
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000008) { if (cpuid_type != intel && highest_ext_cpuid >= 0x80000008) {
unsigned coreidsize; unsigned coreidsize;
eax = 0x80000008; eax = 0x80000008;
@ -177,12 +202,19 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
hwloc_debug("core ID size: %u\n", coreidsize); hwloc_debug("core ID size: %u\n", coreidsize);
if (!coreidsize) { if (!coreidsize) {
infos->max_nbcores = (ecx & 0xff) + 1; infos->max_nbcores = (ecx & 0xff) + 1;
} else } else
infos->max_nbcores = 1 << coreidsize; infos->max_nbcores = 1 << coreidsize;
hwloc_debug("Thus max # of cores: %u\n", infos->max_nbcores); hwloc_debug("Thus max # of cores: %u\n", infos->max_nbcores);
/* Still no multithreaded AMD */ /* Still no multithreaded AMD */
infos->max_nbthreads = 1 ; infos->max_nbthreads = 1 ;
hwloc_debug("and max # of threads: %u\n", infos->max_nbthreads); hwloc_debug("and max # of threads: %u\n", infos->max_nbthreads);
/* The legacy max_log_proc is deprecated, it can be smaller than max_nbcores,
* which is the maximum number of cores that the processor could theoretically support
* (see "Multiple Core Calculation" in the AMD CPUID specification).
* Recompute packageid/logprocid/threadid/coreid accordingly.
*/
infos->packageid = infos->apicid / infos->max_nbcores;
infos->logprocid = infos->apicid % infos->max_nbcores;
infos->threadid = infos->logprocid % infos->max_nbthreads; infos->threadid = infos->logprocid % infos->max_nbthreads;
infos->coreid = infos->logprocid / infos->max_nbthreads; infos->coreid = infos->logprocid / infos->max_nbthreads;
hwloc_debug("this is thread %u of core %u\n", infos->threadid, infos->coreid); hwloc_debug("this is thread %u of core %u\n", infos->threadid, infos->coreid);
@ -191,7 +223,10 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
infos->numcaches = 0; infos->numcaches = 0;
infos->cache = NULL; infos->cache = NULL;
/* AMD topology extension */ /* Get apicid, nodeid, unitid from cpuid 0x8000001e
* and cache information from cpuid 0x8000001d
* (AMD topology extension)
*/
if (cpuid_type != intel && has_topoext(features)) { if (cpuid_type != intel && has_topoext(features)) {
unsigned apic_id, node_id, nodes_per_proc, unit_id, cores_per_unit; unsigned apic_id, node_id, nodes_per_proc, unit_id, cores_per_unit;
@ -254,23 +289,36 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
cache++; cache++;
} }
} else { } else {
/* Intel doesn't actually provide 0x80000005 information */ /* If there's no topoext,
* get cache information from cpuid 0x80000005 and 0x80000006
* (not supported on Intel)
*/
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000005) { if (cpuid_type != intel && highest_ext_cpuid >= 0x80000005) {
eax = 0x80000005; eax = 0x80000005;
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx); hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
fill_amd_cache(infos, 1, ecx); fill_amd_cache(infos, 1, 1, ecx); /* L1d */
fill_amd_cache(infos, 1, 2, edx); /* L1i */
} }
/* Intel doesn't actually provide 0x80000006 information */
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000006) { if (cpuid_type != intel && highest_ext_cpuid >= 0x80000006) {
eax = 0x80000006; eax = 0x80000006;
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx); hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
fill_amd_cache(infos, 2, ecx); if (ecx & 0xf000)
fill_amd_cache(infos, 3, edx); /* This is actually supported on Intel but LinePerTag isn't returned in bits 8-11.
* Could be useful if some Intels (at least before Core micro-architecture)
* support this leaf without leaf 0x4.
*/
fill_amd_cache(infos, 2, 3, ecx); /* L2u */
if (edx & 0xf000)
fill_amd_cache(infos, 3, 3, edx); /* L3u */
/* FIXME: AMD MagnyCours family 0x10 model 0x9 with 8 cores or more actually
* have the L3 split in two halves, and associativity is divided as well (48)
*/
} }
} }
/* AMD doesn't actually provide 0x04 information */ /* Get thread/core + cache information from cpuid 0x04
* (not supported on AMD)
*/
if (cpuid_type != amd && highest_cpuid >= 0x04) { if (cpuid_type != amd && highest_cpuid >= 0x04) {
for (cachenum = 0; ; cachenum++) { for (cachenum = 0; ; cachenum++) {
unsigned type; unsigned type;
@ -285,6 +333,16 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
if (type == 0) if (type == 0)
break; break;
infos->numcaches++; infos->numcaches++;
if (!cachenum) {
/* by the way, get thread/core information from the first cache */
infos->max_nbcores = ((eax >> 26) & 0x3f) + 1;
infos->max_nbthreads = infos->max_log_proc / infos->max_nbcores;
hwloc_debug("thus %u threads\n", infos->max_nbthreads);
infos->threadid = infos->logprocid % infos->max_nbthreads;
infos->coreid = infos->logprocid / infos->max_nbthreads;
hwloc_debug("this is thread %u of core %u\n", infos->threadid, infos->coreid);
}
} }
cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache)); cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache));
@ -304,7 +362,6 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
cache->type = type; cache->type = type;
cache->level = (eax >> 5) & 0x7; cache->level = (eax >> 5) & 0x7;
cache->nbthreads_sharing = ((eax >> 14) & 0xfff) + 1; cache->nbthreads_sharing = ((eax >> 14) & 0xfff) + 1;
infos->max_nbcores = ((eax >> 26) & 0x3f) + 1;
cache->linesize = linesize = (ebx & 0xfff) + 1; cache->linesize = linesize = (ebx & 0xfff) + 1;
cache->linepart = linepart = ((ebx >> 12) & 0x3ff) + 1; cache->linepart = linepart = ((ebx >> 12) & 0x3ff) + 1;
@ -318,17 +375,15 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
cache->size = linesize * linepart * ways * sets; cache->size = linesize * linepart * ways * sets;
hwloc_debug("cache %u type %u L%u t%u c%u linesize %lu linepart %lu ways %lu sets %lu, size %uKB\n", cachenum, cache->type, cache->level, cache->nbthreads_sharing, infos->max_nbcores, linesize, linepart, ways, sets, cache->size >> 10); hwloc_debug("cache %u type %u L%u t%u c%u linesize %lu linepart %lu ways %lu sets %lu, size %uKB\n", cachenum, cache->type, cache->level, cache->nbthreads_sharing, infos->max_nbcores, linesize, linepart, ways, sets, cache->size >> 10);
infos->max_nbthreads = infos->max_log_proc / infos->max_nbcores;
hwloc_debug("thus %u threads\n", infos->max_nbthreads);
infos->threadid = infos->logprocid % infos->max_nbthreads;
infos->coreid = infos->logprocid / infos->max_nbthreads;
hwloc_debug("this is thread %u of core %u\n", infos->threadid, infos->coreid);
cache++; cache++;
} }
} }
if (cpuid_type == intel && highest_cpuid >= 0x0b) { /* Get package/core/thread information from cpuid 0x0b
* (Intel x2APIC)
*/
if (cpuid_type == intel && has_x2apic(features)) {
unsigned level, apic_nextshift, apic_number, apic_type, apic_id = 0, apic_shift = 0, id; unsigned level, apic_nextshift, apic_number, apic_type, apic_id = 0, apic_shift = 0, id;
for (level = 0; ; level++) { for (level = 0; ; level++) {
ecx = level; ecx = level;
@ -368,12 +423,17 @@ static void look_proc(struct procinfo *infos, unsigned highest_cpuid, unsigned h
} }
apic_shift = apic_nextshift; apic_shift = apic_nextshift;
} }
infos->socketid = apic_id >> apic_shift; infos->apicid = apic_id;
hwloc_debug("x2APIC remainder: %d\n", infos->socketid); infos->packageid = apic_id >> apic_shift;
} else hwloc_debug("x2APIC remainder: %d\n", infos->packageid);
infos->otherids = NULL; hwloc_debug("this is thread %u of core %u\n", infos->threadid, infos->coreid);
} else }
infos->otherids = NULL; }
if (hwloc_bitmap_isset(data->apicid_set, infos->apicid))
data->apicid_unique = 0;
else
hwloc_bitmap_set(data->apicid_set, infos->apicid);
} }
static void static void
@ -381,25 +441,29 @@ hwloc_x86_add_cpuinfos(hwloc_obj_t obj, struct procinfo *info, int nodup)
{ {
char number[8]; char number[8];
hwloc_obj_add_info_nodup(obj, "CPUVendor", info->cpuvendor, nodup); hwloc_obj_add_info_nodup(obj, "CPUVendor", info->cpuvendor, nodup);
snprintf(number, sizeof(number), "%u", info->cpufamilynumber);
hwloc_obj_add_info_nodup(obj, "CPUFamilyNumber", number, nodup);
snprintf(number, sizeof(number), "%u", info->cpumodelnumber);
hwloc_obj_add_info_nodup(obj, "CPUModelNumber", number, nodup);
if (info->cpumodel[0]) { if (info->cpumodel[0]) {
const char *c = info->cpumodel; const char *c = info->cpumodel;
while (*c == ' ') while (*c == ' ')
c++; c++;
hwloc_obj_add_info_nodup(obj, "CPUModel", c, nodup); hwloc_obj_add_info_nodup(obj, "CPUModel", c, nodup);
} }
snprintf(number, sizeof(number), "%u", info->cpumodelnumber); snprintf(number, sizeof(number), "%u", info->cpustepping);
hwloc_obj_add_info_nodup(obj, "CPUModelNumber", number, nodup); hwloc_obj_add_info_nodup(obj, "CPUStepping", number, nodup);
snprintf(number, sizeof(number), "%u", info->cpufamilynumber);
hwloc_obj_add_info_nodup(obj, "CPUFamilyNumber", number, nodup);
} }
/* Analyse information stored in infos, and build/annotate topology levels accordingly */ /* Analyse information stored in infos, and build/annotate topology levels accordingly */
static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigned nbprocs, static void summarize(struct hwloc_backend *backend, struct procinfo *infos, int fulldiscovery)
int fulldiscovery)
{ {
struct hwloc_topology *topology = backend->topology;
struct hwloc_x86_backend_data_s *data = backend->private_data;
unsigned nbprocs = data->nbprocs;
hwloc_bitmap_t complete_cpuset = hwloc_bitmap_alloc(); hwloc_bitmap_t complete_cpuset = hwloc_bitmap_alloc();
unsigned i, j, l, level, type; unsigned i, j, l, level, type;
unsigned nbsockets = 0; unsigned nbpackages = 0;
int one = -1; int one = -1;
unsigned next_group_depth = topology->next_group_depth; unsigned next_group_depth = topology->next_group_depth;
@ -419,84 +483,84 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
* Only annotate existing objects for now. * Only annotate existing objects for now.
*/ */
/* Look for sockets */ /* Look for packages */
if (fulldiscovery) { if (fulldiscovery) {
hwloc_bitmap_t sockets_cpuset = hwloc_bitmap_dup(complete_cpuset); hwloc_bitmap_t packages_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t socket_cpuset; hwloc_bitmap_t package_cpuset;
hwloc_obj_t socket; hwloc_obj_t package;
while ((i = hwloc_bitmap_first(sockets_cpuset)) != (unsigned) -1) { while ((i = hwloc_bitmap_first(packages_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid; unsigned packageid = infos[i].packageid;
socket_cpuset = hwloc_bitmap_alloc(); package_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) { for (j = i; j < nbprocs; j++) {
if (infos[j].socketid == socketid) { if (infos[j].packageid == packageid) {
hwloc_bitmap_set(socket_cpuset, j); hwloc_bitmap_set(package_cpuset, j);
hwloc_bitmap_clr(sockets_cpuset, j); hwloc_bitmap_clr(packages_cpuset, j);
} }
} }
socket = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, socketid); package = hwloc_alloc_setup_object(HWLOC_OBJ_PACKAGE, packageid);
socket->cpuset = socket_cpuset; package->cpuset = package_cpuset;
hwloc_x86_add_cpuinfos(socket, &infos[i], 0); hwloc_x86_add_cpuinfos(package, &infos[i], 0);
hwloc_debug_1arg_bitmap("os socket %u has cpuset %s\n", hwloc_debug_1arg_bitmap("os package %u has cpuset %s\n",
socketid, socket_cpuset); packageid, package_cpuset);
hwloc_insert_object_by_cpuset(topology, socket); hwloc_insert_object_by_cpuset(topology, package);
nbsockets++; nbpackages++;
} }
hwloc_bitmap_free(sockets_cpuset); hwloc_bitmap_free(packages_cpuset);
} else { } else {
/* Annotate sockets previously-existing sockets */ /* Annotate packages previously-existing packages */
hwloc_obj_t socket = NULL; hwloc_obj_t package = NULL;
int same = 1; int same = 1;
nbsockets = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_SOCKET); nbpackages = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_PACKAGE);
/* check whether all sockets have the same info */ /* check whether all packages have the same info */
for(i=1; i<nbprocs; i++) { for(i=1; i<nbprocs; i++) {
if (strcmp(infos[i].cpumodel, infos[0].cpumodel)) { if (strcmp(infos[i].cpumodel, infos[0].cpumodel)) {
same = 0; same = 0;
break; break;
} }
} }
/* now iterate over sockets and annotate them */ /* now iterate over packages and annotate them */
while ((socket = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_SOCKET, socket)) != NULL) { while ((package = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PACKAGE, package)) != NULL) {
if (socket->os_index == (unsigned) -1) { if (package->os_index == (unsigned) -1) {
/* try to fix the socket OS index if unknown. /* try to fix the package OS index if unknown.
* FIXME: ideally, we should check all bits in case x86 and the native backend disagree. * FIXME: ideally, we should check all bits in case x86 and the native backend disagree.
*/ */
for(i=0; i<nbprocs; i++) { for(i=0; i<nbprocs; i++) {
if (hwloc_bitmap_isset(socket->cpuset, i)) { if (hwloc_bitmap_isset(package->cpuset, i)) {
socket->os_index = infos[i].socketid; package->os_index = infos[i].packageid;
break; break;
} }
} }
} }
for(i=0; i<nbprocs; i++) { for(i=0; i<nbprocs; i++) {
/* if there's a single socket, it's the one we want. /* if there's a single package, it's the one we want.
* if the index is ok, it's the one we want. * if the index is ok, it's the one we want.
* if the index is unknown but all sockets have the same id, that's fine * if the index is unknown but all packages have the same id, that's fine
*/ */
if (nbsockets == 1 || infos[i].socketid == socket->os_index || (same && socket->os_index == (unsigned) -1)) { if (nbpackages == 1 || infos[i].packageid == package->os_index || (same && package->os_index == (unsigned) -1)) {
hwloc_x86_add_cpuinfos(socket, &infos[i], 1); hwloc_x86_add_cpuinfos(package, &infos[i], 1);
break; break;
} }
} }
} }
} }
/* If there was no socket, annotate the Machine instead */ /* If there was no package, annotate the Machine instead */
if ((!nbsockets) && infos[0].cpumodel[0]) { if ((!nbpackages) && infos[0].cpumodel[0]) {
hwloc_x86_add_cpuinfos(hwloc_get_root_obj(topology), &infos[0], 1); hwloc_x86_add_cpuinfos(hwloc_get_root_obj(topology), &infos[0], 1);
} }
/* Look for Numa nodes inside sockets */ /* Look for Numa nodes inside packages */
if (fulldiscovery) { if (fulldiscovery) {
hwloc_bitmap_t nodes_cpuset = hwloc_bitmap_dup(complete_cpuset); hwloc_bitmap_t nodes_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t node_cpuset; hwloc_bitmap_t node_cpuset;
hwloc_obj_t node; hwloc_obj_t node;
while ((i = hwloc_bitmap_first(nodes_cpuset)) != (unsigned) -1) { while ((i = hwloc_bitmap_first(nodes_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid; unsigned packageid = infos[i].packageid;
unsigned nodeid = infos[i].nodeid; unsigned nodeid = infos[i].nodeid;
if (nodeid == (unsigned)-1) { if (nodeid == (unsigned)-1) {
@ -511,12 +575,12 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
continue; continue;
} }
if (infos[j].socketid == socketid && infos[j].nodeid == nodeid) { if (infos[j].packageid == packageid && infos[j].nodeid == nodeid) {
hwloc_bitmap_set(node_cpuset, j); hwloc_bitmap_set(node_cpuset, j);
hwloc_bitmap_clr(nodes_cpuset, j); hwloc_bitmap_clr(nodes_cpuset, j);
} }
} }
node = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, nodeid); node = hwloc_alloc_setup_object(HWLOC_OBJ_NUMANODE, nodeid);
node->cpuset = node_cpuset; node->cpuset = node_cpuset;
node->nodeset = hwloc_bitmap_alloc(); node->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(node->nodeset, nodeid); hwloc_bitmap_set(node->nodeset, nodeid);
@ -527,14 +591,14 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
hwloc_bitmap_free(nodes_cpuset); hwloc_bitmap_free(nodes_cpuset);
} }
/* Look for Compute units inside sockets */ /* Look for Compute units inside packages */
if (fulldiscovery) { if (fulldiscovery) {
hwloc_bitmap_t units_cpuset = hwloc_bitmap_dup(complete_cpuset); hwloc_bitmap_t units_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t unit_cpuset; hwloc_bitmap_t unit_cpuset;
hwloc_obj_t unit; hwloc_obj_t unit;
while ((i = hwloc_bitmap_first(units_cpuset)) != (unsigned) -1) { while ((i = hwloc_bitmap_first(units_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid; unsigned packageid = infos[i].packageid;
unsigned unitid = infos[i].unitid; unsigned unitid = infos[i].unitid;
if (unitid == (unsigned)-1) { if (unitid == (unsigned)-1) {
@ -549,7 +613,7 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
continue; continue;
} }
if (infos[j].socketid == socketid && infos[j].unitid == unitid) { if (infos[j].packageid == packageid && infos[j].unitid == unitid) {
hwloc_bitmap_set(unit_cpuset, j); hwloc_bitmap_set(unit_cpuset, j);
hwloc_bitmap_clr(units_cpuset, j); hwloc_bitmap_clr(units_cpuset, j);
} }
@ -603,7 +667,7 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
hwloc_obj_t core; hwloc_obj_t core;
while ((i = hwloc_bitmap_first(cores_cpuset)) != (unsigned) -1) { while ((i = hwloc_bitmap_first(cores_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid; unsigned packageid = infos[i].packageid;
unsigned coreid = infos[i].coreid; unsigned coreid = infos[i].coreid;
if (coreid == (unsigned) -1) { if (coreid == (unsigned) -1) {
@ -618,7 +682,7 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
continue; continue;
} }
if (infos[j].socketid == socketid && infos[j].coreid == coreid) { if (infos[j].packageid == packageid && infos[j].coreid == coreid) {
hwloc_bitmap_set(core_cpuset, j); hwloc_bitmap_set(core_cpuset, j);
hwloc_bitmap_clr(cores_cpuset, j); hwloc_bitmap_clr(cores_cpuset, j);
} }
@ -650,7 +714,7 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
hwloc_obj_t cache; hwloc_obj_t cache;
while ((i = hwloc_bitmap_first(caches_cpuset)) != (unsigned) -1) { while ((i = hwloc_bitmap_first(caches_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid; unsigned packageid = infos[i].packageid;
for (l = 0; l < infos[i].numcaches; l++) { for (l = 0; l < infos[i].numcaches; l++) {
if (infos[i].cache[l].level == level && infos[i].cache[l].type == type) if (infos[i].cache[l].level == level && infos[i].cache[l].type == type)
@ -678,7 +742,7 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
hwloc_bitmap_clr(caches_cpuset, j); hwloc_bitmap_clr(caches_cpuset, j);
continue; continue;
} }
if (infos[j].socketid == socketid && infos[j].apicid / infos[j].cache[l2].nbthreads_sharing == cacheid) { if (infos[j].packageid == packageid && infos[j].apicid / infos[j].cache[l2].nbthreads_sharing == cacheid) {
hwloc_bitmap_set(cache_cpuset, j); hwloc_bitmap_set(cache_cpuset, j);
hwloc_bitmap_clr(caches_cpuset, j); hwloc_bitmap_clr(caches_cpuset, j);
} }
@ -722,11 +786,14 @@ static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigne
} }
static int static int
look_procs(struct hwloc_topology *topology, unsigned nbprocs, struct procinfo *infos, int fulldiscovery, look_procs(struct hwloc_backend *backend, struct procinfo *infos, int fulldiscovery,
unsigned highest_cpuid, unsigned highest_ext_cpuid, unsigned *features, enum cpuid_type cpuid_type, unsigned highest_cpuid, unsigned highest_ext_cpuid, unsigned *features, enum cpuid_type cpuid_type,
int (*get_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags), int (*get_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags),
int (*set_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags)) int (*set_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags))
{ {
struct hwloc_x86_backend_data_s *data = backend->private_data;
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = data->nbprocs;
hwloc_bitmap_t orig_cpuset = hwloc_bitmap_alloc(); hwloc_bitmap_t orig_cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_t set; hwloc_bitmap_t set;
unsigned i; unsigned i;
@ -745,14 +812,16 @@ look_procs(struct hwloc_topology *topology, unsigned nbprocs, struct procinfo *i
hwloc_debug("could not bind to CPU%d: %s\n", i, strerror(errno)); hwloc_debug("could not bind to CPU%d: %s\n", i, strerror(errno));
continue; continue;
} }
look_proc(&infos[i], highest_cpuid, highest_ext_cpuid, features, cpuid_type); look_proc(backend, &infos[i], highest_cpuid, highest_ext_cpuid, features, cpuid_type);
} }
set_cpubind(topology, orig_cpuset, 0); set_cpubind(topology, orig_cpuset, 0);
hwloc_bitmap_free(set); hwloc_bitmap_free(set);
hwloc_bitmap_free(orig_cpuset); hwloc_bitmap_free(orig_cpuset);
summarize(topology, infos, nbprocs, fulldiscovery); if (!data->apicid_unique)
fulldiscovery = 0;
summarize(backend, infos, fulldiscovery);
return fulldiscovery; /* success, but objects added only if fulldiscovery */ return fulldiscovery; /* success, but objects added only if fulldiscovery */
} }
@ -801,8 +870,10 @@ static int fake_set_cpubind(hwloc_topology_t topology __hwloc_attribute_unused,
} }
static static
int hwloc_look_x86(struct hwloc_topology *topology, unsigned nbprocs, int fulldiscovery) int hwloc_look_x86(struct hwloc_backend *backend, int fulldiscovery)
{ {
struct hwloc_x86_backend_data_s *data = backend->private_data;
unsigned nbprocs = data->nbprocs;
unsigned eax, ebx, ecx = 0, edx; unsigned eax, ebx, ecx = 0, edx;
unsigned i; unsigned i;
unsigned highest_cpuid; unsigned highest_cpuid;
@ -845,7 +916,7 @@ int hwloc_look_x86(struct hwloc_topology *topology, unsigned nbprocs, int fulldi
goto out; goto out;
for (i = 0; i < nbprocs; i++) { for (i = 0; i < nbprocs; i++) {
infos[i].nodeid = (unsigned) -1; infos[i].nodeid = (unsigned) -1;
infos[i].socketid = (unsigned) -1; infos[i].packageid = (unsigned) -1;
infos[i].unitid = (unsigned) -1; infos[i].unitid = (unsigned) -1;
infos[i].coreid = (unsigned) -1; infos[i].coreid = (unsigned) -1;
infos[i].threadid = (unsigned) -1; infos[i].threadid = (unsigned) -1;
@ -890,7 +961,7 @@ int hwloc_look_x86(struct hwloc_topology *topology, unsigned nbprocs, int fulldi
hwloc_x86_os_state_save(&os_state); hwloc_x86_os_state_save(&os_state);
ret = look_procs(topology, nbprocs, infos, fulldiscovery, ret = look_procs(backend, infos, fulldiscovery,
highest_cpuid, highest_ext_cpuid, features, cpuid_type, highest_cpuid, highest_ext_cpuid, features, cpuid_type,
get_cpubind, set_cpubind); get_cpubind, set_cpubind);
if (ret >= 0) if (ret >= 0)
@ -899,8 +970,8 @@ int hwloc_look_x86(struct hwloc_topology *topology, unsigned nbprocs, int fulldi
if (nbprocs == 1) { if (nbprocs == 1) {
/* only one processor, no need to bind */ /* only one processor, no need to bind */
look_proc(&infos[0], highest_cpuid, highest_ext_cpuid, features, cpuid_type); look_proc(backend, &infos[0], highest_cpuid, highest_ext_cpuid, features, cpuid_type);
summarize(topology, infos, nbprocs, fulldiscovery); summarize(backend, infos, fulldiscovery);
ret = fulldiscovery; ret = fulldiscovery;
} }
@ -919,11 +990,13 @@ out:
static int static int
hwloc_x86_discover(struct hwloc_backend *backend) hwloc_x86_discover(struct hwloc_backend *backend)
{ {
struct hwloc_x86_backend_data_s *data = backend->private_data;
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
int alreadypus = 0; int alreadypus = 0;
int ret; int ret;
data->nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->is_thissystem) { if (!topology->is_thissystem) {
hwloc_debug("%s", "\nno x86 detection (not thissystem)\n"); hwloc_debug("%s", "\nno x86 detection (not thissystem)\n");
return 0; return 0;
@ -931,14 +1004,14 @@ hwloc_x86_discover(struct hwloc_backend *backend)
if (topology->levels[0][0]->cpuset) { if (topology->levels[0][0]->cpuset) {
/* somebody else discovered things */ /* somebody else discovered things */
if (topology->nb_levels == 2 && topology->level_nbobjects[1] == nbprocs) { if (topology->nb_levels == 2 && topology->level_nbobjects[1] == data->nbprocs) {
/* only PUs were discovered, as much as we would, complete the topology with everything else */ /* only PUs were discovered, as much as we would, complete the topology with everything else */
alreadypus = 1; alreadypus = 1;
goto fulldiscovery; goto fulldiscovery;
} }
/* several object types were added, we can't easily complete, just annotate a bit */ /* several object types were added, we can't easily complete, just annotate a bit */
ret = hwloc_look_x86(topology, nbprocs, 0); ret = hwloc_look_x86(backend, 0);
if (ret) if (ret)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86"); hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86");
return 0; return 0;
@ -948,11 +1021,11 @@ hwloc_x86_discover(struct hwloc_backend *backend)
} }
fulldiscovery: fulldiscovery:
hwloc_look_x86(topology, nbprocs, 1); hwloc_look_x86(backend, 1);
/* if failed, just continue and create PUs */ /* if failed, just continue and create PUs */
if (!alreadypus) if (!alreadypus)
hwloc_setup_pu_level(topology, nbprocs); hwloc_setup_pu_level(topology, data->nbprocs);
hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86"); hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86");
@ -969,6 +1042,14 @@ fulldiscovery:
return 1; return 1;
} }
static void
hwloc_x86_backend_disable(struct hwloc_backend *backend)
{
struct hwloc_x86_backend_data_s *data = backend->private_data;
hwloc_bitmap_free(data->apicid_set);
free(data);
}
static struct hwloc_backend * static struct hwloc_backend *
hwloc_x86_component_instantiate(struct hwloc_disc_component *component, hwloc_x86_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
@ -976,13 +1057,33 @@ hwloc_x86_component_instantiate(struct hwloc_disc_component *component,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
struct hwloc_x86_backend_data_s *data;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
if (!backend) if (!backend)
return NULL; goto out;
data = malloc(sizeof(*data));
if (!data) {
errno = ENOMEM;
goto out_with_backend;
}
backend->private_data = data;
backend->flags = HWLOC_BACKEND_FLAG_NEED_LEVELS; backend->flags = HWLOC_BACKEND_FLAG_NEED_LEVELS;
backend->discover = hwloc_x86_discover; backend->discover = hwloc_x86_discover;
backend->disable = hwloc_x86_backend_disable;
/* default values */
data->apicid_set = hwloc_bitmap_alloc();
data->apicid_unique = 1;
return backend; return backend;
out_with_backend:
free(backend);
out:
return NULL;
} }
static struct hwloc_disc_component hwloc_x86_disc_component = { static struct hwloc_disc_component hwloc_x86_disc_component = {
@ -996,6 +1097,7 @@ static struct hwloc_disc_component hwloc_x86_disc_component = {
const struct hwloc_component hwloc_x86_component = { const struct hwloc_component hwloc_x86_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_x86_disc_component &hwloc_x86_disc_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -41,7 +41,7 @@ typedef struct hwloc__libxml_import_state_data_s {
xmlNode *node; /* current libxml node, always valid */ xmlNode *node; /* current libxml node, always valid */
xmlNode *child; /* last processed child, or NULL if none yet */ xmlNode *child; /* last processed child, or NULL if none yet */
xmlAttr *attr; /* last processed attribute, or NULL if none yet */ xmlAttr *attr; /* last processed attribute, or NULL if none yet */
} * hwloc__libxml_import_state_data_t; } __hwloc_attribute_may_alias * hwloc__libxml_import_state_data_t;
static int static int
hwloc__libxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep) hwloc__libxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep)
@ -86,12 +86,7 @@ hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__libxml_import_state_data_t lchildstate = (void*) childstate->data; hwloc__libxml_import_state_data_t lchildstate = (void*) childstate->data;
xmlNode *child; xmlNode *child;
childstate->parent = state; childstate->parent = state;
childstate->next_attr = state->next_attr; childstate->global = state->global;
childstate->find_child = state->find_child;
childstate->close_tag = state->close_tag;
childstate->close_child = state->close_child;
childstate->get_content = state->get_content;
childstate->close_content = state->close_content;
if (!lstate->child) if (!lstate->child)
return 0; return 0;
child = lstate->child->next; child = lstate->child->next;
@ -182,12 +177,12 @@ hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
goto failed; goto failed;
} }
state->next_attr = hwloc__libxml_import_next_attr; state->global->next_attr = hwloc__libxml_import_next_attr;
state->find_child = hwloc__libxml_import_find_child; state->global->find_child = hwloc__libxml_import_find_child;
state->close_tag = hwloc__libxml_import_close_tag; state->global->close_tag = hwloc__libxml_import_close_tag;
state->close_child = hwloc__libxml_import_close_child; state->global->close_child = hwloc__libxml_import_close_child;
state->get_content = hwloc__libxml_import_get_content; state->global->get_content = hwloc__libxml_import_get_content;
state->close_content = hwloc__libxml_import_close_content; state->global->close_content = hwloc__libxml_import_close_content;
state->parent = NULL; state->parent = NULL;
lstate->node = root_node; lstate->node = root_node;
lstate->child = root_node->children; lstate->child = root_node->children;
@ -199,22 +194,16 @@ hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
} }
static int static int
hwloc_libxml_import_diff(const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *firstdiffp, char **refnamep) hwloc_libxml_import_diff(struct hwloc__xml_import_state_s *state, const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *firstdiffp, char **refnamep)
{ {
struct hwloc__xml_import_state_s state; hwloc__libxml_import_state_data_t lstate = (void*) state->data;
hwloc__libxml_import_state_data_t lstate = (void*) state.data;
char *refname = NULL; char *refname = NULL;
xmlDoc *doc = NULL; xmlDoc *doc = NULL;
xmlNode* root_node; xmlNode* root_node;
xmlDtd *dtd; xmlDtd *dtd;
int ret; int ret;
assert(sizeof(*lstate) <= sizeof(state.data)); assert(sizeof(*lstate) <= sizeof(state->data));
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0) {
errno = ENOSYS;
return -1;
}
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
hwloc_libxml2_disable_stderrwarnings(); hwloc_libxml2_disable_stderrwarnings();
@ -252,20 +241,20 @@ hwloc_libxml_import_diff(const char *xmlpath, const char *xmlbuffer, int xmlbufl
goto out_with_doc; goto out_with_doc;
} }
state.next_attr = hwloc__libxml_import_next_attr; state->global->next_attr = hwloc__libxml_import_next_attr;
state.find_child = hwloc__libxml_import_find_child; state->global->find_child = hwloc__libxml_import_find_child;
state.close_tag = hwloc__libxml_import_close_tag; state->global->close_tag = hwloc__libxml_import_close_tag;
state.close_child = hwloc__libxml_import_close_child; state->global->close_child = hwloc__libxml_import_close_child;
state.get_content = hwloc__libxml_import_get_content; state->global->get_content = hwloc__libxml_import_get_content;
state.close_content = hwloc__libxml_import_close_content; state->global->close_content = hwloc__libxml_import_close_content;
state.parent = NULL; state->parent = NULL;
lstate->node = root_node; lstate->node = root_node;
lstate->child = root_node->children; lstate->child = root_node->children;
lstate->attr = NULL; lstate->attr = NULL;
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state.next_attr(&state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "refname")) { if (!strcmp(attrname, "refname")) {
free(refname); free(refname);
@ -274,7 +263,7 @@ hwloc_libxml_import_diff(const char *xmlpath, const char *xmlbuffer, int xmlbufl
goto out_with_doc; goto out_with_doc;
} }
ret = hwloc__xml_import_diff(&state, firstdiffp); ret = hwloc__xml_import_diff(state, firstdiffp);
if (refnamep && !ret) if (refnamep && !ret)
*refnamep = refname; *refnamep = refname;
else else
@ -305,11 +294,6 @@ hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
{ {
xmlDoc *doc = NULL; xmlDoc *doc = NULL;
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0) {
errno = ENOSYS;
return -1;
}
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
hwloc_libxml2_disable_stderrwarnings(); hwloc_libxml2_disable_stderrwarnings();
@ -340,7 +324,7 @@ hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
typedef struct hwloc__libxml_export_state_data_s { typedef struct hwloc__libxml_export_state_data_s {
xmlNodePtr current_node; /* current node to output */ xmlNodePtr current_node; /* current node to output */
} * hwloc__libxml_export_state_data_t; } __hwloc_attribute_may_alias * hwloc__libxml_export_state_data_t;
static void static void
hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate, hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
@ -418,11 +402,6 @@ hwloc_libxml_export_file(hwloc_topology_t topology, const char *filename)
xmlDocPtr doc; xmlDocPtr doc;
int ret; int ret;
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0) {
errno = ENOSYS;
return -1;
}
errno = 0; /* set to 0 so that we know if libxml2 changed it */ errno = 0; /* set to 0 so that we know if libxml2 changed it */
doc = hwloc__libxml2_prepare_export(topology); doc = hwloc__libxml2_prepare_export(topology);
@ -443,11 +422,6 @@ hwloc_libxml_export_buffer(hwloc_topology_t topology, char **xmlbuffer, int *buf
{ {
xmlDocPtr doc; xmlDocPtr doc;
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0) {
errno = ENOSYS;
return -1;
}
doc = hwloc__libxml2_prepare_export(topology); doc = hwloc__libxml2_prepare_export(topology);
xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1); xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
xmlFreeDoc(doc); xmlFreeDoc(doc);
@ -495,11 +469,6 @@ hwloc_libxml_export_diff_file(hwloc_topology_diff_t diff, const char *refname, c
xmlDocPtr doc; xmlDocPtr doc;
int ret; int ret;
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0) {
errno = ENOSYS;
return -1;
}
errno = 0; /* set to 0 so that we know if libxml2 changed it */ errno = 0; /* set to 0 so that we know if libxml2 changed it */
doc = hwloc__libxml2_prepare_export_diff(diff, refname); doc = hwloc__libxml2_prepare_export_diff(diff, refname);
@ -520,11 +489,6 @@ hwloc_libxml_export_diff_buffer(hwloc_topology_diff_t diff, const char *refname,
{ {
xmlDocPtr doc; xmlDocPtr doc;
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0) {
errno = ENOSYS;
return -1;
}
doc = hwloc__libxml2_prepare_export_diff(diff, refname); doc = hwloc__libxml2_prepare_export_diff(diff, refname);
xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1); xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
xmlFreeDoc(doc); xmlFreeDoc(doc);
@ -556,12 +520,23 @@ static struct hwloc_xml_component hwloc_libxml_xml_component = {
&hwloc_xml_libxml_callbacks &hwloc_xml_libxml_callbacks
}; };
static int
hwloc_xml_libxml_component_init(unsigned long flags)
{
if (flags)
return -1;
if (hwloc_plugin_check_namespace("xml_libxml", "hwloc__xml_verbose") < 0)
return -1;
return 0;
}
#ifdef HWLOC_INSIDE_PLUGIN #ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_libxml_component; HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_libxml_component;
#endif #endif
const struct hwloc_component hwloc_xml_libxml_component = { const struct hwloc_component hwloc_xml_libxml_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
hwloc_xml_libxml_component_init, NULL,
HWLOC_COMPONENT_TYPE_XML, HWLOC_COMPONENT_TYPE_XML,
0, 0,
&hwloc_libxml_xml_component &hwloc_libxml_xml_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -36,7 +36,7 @@ typedef struct hwloc__nolibxml_import_state_data_s {
char *attrbuffer; /* buffer containing the next attribute of the current node */ char *attrbuffer; /* buffer containing the next attribute of the current node */
char *tagname; /* tag name of the current node */ char *tagname; /* tag name of the current node */
int closed; /* set if the current node is auto-closing */ int closed; /* set if the current node is auto-closing */
} * hwloc__nolibxml_import_state_data_t; } __hwloc_attribute_may_alias * hwloc__nolibxml_import_state_data_t;
static char * static char *
hwloc__nolibxml_import_ignore_spaces(char *buffer) hwloc__nolibxml_import_ignore_spaces(char *buffer)
@ -119,12 +119,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
int namelen; int namelen;
childstate->parent = state; childstate->parent = state;
childstate->next_attr = state->next_attr; childstate->global = state->global;
childstate->find_child = state->find_child;
childstate->close_tag = state->close_tag;
childstate->close_child = state->close_child;
childstate->get_content = state->get_content;
childstate->close_content = state->close_content;
/* auto-closed tags have no children */ /* auto-closed tags have no children */
if (nstate->closed) if (nstate->closed)
@ -274,12 +269,12 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
if (strncmp(buffer, "<topology>", 10)) if (strncmp(buffer, "<topology>", 10))
goto failed; goto failed;
state->next_attr = hwloc__nolibxml_import_next_attr; state->global->next_attr = hwloc__nolibxml_import_next_attr;
state->find_child = hwloc__nolibxml_import_find_child; state->global->find_child = hwloc__nolibxml_import_find_child;
state->close_tag = hwloc__nolibxml_import_close_tag; state->global->close_tag = hwloc__nolibxml_import_close_tag;
state->close_child = hwloc__nolibxml_import_close_child; state->global->close_child = hwloc__nolibxml_import_close_child;
state->get_content = hwloc__nolibxml_import_get_content; state->global->get_content = hwloc__nolibxml_import_get_content;
state->close_content = hwloc__nolibxml_import_close_content; state->global->close_content = hwloc__nolibxml_import_close_content;
state->parent = NULL; state->parent = NULL;
nstate->closed = 0; nstate->closed = 0;
nstate->tagbuffer = buffer+10; nstate->tagbuffer = buffer+10;
@ -408,17 +403,18 @@ out:
} }
static int static int
hwloc_nolibxml_import_diff(const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen,
hwloc_topology_diff_t *firstdiffp, char **refnamep) hwloc_topology_diff_t *firstdiffp, char **refnamep)
{ {
struct hwloc__xml_import_state_s state, childstate; hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
hwloc__nolibxml_import_state_data_t nstate = (void*) state.data; struct hwloc__xml_import_state_s childstate;
char *refname = NULL; char *refname = NULL;
char *buffer, *tmp, *tag; char *buffer, *tmp, *tag;
size_t buflen; size_t buflen;
int ret; int ret;
assert(sizeof(*nstate) <= sizeof(state.data)); assert(sizeof(*nstate) <= sizeof(state->data));
if (xmlbuffer) { if (xmlbuffer) {
buffer = malloc(xmlbuflen); buffer = malloc(xmlbuflen);
@ -442,20 +438,20 @@ hwloc_nolibxml_import_diff(const char *xmlpath, const char *xmlbuffer, int xmlbu
tmp++; tmp++;
} }
state.next_attr = hwloc__nolibxml_import_next_attr; state->global->next_attr = hwloc__nolibxml_import_next_attr;
state.find_child = hwloc__nolibxml_import_find_child; state->global->find_child = hwloc__nolibxml_import_find_child;
state.close_tag = hwloc__nolibxml_import_close_tag; state->global->close_tag = hwloc__nolibxml_import_close_tag;
state.close_child = hwloc__nolibxml_import_close_child; state->global->close_child = hwloc__nolibxml_import_close_child;
state.get_content = hwloc__nolibxml_import_get_content; state->global->get_content = hwloc__nolibxml_import_get_content;
state.close_content = hwloc__nolibxml_import_close_content; state->global->close_content = hwloc__nolibxml_import_close_content;
state.parent = NULL; state->parent = NULL;
nstate->closed = 0; nstate->closed = 0;
nstate->tagbuffer = tmp; nstate->tagbuffer = tmp;
nstate->tagname = NULL; nstate->tagname = NULL;
nstate->attrbuffer = NULL; nstate->attrbuffer = NULL;
/* find root */ /* find root */
ret = hwloc__nolibxml_import_find_child(&state, &childstate, &tag); ret = hwloc__nolibxml_import_find_child(state, &childstate, &tag);
if (ret < 0) if (ret < 0)
goto out_with_buffer; goto out_with_buffer;
if (strcmp(tag, "topologydiff")) if (strcmp(tag, "topologydiff"))
@ -498,7 +494,7 @@ typedef struct hwloc__nolibxml_export_state_data_s {
unsigned indent; /* indentation level for the next line */ unsigned indent; /* indentation level for the next line */
unsigned nr_children; unsigned nr_children;
unsigned has_content; unsigned has_content;
} * hwloc__nolibxml_export_state_data_t; } __hwloc_attribute_may_alias * hwloc__nolibxml_export_state_data_t;
static void static void
hwloc__nolibxml_export_update_buffer(hwloc__nolibxml_export_state_data_t ndata, int res) hwloc__nolibxml_export_update_buffer(hwloc__nolibxml_export_state_data_t ndata, int res)
@ -847,6 +843,7 @@ static struct hwloc_xml_component hwloc_nolibxml_xml_component = {
const struct hwloc_component hwloc_xml_nolibxml_component = { const struct hwloc_component hwloc_xml_nolibxml_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_XML, HWLOC_COMPONENT_TYPE_XML,
0, 0,
&hwloc_nolibxml_xml_component &hwloc_nolibxml_xml_component

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1 * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -19,7 +19,7 @@ hwloc__xml_verbose(void)
static int first = 1; static int first = 1;
static int verbose = 0; static int verbose = 0;
if (first) { if (first) {
char *env = getenv("HWLOC_XML_VERBOSE"); const char *env = getenv("HWLOC_XML_VERBOSE");
if (env) if (env)
verbose = atoi(env); verbose = atoi(env);
first = 0; first = 0;
@ -27,6 +27,34 @@ hwloc__xml_verbose(void)
return verbose; return verbose;
} }
static int
hwloc_nolibxml_import(void)
{
static int first = 1;
static int nolibxml = 0;
if (first) {
const char *env = getenv("HWLOC_NO_LIBXML_IMPORT");
if (env)
nolibxml = atoi(env);
first = 0;
}
return nolibxml;
}
static int
hwloc_nolibxml_export(void)
{
static int first = 1;
static int nolibxml = 0;
if (first) {
const char *env = getenv("HWLOC_NO_LIBXML_EXPORT");
if (env)
nolibxml = atoi(env);
first = 0;
}
return nolibxml;
}
/********************************* /*********************************
********* XML callbacks ********* ********* XML callbacks *********
*********************************/ *********************************/
@ -51,7 +79,7 @@ hwloc_xml_callbacks_reset(void)
{ {
hwloc_nolibxml_callbacks = NULL; hwloc_nolibxml_callbacks = NULL;
hwloc_libxml_callbacks = NULL; hwloc_libxml_callbacks = NULL;
} }
/************************************************ /************************************************
********* XML import (common routines) ********* ********* XML import (common routines) *********
@ -59,7 +87,8 @@ hwloc_xml_callbacks_reset(void)
static void static void
hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_unused, struct hwloc_obj *obj, hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_unused, struct hwloc_obj *obj,
const char *name, const char *value) const char *name, const char *value,
hwloc__xml_import_state_t state)
{ {
if (!strcmp(name, "type")) { if (!strcmp(name, "type")) {
/* already handled */ /* already handled */
@ -99,7 +128,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
if (obj->type == HWLOC_OBJ_CACHE) if (obj->type == HWLOC_OBJ_CACHE)
obj->attr->cache.size = lvalue; obj->attr->cache.size = lvalue;
else if (hwloc__xml_verbose()) else if (hwloc__xml_verbose())
fprintf(stderr, "ignoring cache_size attribute for non-cache object type\n"); fprintf(stderr, "%s: ignoring cache_size attribute for non-cache object type\n",
state->global->msgprefix);
} }
else if (!strcmp(name, "cache_linesize")) { else if (!strcmp(name, "cache_linesize")) {
@ -107,7 +137,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
if (obj->type == HWLOC_OBJ_CACHE) if (obj->type == HWLOC_OBJ_CACHE)
obj->attr->cache.linesize = lvalue; obj->attr->cache.linesize = lvalue;
else if (hwloc__xml_verbose()) else if (hwloc__xml_verbose())
fprintf(stderr, "ignoring cache_linesize attribute for non-cache object type\n"); fprintf(stderr, "%s: ignoring cache_linesize attribute for non-cache object type\n",
state->global->msgprefix);
} }
else if (!strcmp(name, "cache_associativity")) { else if (!strcmp(name, "cache_associativity")) {
@ -115,7 +146,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
if (obj->type == HWLOC_OBJ_CACHE) if (obj->type == HWLOC_OBJ_CACHE)
obj->attr->cache.associativity = lvalue; obj->attr->cache.associativity = lvalue;
else if (hwloc__xml_verbose()) else if (hwloc__xml_verbose())
fprintf(stderr, "ignoring cache_associativity attribute for non-cache object type\n"); fprintf(stderr, "%s: ignoring cache_associativity attribute for non-cache object type\n",
state->global->msgprefix);
} }
else if (!strcmp(name, "cache_type")) { else if (!strcmp(name, "cache_type")) {
@ -126,9 +158,11 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
|| lvalue == HWLOC_OBJ_CACHE_INSTRUCTION) || lvalue == HWLOC_OBJ_CACHE_INSTRUCTION)
obj->attr->cache.type = (hwloc_obj_cache_type_t) lvalue; obj->attr->cache.type = (hwloc_obj_cache_type_t) lvalue;
else else
fprintf(stderr, "ignoring invalid cache_type attribute %ld\n", lvalue); fprintf(stderr, "%s: ignoring invalid cache_type attribute %ld\n",
state->global->msgprefix, lvalue);
} else if (hwloc__xml_verbose()) } else if (hwloc__xml_verbose())
fprintf(stderr, "ignoring cache_type attribute for non-cache object type\n"); fprintf(stderr, "%s: ignoring cache_type attribute for non-cache object type\n",
state->global->msgprefix);
} }
else if (!strcmp(name, "local_memory")) else if (!strcmp(name, "local_memory"))
@ -148,7 +182,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
break; break;
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring depth attribute for object type without depth\n"); fprintf(stderr, "%s: ignoring depth attribute for object type without depth\n",
state->global->msgprefix);
break; break;
} }
} }
@ -161,7 +196,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
if (sscanf(value, "%04x:%02x:%02x.%01x", if (sscanf(value, "%04x:%02x:%02x.%01x",
&domain, &bus, &dev, &func) != 4) { &domain, &bus, &dev, &func) != 4) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring invalid pci_busid format string %s\n", value); fprintf(stderr, "%s: ignoring invalid pci_busid format string %s\n",
state->global->msgprefix, value);
} else { } else {
obj->attr->pcidev.domain = domain; obj->attr->pcidev.domain = domain;
obj->attr->pcidev.bus = bus; obj->attr->pcidev.bus = bus;
@ -172,7 +208,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
} }
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring pci_busid attribute for non-PCI object\n"); fprintf(stderr, "%s: ignoring pci_busid attribute for non-PCI object\n",
state->global->msgprefix);
break; break;
} }
} }
@ -185,7 +222,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
if (sscanf(value, "%04x [%04x:%04x] [%04x:%04x] %02x", if (sscanf(value, "%04x [%04x:%04x] [%04x:%04x] %02x",
&classid, &vendor, &device, &subvendor, &subdevice, &revision) != 6) { &classid, &vendor, &device, &subvendor, &subdevice, &revision) != 6) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring invalid pci_type format string %s\n", value); fprintf(stderr, "%s: ignoring invalid pci_type format string %s\n",
state->global->msgprefix, value);
} else { } else {
obj->attr->pcidev.class_id = classid; obj->attr->pcidev.class_id = classid;
obj->attr->pcidev.vendor_id = vendor; obj->attr->pcidev.vendor_id = vendor;
@ -198,7 +236,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
} }
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring pci_type attribute for non-PCI object\n"); fprintf(stderr, "%s: ignoring pci_type attribute for non-PCI object\n",
state->global->msgprefix);
break; break;
} }
} }
@ -212,7 +251,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
} }
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring pci_link_speed attribute for non-PCI object\n"); fprintf(stderr, "%s: ignoring pci_link_speed attribute for non-PCI object\n",
state->global->msgprefix);
break; break;
} }
} }
@ -223,7 +263,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
unsigned upstream_type, downstream_type; unsigned upstream_type, downstream_type;
if (sscanf(value, "%u-%u", &upstream_type, &downstream_type) != 2) { if (sscanf(value, "%u-%u", &upstream_type, &downstream_type) != 2) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring invalid bridge_type format string %s\n", value); fprintf(stderr, "%s: ignoring invalid bridge_type format string %s\n",
state->global->msgprefix, value);
} else { } else {
obj->attr->bridge.upstream_type = (hwloc_obj_bridge_type_t) upstream_type; obj->attr->bridge.upstream_type = (hwloc_obj_bridge_type_t) upstream_type;
obj->attr->bridge.downstream_type = (hwloc_obj_bridge_type_t) downstream_type; obj->attr->bridge.downstream_type = (hwloc_obj_bridge_type_t) downstream_type;
@ -232,7 +273,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
} }
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring bridge_type attribute for non-bridge object\n"); fprintf(stderr, "%s: ignoring bridge_type attribute for non-bridge object\n",
state->global->msgprefix);
break; break;
} }
} }
@ -244,7 +286,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
if (sscanf(value, "%04x:[%02x-%02x]", if (sscanf(value, "%04x:[%02x-%02x]",
&domain, &secbus, &subbus) != 3) { &domain, &secbus, &subbus) != 3) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring invalid bridge_pci format string %s\n", value); fprintf(stderr, "%s: ignoring invalid bridge_pci format string %s\n",
state->global->msgprefix, value);
} else { } else {
obj->attr->bridge.downstream.pci.domain = domain; obj->attr->bridge.downstream.pci.domain = domain;
obj->attr->bridge.downstream.pci.secondary_bus = secbus; obj->attr->bridge.downstream.pci.secondary_bus = secbus;
@ -254,7 +297,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
} }
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring bridge_pci attribute for non-bridge object\n"); fprintf(stderr, "%s: ignoring bridge_pci attribute for non-bridge object\n",
state->global->msgprefix);
break; break;
} }
} }
@ -265,14 +309,16 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
unsigned osdev_type; unsigned osdev_type;
if (sscanf(value, "%u", &osdev_type) != 1) { if (sscanf(value, "%u", &osdev_type) != 1) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring invalid osdev_type format string %s\n", value); fprintf(stderr, "%s: ignoring invalid osdev_type format string %s\n",
state->global->msgprefix, value);
} else } else
obj->attr->osdev.type = (hwloc_obj_osdev_type_t) osdev_type; obj->attr->osdev.type = (hwloc_obj_osdev_type_t) osdev_type;
break; break;
} }
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring osdev_type attribute for non-osdev object\n"); fprintf(stderr, "%s: ignoring osdev_type attribute for non-osdev object\n",
state->global->msgprefix);
break; break;
} }
} }
@ -299,21 +345,22 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
case HWLOC_OBJ_CACHE: case HWLOC_OBJ_CACHE:
obj->attr->cache.size = lvalue << 10; obj->attr->cache.size = lvalue << 10;
break; break;
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_MACHINE: case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_SYSTEM: case HWLOC_OBJ_SYSTEM:
obj->memory.local_memory = lvalue << 10; obj->memory.local_memory = lvalue << 10;
break; break;
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring memory_kB attribute for object type without memory\n"); fprintf(stderr, "%s: ignoring memory_kB attribute for object type without memory\n",
state->global->msgprefix);
break; break;
} }
} }
else if (!strcmp(name, "huge_page_size_kB")) { else if (!strcmp(name, "huge_page_size_kB")) {
unsigned long lvalue = strtoul(value, NULL, 10); unsigned long lvalue = strtoul(value, NULL, 10);
switch (obj->type) { switch (obj->type) {
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_MACHINE: case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_SYSTEM: case HWLOC_OBJ_SYSTEM:
if (!obj->memory.page_types) { if (!obj->memory.page_types) {
@ -324,14 +371,15 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
break; break;
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring huge_page_size_kB attribute for object type without huge pages\n"); fprintf(stderr, "%s: ignoring huge_page_size_kB attribute for object type without huge pages\n",
state->global->msgprefix);
break; break;
} }
} }
else if (!strcmp(name, "huge_page_free")) { else if (!strcmp(name, "huge_page_free")) {
unsigned long lvalue = strtoul(value, NULL, 10); unsigned long lvalue = strtoul(value, NULL, 10);
switch (obj->type) { switch (obj->type) {
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_MACHINE: case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_SYSTEM: case HWLOC_OBJ_SYSTEM:
if (!obj->memory.page_types) { if (!obj->memory.page_types) {
@ -342,7 +390,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
break; break;
default: default:
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring huge_page_free attribute for object type without huge pages\n"); fprintf(stderr, "%s: ignoring huge_page_free attribute for object type without huge pages\n",
state->global->msgprefix);
break; break;
} }
} }
@ -353,7 +402,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology __hwloc_attribute_
else if (hwloc__xml_verbose()) else if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unknown object attribute %s\n", name); fprintf(stderr, "%s: ignoring unknown object attribute %s\n",
state->global->msgprefix, name);
} }
@ -366,7 +416,7 @@ hwloc__xml_import_info(hwloc_topology_t topology __hwloc_attribute_unused, hwloc
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state->next_attr(state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "name")) if (!strcmp(attrname, "name"))
infoname = attrvalue; infoname = attrvalue;
@ -380,7 +430,7 @@ hwloc__xml_import_info(hwloc_topology_t topology __hwloc_attribute_unused, hwloc
/* empty strings are ignored by libxml */ /* empty strings are ignored by libxml */
hwloc_obj_add_info(obj, infoname, infovalue ? infovalue : ""); hwloc_obj_add_info(obj, infoname, infovalue ? infovalue : "");
return state->close_tag(state); return state->global->close_tag(state);
} }
static int static int
@ -391,7 +441,7 @@ hwloc__xml_import_pagetype(hwloc_topology_t topology __hwloc_attribute_unused, h
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state->next_attr(state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "size")) if (!strcmp(attrname, "size"))
size = strtoull(attrvalue, NULL, 10); size = strtoull(attrvalue, NULL, 10);
@ -409,7 +459,7 @@ hwloc__xml_import_pagetype(hwloc_topology_t topology __hwloc_attribute_unused, h
obj->memory.page_types[idx].count = count; obj->memory.page_types[idx].count = count;
} }
return state->close_tag(state); return state->global->close_tag(state);
} }
static int static int
@ -424,7 +474,7 @@ hwloc__xml_import_distances(struct hwloc_xml_backend_data_s *data,
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state->next_attr(state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "nbobjs")) if (!strcmp(attrname, "nbobjs"))
nbobjs = strtoul(attrvalue, NULL, 10); nbobjs = strtoul(attrvalue, NULL, 10);
@ -453,7 +503,7 @@ hwloc__xml_import_distances(struct hwloc_xml_backend_data_s *data,
char *attrname, *attrvalue; char *attrname, *attrvalue;
float val; float val;
ret = state->find_child(state, &childstate, &tag); ret = state->global->find_child(state, &childstate, &tag);
if (ret <= 0 || strcmp(tag, "latency")) { if (ret <= 0 || strcmp(tag, "latency")) {
/* a latency child is needed */ /* a latency child is needed */
free(distances->distances.latency); free(distances->distances.latency);
@ -461,7 +511,7 @@ hwloc__xml_import_distances(struct hwloc_xml_backend_data_s *data,
return -1; return -1;
} }
ret = state->next_attr(&childstate, &attrname, &attrvalue); ret = state->global->next_attr(&childstate, &attrname, &attrvalue);
if (ret < 0 || strcmp(attrname, "value")) { if (ret < 0 || strcmp(attrname, "value")) {
free(distances->distances.latency); free(distances->distances.latency);
free(distances); free(distances);
@ -473,11 +523,11 @@ hwloc__xml_import_distances(struct hwloc_xml_backend_data_s *data,
if (val > latmax) if (val > latmax)
latmax = val; latmax = val;
ret = state->close_tag(&childstate); ret = state->global->close_tag(&childstate);
if (ret < 0) if (ret < 0)
return -1; return -1;
state->close_child(&childstate); state->global->close_child(&childstate);
} }
distances->distances.latency_max = latmax; distances->distances.latency_max = latmax;
@ -490,7 +540,7 @@ hwloc__xml_import_distances(struct hwloc_xml_backend_data_s *data,
distances->next = NULL; distances->next = NULL;
} }
return state->close_tag(state); return state->global->close_tag(state);
} }
static int static int
@ -503,7 +553,7 @@ hwloc__xml_import_userdata(hwloc_topology_t topology __hwloc_attribute_unused, h
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state->next_attr(state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "length")) if (!strcmp(attrname, "length"))
length = strtoul(attrvalue, NULL, 10); length = strtoul(attrvalue, NULL, 10);
@ -521,7 +571,7 @@ hwloc__xml_import_userdata(hwloc_topology_t topology __hwloc_attribute_unused, h
if (encoded) { if (encoded) {
char *encoded_buffer; char *encoded_buffer;
size_t encoded_length = 4*((length+2)/3); size_t encoded_length = 4*((length+2)/3);
ret = state->get_content(state, &encoded_buffer, encoded_length); ret = state->global->get_content(state, &encoded_buffer, encoded_length);
if (ret < 0) if (ret < 0)
return -1; return -1;
if (ret) { if (ret) {
@ -537,14 +587,14 @@ hwloc__xml_import_userdata(hwloc_topology_t topology __hwloc_attribute_unused, h
} }
} else { } else {
char *buffer; char *buffer;
ret = state->get_content(state, &buffer, length); ret = state->global->get_content(state, &buffer, length);
if (ret < 0) if (ret < 0)
return -1; return -1;
topology->userdata_import_cb(topology, obj, name, buffer, length); topology->userdata_import_cb(topology, obj, name, buffer, length);
} }
state->close_content(state); state->global->close_content(state);
} }
return state->close_tag(state); return state->global->close_tag(state);
} }
static int static int
@ -553,24 +603,78 @@ hwloc__xml_import_object(hwloc_topology_t topology,
hwloc_obj_t obj, hwloc_obj_t obj,
hwloc__xml_import_state_t state) hwloc__xml_import_state_t state)
{ {
hwloc_obj_t parent = obj->parent;
/* process attributes */ /* process attributes */
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state->next_attr(state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "type")) { if (!strcmp(attrname, "type")) {
if (hwloc_obj_type_sscanf(attrvalue, &obj->type, NULL, NULL, 0) < 0) if (hwloc_obj_type_sscanf(attrvalue, &obj->type, NULL, NULL, 0) < 0)
return -1; goto error;
} else { } else {
/* type needed first */ /* type needed first */
if (obj->type == (hwloc_obj_type_t)-1) if (obj->type == (hwloc_obj_type_t)-1)
return -1; goto error;
hwloc__xml_import_object_attr(topology, obj, attrname, attrvalue); hwloc__xml_import_object_attr(topology, obj, attrname, attrvalue, state);
} }
} }
if (obj->parent) { if (parent) {
/* root->parent is NULL, and root is already inserted */ /* root->parent is NULL, and root is already inserted */
/* warn if inserting out-of-order */
if (parent->cpuset) { /* don't compare children if multinode parent */
hwloc_obj_t *current;
for (current = &parent->first_child; *current; current = &(*current)->next_sibling) {
hwloc_bitmap_t curcpuset = (*current)->cpuset;
if (obj->cpuset && (!curcpuset || hwloc__object_cpusets_compare_first(obj, *current) < 0)) {
static int reported = 0;
if (!reported && !hwloc_hide_errors()) {
char *progname = hwloc_progname(topology);
const char *origversion = hwloc_obj_get_info_by_name(topology->levels[0][0], "hwlocVersion");
const char *origprogname = hwloc_obj_get_info_by_name(topology->levels[0][0], "ProcessName");
char *c1, *cc1, t1[64];
char *c2 = NULL, *cc2 = NULL, t2[64];
hwloc_bitmap_asprintf(&c1, obj->cpuset);
hwloc_bitmap_asprintf(&cc1, obj->complete_cpuset);
hwloc_obj_type_snprintf(t1, sizeof(t1), obj, 0);
if (curcpuset)
hwloc_bitmap_asprintf(&c2, curcpuset);
if ((*current)->complete_cpuset)
hwloc_bitmap_asprintf(&cc2, (*current)->complete_cpuset);
hwloc_obj_type_snprintf(t2, sizeof(t2), *current, 0);
fprintf(stderr, "****************************************************************************\n");
fprintf(stderr, "* hwloc has encountered an out-of-order XML topology load.\n");
fprintf(stderr, "* Object %s cpuset %s complete %s\n",
t1, c1, cc1);
fprintf(stderr, "* was inserted after object %s with %s and %s.\n",
t2, c2 ? c2 : "none", cc2 ? cc2 : "none");
fprintf(stderr, "* The error occured in hwloc %s inside process `%s', while\n",
HWLOC_VERSION,
progname ? progname : "<unknown>");
if (origversion || origprogname)
fprintf(stderr, "* the input XML was generated by hwloc %s inside process `%s'.\n",
origversion ? origversion : "(unknown version)",
origprogname ? origprogname : "<unknown>");
else
fprintf(stderr, "* the input XML was generated by an unspecified ancient hwloc release.\n");
fprintf(stderr, "* Please check that your input topology XML file is valid.\n");
fprintf(stderr, "****************************************************************************\n");
free(c1);
free(cc1);
if (c2)
free(c2);
if (cc2)
free(cc2);
free(progname);
reported = 1;
}
}
}
}
hwloc_insert_object_by_parent(topology, obj->parent /* filled by the caller */, obj); hwloc_insert_object_by_parent(topology, obj->parent /* filled by the caller */, obj);
/* insert_object_by_parent() doesn't merge during insert, so obj is still valid */ /* insert_object_by_parent() doesn't merge during insert, so obj is still valid */
} }
@ -581,9 +685,9 @@ hwloc__xml_import_object(hwloc_topology_t topology,
char *tag; char *tag;
int ret; int ret;
ret = state->find_child(state, &childstate, &tag); ret = state->global->find_child(state, &childstate, &tag);
if (ret < 0) if (ret < 0)
return -1; goto error;
if (!ret) if (!ret)
break; break;
@ -603,12 +707,16 @@ hwloc__xml_import_object(hwloc_topology_t topology,
ret = -1; ret = -1;
if (ret < 0) if (ret < 0)
return ret; goto error;
state->close_child(&childstate); state->global->close_child(&childstate);
} }
return state->close_tag(state); return state->global->close_tag(state);
error:
hwloc_free_unlinked_object(obj);
return -1;
} }
static int static int
@ -627,7 +735,7 @@ hwloc__xml_import_diff_one(hwloc__xml_import_state_t state,
while (1) { while (1) {
char *attrname, *attrvalue; char *attrname, *attrvalue;
if (state->next_attr(state, &attrname, &attrvalue) < 0) if (state->global->next_attr(state, &attrname, &attrvalue) < 0)
break; break;
if (!strcmp(attrname, "type")) if (!strcmp(attrname, "type"))
type_s = attrvalue; type_s = attrvalue;
@ -645,8 +753,12 @@ hwloc__xml_import_diff_one(hwloc__xml_import_state_t state,
obj_attr_oldvalue_s = attrvalue; obj_attr_oldvalue_s = attrvalue;
else if (!strcmp(attrname, "obj_attr_newvalue")) else if (!strcmp(attrname, "obj_attr_newvalue"))
obj_attr_newvalue_s = attrvalue; obj_attr_newvalue_s = attrvalue;
else else {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: ignoring unknown diff attribute %s\n",
state->global->msgprefix, attrname);
return -1; return -1;
}
} }
if (type_s) { if (type_s) {
@ -659,17 +771,29 @@ hwloc__xml_import_diff_one(hwloc__xml_import_state_t state,
hwloc_topology_diff_t diff; hwloc_topology_diff_t diff;
/* obj_attr mandatory generic attributes */ /* obj_attr mandatory generic attributes */
if (!obj_depth_s || !obj_index_s || !obj_attr_type_s) if (!obj_depth_s || !obj_index_s || !obj_attr_type_s) {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: missing mandatory obj attr generic attributes\n",
state->global->msgprefix);
break; break;
}
/* obj_attr mandatory attributes common to all subtypes */ /* obj_attr mandatory attributes common to all subtypes */
if (!obj_attr_oldvalue_s || !obj_attr_newvalue_s) if (!obj_attr_oldvalue_s || !obj_attr_newvalue_s) {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: missing mandatory obj attr value attributes\n",
state->global->msgprefix);
break; break;
}
/* mandatory attributes for obj_attr_info subtype */ /* mandatory attributes for obj_attr_info subtype */
obj_attr_type = atoi(obj_attr_type_s); obj_attr_type = atoi(obj_attr_type_s);
if (obj_attr_type == HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO && !obj_attr_name_s) if (obj_attr_type == HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO && !obj_attr_name_s) {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: missing mandatory obj attr info name attribute\n",
state->global->msgprefix);
break; break;
}
/* now we know we have everything we need */ /* now we know we have everything we need */
diff = malloc(sizeof(*diff)); diff = malloc(sizeof(*diff));
@ -705,7 +829,7 @@ hwloc__xml_import_diff_one(hwloc__xml_import_state_t state,
} }
} }
return state->close_tag(state); return state->global->close_tag(state);
} }
int int
@ -720,7 +844,7 @@ hwloc__xml_import_diff(hwloc__xml_import_state_t state,
char *tag; char *tag;
int ret; int ret;
ret = state->find_child(state, &childstate, &tag); ret = state->global->find_child(state, &childstate, &tag);
if (ret < 0) if (ret < 0)
return -1; return -1;
if (!ret) if (!ret)
@ -734,7 +858,7 @@ hwloc__xml_import_diff(hwloc__xml_import_state_t state,
if (ret < 0) if (ret < 0)
return ret; return ret;
state->close_child(&childstate); state->global->close_child(&childstate);
} }
*firstdiffp = firstdiff; *firstdiffp = firstdiff;
@ -747,7 +871,8 @@ hwloc__xml_import_diff(hwloc__xml_import_state_t state,
static int static int
hwloc_xml__handle_distances(struct hwloc_topology *topology, hwloc_xml__handle_distances(struct hwloc_topology *topology,
struct hwloc_xml_backend_data_s *data) struct hwloc_xml_backend_data_s *data,
const char *msgprefix)
{ {
struct hwloc_xml_imported_distances_s *xmldist, *next = data->first_distances; struct hwloc_xml_imported_distances_s *xmldist, *next = data->first_distances;
@ -766,8 +891,8 @@ hwloc_xml__handle_distances(struct hwloc_topology *topology,
if (nbobjs != xmldist->distances.nbobjs) { if (nbobjs != xmldist->distances.nbobjs) {
/* distances invalid, drop */ /* distances invalid, drop */
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring invalid distance matrix with %u objs instead of %u\n", fprintf(stderr, "%s: ignoring invalid distance matrix with %u objs instead of %u\n",
xmldist->distances.nbobjs, nbobjs); msgprefix, xmldist->distances.nbobjs, nbobjs);
free(xmldist->distances.latency); free(xmldist->distances.latency);
} else { } else {
/* distances valid, add it to the internal OS distances list for grouping */ /* distances valid, add it to the internal OS distances list for grouping */
@ -803,6 +928,8 @@ hwloc_look_xml(struct hwloc_backend *backend)
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
int ret; int ret;
state.global = data;
assert(!topology->levels[0][0]->cpuset); assert(!topology->levels[0][0]->cpuset);
hwloc_localeswitch_init(); hwloc_localeswitch_init();
@ -814,22 +941,22 @@ hwloc_look_xml(struct hwloc_backend *backend)
goto failed; goto failed;
/* find root object tag and import it */ /* find root object tag and import it */
ret = state.find_child(&state, &childstate, &tag); ret = state.global->find_child(&state, &childstate, &tag);
if (ret < 0 || !ret || strcmp(tag, "object")) if (ret < 0 || !ret || strcmp(tag, "object"))
goto failed; goto failed;
ret = hwloc__xml_import_object(topology, data, topology->levels[0][0], &childstate); ret = hwloc__xml_import_object(topology, data, topology->levels[0][0], &childstate);
if (ret < 0) if (ret < 0)
goto failed; goto failed;
state.close_child(&childstate); state.global->close_child(&childstate);
/* find end of topology tag */ /* find end of topology tag */
state.close_tag(&state); state.global->close_tag(&state);
/* keep the "Backend" information intact */ /* keep the "Backend" information intact */
/* we could add "BackendSource=XML" to notify that XML was used between the actual backend and here */ /* we could add "BackendSource=XML" to notify that XML was used between the actual backend and here */
/* if we added some distances, we must check them, and make them groupable */ /* if we added some distances, we must check them, and make them groupable */
if (hwloc_xml__handle_distances(topology, data) < 0) if (hwloc_xml__handle_distances(topology, data, data->msgprefix) < 0)
goto err; goto err;
data->first_distances = data->last_distances = NULL; data->first_distances = data->last_distances = NULL;
topology->support.discovery->pu = 1; topology->support.discovery->pu = 1;
@ -841,7 +968,8 @@ hwloc_look_xml(struct hwloc_backend *backend)
if (data->look_failed) if (data->look_failed)
data->look_failed(data); data->look_failed(data);
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "XML component discovery failed.\n"); fprintf(stderr, "%s: XML component discovery failed.\n",
data->msgprefix);
err: err:
hwloc_localeswitch_fini(); hwloc_localeswitch_fini();
return -1; return -1;
@ -853,11 +981,22 @@ hwloc_topology_diff_load_xml(hwloc_topology_t topology __hwloc_attribute_unused,
const char *xmlpath, const char *xmlpath,
hwloc_topology_diff_t *firstdiffp, char **refnamep) hwloc_topology_diff_t *firstdiffp, char **refnamep)
{ {
struct hwloc__xml_import_state_s state;
struct hwloc_xml_backend_data_s fakedata; /* only for storing global info during parsing */
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
char *env; const char *basename;
int force_nolibxml; int force_nolibxml;
int ret; int ret;
state.global = &fakedata;
basename = strrchr(xmlpath, '/');
if (basename)
basename++;
else
basename = xmlpath;
fakedata.msgprefix = strdup(basename);
if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) { if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
@ -867,13 +1006,12 @@ hwloc_topology_diff_load_xml(hwloc_topology_t topology __hwloc_attribute_unused,
*firstdiffp = NULL; *firstdiffp = NULL;
env = getenv("HWLOC_NO_LIBXML_IMPORT"); force_nolibxml = hwloc_nolibxml_import();
force_nolibxml = (env && atoi(env));
retry: retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
ret = hwloc_nolibxml_callbacks->import_diff(xmlpath, NULL, 0, firstdiffp, refnamep); ret = hwloc_nolibxml_callbacks->import_diff(&state, xmlpath, NULL, 0, firstdiffp, refnamep);
else { else {
ret = hwloc_libxml_callbacks->import_diff(xmlpath, NULL, 0, firstdiffp, refnamep); ret = hwloc_libxml_callbacks->import_diff(&state, xmlpath, NULL, 0, firstdiffp, refnamep);
if (ret < 0 && errno == ENOSYS) { if (ret < 0 && errno == ENOSYS) {
hwloc_libxml_callbacks = NULL; hwloc_libxml_callbacks = NULL;
goto retry; goto retry;
@ -881,6 +1019,8 @@ retry:
} }
hwloc_localeswitch_fini(); hwloc_localeswitch_fini();
free(fakedata.msgprefix);
return ret; return ret;
} }
@ -890,11 +1030,15 @@ hwloc_topology_diff_load_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_u
const char *xmlbuffer, int buflen, const char *xmlbuffer, int buflen,
hwloc_topology_diff_t *firstdiffp, char **refnamep) hwloc_topology_diff_t *firstdiffp, char **refnamep)
{ {
struct hwloc__xml_import_state_s state;
struct hwloc_xml_backend_data_s fakedata; /* only for storing global info during parsing */
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
char *env;
int force_nolibxml; int force_nolibxml;
int ret; int ret;
state.global = &fakedata;
fakedata.msgprefix = "xmldiffbuffer";
if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) { if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
@ -904,13 +1048,12 @@ hwloc_topology_diff_load_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_u
*firstdiffp = NULL; *firstdiffp = NULL;
env = getenv("HWLOC_NO_LIBXML_IMPORT"); force_nolibxml = hwloc_nolibxml_import();
force_nolibxml = (env && atoi(env)); retry:
retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
ret = hwloc_nolibxml_callbacks->import_diff(NULL, xmlbuffer, buflen, firstdiffp, refnamep); ret = hwloc_nolibxml_callbacks->import_diff(&state, NULL, xmlbuffer, buflen, firstdiffp, refnamep);
else { else {
ret = hwloc_libxml_callbacks->import_diff(NULL, xmlbuffer, buflen, firstdiffp, refnamep); ret = hwloc_libxml_callbacks->import_diff(&state, NULL, xmlbuffer, buflen, firstdiffp, refnamep);
if (ret < 0 && errno == ENOSYS) { if (ret < 0 && errno == ENOSYS) {
hwloc_libxml_callbacks = NULL; hwloc_libxml_callbacks = NULL;
goto retry; goto retry;
@ -1188,7 +1331,6 @@ hwloc__xml_export_diff(hwloc__xml_export_state_t parentstate, hwloc_topology_dif
int hwloc_topology_export_xml(hwloc_topology_t topology, const char *filename) int hwloc_topology_export_xml(hwloc_topology_t topology, const char *filename)
{ {
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
char *env;
int force_nolibxml; int force_nolibxml;
int ret; int ret;
@ -1199,8 +1341,7 @@ int hwloc_topology_export_xml(hwloc_topology_t topology, const char *filename)
hwloc_localeswitch_init(); hwloc_localeswitch_init();
env = getenv("HWLOC_NO_LIBXML_EXPORT"); force_nolibxml = hwloc_nolibxml_export();
force_nolibxml = (env && atoi(env));
retry: retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
ret = hwloc_nolibxml_callbacks->export_file(topology, filename); ret = hwloc_nolibxml_callbacks->export_file(topology, filename);
@ -1220,7 +1361,6 @@ retry:
int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen) int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen)
{ {
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
char *env;
int force_nolibxml; int force_nolibxml;
int ret; int ret;
@ -1231,8 +1371,7 @@ int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer,
hwloc_localeswitch_init(); hwloc_localeswitch_init();
env = getenv("HWLOC_NO_LIBXML_EXPORT"); force_nolibxml = hwloc_nolibxml_export();
force_nolibxml = (env && atoi(env));
retry: retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
ret = hwloc_nolibxml_callbacks->export_buffer(topology, xmlbuffer, buflen); ret = hwloc_nolibxml_callbacks->export_buffer(topology, xmlbuffer, buflen);
@ -1256,7 +1395,6 @@ hwloc_topology_diff_export_xml(hwloc_topology_t topology __hwloc_attribute_unuse
{ {
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
hwloc_topology_diff_t tmpdiff; hwloc_topology_diff_t tmpdiff;
char *env;
int force_nolibxml; int force_nolibxml;
int ret; int ret;
@ -1276,8 +1414,7 @@ hwloc_topology_diff_export_xml(hwloc_topology_t topology __hwloc_attribute_unuse
hwloc_localeswitch_init(); hwloc_localeswitch_init();
env = getenv("HWLOC_NO_LIBXML_EXPORT"); force_nolibxml = hwloc_nolibxml_export();
force_nolibxml = (env && atoi(env));
retry: retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
ret = hwloc_nolibxml_callbacks->export_diff_file(diff, refname, filename); ret = hwloc_nolibxml_callbacks->export_diff_file(diff, refname, filename);
@ -1301,7 +1438,6 @@ hwloc_topology_diff_export_xmlbuffer(hwloc_topology_t topology __hwloc_attribute
{ {
hwloc_localeswitch_declare; hwloc_localeswitch_declare;
hwloc_topology_diff_t tmpdiff; hwloc_topology_diff_t tmpdiff;
char *env;
int force_nolibxml; int force_nolibxml;
int ret; int ret;
@ -1321,8 +1457,7 @@ hwloc_topology_diff_export_xmlbuffer(hwloc_topology_t topology __hwloc_attribute
hwloc_localeswitch_init(); hwloc_localeswitch_init();
env = getenv("HWLOC_NO_LIBXML_EXPORT"); force_nolibxml = hwloc_nolibxml_export();
force_nolibxml = (env && atoi(env));
retry: retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
ret = hwloc_nolibxml_callbacks->export_diff_buffer(diff, refname, xmlbuffer, buflen); ret = hwloc_nolibxml_callbacks->export_diff_buffer(diff, refname, xmlbuffer, buflen);
@ -1340,7 +1475,6 @@ retry:
void hwloc_free_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_unused, char *xmlbuffer) void hwloc_free_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_unused, char *xmlbuffer)
{ {
char *env;
int force_nolibxml; int force_nolibxml;
if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) { if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
@ -1348,8 +1482,7 @@ void hwloc_free_xmlbuffer(hwloc_topology_t topology __hwloc_attribute_unused, ch
return ; return ;
} }
env = getenv("HWLOC_NO_LIBXML_EXPORT"); force_nolibxml = hwloc_nolibxml_export();
force_nolibxml = (env && atoi(env));
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
hwloc_nolibxml_callbacks->free_buffer(xmlbuffer); hwloc_nolibxml_callbacks->free_buffer(xmlbuffer);
else else
@ -1405,7 +1538,7 @@ hwloc_export_obj_userdata_base64(void *reserved,
hwloc__xml_export_state_t state = reserved; hwloc__xml_export_state_t state = reserved;
size_t encoded_length; size_t encoded_length;
char *encoded_buffer; char *encoded_buffer;
int ret; int ret __hwloc_attribute_unused;
if (name && hwloc__xml_export_check_buffer(name, strlen(name)) < 0) { if (name && hwloc__xml_export_check_buffer(name, strlen(name)) < 0) {
errno = EINVAL; errno = EINVAL;
@ -1444,6 +1577,7 @@ hwloc_xml_backend_disable(struct hwloc_backend *backend)
{ {
struct hwloc_xml_backend_data_s *data = backend->private_data; struct hwloc_xml_backend_data_s *data = backend->private_data;
data->backend_exit(data); data->backend_exit(data);
free(data->msgprefix);
free(data); free(data);
} }
@ -1455,11 +1589,11 @@ hwloc_xml_component_instantiate(struct hwloc_disc_component *component,
{ {
struct hwloc_xml_backend_data_s *data; struct hwloc_xml_backend_data_s *data;
struct hwloc_backend *backend; struct hwloc_backend *backend;
char *env;
int force_nolibxml; int force_nolibxml;
const char * xmlpath = (const char *) _data1; const char * xmlpath = (const char *) _data1;
const char * xmlbuffer = (const char *) _data2; const char * xmlbuffer = (const char *) _data2;
int xmlbuflen = (int)(uintptr_t) _data3; int xmlbuflen = (int)(uintptr_t) _data3;
const char *basename;
int err; int err;
if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) { if (!hwloc_libxml_callbacks && !hwloc_nolibxml_callbacks) {
@ -1487,8 +1621,18 @@ hwloc_xml_component_instantiate(struct hwloc_disc_component *component,
backend->disable = hwloc_xml_backend_disable; backend->disable = hwloc_xml_backend_disable;
backend->is_thissystem = 0; backend->is_thissystem = 0;
env = getenv("HWLOC_NO_LIBXML_IMPORT"); if (xmlpath) {
force_nolibxml = (env && atoi(env)); basename = strrchr(xmlpath, '/');
if (basename)
basename++;
else
basename = xmlpath;
} else {
basename = "xmlbuffer";
}
data->msgprefix = strdup(basename);
force_nolibxml = hwloc_nolibxml_import();
retry: retry:
if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml)) if (!hwloc_libxml_callbacks || (hwloc_nolibxml_callbacks && force_nolibxml))
err = hwloc_nolibxml_callbacks->backend_init(data, xmlpath, xmlbuffer, xmlbuflen); err = hwloc_nolibxml_callbacks->backend_init(data, xmlpath, xmlbuffer, xmlbuflen);
@ -1505,6 +1649,7 @@ retry:
return backend; return backend;
out_with_data: out_with_data:
free(data->msgprefix);
free(data); free(data);
out_with_backend: out_with_backend:
free(backend); free(backend);
@ -1523,6 +1668,7 @@ static struct hwloc_disc_component hwloc_xml_disc_component = {
const struct hwloc_component hwloc_xml_component = { const struct hwloc_component hwloc_xml_component = {
HWLOC_COMPONENT_ABI, HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC, HWLOC_COMPONENT_TYPE_DISC,
0, 0,
&hwloc_xml_disc_component &hwloc_xml_disc_component

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1 * Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -183,8 +183,8 @@ hwloc_obj_type_string (hwloc_obj_type_t obj)
case HWLOC_OBJ_MACHINE: return "Machine"; case HWLOC_OBJ_MACHINE: return "Machine";
case HWLOC_OBJ_MISC: return "Misc"; case HWLOC_OBJ_MISC: return "Misc";
case HWLOC_OBJ_GROUP: return "Group"; case HWLOC_OBJ_GROUP: return "Group";
case HWLOC_OBJ_NODE: return "NUMANode"; case HWLOC_OBJ_NUMANODE: return "NUMANode";
case HWLOC_OBJ_SOCKET: return "Socket"; case HWLOC_OBJ_PACKAGE: return "Package";
case HWLOC_OBJ_CACHE: return "Cache"; case HWLOC_OBJ_CACHE: return "Cache";
case HWLOC_OBJ_CORE: return "Core"; case HWLOC_OBJ_CORE: return "Core";
case HWLOC_OBJ_BRIDGE: return "Bridge"; case HWLOC_OBJ_BRIDGE: return "Bridge";
@ -202,8 +202,8 @@ hwloc_obj_type_of_string (const char * string)
if (!strcasecmp(string, "Machine")) return HWLOC_OBJ_MACHINE; if (!strcasecmp(string, "Machine")) return HWLOC_OBJ_MACHINE;
if (!strcasecmp(string, "Misc")) return HWLOC_OBJ_MISC; if (!strcasecmp(string, "Misc")) return HWLOC_OBJ_MISC;
if (!strcasecmp(string, "Group")) return HWLOC_OBJ_GROUP; if (!strcasecmp(string, "Group")) return HWLOC_OBJ_GROUP;
if (!strcasecmp(string, "NUMANode") || !strcasecmp(string, "Node")) return HWLOC_OBJ_NODE; if (!strcasecmp(string, "NUMANode") || !strcasecmp(string, "Node")) return HWLOC_OBJ_NUMANODE;
if (!strcasecmp(string, "Socket")) return HWLOC_OBJ_SOCKET; if (!strcasecmp(string, "Package") || !strcasecmp(string, "Socket") /* backward compat with v1.10 */) return HWLOC_OBJ_PACKAGE;
if (!strcasecmp(string, "Cache")) return HWLOC_OBJ_CACHE; if (!strcasecmp(string, "Cache")) return HWLOC_OBJ_CACHE;
if (!strcasecmp(string, "Core")) return HWLOC_OBJ_CORE; if (!strcasecmp(string, "Core")) return HWLOC_OBJ_CORE;
if (!strcasecmp(string, "PU")) return HWLOC_OBJ_PU; if (!strcasecmp(string, "PU")) return HWLOC_OBJ_PU;
@ -228,9 +228,10 @@ hwloc_obj_type_sscanf(const char *string, hwloc_obj_type_t *typep, int *depthatt
type = HWLOC_OBJ_MACHINE; type = HWLOC_OBJ_MACHINE;
} else if (!hwloc_strncasecmp(string, "node", 1) } else if (!hwloc_strncasecmp(string, "node", 1)
|| !hwloc_strncasecmp(string, "numa", 1)) { /* matches node and numanode */ || !hwloc_strncasecmp(string, "numa", 1)) { /* matches node and numanode */
type = HWLOC_OBJ_NODE; type = HWLOC_OBJ_NUMANODE;
} else if (!hwloc_strncasecmp(string, "socket", 2)) { } else if (!hwloc_strncasecmp(string, "package", 2)
type = HWLOC_OBJ_SOCKET; || !hwloc_strncasecmp(string, "socket", 2)) { /* backward compat with v1.10 */
type = HWLOC_OBJ_PACKAGE;
} else if (!hwloc_strncasecmp(string, "core", 2)) { } else if (!hwloc_strncasecmp(string, "core", 2)) {
type = HWLOC_OBJ_CORE; type = HWLOC_OBJ_CORE;
} else if (!hwloc_strncasecmp(string, "pu", 2)) { } else if (!hwloc_strncasecmp(string, "pu", 2)) {
@ -300,6 +301,7 @@ hwloc_pci_class_string(unsigned short class_id)
case 0x0105: return "ATA"; case 0x0105: return "ATA";
case 0x0106: return "SATA"; case 0x0106: return "SATA";
case 0x0107: return "SAS"; case 0x0107: return "SAS";
case 0x0108: return "NVMExp";
} }
return "Stor"; return "Stor";
case 0x02: case 0x02:
@ -311,6 +313,7 @@ hwloc_pci_class_string(unsigned short class_id)
case 0x0204: return "ISDN"; case 0x0204: return "ISDN";
case 0x0205: return "WrdFip"; case 0x0205: return "WrdFip";
case 0x0206: return "PICMG"; case 0x0206: return "PICMG";
case 0x0207: return "IB";
} }
return "Net"; return "Net";
case 0x03: case 0x03:
@ -367,6 +370,7 @@ hwloc_pci_class_string(unsigned short class_id)
case 0x0803: return "RTC"; case 0x0803: return "RTC";
case 0x0804: return "HtPl"; case 0x0804: return "HtPl";
case 0x0805: return "SD-HtPl"; case 0x0805: return "SD-HtPl";
case 0x0806: return "IOMMU";
} }
return "Syst"; return "Syst";
case 0x09: case 0x09:
@ -433,17 +437,16 @@ hwloc_pci_class_string(unsigned short class_id)
return "Crypt"; return "Crypt";
case 0x11: case 0x11:
return "Signl"; return "Signl";
case 0x12:
return "Accel";
case 0x13:
return "Instr";
case 0xff: case 0xff:
return "Oth"; return "Oth";
} }
return "PCI"; return "PCI";
} }
#define hwloc_memory_size_printf_value(_size, _verbose) \
((_size) < (10ULL<<20) || _verbose ? (((_size)>>9)+1)>>1 : (_size) < (10ULL<<30) ? (((_size)>>19)+1)>>1 : (((_size)>>29)+1)>>1)
#define hwloc_memory_size_printf_unit(_size, _verbose) \
((_size) < (10ULL<<20) || _verbose ? "KB" : (_size) < (10ULL<<30) ? "MB" : "GB")
static const char* hwloc_obj_cache_type_letter(hwloc_obj_cache_type_t type) static const char* hwloc_obj_cache_type_letter(hwloc_obj_cache_type_t type)
{ {
switch (type) { switch (type) {
@ -462,8 +465,8 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
case HWLOC_OBJ_MISC: case HWLOC_OBJ_MISC:
case HWLOC_OBJ_SYSTEM: case HWLOC_OBJ_SYSTEM:
case HWLOC_OBJ_MACHINE: case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_NODE: case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_SOCKET: case HWLOC_OBJ_PACKAGE:
case HWLOC_OBJ_CORE: case HWLOC_OBJ_CORE:
case HWLOC_OBJ_PU: case HWLOC_OBJ_PU:
return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type)); return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
@ -537,11 +540,11 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
(unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose)); hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose));
} else { } else {
if (obj->memory.total_memory) if (obj->memory.local_memory)
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s", res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
prefix, prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->memory.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose)); hwloc_memory_size_printf_unit(obj->memory.local_memory, verbose));
} }
if (res < 0) if (res < 0)
return -1; return -1;
@ -603,10 +606,14 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
case HWLOC_OBJ_PCI_DEVICE: case HWLOC_OBJ_PCI_DEVICE:
if (verbose) { if (verbose) {
char linkspeed[64]= ""; char linkspeed[64]= "";
char busid[16] = "[collapsed]";
if (obj->attr->pcidev.linkspeed) if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed); snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
res = snprintf(string, size, "busid=%04x:%02x:%02x.%01x%sclass=%04x(%s)%s", if (!hwloc_obj_get_info_by_name(obj, "lstopoCollapse"))
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator, snprintf(busid, sizeof(busid), "%04x:%02x:%02x.%01x",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func);
res = snprintf(string, size, "busid=%s%sclass=%04x(%s)%s",
busid, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed); obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
} }
break; break;
@ -627,6 +634,8 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (verbose) { if (verbose) {
unsigned i; unsigned i;
for(i=0; i<obj->infos_count; i++) { for(i=0; i<obj->infos_count; i++) {
if (!strcmp(obj->infos[i].name, "lstopoCollapse"))
continue;
if (strchr(obj->infos[i].value, ' ')) if (strchr(obj->infos[i].value, ' '))
res = hwloc_snprintf(tmp, tmplen, "%s%s=\"%s\"", res = hwloc_snprintf(tmp, tmplen, "%s%s=\"%s\"",
prefix, prefix,

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2014 Intel, Inc. All rights reserved. * Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
* *
* $COPYRIGHT$ * $COPYRIGHT$
* *
@ -13,8 +13,8 @@
* this header represents the public interface to this static component. * this header represents the public interface to this static component.
*/ */
#ifndef MCA_OPAL_HWLOC_HWLOC191_H #ifndef MCA_OPAL_HWLOC_HWLOC1110_H
#define MCA_OPAL_HWLOC_HWLOC191_H #define MCA_OPAL_HWLOC_HWLOC1110_H
BEGIN_C_DECLS BEGIN_C_DECLS
@ -42,4 +42,4 @@ BEGIN_C_DECLS
END_C_DECLS END_C_DECLS
#endif /* MCA_OPAL_HWLOC_HWLOC191_H */ #endif /* MCA_OPAL_HWLOC_HWLOC1110_H */

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/* /*
* Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2014 Intel, Inc. All rights reserved. * Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights * Copyright (c) 2015 Los Alamos National Security, LLC. All rights
* reserved. * reserved.
* *
@ -22,20 +22,20 @@
#include "opal/constants.h" #include "opal/constants.h"
#include "opal/mca/hwloc/hwloc.h" #include "opal/mca/hwloc/hwloc.h"
#include "hwloc191.h" #include "hwloc1110.h"
/* /*
* Public string showing the sysinfo ompi_linux component version number * Public string showing the sysinfo ompi_linux component version number
*/ */
const char *opal_hwloc_hwloc191_component_version_string = const char *opal_hwloc_hwloc1110_component_version_string =
"OPAL hwloc191 hwloc MCA component version " OPAL_VERSION; "OPAL hwloc1110 hwloc MCA component version " OPAL_VERSION;
/* /*
* Instantiate the public struct with all of our public information * Instantiate the public struct with all of our public information
* and pointers to our public functions in it * and pointers to our public functions in it
*/ */
const opal_hwloc_component_t mca_hwloc_hwloc191_component = { const opal_hwloc_component_t mca_hwloc_hwloc1110_component = {
/* First, the mca_component_t struct containing meta information /* First, the mca_component_t struct containing meta information
about the component itself */ about the component itself */
@ -44,7 +44,7 @@ const opal_hwloc_component_t mca_hwloc_hwloc191_component = {
OPAL_HWLOC_BASE_VERSION_2_0_0, OPAL_HWLOC_BASE_VERSION_2_0_0,
/* Component name and version */ /* Component name and version */
.mca_component_name = "hwloc191", .mca_component_name = "hwloc1110",
MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
OPAL_RELEASE_VERSION), OPAL_RELEASE_VERSION),
}, },

Просмотреть файл

Просмотреть файл

@ -1,170 +0,0 @@
# -*- shell-script -*-
#
# Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2014 Intel, Inc. All rights reserved.
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
#
# Priority
#
AC_DEFUN([MCA_opal_hwloc_hwloc191_PRIORITY], [90])
#
# Force this component to compile in static-only mode
#
AC_DEFUN([MCA_opal_hwloc_hwloc191_COMPILE_MODE], [
AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
$4="static"
AC_MSG_RESULT([$$4])
])
# Include hwloc m4 files
m4_include(opal/mca/hwloc/hwloc191/hwloc/config/hwloc.m4)
m4_include(opal/mca/hwloc/hwloc191/hwloc/config/hwloc_pkg.m4)
m4_include(opal/mca/hwloc/hwloc191/hwloc/config/hwloc_check_attributes.m4)
m4_include(opal/mca/hwloc/hwloc191/hwloc/config/hwloc_check_visibility.m4)
m4_include(opal/mca/hwloc/hwloc191/hwloc/config/hwloc_check_vendor.m4)
m4_include(opal/mca/hwloc/hwloc191/hwloc/config/hwloc_components.m4)
# MCA_hwloc_hwloc191_POST_CONFIG()
# ---------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc191_POST_CONFIG],[
OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc191_basedir])
# If we won, then do all the rest of the setup
AS_IF([test "$1" = "1" && test "$opal_hwloc_hwloc191_support" = "yes"],
[
# Set this variable so that the framework m4 knows what
# file to include in opal/mca/hwloc/hwloc.h
opal_hwloc_hwloc191_basedir=opal/mca/hwloc/hwloc191
opal_hwloc_base_include="$opal_hwloc_hwloc191_basedir/hwloc191.h"
# Add some stuff to CPPFLAGS so that the rest of the source
# tree can be built
file=$opal_hwloc_hwloc191_basedir/hwloc
CPPFLAGS="$CPPFLAGS -I$OPAL_TOP_SRCDIR/$file/include"
AS_IF([test "$OPAL_TOP_BUILDDIR" != "$OPAL_TOP_SRCDIR"],
[CPPFLAGS="$CPPFLAGS -I$OPAL_TOP_BUILDDIR/$file/include"])
unset file
])
OPAL_VAR_SCOPE_POP
# This must be run unconditionally
HWLOC_DO_AM_CONDITIONALS
])dnl
# MCA_hwloc_hwloc191_CONFIG([action-if-found], [action-if-not-found])
# --------------------------------------------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc191_CONFIG],[
# Hwloc needs to know if we have Verbs support
AC_REQUIRE([OPAL_CHECK_VERBS_DIR])
AC_CONFIG_FILES([opal/mca/hwloc/hwloc191/Makefile])
OPAL_VAR_SCOPE_PUSH([HWLOC_VERSION opal_hwloc_hwloc191_save_CPPFLAGS opal_hwloc_hwloc191_save_LDFLAGS opal_hwloc_hwloc191_save_LIBS opal_hwloc_hwloc191_save_cairo opal_hwloc_hwloc191_save_xml opal_hwloc_hwloc191_basedir opal_hwloc_hwloc191_file opal_hwloc_hwloc191_save_cflags CPPFLAGS_save LIBS_save])
# default to this component not providing support
opal_hwloc_hwloc191_basedir=opal/mca/hwloc/hwloc191
opal_hwloc_hwloc191_support=no
if test "$with_hwloc" = "internal" -o "$with_hwloc" = "" -o "$with_hwloc" = "yes"; then
opal_hwloc_hwloc191_save_CPPFLAGS=$CPPFLAGS
opal_hwloc_hwloc191_save_LDFLAGS=$LDFLAGS
opal_hwloc_hwloc191_save_LIBS=$LIBS
# Run the hwloc configuration - set the prefix to minimize
# the chance that someone will use the internal symbols
HWLOC_SET_SYMBOL_PREFIX([opal_hwloc191_])
# save XML or graphical options
opal_hwloc_hwloc191_save_cairo=$enable_cairo
opal_hwloc_hwloc191_save_xml=$enable_xml
opal_hwloc_hwloc191_save_static=$enable_static
opal_hwloc_hwloc191_save_shared=$enable_shared
opal_hwloc_hwloc191_save_plugins=$enable_plugins
# never enable hwloc's graphical option
enable_cairo=no
# never enable hwloc's plugin system
enable_plugins=no
enable_static=yes
enable_shared=no
# Override -- disable hwloc's libxml2 support, but enable the
# native hwloc XML support
enable_libxml2=no
enable_xml=yes
# hwloc checks for compiler visibility, and its needs to do
# this without "picky" flags.
opal_hwloc_hwloc191_save_cflags=$CFLAGS
CFLAGS=$OPAL_CFLAGS_BEFORE_PICKY
HWLOC_SETUP_CORE([opal/mca/hwloc/hwloc191/hwloc],
[AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([yes])
HWLOC_VERSION="internal v`$srcdir/$opal_hwloc_hwloc191_basedir/hwloc/config/hwloc_get_version.sh $srcdir/$opal_hwloc_hwloc191_basedir/hwloc/VERSION`"
# Build flags for our Makefile.am
opal_hwloc_hwloc191_LDFLAGS='$(HWLOC_EMBEDDED_LDFLAGS)'
opal_hwloc_hwloc191_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_hwloc_hwloc191_basedir"'/hwloc/src/libhwloc_embedded.la $(HWLOC_EMBEDDED_LIBS)'
opal_hwloc_hwloc191_support=yes
AC_DEFINE_UNQUOTED([HWLOC_HWLOC191_HWLOC_VERSION],
["$HWLOC_VERSION"],
[Version of hwloc])
# Do we have verbs support?
CPPFLAGS_save=$CPPFLAGS
AS_IF([test "$opal_want_verbs" = "yes"],
[CPPFLAGS="-I$opal_verbs_dir/include $CPPFLAGS"])
AC_CHECK_HEADERS([infiniband/verbs.h])
CPPFLAGS=$CPPFLAGS_save
],
[AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([no])
opal_hwloc_hwloc191_support=no])
CFLAGS=$opal_hwloc_hwloc191_save_cflags
# Restore some env variables, if necessary
AS_IF([test -n "$opal_hwloc_hwloc191_save_cairo"],
[enable_cairo=$opal_hwloc_hwloc191_save_cairo])
AS_IF([test -n "$opal_hwloc_hwloc191_save_xml"],
[enable_xml=$opal_hwloc_hwloc191_save_xml])
AS_IF([test -n "$opal_hwloc_hwloc191_save_static"],
[enable_static=$opal_hwloc_hwloc191_save_static])
AS_IF([test -n "$opal_hwloc_hwloc191_save_shared"],
[enable_shared=$opal_hwloc_hwloc191_save_shared])
AS_IF([test -n "$opal_hwloc_hwloc191_save_plugins"],
[enable_plugins=$opal_hwloc_hwloc191_save_shared])
CPPFLAGS=$opal_hwloc_hwloc191_save_CPPFLAGS
LDFLAGS=$opal_hwloc_hwloc191_save_LDFLAGS
LIBS=$opal_hwloc_hwloc191_save_LIBS
AC_SUBST([opal_hwloc_hwloc191_CFLAGS])
AC_SUBST([opal_hwloc_hwloc191_CPPFLAGS])
AC_SUBST([opal_hwloc_hwloc191_LDFLAGS])
AC_SUBST([opal_hwloc_hwloc191_LIBS])
# Finally, add some flags to the wrapper compiler so that our
# headers can be found.
hwloc_hwloc191_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS"
hwloc_hwloc191_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS"
hwloc_hwloc191_WRAPPER_EXTRA_CPPFLAGS='-I${includedir}/openmpi/'"$opal_hwloc_hwloc191_basedir/hwloc/include"
fi
# Done!
AS_IF([test "$opal_hwloc_hwloc191_support" = "yes"],
[$1],
[$2])
OPAL_VAR_SCOPE_POP
])dnl

Просмотреть файл

@ -1,720 +0,0 @@
Introduction
hwloc provides command line tools and a C API to obtain the hierarchical map of
key computing elements, such as: NUMA memory nodes, shared caches, processor
sockets, processor cores, processing units (logical processors or "threads")
and even I/O devices. hwloc also gathers various attributes such as cache and
memory information, and is portable across a variety of different operating
systems and platforms. Additionally it may assemble the topologies of multiple
machines into a single one so as to let applications consult the topology of an
entire fabric or cluster at once.
hwloc primarily aims at helping high-performance computing (HPC) applications,
but is also applicable to any project seeking to exploit code and/or data
locality on modern computing platforms.
Note that the hwloc project represents the merger of the libtopology project
from inria and the Portable Linux Processor Affinity (PLPA) sub-project from
Open MPI. Both of these prior projects are now deprecated. The first hwloc
release was essentially a "re-branding" of the libtopology code base, but with
both a few genuinely new features and a few PLPA-like features added in. Prior
releases of hwloc included documentation about switching from PLPA to hwloc;
this documentation has been dropped on the assumption that everyone who was
using PLPA has already switched to hwloc.
hwloc supports the following operating systems:
* Linux (including old kernels not having sysfs topology information, with
knowledge of cpusets, offline CPUs, ScaleMP vSMP, NumaScale NumaConnect,
and Kerrighed support)
* Solaris
* AIX
* Darwin / OS X
* FreeBSD and its variants (such as kFreeBSD/GNU)
* NetBSD
* OSF/1 (a.k.a., Tru64)
* HP-UX
* Microsoft Windows
* IBM BlueGene/Q Compute Node Kernel (CNK)
Since it uses standard Operating System information, hwloc's support is mostly
independant from the processor type (x86, powerpc, ...) and just relies on the
Operating System support. The only exception to this is kFreeBSD, which does
not support topology information, and hwloc thus uses an x86-only CPUID-based
backend (which can be used for other OSes too, see the Components and plugins
section).
To check whether hwloc works on a particular machine, just try to build it and
run lstopo or lstopo-no-graphics. If some things do not look right (e.g. bogus
or missing cache information), see Questions and Bugs below.
hwloc only reports the number of processors on unsupported operating systems;
no topology information is available.
For development and debugging purposes, hwloc also offers the ability to work
on "fake" topologies:
* Symmetrical tree of resources generated from a list of level arities
* Remote machine simulation through the gathering of Linux sysfs topology
files
hwloc can display the topology in a human-readable format, either in graphical
mode (X11), or by exporting in one of several different formats, including:
plain text, PDF, PNG, and FIG (see CLI Examples below). Note that some of the
export formats require additional support libraries.
hwloc offers a programming interface for manipulating topologies and objects.
It also brings a powerful CPU bitmap API that is used to describe topology
objects location on physical/logical processors. See the Programming Interface
below. It may also be used to binding applications onto certain cores or memory
nodes. Several utility programs are also provided to ease command-line
manipulation of topology objects, binding of processes, and so on.
Perl bindings are available from Bernd Kallies on CPAN.
Python bindings are available from Guy Streeter:
* Fedora RPM and tarball.
* git tree (html).
Installation
hwloc (http://www.open-mpi.org/projects/hwloc/) is available under the BSD
license. It is hosted as a sub-project of the overall Open MPI project (http://
www.open-mpi.org/). Note that hwloc does not require any functionality from
Open MPI -- it is a wholly separate (and much smaller!) project and code base.
It just happens to be hosted as part of the overall Open MPI project.
Nightly development snapshots are available on the web site. Additionally, the
code can be directly checked out of Subversion:
shell$ git clone https://github.com/open-mpi/hwloc.git
shell$ cd hwloc
shell$ ./autogen.sh
Note that GNU Autoconf >=2.63, Automake >=1.10 and Libtool >=2.2.6 are required
when building from a Subversion checkout.
Installation by itself is the fairly common GNU-based process:
shell$ ./configure --prefix=...
shell$ make
shell$ make install
The hwloc command-line tool "lstopo" produces human-readable topology maps, as
mentioned above. It can also export maps to the "fig" file format. Support for
PDF, Postscript, and PNG exporting is provided if the "Cairo" development
package (usually cairo-devel or libcairo2-dev) can be found in "lstopo" when
hwloc is configured and build.
The hwloc core may also benefit from the following development packages:
* libnuma for memory binding and migration support on Linux (numactl-devel or
libnuma-dev package).
* hwloc can use one of two different libraries for full I/O device discovery:
1. libpciaccess (BSD). The relevant development package is usually
libpciaccess-devel or libpciaccess-dev.
2. libpci, from the pciutils package (GPL). The relevant development
package is usually pciutils-devel or libpci-dev.
On Linux, PCI discovery may still be performed even if none of the above
libraries can be used.
* the AMD OpenCL implementation for OpenCL device discovery.
* the NVIDIA CUDA Toolkit for CUDA device discovery.
* the NVIDIA Tesla Development Kit for NVML device discovery.
* the NV-CONTROL X extension library (NVCtrl) for NVIDIA display discovery.
* libxml2 for full XML import/export support (otherwise, the internal
minimalistic parser will only be able to import XML files that were
exported by the same hwloc release). See Importing and exporting topologies
from/to XML files for details. The relevant development package is usually
libxml2-devel or libxml2-dev.
* libtool's ltdl library for dynamic plugin loading. The relevant development
package is usually libtool-ltdl-devel or libltdl-dev.
PCI and XML support may be statically built inside the main hwloc library, or
as separate dynamically-loaded plugins (see the Components and plugins
section).
Note that because of the possibility of GPL taint (remember that hwloc is
BSD-licensed), hwloc's configure script will prefer libpciaccess to the
pciutils package. Indeed, if libpciaccess is not found, hwloc will not use
pciutils unless it is specifically requested via the --enable-libpci flag is
provided.
Also note that if you install supplemental libraries in non-standard locations,
hwloc's configure script may not be able to find them without some help. You
may need to specify additional CPPFLAGS, LDFLAGS, or PKG_CONFIG_PATH values on
the configure command line.
For example, if libpciaccess was installed into /opt/pciaccess, hwloc's
configure script may not find it be default. Try adding PKG_CONFIG_PATH to the
./configure command line, like this:
./configure PKG_CONFIG_PATH=/opt/pciaccess/lib/pkgconfig ...
CLI Examples
On a 4-socket 2-core machine with hyperthreading, the lstopo tool may show the
following graphical output:
dudley.png
Here's the equivalent output in textual form:
Machine (16GB)
Socket L#0 + L3 L#0 (4096KB)
L2 L#0 (1024KB) + L1 L#0 (16KB) + Core L#0
PU L#0 (P#0)
PU L#1 (P#8)
L2 L#1 (1024KB) + L1 L#1 (16KB) + Core L#1
PU L#2 (P#4)
PU L#3 (P#12)
Socket L#1 + L3 L#1 (4096KB)
L2 L#2 (1024KB) + L1 L#2 (16KB) + Core L#2
PU L#4 (P#1)
PU L#5 (P#9)
L2 L#3 (1024KB) + L1 L#3 (16KB) + Core L#3
PU L#6 (P#5)
PU L#7 (P#13)
Socket L#2 + L3 L#2 (4096KB)
L2 L#4 (1024KB) + L1 L#4 (16KB) + Core L#4
PU L#8 (P#2)
PU L#9 (P#10)
L2 L#5 (1024KB) + L1 L#5 (16KB) + Core L#5
PU L#10 (P#6)
PU L#11 (P#14)
Socket L#3 + L3 L#3 (4096KB)
L2 L#6 (1024KB) + L1 L#6 (16KB) + Core L#6
PU L#12 (P#3)
PU L#13 (P#11)
L2 L#7 (1024KB) + L1 L#7 (16KB) + Core L#7
PU L#14 (P#7)
PU L#15 (P#15)
Finally, here's the equivalent output in XML. Long lines were artificially
broken for document clarity (in the real output, each XML tag is on a single
line), and only socket #0 is shown for brevity:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topology SYSTEM "hwloc.dtd">
<topology>
<object type="Machine" os_index="0" cpuset="0x0000ffff"
complete_cpuset="0x0000ffff" online_cpuset="0x0000ffff"
allowed_cpuset="0x0000ffff"
dmi_board_vendor="Dell Computer Corporation" dmi_board_name="0RD318"
local_memory="16648183808">
<page_type size="4096" count="4064498"/>
<page_type size="2097152" count="0"/>
<object type="Socket" os_index="0" cpuset="0x00001111" ... >
<object type="Cache" cpuset="0x00001111" ...
cache_size="4194304" depth="3" cache_linesize="64">
<object type="Cache" cpuset="0x00000101" ...
cache_size="1048576" depth="2" cache_linesize="64">
<object type="Cache" cpuset="0x00000101" ...
cache_size="16384" depth="1" cache_linesize="64">
<object type="Core" os_index="0" ... >
<object type="PU" os_index="0" cpuset="0x00000001"
complete_cpuset="0x00000001" online_cpuset="0x00000001"
allowed_cpuset="0x00000001"/>
<object type="PU" os_index="8" cpuset="0x00000100"
complete_cpuset="0x00000100" online_cpuset="0x00000100"
allowed_cpuset="0x00000100"/>
</object>
</object>
</object>
<object type="Cache" cpuset="0x00001010" ...
cache_size="1048576" depth="2" cache_linesize="64">
<object type="Cache" cpuset="0x00001010"
cache_size="16384" depth="1" cache_linesize="64">
<object type="Core" os_index="1" cpuset="0x00001010" ... >
<object type="PU" os_index="4" cpuset="0x00000010"
complete_cpuset="0x00000010" online_cpuset="0x00000010"
allowed_cpuset="0x00000010"/>
<object type="PU" os_index="12" cpuset="0x00001000"
complete_cpuset="0x00001000" online_cpuset="0x00001000"
allowed_cpuset="0x00001000"/>
</object>
</object>
</object>
</object>
</object>
<!-- ...other sockets listed here ... -->
</object>
</topology>
On a 4-socket 2-core Opteron NUMA machine, the lstopo tool may show the
following graphical output:
hagrid.png
Here's the equivalent output in textual form:
Machine (32GB)
NUMANode L#0 (P#0 8190MB) + Socket L#0
L2 L#0 (1024KB) + L1 L#0 (64KB) + Core L#0 + PU L#0 (P#0)
L2 L#1 (1024KB) + L1 L#1 (64KB) + Core L#1 + PU L#1 (P#1)
NUMANode L#1 (P#1 8192MB) + Socket L#1
L2 L#2 (1024KB) + L1 L#2 (64KB) + Core L#2 + PU L#2 (P#2)
L2 L#3 (1024KB) + L1 L#3 (64KB) + Core L#3 + PU L#3 (P#3)
NUMANode L#2 (P#2 8192MB) + Socket L#2
L2 L#4 (1024KB) + L1 L#4 (64KB) + Core L#4 + PU L#4 (P#4)
L2 L#5 (1024KB) + L1 L#5 (64KB) + Core L#5 + PU L#5 (P#5)
NUMANode L#3 (P#3 8192MB) + Socket L#3
L2 L#6 (1024KB) + L1 L#6 (64KB) + Core L#6 + PU L#6 (P#6)
L2 L#7 (1024KB) + L1 L#7 (64KB) + Core L#7 + PU L#7 (P#7)
And here's the equivalent output in XML. Similar to above, line breaks were
added and only PU #0 is shown for brevity:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topology SYSTEM "hwloc.dtd">
<topology>
<object type="Machine" os_index="0" cpuset="0x000000ff"
complete_cpuset="0x000000ff" online_cpuset="0x000000ff"
allowed_cpuset="0x000000ff" nodeset="0x000000ff"
complete_nodeset="0x000000ff" allowed_nodeset="0x000000ff"
dmi_board_vendor="TYAN Computer Corp" dmi_board_name="S4881 ">
<page_type size="4096" count="0"/>
<page_type size="2097152" count="0"/>
<object type="NUMANode" os_index="0" cpuset="0x00000003" ...
nodeset="0x00000001" ... local_memory="7514177536">
<page_type size="4096" count="1834516"/>
<page_type size="2097152" count="0"/>
<object type="Socket" os_index="0" cpuset="0x00000003" ... >
<object type="Cache" cpuset="0x00000001" ...
cache_size="1048576" depth="2" cache_linesize="64">
<object type="Cache" cpuset="0x00000001" ...
cache_size="65536" depth="1" cache_linesize="64">
<object type="Core" os_index="0" ... >
<object type="PU" os_index="0" cpuset="0x00000001"
complete_cpuset="0x00000001" online_cpuset="0x00000001"
allowed_cpuset="0x00000001" nodeset="0x00000001"
complete_nodeset="0x00000001" allowed_nodeset="0x00000001"/>
</object>
</object>
</object>
<!-- ...more objects listed here ... -->
</topology>
On a 2-socket quad-core Xeon (pre-Nehalem, with 2 dual-core dies into each
socket):
emmett.png
Here's the same output in textual form:
Machine (16GB)
Socket L#0
L2 L#0 (4096KB)
L1 L#0 (32KB) + Core L#0 + PU L#0 (P#0)
L1 L#1 (32KB) + Core L#1 + PU L#1 (P#4)
L2 L#1 (4096KB)
L1 L#2 (32KB) + Core L#2 + PU L#2 (P#2)
L1 L#3 (32KB) + Core L#3 + PU L#3 (P#6)
Socket L#1
L2 L#2 (4096KB)
L1 L#4 (32KB) + Core L#4 + PU L#4 (P#1)
L1 L#5 (32KB) + Core L#5 + PU L#5 (P#5)
L2 L#3 (4096KB)
L1 L#6 (32KB) + Core L#6 + PU L#6 (P#3)
L1 L#7 (32KB) + Core L#7 + PU L#7 (P#7)
And the same output in XML (line breaks added, only PU #0 shown):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topology SYSTEM "hwloc.dtd">
<topology>
<object type="Machine" os_index="0" cpuset="0x000000ff"
complete_cpuset="0x000000ff" online_cpuset="0x000000ff"
allowed_cpuset="0x000000ff" dmi_board_vendor="Dell Inc."
dmi_board_name="0NR282" local_memory="16865292288">
<page_type size="4096" count="4117503"/>
<page_type size="2097152" count="0"/>
<object type="Socket" os_index="0" cpuset="0x00000055" ... >
<object type="Cache" cpuset="0x00000011" ...
cache_size="4194304" depth="2" cache_linesize="64">
<object type="Cache" cpuset="0x00000001" ...
cache_size="32768" depth="1" cache_linesize="64">
<object type="Core" os_index="0" ... >
<object type="PU" os_index="0" cpuset="0x00000001"
complete_cpuset="0x00000001" online_cpuset="0x00000001"
allowed_cpuset="0x00000001"/>
</object>
</object>
<object type="Cache" cpuset="0x00000010" ...
cache_size="32768" depth="1" cache_linesize="64">
<object type="Core" os_index="1" ... >
<object type="PU" os_index="4" cpuset="0x00000010" ...
complete_cpuset="0x00000010" online_cpuset="0x00000010"
allowed_cpuset="0x00000010"/>
</object>
</object>
</object>
<!-- ...more objects listed here ... -->
</topology>
Programming Interface
The basic interface is available in hwloc.h. Some higher-level functions are
available in hwloc/helper.h to reduce the need to manually manipulate objects
and follow links between them. Documentation for all these is provided later in
this document. Developers may also want to look at hwloc/inlines.h which
contains the actual inline code of some hwloc.h routines, and at this document,
which provides good higher-level topology traversal examples.
To precisely define the vocabulary used by hwloc, a Terms and Definitions
section is available and should probably be read first.
Each hwloc object contains a cpuset describing the list of processing units
that it contains. These bitmaps may be used for CPU binding and Memory binding.
hwloc offers an extensive bitmap manipulation interface in hwloc/bitmap.h.
Moreover, hwloc also comes with additional helpers for interoperability with
several commonly used environments. See the Interoperability With Other
Software section for details.
The complete API 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/.
NOTE: If you are building the documentation 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 install" to $prefix/share/doc/hwloc/ and your systems default man page
tree (under $prefix, of course).
Portability
As shown in CLI Examples, hwloc can obtain information on a wide variety of
hardware topologies. However, some platforms and/or operating system versions
will only report a subset of this information. For example, on an PPC64-based
system with 32 cores (each with 2 hardware threads) running a default
2.6.18-based kernel from RHEL 5.4, hwloc is only able to glean information
about NUMA nodes and processor units (PUs). No information about caches,
sockets, or cores is available.
Similarly, Operating System have varying support for CPU and memory binding,
e.g. while some Operating Systems provide interfaces for all kinds of CPU and
memory bindings, some others provide only interfaces for a limited number of
kinds of CPU and memory binding, and some do not provide any binding interface
at all. Hwloc's binding functions would then simply return the ENOSYS error
(Function not implemented), meaning that the underlying Operating System does
not provide any interface for them. CPU binding and Memory binding provide more
information on which hwloc binding functions should be preferred because
interfaces for them are usually available on the supported Operating Systems.
Here's the graphical output from lstopo on this platform when Simultaneous
Multi-Threading (SMT) is enabled:
ppc64-with-smt.png
And here's the graphical output from lstopo on this platform when SMT is
disabled:
ppc64-without-smt.png
Notice that hwloc only sees half the PUs when SMT is disabled. PU #15, for
example, seems to change location from NUMA node #0 to #1. In reality, no PUs
"moved" -- they were simply re-numbered when hwloc only saw half as many.
Hence, PU #15 in the SMT-disabled picture probably corresponds to PU #30 in the
SMT-enabled picture.
This same "PUs have disappeared" effect can be seen on other platforms -- even
platforms / OSs that provide much more information than the above PPC64 system.
This is an unfortunate side-effect of how operating systems report information
to hwloc.
Note that upgrading the Linux kernel on the same PPC64 system mentioned above
to 2.6.34, hwloc is able to discover all the topology information. The
following picture shows the entire topology layout when SMT is enabled:
ppc64-full-with-smt.png
Developers using the hwloc API or XML output for portable applications should
therefore be extremely careful to not make any assumptions about the structure
of data that is returned. For example, per the above reported PPC topology, it
is not safe to assume that PUs will always be descendants of cores.
Additionally, future hardware may insert new topology elements that are not
available in this version of hwloc. Long-lived applications that are meant to
span multiple different hardware platforms should also be careful about making
structure assumptions. For example, there may someday be an element "lower"
than a PU, or perhaps a new element may exist between a core and a PU.
API Example
The following small C example (named ``hwloc-hello.c'') prints the topology of
the machine and bring the process to the first logical processor of the second
core of the machine.
/* Example hwloc API program.
*
* Copyright (c) 2009-2010 inria. All rights reserved.
* Copyright (c) 2009-2011 Universit?eacute; Bordeaux 1
* Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*
* hwloc-hello.c
*/
#include <hwloc.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
static void print_children(hwloc_topology_t topology, hwloc_obj_t obj,
int depth)
{
char string[128];
unsigned i;
hwloc_obj_snprintf(string, sizeof(string), topology, obj, "#", 0);
printf("%*s%s\n", 2*depth, "", string);
for (i = 0; i < obj->arity; i++) {
print_children(topology, obj->children[i], depth + 1);
}
}
int main(void)
{
int depth;
unsigned i, n;
unsigned long size;
int levels;
char string[128];
int topodepth;
hwloc_topology_t topology;
hwloc_cpuset_t cpuset;
hwloc_obj_t obj;
/* Allocate and initialize topology object. */
hwloc_topology_init(&topology);
/* ... Optionally, put detection configuration here to ignore
some objects types, define a synthetic topology, etc....
The default is to detect all the objects of the machine that
the caller is allowed to access. See Configure Topology
Detection. */
/* Perform the topology detection. */
hwloc_topology_load(topology);
/* Optionally, get some additional topology information
in case we need the topology depth later. */
topodepth = hwloc_topology_get_depth(topology);
/*****************************************************************
* First example:
* Walk the topology with an array style, from level 0 (always
* the system level) to the lowest level (always the proc level).
*****************************************************************/
for (depth = 0; depth < topodepth; depth++) {
printf("*** Objects at level %d\n", depth);
for (i = 0; i < hwloc_get_nbobjs_by_depth(topology, depth);
i++) {
hwloc_obj_snprintf(string, sizeof(string), topology,
hwloc_get_obj_by_depth(topology, depth, i),
"#", 0);
printf("Index %u: %s\n", i, string);
}
}
/*****************************************************************
* Second example:
* Walk the topology with a tree style.
*****************************************************************/
printf("*** Printing overall tree\n");
print_children(topology, hwloc_get_root_obj(topology), 0);
/*****************************************************************
* Third example:
* Print the number of sockets.
*****************************************************************/
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
printf("*** The number of sockets is unknown\n");
} else {
printf("*** %u socket(s)\n",
hwloc_get_nbobjs_by_depth(topology, depth));
}
/*****************************************************************
* Fourth example:
* Compute the amount of cache that the first logical processor
* has above it.
*****************************************************************/
levels = 0;
size = 0;
for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0);
obj;
obj = obj->parent)
if (obj->type == HWLOC_OBJ_CACHE) {
levels++;
size += obj->attr->cache.size;
}
printf("*** Logical processor 0 has %d caches totaling %luKB\n",
levels, size / 1024);
/*****************************************************************
* Fifth example:
* Bind to only one thread of the last core of the machine.
*
* First find out where cores are, or else smaller sets of CPUs if
* the OS doesn't have the notion of a "core".
*****************************************************************/
depth = hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_CORE);
/* Get last core. */
obj = hwloc_get_obj_by_depth(topology, depth,
hwloc_get_nbobjs_by_depth(topology, depth) - 1);
if (obj) {
/* Get a copy of its cpuset that we may modify. */
cpuset = hwloc_bitmap_dup(obj->cpuset);
/* Get only one logical processor (in case the core is
SMT/hyperthreaded). */
hwloc_bitmap_singlify(cpuset);
/* And try to bind ourself there. */
if (hwloc_set_cpubind(topology, cpuset, 0)) {
char *str;
int error = errno;
hwloc_bitmap_asprintf(&str, obj->cpuset);
printf("Couldn't bind to cpuset %s: %s\n", str, strerror(error));
free(str);
}
/* Free our cpuset copy */
hwloc_bitmap_free(cpuset);
}
/*****************************************************************
* Sixth example:
* Allocate some memory on the last NUMA node, bind some existing
* memory to the last NUMA node.
*****************************************************************/
/* Get last node. */
n = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NODE);
if (n) {
void *m;
size = 1024*1024;
obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NODE, n - 1);
m = hwloc_alloc_membind_nodeset(topology, size, obj->nodeset,
HWLOC_MEMBIND_DEFAULT, 0);
hwloc_free(topology, m, size);
m = malloc(size);
hwloc_set_area_membind_nodeset(topology, m, size, obj->nodeset,
HWLOC_MEMBIND_DEFAULT, 0);
free(m);
}
/* Destroy topology object. */
hwloc_topology_destroy(topology);
return 0;
}
hwloc provides a pkg-config 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):
CFLAGS += $(pkg-config --cflags hwloc)
LDLIBS += $(pkg-config --libs hwloc)
cc hwloc-hello.c $(CFLAGS) -o hwloc-hello $(LDLIBS)
On a machine with 4GB of RAM and 2 processor sockets -- each socket of which
has two processing cores -- the output from running hwloc-hello could be
something like the following:
shell$ ./hwloc-hello
*** Objects at level 0
Index 0: Machine(3938MB)
*** Objects at level 1
Index 0: Socket#0
Index 1: Socket#1
*** Objects at level 2
Index 0: Core#0
Index 1: Core#1
Index 2: Core#3
Index 3: Core#2
*** Objects at level 3
Index 0: PU#0
Index 1: PU#1
Index 2: PU#2
Index 3: PU#3
*** Printing overall tree
Machine(3938MB)
Socket#0
Core#0
PU#0
Core#1
PU#1
Socket#1
Core#3
PU#2
Core#2
PU#3
*** 2 socket(s)
shell$
Questions and Bugs
Questions should be sent to the devel mailing list (http://www.open-mpi.org/
community/lists/hwloc.php). Bug reports should be reported in the tracker (
https://git.open-mpi.org/trac/hwloc/).
If hwloc discovers an incorrect topology for your machine, the very first thing
you should check is to ensure that you have the most recent updates installed
for your operating system. Indeed, most of hwloc topology discovery relies on
hardware information retrieved through the operation system (e.g., via the /sys
virtual filesystem of the Linux kernel). If upgrading your OS or Linux kernel
does not solve your problem, you may also want to ensure that you are running
the most recent version of the BIOS for your machine.
If those things fail, contact us on the mailing list for additional help.
Please attach the output of lstopo after having given the --enable-debug option
to ./configure and rebuilt completely, to get debugging output. Also attach the
/proc + /sys tarball generated by the installed script hwloc-gather-topology
when submitting problems about Linux, or send the output of kstat cpu_info in
the Solaris case, or the output of sysctl hw in the Darwin or BSD cases.
History / Credits
hwloc is the evolution and merger of the libtopology (http://
runtime.bordeaux.inria.fr/libtopology/) project and the Portable Linux
Processor Affinity (PLPA) (http://www.open-mpi.org/projects/plpa/) project.
Because of functional and ideological overlap, these two code bases and ideas
were merged and released under the name "hwloc" as an Open MPI sub-project.
libtopology was initially developed by the inria Runtime Team-Project (http://
runtime.bordeaux.inria.fr/) (headed by Raymond Namyst (http://
dept-info.labri.fr/~namyst/). PLPA was initially developed by the Open MPI
development team as a sub-project. Both are now deprecated in favor of hwloc,
which is distributed as an Open MPI sub-project.
Further Reading
The documentation chapters include
* Terms and Definitions
* Command-Line Tools
* Environment Variables
* CPU and Memory Binding Overview
* I/O Devices
* Multi-node Topologies
* Object attributes
* Importing and exporting topologies from/to XML files
* Synthetic topologies
* Interoperability With Other Software
* Thread Safety
* Components and plugins
* Embedding hwloc in Other Software
* Frequently Asked Questions
Make sure to have had a look at those too!

1221
opal/mca/hwloc/hwloc191/hwloc/aclocal.m4 поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,270 +0,0 @@
#! /bin/sh
# Wrapper for Microsoft lib.exe
me=ar-lib
scriptversion=2012-03-01.08; # UTC
# Copyright (C) 2010-2013 Free Software Foundation, Inc.
# Written by Peter Rosin <peda@lysator.liu.se>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
# func_error message
func_error ()
{
echo "$me: $1" 1>&2
exit 1
}
file_conv=
# func_file_conv build_file
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv in
mingw)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin)
file=`cygpath -m "$file" || echo "$file"`
;;
wine)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_at_file at_file operation archive
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
# for each of them.
# When interpreting the content of the @FILE, do NOT use func_file_conv,
# since the user would need to supply preconverted file names to
# binutils ar, at least for MinGW.
func_at_file ()
{
operation=$2
archive=$3
at_file_contents=`cat "$1"`
eval set x "$at_file_contents"
shift
for member
do
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
done
}
case $1 in
'')
func_error "no command. Try '$0 --help' for more information."
;;
-h | --h*)
cat <<EOF
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
Members may be specified in a file named with @FILE.
EOF
exit $?
;;
-v | --v*)
echo "$me, version $scriptversion"
exit $?
;;
esac
if test $# -lt 3; then
func_error "you must specify a program, an action and an archive"
fi
AR=$1
shift
while :
do
if test $# -lt 2; then
func_error "you must specify a program, an action and an archive"
fi
case $1 in
-lib | -LIB \
| -ltcg | -LTCG \
| -machine* | -MACHINE* \
| -subsystem* | -SUBSYSTEM* \
| -verbose | -VERBOSE \
| -wx* | -WX* )
AR="$AR $1"
shift
;;
*)
action=$1
shift
break
;;
esac
done
orig_archive=$1
shift
func_file_conv "$orig_archive"
archive=$file
# strip leading dash in $action
action=${action#-}
delete=
extract=
list=
quick=
replace=
index=
create=
while test -n "$action"
do
case $action in
d*) delete=yes ;;
x*) extract=yes ;;
t*) list=yes ;;
q*) quick=yes ;;
r*) replace=yes ;;
s*) index=yes ;;
S*) ;; # the index is always updated implicitly
c*) create=yes ;;
u*) ;; # TODO: don't ignore the update modifier
v*) ;; # TODO: don't ignore the verbose modifier
*)
func_error "unknown action specified"
;;
esac
action=${action#?}
done
case $delete$extract$list$quick$replace,$index in
yes,* | ,yes)
;;
yesyes*)
func_error "more than one action specified"
;;
*)
func_error "no action specified"
;;
esac
if test -n "$delete"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
for member
do
case $1 in
@*)
func_at_file "${1#@}" -REMOVE "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
;;
esac
done
elif test -n "$extract"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
if test $# -gt 0; then
for member
do
case $1 in
@*)
func_at_file "${1#@}" -EXTRACT "$archive"
;;
*)
func_file_conv "$1"
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
;;
esac
done
else
$AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
do
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
done
fi
elif test -n "$quick$replace"; then
if test ! -f "$orig_archive"; then
if test -z "$create"; then
echo "$me: creating $orig_archive"
fi
orig_archive=
else
orig_archive=$archive
fi
for member
do
case $1 in
@*)
func_file_conv "${1#@}"
set x "$@" "@$file"
;;
*)
func_file_conv "$1"
set x "$@" "$file"
;;
esac
shift
shift
done
if test -n "$orig_archive"; then
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
else
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
fi
elif test -n "$list"; then
if test ! -f "$orig_archive"; then
func_error "archive not found"
fi
$AR -NOLOGO -LIST "$archive" || exit $?
fi

Просмотреть файл

@ -1,347 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше