1
1

As per the telecon, update hwloc to v1.7.2 so we can add MIC support. Ignore hwloc1.5.2 component for now until this tests out - will remove it then.

cmr:v1.7.4:reviewer=jsquyres

This commit was SVN r29107.
Этот коммит содержится в:
Ralph Castain 2013-09-03 16:23:42 +00:00
родитель 2bfa99e945
Коммит 6011a4d29c
105 изменённых файлов: 95417 добавлений и 0 удалений

0
opal/mca/hwloc/hwloc152/.ompi_ignore Обычный файл
Просмотреть файл

67
opal/mca/hwloc/hwloc172/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,67 @@
#
# Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# Need to include these files so that these directories are carried in
# the tarball (in case someone invokes autogen.sh on a dist tarball).
EXTRA_DIST = \
hwloc/doc/README.txt \
hwloc/tests/README.txt \
hwloc/utils/README.txt
SUBDIRS = hwloc
# Headers and sources
headers = hwloc172.h
sources = hwloc172_component.c
# We only ever build this component statically
noinst_LTLIBRARIES = libmca_hwloc_hwloc172.la
libmca_hwloc_hwloc172_la_SOURCES = $(headers) $(sources)
nodist_libmca_hwloc_hwloc172_la_SOURCES = $(nodist_headers)
libmca_hwloc_hwloc172_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc172_LDFLAGS)
libmca_hwloc_hwloc172_la_LIBADD = $(opal_hwloc_hwloc172_LIBS)
libmca_hwloc_hwloc172_la_DEPENDENCIES = \
$(HWLOC_top_builddir)/src/libhwloc_embedded.la
# Since the rest of the code base includes the underlying hwloc.h, we
# also have to install the underlying header files when
# --with-devel-headers is specified. hwloc doesn't support this; the
# least gross way to make this happen is just to list all of hwloc's
# header files here. :-(
headers += \
hwloc/include/hwloc.h \
hwloc/include/hwloc/bitmap.h \
hwloc/include/hwloc/helper.h \
hwloc/include/hwloc/myriexpress.h \
hwloc/include/hwloc/openfabrics-verbs.h \
hwloc/include/hwloc/cuda.h \
hwloc/include/hwloc/cudart.h \
hwloc/include/hwloc/rename.h \
hwloc/include/private/private.h \
hwloc/include/private/debug.h \
hwloc/include/private/misc.h \
hwloc/include/private/cpuid.h
nodist_headers = hwloc/include/hwloc/autogen/config.h
if HWLOC_HAVE_LINUX
headers += \
hwloc/include/hwloc/linux.h \
hwloc/include/hwloc/linux-libnuma.h
endif HWLOC_HAVE_LINUX
if HWLOC_HAVE_SCHED_SETAFFINITY
headers += hwloc/include/hwloc/glibc-sched.h
endif HWLOC_HAVE_SCHED_SETAFFINITY
# Conditionally install the header files
if WANT_INSTALL_HEADERS
opaldir = $(includedir)/openmpi/$(subdir)
nobase_opal_HEADERS = $(headers)
nobase_nodist_opal_HEADERS = $(nodist_headers)
endif

3
opal/mca/hwloc/hwloc172/README-ompi.txt Обычный файл
Просмотреть файл

@ -0,0 +1,3 @@
Applied the following patches from the upstream hwloc 1.7 branch after
the v1.7.2 release:

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

@ -0,0 +1,155 @@
# -*- shell-script -*-
#
# Copyright (c) 2009-2013 Cisco Systems, Inc. All rights reserved.
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
#
# Priority
#
AC_DEFUN([MCA_opal_hwloc_hwloc172_PRIORITY], [75])
#
# Force this component to compile in static-only mode
#
AC_DEFUN([MCA_opal_hwloc_hwloc172_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/hwloc172/hwloc/config/hwloc.m4)
m4_include(opal/mca/hwloc/hwloc172/hwloc/config/hwloc_pkg.m4)
m4_include(opal/mca/hwloc/hwloc172/hwloc/config/hwloc_check_attributes.m4)
m4_include(opal/mca/hwloc/hwloc172/hwloc/config/hwloc_check_visibility.m4)
m4_include(opal/mca/hwloc/hwloc172/hwloc/config/hwloc_check_vendor.m4)
m4_include(opal/mca/hwloc/hwloc172/hwloc/config/hwloc_components.m4)
# MCA_hwloc_hwloc172_POST_CONFIG()
# ---------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc172_POST_CONFIG],[
OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc172_basedir])
# If we won, then do all the rest of the setup
AS_IF([test "$1" = "1"],
[
# Set this variable so that the framework m4 knows what
# file to include in opal/mca/hwloc/hwloc.h
opal_hwloc_hwloc172_basedir=opal/mca/hwloc/hwloc172
opal_hwloc_base_include="$opal_hwloc_hwloc172_basedir/hwloc172.h"
# Add some stuff to CPPFLAGS so that the rest of the source
# tree can be built
file=$opal_hwloc_hwloc172_basedir/hwloc
CPPFLAGS="$CPPFLAGS -I$OMPI_TOP_SRCDIR/$file/include"
AS_IF([test "$OMPI_TOP_BUILDDIR" != "$OMPI_TOP_SRCDIR"],
[CPPFLAGS="$CPPFLAGS -I$OMPI_TOP_BUILDDIR/$file/include"])
unset file
])
OPAL_VAR_SCOPE_POP
# This must be run unconditionally
HWLOC_DO_AM_CONDITIONALS
])dnl
# MCA_hwloc_hwloc172_CONFIG([action-if-found], [action-if-not-found])
# --------------------------------------------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc172_CONFIG],[
# Hwloc needs to know if we have Verbs support
AC_REQUIRE([OPAL_CHECK_VERBS_DIR])
AC_CONFIG_FILES([opal/mca/hwloc/hwloc172/Makefile])
OPAL_VAR_SCOPE_PUSH([HWLOC_VERSION opal_hwloc_hwloc172_save_CPPFLAGS opal_hwloc_hwloc172_save_LDFLAGS opal_hwloc_hwloc172_save_LIBS opal_hwloc_hwloc172_save_cairo opal_hwloc_hwloc172_save_xml opal_hwloc_hwloc172_basedir opal_hwloc_hwloc172_file opal_hwloc_hwloc172_save_cflags])
# default to this component not providing support
opal_hwloc_hwloc172_basedir=opal/mca/hwloc/hwloc172
opal_hwloc_hwloc172_support=no
if test "$with_hwloc" = "internal" -o "$with_hwloc" = "" -o "$with_hwloc" = "yes"; then
opal_hwloc_hwloc172_save_CPPFLAGS=$CPPFLAGS
opal_hwloc_hwloc172_save_LDFLAGS=$LDFLAGS
opal_hwloc_hwloc172_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_hwloc172_])
# save XML or graphical options
opal_hwloc_hwloc172_save_cairo=$enable_cairo
opal_hwloc_hwloc172_save_xml=$enable_xml
# never enable hwloc's graphical option
enable_cairo=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_hwloc172_save_cflags=$CFLAGS
CFLAGS=$OMPI_CFLAGS_BEFORE_PICKY
HWLOC_SETUP_CORE([opal/mca/hwloc/hwloc172/hwloc],
[AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([yes])
HWLOC_VERSION="internal v`$srcdir/$opal_hwloc_hwloc172_basedir/hwloc/config/hwloc_get_version.sh $srcdir/$opal_hwloc_hwloc172_basedir/hwloc/VERSION`"
# Build flags for our Makefile.am
opal_hwloc_hwloc172_LDFLAGS='$(HWLOC_EMBEDDED_LDFLAGS)'
opal_hwloc_hwloc172_LIBS='$(top_ompi_builddir)/'"$opal_hwloc_hwloc172_basedir"'/hwloc/src/libhwloc_embedded.la $(HWLOC_EMBEDDED_LIBS)'
opal_hwloc_hwloc172_support=yes
AC_DEFINE_UNQUOTED([HWLOC_HWLOC172_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_hwloc172_support=no])
CFLAGS=$opal_hwloc_hwloc172_save_cflags
# Restore some env variables, if necessary
AS_IF([test -n "$opal_hwloc_hwloc172_save_cairo"],
[enable_cairo=$opal_hwloc_hwloc172_save_cairo])
AS_IF([test -n "$opal_hwloc_hwloc172_save_xml"],
[enable_xml=$opal_hwloc_hwloc172_save_xml])
CPPFLAGS=$opal_hwloc_hwloc172_save_CPPFLAGS
LDFLAGS=$opal_hwloc_hwloc172_save_LDFLAGS
LIBS=$opal_hwloc_hwloc172_save_LIBS
AC_SUBST([opal_hwloc_hwloc172_CFLAGS])
AC_SUBST([opal_hwloc_hwloc172_CPPFLAGS])
AC_SUBST([opal_hwloc_hwloc172_LDFLAGS])
AC_SUBST([opal_hwloc_hwloc172_LIBS])
# Finally, add some flags to the wrapper compiler so that our
# headers can be found.
hwloc_hwloc172_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS"
hwloc_hwloc172_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS"
hwloc_hwloc172_WRAPPER_EXTRA_CPPFLAGS='-I${includedir}/openmpi/'"$opal_hwloc_hwloc172_basedir/hwloc/include"
fi
# Done!
AS_IF([test "$opal_hwloc_hwloc172_support" = "yes"],
[$1],
[$2])
OPAL_VAR_SCOPE_POP
])dnl

8
opal/mca/hwloc/hwloc172/hwloc/AUTHORS Обычный файл
Просмотреть файл

@ -0,0 +1,8 @@
Cédric Augonnet <Cedric.Augonnet@labri.fr>
Jérôme Clet-Ortega <Jerome.Clet-Ortega@labri.fr>
Ludovic Courtès <Ludovic.Courtes@inria.fr>
Brice Goglin <Brice.Goglin@inria.fr>
Nathalie Furmento <Nathalie.Furmento@labri.fr>
Samuel Thibault <Samuel.Thibault@labri.fr>
Jeff Squyres <jsquyres@cisco.com>
Alexey Kardashevskiy <aik@au1.ibm.com>

28
opal/mca/hwloc/hwloc172/hwloc/COPYING Обычный файл
Просмотреть файл

@ -0,0 +1,28 @@
Copyright © 2009 CNRS
Copyright © 2009 inria. All rights reserved.
Copyright © 2009 Université Bordeaux 1
Copyright © 2009 Cisco Systems, Inc. All rights reserved.
Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
See COPYING in top-level directory.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

92
opal/mca/hwloc/hwloc172/hwloc/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,92 @@
# Copyright © 2009 inria. All rights reserved.
# Copyright © 2009 Université Bordeaux 1
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory.
# Note that the -I directory must *exactly* match what was specified
# via AC_CONFIG_MACRO_DIR in configure.ac.
ACLOCAL_AMFLAGS = -I ./config
SUBDIRS = src include
if HWLOC_BUILD_STANDALONE
SUBDIRS += utils tests
# 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
SUBDIRS += doc
endif
# Do not let automake automatically add the non-standalone dirs to the
# distribution tarball if we're building in embedded mode.
DIST_SUBDIRS = $(SUBDIRS)
# Only install the pkg file if we're building in standalone mode (and not on Windows)
if HWLOC_BUILD_STANDALONE
if !HWLOC_HAVE_WINDOWS
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = hwloc.pc
endif
endif
# Only install the valgrind suppressions file if we're building in standalone mode
if HWLOC_BUILD_STANDALONE
dist_pkgdata_DATA = contrib/hwloc-valgrind.supp
endif
#
# "make distcheck" requires that tarballs are able to be able to "make
# dist", so we have to include config/distscript.csh.
#
EXTRA_DIST = \
README VERSION COPYING AUTHORS \
config/hwloc_get_version.sh \
config/distscript.csh
if HWLOC_BUILD_STANDALONE
#
# Double check that we generated both the doxygen docs and a new copy
# of the top-level README file.
#
cannot-dist:
@echo "ERROR: Did not build both of the doxygen docs and README."
@echo "ERROR: This tarball is not complete!"
@echo "ERROR: Cowardly refusing to complete successfully..."
@exit 1
# Refuse to make dist if we can't make the doxygen stuff (note that
# BUILD_DOXYGEN will automatically be false if we're not building
# standalone).
if !HWLOC_BUILD_DOXYGEN
dist-hook: cannot-dist
else
if !HWLOC_BUILD_README
dist-hook: cannot-dist
else
dist-hook:
csh "$(top_srcdir)/config/distscript.csh" "$(top_srcdir)" "$(distdir)" "$(HWLOC_VERSION)" "$(HWLOC_SVN_R)"
endif HWLOC_BUILD_README
endif HWLOC_BUILD_DOXYGEN
endif HWLOC_BUILD_STANDALONE
#
# Build the top-level README file
#
if HWLOC_BUILD_STANDALONE
.PHONY: doc readme
doc readme:
$(MAKE) -C doc readme
endif HWLOC_BUILD_STANDALONE
if HWLOC_BUILD_STANDALONE
if HWLOC_HAVE_WINDOWS
#
# Winball specific rules
#
install-data-local:
sed -e 's/$$/'$$'\015'/ < $(srcdir)/README > $(DESTDIR)$(prefix)/README.txt
sed -e 's/$$/'$$'\015'/ < $(srcdir)/NEWS > $(DESTDIR)$(prefix)/NEWS.txt
sed -e 's/$$/'$$'\015'/ < $(srcdir)/COPYING > $(DESTDIR)$(prefix)/COPYING.txt
uninstall-local:
rm -f $(DESTDIR)$(prefix)/README.txt $(DESTDIR)$(prefix)/NEWS.txt $(DESTDIR)$(prefix)/COPYING.txt
endif HWLOC_HAVE_WINDOWS
endif HWLOC_BUILD_STANDALONE

859
opal/mca/hwloc/hwloc172/hwloc/NEWS Обычный файл
Просмотреть файл

@ -0,0 +1,859 @@
Copyright © 2009 CNRS
Copyright © 2009-2013 Inria. All rights reserved.
Copyright © 2009-2013 Université Bordeaux 1
Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
$COPYRIGHT$
Additional copyrights may follow
$HEADER$
===========================================================================
This file contains the main features as well as overviews of specific
bug fixes (and other actions) for each version of hwloc since version
0.9 (as initially released as "libtopology", then re-branded to "hwloc"
in v0.9.1).
Version 1.7.2
-------------
* Do not create invalid block OS devices on very old Linux kernel such
as RHEL4 2.6.9.
* Fix PCI subvendor/device IDs.
* Fix the management of Misc objects inserted by parent.
Thanks to Jirka Hladky for reporting the problem.
* Add a Port<n>State into attribute to OpenFabrics OS devices.
* Add a MICSerialNumber info attribute to Xeon PHI/MIC OS devices.
* Improve verbose error messages when failing to load from XML.
Version 1.7.1
-------------
* Fix a failed assertion in the distance grouping code when loading a XML
file that already contains some groups.
Thanks to Laercio Lima Pilla for reporting the problem.
* Remove unexpected Group objects when loading XML topologies with I/O
objects and NUMA distances.
Thanks to Elena Elkina for reporting the problem and testing patches.
* Fix PCI link speed discovery when using libpciaccess.
* Fix invalid libpciaccess virtual function device/vendor IDs when using
SR-IOV PCI devices on Linux.
* Fix GL component build with old NVCtrl releases.
Thanks to Jirka Hladky for reporting the problem.
* Fix embedding breakage caused by libltdl.
Thanks to Pavan Balaji for reporting the problem.
* Always use the system-wide libltdl instead of shipping one inside hwloc.
* Document issues when enabling plugins while embedding hwloc in another
project, in the documentation section Embedding hwloc in Other Software.
* Add a FAQ entry "How to get useful topology information on NetBSD?"
in the documentation.
* Somes fixes in the renaming code for embedding.
* Miscellaneous minor build fixes.
Version 1.7.0
-------------
* New operating system backends
+ Add BlueGene/Q compute node kernel (CNK) support. See the FAQ in the
documentation for details. Thanks to Jeff Hammond, Christopher Samuel
and Erik Schnetter for their help.
+ Add NetBSD support, thanks to Aleksej Saushev.
* New I/O device discovery
+ Add co-processor OS devices such as "mic0" for Intel Xeon Phi (MIC)
on Linux. Thanks to Jerome Vienne for helping.
+ Add co-processor OS devices such as "cuda0" for NVIDIA CUDA-capable GPUs.
+ Add co-processor OS devices such as "opencl0d0" for OpenCL GPU devices
on the AMD OpenCL implementation.
+ Add GPU OS devices such as ":0.0" for NVIDIA X11 displays.
+ Add GPU OS devices such as "nvml0" for NVIDIA GPUs.
Thanks to Marwan Abdellah and Stefan Eilemann for helping.
These new OS devices have some string info attributes such as CoProcType,
GPUModel, etc. to better identify them.
See the I/O Devices and Attributes documentation sections for details.
* New components
+ Add the "opencl", "cuda", "nvml" and "gl" components for I/O device
discovery.
+ "nvml" also improves the discovery of NVIDIA GPU PCIe link speed.
All of these new components may be built as plugins. They may also be
disabled entirely by passing --disable-opencl/cuda/nvml/gl to configure.
See the I/O Devices, Components and Plugins, and FAQ documentation
sections for details.
* API
+ Add hwloc_topology_get_flags().
+ Add hwloc/plugins.h for building external plugins.
See the Adding new discovery components and plugins section.
* Interoperability
+ Add hwloc/opencl.h, hwloc/nvml.h, hwloc/gl.h and hwloc/intel-mic.h
to retrieve the locality of OS devices that correspond to AMD OpenCL
GPU devices or indexes, to NVML devices or indexes, to NVIDIA X11
displays, or to Intel Xeon Phi (MIC) device indexes.
+ Add new helpers in hwloc/cuda.h and hwloc/cudart.h to convert
between CUDA devices or indexes and hwloc OS devices.
+ Add hwloc_ibv_get_device_osdev() and clarify the requirements
of the OpenFabrics Verbs helpers in hwloc/openfabrics-verbs.h.
* Tools
+ hwloc-info is not only a synonym of lstopo -s anymore, it also
dumps information about objects given on the command-line.
* Documentation
+ Add a section "Existing components and plugins".
+ Add a list of common OS devices in section "Software devices".
+ Add a new FAQ entry "Why is lstopo slow?" about lstopo slowness
issues because of GPUs.
+ Clarify the documentation of inline helpers in hwloc/myriexpress.h
and hwloc/openfabrics-verbs.h.
* Misc
+ Improve cache detection on AIX.
+ The HWLOC_COMPONENTS variable now excludes the components whose
names are prefixed with '-'.
+ lstopo --ignore PU now works when displaying the topology in
graphical and textual mode (not when exporting to XML).
+ Make sure I/O options always appear in lstopo usage, not only when
using pciutils/libpci.
+ Remove some unneeded Linux specific includes from some interoperability
headers.
+ Fix some inconsistencies in hwloc-distrib and hwloc-assembler-remote
manpages. Thanks to Guy Streeter for the report.
+ Fix a memory leak on AIX when getting memory binding.
+ Fix many small memory leaks on Linux.
+ The `libpci' component is now called `pci' but the old name is still
accepted in the HWLOC_COMPONENTS variable for backward compatibility.
Version 1.6.2
-------------
* Use libpciaccess instead of pciutils/libpci by default for I/O discovery.
pciutils/libpci is only used if --enable-libpci is given to configure
because its GPL license may taint hwloc. See the Installation section
in the documentation for details.
* Fix get_cpubind on Solaris when bound to a single PU with
processor_bind(). Thanks to Eugene Loh for reporting the problem
and providing a patch.
Version 1.6.1
-------------
* Fix some crash or buggy detection in the x86 backend when Linux
cgroups/cpusets restrict the available CPUs.
* Fix the pkg-config output with --libs --static.
Thanks to Erik Schnetter for reporting one of the problems.
* Fix the output of hwloc-calc -H --hierarchical when using logical
indexes in the output.
* Calling hwloc_topology_load() multiple times on the same topology
is officially deprecated. hwloc will warn in such cases.
* Add some documentation about existing plugins/components, package
dependencies, and I/O devices specification on the command-line.
Version 1.6.0
-------------
* Major changes
+ Reorganize the backend infrastructure to support dynamic selection
of components and dynamic loading of plugins. For details, see the
new documentation section Components and plugins.
- The HWLOC_COMPONENTS variable lets one replace the default discovery
components.
- Dynamic loading of plugins may be enabled with --enable-plugins
(except on AIX and Windows). It will build libxml2 and libpci
support as separated modules. This helps reducing the dependencies
of the core hwloc library when distributed as a binary package.
* Backends
+ Add CPUModel detection on Darwin and x86/FreeBSD.
Thanks to Robin Scher for providing ways to implement this.
+ The x86 backend now adds CPUModel info attributes to socket objects
created by other backends that do not natively support this attribute.
+ Fix detection on FreeBSD in case of cpuset restriction. Thanks to
Sebastian Kuzminsky for reporting the problem.
* XML
+ Add hwloc_topology_set_userdata_import/export_callback(),
hwloc_export_obj_userdata() and _userdata_base64() to let
applications specify how to save/restore the custom data they placed
in the userdata private pointer field of hwloc objects.
* Tools
+ Add hwloc-annotate program to add string info attributes to XML
topologies.
+ Add --pid-cmd to hwloc-ps to append the output of a command to each
PID line. May be used for showing Open MPI process ranks, see the
hwloc-ps(1) manpage for details.
+ hwloc-bind now exits with an error if binding fails; the executable
is not launched unless binding suceeeded or --force was given.
+ Add --quiet to hwloc-calc and hwloc-bind to hide non-fatal error
messages.
+ Fix command-line pid support in windows tools.
+ All programs accept --verbose as a synonym to -v.
* Misc
+ Fix some DIR descriptor leaks on Linux.
+ Fix I/O device lists when some were filtered out after a XML import.
+ Fix the removal of I/O objects when importing a I/O-enabled XML topology
without any I/O topology flag.
+ When merging objects with HWLOC_IGNORE_TYPE_KEEP_STRUCTURE or
lstopo --merge, compare object types before deciding which one of two
identical object to remove (e.g. keep sockets in favor of caches).
+ Add some GUID- and LID-related info attributes to OpenFabrics
OS devices.
+ Only add CPUType socket attributes on Solaris/Sparc. Other cases
don't report reliable information (Solaris/x86), and a replacement
is available as the Architecture string info in the Machine object.
+ Add missing Backend string info on Solaris in most cases.
+ Document object attributes and string infos in a new Attributes
section in the documentation.
+ Add a section about Synthetic topologies in the documentation.
Version 1.5.2 (some of these changes are in v1.6.2 but not in v1.6)
-------------
* Use libpciaccess instead of pciutils/libpci by default for I/O discovery.
pciutils/libpci is only used if --enable-libpci is given to configure
because its GPL license may taint hwloc. See the Installation section
in the documentation for details.
* Fix get_cpubind on Solaris when bound to a single PU with
processor_bind(). Thanks to Eugene Loh for reporting the problem
and providing a patch.
* Fix some DIR descriptor leaks on Linux.
* Fix I/O device lists when some were filtered out after a XML import.
* Add missing Backend string info on Solaris in most cases.
* Fix the removal of I/O objects when importing a I/O-enabled XML topology
without any I/O topology flag.
* Fix the output of hwloc-calc -H --hierarchical when using logical
indexes in the output.
* Fix the pkg-config output with --libs --static.
Thanks to Erik Schnetter for reporting one of the problems.
Version 1.5.1
-------------
* Fix block OS device detection on Linux kernel 3.3 and later.
Thanks to Guy Streeter for reporting the problem and testing the fix.
* Fix the cpuid code in the x86 backend (for FreeBSD). Thanks to
Sebastian Kuzminsky for reporting problems and testing patches.
* Fix 64bit detection on FreeBSD.
* Fix some corner cases in the management of the thissystem flag with
respect to topology flags and environment variables.
* Fix some corner cases in command-line parsing checks in hwloc-distrib
and hwloc-distances.
* Make sure we do not miss some block OS devices on old Linux kernels
when a single PCI device has multiple IDE hosts/devices behind it.
* Do not disable I/O devices or instruction caches in hwloc-assembler output.
Version 1.5.0
-------------
* Backends
+ Do not limit the number of processors to 1024 on Solaris anymore.
+ Gather total machine memory on FreeBSD.
+ 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
decimal separator.
+ Add instruction caches detection on Linux, AIX, Windows and Darwin.
+ Add get_last_cpu_location() support for the current thread on AIX.
+ Support binding on AIX when threads or processes were bound with
bindprocessor(). Thanks to Hendryk Bockelmann for reporting the issue
and testing patches, and to Farid Parpia for explaining the binding
interfaces.
+ Improve AMD topology detection in the x86 backend (for FreeBSD) using
the topoext feature.
* API
+ Increase HWLOC_API_VERSION to 0x00010500 so that API changes may be
detected at build-time.
+ Add a cache type attribute describind Data, Instruction and Unified
caches. Caches with different types but same depth (for instance L1d
and L1i) are placed on different levels.
+ Add hwloc_get_cache_type_depth() to retrieve the hwloc level depth of
of the given cache depth and type, for instance L1i or L2.
It helps disambiguating the case where hwloc_get_type_depth() returns
HWLOC_TYPE_DEPTH_MULTIPLE.
+ Instruction caches are ignored unless HWLOC_TOPOLOGY_FLAG_ICACHES is
passed to hwloc_topology_set_flags() before load.
+ Add hwloc_ibv_get_device_osdev_by_name() OpenFabrics helper in
openfabrics-verbs.h to find the hwloc OS device object corresponding to
an OpenFabrics device.
* Tools
+ Add lstopo-no-graphics, a lstopo built without graphical support to
avoid dependencies on external libraries such as Cairo and X11. When
supported, graphical outputs are only available in the original lstopo
program.
- Packagers splitting lstopo and lstopo-no-graphics into different
packages are advised to use the alternatives system so that lstopo
points to the best available binary.
+ Instruction caches are enabled in lstopo by default. User --no-icaches
to disable them.
+ Add -t/--threads to show threads in hwloc-ps.
* Removal of obsolete components
+ Remove the old cpuset interface (hwloc/cpuset.h) which is deprecated and
superseded by the bitmap API (hwloc/bitmap.h) since v1.1.
hwloc_cpuset and nodeset types are still defined, but all hwloc_cpuset_*
compatibility wrappers are now gone.
+ Remove Linux libnuma conversion helpers for the deprecated and
broken nodemask_t interface.
+ Remove support for "Proc" type name, it was superseded by "PU" in v1.0.
+ Remove hwloc-mask symlinks, it was replaced by hwloc-calc in v1.0.
* Misc
+ Fix PCIe 3.0 link speed computation.
+ Non-printable characters are dropped from strings during XML export.
+ Fix importing of escaped characters with the minimalistic XML backend.
+ Assert hwloc_is_thissystem() in several I/O related helpers.
+ Fix some memory leaks in the x86 backend for FreeBSD.
+ Minor fixes to ease native builds on Windows.
+ Limit the number of retries when operating on all threads within a
process on Linux if the list of threads is heavily getting modified.
Version 1.4.3
-------------
* This release is only meant to fix the pciutils license issue when upgrading
to hwloc v1.5 or later is not possible. It contains several other minor
fixes but ignores many of them that are only in v1.5 or later.
* Use libpciaccess instead of pciutils/libpci by default for I/O discovery.
pciutils/libpci is only used if --enable-libpci is given to configure
because its GPL license may taint hwloc. See the Installation section
in the documentation for details.
* Fix PCIe 3.0 link speed computation.
* Fix importing of escaped characters with the minimalistic XML backend.
* Fix a memory leak in the x86 backend.
Version 1.4.2
-------------
* Fix build on Solaris 9 and earlier when fabsf() is not a compiler
built-in. Thanks to Igor Galić for reporting the problem.
* Fix support for more than 32 processors on Windows. Thanks to Hartmut
Kaiser for reporting the problem.
* Fix process-wide binding and cpulocation routines on Linux when some
threads disappear in the meantime. Thanks to Vlad Roubtsov for reporting
the issue.
* Make installed scripts executable. Thanks to Jirka Hladky for reporting
the problem.
* Fix libtool revision management when building for Windows. This fix was
also released as hwloc v1.4.1.1 Windows builds. Thanks to Hartmut Kaiser
for reporting the problem.
* Fix the __hwloc_inline keyword in public headers when compiling with a
C++ compiler.
* Add Port info attribute to network OS devices inside OpenFabrics PCI
devices so as to identify which interface corresponds to which port.
* Document requirements for interoperability helpers: I/O devices discovery
is required for some of them; the topology must match the current host
for most of them.
Version 1.4.1
-------------
* This release contains all changes from v1.3.2.
* Fix hwloc_alloc_membind, thanks Karl Napf for reporting the issue.
* Fix memory leaks in some get_membind() functions.
* Fix helpers converting from Linux libnuma to hwloc (hwloc/linux-libnuma.h)
in case of out-of-order NUMA node ids.
* Fix some overzealous assertions in the distance grouping code.
* Workaround BIOS reporting empty I/O locality in cuda and openfabrics
helpers on Linux. Thanks to Albert Solernou for reporting the problem.
* Install a valgrind suppressions file hwloc-valgrind.supp (see the FAQ).
* Fix memory binding documentation. Thanks to Karl Napf for reporting the
issues.
Version 1.4.0 (does not contain all v1.3.2 changes)
-------------
* Major features
+ Add "custom" interface and "assembler" tools to build multi-node
topology. See the Multi-node Topologies section in the documentation
for details.
* Interface improvements
+ Add symmetric_subtree object attribute to ease assumptions when consulting
regular symmetric topologies.
+ Add a CPUModel and CPUType info attribute to Socket objects on Linux
and Solaris.
+ Add hwloc_get_obj_index_inside_cpuset() to retrieve the "logical" index
of an object within a subtree of the topology.
+ Add more NVIDIA CUDA helpers in cuda.h and cudart.h to find hwloc objects
corresponding to CUDA devices.
* Discovery improvements
+ Add a group object above partial distance matrices to make sure
the matrices are available in the final topology, except when this
new object would contradict the existing hierarchy.
+ Grouping by distances now also works when loading from XML.
+ Fix some corner cases in object insertion, for instance when dealing
with NUMA nodes without any CPU.
* Backends
+ Implement hwloc_get_area_membind() on Linux.
+ Honor I/O topology flags when importing from XML.
+ Further improve XML-related error checking and reporting.
+ Hide synthetic topology error messages unless HWLOC_SYNTHETIC_VERBOSE=1.
* Tools
+ Add synthetic exporting of symmetric topologies to lstopo.
+ lstopo --horiz and --vert can now be applied to some specific object types.
+ lstopo -v -p now displays distance matrices with physical indexes.
+ Add hwloc-distances utility to list distances.
* Documentation
+ Fix and/or document the behavior of most inline functions in hwloc/helper.h
when the topology contains some I/O or Misc objects.
+ Backend documentation enhancements.
* Bug fixes
+ Fix missing last bit in hwloc_linux_get_thread_cpubind().
Thanks to Carolina Gómez-Tostón Gutiérrez for reporting the issue.
+ Fix FreeBSD build without cpuid support.
+ Fix several Windows build issues.
+ Fix inline keyword definition in public headers.
+ Fix dependencies in the embedded library.
+ Improve visibility support detection. Thanks to Dave Love for providing
the patch.
+ Remove references to internal symbols in the tools.
Version 1.3.3
-------------
* This release is only meant to fix the pciutils license issue when upgrading
to hwloc v1.4 or later is not possible. It contains several other minor
fixes but ignores many of them that are only in v1.4 or later.
* Use libpciaccess instead of pciutils/libpci by default for I/O discovery.
pciutils/libpci is only used if --enable-libpci is given to configure
because its GPL license may taint hwloc. See the Installation section
in the documentation for details.
Version 1.3.2
-------------
* Fix missing last bit in hwloc_linux_get_thread_cpubind().
Thanks to Carolina Gómez-Tostón Gutiérrez for reporting the issue.
* Fix build with -mcmodel=medium. Thanks to Devendar Bureddy for reporting
the issue.
* Fix build with Solaris Studio 12 compiler when XML is disabled.
Thanks to Paul H. Hargrove for reporting the problem.
* Fix installation with old GNU sed, for instance on Red Hat 8.
Thanks to Paul H. Hargrove for reporting the problem.
* Fix PCI locality when Linux cgroups restrict the available CPUs.
* Fix floating point issue when grouping by distance on mips64 architecture.
Thanks to Paul H. Hargrove for reporting the problem.
* Fix conversion from/to Linux libnuma when some NUMA nodes have no memory.
* Fix support for gccfss compilers with broken ffs() support. Thanks to
Paul H. Hargrove for reporting the problem and providing a patch.
* Fix FreeBSD build without cpuid support.
* Fix several Windows build issues.
* Fix inline keyword definition in public headers.
* Fix dependencies in the embedded library.
* Detect when a compiler such as xlc may not report compile errors
properly, causing some configure checks to be wrong. Thanks to
Paul H. Hargrove for reporting the problem and providing a patch.
* Improve visibility support detection. Thanks to Dave Love for providing
the patch.
* Remove references to internal symbols in the tools.
* Fix installation on systems with limited command-line size.
Thanks to Paul H. Hargrove for reporting the problem.
* Further improve XML-related error checking and reporting.
Version 1.3.1
-------------
* Fix pciutils detection with pkg-config when not installed in standard
directories.
* Fix visibility options detection with the Solaris Studio compiler.
Thanks to Igor Galić and Terry Dontje for reporting the problems.
* Fix support for old Linux sched.h headers such as those found
on Red Hat 8. Thanks to Paul H. Hargrove for reporting the problems.
* Fix inline and attribute support for Solaris compilers. Thanks to
Dave Love for reporting the problems.
* Print a short summary at the end of the configure output. Thanks to
Stefan Eilemann for the suggestion.
* Add --disable-libnuma configure option to disable libnuma-based
memory binding support on Linux. Thanks to Rayson Ho for the
suggestion.
* Make hwloc's configure script properly obey $PKG_CONFIG. Thanks to
Nathan Phillip Brink for raising the issue.
* Silence some harmless pciutils warnings, thanks to Paul H. Hargrove
for reporting the problem.
* Fix the documentation with respect to hwloc_pid_t and hwloc_thread_t
being either pid_t and pthread_t on Unix, or HANDLE on Windows.
Version 1.3.0
-------------
* Major features
+ Add I/O devices and bridges to the topology using the pciutils
library. Only enabled after setting the relevant flag with
hwloc_topology_set_flags() before hwloc_topology_load(). See the
I/O Devices section in the documentation for details.
* Discovery improvements
+ Add associativity to the cache attributes.
+ Add support for s390/z11 "books" on Linux.
+ Add the HWLOC_GROUPING_ACCURACY environment variable to relax
distance-based grouping constraints. See the Environment Variables
section in the documentation for details about grouping behavior
and configuration.
+ Allow user-given distance matrices to remove or replace those
discovered by the OS backend.
* XML improvements
+ XML is now always supported: a minimalistic custom import/export
code is used when libxml2 is not available. It is only guaranteed
to read XML files generated by hwloc.
+ hwloc_topology_export_xml() and export_xmlbuffer() now return an
integer.
+ Add hwloc_free_xmlbuffer() to free the buffer allocated by
hwloc_topology_export_xmlbuffer().
+ Hide XML topology error messages unless HWLOC_XML_VERBOSE=1.
* Minor API updates
+ Add hwloc_obj_add_info to customize object info attributes.
* Tools
+ lstopo now displays I/O devices by default. Several options are
added to configure the I/O discovery.
+ hwloc-calc and hwloc-bind now accept I/O devices as input.
+ Add --restrict option to hwloc-calc and hwloc-distribute.
+ Add --sep option to change the output field separator in hwloc-calc.
+ Add --whole-system option to hwloc-ps.
Version 1.2.2
-------------
* Fix build on AIX 5.2, thanks Utpal Kumar Ray for the report.
* Fix XML import of very large page sizes or counts on 32bits platform,
thanks to Karsten Hopp for the RedHat ticket.
* Fix crash when administrator limitations such as Linux cgroup require
to restrict distance matrices. Thanks to Ake Sandgren for reporting the
problem.
* Fix the removal of objects such as AMD Magny-Cours dual-node sockets
in case of administrator restrictions.
* Improve error reporting and messages in case of wrong synthetic topology
description.
* Several other minor internal fixes and documentation improvements.
Version 1.2.1
-------------
* Improve support of AMD Bulldozer "Compute-Unit" modules by detecting
logical processors with different core IDs on Linux.
* Fix hwloc-ps crash when listing processes from another Linux cpuset.
Thanks to Carl Smith for reporting the problem.
* Fix build on AIX and Solaris. Thanks to Carl Smith and Andreas Kupries
for reporting the problems.
* Fix cache size detection on Darwin. Thanks to Erkcan Özcan for reporting
the problem.
* Make configure fail if --enable-xml or --enable-cairo is given and
proper support cannot be found. Thanks to Andreas Kupries for reporting
the XML problem.
* Fix spurious L1 cache detection on AIX. Thanks to Hendryk Bockelmann
for reporting the problem.
* Fix hwloc_get_last_cpu_location(THREAD) on Linux. Thanks to Gabriele
Fatigati for reporting the problem.
* Fix object distance detection on Solaris.
* Add pthread_self weak symbol to ease static linking.
* Minor documentation fixes.
Version 1.2.0
-------------
* Major features
+ Expose latency matrices in the API as an array of distance structures
within objects. Add several helpers to find distances.
+ Add hwloc_topology_set_distance_matrix() and environment variables
to provide a matrix of distances between a given set of objects.
+ Add hwloc_get_last_cpu_location() and hwloc_get_proc_last_cpu_location()
to retrieve the processors where a process or thread recently ran.
- Add the corresponding --get-last-cpu-location option to hwloc-bind.
+ Add hwloc_topology_restrict() to restrict an existing topology to a
given cpuset.
- Add the corresponding --restrict option to lstopo.
* Minor API updates
+ Add hwloc_bitmap_list_sscanf/snprintf/asprintf to convert between bitmaps
and strings such as 4-5,7-9,12,15-
+ hwloc_bitmap_set/clr_range() now support infinite ranges.
+ Clarify the difference between inserting Misc objects by cpuset or by
parent.
+ hwloc_insert_misc_object_by_cpuset() now returns NULL in case of error.
* Discovery improvements
+ x86 backend (for freebsd): add x2APIC support
+ Support standard device-tree phandle, to get better support on e.g. ARM
systems providing it.
+ Detect cache size on AIX. Thanks Christopher and IBM.
+ Improve grouping to support asymmetric topologies.
* Tools
+ Command-line tools now support "all" and "root" special locations
consisting in the entire topology, as well as type names with depth
attributes such as L2 or Group4.
+ hwloc-calc improvements:
- Add --number-of/-N option to report the number of objects of a given
type or depth.
- -I is now equivalent to --intersect for listing the indexes of
objects of a given type or depth that intersects the input.
- Add -H to report the output as a hierarchical combination of types
and depths.
+ Add --thissystem to lstopo.
+ Add lstopo-win, a console-less lstopo variant on Windows.
* Miscellaneous
+ Remove C99 usage from code base.
+ Rename hwloc-gather-topology.sh into hwloc-gather-topology
+ Fix AMD cache discovery on freebsd when there is no L3 cache, thanks
Andriy Gapon for the fix.
Version 1.1.2
-------------
* Fix a segfault in the distance-based grouping code when some objects
are not placed in any group. Thanks to Bernd Kallies for reporting
the problem and providing a patch.
* Fix the command-line parsing of hwloc-bind --mempolicy interleave.
Thanks to Guy Streeter for reporting the problem.
* Stop truncating the output in hwloc_obj_attr_snprintf() and in the
corresponding lstopo output. Thanks to Guy Streeter for reporting the
problem.
* Fix object levels ordering in synthetic topologies.
* Fix potential incoherency between device tree and kernel information,
when SMT is disabled on Power machines.
* Fix and document the behavior of hwloc_topology_set_synthetic() in case
of invalid argument. Thanks to Guy Streeter for reporting the problem.
* Add some verbose error message reporting when it looks like the OS
gives erroneous information.
* Do not include unistd.h and stdint.h in public headers on Windows.
* Move config.h files into their own subdirectories to avoid name
conflicts when AC_CONFIG_HEADERS adds -I's for them.
* Remove the use of declaring variables inside "for" loops.
* Some other minor fixes.
* Many minor documentation fixes.
Version 1.1.1
-------------
* Add hwloc_get_api_version() which returns the version of hwloc used
at runtime. Thanks to Guy Streeter for the suggestion.
* Fix the number of hugepages reported for NUMA nodes on Linux.
* Fix hwloc_bitmap_to_ulong() right after allocating the bitmap.
Thanks to Bernd Kallies for reporting the problem.
* Fix hwloc_bitmap_from_ith_ulong() to properly zero the first ulong.
Thanks to Guy Streeter for reporting the problem.
* Fix hwloc_get_membind_nodeset() on Linux.
Thanks to Bernd Kallies for reporting the problem and providing a patch.
* Fix some file descriptor leaks in the Linux discovery.
* Fix the minimum width of NUMA nodes, caches and the legend in the graphical
lstopo output. Thanks to Jirka Hladky for reporting the problem.
* Various fixes to bitmap conversion from/to taskset-strings.
* Fix and document snprintf functions behavior when the buffer size is too
small or zero. Thanks to Guy Streeter for reporting the problem.
* Fix configure to avoid spurious enabling of the cpuid backend.
Thanks to Tim Anderson for reporting the problem.
* Cleanup error management in hwloc-gather-topology.sh.
Thanks to Jirka Hladky for reporting the problem and providing a patch.
* Add a manpage and usage for hwloc-gather-topology.sh on Linux.
Thanks to Jirka Hladky for providing a patch.
* Memory binding documentation enhancements.
Version 1.1.0
-------------
* API
+ Increase HWLOC_API_VERSION to 0x00010100 so that API changes may be
detected at build-time.
+ Add a memory binding interface.
+ The cpuset API (hwloc/cpuset.h) is now deprecated. It is replaced by
the bitmap API (hwloc/bitmap.h) which offers the same features with more
generic names since it applies to CPU sets, node sets and more.
Backward compatibility with the cpuset API and ABI is still provided but
it will be removed in a future release.
Old types (hwloc_cpuset_t, ...) are still available as a way to clarify
what kind of hwloc_bitmap_t each API function manipulates.
Upgrading to the new API only requires to replace hwloc_cpuset_ function
calls with the corresponding hwloc_bitmap_ calls, with the following
renaming exceptions:
- hwloc_cpuset_cpu -> hwloc_bitmap_only
- hwloc_cpuset_all_but_cpu -> hwloc_bitmap_allbut
- hwloc_cpuset_from_string -> hwloc_bitmap_sscanf
+ Add an `infos' array in each object to store couples of info names and
values. It enables generic storage of things like the old dmi board infos
that were previously stored in machine specific attributes.
+ Add linesize cache attribute.
* Features
+ Bitmaps (and thus CPU sets and node sets) are dynamically (re-)allocated,
the maximal number of CPUs (HWLOC_NBMAXCPUS) has been removed.
+ Improve the distance-based grouping code to better support irregular
distance matrices.
+ Add support for device-tree to get cache information (useful on Power
architectures).
* Helpers
+ Add NVIDIA CUDA helpers in cuda.h and cudart.h to ease interoperability
with CUDA Runtime and Driver APIs.
+ Add Myrinet Express helper in myriexpress.h to ease interoperability.
* Tools
+ lstopo now displays physical/OS indexes by default in graphical mode
(use -l to switch back to logical indexes). The textual output still uses
logical by default (use -p to switch to physical indexes).
+ lstopo prefixes logical indexes with `L#' and physical indexes with `P#'.
Physical indexes are also printed as `P#N' instead of `phys=N' within
object attributes (in parentheses).
+ Add a legend at the bottom of the lstopo graphical output, use --no-legend
to remove it.
+ Add hwloc-ps to list process' bindings.
+ Add --membind and --mempolicy options to hwloc-bind.
+ Improve tools command-line options by adding a generic --input option
(and more) which replaces the old --xml, --synthetic and --fsys-root.
+ Cleanup lstopo output configuration by adding --output-format.
+ Add --intersect in hwloc-calc, and replace --objects with --largest.
+ Add the ability to work on standard input in hwloc-calc.
+ Add --from, --to and --at in hwloc-distrib.
+ Add taskset-specific functions and command-line tools options to
manipulate CPU set strings in the format of the taskset program.
+ Install hwloc-gather-topology.sh on Linux.
Version 1.0.3
-------------
* Fix support for Linux cpuset when emulated by a cgroup mount point.
* Remove unneeded runtime dependency on libibverbs.so in the library and
all utils programs.
* Fix hwloc_cpuset_to_linux_libnuma_ulongs in case of non-linear OS-indexes
for NUMA nodes.
* lstopo now displays physical/OS indexes by default in graphical mode
(use -l to switch back to logical indexes). The textual output still uses
logical by default (use -p to switch to physical indexes).
Version 1.0.2
-------------
* Public headers can now be included directly from C++ programs.
* Solaris fix for non-contiguous cpu numbers. Thanks to Rolf vandeVaart for
reporting the issue.
* Darwin 10.4 fix. Thanks to Olivier Cessenat for reporting the issue.
* Revert 1.0.1 patch that ignored sockets with unknown ID values since it
only slightly helped POWER7 machines with old Linux kernels while it
prevents recent kernels from getting the complete POWER7 topology.
* Fix hwloc_get_common_ancestor_obj().
* Remove arch-specific bits in public headers.
* Some fixes in the lstopo graphical output.
* Various man page clarifications and minor updates.
Version 1.0.1
-------------
* Various Solaris fixes. Thanks to Yannick Martin for reporting the issue.
* Fix "non-native" builds on x86 platforms (e.g., when building 32
bit executables with compilers that natively build 64 bit).
* Ignore sockets with unknown ID values (which fixes issues on POWER7
machines). Thanks to Greg Bauer for reporting the issue.
* Various man page clarifications and minor updates.
* Fixed memory leaks in hwloc_setup_group_from_min_distance_clique().
* Fix cache type filtering on MS Windows 7. Thanks to Αλέξανδρος
Παπαδογιαννάκ for reporting the issue.
* Fixed warnings when compiling with -DNDEBUG.
Version 1.0.0
-------------
* The ABI of the library has changed.
* Backend updates
+ Add FreeBSD support.
+ Add x86 cpuid based backend.
+ Add Linux cgroup support to the Linux cpuset code.
+ Support binding of entire multithreaded process on Linux.
+ Fix and enable Group support in Windows.
+ Cleanup XML export/import.
* Objects
+ HWLOC_OBJ_PROC is renamed into HWLOC_OBJ_PU for "Processing Unit",
its stringified type name is now "PU".
+ Use new HWLOC_OBJ_GROUP objects instead of MISC when grouping
objects according to NUMA distances or arbitrary OS aggregation.
+ Rework memory attributes.
+ Add different cpusets in each object to specify processors that
are offline, unavailable, ...
+ Cleanup the storage of object names and DMI infos.
* Features
+ Add support for looking up specific PID topology information.
+ Add hwloc_topology_export_xml() to export the topology in a XML file.
+ Add hwloc_topology_get_support() to retrieve the supported features
for the current topology context.
+ Support non-SYSTEM object as the root of the tree, use MACHINE in
most common cases.
+ Add hwloc_get_*cpubind() routines to retrieve the current binding
of processes and threads.
* API
+ Add HWLOC_API_VERSION to help detect the currently used API version.
+ Add missing ending "e" to *compare* functions.
+ Add several routines to emulate PLPA functions.
+ Rename and rework the cpuset and/or/xor/not/clear operators to output
their result in a dedicated argument instead of modifying one input.
+ Deprecate hwloc_obj_snprintf() in favor of hwloc_obj_type/attr_snprintf().
+ Clarify the use of parent and ancestor in the API, do not use father.
+ Replace hwloc_get_system_obj() with hwloc_get_root_obj().
+ Return -1 instead of HWLOC_OBJ_TYPE_MAX in the API since the latter
isn't public.
+ Relax constraints in hwloc_obj_type_of_string().
+ Improve displaying of memory sizes.
+ Add 0x prefix to cpuset strings.
* Tools
+ lstopo now displays logical indexes by default, use --physical to
revert back to OS/physical indexes.
+ Add colors in the lstopo graphical outputs to distinguish between online,
offline, reserved, ... objects.
+ Extend lstopo to show cpusets, filter objects by type, ...
+ Renamed hwloc-mask into hwloc-calc which supports many new options.
* Documentation
+ Add a hwloc(7) manpage containing general information.
+ Add documentation about how to switch from PLPA to hwloc.
+ Cleanup the distributed documentation files.
* Miscellaneous
+ Many compilers warning fixes.
+ Cleanup the ABI by using the visibility attribute.
+ Add project embedding support.
Version 0.9.4 (unreleased)
--------------------------
* Fix reseting colors to normal in lstopo -.txt output.
* Fix Linux pthread_t binding error report.
Version 0.9.3
-------------
* Fix autogen.sh to work with Autoconf 2.63.
* Fix various crashes in particular conditions:
- xml files with root attributes
- offline CPUs
- partial sysfs support
- unparseable /proc/cpuinfo
- ignoring NUMA level while Misc level have been generated
* Tweak documentation a bit
* Do not require the pthread library for binding the current thread on Linux
* Do not erroneously consider the sched_setaffinity prototype is the old version
when there is actually none.
* Fix _syscall3 compilation on archs for which we do not have the
sched_setaffinity system call number.
* Fix AIX binding.
* Fix libraries dependencies: now only lstopo depends on libtermcap, fix
binutils-gold link
* Have make check always build and run hwloc-hello.c
* Do not limit size of a cpuset.
Version 0.9.2
-------------
* Trivial documentation changes.
Version 0.9.1
-------------
* Re-branded to "hwloc" and moved to the Open MPI project, relicensed under the
BSD license.
* The prefix of all functions and tools is now hwloc, and some public
functions were also renamed for real.
* Group NUMA nodes into Misc objects according to their physical distance
that may be reported by the OS/BIOS.
May be ignored by setting HWLOC_IGNORE_DISTANCES=1 in the environment.
* Ignore offline CPUs on Solaris.
* Improved binding support on AIX.
* Add HP-UX support.
* CPU sets are now allocated/freed dynamically.
* Add command line options to tune the lstopo graphical output, add
semi-graphical textual output
* Extend topobind to support multiple cpusets or objects on the command
line as topomask does.
* Add an Infiniband-specific helper hwloc/openfabrics-verbs.h to retrieve
the physical location of IB devices.
Version 0.9 (libtopology)
-------------------------
* First release.

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

@ -0,0 +1,720 @@
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, 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$ svn checkout http://svn.open-mpi.org/svn/hwloc/trunk hwloc-trunk
shell$ cd hwloc-trunk
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 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.
* 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. It essentially offers low-level
routines for advanced programmers that want to manually manipulate objects and
follow links between them. Documentation for everything in hwloc.h are provided
later in this document. Developers should also look at hwloc/helper.h (and also
in 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://svn.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.sh
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!
-------------------------------------------------------------------------------
Generated on Thu Aug 29 2013 09:44:35 for Hardware Locality (hwloc) by
doxygen 1.8.4

61
opal/mca/hwloc/hwloc172/hwloc/VERSION Обычный файл
Просмотреть файл

@ -0,0 +1,61 @@
# This is the VERSION file for hwloc, describing the precise version
# of hwloc in this distribution. The various components of the version
# number below are combined to form a single version number string.
# major, minor, and release are generally combined in the form
# <major>.<minor>.<release>. If release is zero, then it is omitted.
major=1
minor=7
release=2
# 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
# numeric. Common examples include a1 (alpha release 1), b1 (beta
# release 1), sc2005 (Super Computing 2005 release). The only
# requirement is that it must be entirely printable ASCII characters
# and have no white space.
greek=rc1
# If want_repo_rev=1, then the SVN r number will be included in the overall
# hwloc version number in some form.
want_repo_rev=0
# If repo_rev=-1, then the repository version number will be obtained
# dynamically at run time, either:
#
# 1) via the "svnversion" command (if this is a Subversion checkout)
# in the form "r<svn_r>", or
# 2) via the "hg -v -R tip" command (if this is a Mercurial clone)
# in the form of "hg<hash>", using the hash tag at the tip
# 3) via the "git log -1" command (if this is a Git clone) in the form
# of "git<hash>", using the hash tag at the HEAD
# 4) with the date (if none of the above work) in the form of
# "date<date>".
#
# Alternatively, if repo_rev is not -1, the value of repo_rev_r will
# be directly appended to the version string. This happens during
# "make dist", for example: if the distribution tarball is being made
# from an SVN checkout, if repo_rev=-1, then its value is replaced
# with the output of "svnversion".
repo_rev=r5771M
# The date when this release was created
date="Aug 29, 2013"
# The shared library version of hwloc's public library. This version
# is maintained in accordance with the "Library Interface Versions"
# chapter from the GNU Libtool documentation. Notes:
# 1. Since version numbers are associated with *releases*, the version
# number maintained on the hwloc SVN trunk (and developer branches) is
# always 0:0:0.
# 2. Version numbers are described in the Libtool current:revision:age
# format.
libhwloc_so_version=8:2:3

1121
opal/mca/hwloc/hwloc172/hwloc/aclocal.m4 поставляемый Обычный файл

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

270
opal/mca/hwloc/hwloc172/hwloc/config/ar-lib Исполняемый файл
Просмотреть файл

@ -0,0 +1,270 @@
#! /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

347
opal/mca/hwloc/hwloc172/hwloc/config/compile Исполняемый файл
Просмотреть файл

@ -0,0 +1,347 @@
#! /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:

1535
opal/mca/hwloc/hwloc172/hwloc/config/config.guess поставляемый Исполняемый файл

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

1790
opal/mca/hwloc/hwloc172/hwloc/config/config.sub поставляемый Исполняемый файл

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

790
opal/mca/hwloc/hwloc172/hwloc/config/depcomp Исполняемый файл
Просмотреть файл

@ -0,0 +1,790 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2012-10-18.11; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# 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.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# 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:

240
opal/mca/hwloc/hwloc172/hwloc/config/distscript.csh Исполняемый файл
Просмотреть файл

@ -0,0 +1,240 @@
#! /bin/csh -f
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright © 2010 inria. All rights reserved.
# Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
set builddir="`pwd`"
set srcdir="$1"
cd "$srcdir"
set srcdir=`pwd`
cd "$builddir"
set distdir="$builddir/$2"
set HWLOC_VERSION="$3"
set HWLOC_REPO_REV="$4"
if ("$distdir" == "") then
echo "Must supply relative distdir as argv[2] -- aborting"
exit 1
elif ("$HWLOC_VERSION" == "") then
echo "Must supply version as argv[1] -- aborting"
exit 1
endif
#========================================================================
if ("$srcdir" != "$builddir") then
set vpath=1
set vpath_msg=yes
else
set vpath=0
set vpath_msg=no
endif
# We can catch some hard (but possible) to do mistakes by looking at
# our tree's revision number, but only if we are in the source tree.
# Otherwise, use what configure told us, at the cost of allowing one
# or two corner cases in (but otherwise VPATH builds won't work).
set repo_rev=$HWLOC_REPO_REV
if (-d .svn) then
set repo_rev="r`svnversion .`"
endif
set start=`date`
cat <<EOF
Creating hwloc distribution
In directory: `pwd`
Srcdir: $srcdir
Builddir: $builddir
VPATH: $vpath_msg
Version: $HWLOC_VERSION
Started: $start
EOF
umask 022
if (! -d "$distdir") then
echo "*** ERROR: dist dir does not exist"
echo "*** ERROR: $distdir"
exit 1
endif
#
# See if we need to update the version file with the current repo
# revision number. Do this *before* entering the distribution tree to
# solve a whole host of problems with VPATH (since srcdir may be
# relative or absolute)
#
set cur_repo_rev="`grep '^repo_rev' ${distdir}/VERSION | cut -d= -f2`"
if ("$cur_repo_rev" == "-1") then
sed -e 's/^repo_rev=.*/repo_rev='$repo_rev'/' "${distdir}/VERSION" > "${distdir}/version.new"
cp "${distdir}/version.new" "${distdir}/VERSION"
rm -f "${distdir}/version.new"
# need to reset the timestamp to not annoy AM dependencies
touch -r "${srcdir}/VERSION" "${distdir}/VERSION"
echo "*** Updated VERSION file with repo rev number: $repo_rev"
else
echo "*** Did NOT update VERSION file with repo rev number"
endif
#
# VPATH builds only work if the srcdir has valid docs already built.
# If we're VPATH and the srcdir doesn't have valid docs, then fail.
#
if ($vpath == 1 && ! -d $srcdir/doc/doxygen-doc) then
echo "*** This is a VPATH 'make dist', but the srcdir does not already"
echo "*** have a doxygen-doc tree built. hwloc's config/distscript.csh"
echo "*** requores the docs to be built in the srcdir before executing"
echo "*** 'make dist' in a VPATH build."
exit 1
endif
#
# If we're not VPATH, force the generation of new doxygen documentation
#
if ($vpath == 0) then
# Not VPATH
echo "*** Making new doxygen documentation (doxygen-doc tree)"
echo "*** Directory: srcdir: $srcdir, distdir: $distdir, pwd: `pwd`"
cd doc
# We're still in the src tree, so kill any previous doxygen-docs
# tree and make a new one.
chmod -R a=rwx doxygen-doc
rm -rf doxygen-doc
make
if ($status != 0) then
echo ERROR: generating doxygen docs failed
echo ERROR: cannot continue
exit 1
endif
# Make new README file
echo "*** Making new README"
make readme
if ($status != 0) then
echo ERROR: generating new README failed
echo ERROR: cannot continue
exit 1
endif
else
echo "*** This is a VPATH build; assuming that the doxygen docs and REAME"
echo "*** are current in the srcdir (i.e., we'll just copy those)"
endif
echo "*** Copying doxygen-doc tree to dist..."
echo "*** Directory: srcdir: $srcdir, distdir: $distdir, pwd: `pwd`"
chmod -R a=rwx $distdir/doc/doxygen-doc
echo rm -rf $distdir/doc/doxygen-doc
rm -rf $distdir/doc/doxygen-doc
echo cp -rpf $srcdir/doc/doxygen-doc $distdir/doc
cp -rpf $srcdir/doc/doxygen-doc $distdir/doc
echo "*** Copying new README"
ls -lf $distdir/README
cp -pf $srcdir/README $distdir
#########################################################
# VERY IMPORTANT: Now go into the new distribution tree #
#########################################################
cd "$distdir"
echo "*** Now in distdir: $distdir"
#
# Remove all the latex source files from the distribution tree (the
# PDFs are still there; we're just removing the latex source because
# some of the filenames get really, really long...).
#
echo "*** Removing latex source from dist tree"
rm -rf doc/doxygen-doc/latex
#
# Get the latest config.guess and config.sub from ftp.gnu.org
#
echo "*** Downloading latest config.sub/config.guess from ftp.gnu.org..."
cd config
set configdir="`pwd`"
mkdir tmp.$$
cd tmp.$$
# Official HTTP git mirrors for config.guess / config.sub
wget -t 1 -T 10 -O config.guess 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=master'
wget -t 1 -T 10 -O config.sub 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=master'
chmod +x config.guess config.sub
# Recently, ftp.gnu.org has had zero-legnth config.guess / config.sub
# files, which causes the automated nightly SVN snapshot tarball to
# fail to be made correctly. This is a primitive attempt to fix that.
# If we got zero-length files from wget, use a config.guess /
# config.sub from a known location that is more recent than what ships
# in the current generation of auto* tools. Also check to ensure that
# the resulting scripts are runnable (Jan 2009: there are un-runnable
# scripts available right now because of some git vulnerability).
# Before you complain about this too loudly, remember that we're using
# unreleased software...
set happy=0
if (! -f config.guess || ! -s config.guess) then
echo " - WARNING: Got bad config.guess from ftp.gnu.org (non-existent or empty)"
else
./config.guess >& /dev/null
if ($status != 0) then
echo " - WARNING: Got bad config.guess from ftp.gnu.org (not executable)"
else
if (! -f config.sub || ! -s config.sub) then
echo " - WARNING: Got bad config.sub from ftp.gnu.org (non-existent or empty)"
else
./config.sub `./config.guess` >& /dev/null
if ($status != 0) then
echo " - WARNING: Got bad config.sub from ftp.gnu.org (not executable)"
else
echo " - Got good config.guess and config.sub from ftp.gnu.org"
chmod +w ../config.sub ../config.guess
cp config.sub config.guess ..
set happy=1
endif
endif
endif
endif
if ("$happy" == "0") then
echo " - WARNING: using included versions for both config.sub and config.guess"
endif
cd ..
rm -rf tmp.$$
cd ..
#
# All done
#
cat <<EOF
*** hwloc version $HWLOC_VERSION distribution created
Started: $start
Ended: `date`
EOF

1323
opal/mca/hwloc/hwloc172/hwloc/config/hwloc.m4 Обычный файл

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

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

@ -0,0 +1,533 @@
# This macro set originally copied from Open MPI:
# Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# and renamed for hwloc:
# Copyright (c) 2009 inria. All rights reserved.
# Copyright (c) 2009 Université Bordeaux 1
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer listed
# in this license in the documentation and/or other materials
# provided with the distribution.
#
# - Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# The copyright holders provide no reassurances that the source code
# provided does not infringe any patent, copyright, or any other
# intellectual property rights of third parties. The copyright holders
# disclaim any liability to any recipient for claims brought against
# recipient by any third party for infringement of that parties
# intellectual property rights.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# Search the generated warnings for
# keywords regarding skipping or ignoring certain attributes
# Intel: ignore
# Sun C++: skip
#
AC_DEFUN([_HWLOC_ATTRIBUTE_FAIL_SEARCH],[
# Be safe for systems that have ancient Autoconf's (e.g., RHEL5)
m4_ifdef([AC_PROG_GREP],
[AC_REQUIRE([AC_PROG_GREP])],
[GREP=grep])
if test -s conftest.err ; then
for i in ignore skip ; do
$GREP -iq $i conftest.err
if test "$?" = "0" ; then
hwloc_cv___attribute__[$1]=0
break;
fi
done
fi
])
#
# HWLOC: Remove C++ compiler check. It can result in a circular
# dependency in embedded situations.
#
# Check for one specific attribute by compiling with C
# and possibly using a cross-check.
#
# If the cross-check is defined, a static function "usage" should be
# defined, which is to be called from main (to circumvent warnings
# regarding unused function in main file)
# static int usage (int * argument);
#
# The last argument is for specific CFLAGS, that need to be set
# for the compiler to generate a warning on the cross-check.
# This may need adaption for future compilers / CFLAG-settings.
#
AC_DEFUN([_HWLOC_CHECK_SPECIFIC_ATTRIBUTE], [
AC_MSG_CHECKING([for __attribute__([$1])])
AC_CACHE_VAL(hwloc_cv___attribute__[$1], [
#
# Try to compile using the C compiler
#
AC_TRY_COMPILE([$2],[],
[
#
# In case we did succeed: Fine, but was this due to the
# attribute being ignored/skipped? Grep for IgNoRe/skip in conftest.err
# and if found, reset the hwloc_cv__attribute__var=0
#
hwloc_cv___attribute__[$1]=1
_HWLOC_ATTRIBUTE_FAIL_SEARCH([$1])
],
[hwloc_cv___attribute__[$1]=0])
#
# If the attribute is supported by both compilers,
# try to recompile a *cross-check*, IFF defined.
#
if test '(' "$hwloc_cv___attribute__[$1]" = "1" -a "[$3]" != "" ')' ; then
ac_c_werror_flag_safe=$ac_c_werror_flag
ac_c_werror_flag="yes"
CFLAGS_safe=$CFLAGS
CFLAGS="$CFLAGS [$4]"
AC_TRY_COMPILE([$3],
[
int i=4711;
i=usage(&i);
],
[hwloc_cv___attribute__[$1]=0],
[
#
# In case we did NOT succeed: Fine, but was this due to the
# attribute being ignored? Grep for IgNoRe in conftest.err
# and if found, reset the hwloc_cv__attribute__var=0
#
hwloc_cv___attribute__[$1]=1
_HWLOC_ATTRIBUTE_FAIL_SEARCH([$1])
])
ac_c_werror_flag=$ac_c_werror_flag_safe
CFLAGS=$CFLAGS_safe
fi
])
if test "$hwloc_cv___attribute__[$1]" = "1" ; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
])
#
# Test the availability of __attribute__ and with the help
# of _HWLOC_CHECK_SPECIFIC_ATTRIBUTE for the support of
# particular attributes. Compilers, that do not support an
# attribute most often fail with a warning (when the warning
# level is set).
# The compilers output is parsed in _HWLOC_ATTRIBUTE_FAIL_SEARCH
#
# To add a new attributes __NAME__ add the
# hwloc_cv___attribute__NAME
# add a new check with _HWLOC_CHECK_SPECIFIC_ATTRIBUTE (possibly with a cross-check)
# _HWLOC_CHECK_SPECIFIC_ATTRIBUTE([name], [int foo (int arg) __attribute__ ((__name__));], [], [])
# and define the corresponding
# AC_DEFINE_UNQUOTED(_HWLOC_HAVE_ATTRIBUTE_NAME, [$hwloc_cv___attribute__NAME],
# [Whether your compiler has __attribute__ NAME or not])
# and decide on a correct macro (in opal/include/opal_config_bottom.h):
# # define __opal_attribute_NAME(x) __attribute__(__NAME__)
#
# Please use the "__"-notation of the attribute in order not to
# clash with predefined names or macros (e.g. const, which some compilers
# do not like..)
#
AC_DEFUN([_HWLOC_CHECK_ATTRIBUTES], [
AC_MSG_CHECKING(for __attribute__)
AC_CACHE_VAL(hwloc_cv___attribute__, [
AC_TRY_COMPILE(
[#include <stdlib.h>
/* Check for the longest available __attribute__ (since gcc-2.3) */
struct foo {
char a;
int x[2] __attribute__ ((__packed__));
};
],
[],
[hwloc_cv___attribute__=1],
[hwloc_cv___attribute__=0],
)
if test "$hwloc_cv___attribute__" = "1" ; then
AC_TRY_COMPILE(
[#include <stdlib.h>
/* Check for the longest available __attribute__ (since gcc-2.3) */
struct foo {
char a;
int x[2] __attribute__ ((__packed__));
};
],
[],
[hwloc_cv___attribute__=1],
[hwloc_cv___attribute__=0],
)
fi
])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE, [$hwloc_cv___attribute__],
[Whether your compiler has __attribute__ or not])
#
# Now that we know the compiler support __attribute__ let's check which kind of
# attributed are supported.
#
if test "$hwloc_cv___attribute__" = "0" ; then
AC_MSG_RESULT([no])
hwloc_cv___attribute__aligned=0
hwloc_cv___attribute__always_inline=0
hwloc_cv___attribute__cold=0
hwloc_cv___attribute__const=0
hwloc_cv___attribute__deprecated=0
hwloc_cv___attribute__format=0
hwloc_cv___attribute__hot=0
hwloc_cv___attribute__malloc=0
hwloc_cv___attribute__may_alias=0
hwloc_cv___attribute__no_instrument_function=0
hwloc_cv___attribute__nonnull=0
hwloc_cv___attribute__noreturn=0
hwloc_cv___attribute__packed=0
hwloc_cv___attribute__pure=0
hwloc_cv___attribute__sentinel=0
hwloc_cv___attribute__unused=0
hwloc_cv___attribute__warn_unused_result=0
hwloc_cv___attribute__weak_alias=0
else
AC_MSG_RESULT([yes])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([aligned],
[struct foo { char text[4]; } __attribute__ ((__aligned__(8)));],
[],
[])
#
# Ignored by PGI-6.2.5; -- recognized by output-parser
#
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([always_inline],
[int foo (int arg) __attribute__ ((__always_inline__));],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([cold],
[
int foo(int arg1, int arg2) __attribute__ ((__cold__));
int foo(int arg1, int arg2) { return arg1 * arg2 + arg1; }
],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([const],
[
int foo(int arg1, int arg2) __attribute__ ((__const__));
int foo(int arg1, int arg2) { return arg1 * arg2 + arg1; }
],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([deprecated],
[
int foo(int arg1, int arg2) __attribute__ ((__deprecated__));
int foo(int arg1, int arg2) { return arg1 * arg2 + arg1; }
],
[],
[])
HWLOC_ATTRIBUTE_CFLAGS=
case "$hwloc_c_vendor" in
gnu)
HWLOC_ATTRIBUTE_CFLAGS="-Wall"
;;
intel)
# we want specifically the warning on format string conversion
HWLOC_ATTRIBUTE_CFLAGS="-we181"
;;
esac
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([format],
[
int this_printf (void *my_object, const char *my_format, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
],
[
static int usage (int * argument);
extern int this_printf (int arg1, const char *my_format, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
static int usage (int * argument) {
return this_printf (*argument, "%d", argument); /* This should produce a format warning */
}
/* The autoconf-generated main-function is int main(), which produces a warning by itself */
int main(void);
],
[$HWLOC_ATTRIBUTE_CFLAGS])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([hot],
[
int foo(int arg1, int arg2) __attribute__ ((__hot__));
int foo(int arg1, int arg2) { return arg1 * arg2 + arg1; }
],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([malloc],
[
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
int * foo(int arg1) __attribute__ ((__malloc__));
int * foo(int arg1) { return (int*) malloc(arg1); }
],
[],
[])
#
# Attribute may_alias: No suitable cross-check available, that works for non-supporting compilers
# Ignored by intel-9.1.045 -- turn off with -wd1292
# Ignored by PGI-6.2.5; ignore not detected due to missing cross-check
#
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([may_alias],
[int * p_value __attribute__ ((__may_alias__));],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([no_instrument_function],
[int * foo(int arg1) __attribute__ ((__no_instrument_function__));],
[],
[])
#
# Attribute nonnull:
# Ignored by intel-compiler 9.1.045 -- recognized by cross-check
# Ignored by PGI-6.2.5 (pgCC) -- recognized by cross-check
#
HWLOC_ATTRIBUTE_CFLAGS=
case "$hwloc_c_vendor" in
gnu)
HWLOC_ATTRIBUTE_CFLAGS="-Wall"
;;
intel)
# we do not want to get ignored attributes warnings, but rather real warnings
HWLOC_ATTRIBUTE_CFLAGS="-wd1292"
;;
esac
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([nonnull],
[
int square(int *arg) __attribute__ ((__nonnull__));
int square(int *arg) { return *arg; }
],
[
static int usage(int * argument);
int square(int * argument) __attribute__ ((__nonnull__));
int square(int * argument) { return (*argument) * (*argument); }
static int usage(int * argument) {
return square( ((void*)0) ); /* This should produce an argument must be nonnull warning */
}
/* The autoconf-generated main-function is int main(), which produces a warning by itself */
int main(void);
],
[$HWLOC_ATTRIBUTE_CFLAGS])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([noreturn],
[
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
void fatal(int arg1) __attribute__ ((__noreturn__));
void fatal(int arg1) { exit(arg1); }
],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([packed],
[
struct foo {
char a;
int x[2] __attribute__ ((__packed__));
};
],
[],
[])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([pure],
[
int square(int arg) __attribute__ ((__pure__));
int square(int arg) { return arg * arg; }
],
[],
[])
#
# Attribute sentinel:
# Ignored by the intel-9.1.045 -- recognized by cross-check
# intel-10.0beta works fine
# Ignored by PGI-6.2.5 (pgCC) -- recognized by output-parser and cross-check
# Ignored by pathcc-2.2.1 -- recognized by cross-check (through grep ignore)
#
HWLOC_ATTRIBUTE_CFLAGS=
case "$hwloc_c_vendor" in
gnu)
HWLOC_ATTRIBUTE_CFLAGS="-Wall"
;;
intel)
# we do not want to get ignored attributes warnings
HWLOC_ATTRIBUTE_CFLAGS="-wd1292"
;;
esac
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([sentinel],
[
int my_execlp(const char * file, const char *arg, ...) __attribute__ ((__sentinel__));
],
[
static int usage(int * argument);
int my_execlp(const char * file, const char *arg, ...) __attribute__ ((__sentinel__));
static int usage(int * argument) {
void * last_arg_should_be_null = argument;
return my_execlp ("lala", "/home/there", last_arg_should_be_null); /* This should produce a warning */
}
/* The autoconf-generated main-function is int main(), which produces a warning by itself */
int main(void);
],
[$HWLOC_ATTRIBUTE_CFLAGS])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([unused],
[
int square(int arg1 __attribute__ ((__unused__)), int arg2);
int square(int arg1, int arg2) { return arg2; }
],
[],
[])
#
# Attribute warn_unused_result:
# Ignored by the intel-compiler 9.1.045 -- recognized by cross-check
# Ignored by pathcc-2.2.1 -- recognized by cross-check (through grep ignore)
#
HWLOC_ATTRIBUTE_CFLAGS=
case "$hwloc_c_vendor" in
gnu)
HWLOC_ATTRIBUTE_CFLAGS="-Wall"
;;
intel)
# we do not want to get ignored attributes warnings
HWLOC_ATTRIBUTE_CFLAGS="-wd1292"
;;
esac
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([warn_unused_result],
[
int foo(int arg) __attribute__ ((__warn_unused_result__));
int foo(int arg) { return arg + 3; }
],
[
static int usage(int * argument);
int foo(int arg) __attribute__ ((__warn_unused_result__));
int foo(int arg) { return arg + 3; }
static int usage(int * argument) {
foo (*argument); /* Should produce an unused result warning */
return 0;
}
/* The autoconf-generated main-function is int main(), which produces a warning by itself */
int main(void);
],
[$HWLOC_ATTRIBUTE_CFLAGS])
_HWLOC_CHECK_SPECIFIC_ATTRIBUTE([weak_alias],
[
int foo(int arg);
int foo(int arg) { return arg + 3; }
int foo2(int arg) __attribute__ ((__weak__, __alias__("foo")));
],
[],
[])
fi
# Now that all the values are set, define them
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_ALIGNED, [$hwloc_cv___attribute__aligned],
[Whether your compiler has __attribute__ aligned or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_ALWAYS_INLINE, [$hwloc_cv___attribute__always_inline],
[Whether your compiler has __attribute__ always_inline or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_COLD, [$hwloc_cv___attribute__cold],
[Whether your compiler has __attribute__ cold or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_CONST, [$hwloc_cv___attribute__const],
[Whether your compiler has __attribute__ const or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_DEPRECATED, [$hwloc_cv___attribute__deprecated],
[Whether your compiler has __attribute__ deprecated or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_FORMAT, [$hwloc_cv___attribute__format],
[Whether your compiler has __attribute__ format or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_HOT, [$hwloc_cv___attribute__hot],
[Whether your compiler has __attribute__ hot or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_MALLOC, [$hwloc_cv___attribute__malloc],
[Whether your compiler has __attribute__ malloc or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS, [$hwloc_cv___attribute__may_alias],
[Whether your compiler has __attribute__ may_alias or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_NO_INSTRUMENT_FUNCTION, [$hwloc_cv___attribute__no_instrument_function],
[Whether your compiler has __attribute__ no_instrument_function or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_NONNULL, [$hwloc_cv___attribute__nonnull],
[Whether your compiler has __attribute__ nonnull or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_NORETURN, [$hwloc_cv___attribute__noreturn],
[Whether your compiler has __attribute__ noreturn or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_PACKED, [$hwloc_cv___attribute__packed],
[Whether your compiler has __attribute__ packed or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_PURE, [$hwloc_cv___attribute__pure],
[Whether your compiler has __attribute__ pure or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_SENTINEL, [$hwloc_cv___attribute__sentinel],
[Whether your compiler has __attribute__ sentinel or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_UNUSED, [$hwloc_cv___attribute__unused],
[Whether your compiler has __attribute__ unused or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT, [$hwloc_cv___attribute__warn_unused_result],
[Whether your compiler has __attribute__ warn unused result or not])
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS, [$hwloc_cv___attribute__weak_alias],
[Whether your compiler has __attribute__ weak alias or not])
])

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

@ -0,0 +1,239 @@
dnl -*- shell-script -*-
dnl
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology
dnl Corporation. All rights reserved.
dnl Copyright (c) 2004-2005 The University of Tennessee and The University
dnl of Tennessee Research Foundation. All rights
dnl reserved.
dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved.
dnl Copyright (c) 2004-2005 The Regents of the University of California.
dnl All rights reserved.
dnl Copyright (c) 2011 Cisco Systems, Inc. All rights reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
dnl
dnl $HEADER$
dnl
dnl ------------------------------------------------------------------
dnl This m4 file originally copied from Open MPI
dnl config/ompi_check_vendor.m4.
dnl ------------------------------------------------------------------
# HWLOC_C_COMPILER_VENDOR(VENDOR_VARIABLE)
# ---------------------------------------
# Set shell variable VENDOR_VARIABLE to the name of the compiler
# vendor for the current C compiler.
#
# See comment for _HWLOC_CHECK_COMPILER_VENDOR for a complete
# list of currently detected compilers.
AC_DEFUN([_HWLOC_C_COMPILER_VENDOR], [
AC_REQUIRE([AC_PROG_CC])
AC_CACHE_CHECK([for the C compiler vendor],
[hwloc_cv_c_compiler_vendor],
[AC_LANG_PUSH(C)
_HWLOC_CHECK_COMPILER_VENDOR([hwloc_cv_c_compiler_vendor])
AC_LANG_POP(C)])
$1="$hwloc_cv_c_compiler_vendor"
])
# workaround to avoid syntax error with Autoconf < 2.68:
m4_ifndef([AC_LANG_DEFINES_PROVIDED],
[m4_define([AC_LANG_DEFINES_PROVIDED])])
# HWLOC_IFDEF_IFELSE(symbol, [action-if-defined],
# [action-if-not-defined])
# ----------------------------------------------
# Run compiler to determine if preprocessor symbol "symbol" is
# defined by the compiler.
AC_DEFUN([HWLOC_IFDEF_IFELSE], [
AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED
#ifndef $1
#error "symbol $1 not defined"
choke me
#endif], [$2], [$3])])
# HWLOC_IF_IFELSE(symbol, [action-if-defined],
# [action-if-not-defined])
# ----------------------------------------------
# Run compiler to determine if preprocessor symbol "symbol" is
# defined by the compiler.
AC_DEFUN([HWLOC_IF_IFELSE], [
AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED
#if !( $1 )
#error "condition $1 not met"
choke me
#endif], [$2], [$3])])
# _HWLOC_CHECK_COMPILER_VENDOR(VENDOR_VARIABLE)
# --------------------------------------------
# Set shell variable VENDOR_VARIABLE to the name of the compiler
# vendor for the compiler for the current language. Language must be
# one of C, OBJC, or C++.
#
# thanks to http://predef.sourceforge.net/precomp.html for the list
# of defines to check.
AC_DEFUN([_HWLOC_CHECK_COMPILER_VENDOR], [
hwloc_check_compiler_vendor_result="unknown"
# GNU is probably the most common, so check that one as soon as
# possible. Intel pretends to be GNU, so need to check Intel
# before checking for GNU.
# Intel
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__INTEL_COMPILER) || defined(__ICC)],
[hwloc_check_compiler_vendor_result="intel"])])
# GNU
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__GNUC__],
[hwloc_check_compiler_vendor_result="gnu"])])
# Borland Turbo C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__TURBOC__],
[hwloc_check_compiler_vendor_result="borland"])])
# Borland C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__BORLANDC__],
[hwloc_check_compiler_vendor_result="borland"])])
# Comeau C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__COMO__],
[hwloc_check_compiler_vendor_result="comeau"])])
# Compaq C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__DECC) || defined(VAXC) || defined(__VAXC)],
[hwloc_check_compiler_vendor_result="compaq"],
[HWLOC_IF_IFELSE([defined(__osf__) && defined(__LANGUAGE_C__)],
[hwloc_check_compiler_vendor_result="compaq"],
[HWLOC_IFDEF_IFELSE([__DECCXX],
[hwloc_check_compiler_vendor_result="compaq"])])])])
# Cray C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([_CRAYC],
[hwloc_check_compiler_vendor_result="cray"])])
# Diab C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__DCC__],
[hwloc_check_compiler_vendor_result="diab"])])
# Digital Mars
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__DMC__) || defined(__SC__) || defined(__ZTC__)],
[hwloc_check_compiler_vendor_result="digital mars"])])
# HP ANSI C / aC++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__HP_cc) || defined(__HP_aCC)],
[hwloc_check_compiler_vendor_result="hp"])])
# IBM XL C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)],
[hwloc_check_compiler_vendor_result="ibm"],
[HWLOC_IF_IFELSE([defined(_AIX) && !defined(__GNUC__)],
[hwloc_check_compiler_vendor_result="ibm"])])])
# KAI C++ (rest in peace)
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__KCC],
[hwloc_check_compiler_vendor_result="kai"])])
# LCC
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__LCC__],
[hwloc_check_compiler_vendor_result="lcc"])])
# MetaWare High C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__HIGHC__],
[hwloc_check_compiler_vendor_result="metaware high"])])
# Metrowerks Codewarrior
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__MWERKS__],
[hwloc_check_compiler_vendor_result="metrowerks"])])
# MIPSpro (SGI)
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(sgi) || defined(__sgi)],
[hwloc_check_compiler_vendor_result="sgi"])])
# MPW C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__MRC__) || defined(MPW_C) || defined(MPW_CPLUS)],
[hwloc_check_compiler_vendor_result="mpw"])])
# Microsoft
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[# Always use C compiler when checking for Microsoft, as
# Visual C++ doesn't recognize .cc as a C++ file.
AC_LANG_PUSH(C)
HWLOC_IF_IFELSE([defined(_MSC_VER) || defined(__MSC_VER)],
[hwloc_check_compiler_vendor_result="microsoft"])
AC_LANG_POP(C)])
# Norcroft C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__CC_NORCROFT],
[hwloc_check_compiler_vendor_result="norcroft"])])
# Pelles C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__POCC__],
[hwloc_check_compiler_vendor_result="pelles"])])
# Portland Group
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__PGI],
[hwloc_check_compiler_vendor_result="portland group"])])
# SAS/C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(SASC) || defined(__SASC) || defined(__SASC__)],
[hwloc_check_compiler_vendor_result="sas"])])
# Sun Workshop C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IF_IFELSE([defined(__SUNPRO_C) || defined(__SUNPRO_CC)],
[hwloc_check_compiler_vendor_result="sun"])])
# TenDRA C/C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__TenDRA__],
[hwloc_check_compiler_vendor_result="tendra"])])
# Tiny C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__TINYC__],
[hwloc_check_compiler_vendor_result="tiny"])])
# USL C
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__USLC__],
[hwloc_check_compiler_vendor_result="usl"])])
# Watcom C++
AS_IF([test "$hwloc_check_compiler_vendor_result" = "unknown"],
[HWLOC_IFDEF_IFELSE([__WATCOMC__],
[hwloc_check_compiler_vendor_result="watcom"])])
$1="$hwloc_check_compiler_vendor_result"
unset hwloc_check_compiler_vendor_result
])

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

@ -0,0 +1,131 @@
# This macro set originally copied from Open MPI:
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
# and renamed/modified for hwloc:
# Copyright (c) 2009 inria. All rights reserved.
# Copyright (c) 2009-2010 Université Bordeaux 1
# Copyright © 2010-2012 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer listed
# in this license in the documentation and/or other materials
# provided with the distribution.
#
# - Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# The copyright holders provide no reassurances that the source code
# provided does not infringe any patent, copyright, or any other
# intellectual property rights of third parties. The copyright holders
# disclaim any liability to any recipient for claims brought against
# recipient by any third party for infringement of that parties
# intellectual property rights.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# _HWLOC_CHECK_VISIBILITY
# --------------------------------------------------------
AC_DEFUN([_HWLOC_CHECK_VISIBILITY],[
# Be safe for systems that have ancient Autoconf's (e.g., RHEL5)
m4_ifdef([AC_PROG_GREP],
[AC_REQUIRE([AC_PROG_GREP])],
[GREP=grep])
# Check if the compiler has support for visibility, like some
# versions of gcc, icc, Sun Studio cc.
AC_ARG_ENABLE(visibility,
AC_HELP_STRING([--enable-visibility],
[enable visibility feature of certain compilers/linkers (default: enabled on platforms that support it)]))
case ${target} in
*-*-aix*|*-*-mingw*|*-*-cygwin*|*-*-hpux*)
enable_visibility=no
;;
esac
hwloc_visibility_define=0
hwloc_msg="whether to enable symbol visibility"
if test "$enable_visibility" = "no"; then
AC_MSG_CHECKING([$hwloc_msg])
AC_MSG_RESULT([no (disabled)])
else
CFLAGS_orig=$CFLAGS
hwloc_add=
case "$hwloc_c_vendor" in
sun)
# Check using Sun Studio -xldscope=hidden flag
hwloc_add=-xldscope=hidden
CFLAGS="$CFLAGS_orig $hwloc_add -errwarn=%all"
;;
*)
# Check using -fvisibility=hidden
hwloc_add=-fvisibility=hidden
CFLAGS="$CFLAGS_orig $hwloc_add -Werror"
;;
esac
AC_MSG_CHECKING([if $CC supports $hwloc_add])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
__attribute__((visibility("default"))) int foo;
]],[[fprintf(stderr, "Hello, world\n");]])],
[AS_IF([test -s conftest.err],
[$GREP -iq visibility conftest.err
# If we find "visibility" in the stderr, then
# assume it doesn't work
AS_IF([test "$?" = "0"], [hwloc_add=])])
], [hwloc_add=])
AS_IF([test "$hwloc_add" = ""],
[AC_MSG_RESULT([no])],
[AC_MSG_RESULT([yes])])
CFLAGS=$CFLAGS_orig
HWLOC_VISIBILITY_CFLAGS=$hwloc_add
if test "$hwloc_add" != "" ; then
hwloc_visibility_define=1
AC_MSG_CHECKING([$hwloc_msg])
AC_MSG_RESULT([yes (via $hwloc_add)])
elif test "$enable_visibility" = "yes"; then
AC_MSG_ERROR([Symbol visibility support requested but compiler does not seem to support it. Aborting])
else
AC_MSG_CHECKING([$hwloc_msg])
AC_MSG_RESULT([no (unsupported)])
fi
unset hwloc_add
fi
AC_DEFINE_UNQUOTED([HWLOC_C_HAVE_VISIBILITY], [$hwloc_visibility_define],
[Whether C compiler supports symbol visibility or not])
])

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

@ -0,0 +1,66 @@
# Copyright © 2012 Inria. All rights reserved.
# See COPYING in top-level directory.
# HWLOC_PREPARE_FILTER_COMPONENTS
#
# Given a comma-separated list of names, define hwloc_<name>_component_maybeplugin=1.
#
# $1 = command-line given list of components to build as plugins
#
AC_DEFUN([HWLOC_PREPARE_FILTER_COMPONENTS], [
for name in `echo [$1] | sed -e 's/,/ /g'` ; do
str="hwloc_${name}_component_wantplugin=1"
eval $str
done
])
# HWLOC_FILTER_COMPONENTS
#
# For each component in hwloc_components,
# check if hwloc_<name>_component_wantplugin=1 or enable_plugin=yes,
# and check if hwloc_<name>_component_maybeplugin=1.
# Add <name> to hwloc_[static|plugin]_components accordingly.
# And set hwloc_<name>_component=[static|plugin] accordingly.
#
AC_DEFUN([HWLOC_FILTER_COMPONENTS], [
for name in $hwloc_components ; do
str="maybeplugin=\$hwloc_${name}_component_maybeplugin"
eval $str
str="wantplugin=\$hwloc_${name}_component_wantplugin"
eval $str
if test x$hwloc_have_plugins = xyes && test x$maybeplugin = x1 && test x$wantplugin = x1 -o x$enable_plugins = xyes; then
hwloc_plugin_components="$hwloc_plugin_components $name"
str="hwloc_${name}_component=plugin"
else
hwloc_static_components="$hwloc_static_components $name"
str="hwloc_${name}_component=static"
fi
eval $str
done
])
# HWLOC_LIST_STATIC_COMPONENTS
#
# Append to file $1 an array of components by listing component names in $2.
#
# $1 = filename
# $2 = list of component names
#
AC_DEFUN([HWLOC_LIST_STATIC_COMPONENTS], [
for comp in [$2]; do
echo "HWLOC_DECLSPEC extern const struct hwloc_component hwloc_${comp}_component;" >>[$1]
done
cat <<EOF >>[$1]
static const struct hwloc_component * hwloc_static_components[[]] = {
EOF
for comp in [$2]; do
echo " &hwloc_${comp}_component," >>[$1]
done
cat <<EOF >>[$1]
NULL
};
EOF
])

173
opal/mca/hwloc/hwloc172/hwloc/config/hwloc_get_version.sh Исполняемый файл
Просмотреть файл

@ -0,0 +1,173 @@
#!/bin/sh
#
# hwloc_get_version is created from hwloc_get_version.m4 and hwloc_get_version.m4sh.
#
# Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright © 2008-2010 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# 11 September 2009: this file was copied from PLPA's SVN trunk as of
# r251 on 11 September 2009. The only change made to it was
# s/PLPA/hwloc/ig.
# HWLOC_GET_VERSION(version_file, variable_prefix)
# -----------------------------------------------
# parse version_file for version information, setting
# the following shell variables:
#
# prefix_VERSION
# prefix_BASE_VERSION
# prefix_MAJOR_VERSION
# prefix_MINOR_VERSION
# prefix_RELEASE_VERSION
# prefix_GREEK_VERSION
# prefix_WANT_REPO_REV
# prefix_REPO_REV
# prefix_RELEASE_DATE
srcfile="$1"
option="$2"
case "$option" in
# svnversion can take a while to run. If we don't need it, don't run it.
--major|--minor|--release|--greek|--base|--help)
ompi_ver_need_repo_rev=0
;;
*)
ompi_ver_need_repo_rev=1
esac
if test -z "$srcfile"; then
option="--help"
else
: ${ompi_ver_need_repo_rev=1}
: ${srcdir=.}
: ${svnversion_result=-1}
if test -f "$srcfile"; then
ompi_vers=`sed -n "
t clear
: clear
s/^major/HWLOC_MAJOR_VERSION/
s/^minor/HWLOC_MINOR_VERSION/
s/^release/HWLOC_RELEASE_VERSION/
s/^greek/HWLOC_GREEK_VERSION/
s/^want_repo_rev/HWLOC_WANT_REPO_REV/
s/^repo_rev/HWLOC_REPO_REV/
s/^date/HWLOC_RELEASE_DATE/
t print
b
: print
p" < "$srcfile"`
eval "$ompi_vers"
# Only print release version if it isn't 0
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}"
HWLOC_BASE_VERSION=$HWLOC_VERSION
if test $HWLOC_WANT_REPO_REV -eq 1 && test $ompi_ver_need_repo_rev -eq 1 ; then
if test "$svnversion_result" != "-1" ; then
HWLOC_REPO_REV=$svnversion_result
fi
if test "$HWLOC_REPO_REV" = "-1" ; then
if test -d "$srcdir/.svn" ; then
HWLOC_REPO_REV=r`svnversion "$srcdir"`
elif test -d "$srcdir/.hg" ; then
HWLOC_REPO_REV=hg`hg -v -R "$srcdir" tip | grep changeset | cut -d: -f3`
elif test -d "$srcdir/.git" ; then
HWLOC_REPO_REV=git`git log -1 "$srcdir" | grep commit | awk '{ print $2 }'`
fi
if test "HWLOC_REPO_REV" = ""; then
HWLOC_REPO_REV=date`date '+%m%d%Y'`
fi
fi
HWLOC_VERSION="${HWLOC_VERSION}${HWLOC_REPO_REV}"
fi
fi
if test "$option" = ""; then
option="--full"
fi
fi
case "$option" in
--full|-v|--version)
echo $HWLOC_VERSION
;;
--major)
echo $HWLOC_MAJOR_VERSION
;;
--minor)
echo $HWLOC_MINOR_VERSION
;;
--release)
echo $HWLOC_RELEASE_VERSION
;;
--greek)
echo $HWLOC_GREEK_VERSION
;;
--repo-rev)
echo $HWLOC_REPO_REV
;;
--base)
echo $HWLOC_BASE_VERSION
;;
--release-date)
echo $HWLOC_RELEASE_DATE
;;
--all)
echo ${HWLOC_VERSION} ${HWLOC_MAJOR_VERSION} ${HWLOC_MINOR_VERSION} ${HWLOC_RELEASE_VERSION} ${HWLOC_GREEK_VERSION} ${HWLOC_REPO_REV}
;;
-h|--help)
cat <<EOF
$0 <srcfile> <option>
<srcfile> - Text version file
<option> - One of:
--full - Full version number
--major - Major version number
--minor - Minor version number
--release - Release version number
--greek - Greek (alpha, beta, etc) version number
--repo-rev - Repository version number
--all - Show all version numbers, separated by :
--base - Show base version number (no repo version number)
--release-date - Show the release date
--help - This message
EOF
;;
*)
echo "Unrecognized option $option. Run $0 --help for options"
;;
esac
# All done
exit 0

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

@ -0,0 +1,445 @@
dnl -*- Autoconf -*-
dnl
dnl Copyright (c) 2009-2012 Inria. All rights reserved.
dnl Copyright (c) 2009, 2011 Université Bordeaux 1
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology
dnl Corporation. All rights reserved.
dnl Copyright (c) 2004-2005 The Regents of the University of California.
dnl All rights reserved.
dnl Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved.
dnl Copyright © 2010-2012 Inria. All rights reserved.
dnl Copyright © 2006-2011 Cisco Systems, Inc. All rights reserved.
dnl
dnl See COPYING in top-level directory.
#-----------------------------------------------------------------------
# Probably only ever invoked by hwloc's configure.ac
AC_DEFUN([HWLOC_BUILD_STANDALONE],[
hwloc_mode=standalone
])dnl
#-----------------------------------------------------------------------
# Probably only ever invoked by hwloc's configure.ac
AC_DEFUN([HWLOC_DEFINE_ARGS],[
# Embedded mode, or standalone?
AC_ARG_ENABLE([embedded-mode],
AC_HELP_STRING([--enable-embedded-mode],
[Using --enable-embedded-mode puts the HWLOC into "embedded" mode. The default is --disable-embedded-mode, meaning that the HWLOC is in "standalone" mode.]))
# Change the symbol prefix?
AC_ARG_WITH([hwloc-symbol-prefix],
AC_HELP_STRING([--with-hwloc-symbol-prefix=STRING],
[STRING can be any valid C symbol name. It will be prefixed to all public HWLOC symbols. Default: "hwloc_"]))
# Debug mode?
AC_ARG_ENABLE([debug],
AC_HELP_STRING([--enable-debug],
[Using --enable-debug enables various hwloc maintainer-level debugging controls. This option is not recomended for end users.]))
# Doxygen?
AC_ARG_ENABLE([doxygen],
[AC_HELP_STRING([--enable-doxygen],
[enable support for building Doxygen documentation (note that this option is ONLY relevant in developer builds; Doxygen documentation is pre-built for tarball builds and this option is therefore ignored)])])
# Picky?
AC_ARG_ENABLE(picky,
AC_HELP_STRING([--disable-picky],
[When in developer checkouts of hwloc and compiling with gcc, the default is to enable maximum compiler pickyness. Using --disable-picky or --enable-picky overrides any default setting]))
# Cairo?
AC_ARG_ENABLE([cairo],
AS_HELP_STRING([--disable-cairo],
[Disable the Cairo back-end of hwloc's lstopo command]))
# XML using libxml2?
AC_ARG_ENABLE([libxml2],
AS_HELP_STRING([--disable-libxml2],
[Do not use libxml2 for XML support, use a custom minimalistic support]))
# PCI?
AC_ARG_ENABLE([pci],
AS_HELP_STRING([--disable-pci],
[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?
AC_ARG_ENABLE([opencl],
AS_HELP_STRING([--disable-opencl],
[Disable the OpenCL device discovery]))
# CUDA?
AC_ARG_ENABLE([cuda],
AS_HELP_STRING([--disable-cuda],
[Disable the CUDA device discovery using libcudart]))
# NVML?
AC_ARG_ENABLE([nvml],
AS_HELP_STRING([--disable-nvml],
[Disable the NVML device discovery]))
# GL/Display
AC_ARG_ENABLE([gl],
AS_HELP_STRING([--disable-gl],
[Disable the GL display device discovery]))
# Linux libnuma
AC_ARG_ENABLE([libnuma],
AS_HELP_STRING([--disable-libnuma],
[Disable the Linux libnuma]))
# Plugins
AC_ARG_ENABLE([plugins],
AS_HELP_STRING([--enable-plugins=name,...],
[Build the given components as dynamically-loaded plugins]))
])dnl
#-----------------------------------------------------------------------
dnl We only build documentation if this is a developer checkout.
dnl Distribution tarballs just install pre-built docuemntation that was
dnl included in the tarball.
# Probably only ever invoked by hwloc's configure.ac
AC_DEFUN([HWLOC_SETUP_DOCS],[
cat <<EOF
###
### Configuring hwloc documentation
###
EOF
AC_MSG_CHECKING([if this is a developer build])
AS_IF([test ! -d "$srcdir/.svn" -a ! -d "$srcdir/.hg" -a ! -d "$srcdir/.git"],
[AC_MSG_RESULT([no (doxygen generation is optional)])],
[AC_MSG_RESULT([yes])])
# Generating the doxygen output requires a few tools. If we
# 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_PATH_TOOL([DOXYGEN], [doxygen])
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_PATH_TOOL([PDFLATEX], [pdflatex])
AC_ARG_VAR([MAKEINDEX], [Location of the makeindex program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([MAKEINDEX], [makeindex])
AC_ARG_VAR([FIG2DEV], [Location of the fig2dev program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([FIG2DEV], [fig2dev])
AC_ARG_VAR([GS], [Location of the gs program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([GS], [gs])
AC_ARG_VAR([EPSTOPDF], [Location of the epstopdf program (required for building the hwloc doxygen documentation)])
AC_PATH_TOOL([EPSTOPDF], [epstopdf])
AC_MSG_CHECKING([if can build doxygen docs])
AS_IF([test "x$DOXYGEN" != "x" -a "x$PDFLATEX" != "x" -a "x$MAKEINDEX" != "x" -a "x$FIG2DEV" != "x" -a "x$GS" != "x" -a "x$EPSTOPDF" != "x"],
[hwloc_generate_doxs=yes], [hwloc_generate_doxs=no])
AC_MSG_RESULT([$hwloc_generate_doxs])
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])])
# Linux and OS X take different sed arguments.
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.
AC_ARG_VAR([W3M], [Location of the w3m program (required to building the top-level hwloc README file)])
AC_PATH_TOOL([W3M], [w3m])
AC_ARG_VAR([LYNX], [Location of the lynx program (required to building the top-level hwloc README file)])
AC_PATH_TOOL([LYNX], [lynx])
AC_MSG_CHECKING([if can build top-level README])
AS_IF([test "x$W3M" != "x"],
[hwloc_generate_readme=yes
HWLOC_W3_GENERATOR=$W3M],
[AS_IF([test "x$LYNX" != "x"],
[hwloc_generate_readme=yes
HWLOC_W3_GENERATOR="$LYNX -dump -nolist"],
[hwloc_generate_readme=no])])
AC_SUBST(HWLOC_W3_GENERATOR)
AC_MSG_RESULT([$hwloc_generate_readme])
# If any one of the above tools is missing, we will refuse to make dist.
AC_MSG_CHECKING([if will build doxygen docs])
AS_IF([test "x$hwloc_generate_doxs" = "xyes" -a "x$enable_doxygen" != "xno"],
[], [hwloc_generate_doxs=no])
AC_MSG_RESULT([$hwloc_generate_doxs])
# See if we want to install the doxygen docs
AC_MSG_CHECKING([if will install doxygen docs])
AS_IF([test "x$hwloc_generate_doxs" = "xyes" -o \
-f "$srcdir/doc/doxygen-doc/man/man3/hwloc_distribute.3" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-a4.pdf" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-letter.pdf"],
[hwloc_install_doxs=yes],
[hwloc_install_doxs=no])
AC_MSG_RESULT([$hwloc_install_doxs])
# For the common developer case, if we're in a developer checkout and
# using the GNU compilers, turn on maximum warnings unless
# specifically disabled by the user.
AC_MSG_CHECKING([whether to enable "picky" compiler mode])
hwloc_want_picky=0
AS_IF([test "$hwloc_c_vendor" = "gnu"],
[AS_IF([test -d "$srcdir/.svn" -o -d "$srcdir/.hg" -o -d "$srcdir/.git"],
[hwloc_want_picky=1])])
if test "$enable_picky" = "yes"; then
if test "$GCC" = "yes"; then
AC_MSG_RESULT([yes])
hwloc_want_picky=1
else
AC_MSG_RESULT([no])
AC_MSG_WARN([Warning: --enable-picky used, but is currently only defined for the GCC compiler set -- automatically disabled])
hwloc_want_picky=0
fi
elif test "$enable_picky" = "no"; then
AC_MSG_RESULT([no])
hwloc_want_picky=0
else
if test "$hwloc_want_picky" = 1; then
AC_MSG_RESULT([yes (default)])
else
AC_MSG_RESULT([no (default)])
fi
fi
if test "$hwloc_want_picky" = 1; then
add="-Wall -Wunused-parameter -Wundef -Wno-long-long -Wsign-compare"
add="$add -Wmissing-prototypes -Wstrict-prototypes"
add="$add -Wcomment -pedantic"
HWLOC_CFLAGS="$HWLOC_CFLAGS $add"
fi
# Generate some files for the docs
AC_CONFIG_FILES(
hwloc_config_prefix[doc/Makefile]
hwloc_config_prefix[doc/doxygen-config.cfg])
])
#-----------------------------------------------------------------------
# Probably only ever invoked by hwloc's configure.ac
AC_DEFUN([HWLOC_SETUP_UTILS],[
cat <<EOF
###
### Configuring hwloc command line utilities
###
EOF
# Cairo support
hwloc_cairo_happy=no
if test "x$enable_cairo" != "xno"; then
HWLOC_PKG_CHECK_MODULES([CAIRO], [cairo], [cairo_fill],
[hwloc_cairo_happy=yes],
[hwloc_cairo_happy=no])
if test "x$hwloc_cairo_happy" = "xyes"; then
AC_PATH_XTRA
CFLAGS_save=$CFLAGS
LIBS_save=$LIBS
CFLAGS="$CFLAGS $X_CFLAGS"
LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS"
AC_CHECK_HEADERS([X11/Xlib.h], [
AC_CHECK_HEADERS([X11/Xutil.h X11/keysym.h], [
AC_CHECK_LIB([X11], [XOpenDisplay], [
enable_X11=yes
AC_SUBST([HWLOC_X11_LIBS], ["-lX11"])
AC_DEFINE([HWLOC_HAVE_X11], [1], [Define to 1 if X11 libraries are available.])
])]
)],,
[[#include <X11/Xlib.h>]]
)
if test "x$enable_X11" != "xyes"; then
AC_MSG_WARN([X11 headers not found, Cairo/X11 back-end disabled])
hwloc_cairo_happy=no
fi
CFLAGS=$CFLAGS_save
LIBS=$LIBS_save
fi
fi
if test "x$hwloc_cairo_happy" = "xyes"; then
AC_DEFINE([HWLOC_HAVE_CAIRO], [1], [Define to 1 if you have the `cairo' library.])
else
AS_IF([test "$enable_cairo" = "yes"],
[AC_MSG_WARN([--enable-cairo requested, but Cairo/X11 support was not found])
AC_MSG_ERROR([Cannot continue])])
fi
AC_CHECK_TYPES([wchar_t], [
AC_CHECK_FUNCS([putwc])
], [], [[#include <wchar.h>]])
HWLOC_XML_LOCALIZED=1
AC_CHECK_HEADERS([locale.h xlocale.h], [
AC_CHECK_FUNCS([setlocale])
AC_CHECK_FUNCS([uselocale], [HWLOC_XML_LOCALIZED=0])
])
AC_SUBST([HWLOC_XML_LOCALIZED])
AC_CHECK_HEADERS([langinfo.h], [
AC_CHECK_FUNCS([nl_langinfo])
])
hwloc_old_LIBS="$LIBS"
chosen_curses=""
for curses in ncurses curses
do
for lib in "" -ltermcap -l${curses}w -l$curses
do
AC_MSG_CHECKING(termcap support using $curses and $lib)
LIBS="$hwloc_old_LIBS $lib"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <$curses.h>
#include <term.h>
]], [[tparm(NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0)]])], [
AC_MSG_RESULT(yes)
AC_SUBST([HWLOC_TERMCAP_LIBS], ["$LIBS"])
AC_DEFINE([HWLOC_HAVE_LIBTERMCAP], [1],
[Define to 1 if you have a library providing the termcap interface])
chosen_curses=$curses
], [
AC_MSG_RESULT(no)
])
test "x$chosen_curses" != "x" && break
done
test "x$chosen_curses" != "x" && break
done
if test "$chosen_curses" = ncurses
then
AC_DEFINE([HWLOC_USE_NCURSES], [1], [Define to 1 if ncurses works, preferred over curses])
fi
LIBS="$hwloc_old_LIBS"
unset hwloc_old_LIBS
_HWLOC_CHECK_DIFF_U
_HWLOC_CHECK_DIFF_W
# Only generate this if we're building the utilities
AC_CONFIG_FILES(
hwloc_config_prefix[utils/Makefile]
hwloc_config_prefix[hwloc.pc])
])dnl
#-----------------------------------------------------------------------
# Probably only ever invoked by hwloc's configure.ac
AC_DEFUN([HWLOC_SETUP_TESTS],[
cat <<EOF
###
### Configuring hwloc tests
###
EOF
AC_CHECK_LIB([pthread], [pthread_self], [hwloc_have_pthread=yes])
# linux-libnuma.h testing requires libnuma with numa_bitmask_alloc()
AC_CHECK_DECL([numa_bitmask_alloc], [hwloc_have_linux_libnuma=yes], [],
[#include <numa.h>])
AC_CHECK_HEADERS([infiniband/verbs.h], [
AC_CHECK_LIB([ibverbs], [ibv_open_device],
[AC_DEFINE([HAVE_LIBIBVERBS], 1, [Define to 1 if we have -libverbs])
hwloc_have_libibverbs=yes])
])
AC_CHECK_HEADERS([myriexpress.h], [
AC_MSG_CHECKING(if MX_NUMA_NODE exists)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <myriexpress.h>]],
[[int a = MX_NUMA_NODE;]])],
[AC_MSG_RESULT(yes)
AC_CHECK_LIB([myriexpress], [mx_get_info],
[AC_DEFINE([HAVE_MYRIEXPRESS], 1, [Define to 1 if we have -lmyriexpress])
hwloc_have_myriexpress=yes])],
[AC_MSG_RESULT(no)])])
AC_CHECK_PROGS(XMLLINT, [xmllint])
AC_CHECK_PROGS(BUNZIPP, bunzip2, false)
AC_MSG_CHECKING(if CXX works)
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <iostream>
using namespace std;
int foo(void) {
cout << "test" << endl;
return 0;
}
]])], [hwloc_have_cxx=yes], [hwloc_have_cxx=no])
AC_LANG_POP([C++])
AC_MSG_RESULT([$hwloc_have_cxx])
_HWLOC_CHECK_DIFF_U
# Only generate these files if we're making the tests
AC_CONFIG_FILES(
hwloc_config_prefix[tests/Makefile]
hwloc_config_prefix[tests/linux/Makefile]
hwloc_config_prefix[tests/linux/gather/Makefile]
hwloc_config_prefix[tests/xml/Makefile]
hwloc_config_prefix[tests/ports/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/test-topology.sh]
hwloc_config_prefix[tests/xml/test-topology.sh]
hwloc_config_prefix[tests/wrapper.sh]
hwloc_config_prefix[utils/hwloc-assembler-remote]
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-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/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/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-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])
# These links are only needed in standalone mode. It would
# be nice to m4 foreach this somehow, but whenever I tried
# it, I got obscure "invalid tag" errors from
# AC_CONFIG_LINKS. :-\ Since these tests are only run when
# built in standalone mode, only generate them in
# standalone mode.
AC_CONFIG_LINKS(
hwloc_config_prefix[tests/ports/topology-solaris.c]:hwloc_config_prefix[src/topology-solaris.c]
hwloc_config_prefix[tests/ports/topology-solaris-chiptype.c]:hwloc_config_prefix[src/topology-solaris-chiptype.c]
hwloc_config_prefix[tests/ports/topology-aix.c]:hwloc_config_prefix[src/topology-aix.c]
hwloc_config_prefix[tests/ports/topology-osf.c]:hwloc_config_prefix[src/topology-osf.c]
hwloc_config_prefix[tests/ports/topology-windows.c]:hwloc_config_prefix[src/topology-windows.c]
hwloc_config_prefix[tests/ports/topology-darwin.c]:hwloc_config_prefix[src/topology-darwin.c]
hwloc_config_prefix[tests/ports/topology-freebsd.c]:hwloc_config_prefix[src/topology-freebsd.c]
hwloc_config_prefix[tests/ports/topology-netbsd.c]:hwloc_config_prefix[src/topology-netbsd.c]
hwloc_config_prefix[tests/ports/topology-hpux.c]:hwloc_config_prefix[src/topology-hpux.c]
hwloc_config_prefix[tests/ports/topology-bgq.c]:hwloc_config_prefix[src/topology-bgq.c]
hwloc_config_prefix[tests/ports/topology-opencl.c]:hwloc_config_prefix[src/topology-opencl.c]
hwloc_config_prefix[tests/ports/topology-cuda.c]:hwloc_config_prefix[src/topology-cuda.c]
hwloc_config_prefix[tests/ports/topology-nvml.c]:hwloc_config_prefix[src/topology-nvml.c]
hwloc_config_prefix[tests/ports/topology-gl.c]:hwloc_config_prefix[src/topology-gl.c])
])
])dnl

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

@ -0,0 +1,197 @@
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory.
#
# hwloc modification to the following PKG_* macros -- add HWLOC_
# prefix to make it "safe" to embed these macros in other packages.
# Originally copied from the pkg-config package; see copyright and
# license below.
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.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 of the License, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# 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.
# HWLOC_PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
# hwloc note: Per https://svn.open-mpi.org/trac/hwloc/ticket/55, keep
# the environment variable $PKG_CONFIG (vs. renaming it
# $HWLOC_PKG_CONFIG). Short explanation: $PKG_CONFIG is a well-known
# environment variable that can be set by users to override what these
# .m4 macros do. There's no reason we should have a different env
# variable name (e.g., $HWLOC_PKG_CONFIG). So leave it named
# $PKG_CONFIG both here in this specific macro, and all the other
# macros that use it.
AC_DEFUN([HWLOC_PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
HWLOC_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $HWLOC_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $HWLOC_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# HWLOC_PKG_PROG_PKG_CONFIG
# HWLOC_PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to HWLOC_PKG_CHECK_MODULES(), but does not set variables or print errors.
#
#
# Similar to HWLOC_PKG_CHECK_MODULES, make sure that the first instance of
# this or HWLOC_PKG_CHECK_MODULES is called, or make sure to call
# HWLOC_PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([HWLOC_PKG_CHECK_EXISTS],
[AC_REQUIRE([HWLOC_PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --silence-errors "$1"]); then
m4_ifval([$2], [$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _HWLOC_PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_HWLOC_PKG_CONFIG],
[if test -n "$PKG_CONFIG"; then
if test -n "$$1"; then
HWLOC_pkg_cv_[]$1="$$1"
else
HWLOC_PKG_CHECK_EXISTS([$3],
[HWLOC_pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
[HWLOC_pkg_failed=yes])
fi
else
HWLOC_pkg_failed=untried
fi[]
])# _HWLOC_PKG_CONFIG
# _HWLOC_PKG_SHORT_ERRORS_SUPPORTED
# -----------------------------
AC_DEFUN([_HWLOC_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([HWLOC_PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
HWLOC_pkg_short_errors_supported=yes
else
HWLOC_pkg_short_errors_supported=no
fi[]dnl
])# _HWLOC_PKG_SHORT_ERRORS_SUPPORTED
# HWLOC_PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
#
# Note that if there is a possibility the first call to
# HWLOC_PKG_CHECK_MODULES might not happen, you should be sure to include an
# explicit call to HWLOC_PKG_PROG_PKG_CONFIG in your configure.ac
#
#
# --------------------------------------------------------------
AC_DEFUN([HWLOC_PKG_CHECK_MODULES],[
AC_REQUIRE([HWLOC_PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([HWLOC_]$1[_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([HWLOC_]$1[_LIBS], [linker flags for $1, overriding pkg-config])dnl
HWLOC_pkg_failed=no
AC_MSG_CHECKING([for $1])
_HWLOC_PKG_CONFIG([HWLOC_][$1][_CFLAGS], [cflags], [$2])
_HWLOC_PKG_CONFIG([HWLOC_][$1][_LIBS], [libs], [$2])
m4_define([_HWLOC_PKG_TEXT], [Alternatively, you may set the environment variables HWLOC_[]$1[]_CFLAGS
and HWLOC_[]$1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
# Check for failure of pkg-config
if test $HWLOC_pkg_failed = yes; then
_HWLOC_PKG_SHORT_ERRORS_SUPPORTED
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`
else
HWLOC_[]$1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$HWLOC_[]$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
ifelse([$5], , [AC_MSG_ERROR(dnl
[Package requirements ($2) were not met:
$HWLOC_$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_HWLOC_PKG_TEXT
])],
[AC_MSG_RESULT([no])
$5])
elif test $HWLOC_pkg_failed = untried; then
ifelse([$5], , [AC_MSG_FAILURE(dnl
[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
path to pkg-config.
_HWLOC_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
[AC_MSG_RESULT([cannot check without pkg-config])
$5])
else
AC_MSG_RESULT([yes])
# If we got good results from pkg-config, check that they
# actually work (i.e., that we can link against the resulting
# $LIBS). The canonical example why we do this is if
# pkg-config returns 64 bit libraries but ./configure was run
# with CFLAGS=-m32 LDFLAGS=-m32. pkg-config gave us valid
# results, but we'll fail if we try to link. So detect that
# failure now.
hwloc_cflags_save=$CFLAGS
hwloc_libs_save=$LIBS
CFLAGS="$CFLAGS $HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS"
LIBS="$LIBS $HWLOC_pkg_cv_HWLOC_[]$1[]_LIBS"
AC_CHECK_FUNC([$3], [hwloc_result=yes], [hwloc_result=no])
CFLAGS=$hwloc_cflags_save
LIBS=$hwloc_libs_save
AC_MSG_CHECKING([for final $1 support])
AS_IF([test "$hwloc_result" = "yes"],
[HWLOC_[]$1[]_CFLAGS=$HWLOC_pkg_cv_HWLOC_[]$1[]_CFLAGS
HWLOC_[]$1[]_LIBS=$HWLOC_pkg_cv_HWLOC_[]$1[]_LIBS
AC_MSG_RESULT([yes])
ifelse([$4], , :, [$4])],
[AC_MSG_RESULT([no])
ifelse([$5], , :, [$5])])
fi[]dnl
])# HWLOC_PKG_CHECK_MODULES

527
opal/mca/hwloc/hwloc172/hwloc/config/install-sh Исполняемый файл
Просмотреть файл

@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# 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:

7982
opal/mca/hwloc/hwloc172/hwloc/config/libtool.m4 поставляемый Обычный файл

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

9655
opal/mca/hwloc/hwloc172/hwloc/config/ltmain.sh Обычный файл

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

384
opal/mca/hwloc/hwloc172/hwloc/config/ltoptions.m4 поставляемый Обычный файл
Просмотреть файл

@ -0,0 +1,384 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

123
opal/mca/hwloc/hwloc172/hwloc/config/ltsugar.m4 поставляемый Обычный файл
Просмотреть файл

@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

23
opal/mca/hwloc/hwloc172/hwloc/config/ltversion.m4 поставляемый Обычный файл
Просмотреть файл

@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 3337 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.2])
m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.2'
macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

98
opal/mca/hwloc/hwloc172/hwloc/config/lt~obsolete.m4 поставляемый Обычный файл
Просмотреть файл

@ -0,0 +1,98 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

215
opal/mca/hwloc/hwloc172/hwloc/config/missing Исполняемый файл
Просмотреть файл

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# 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:

127
opal/mca/hwloc/hwloc172/hwloc/config/test-driver Исполняемый файл
Просмотреть файл

@ -0,0 +1,127 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
scriptversion=2012-06-27.10; # UTC
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
# 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>.
# Make unconditional expansion of undefined variables an error. This
# helps a lot in preventing typo-related bugs.
set -u
usage_error ()
{
echo "$0: $*" >&2
print_usage >&2
exit 2
}
print_usage ()
{
cat <<END
Usage:
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}]
[--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
END
}
# TODO: better error handling in option parsing (in particular, ensure
# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting.
log_file= # Where to save the output of the test script.
trs_file= # Where to save the metadata of the test run.
expect_failure=no
color_tests=no
enable_hard_errors=yes
while test $# -gt 0; do
case $1 in
--help) print_usage; exit $?;;
--version) echo "test-driver $scriptversion"; exit $?;;
--test-name) test_name=$2; shift;;
--log-file) log_file=$2; shift;;
--trs-file) trs_file=$2; shift;;
--color-tests) color_tests=$2; shift;;
--expect-failure) expect_failure=$2; shift;;
--enable-hard-errors) enable_hard_errors=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
esac
shift
done
if test $color_tests = yes; then
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
red='' # Red.
grn='' # Green.
lgn='' # Light green.
blu='' # Blue.
mgn='' # Magenta.
std='' # No color.
else
red= grn= lgn= blu= mgn= std=
fi
do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
trap "st=129; $do_exit" 1
trap "st=130; $do_exit" 2
trap "st=141; $do_exit" 13
trap "st=143; $do_exit" 15
# Test script is run here.
"$@" >$log_file 2>&1
estatus=$?
if test $enable_hard_errors = no && test $estatus -eq 99; then
estatus=1
fi
case $estatus:$expect_failure in
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
0:*) col=$grn res=PASS recheck=no gcopy=no;;
77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
*:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
*:*) col=$red res=FAIL recheck=yes gcopy=yes;;
esac
# Report outcome to console.
echo "${col}${res}${std}: $test_name"
# Register the test result, and other relevant metadata.
echo ":test-result: $res" > $trs_file
echo ":global-test-result: $res" >> $trs_file
echo ":recheck: $recheck" >> $trs_file
echo ":copy-in-global-log: $gcopy" >> $trs_file
# 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:

31279
opal/mca/hwloc/hwloc172/hwloc/configure поставляемый Исполняемый файл

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

245
opal/mca/hwloc/hwloc172/hwloc/configure.ac Обычный файл
Просмотреть файл

@ -0,0 +1,245 @@
# -*- shell-script -*-
#
# Copyright © 2009 CNRS
# Copyright © 2009-2013 Inria. All rights reserved.
# Copyright © 2009, 2011-2012 Université Bordeaux 1
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
#
# See COPYING in top-level directory.
#
# Additional copyrights may follow
#
# $HEADER$
#
AC_INIT([hwloc],
[m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --base]))],
[http://www.open-mpi.org/projects/hwloc/], [hwloc])
AC_PREREQ(2.63)
AC_CONFIG_AUX_DIR(./config)
# Note that this directory must *exactly* match what was specified via
# -I in ACLOCAL_AMFLAGS in the top-level Makefile.am.
AC_CONFIG_MACRO_DIR(./config)
cat <<EOF
###
### Configuring hwloc distribution tarball
### Startup tests
###
EOF
# This must be before AM_INIT_AUTOMAKE
AC_CANONICAL_TARGET
# Init automake
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])])
# We want new Libtool. None of that old stuff. Pfft.
m4_ifdef([LT_PREREQ], [],
[m4_fatal([libtool version 2.2.6 or higher is required], [63])])
LT_PREREQ([2.2.6])
AC_LANG([C])
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'])
# 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`"
HWLOC_MAJOR_VERSION="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --major`"
HWLOC_MINOR_VERSION="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --minor`"
HWLOC_RELEASE_VERSION="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --release`"
HWLOC_REPO_REV="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --repo-rev`"
HWLOC_RELEASE_DATE="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --release-date`"
AC_SUBST(HWLOC_VERSION)
AC_SUBST(HWLOC_SVN_R)
AC_SUBST(HWLOC_RELEASE_DATE)
AC_DEFINE_UNQUOTED([HWLOC_MAJOR_VERSION], [$HWLOC_MAJOR_VERSION],
[Major version of hwloc])
AC_DEFINE_UNQUOTED([HWLOC_MINOR_VERSION], [$HWLOC_MINOR_VERSION],
[Minor version of hwloc])
AC_DEFINE_UNQUOTED([HWLOC_RELEASE_VERSION], [$HWLOC_RELEASE_VERSION],
[Release version of hwloc])
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
# (ie, no svn r numbers) 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 -*-
*
* Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux 1 All rights reserved.
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*
* This file is automatically generated by configure. Edits will be lost
* the next time you run configure!
*/
#ifndef HWLOC_CONFIGURE_H
#define HWLOC_CONFIGURE_H
])
AH_BOTTOM([
#endif /* HWLOC_CONFIGURE_H */
])
# Setup C compiler
CFLAGS_save="$CFLAGS"
AC_PROG_CC
AC_PROG_CXX
AM_PROG_CC_C_O
CFLAGS="$CFLAGS_save"
# This did not exist pre AM 1.11.x (where x is somewhere >0 and <3),
# but it is necessary in AM 1.12.x.
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])
AS_IF([test -z "$CC_FOR_BUILD"],[
AC_SUBST([CC_FOR_BUILD], [$CC])
])
# Define hwloc's configure arguments
HWLOC_DEFINE_ARGS
# If debug mode, add -g
AS_IF([test "$hwloc_debug" = "1"],
[CFLAGS="$CFLAGS -g"])
# If the user didn't specifically ask for embedding mode, default to
# standalone mode
AS_IF([test "$enable_embedded_mode" != "yes"],
[AS_IF([test ! -d "$srcdir/doc"],
[AC_MSG_WARN([The hwloc source tree looks incomplete for a standalone])
AC_MSG_WARN([build. Perhaps this hwloc tree is intended for an embedded])
AC_MSG_WARN([build? Try using the --enable-embedded-mode switch.])
AC_MSG_ERROR([Cannot build standalone hwloc])],
[HWLOC_BUILD_STANDALONE])])
# Setup the hwloc core
HWLOC_SETUP_CORE([], [], [AC_MSG_ERROR([Cannot build hwloc core])], [1])
# Setup hwloc's docs, utils, and tests
AS_IF([test "$hwloc_mode" = "standalone"],
[HWLOC_SETUP_DOCS
HWLOC_SETUP_UTILS
HWLOC_SETUP_TESTS])
cat <<EOF
###
### Performing final hwloc configuration
###
EOF
# Run the AM_CONDITIONALs
HWLOC_DO_AM_CONDITIONALS
# Set the final flags
CFLAGS="$HWLOC_EMBEDDED_CFLAGS $CFLAGS"
CPPFLAGS="$HWLOC_EMBEDDED_CPPFLAGS $CPPFLAGS"
LIBS="$HWLOC_EMBEDDED_LIBS $LIBS"
# Setup libtool, but disable C++, F77, Java and Windows Resource
# Compiler support -- we don't need that stuff.
AM_ENABLE_SHARED
AM_DISABLE_STATIC
AM_PROG_LIBTOOL([dlopen win32-dll])
LT_LANG([C])
# Party on
AC_OUTPUT
# Create a comma-delimited list in an environment variable.
# $1 = variable name
# $2 = value to append
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"],
[new_value="[$]2]")
eval "[$]1=\"$new_value\""
}
# Warn about PCI support
if test x$hwloc_warn_may_use_libpci = xyes; then
echo
echo "***********************************************************************"
echo "PCI support could not be enabled because libpciaccess is not available."
echo "libpci could be used instead but hwloc may be tainted by the GPL"
echo "license of pciutils. Add --enable-libpci to enable it."
echo "***********************************************************************"
fi
# Show which optional support we'll be building
hwloc_xml_status=basic
AS_IF([test "$hwloc_libxml2_happy" = "yes"], [hwloc_xml_status=full])
# Prepare the I/O summary
hwloc_probeio_list=
test "x$hwloc_pci_happy" = "xyes" && hwloc_probeio_list="$hwloc_probeio_list PCI"
test "x$hwloc_opencl_happy" = "xyes" && hwloc_probeio_list="$hwloc_probeio_list OpenCL"
test "x$hwloc_have_cudart" = "xyes" && hwloc_probeio_list="$hwloc_probeio_list CUDA"
test "x$hwloc_nvml_happy" = "xyes" && hwloc_probeio_list="$hwloc_probeio_list NVML"
test "x$hwloc_gl_happy" = "xyes" && hwloc_probeio_list="$hwloc_probeio_list GL"
# if anything but PCI, that anything will be useless
test "x$hwloc_pci_happy" != "xyes" && test "x$hwloc_probeio_list" != "x" && hwloc_probeio_list="$hwloc_probeio_list (cannot work without PCI)"
# if nothing, say "no"
test "x$hwloc_probeio_list" = "x" && hwloc_probeio_list=" no"
# Beginning of generic support
cat <<EOF
-----------------------------------------------------------------------------
Hwloc optional build support status (more details can be found above):
Probe / display I/O devices:$hwloc_probeio_list
Graphical output (Cairo): $hwloc_cairo_happy
XML input / output: $hwloc_xml_status
EOF
# Linux specific support
AS_IF([test "$hwloc_linux" = "yes"], [cat <<EOF
libnuma memory support: $hwloc_linux_libnuma_happy
EOF])
# Plugin support
hwloc_plugin_summary=$hwloc_have_plugins
test "x$hwloc_plugin_components" != "x" && hwloc_plugin_summary="yes ("`echo $hwloc_plugin_components`")" # echo removes the starting space
cat <<EOF
Plugin support: $hwloc_plugin_summary
EOF
# End of generic support
cat <<EOF
-----------------------------------------------------------------------------
EOF

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

@ -0,0 +1,145 @@
# Copyright © 2012 Inria. All rights reserved.
# See COPYING in top-level directory.
# suppressions file to be passed to valgrind with
# --suppressions=/path/to/hwloc-valgrind.supp
# zlib (brought by libpci or libxml2) doesn't cleanup its global state
{
inflate_init
Memcheck:Cond
fun:inflateReset2
fun:inflateInit2_
}
# hwloc cannot free the global parser (with xmlCleanupParser()) because other threads may be using it
{
xml_init_parser
Memcheck:Leak
...
fun:xmlInitParser
}
# hwloc cannot free the global xml dict RMutex because it cannot call xmlCleanupParser() as explained above
{
xml_dict_create_new_rmutex
Memcheck:Leak
fun:malloc
fun:xmlNewRMutex
...
fun:xmlDictCreate
}
# ltdl dlopen global state?
{
ltdl_dlopen_doit_leak
Memcheck:Leak
...
fun:dl_open_worker
fun:_dl_catch_error
fun:_dl_open
fun:dlopen_doit
}
# ltdl_dlclose_leak
{
ltdl_dlclose_leak
Memcheck:Leak
...
fun:_dl_close_worker
fun:_dl_close
...
fun:dlclose
}
# lt_dlforeachfile abusing paths
{
lt_dlforeachfile_addr8
Memcheck:Addr8
fun:_wordcopy_fwd_dest_aligned
fun:__GI_memmove
fun:argz_insert
...
fun:lt_dlforeachfile
}
# cuda
{
cuda_leak
Memcheck:Leak
...
obj:*libcuda*
}
# nvml
{
nvmlInit_cond
Memcheck:Cond
...
obj:*nvidia-ml*
...
fun:nvmlInit
}
# amd opencl
{
atical_leak
Memcheck:Leak
...
obj:*libatical*
}
{
atical_cond
Memcheck:Cond
...
obj:*libatical*
}
{
amdocl_leak
Memcheck:Leak
...
obj:*libamdocl*
}
{
amdocl_param
Memcheck:Param
write(buf)
fun:*write*
obj:*libamdocl*
}
{
opencl_leak
Memcheck:Leak
...
obj:*libOpenCL*
...
fun:clGetPlatformIDs
}
{
libatiadl_xcb_leak
Memcheck:Leak
...
obj:*libxcb*
...
fun:XOpenDisplay
...
obj:*libatiadl*
}
#
{
libpciaccess_device_name_leak
Memcheck:Leak
...
fun:pci_device_get_device_name
fun:hwloc_look_libpci
}
{
libpciaccess_leak
Memcheck:Leak
...
obj:*libpciaccess*
...
fun:hwloc_look_libpci
}

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

@ -0,0 +1,4 @@
Open MPI doesn't need this tree from hwloc. But automake *requires*
that this directory has to be here. So we have an empty directory
with a README in it, a) just to explain why it's here, and b) so that
hg clones won't delete the directory (because it's empty).

12
opal/mca/hwloc/hwloc172/hwloc/hwloc.pc.in Обычный файл
Просмотреть файл

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: hwloc
Description: Hardware locality detection and management library
Version: @VERSION@
Requires.private: @HWLOC_REQUIRES@
Cflags: -I${includedir}
Libs: -L${libdir} -lhwloc
Libs.private: @HWLOC_LIBS@ @HWLOC_LIBS_PRIVATE@

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

@ -0,0 +1,52 @@
# Copyright © 2009-2012 Inria. All rights reserved.
# Copyright © 2009-2010 Université Bordeaux 1
# Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
# Copyright © 2011 Oracle and/or its affiliates. All rights reserved.
# See COPYING in top-level directory.
# Only install the headers if we're in standalone mode (meaning:
# *don't* install the headers if we're in embedded mode).
if HWLOC_BUILD_STANDALONE
include_HEADERS = hwloc.h
include_hwlocdir = $(includedir)/hwloc
include_hwloc_HEADERS = \
hwloc/bitmap.h \
hwloc/helper.h \
hwloc/myriexpress.h \
hwloc/openfabrics-verbs.h \
hwloc/opencl.h \
hwloc/cuda.h \
hwloc/cudart.h \
hwloc/nvml.h \
hwloc/plugins.h \
hwloc/gl.h \
hwloc/intel-mic.h \
hwloc/rename.h
include_hwloc_autogendir = $(includedir)/hwloc/autogen
nodist_include_hwloc_autogen_HEADERS = hwloc/autogen/config.h
noinst_HEADERS = \
private/private.h \
private/debug.h \
private/misc.h \
private/xml.h \
private/components.h \
private/cpuid.h
if HWLOC_HAVE_LINUX
include_hwloc_HEADERS += \
hwloc/linux.h \
hwloc/linux-libnuma.h
endif HWLOC_HAVE_LINUX
if HWLOC_HAVE_SOLARIS
include_hwloc_HEADERS += \
private/solaris-chiptype.h
endif HWLOC_HAVE_SOLARIS
if HWLOC_HAVE_SCHED_SETAFFINITY
include_hwloc_HEADERS += hwloc/glibc-sched.h
endif HWLOC_HAVE_SCHED_SETAFFINITY
endif HWLOC_BUILD_STANDALONE

2228
opal/mca/hwloc/hwloc172/hwloc/include/hwloc.h Обычный файл

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

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

@ -0,0 +1,188 @@
/* -*- c -*-
* Copyright © 2009 CNRS
* Copyright © 2009-2010 inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* The configuration file */
#ifndef HWLOC_CONFIG_H
#define HWLOC_CONFIG_H
#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
# define __hwloc_restrict __restrict
#else
# if __STDC_VERSION__ >= 199901L
# define __hwloc_restrict restrict
# else
# define __hwloc_restrict
# endif
#endif
/* Note that if we're compiling C++, then just use the "inline"
keyword, since it's part of C++ */
#if defined(c_plusplus) || defined(__cplusplus)
# define __hwloc_inline inline
#elif defined(_MSC_VER) || defined(__HP_cc)
# define __hwloc_inline __inline
#else
# define __hwloc_inline __inline__
#endif
/*
* Note: this is public. We can not assume anything from the compiler used
* by the application and thus the HWLOC_HAVE_* macros below are not
* fetched from the autoconf result here. We only automatically use a few
* well-known easy cases.
*/
/* Some handy constants to make the logic below a little more readable */
#if defined(__cplusplus) && \
(__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR >= 4))
#define GXX_ABOVE_3_4 1
#else
#define GXX_ABOVE_3_4 0
#endif
#if !defined(__cplusplus) && \
(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
#define GCC_ABOVE_2_95 1
#else
#define GCC_ABOVE_2_95 0
#endif
#if !defined(__cplusplus) && \
(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
#define GCC_ABOVE_2_96 1
#else
#define GCC_ABOVE_2_96 0
#endif
#if !defined(__cplusplus) && \
(__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
#define GCC_ABOVE_3_3 1
#else
#define GCC_ABOVE_3_3 0
#endif
/* Maybe before gcc 2.95 too */
#ifdef HWLOC_HAVE_ATTRIBUTE_UNUSED
#define __HWLOC_HAVE_ATTRIBUTE_UNUSED HWLOC_HAVE_ATTRIBUTE_UNUSED
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_UNUSED (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)
#else
# define __HWLOC_HAVE_ATTRIBUTE_UNUSED 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_UNUSED
# define __hwloc_attribute_unused __attribute__((__unused__))
#else
# define __hwloc_attribute_unused
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_MALLOC
#define __HWLOC_HAVE_ATTRIBUTE_MALLOC HWLOC_HAVE_ATTRIBUTE_MALLOC
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_MALLOC (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)
#else
# define __HWLOC_HAVE_ATTRIBUTE_MALLOC 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_MALLOC
# define __hwloc_attribute_malloc __attribute__((__malloc__))
#else
# define __hwloc_attribute_malloc
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_CONST
#define __HWLOC_HAVE_ATTRIBUTE_CONST HWLOC_HAVE_ATTRIBUTE_CONST
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_CONST (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)
#else
# define __HWLOC_HAVE_ATTRIBUTE_CONST 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_CONST
# define __hwloc_attribute_const __attribute__((__const__))
#else
# define __hwloc_attribute_const
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_PURE
#define __HWLOC_HAVE_ATTRIBUTE_PURE HWLOC_HAVE_ATTRIBUTE_PURE
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_PURE (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)
#else
# define __HWLOC_HAVE_ATTRIBUTE_PURE 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_PURE
# define __hwloc_attribute_pure __attribute__((__pure__))
#else
# define __hwloc_attribute_pure
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED (GXX_ABOVE_3_4 || GCC_ABOVE_3_3)
#else
# define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_DEPRECATED
# define __hwloc_attribute_deprecated __attribute__((__deprecated__))
#else
# define __hwloc_attribute_deprecated
#endif
#ifdef HWLOC_C_HAVE_VISIBILITY
# if HWLOC_C_HAVE_VISIBILITY
# define HWLOC_DECLSPEC __attribute__((__visibility__("default")))
# else
# define HWLOC_DECLSPEC
# endif
#else
# define HWLOC_DECLSPEC
#endif
/* Defined to 1 on Linux */
#undef HWLOC_LINUX_SYS
/* Defined to 1 if the CPU_SET macro works */
#undef HWLOC_HAVE_CPU_SET
/* Defined to 1 if you have the `windows.h' header. */
#undef HWLOC_HAVE_WINDOWS_H
#undef hwloc_pid_t
#undef hwloc_thread_t
#ifdef HWLOC_HAVE_WINDOWS_H
# include <windows.h>
typedef DWORDLONG hwloc_uint64_t;
#else /* HWLOC_HAVE_WINDOWS_H */
# ifdef hwloc_thread_t
# include <pthread.h>
# endif /* hwloc_thread_t */
/* Defined to 1 if you have the <stdint.h> header file. */
# undef HWLOC_HAVE_STDINT_H
# include <unistd.h>
# ifdef HWLOC_HAVE_STDINT_H
# include <stdint.h>
# endif
typedef uint64_t hwloc_uint64_t;
#endif /* HWLOC_HAVE_WINDOWS_H */
/* Whether we need to re-define all the hwloc public symbols or not */
#undef HWLOC_SYM_TRANSFORM
/* The hwloc symbol prefix */
#undef HWLOC_SYM_PREFIX
/* The hwloc symbol prefix in all caps */
#undef HWLOC_SYM_PREFIX_CAPS
#endif /* HWLOC_CONFIG_H */

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

@ -0,0 +1,350 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2011 inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief The bitmap API, for use in hwloc itself.
*/
#ifndef HWLOC_BITMAP_H
#define HWLOC_BITMAP_H
#include <hwloc/autogen/config.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_bitmap The bitmap API
*
* The ::hwloc_bitmap_t type represents a set of objects, typically OS
* processors -- which may actually be hardware threads (represented
* by ::hwloc_cpuset_t, which is a typedef for ::hwloc_bitmap_t) -- or
* memory nodes (represented by ::hwloc_nodeset_t, which is also a
* typedef for ::hwloc_bitmap_t).
*
* <em>Both CPU and node sets are always indexed by OS physical number.</em>
*
* \note CPU sets and nodesets are described in \ref hwlocality_sets.
*
* A bitmap may be of infinite size.
* @{
*/
/** \brief
* Set of bits represented as an opaque pointer to an internal bitmap.
*/
typedef struct hwloc_bitmap_s * hwloc_bitmap_t;
/** \brief a non-modifiable ::hwloc_bitmap_t */
typedef const struct hwloc_bitmap_s * hwloc_const_bitmap_t;
/*
* Bitmap allocation, freeing and copying.
*/
/** \brief Allocate a new empty bitmap.
*
* \returns A valid bitmap or \c NULL.
*
* The bitmap should be freed by a corresponding call to
* hwloc_bitmap_free().
*/
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc(void) __hwloc_attribute_malloc;
/** \brief Allocate a new full bitmap. */
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc_full(void) __hwloc_attribute_malloc;
/** \brief Free bitmap \p bitmap.
*
* If \p bitmap is \c NULL, no operation is performed.
*/
HWLOC_DECLSPEC void hwloc_bitmap_free(hwloc_bitmap_t bitmap);
/** \brief Duplicate bitmap \p bitmap by allocating a new bitmap and copying \p bitmap contents.
*
* If \p bitmap is \c NULL, \c NULL is returned.
*/
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc;
/** \brief Copy the contents of bitmap \p src into the already allocated bitmap \p dst */
HWLOC_DECLSPEC void hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src);
/*
* Bitmap/String Conversion
*/
/** \brief Stringify a bitmap.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated string.
*/
HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a bitmap string and stores it in bitmap \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/** \brief Stringify a bitmap in the list format.
*
* Lists are comma-separated indexes or ranges.
* Ranges are dash separated indexes.
* The last range may not have a ending indexes if the bitmap is infinite.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated list string.
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a list string and stores it in bitmap \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/** \brief Stringify a bitmap in the taskset-specific format.
*
* The taskset command manipulates bitmap strings that contain a single
* (possible very long) hexadecimal number starting with 0x.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated taskset-specific string.
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a taskset-specific bitmap string and stores it in bitmap \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/*
* Building bitmaps.
*/
/** \brief Empty the bitmap \p bitmap */
HWLOC_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap);
/** \brief Fill bitmap \p bitmap with all possible indexes (even if those objects don't exist or are otherwise unavailable) */
HWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap);
/** \brief Empty the bitmap \p bitmap and add bit \p id */
HWLOC_DECLSPEC void hwloc_bitmap_only(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Fill the bitmap \p and clear the index \p id */
HWLOC_DECLSPEC void hwloc_bitmap_allbut(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Setup bitmap \p bitmap from unsigned long \p mask */
HWLOC_DECLSPEC void hwloc_bitmap_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask);
/** \brief Setup bitmap \p bitmap from unsigned long \p mask used as \p i -th subset */
HWLOC_DECLSPEC void hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
/*
* Modifying bitmaps.
*/
/** \brief Add index \p id in bitmap \p bitmap */
HWLOC_DECLSPEC void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Add indexes from \p begin to \p end in bitmap \p bitmap.
*
* If \p end is \c -1, the range is infinite.
*/
HWLOC_DECLSPEC void hwloc_bitmap_set_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
/** \brief Replace \p i -th subset of bitmap \p bitmap with unsigned long \p mask */
HWLOC_DECLSPEC void hwloc_bitmap_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
/** \brief Remove index \p id from bitmap \p bitmap */
HWLOC_DECLSPEC void hwloc_bitmap_clr(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Remove indexes from \p begin to \p end in bitmap \p bitmap.
*
* If \p end is \c -1, the range is infinite.
*/
HWLOC_DECLSPEC void hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
/** \brief Keep a single index among those set in bitmap \p bitmap
*
* May be useful before binding so that the process does not
* have a chance of migrating between multiple logical CPUs
* in the original mask.
*/
HWLOC_DECLSPEC void hwloc_bitmap_singlify(hwloc_bitmap_t bitmap);
/*
* Consulting bitmaps.
*/
/** \brief Convert the beginning part of bitmap \p bitmap into unsigned long \p mask */
HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ulong(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Convert the \p i -th subset of bitmap \p bitmap into unsigned long mask */
HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ith_ulong(hwloc_const_bitmap_t bitmap, unsigned i) __hwloc_attribute_pure;
/** \brief Test whether index \p id is part of bitmap \p bitmap */
HWLOC_DECLSPEC int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p bitmap is empty */
HWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p bitmap is completely full */
HWLOC_DECLSPEC int hwloc_bitmap_isfull(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the first index (least significant bit) in bitmap \p bitmap
*
* \return -1 if no index is set.
*/
HWLOC_DECLSPEC int hwloc_bitmap_first(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the next index in bitmap \p bitmap which is after index \p prev
*
* If \p prev is -1, the first index is returned.
*
* \return -1 if no index with higher index is bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_next(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;
/** \brief Compute the last index (most significant bit) in bitmap \p bitmap
*
* \return -1 if no index is bitmap, or if the index bitmap is infinite.
*/
HWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the "weight" of bitmap \p bitmap (i.e., number of
* indexes that are in the bitmap).
*
* \return the number of indexes that are in the bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Loop macro iterating on bitmap \p bitmap
* \hideinitializer
*
* \p index is the loop variable; it should be an unsigned int. The
* first iteration will set \p index to the lowest index in the bitmap.
* Successive iterations will iterate through, in order, all remaining
* indexes that in the bitmap. To be specific: each iteration will return a
* value for \p index such that hwloc_bitmap_isset(bitmap, index) is true.
*
* The assert prevents the loop from being infinite if the bitmap is infinite.
*/
#define hwloc_bitmap_foreach_begin(id, bitmap) \
do { \
assert(hwloc_bitmap_weight(bitmap) != -1); \
for (id = hwloc_bitmap_first(bitmap); \
(unsigned) id != (unsigned) -1; \
id = hwloc_bitmap_next(bitmap, id)) { \
/** \brief End of loop. Needs a terminating ';'.
* \hideinitializer
*
* \sa hwloc_bitmap_foreach_begin */
#define hwloc_bitmap_foreach_end() \
} \
} while (0)
/*
* Combining bitmaps.
*/
/** \brief Or bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC void hwloc_bitmap_or (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief And bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC void hwloc_bitmap_and (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief And bitmap \p bitmap1 and the negation of \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC void hwloc_bitmap_andnot (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief Xor bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC void hwloc_bitmap_xor (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief Negate bitmap \p bitmap and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap
*/
HWLOC_DECLSPEC void hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap);
/*
* Comparing bitmaps.
*/
/** \brief Test whether bitmaps \p bitmap1 and \p bitmap2 intersects */
HWLOC_DECLSPEC int hwloc_bitmap_intersects (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p sub_bitmap is part of bitmap \p super_bitmap */
HWLOC_DECLSPEC int hwloc_bitmap_isincluded (hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p bitmap1 is equal to bitmap \p bitmap2 */
HWLOC_DECLSPEC int hwloc_bitmap_isequal (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 using their lowest index.
*
* Smaller least significant bit is smaller.
* The empty bitmap is considered higher than anything.
*/
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.
*
* Higher most significant bit is higher.
* The empty bitmap is considered lower than anything.
*/
HWLOC_DECLSPEC int hwloc_bitmap_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_BITMAP_H */

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

@ -0,0 +1,220 @@
/*
* Copyright © 2010-2013 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the CUDA Driver API.
*
* Applications that use both hwloc and the CUDA Driver API may want to
* include this file so as to get topology information for CUDA devices.
*
*/
#ifndef HWLOC_CUDA_H
#define HWLOC_CUDA_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#include <hwloc/helper.h>
#ifdef HWLOC_LINUX_SYS
#include <hwloc/linux.h>
#endif
#include <cuda.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_cuda CUDA Driver API Specific Functions
* @{
*/
/** \brief Return the domain, bus and device IDs of the CUDA device \p cudevice.
*
* Device \p cudevice must match the local machine.
*/
static __hwloc_inline int
hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, int *domain, int *bus, int *dev)
{
CUresult cres;
#ifdef CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID
cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
if (cres != CUDA_SUCCESS) {
errno = ENOSYS;
return -1;
}
#else
*domain = 0;
#endif
cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);
if (cres != CUDA_SUCCESS) {
errno = ENOSYS;
return -1;
}
cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);
if (cres != CUDA_SUCCESS) {
errno = ENOSYS;
return -1;
}
return 0;
}
/** \brief Get the CPU set of logical processors that are physically
* close to device \p cudevice.
*
* Return the CPU set describing the locality of the CUDA device \p cudevice.
*
* Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection and the CUDA component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_cuda_get_device_osdev()
* and hwloc_cuda_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
int domainid, busid, deviceid;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
return -1;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;
hwloc_linux_parse_cpumap_file(sysfile, set);
if (hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc PCI device object corresponding to the
* CUDA device \p cudevice.
*
* Return the PCI device object describing the CUDA device \p cudevice.
* Return NULL if there is none.
*
* Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection must be enabled in topology \p topology.
* The CUDA component is not needed in the topology.
*/
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
{
int domain, bus, dev;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL;
return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
}
/** \brief Get the hwloc OS device object corresponding to CUDA device \p cudevice.
*
* Return the hwloc OS device object that describes the given
* CUDA device \p cudevice. Return NULL if there is none.
*
* Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection and the NVML component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_cuda_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer.
*/
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
{
hwloc_obj_t osdev = NULL;
int domain, bus, dev;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL;
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "cuda", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& (int) pcidev->attr->pcidev.domain == domain
&& (int) pcidev->attr->pcidev.bus == bus
&& (int) pcidev->attr->pcidev.dev == dev
&& pcidev->attr->pcidev.func == 0)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the
* CUDA device whose index is \p idx.
*
* Return the OS device object describing the CUDA device whose
* index is \p idx. Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the CUDA component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*
* \note This function is identical to hwloc_cudart_get_device_osdev_by_index().
*/
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_CUDA_H */

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

@ -0,0 +1,179 @@
/*
* Copyright © 2010-2013 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the CUDA Runtime API.
*
* Applications that use both hwloc and the CUDA Runtime API may want to
* include this file so as to get topology information for CUDA devices.
*
*/
#ifndef HWLOC_CUDART_H
#define HWLOC_CUDART_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#include <hwloc/helper.h>
#ifdef HWLOC_LINUX_SYS
#include <hwloc/linux.h>
#endif
#include <cuda_runtime_api.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_cudart CUDA Runtime API Specific Functions
* @{
*/
/** \brief Return the domain, bus and device IDs of the CUDA device whose index is \p idx.
*
* Device index \p idx must match the local machine.
*/
static __hwloc_inline int
hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
int idx, int *domain, int *bus, int *dev)
{
cudaError_t cerr;
struct cudaDeviceProp prop;
cerr = cudaGetDeviceProperties(&prop, idx);
if (cerr) {
errno = ENOSYS;
return -1;
}
#ifdef CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID
*domain = prop.pciDomainID;
#else
*domain = 0;
#endif
*bus = prop.pciBusID;
*dev = prop.pciDeviceID;
return 0;
}
/** \brief Get the CPU set of logical processors that are physically
* close to device \p idx.
*
* Return the CPU set describing the locality of the CUDA device
* whose index is \p idx.
*
* Topology \p topology and device \p idx must match the local machine.
* I/O devices detection and the CUDA component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_cudart_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
int idx, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
int domain, bus, dev;
if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
return -1;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, dev);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;
hwloc_linux_parse_cpumap_file(sysfile, set);
if (hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc PCI device object corresponding to the
* CUDA device whose index is \p idx.
*
* Return the PCI device object describing the CUDA device whose
* index is \p idx. Return NULL if there is none.
*
* Topology \p topology and device \p idx must match the local machine.
* I/O devices detection must be enabled in topology \p topology.
* The CUDA component is not needed in the topology.
*/
static __hwloc_inline hwloc_obj_t
hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx)
{
int domain, bus, dev;
if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
return NULL;
return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
}
/** \brief Get the hwloc OS device object corresponding to the
* CUDA device whose index is \p idx.
*
* Return the OS device object describing the CUDA device whose
* index is \p idx. Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the CUDA component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_cudart_get_device_cpuset().
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*
* \note This function is identical to hwloc_cuda_get_device_osdev_by_index().
*/
static __hwloc_inline hwloc_obj_t
hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_CUDART_H */

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

@ -0,0 +1,131 @@
/*
* Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
* Copyright © 2012-2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and OpenGL displays.
*
* Applications that use both hwloc and OpenGL may want to include
* this file so as to get topology information for OpenGL displays.
*
* Only the NVIDIA display locality information is currently available,
* using the NV-CONTROL X11 extension and the NVCtrl library.
*/
#ifndef HWLOC_GL_H
#define HWLOC_GL_H
#include <hwloc.h>
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_gl OpenGL display specific functions
* @{
*/
/** \brief Get the hwloc OS device object corresponding to the
* OpenGL display given by port and device index.
*
* Return the OS device object describing the OpenGL display
* whose port (server) is \p port and device (screen) is \p device.
* Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the GL component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,
unsigned port, unsigned device)
{
unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2
&& port == x && device == y)
return osdev;
}
errno = EINVAL;
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the
* OpenGL display given by name.
*
* Return the OS device object describing the OpenGL display
* whose name is \p name, built as ":port.device" such as ":0.0" .
* Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the GL component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,
const char *name)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strcmp(name, osdev->name))
return osdev;
}
errno = EINVAL;
return NULL;
}
/** \brief Get the OpenGL display port and device corresponding
* to the given hwloc OS object.
*
* Return the OpenGL display port (server) in \p port and device (screen)
* in \p screen that correspond to the given hwloc OS device object.
* Return \c -1 if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the GL component must be enabled in the topology.
*/
static __hwloc_inline int
hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
hwloc_obj_t osdev,
unsigned *port, unsigned *device)
{
unsigned x = -1, y = -1;
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2) {
*port = x;
*device = y;
return 0;
}
errno = EINVAL;
return -1;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_GL_H */

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

@ -0,0 +1,121 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and glibc scheduling routines.
*
* Applications that use both hwloc and glibc scheduling routines such as
* sched_getaffinity() or pthread_attr_setaffinity_np() may want to include
* this file so as to ease conversion between their respective types.
*
* \note Topology \p topology must match the current machine.
*/
#ifndef HWLOC_GLIBC_SCHED_H
#define HWLOC_GLIBC_SCHED_H
#include <hwloc.h>
#include <hwloc/helper.h>
#include <assert.h>
#if !defined _GNU_SOURCE || !defined _SCHED_H || (!defined CPU_SETSIZE && !defined sched_priority)
#error Please make sure to include sched.h before including glibc-sched.h, and define _GNU_SOURCE before any inclusion of sched.h
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HWLOC_HAVE_CPU_SET
/** \defgroup hwlocality_glibc_sched Helpers for manipulating glibc sched affinity
* @{
*/
/** \brief Convert hwloc CPU set \p toposet into glibc sched affinity CPU set \p schedset
*
* This function may be used before calling sched_setaffinity or any other function
* that takes a cpu_set_t as input parameter.
*
* \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC
*/
static __hwloc_inline int
hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset,
cpu_set_t *schedset, size_t schedsetsize)
{
#ifdef CPU_ZERO_S
unsigned cpu;
CPU_ZERO_S(schedsetsize, schedset);
hwloc_bitmap_foreach_begin(cpu, hwlocset)
CPU_SET_S(cpu, schedsetsize, schedset);
hwloc_bitmap_foreach_end();
#else /* !CPU_ZERO_S */
unsigned cpu;
CPU_ZERO(schedset);
assert(schedsetsize == sizeof(cpu_set_t));
hwloc_bitmap_foreach_begin(cpu, hwlocset)
CPU_SET(cpu, schedset);
hwloc_bitmap_foreach_end();
#endif /* !CPU_ZERO_S */
return 0;
}
/** \brief Convert glibc sched affinity CPU set \p schedset into hwloc CPU set
*
* This function may be used before calling sched_setaffinity or any other function
* that takes a cpu_set_t as input parameter.
*
* \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC
*/
static __hwloc_inline int
hwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cpuset_t hwlocset,
const cpu_set_t *schedset, size_t schedsetsize)
{
int cpu;
#ifdef CPU_ZERO_S
int count;
#endif
hwloc_bitmap_zero(hwlocset);
#ifdef CPU_ZERO_S
count = CPU_COUNT_S(schedsetsize, schedset);
cpu = 0;
while (count) {
if (CPU_ISSET_S(cpu, schedsetsize, schedset)) {
hwloc_bitmap_set(hwlocset, cpu);
count--;
}
cpu++;
}
#else /* !CPU_ZERO_S */
/* sched.h does not support dynamic cpu_set_t (introduced in glibc 2.7),
* assume we have a very old interface without CPU_COUNT (added in 2.6)
*/
assert(schedsetsize == sizeof(cpu_set_t));
for(cpu=0; cpu<CPU_SETSIZE; cpu++)
if (CPU_ISSET(cpu, schedset))
hwloc_bitmap_set(hwlocset, cpu);
#endif /* !CPU_ZERO_S */
return 0;
}
/** @} */
#endif /* CPU_SET */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_GLIBC_SCHED_H */

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

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

@ -0,0 +1,139 @@
/*
* Copyright © 2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Intel Xeon Phi (MIC).
*
* Applications that use both hwloc and Intel Xeon Phi (MIC) may want to
* include this file so as to get topology information for MIC devices.
*/
#ifndef HWLOC_INTEL_MIC_H
#define HWLOC_INTEL_MIC_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#include <hwloc/helper.h>
#ifdef HWLOC_LINUX_SYS
#include <hwloc/linux.h>
#include <dirent.h>
#include <string.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_intel_mic Intel Xeon Phi (MIC) Specific Functions
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to MIC device whose index is \p idx.
*
* Return the CPU set describing the locality of the MIC device whose index is \p idx.
*
* Topology \p topology and device index \p idx must match the local machine.
* I/O devices detection is not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_intel_mic_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
int idx __hwloc_attribute_unused,
hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX];
DIR *sysdir = NULL;
FILE *sysfile = NULL;
struct dirent *dirent;
unsigned pcibus, pcidev, pcifunc;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/class/mic/mic%d", idx);
sysdir = opendir(path);
if (!sysdir)
return -1;
while ((dirent = readdir(sysdir)) != NULL) {
if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) {
sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc);
sysfile = fopen(path, "r");
if (!sysfile) {
closedir(sysdir);
return -1;
}
hwloc_linux_parse_cpumap_file(sysfile, set);
if (hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
fclose(sysfile);
break;
}
}
closedir(sysdir);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* MIC device for the given index.
*
* Return the OS device object describing the MIC device whose index is \p idx.
* Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_intel_mic_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("mic", osdev->name, 3)
&& atoi(osdev->name + 3) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_INTEL_MIC_H */

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

@ -0,0 +1,336 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Linux libnuma.
*
* Applications that use both Linux libnuma and hwloc may want to
* include this file so as to ease conversion between their respective types.
*
* This helper also offers a consistent behavior on non-NUMA machines
* or non-NUMA-aware kernels by assuming that the machines have a single
* NUMA node.
*
* \note Topology \p topology must match the current machine.
*
* \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
* (when CONFIG_NUMA is not set in the kernel configuration).
* This helper and libnuma may thus not be strictly compatible in this case,
* which may be detected by checking whether numa_available() returns -1.
*/
#ifndef HWLOC_LINUX_LIBNUMA_H
#define HWLOC_LINUX_LIBNUMA_H
#include <hwloc.h>
#include <numa.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_linux_libnuma_ulongs Helpers for manipulating Linux libnuma unsigned long masks
* @{
*/
/** \brief Convert hwloc CPU set \p cpuset into the array of unsigned long \p mask
*
* \p mask is the array of unsigned long that will be filled.
* \p maxnode contains the maximal node number that may be stored in \p mask.
* \p maxnode will be set to the maximal node number that was found, plus one.
*
* This function may be used before calling set_mempolicy, mbind, migrate_pages
* or any other function that takes an array of unsigned long and a maximal
* node number as input parameter.
*/
static __hwloc_inline int
hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
unsigned long *mask, unsigned long *maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
unsigned long outmaxnode = -1;
/* round-up to the next ulong and clear all bytes */
*maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
memset(mask, 0, *maxnode/8);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL) {
if (node->os_index >= *maxnode)
continue;
mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
outmaxnode = node->os_index;
}
} else {
/* if no numa, libnuma assumes we have a single node */
if (!hwloc_bitmap_iszero(cpuset)) {
mask[0] = 1;
outmaxnode = 0;
}
}
*maxnode = outmaxnode+1;
return 0;
}
/** \brief Convert hwloc NUMA node set \p nodeset into the array of unsigned long \p mask
*
* \p mask is the array of unsigned long that will be filled.
* \p maxnode contains the maximal node number that may be stored in \p mask.
* \p maxnode will be set to the maximal node number that was found, plus one.
*
* This function may be used before calling set_mempolicy, mbind, migrate_pages
* or any other function that takes an array of unsigned long and a maximal
* node number as input parameter.
*/
static __hwloc_inline int
hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
unsigned long *mask, unsigned long *maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
unsigned long outmaxnode = -1;
/* round-up to the next ulong and clear all bytes */
*maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
memset(mask, 0, *maxnode/8);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) {
if (node->os_index >= *maxnode)
continue;
if (!hwloc_bitmap_isset(nodeset, node->os_index))
continue;
mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
outmaxnode = node->os_index;
}
} else {
/* if no numa, libnuma assumes we have a single node */
if (!hwloc_bitmap_iszero(nodeset)) {
mask[0] = 1;
outmaxnode = 0;
}
}
*maxnode = outmaxnode+1;
return 0;
}
/** \brief Convert the array of unsigned long \p mask into hwloc CPU set
*
* \p mask is a array of unsigned long that will be read.
* \p maxnode contains the maximal node number that may be read in \p mask.
*
* This function may be used after calling get_mempolicy or any other function
* that takes an array of unsigned long as output parameter (and possibly
* a maximal node number as input parameter).
*/
static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const unsigned long *mask, unsigned long maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(cpuset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
} else {
/* if no numa, libnuma assumes we have a single node */
if (mask[0] & 1)
hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
else
hwloc_bitmap_zero(cpuset);
}
return 0;
}
/** \brief Convert the array of unsigned long \p mask into hwloc NUMA node set
*
* \p mask is a array of unsigned long that will be read.
* \p maxnode contains the maximal node number that may be read in \p mask.
*
* This function may be used after calling get_mempolicy or any other function
* that takes an array of unsigned long as output parameter (and possibly
* a maximal node number as input parameter).
*/
static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const unsigned long *mask, unsigned long maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(nodeset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_set(nodeset, node->os_index);
} else {
/* if no numa, libnuma assumes we have a single node */
if (mask[0] & 1)
hwloc_bitmap_fill(nodeset);
else
hwloc_bitmap_zero(nodeset);
}
return 0;
}
/** @} */
/** \defgroup hwlocality_linux_libnuma_bitmask Helpers for manipulating Linux libnuma bitmask
* @{
*/
/** \brief Convert hwloc CPU set \p cpuset into the returned libnuma bitmask
*
* The returned bitmask should later be freed with numa_bitmask_free.
*
* This function may be used before calling many numa_ functions
* that use a struct bitmask as an input parameter.
*
* \return newly allocated struct bitmask.
*/
static __hwloc_inline struct bitmask *
hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) __hwloc_attribute_malloc;
static __hwloc_inline struct bitmask *
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);
struct bitmask *bitmask = numa_allocate_cpumask();
if (!bitmask)
return NULL;
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL)
if (node->memory.local_memory)
numa_bitmask_setbit(bitmask, node->os_index);
} else {
/* if no numa, libnuma assumes we have a single node */
if (!hwloc_bitmap_iszero(cpuset))
numa_bitmask_setbit(bitmask, 0);
}
return bitmask;
}
/** \brief Convert hwloc NUMA node set \p nodeset into the returned libnuma bitmask
*
* The returned bitmask should later be freed with numa_bitmask_free.
*
* This function may be used before calling many numa_ functions
* that use a struct bitmask as an input parameter.
*
* \return newly allocated struct bitmask.
*/
static __hwloc_inline struct bitmask *
hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) __hwloc_attribute_malloc;
static __hwloc_inline struct bitmask *
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);
struct bitmask *bitmask = numa_allocate_cpumask();
if (!bitmask)
return NULL;
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (hwloc_bitmap_isset(nodeset, node->os_index) && node->memory.local_memory)
numa_bitmask_setbit(bitmask, node->os_index);
} else {
/* if no numa, libnuma assumes we have a single node */
if (!hwloc_bitmap_iszero(nodeset))
numa_bitmask_setbit(bitmask, 0);
}
return bitmask;
}
/** \brief Convert libnuma bitmask \p bitmask into hwloc CPU set \p cpuset
*
* This function may be used after calling many numa_ functions
* that use a struct bitmask as an output parameter.
*/
static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const struct bitmask *bitmask)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(cpuset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (numa_bitmask_isbitset(bitmask, node->os_index))
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
} else {
/* if no numa, libnuma assumes we have a single node */
if (numa_bitmask_isbitset(bitmask, 0))
hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));
else
hwloc_bitmap_zero(cpuset);
}
return 0;
}
/** \brief Convert libnuma bitmask \p bitmask into hwloc NUMA node set \p nodeset
*
* This function may be used after calling many numa_ functions
* that use a struct bitmask as an output parameter.
*/
static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const struct bitmask *bitmask)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(nodeset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (numa_bitmask_isbitset(bitmask, node->os_index))
hwloc_bitmap_set(nodeset, node->os_index);
} else {
/* if no numa, libnuma assumes we have a single node */
if (numa_bitmask_isbitset(bitmask, 0))
hwloc_bitmap_fill(nodeset);
else
hwloc_bitmap_zero(nodeset);
}
return 0;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_LINUX_NUMA_H */

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

@ -0,0 +1,64 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2010 inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Linux.
*
* Applications that use hwloc on Linux may want to include this file
* if using some low-level Linux features.
*/
#ifndef HWLOC_LINUX_H
#define HWLOC_LINUX_H
#include <hwloc.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_linux Linux-only helpers
*
* This includes helpers for manipulating linux kernel cpumap files, and hwloc
* equivalents of the Linux sched_setaffinity and sched_getaffinity system calls.
*
* @{
*/
/** \brief Convert a linux kernel cpumap file \p file into hwloc CPU set.
*
* Might be used when reading CPU set from sysfs attributes such as topology
* and caches for processors, or local_cpus for devices.
*/
HWLOC_DECLSPEC int hwloc_linux_parse_cpumap_file(FILE *file, hwloc_cpuset_t set);
/** \brief Bind a thread \p tid on cpus given in cpuset \p set
*
* The behavior is exactly the same as the Linux sched_setaffinity system call,
* but uses a hwloc cpuset.
*/
HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_const_cpuset_t set);
/** \brief Get the current binding of thread \p tid
*
* The behavior is exactly the same as the Linux sched_getaffinity system call,
* but uses a hwloc cpuset.
*/
HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_cpuset_t set);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_GLIBC_SCHED_H */

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

@ -0,0 +1,123 @@
/*
* Copyright © 2010-2013 Inria. All rights reserved.
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Myrinet Express.
*
* Applications that use both hwloc and Myrinet Express verbs may want to
* include this file so as to get topology information for Myrinet hardware.
*
*/
#ifndef HWLOC_MYRIEXPRESS_H
#define HWLOC_MYRIEXPRESS_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#include <myriexpress.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_myriexpress Myrinet Express-Specific Functions
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close the MX board \p id.
*
* Return the CPU set describing the locality of the Myrinet Express
* board whose index is \p id.
*
* Topology \p topology and device \p id must match the local machine.
* I/O devices detection is not needed in the topology.
*
* The function only returns the locality of the device.
* No additional information about the device is available.
*/
static __hwloc_inline int
hwloc_mx_board_get_device_cpuset(hwloc_topology_t topology,
unsigned id, hwloc_cpuset_t set)
{
uint32_t in, out;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
in = id;
if (mx_get_info(NULL, MX_NUMA_NODE, &in, sizeof(in), &out, sizeof(out)) != MX_SUCCESS) {
errno = EINVAL;
return -1;
}
if (out != (uint32_t) -1) {
hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, obj)) != NULL)
if (obj->os_index == out) {
hwloc_bitmap_copy(set, obj->cpuset);
goto out;
}
}
/* fallback to the full topology cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
out:
return 0;
}
/** \brief Get the CPU set of logical processors that are physically
* close the MX endpoint \p endpoint.
*
* Return the CPU set describing the locality of the Myrinet Express
* board that runs the MX endpoint \p endpoint.
*
* Topology \p topology and device \p id must match the local machine.
* I/O devices detection is not needed in the topology.
*
* The function only returns the locality of the endpoint.
* No additional information about the endpoint or device is available.
*/
static __hwloc_inline int
hwloc_mx_endpoint_get_device_cpuset(hwloc_topology_t topology,
mx_endpoint_t endpoint, hwloc_cpuset_t set)
{
uint64_t nid;
uint32_t nindex, eid;
mx_endpoint_addr_t eaddr;
if (mx_get_endpoint_addr(endpoint, &eaddr) != MX_SUCCESS) {
errno = EINVAL;
return -1;
}
if (mx_decompose_endpoint_addr(eaddr, &nid, &eid) != MX_SUCCESS) {
errno = EINVAL;
return -1;
}
if (mx_nic_id_to_board_number(nid, &nindex) != MX_SUCCESS) {
errno = EINVAL;
return -1;
}
return hwloc_mx_board_get_device_cpuset(topology, nindex, set);
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_MYRIEXPRESS_H */

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

@ -0,0 +1,172 @@
/*
* Copyright © 2012-2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the NVIDIA Management Library.
*
* Applications that use both hwloc and the NVIDIA Management Library may want to
* include this file so as to get topology information for NVML devices.
*/
#ifndef HWLOC_NVML_H
#define HWLOC_NVML_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#include <hwloc/helper.h>
#ifdef HWLOC_LINUX_SYS
#include <hwloc/linux.h>
#endif
#include <nvml.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_nvml NVIDIA Management Library Specific Functions
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to NVML device \p device.
*
* Return the CPU set describing the locality of the NVML device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the NVML component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_nvml_get_device_osdev()
* and hwloc_nvml_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
nvmlDevice_t device, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
nvmlReturn_t nvres;
nvmlPciInfo_t pci;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;
hwloc_linux_parse_cpumap_file(sysfile, set);
if (hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* NVML device whose index is \p idx.
*
* Return the OS device object describing the NVML device whose
* index is \p idx. Returns NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the NVML component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("nvml", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to NVML device \p device.
*
* Return the hwloc OS device object that describes the given
* NVML device \p device. Return NULL if there is none.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the NVML component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_nvml_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer.
*/
static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
{
hwloc_obj_t osdev;
nvmlReturn_t nvres;
nvmlPciInfo_t pci;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres)
return NULL;
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "nvml", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.domain
&& pcidev->attr->pcidev.bus == pci.bus
&& pcidev->attr->pcidev.dev == pci.device
&& pcidev->attr->pcidev.func == 0)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_NVML_H */

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

@ -0,0 +1,195 @@
/*
* Copyright © 2012-2013 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux 1. All right reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the OpenCL interface.
*
* Applications that use both hwloc and OpenCL may want to
* include this file so as to get topology information for OpenCL devices.
*
* Only the AMD OpenCL interface currently offers useful locality information
* about its devices.
*/
#ifndef HWLOC_OPENCL_H
#define HWLOC_OPENCL_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#include <hwloc/helper.h>
#ifdef HWLOC_LINUX_SYS
#include <hwloc/linux.h>
#endif
#include <CL/cl.h>
#include <CL/cl_ext.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_opencl OpenCL Specific Functions
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to OpenCL device \p device.
*
* Return the CPU set describing the locality of the OpenCL device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the OpenCL component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_opencl_get_device_osdev()
* and hwloc_opencl_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux with the AMD OpenCL implementation; other systems will simply
* get a full cpuset.
*/
static __hwloc_inline int
hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused,
hwloc_cpuset_t set)
{
#if (defined HWLOC_LINUX_SYS) && (defined CL_DEVICE_TOPOLOGY_AMD)
/* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */
#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
cl_device_topology_amd amdtopo;
cl_int clret;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus", amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;
hwloc_linux_parse_cpumap_file(sysfile, set);
if (hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
fclose(sysfile);
#else
/* Non-Linux + AMD OpenCL systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* OpenCL device for the given indexes.
*
* Return the OS device object describing the OpenCL device
* whose platform index is \p platform_index,
* and whose device index within this platform if \p device_index.
* Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the OpenCL component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned platform_index, unsigned device_index)
{
unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
&& platform_index == x && device_index == y)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to OpenCL device \p device.
*
* Return the hwloc OS device object that describes the given
* OpenCL device \p device. Return NULL if there is none.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the OpenCL component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_opencl_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer.
*/
static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused)
{
#ifdef CL_DEVICE_TOPOLOGY_AMD
hwloc_obj_t osdev;
cl_device_topology_amd amdtopo;
cl_int clret;
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
errno = EINVAL;
return NULL;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
errno = EINVAL;
return NULL;
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "opencl", 6))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == 0
&& pcidev->attr->pcidev.bus == amdtopo.pcie.bus
&& pcidev->attr->pcidev.dev == amdtopo.pcie.device
&& pcidev->attr->pcidev.func == amdtopo.pcie.function)
return osdev;
}
return NULL;
#else
return NULL;
#endif
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_OPENCL_H */

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

@ -0,0 +1,151 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and OpenFabrics
* verbs.
*
* Applications that use both hwloc and OpenFabrics verbs may want to
* include this file so as to get topology information for OpenFabrics
* hardware.
*
*/
#ifndef HWLOC_OPENFABRICS_VERBS_H
#define HWLOC_OPENFABRICS_VERBS_H
#include <hwloc.h>
#include <hwloc/autogen/config.h>
#ifdef HWLOC_LINUX_SYS
#include <hwloc/linux.h>
#endif
#include <infiniband/verbs.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_openfabrics OpenFabrics-Specific Functions
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to device \p ibdev.
*
* Return the CPU set describing the locality of the OpenFabrics
* device \p ibdev.
*
* Topology \p topology and device \p ibdev must match the local machine.
* I/O devices detection is not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_ibv_get_device_osdev()
* and hwloc_ibv_get_device_osdev_by_name().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
struct ibv_device *ibdev, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the verbs-provided sysfs mechanism to
get the local cpus */
#define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128
char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/class/infiniband/%s/device/local_cpus",
ibv_get_device_name(ibdev));
sysfile = fopen(path, "r");
if (!sysfile)
return -1;
hwloc_linux_parse_cpumap_file(sysfile, set);
if (hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics
* device named \p ibname.
*
* Return the OS device object describing the OpenFabrics device whose
* name is \p ibname. Returns NULL if there is none.
* The name \p ibname is usually obtained from ibv_get_device_name().
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,
const char *ibname)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type
&& osdev->name && !strcmp(ibname, osdev->name))
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics
* device \p ibdev.
*
* Return the OS device object describing the OpenFabrics device \p ibdev.
* Returns NULL if there is none.
*
* Topology \p topology and device \p ibdev must match the local machine.
* I/O devices detection must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_ibv_get_device_cpuset().
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_ibv_get_device_osdev(hwloc_topology_t topology,
struct ibv_device *ibdev)
{
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
return hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev));
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_OPENFABRICS_VERBS_H */

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

@ -0,0 +1,302 @@
/*
* Copyright © 2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifndef HWLOC_PLUGINS_H
#define HWLOC_PLUGINS_H
/** \file
* \brief Public interface for building hwloc plugins.
*/
struct hwloc_backend;
#include <hwloc.h>
/** \defgroup hwlocality_disc_components Discovery components
* @{
*/
/** \brief Discovery component type */
typedef enum hwloc_disc_component_type_e {
/** \brief CPU-only discovery through the OS, or generic no-OS support.
* \hideinitializer */
HWLOC_DISC_COMPONENT_TYPE_CPU = (1<<0),
/** \brief xml, synthetic or custom,
* platform-specific components such as bgq.
* Anything the discovers CPU and everything else.
* No misc backend is expected to complement a global component.
* \hideinitializer */
HWLOC_DISC_COMPONENT_TYPE_GLOBAL = (1<<1),
/** \brief PCI, etc.
* \hideinitializer */
HWLOC_DISC_COMPONENT_TYPE_MISC = (1<<2)
} hwloc_disc_component_type_t;
/** \brief Discovery component structure
*
* This is the major kind of components, taking care of the discovery.
* They are registered by generic components, either statically-built or as plugins.
*/
struct hwloc_disc_component {
/** \brief Discovery component type */
hwloc_disc_component_type_t type;
/** \brief Name.
* If this component is built as a plugin, this name does not have to match the plugin filename.
*/
const char *name;
/** \brief Component types to exclude, as an OR'ed set of HWLOC_DISC_COMPONENT_TYPE_*.
*
* For a GLOBAL component, this usually includes all other types (~0).
*
* Other components only exclude types that may bring conflicting
* topology information. MISC components should likely not be excluded
* since they usually bring non-primary additional information.
*/
unsigned excludes;
/** \brief Instantiate callback to create a backend from the component.
* Parameters data1, data2, data3 are NULL except for components
* that have special enabling routines such as hwloc_topology_set_xml(). */
struct hwloc_backend * (*instantiate)(struct hwloc_disc_component *component, const void *data1, const void *data2, const void *data3);
/** \brief Component priority.
* Used to sort topology->components, higher priority first.
* Also used to decide between two components with the same name.
*
* Usual values are
* 50 for native OS (or platform) components,
* 45 for x86,
* 40 for no-OS fallback,
* 30 for global components (xml/synthetic/custom),
* 20 for pci,
* 10 for other misc components (opencl etc.).
*/
unsigned priority;
/** \private Used internally to list components by priority on topology->components
* (the component structure is usually read-only,
* the core copies it before using this field for queueing)
*/
struct hwloc_disc_component * next;
};
/** @} */
/** \defgroup hwlocality_disc_backends Discovery backends
* @{
*/
/** \brief Discovery backend structure
*
* A backend is the instantiation of a discovery component.
* When a component gets enabled for a topology,
* its instantiate() callback creates a backend.
*
* hwloc_backend_alloc() initializes all fields to default values
* that the component may change (except "component" and "next")
* before enabling the backend with hwloc_backend_enable().
*/
struct hwloc_backend {
/** \private Reserved for the core, set by hwloc_backend_alloc() */
struct hwloc_disc_component * component;
/** \private Reserved for the core, set by hwloc_backend_enable() */
struct hwloc_topology * topology;
/** \private Reserved for the core. Set to 1 if forced through envvar, 0 otherwise. */
int envvar_forced;
/** \private Reserved for the core. Used internally to list backends topology->backends. */
struct hwloc_backend * next;
/** \brief Backend flags, as an OR'ed set of HWLOC_BACKEND_FLAG_* */
unsigned long flags;
/** \brief Backend-specific 'is_custom' property.
* Shortcut on !strcmp(..->component->name, "custom").
* Only the custom component should touch this. */
int is_custom;
/** \brief Backend-specific 'is_thissystem' property.
* Set to 0 or 1 if the backend should enforce the thissystem flag when it gets enabled.
* Set to -1 if the backend doesn't care (default). */
int is_thissystem;
/** \brief Backend private data, or NULL if none. */
void * private_data;
/** \brief Callback for freeing the private_data.
* May be NULL.
*/
void (*disable)(struct hwloc_backend *backend);
/** \brief Main discovery callback.
* returns > 0 if it modified the topology tree, -1 on error, 0 otherwise.
* May be NULL if type is HWLOC_DISC_COMPONENT_TYPE_MISC. */
int (*discover)(struct hwloc_backend *backend);
/** \brief Callback used by the PCI backend to retrieve the locality of a PCI object from the OS/cpu backend.
* May be NULL. */
int (*get_obj_cpuset)(struct hwloc_backend *backend, struct hwloc_backend *caller, struct hwloc_obj *obj, hwloc_bitmap_t cpuset);
/** \brief Callback called by backends to notify this backend that a new object was added.
* returns > 0 if it modified the topology tree, 0 otherwise.
* May be NULL. */
int (*notify_new_object)(struct hwloc_backend *backend, struct hwloc_backend *caller, struct hwloc_obj *obj);
};
/** \brief Backend flags */
enum hwloc_backend_flag_e {
/** \brief Levels should be reconnected before this backend discover() is used.
* \hideinitializer */
HWLOC_BACKEND_FLAG_NEED_LEVELS = (1UL<<0)
};
/** \brief Allocate a backend structure, set good default values, initialize backend->component and topology, etc.
* The caller will then modify whatever needed, and call hwloc_backend_enable().
*/
HWLOC_DECLSPEC struct hwloc_backend * hwloc_backend_alloc(struct hwloc_disc_component *component);
/** \brief Enable a previously allocated and setup backend. */
HWLOC_DECLSPEC int hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *backend);
/** \brief Used by backends discovery callbacks to request locality information from others.
*
* Traverse the list of enabled backends until one has a
* get_obj_cpuset() method, and call it.
*/
HWLOC_DECLSPEC int hwloc_backends_get_obj_cpuset(struct hwloc_backend *caller, struct hwloc_obj *obj, hwloc_bitmap_t cpuset);
/** \brief Used by backends discovery callbacks to notify other
* backends of new objects.
*
* Traverse the list of enabled backends (all but caller) and invoke
* their notify_new_object() method to notify them that a new object
* just got added to the topology.
*
* Currently only used for notifying of new PCI device objects.
*/
HWLOC_DECLSPEC int hwloc_backends_notify_new_object(struct hwloc_backend *caller, struct hwloc_obj *obj);
/** @} */
/** \defgroup hwlocality_generic_components Generic components
* @{
*/
/** \brief Generic component type */
typedef enum hwloc_component_type_e {
/** \brief The data field must point to a struct hwloc_disc_component. */
HWLOC_COMPONENT_TYPE_DISC,
/** \brief The data field must point to a struct hwloc_xml_component. */
HWLOC_COMPONENT_TYPE_XML
} hwloc_component_type_t;
/** \brief Generic component structure
*
* Generic components structure, either statically listed by configure in static-components.h
* or dynamically loaded as a plugin.
*/
struct hwloc_component {
/** \brief Component ABI version, set to HWLOC_COMPONENT_ABI */
unsigned abi;
/** \brief Component type */
hwloc_component_type_t type;
/** \brief Component flags, unused for now */
unsigned long flags;
/** \brief Component data, pointing to a struct hwloc_disc_component or struct hwloc_xml_component. */
void * data;
};
/** @} */
/** \defgroup hwlocality_components_core_funcs Core functions to be used by components
* @{
*/
/** \brief Add an object to the topology.
*
* It is sorted along the tree of other objects according to the inclusion of
* cpusets, to eventually be added as a child of the smallest object including
* this object.
*
* If the cpuset is empty, the type of the object (and maybe some attributes)
* must be enough to find where to insert the object. This is especially true
* for NUMA nodes with memory and no CPUs.
*
* The given object should not have children.
*
* This shall only be called before levels are built.
*
* In case of error, hwloc_report_os_error() is called.
*
* Returns the object on success.
* Returns NULL and frees obj on error.
* Returns another object and frees obj if it was merged with an identical pre-existing object.
*/
HWLOC_DECLSPEC struct hwloc_obj *hwloc_insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj);
/** \brief Type of error callbacks during object insertion */
typedef void (*hwloc_report_error_t)(const char * msg, int line);
/** \brief Report an insertion error from a backend */
HWLOC_DECLSPEC void hwloc_report_os_error(const char * msg, int line);
/** \brief Check whether insertion errors are hidden */
HWLOC_DECLSPEC int hwloc_hide_errors(void);
/** \brief Add an object to the topology and specify which error callback to use.
*
* Aside from the error callback selection, this function is identical to hwloc_insert_object_by_cpuset()
*/
HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj, hwloc_report_error_t report_error);
/** \brief Insert an object somewhere in the topology.
*
* It is added as the last child of the given parent.
* The cpuset is completely ignored, so strange objects such as I/O devices should
* preferably be inserted with this.
*
* The given object may have children.
*
* Remember to call topology_connect() afterwards to fix handy pointers.
*/
HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);
/** \brief Allocate and initialize an object of the given type and physical index */
static __hwloc_inline struct hwloc_obj *
hwloc_alloc_setup_object(hwloc_obj_type_t type, signed os_index)
{
struct hwloc_obj *obj = malloc(sizeof(*obj));
memset(obj, 0, sizeof(*obj));
obj->type = type;
obj->os_index = os_index;
obj->os_level = -1;
obj->attr = malloc(sizeof(*obj->attr));
memset(obj->attr, 0, sizeof(*obj->attr));
/* do not allocate the cpuset here, let the caller do it */
return obj;
}
/** @} */
#endif /* HWLOC_PLUGINS_H */

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

@ -0,0 +1,580 @@
/*
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2010-2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifndef HWLOC_RENAME_H
#define HWLOC_RENAME_H
#include <hwloc/autogen/config.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Only enact these defines if we're actually renaming the symbols
(i.e., avoid trying to have no-op defines if we're *not*
renaming). */
#if HWLOC_SYM_TRANSFORM
/* Use a preprocessor two-step in order to get the prefixing right.
Make 2 macros: HWLOC_NAME and HWLOC_NAME_CAPS for renaming
things. */
#define HWLOC_MUNGE_NAME(a, b) HWLOC_MUNGE_NAME2(a, b)
#define HWLOC_MUNGE_NAME2(a, b) a ## b
#define HWLOC_NAME(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX, hwloc_ ## name)
#define HWLOC_NAME_CAPS(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX_CAPS, hwloc_ ## name)
/* Now define all the "real" names to be the prefixed names. This
allows us to use the real names throughout the code base (i.e.,
"hwloc_<foo>"); the preprocessor will adjust to have the prefixed
name under the covers. */
/* Names from hwloc.h */
#define hwloc_get_api_version HWLOC_NAME(get_api_version)
#define hwloc_topology HWLOC_NAME(topology)
#define hwloc_topology_t HWLOC_NAME(topology_t)
#define hwloc_cpuset_t HWLOC_NAME(cpuset_t)
#define hwloc_const_cpuset_t HWLOC_NAME(const_cpuset_t)
#define hwloc_nodeset_t HWLOC_NAME(nodeset_t)
#define hwloc_const_nodeset_t HWLOC_NAME(const_nodeset_t)
#define HWLOC_OBJ_SYSTEM HWLOC_NAME_CAPS(OBJ_SYSTEM)
#define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE)
#define HWLOC_OBJ_NODE HWLOC_NAME_CAPS(OBJ_NODE)
#define HWLOC_OBJ_SOCKET HWLOC_NAME_CAPS(OBJ_SOCKET)
#define HWLOC_OBJ_CACHE HWLOC_NAME_CAPS(OBJ_CACHE)
#define HWLOC_OBJ_CORE HWLOC_NAME_CAPS(OBJ_CORE)
#define HWLOC_OBJ_PU HWLOC_NAME_CAPS(OBJ_PU)
#define HWLOC_OBJ_MISC HWLOC_NAME_CAPS(OBJ_MISC)
#define HWLOC_OBJ_GROUP HWLOC_NAME_CAPS(OBJ_GROUP)
#define HWLOC_OBJ_BRIDGE HWLOC_NAME_CAPS(OBJ_BRIDGE)
#define HWLOC_OBJ_PCI_DEVICE HWLOC_NAME_CAPS(OBJ_PCI_DEVICE)
#define HWLOC_OBJ_OS_DEVICE HWLOC_NAME_CAPS(OBJ_OS_DEVICE)
#define HWLOC_OBJ_TYPE_MAX HWLOC_NAME_CAPS(OBJ_TYPE_MAX)
#define hwloc_obj_type_t HWLOC_NAME(obj_type_t)
#define hwloc_obj_cache_type_e HWLOC_NAME(obj_cache_type_e)
#define hwloc_obj_cache_type_t HWLOC_NAME(obj_cache_type_t)
#define HWLOC_OBJ_CACHE_UNIFIED HWLOC_NAME_CAPS(OBJ_CACHE_UNIFIED)
#define HWLOC_OBJ_CACHE_DATA HWLOC_NAME_CAPS(OBJ_CACHE_DATA)
#define HWLOC_OBJ_CACHE_INSTRUCTION HWLOC_NAME_CAPS(OBJ_CACHE_INSTRUCTION)
#define hwloc_obj_bridge_type_e HWLOC_NAME(obj_bridge_type_e)
#define hwloc_obj_bridge_type_t HWLOC_NAME(obj_bridge_type_t)
#define HWLOC_OBJ_BRIDGE_HOST HWLOC_NAME_CAPS(OBJ_BRIDGE_HOST)
#define HWLOC_OBJ_BRIDGE_PCI HWLOC_NAME_CAPS(OBJ_BRIDGE_PCI)
#define hwloc_obj_osdev_type_e HWLOC_NAME(obj_osdev_type_e)
#define hwloc_obj_osdev_type_t HWLOC_NAME(obj_osdev_type_t)
#define HWLOC_OBJ_OSDEV_BLOCK HWLOC_NAME_CAPS(OBJ_OSDEV_BLOCK)
#define HWLOC_OBJ_OSDEV_GPU HWLOC_NAME_CAPS(OBJ_OSDEV_GPU)
#define HWLOC_OBJ_OSDEV_NETWORK HWLOC_NAME_CAPS(OBJ_OSDEV_NETWORK)
#define HWLOC_OBJ_OSDEV_OPENFABRICS HWLOC_NAME_CAPS(OBJ_OSDEV_OPENFABRICS)
#define HWLOC_OBJ_OSDEV_DMA HWLOC_NAME_CAPS(OBJ_OSDEV_DMA)
#define HWLOC_OBJ_OSDEV_COPROC HWLOC_NAME_CAPS(OBJ_OSDEV_COPROC)
#define hwloc_compare_types HWLOC_NAME(compare_types)
#define hwloc_compare_types_e HWLOC_NAME(compare_types_e)
#define HWLOC_TYPE_UNORDERED HWLOC_NAME_CAPS(TYPE_UNORDERED)
#define hwloc_obj_memory_s HWLOC_NAME(obj_memory_s)
#define hwloc_obj_memory_page_type_s HWLOC_NAME(obj_memory_page_type_s)
#define hwloc_obj HWLOC_NAME(obj)
#define hwloc_obj_t HWLOC_NAME(obj_t)
#define hwloc_distances_s HWLOC_NAME(distances_s)
#define hwloc_obj_info_s HWLOC_NAME(obj_info_s)
#define hwloc_obj_attr_u HWLOC_NAME(obj_attr_u)
#define hwloc_cache_attr_s HWLOC_NAME(cache_attr_s)
#define hwloc_group_attr_s HWLOC_NAME(group_attr_s)
#define hwloc_pcidev_attr_s HWLOC_NAME(pcidev_attr_s)
#define hwloc_bridge_attr_s HWLOC_NAME(bridge_attr_s)
#define hwloc_osdev_attr_s HWLOC_NAME(osdev_attr_s)
#define hwloc_topology_init HWLOC_NAME(topology_init)
#define hwloc_topology_load HWLOC_NAME(topology_load)
#define hwloc_topology_destroy HWLOC_NAME(topology_destroy)
#define hwloc_topology_check HWLOC_NAME(topology_check)
#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_all_keep_structure HWLOC_NAME(topology_ignore_all_keep_structure)
#define hwloc_topology_flags_e HWLOC_NAME(topology_flags_e)
#define HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM HWLOC_NAME_CAPS(TOPOLOGY_FLAG_WHOLE_SYSTEM)
#define HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IS_THISSYSTEM)
#define HWLOC_TOPOLOGY_FLAG_IO_DEVICES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IO_DEVICES)
#define HWLOC_TOPOLOGY_FLAG_IO_BRIDGES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IO_BRIDGES)
#define HWLOC_TOPOLOGY_FLAG_WHOLE_IO HWLOC_NAME_CAPS(TOPOLOGY_FLAG_WHOLE_IO)
#define HWLOC_TOPOLOGY_FLAG_ICACHES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_ICACHES)
#define hwloc_topology_set_flags HWLOC_NAME(topology_set_flags)
#define hwloc_topology_set_fsroot HWLOC_NAME(topology_set_fsroot)
#define hwloc_topology_set_pid HWLOC_NAME(topology_set_pid)
#define hwloc_topology_set_synthetic HWLOC_NAME(topology_set_synthetic)
#define hwloc_topology_set_xml HWLOC_NAME(topology_set_xml)
#define hwloc_topology_set_xmlbuffer HWLOC_NAME(topology_set_xmlbuffer)
#define hwloc_topology_set_custom HWLOC_NAME(topology_set_custom)
#define hwloc_topology_set_distance_matrix HWLOC_NAME(topology_set_distance_matrix)
#define hwloc_topology_discovery_support HWLOC_NAME(topology_discovery_support)
#define hwloc_topology_cpubind_support HWLOC_NAME(topology_cpubind_support)
#define hwloc_topology_membind_support HWLOC_NAME(topology_membind_support)
#define hwloc_topology_support HWLOC_NAME(topology_support)
#define hwloc_topology_get_support HWLOC_NAME(topology_get_support)
#define hwloc_topology_export_xml HWLOC_NAME(topology_export_xml)
#define hwloc_topology_export_xmlbuffer HWLOC_NAME(topology_export_xmlbuffer)
#define hwloc_free_xmlbuffer HWLOC_NAME(free_xmlbuffer)
#define hwloc_topology_set_userdata_export_callback HWLOC_NAME(topology_set_userdata_export_callback)
#define hwloc_export_obj_userdata HWLOC_NAME(export_obj_userdata)
#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_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_custom_insert_topology HWLOC_NAME(custom_insert_topology)
#define hwloc_custom_insert_group_object_by_parent HWLOC_NAME(custom_insert_group_object_by_parent)
#define hwloc_restrict_flags_e HWLOC_NAME(restrict_flags_e)
#define HWLOC_RESTRICT_FLAG_ADAPT_DISTANCES HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_DISTANCES)
#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_topology_restrict HWLOC_NAME(topology_restrict)
#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_e HWLOC_NAME(get_type_depth_e)
#define HWLOC_TYPE_DEPTH_UNKNOWN HWLOC_NAME_CAPS(TYPE_DEPTH_UNKNOWN)
#define HWLOC_TYPE_DEPTH_MULTIPLE HWLOC_NAME_CAPS(TYPE_DEPTH_MULTIPLE)
#define HWLOC_TYPE_DEPTH_BRIDGE HWLOC_NAME_CAPS(TYPE_DEPTH_BRIDGE)
#define HWLOC_TYPE_DEPTH_PCI_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_PCI_DEVICE)
#define HWLOC_TYPE_DEPTH_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE)
#define hwloc_get_depth_type HWLOC_NAME(get_depth_type)
#define hwloc_get_nbobjs_by_depth HWLOC_NAME(get_nbobjs_by_depth)
#define hwloc_get_nbobjs_by_type HWLOC_NAME(get_nbobjs_by_type)
#define hwloc_topology_is_thissystem HWLOC_NAME(topology_is_thissystem)
#define hwloc_topology_get_flags HWLOC_NAME(topology_get_flags)
#define hwloc_get_obj_by_depth HWLOC_NAME(get_obj_by_depth )
#define hwloc_get_obj_by_type HWLOC_NAME(get_obj_by_type )
#define hwloc_obj_type_string HWLOC_NAME(obj_type_string )
#define hwloc_obj_type_of_string HWLOC_NAME(obj_type_of_string )
#define hwloc_obj_type_snprintf HWLOC_NAME(obj_type_snprintf )
#define hwloc_obj_attr_snprintf HWLOC_NAME(obj_attr_snprintf )
#define hwloc_obj_snprintf HWLOC_NAME(obj_snprintf)
#define hwloc_obj_cpuset_snprintf HWLOC_NAME(obj_cpuset_snprintf)
#define hwloc_obj_get_info_by_name HWLOC_NAME(obj_get_info_by_name)
#define hwloc_obj_add_info HWLOC_NAME(obj_add_info)
#define HWLOC_CPUBIND_PROCESS HWLOC_NAME_CAPS(CPUBIND_PROCESS)
#define HWLOC_CPUBIND_THREAD HWLOC_NAME_CAPS(CPUBIND_THREAD)
#define HWLOC_CPUBIND_STRICT HWLOC_NAME_CAPS(CPUBIND_STRICT)
#define HWLOC_CPUBIND_NOMEMBIND HWLOC_NAME_CAPS(CPUBIND_NOMEMBIND)
#define hwloc_cpubind_flags_t HWLOC_NAME(cpubind_flags_t)
#define hwloc_set_cpubind HWLOC_NAME(set_cpubind)
#define hwloc_get_cpubind HWLOC_NAME(get_cpubind)
#define hwloc_set_proc_cpubind HWLOC_NAME(set_proc_cpubind)
#define hwloc_get_proc_cpubind HWLOC_NAME(get_proc_cpubind)
#define hwloc_set_thread_cpubind HWLOC_NAME(set_thread_cpubind)
#define hwloc_get_thread_cpubind HWLOC_NAME(get_thread_cpubind)
#define hwloc_get_last_cpu_location HWLOC_NAME(get_last_cpu_location)
#define hwloc_get_proc_last_cpu_location HWLOC_NAME(get_proc_last_cpu_location)
#define HWLOC_MEMBIND_DEFAULT HWLOC_NAME_CAPS(MEMBIND_DEFAULT)
#define HWLOC_MEMBIND_FIRSTTOUCH HWLOC_NAME_CAPS(MEMBIND_FIRSTTOUCH)
#define HWLOC_MEMBIND_BIND HWLOC_NAME_CAPS(MEMBIND_BIND)
#define HWLOC_MEMBIND_INTERLEAVE HWLOC_NAME_CAPS(MEMBIND_INTERLEAVE)
#define HWLOC_MEMBIND_REPLICATE HWLOC_NAME_CAPS(MEMBIND_REPLICATE)
#define HWLOC_MEMBIND_NEXTTOUCH HWLOC_NAME_CAPS(MEMBIND_NEXTTOUCH)
#define HWLOC_MEMBIND_MIXED HWLOC_NAME_CAPS(MEMBIND_MIXED)
#define hwloc_membind_policy_t HWLOC_NAME(membind_policy_t)
#define HWLOC_MEMBIND_PROCESS HWLOC_NAME_CAPS(MEMBIND_PROCESS)
#define HWLOC_MEMBIND_THREAD HWLOC_NAME_CAPS(MEMBIND_THREAD)
#define HWLOC_MEMBIND_STRICT HWLOC_NAME_CAPS(MEMBIND_STRICT)
#define HWLOC_MEMBIND_MIGRATE HWLOC_NAME_CAPS(MEMBIND_MIGRATE)
#define HWLOC_MEMBIND_NOCPUBIND HWLOC_NAME_CAPS(MEMBIND_NOCPUBIND)
#define hwloc_membind_flags_t HWLOC_NAME(membind_flags_t)
#define hwloc_set_membind_nodeset HWLOC_NAME(set_membind_nodeset)
#define hwloc_set_membind HWLOC_NAME(set_membind)
#define hwloc_get_membind_nodeset HWLOC_NAME(get_membind_nodeset)
#define hwloc_get_membind HWLOC_NAME(get_membind)
#define hwloc_set_proc_membind_nodeset HWLOC_NAME(set_proc_membind_nodeset)
#define hwloc_set_proc_membind HWLOC_NAME(set_proc_membind)
#define hwloc_get_proc_membind_nodeset HWLOC_NAME(get_proc_membind_nodeset)
#define hwloc_get_proc_membind HWLOC_NAME(get_proc_membind)
#define hwloc_set_area_membind_nodeset HWLOC_NAME(set_area_membind_nodeset)
#define hwloc_set_area_membind HWLOC_NAME(set_area_membind)
#define hwloc_get_area_membind_nodeset HWLOC_NAME(get_area_membind_nodeset)
#define hwloc_get_area_membind HWLOC_NAME(get_area_membind)
#define hwloc_alloc_membind_nodeset HWLOC_NAME(alloc_membind_nodeset)
#define hwloc_alloc_membind HWLOC_NAME(alloc_membind)
#define hwloc_alloc HWLOC_NAME(alloc)
#define hwloc_free HWLOC_NAME(free)
#define hwloc_get_non_io_ancestor_obj HWLOC_NAME(get_non_io_ancestor_obj)
#define hwloc_get_next_pcidev HWLOC_NAME(get_next_pcidev)
#define hwloc_get_pcidev_by_busid HWLOC_NAME(get_pcidev_by_busid)
#define hwloc_get_pcidev_by_busidstring HWLOC_NAME(get_pcidev_by_busidstring)
#define hwloc_get_next_osdev HWLOC_NAME(get_next_osdev)
#define hwloc_get_next_bridge HWLOC_NAME(get_next_bridge)
#define hwloc_bridge_covers_pcibus HWLOC_NAME(bridge_covers_pcibus)
#define hwloc_get_hostbridge_by_pcibus HWLOC_NAME(get_hostbridge_by_pcibus)
/* hwloc/bitmap.h */
#define hwloc_bitmap_s HWLOC_NAME(bitmap_s)
#define hwloc_bitmap_t HWLOC_NAME(bitmap_t)
#define hwloc_const_bitmap_t HWLOC_NAME(const_bitmap_t)
#define hwloc_bitmap_alloc HWLOC_NAME(bitmap_alloc)
#define hwloc_bitmap_alloc_full HWLOC_NAME(bitmap_alloc_full)
#define hwloc_bitmap_free HWLOC_NAME(bitmap_free)
#define hwloc_bitmap_dup HWLOC_NAME(bitmap_dup)
#define hwloc_bitmap_copy HWLOC_NAME(bitmap_copy)
#define hwloc_bitmap_snprintf HWLOC_NAME(bitmap_snprintf)
#define hwloc_bitmap_asprintf HWLOC_NAME(bitmap_asprintf)
#define hwloc_bitmap_sscanf HWLOC_NAME(bitmap_sscanf)
#define hwloc_bitmap_list_snprintf HWLOC_NAME(bitmap_list_snprintf)
#define hwloc_bitmap_list_asprintf HWLOC_NAME(bitmap_list_asprintf)
#define hwloc_bitmap_list_sscanf HWLOC_NAME(bitmap_list_sscanf)
#define hwloc_bitmap_taskset_snprintf HWLOC_NAME(bitmap_taskset_snprintf)
#define hwloc_bitmap_taskset_asprintf HWLOC_NAME(bitmap_taskset_asprintf)
#define hwloc_bitmap_taskset_sscanf HWLOC_NAME(bitmap_taskset_sscanf)
#define hwloc_bitmap_zero HWLOC_NAME(bitmap_zero)
#define hwloc_bitmap_fill HWLOC_NAME(bitmap_fill)
#define hwloc_bitmap_from_ulong HWLOC_NAME(bitmap_from_ulong)
#define hwloc_bitmap_from_ith_ulong HWLOC_NAME(bitmap_from_ith_ulong)
#define hwloc_bitmap_to_ulong HWLOC_NAME(bitmap_to_ulong)
#define hwloc_bitmap_to_ith_ulong HWLOC_NAME(bitmap_to_ith_ulong)
#define hwloc_bitmap_only HWLOC_NAME(bitmap_only)
#define hwloc_bitmap_allbut HWLOC_NAME(bitmap_allbut)
#define hwloc_bitmap_set HWLOC_NAME(bitmap_set)
#define hwloc_bitmap_set_range HWLOC_NAME(bitmap_set_range)
#define hwloc_bitmap_set_ith_ulong HWLOC_NAME(bitmap_set_ith_ulong)
#define hwloc_bitmap_clr HWLOC_NAME(bitmap_clr)
#define hwloc_bitmap_clr_range HWLOC_NAME(bitmap_clr_range)
#define hwloc_bitmap_isset HWLOC_NAME(bitmap_isset)
#define hwloc_bitmap_iszero HWLOC_NAME(bitmap_iszero)
#define hwloc_bitmap_isfull HWLOC_NAME(bitmap_isfull)
#define hwloc_bitmap_isequal HWLOC_NAME(bitmap_isequal)
#define hwloc_bitmap_intersects HWLOC_NAME(bitmap_intersects)
#define hwloc_bitmap_isincluded HWLOC_NAME(bitmap_isincluded)
#define hwloc_bitmap_or HWLOC_NAME(bitmap_or)
#define hwloc_bitmap_and HWLOC_NAME(bitmap_and)
#define hwloc_bitmap_andnot HWLOC_NAME(bitmap_andnot)
#define hwloc_bitmap_xor HWLOC_NAME(bitmap_xor)
#define hwloc_bitmap_not HWLOC_NAME(bitmap_not)
#define hwloc_bitmap_first HWLOC_NAME(bitmap_first)
#define hwloc_bitmap_last HWLOC_NAME(bitmap_last)
#define hwloc_bitmap_next HWLOC_NAME(bitmap_next)
#define hwloc_bitmap_singlify HWLOC_NAME(bitmap_singlify)
#define hwloc_bitmap_compare_first HWLOC_NAME(bitmap_compare_first)
#define hwloc_bitmap_compare HWLOC_NAME(bitmap_compare)
#define hwloc_bitmap_weight HWLOC_NAME(bitmap_weight)
/* hwloc/helper.h */
#define hwloc_get_type_or_below_depth HWLOC_NAME(get_type_or_below_depth)
#define hwloc_get_type_or_above_depth HWLOC_NAME(get_type_or_above_depth)
#define hwloc_get_root_obj HWLOC_NAME(get_root_obj)
#define hwloc_get_system_obj HWLOC_NAME(get_system_obj)
#define hwloc_get_ancestor_obj_by_depth HWLOC_NAME(get_ancestor_obj_by_depth)
#define hwloc_get_ancestor_obj_by_type HWLOC_NAME(get_ancestor_obj_by_type)
#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_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index)
#define hwloc_get_next_child HWLOC_NAME(get_next_child)
#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_get_first_largest_obj_inside_cpuset HWLOC_NAME(get_first_largest_obj_inside_cpuset)
#define hwloc_get_largest_objs_inside_cpuset HWLOC_NAME(get_largest_objs_inside_cpuset)
#define hwloc_get_next_obj_inside_cpuset_by_depth HWLOC_NAME(get_next_obj_inside_cpuset_by_depth)
#define hwloc_get_next_obj_inside_cpuset_by_type HWLOC_NAME(get_next_obj_inside_cpuset_by_type)
#define hwloc_get_obj_inside_cpuset_by_depth HWLOC_NAME(get_obj_inside_cpuset_by_depth)
#define hwloc_get_obj_inside_cpuset_by_type HWLOC_NAME(get_obj_inside_cpuset_by_type)
#define hwloc_get_nbobjs_inside_cpuset_by_depth HWLOC_NAME(get_nbobjs_inside_cpuset_by_depth)
#define hwloc_get_nbobjs_inside_cpuset_by_type HWLOC_NAME(get_nbobjs_inside_cpuset_by_type)
#define hwloc_get_obj_index_inside_cpuset HWLOC_NAME(get_obj_index_inside_cpuset)
#define hwloc_get_child_covering_cpuset HWLOC_NAME(get_child_covering_cpuset)
#define hwloc_get_obj_covering_cpuset HWLOC_NAME(get_obj_covering_cpuset)
#define hwloc_get_next_obj_covering_cpuset_by_depth HWLOC_NAME(get_next_obj_covering_cpuset_by_depth)
#define hwloc_get_next_obj_covering_cpuset_by_type HWLOC_NAME(get_next_obj_covering_cpuset_by_type)
#define hwloc_get_cache_type_depth HWLOC_NAME(get_cache_type_depth)
#define hwloc_get_cache_covering_cpuset HWLOC_NAME(get_cache_covering_cpuset)
#define hwloc_get_shared_cache_covering_obj HWLOC_NAME(get_shared_cache_covering_obj)
#define hwloc_get_closest_objs HWLOC_NAME(get_closest_objs)
#define hwloc_get_obj_below_by_type HWLOC_NAME(get_obj_below_by_type)
#define hwloc_get_obj_below_array_by_type HWLOC_NAME(get_obj_below_array_by_type)
#define hwloc_distributev HWLOC_NAME(distributev)
#define hwloc_distribute HWLOC_NAME(distribute)
#define hwloc_alloc_membind_policy HWLOC_NAME(alloc_membind_policy)
#define hwloc_alloc_membind_policy_nodeset HWLOC_NAME(alloc_membind_policy_nodeset)
#define hwloc_topology_get_complete_cpuset HWLOC_NAME(topology_get_complete_cpuset)
#define hwloc_topology_get_topology_cpuset HWLOC_NAME(topology_get_topology_cpuset)
#define hwloc_topology_get_online_cpuset HWLOC_NAME(topology_get_online_cpuset)
#define hwloc_topology_get_allowed_cpuset HWLOC_NAME(topology_get_allowed_cpuset)
#define hwloc_topology_get_complete_nodeset HWLOC_NAME(topology_get_complete_nodeset)
#define hwloc_topology_get_topology_nodeset HWLOC_NAME(topology_get_topology_nodeset)
#define hwloc_topology_get_allowed_nodeset HWLOC_NAME(topology_get_allowed_nodeset)
#define hwloc_cpuset_to_nodeset HWLOC_NAME(cpuset_to_nodeset)
#define hwloc_cpuset_to_nodeset_strict HWLOC_NAME(cpuset_to_nodeset_strict)
#define hwloc_cpuset_from_nodeset HWLOC_NAME(cpuset_from_nodeset)
#define hwloc_cpuset_from_nodeset_strict HWLOC_NAME(cpuset_from_nodeset_strict)
#define hwloc_get_whole_distance_matrix_by_depth HWLOC_NAME(get_whole_distance_matrix_by_depth)
#define hwloc_get_whole_distance_matrix_by_type HWLOC_NAME(get_whole_distance_matrix_by_type)
#define hwloc_get_distance_matrix_covering_obj_by_depth HWLOC_NAME(get_distance_matrix_covering_obj_by_depth)
#define hwloc_get_latency HWLOC_NAME(get_latency)
/* glibc-sched.h */
#define hwloc_cpuset_to_glibc_sched_affinity HWLOC_NAME(cpuset_to_glibc_sched_affinity)
#define hwloc_cpuset_from_glibc_sched_affinity HWLOC_NAME(cpuset_from_glibc_sched_affinity)
/* linux-libnuma.h */
#define hwloc_cpuset_to_linux_libnuma_ulongs HWLOC_NAME(cpuset_to_linux_libnuma_ulongs)
#define hwloc_nodeset_to_linux_libnuma_ulongs HWLOC_NAME(nodeset_to_linux_libnuma_ulongs)
#define hwloc_cpuset_from_linux_libnuma_ulongs HWLOC_NAME(cpuset_from_linux_libnuma_ulongs)
#define hwloc_nodeset_from_linux_libnuma_ulongs HWLOC_NAME(nodeset_from_linux_libnuma_ulongs)
#define hwloc_cpuset_to_linux_libnuma_bitmask HWLOC_NAME(cpuset_to_linux_libnuma_bitmask)
#define hwloc_nodeset_to_linux_libnuma_bitmask HWLOC_NAME(nodeset_to_linux_libnuma_bitmask)
#define hwloc_cpuset_from_linux_libnuma_bitmask HWLOC_NAME(cpuset_from_linux_libnuma_bitmask)
#define hwloc_nodeset_from_linux_libnuma_bitmask HWLOC_NAME(nodeset_from_linux_libnuma_bitmask)
/* linux.h */
#define hwloc_linux_parse_cpumap_file HWLOC_NAME(linux_parse_cpumap_file)
#define hwloc_linux_set_tid_cpubind HWLOC_NAME(linux_set_tid_cpubind)
#define hwloc_linux_get_tid_cpubind HWLOC_NAME(linux_get_tid_cpubind)
/* openfabrics-verbs.h */
#define hwloc_ibv_get_device_cpuset HWLOC_NAME(ibv_get_device_cpuset)
#define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev)
#define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name)
/* myriexpress.h */
#define hwloc_mx_board_get_device_cpuset HWLOC_NAME(mx_board_get_device_cpuset)
#define hwloc_mx_endpoint_get_device_cpuset HWLOC_NAME(mx_endpoint_get_device_cpuset)
/* intel-mic.h */
#define hwloc_intel_mic_get_device_cpuset HWLOC_NAME(intel_mic_get_device_cpuset)
#define hwloc_intel_mic_get_device_osdev_by_index HWLOC_NAME(intel_mic_get_device_osdev_by_index)
/* opencl.h */
#define hwloc_opencl_get_device_cpuset HWLOC_NAME(opencl_get_device_cpuset)
#define hwloc_opencl_get_device_osdev HWLOC_NAME(opencl_get_device_osdev)
#define hwloc_opencl_get_device_osdev_by_index HWLOC_NAME(opencl_get_device_osdev_by_index)
/* cuda.h */
#define hwloc_cuda_get_device_pci_ids HWLOC_NAME(cuda_get_device_pci_ids)
#define hwloc_cuda_get_device_cpuset HWLOC_NAME(cuda_get_device_cpuset)
#define hwloc_cuda_get_device_pcidev HWLOC_NAME(cuda_get_device_pcidev)
#define hwloc_cuda_get_device_osdev HWLOC_NAME(cuda_get_device_osdev)
#define hwloc_cuda_get_device_osdev_by_index HWLOC_NAME(cuda_get_device_osdev_by_index)
/* cudart.h */
#define hwloc_cudart_get_device_pci_ids HWLOC_NAME(cudart_get_device_pci_ids)
#define hwloc_cudart_get_device_cpuset HWLOC_NAME(cudart_get_device_cpuset)
#define hwloc_cudart_get_device_pcidev HWLOC_NAME(cudart_get_device_pcidev)
#define hwloc_cudart_get_device_osdev_by_index HWLOC_NAME(cudart_get_device_osdev_by_index)
/* nvml.h */
#define hwloc_nvml_get_device_cpuset HWLOC_NAME(nvml_get_device_cpuset)
#define hwloc_nvml_get_device_osdev HWLOC_NAME(nvml_get_device_osdev)
#define hwloc_nvml_get_device_osdev_by_index HWLOC_NAME(nvml_get_device_osdev_by_index)
/* gl.h */
#define hwloc_gl_get_display_osdev_by_port_device HWLOC_NAME(gl_get_display_osdev_by_port_device)
#define hwloc_gl_get_display_osdev_by_name HWLOC_NAME(gl_get_display_osdev_by_name)
#define hwloc_gl_get_display_by_osdev HWLOC_NAME(gl_get_display_by_osdev)
/* hwloc/plugins.h */
#define hwloc_disc_component_type_e HWLOC_NAME(disc_component_type_e)
#define HWLOC_DISC_COMPONENT_TYPE_CPU HWLOC_NAME_CAPS(DISC_COMPONENT_TYPE_CPU)
#define HWLOC_DISC_COMPONENT_TYPE_GLOBAL HWLOC_NAME_CAPS(DISC_COMPONENT_TYPE_GLOBAL)
#define HWLOC_DISC_COMPONENT_TYPE_MISC HWLOC_NAME_CAPS(DISC_COMPONENT_TYPE_MISC)
#define hwloc_disc_component_type_t HWLOC_NAME(disc_component_type_t)
#define hwloc_disc_component HWLOC_NAME(disc_component)
#define hwloc_backend HWLOC_NAME(backend)
#define hwloc_backend_flag_e HWLOC_NAME(backend_flag_e)
#define HWLOC_BACKEND_FLAG_NEED_LEVELS HWLOC_NAME_CAPS(BACKEND_FLAG_NEED_LEVELS)
#define hwloc_backend_alloc HWLOC_NAME(backend_alloc)
#define hwloc_backend_enable HWLOC_NAME(backend_enable)
#define hwloc_backends_get_obj_cpuset HWLOC_NAME(backends_get_obj_cpuset)
#define hwloc_backends_notify_new_object HWLOC_NAME(backends_notify_new_object)
#define hwloc_component_type_e HWLOC_NAME(component_type_e)
#define HWLOC_COMPONENT_TYPE_DISC HWLOC_NAME_CAPS(COMPONENT_TYPE_DISC)
#define HWLOC_COMPONENT_TYPE_XML HWLOC_NAME_CAPS(COMPONENT_TYPE_XML)
#define hwloc_component_type_t HWLOC_NAME(component_type_t)
#define hwloc_component HWLOC_NAME(component)
#define hwloc_insert_object_by_cpuset HWLOC_NAME(insert_object_by_cpuset)
#define hwloc_report_error_t HWLOC_NAME(report_error_t)
#define hwloc_report_os_error HWLOC_NAME(report_os_error)
#define hwloc_hide_errors HWLOC_NAME(hide_errors)
#define hwloc__insert_object_by_cpuset HWLOC_NAME(_insert_object_by_cpuset)
#define hwloc_insert_object_by_parent HWLOC_NAME(insert_object_by_parent)
#define hwloc_alloc_setup_object HWLOC_NAME(alloc_setup_object)
/* private/debug.h */
#define hwloc_debug HWLOC_NAME(debug)
/* private/misc.h */
#define hwloc_snprintf HWLOC_NAME(snprintf)
#define hwloc_namecoloncmp HWLOC_NAME(namecoloncmp)
/* FIXME: hwloc_ffsl may be a macro, but it may not be defined yet */
#define hwloc_ffs32 HWLOC_NAME(ffs32)
/* FIXME: hwloc_flsl may be a macro, but it may not be defined yet */
#define hwloc_fls32 HWLOC_NAME(fls32)
#define hwloc_weight_long HWLOC_NAME(weight_long)
/* private/cpuid.h */
#define hwloc_have_cpuid HWLOC_NAME(have_cpuid)
#define hwloc_cpuid HWLOC_NAME(cpuid)
/* private/xml.h */
#define hwloc__xml_verbose HWLOC_NAME(_xml_verbose)
#define hwloc__xml_import_state_s HWLOC_NAME(_xml_import_state_s)
#define hwloc__xml_import_state_t HWLOC_NAME(_xml_import_state_t)
#define hwloc_xml_backend_data_s HWLOC_NAME(xml_backend_data_s)
#define hwloc__xml_export_state_s HWLOC_NAME(_xml_export_state_s)
#define hwloc__xml_export_state_t HWLOC_NAME(_xml_export_state_t)
#define hwloc__xml_export_object HWLOC_NAME(_xml_export_object)
#define hwloc_xml_callbacks HWLOC_NAME(xml_callbacks)
#define hwloc_xml_component HWLOC_NAME(xml_component)
#define hwloc_xml_callbacks_register HWLOC_NAME(xml_callbacks_register)
#define hwloc_xml_callbacks_reset HWLOC_NAME(xml_callbacks_reset)
/* private/components.h */
#define hwloc_disc_component_force_enable HWLOC_NAME(disc_component_force_enable)
#define hwloc_disc_components_enable_others HWLOC_NAME(disc_components_instantiate_others)
#define hwloc_backends_reset HWLOC_NAME(backends_reset)
#define hwloc_backends_disable_all HWLOC_NAME(backends_disable_all)
#define hwloc_backends_is_thissystem HWLOC_NAME(backends_is_thissystem)
#define hwloc_components_init HWLOC_NAME(components_init)
#define hwloc_components_destroy_all HWLOC_NAME(components_destroy_all)
/* private/private.h */
#define hwloc_ignore_type_e HWLOC_NAME(ignore_type_e)
#define HWLOC_IGNORE_TYPE_NEVER HWLOC_NAME_CAPS(IGNORE_TYPE_NEVER)
#define HWLOC_IGNORE_TYPE_KEEP_STRUCTURE HWLOC_NAME_CAPS(IGNORE_TYPE_KEEP_STRUCTURE)
#define HWLOC_IGNORE_TYPE_ALWAYS HWLOC_NAME_CAPS(IGNORE_TYPE_ALWAYS)
#define hwloc_os_distances_s HWLOC_NAME(os_distances_s)
#define hwloc_xml_imported_distances_s HWLOC_NAME(xml_imported_distances_s)
#define hwloc_alloc_obj_cpusets HWLOC_NAME(alloc_obj_cpusets)
#define hwloc_setup_pu_level HWLOC_NAME(setup_pu_level)
#define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname)
#define hwloc_get_sysctl HWLOC_NAME(get_sysctl)
#define hwloc_fallback_nbprocessors HWLOC_NAME(fallback_nbprocessors)
#define hwloc_connect_children HWLOC_NAME(connect_children)
#define hwloc_connect_levels HWLOC_NAME(connect_levels)
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
#define hwloc_topology_clear HWLOC_NAME(topology_clear)
#define hwloc_binding_hooks HWLOC_NAME(binding_hooks)
#define hwloc_set_native_binding_hooks HWLOC_NAME(set_native_binding_hooks)
#define hwloc_set_binding_hooks HWLOC_NAME(set_binding_hooks)
#define hwloc_set_linuxfs_hooks HWLOC_NAME(set_linuxfs_hooks)
#define hwloc_set_bgq_hooks HWLOC_NAME(set_bgq_hooks)
#define hwloc_set_solaris_hooks HWLOC_NAME(set_solaris_hooks)
#define hwloc_set_aix_hooks HWLOC_NAME(set_aix_hooks)
#define hwloc_set_osf_hooks HWLOC_NAME(set_osf_hooks)
#define hwloc_set_windows_hooks HWLOC_NAME(set_windows_hooks)
#define hwloc_set_darwin_hooks HWLOC_NAME(set_darwin_hooks)
#define hwloc_set_freebsd_hooks HWLOC_NAME(set_freebsd_hooks)
#define hwloc_set_netbsd_hooks HWLOC_NAME(set_netbsd_hooks)
#define hwloc_set_hpux_hooks HWLOC_NAME(set_hpux_hooks)
#define hwloc_add_uname_info HWLOC_NAME(add_uname_info)
#define hwloc_free_unlinked_object HWLOC_NAME(free_unlinked_object)
#define hwloc__duplicate_objects HWLOC_NAME(_duplicate_objects)
#define hwloc_alloc_heap HWLOC_NAME(alloc_heap)
#define hwloc_alloc_mmap HWLOC_NAME(alloc_mmap)
#define hwloc_free_heap HWLOC_NAME(free_heap)
#define hwloc_free_mmap HWLOC_NAME(free_mmap)
#define hwloc_alloc_or_fail HWLOC_NAME(alloc_or_fail)
#define hwloc_distances_init HWLOC_NAME(distances_init)
#define hwloc_distances_clear HWLOC_NAME(distances_clear)
#define hwloc_distances_destroy HWLOC_NAME(distances_destroy)
#define hwloc_distances_set HWLOC_NAME(distances_set)
#define hwloc_distances_set_from_env HWLOC_NAME(distances_set_from_env)
#define hwloc_distances_restrict_os HWLOC_NAME(distances_restrict_os)
#define hwloc_distances_restrict HWLOC_NAME(distances_restrict)
#define hwloc_distances_finalize_os HWLOC_NAME(distances_finalize_os)
#define hwloc_distances_finalize_logical HWLOC_NAME(distances_finalize_logical)
#define hwloc_clear_object_distances HWLOC_NAME(clear_object_distances)
#define hwloc_clear_object_distances_one HWLOC_NAME(clear_object_distances_one)
#define hwloc_group_by_distances HWLOC_NAME(group_by_distances)
#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64)
#define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64)
/* private/solaris-chiptype.h */
#define hwloc_solaris_get_chip_type HWLOC_NAME(solaris_get_chip_type)
#define hwloc_solaris_get_chip_model HWLOC_NAME(solaris_get_chip_model)
#endif /* HWLOC_SYM_TRANSFORM */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_RENAME_H */

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

@ -0,0 +1,692 @@
/* include/private/autogen/config.h.in. Generated from configure.ac by autoheader. */
/* -*- c -*-
*
* Copyright © 2009, 2011, 2012 CNRS, inria., Université Bordeaux 1 All rights reserved.
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*
* This file is automatically generated by configure. Edits will be lost
* the next time you run configure!
*/
#ifndef HWLOC_CONFIGURE_H
#define HWLOC_CONFIGURE_H
/* Define to 1 if the system has the type `CACHE_DESCRIPTOR'. */
#undef HAVE_CACHE_DESCRIPTOR
/* Define to 1 if the system has the type `CACHE_RELATIONSHIP'. */
#undef HAVE_CACHE_RELATIONSHIP
/* Define to 1 if you have the `clz' function. */
#undef HAVE_CLZ
/* Define to 1 if you have the `clzl' function. */
#undef HAVE_CLZL
/* Define to 1 if you have the <CL/cl_ext.h> header file. */
#undef HAVE_CL_CL_EXT_H
/* Define to 1 if you have the `cpuset_setaffinity' function. */
#undef HAVE_CPUSET_SETAFFINITY
/* Define to 1 if you have the `cpuset_setid' function. */
#undef HAVE_CPUSET_SETID
/* Define to 1 if we have -lcuda */
#undef HAVE_CUDA
/* Define to 1 if you have the <cuda.h> header file. */
#undef HAVE_CUDA_H
/* Define to 1 if you have the <cuda_runtime_api.h> header file. */
#undef HAVE_CUDA_RUNTIME_API_H
/* Define to 1 if you have the declaration of `CL_DEVICE_TOPOLOGY_AMD', and to
0 if you don't. */
#undef HAVE_DECL_CL_DEVICE_TOPOLOGY_AMD
/* Define to 1 if you have the declaration of `CTL_HW', and to 0 if you don't.
*/
#undef HAVE_DECL_CTL_HW
/* Define to 1 if you have the declaration of `fabsf', and to 0 if you don't.
*/
#undef HAVE_DECL_FABSF
/* Define to 1 if you have the declaration of `HW_NCPU', and to 0 if you
don't. */
#undef HAVE_DECL_HW_NCPU
/* Define to 1 if you have the declaration of
`nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */
#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
0 if you don't. */
#undef HAVE_DECL_PTHREAD_GETAFFINITY_NP
/* Define to 1 if you have the declaration of `pthread_setaffinity_np', and to
0 if you don't. */
#undef HAVE_DECL_PTHREAD_SETAFFINITY_NP
/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
don't. */
#undef HAVE_DECL_STRTOULL
/* Define to 1 if you have the declaration of `_SC_LARGE_PAGESIZE', and to 0
if you don't. */
#undef HAVE_DECL__SC_LARGE_PAGESIZE
/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_CONF', and to 0
if you don't. */
#undef HAVE_DECL__SC_NPROCESSORS_CONF
/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_ONLN', and to 0
if you don't. */
#undef HAVE_DECL__SC_NPROCESSORS_ONLN
/* Define to 1 if you have the declaration of `_SC_NPROC_CONF', and to 0 if
you don't. */
#undef HAVE_DECL__SC_NPROC_CONF
/* Define to 1 if you have the declaration of `_SC_NPROC_ONLN', and to 0 if
you don't. */
#undef HAVE_DECL__SC_NPROC_ONLN
/* Define to 1 if you have the declaration of `_SC_PAGESIZE', and to 0 if you
don't. */
#undef HAVE_DECL__SC_PAGESIZE
/* Define to 1 if you have the declaration of `_SC_PAGE_SIZE', and to 0 if you
don't. */
#undef HAVE_DECL__SC_PAGE_SIZE
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `ffs' function. */
#undef HAVE_FFS
/* Define to 1 if you have the `ffsl' function. */
#undef HAVE_FFSL
/* Define to 1 if you have the `fls' function. */
#undef HAVE_FLS
/* Define to 1 if you have the `flsl' function. */
#undef HAVE_FLSL
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if the system has the type `GROUP_AFFINITY'. */
#undef HAVE_GROUP_AFFINITY
/* Define to 1 if the system has the type `GROUP_RELATIONSHIP'. */
#undef HAVE_GROUP_RELATIONSHIP
/* Define to 1 if you have the `host_info' function. */
#undef HAVE_HOST_INFO
/* Define to 1 if you have the <infiniband/verbs.h> header file. */
#undef HAVE_INFINIBAND_VERBS_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if the system has the type `KAFFINITY'. */
#undef HAVE_KAFFINITY
/* Define to 1 if you have the <kstat.h> header file. */
#undef HAVE_KSTAT_H
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
/* Define to 1 if we have -lgdi32 */
#undef HAVE_LIBGDI32
/* Define to 1 if we have -libverbs */
#undef HAVE_LIBIBVERBS
/* Define to 1 if we have -lkstat */
#undef HAVE_LIBKSTAT
/* Define to 1 if we have -llgrp */
#undef HAVE_LIBLGRP
/* Define to 1 if you have the `pci' library (-lpci). */
#undef HAVE_LIBPCI
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if the system has the type `LOGICAL_PROCESSOR_RELATIONSHIP'. */
#undef HAVE_LOGICAL_PROCESSOR_RELATIONSHIP
/* Define to 1 if you have the <mach/mach_host.h> header file. */
#undef HAVE_MACH_MACH_HOST_H
/* Define to 1 if you have the <mach/mach_init.h> header file. */
#undef HAVE_MACH_MACH_INIT_H
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the `memalign' function. */
#undef HAVE_MEMALIGN
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if we have -lmyriexpress */
#undef HAVE_MYRIEXPRESS
/* Define to 1 if you have the <myriexpress.h> header file. */
#undef HAVE_MYRIEXPRESS_H
/* Define to 1 if you have the `nl_langinfo' function. */
#undef HAVE_NL_LANGINFO
/* Define to 1 if you have the <numaif.h> header file. */
#undef HAVE_NUMAIF_H
/* Define to 1 if the system has the type `NUMA_NODE_RELATIONSHIP'. */
#undef HAVE_NUMA_NODE_RELATIONSHIP
/* Define to 1 if you have the <NVCtrl/NVCtrl.h> header file. */
#undef HAVE_NVCTRL_NVCTRL_H
/* Define to 1 if you have the <nvml.h> header file. */
#undef HAVE_NVML_H
/* Define to 1 if you have the `openat' function. */
#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. */
#undef HAVE_PICL_H
/* Define to 1 if you have the `posix_memalign' function. */
#undef HAVE_POSIX_MEMALIGN
/* Define to 1 if the system has the type `PROCESSOR_CACHE_TYPE'. */
#undef HAVE_PROCESSOR_CACHE_TYPE
/* Define to 1 if the system has the type `PROCESSOR_GROUP_INFO'. */
#undef HAVE_PROCESSOR_GROUP_INFO
/* Define to 1 if the system has the type `PROCESSOR_RELATIONSHIP'. */
#undef HAVE_PROCESSOR_RELATIONSHIP
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_BLOCK'. */
#undef HAVE_PSAPI_WORKING_SET_EX_BLOCK
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_INFORMATION'.
*/
#undef HAVE_PSAPI_WORKING_SET_EX_INFORMATION
/* Define to 1 if you have the <pthread_np.h> header file. */
#undef HAVE_PTHREAD_NP_H
/* Define to 1 if the system has the type `pthread_t'. */
#undef HAVE_PTHREAD_T
/* Define to 1 if you have the `putwc' function. */
#undef HAVE_PUTWC
/* Define to 1 if the system has the type `RelationProcessorPackage'. */
#undef HAVE_RELATIONPROCESSORPACKAGE
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `sysctl' function. */
#undef HAVE_SYSCTL
/* Define to 1 if you have the `sysctlbyname' function. */
#undef HAVE_SYSCTLBYNAME
/* Define to 1 if the system has the type
`SYSTEM_LOGICAL_PROCESSOR_INFORMATION'. */
#undef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION
/* Define to 1 if the system has the type
`SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX'. */
#undef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
/* Define to 1 if you have the <sys/cpuset.h> header file. */
#undef HAVE_SYS_CPUSET_H
/* Define to 1 if you have the <sys/lgrp_user.h> header file. */
#undef HAVE_SYS_LGRP_USER_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
/* Define to 1 if you have the `uname' function. */
#undef HAVE_UNAME
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `uselocale' function. */
#undef HAVE_USELOCALE
/* Define to 1 if the system has the type `wchar_t'. */
#undef HAVE_WCHAR_T
/* Define to 1 if you have the <X11/keysym.h> header file. */
#undef HAVE_X11_KEYSYM_H
/* Define to 1 if you have the <X11/Xlib.h> header file. */
#undef HAVE_X11_XLIB_H
/* Define to 1 if you have the <X11/Xutil.h> header file. */
#undef HAVE_X11_XUTIL_H
/* Define to 1 if you have the <xlocale.h> header file. */
#undef HAVE_XLOCALE_H
/* Define to 1 on AIX */
#undef HWLOC_AIX_SYS
/* Define to 1 on BlueGene/Q */
#undef HWLOC_BGQ_SYS
/* Whether C compiler supports symbol visibility or not */
#undef HWLOC_C_HAVE_VISIBILITY
/* Define to 1 on Darwin */
#undef HWLOC_DARWIN_SYS
/* Whether we are in debugging mode or not */
#undef HWLOC_DEBUG
/* Define to 1 on *FREEBSD */
#undef HWLOC_FREEBSD_SYS
/* Whether your compiler has __attribute__ or not */
#undef HWLOC_HAVE_ATTRIBUTE
/* Whether your compiler has __attribute__ aligned or not */
#undef HWLOC_HAVE_ATTRIBUTE_ALIGNED
/* Whether your compiler has __attribute__ always_inline or not */
#undef HWLOC_HAVE_ATTRIBUTE_ALWAYS_INLINE
/* Whether your compiler has __attribute__ cold or not */
#undef HWLOC_HAVE_ATTRIBUTE_COLD
/* Whether your compiler has __attribute__ const or not */
#undef HWLOC_HAVE_ATTRIBUTE_CONST
/* Whether your compiler has __attribute__ deprecated or not */
#undef HWLOC_HAVE_ATTRIBUTE_DEPRECATED
/* Whether your compiler has __attribute__ format or not */
#undef HWLOC_HAVE_ATTRIBUTE_FORMAT
/* Whether your compiler has __attribute__ hot or not */
#undef HWLOC_HAVE_ATTRIBUTE_HOT
/* Whether your compiler has __attribute__ malloc or not */
#undef HWLOC_HAVE_ATTRIBUTE_MALLOC
/* Whether your compiler has __attribute__ may_alias or not */
#undef HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS
/* Whether your compiler has __attribute__ nonnull or not */
#undef HWLOC_HAVE_ATTRIBUTE_NONNULL
/* Whether your compiler has __attribute__ noreturn or not */
#undef HWLOC_HAVE_ATTRIBUTE_NORETURN
/* Whether your compiler has __attribute__ no_instrument_function or not */
#undef HWLOC_HAVE_ATTRIBUTE_NO_INSTRUMENT_FUNCTION
/* Whether your compiler has __attribute__ packed or not */
#undef HWLOC_HAVE_ATTRIBUTE_PACKED
/* Whether your compiler has __attribute__ pure or not */
#undef HWLOC_HAVE_ATTRIBUTE_PURE
/* Whether your compiler has __attribute__ sentinel or not */
#undef HWLOC_HAVE_ATTRIBUTE_SENTINEL
/* Whether your compiler has __attribute__ unused or not */
#undef HWLOC_HAVE_ATTRIBUTE_UNUSED
/* Whether your compiler has __attribute__ warn unused result or not */
#undef HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT
/* Whether your compiler has __attribute__ weak alias or not */
#undef HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS
/* Define to 1 if your `ffs' function is known to be broken. */
#undef HWLOC_HAVE_BROKEN_FFS
/* Define to 1 if you have the `cairo' library. */
#undef HWLOC_HAVE_CAIRO
/* Define to 1 if you have the `clz' function. */
#undef HWLOC_HAVE_CLZ
/* Define to 1 if you have the `clzl' function. */
#undef HWLOC_HAVE_CLZL
/* Define to 1 if you have cpuid */
#undef HWLOC_HAVE_CPUID
/* Define to 1 if the CPU_SET macro works */
#undef HWLOC_HAVE_CPU_SET
/* Define to 1 if the CPU_SET_S macro works */
#undef HWLOC_HAVE_CPU_SET_S
/* Define to 1 if you have the `cudart' SDK. */
#undef HWLOC_HAVE_CUDART
/* Define to 1 if function `clz' is declared by system headers */
#undef HWLOC_HAVE_DECL_CLZ
/* Define to 1 if function `clzl' is declared by system headers */
#undef HWLOC_HAVE_DECL_CLZL
/* Define to 1 if function `ffs' is declared by system headers */
#undef HWLOC_HAVE_DECL_FFS
/* Define to 1 if function `ffsl' is declared by system headers */
#undef HWLOC_HAVE_DECL_FFSL
/* Define to 1 if function `fls' is declared by system headers */
#undef HWLOC_HAVE_DECL_FLS
/* Define to 1 if function `flsl' is declared by system headers */
#undef HWLOC_HAVE_DECL_FLSL
/* Define to 1 if you have the `ffs' function. */
#undef HWLOC_HAVE_FFS
/* Define to 1 if you have the `ffsl' function. */
#undef HWLOC_HAVE_FFSL
/* Define to 1 if you have the `fls' function. */
#undef HWLOC_HAVE_FLS
/* Define to 1 if you have the `flsl' function. */
#undef HWLOC_HAVE_FLSL
/* Define to 1 if you have the GL module components. */
#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 */
#undef HWLOC_HAVE_LIBTERMCAP
/* Define to 1 if you have the `libxml2' library. */
#undef HWLOC_HAVE_LIBXML2
/* Define to 1 if mbind is available. */
#undef HWLOC_HAVE_MBIND
/* Define to 1 if migrate_pages is available. */
#undef HWLOC_HAVE_MIGRATE_PAGES
/* Define to 1 if you have the `NVML' library. */
#undef HWLOC_HAVE_NVML
/* Define to 1 if glibc provides the old prototype (without length) of
sched_setaffinity() */
#undef HWLOC_HAVE_OLD_SCHED_SETAFFINITY
/* Define to 1 if you have the `OpenCL' library. */
#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
*/
#undef HWLOC_HAVE_PLUGINS
/* `Define to 1 if you have pthread_getthrds_np' */
#undef HWLOC_HAVE_PTHREAD_GETTHRDS_NP
/* Define to 1 if pthread mutexes are available */
#undef HWLOC_HAVE_PTHREAD_MUTEX
/* Define to 1 if glibc provides a prototype of sched_setaffinity() */
#undef HWLOC_HAVE_SCHED_SETAFFINITY
/* Define to 1 if set_mempolicy is available. */
#undef HWLOC_HAVE_SET_MEMPOLICY
/* Define to 1 if you have the <stdint.h> header file. */
#undef HWLOC_HAVE_STDINT_H
/* Define to 1 if you have the `windows.h' header. */
#undef HWLOC_HAVE_WINDOWS_H
/* Define to 1 if X11 libraries are available. */
#undef HWLOC_HAVE_X11
/* Define to 1 if the _syscall3 macro works */
#undef HWLOC_HAVE__SYSCALL3
/* Define to 1 on HP-UX */
#undef HWLOC_HPUX_SYS
/* Define to 1 on Irix */
#undef HWLOC_IRIX_SYS
/* Define to 1 on Linux */
#undef HWLOC_LINUX_SYS
/* Major version of hwloc */
#undef HWLOC_MAJOR_VERSION
/* Minor version of hwloc */
#undef HWLOC_MINOR_VERSION
/* Define to 1 on *NETBSD */
#undef HWLOC_NETBSD_SYS
/* Define to 1 on OSF */
#undef HWLOC_OSF_SYS
/* Release version of hwloc */
#undef HWLOC_RELEASE_VERSION
/* The size of `unsigned int', as computed by sizeof */
#undef HWLOC_SIZEOF_UNSIGNED_INT
/* The size of `unsigned long', as computed by sizeof */
#undef HWLOC_SIZEOF_UNSIGNED_LONG
/* Define to 1 on Solaris */
#undef HWLOC_SOLARIS_SYS
/* The hwloc symbol prefix */
#undef HWLOC_SYM_PREFIX
/* The hwloc symbol prefix in all caps */
#undef HWLOC_SYM_PREFIX_CAPS
/* Whether we need to re-define all the hwloc public symbols or not */
#undef HWLOC_SYM_TRANSFORM
/* Define to 1 on unsupported systems */
#undef HWLOC_UNSUPPORTED_SYS
/* Define to 1 if ncurses works, preferred over curses */
#undef HWLOC_USE_NCURSES
/* Define to 1 on WINDOWS */
#undef HWLOC_WIN_SYS
/* Define to 1 on x86_32 */
#undef HWLOC_X86_32_ARCH
/* Define to 1 on x86_64 */
#undef HWLOC_X86_64_ARCH
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of `unsigned int', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_INT
/* The size of `unsigned long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG
/* The size of `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Enable extensions on HP-UX. */
#ifndef _HPUX_SOURCE
# undef _HPUX_SOURCE
#endif
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Version number of package */
#undef VERSION
/* Define to 1 if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING
/* Are we building for HP-UX? */
#undef _HPUX_SOURCE
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define this to the process ID type */
#undef hwloc_pid_t
/* Define this to either strncasecmp or strncmp */
#undef hwloc_strncasecmp
/* Define this to the thread ID type */
#undef hwloc_thread_t
#endif /* HWLOC_CONFIGURE_H */

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

@ -0,0 +1,42 @@
/*
* Copyright © 2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifdef HWLOC_INSIDE_PLUGIN
/*
* these declarations are internal only, they are not available to plugins
* (many functions below are internal static symbols).
*/
#error This file should not be used in plugins
#endif
#ifndef PRIVATE_COMPONENTS_H
#define PRIVATE_COMPONENTS_H 1
#include <hwloc/plugins.h>
struct hwloc_topology;
extern int hwloc_disc_component_force_enable(struct hwloc_topology *topology,
int envvar_forced, /* 1 if forced through envvar, 0 if forced through API */
int type, const char *name,
const void *data1, const void *data2, const void *data3);
extern void hwloc_disc_components_enable_others(struct hwloc_topology *topology);
/* Compute the topology is_thissystem flag based on enabled backends */
extern void hwloc_backends_is_thissystem(struct hwloc_topology *topology);
/* Reset the list of currently enabled backend */
extern void hwloc_backends_reset(struct hwloc_topology *topology);
/* Disable and destroy all backends used by a topology */
extern void hwloc_backends_disable_all(struct hwloc_topology *topology);
/* Used by the core to setup/destroy the list of components */
extern void hwloc_components_init(struct hwloc_topology *topology); /* increases components refcount, should be called exactly once per topology (during init) */
extern void hwloc_components_destroy_all(struct hwloc_topology *topology); /* decreases components refcount, should be called exactly once per topology (during destroy) */
#endif /* PRIVATE_COMPONENTS_H */

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

@ -0,0 +1,79 @@
/*
* Copyright © 2010-2012 Université Bordeaux 1
* Copyright © 2010 Cisco Systems, Inc. All rights reserved.
*
* See COPYING in top-level directory.
*/
/* Internals for x86's cpuid. */
#ifndef HWLOC_PRIVATE_CPUID_H
#define HWLOC_PRIVATE_CPUID_H
#ifdef HWLOC_X86_32_ARCH
static __hwloc_inline int hwloc_have_cpuid(void)
{
int ret;
unsigned tmp, tmp2;
asm(
"mov $0,%0\n\t" /* Not supported a priori */
"pushfl \n\t" /* Save flags */
"pushfl \n\t" \
"pop %1 \n\t" /* Get flags */ \
#define TRY_TOGGLE \
"xor $0x00200000,%1\n\t" /* Try to toggle ID */ \
"mov %1,%2\n\t" /* Save expected value */ \
"push %1 \n\t" \
"popfl \n\t" /* Try to toggle */ \
"pushfl \n\t" \
"pop %1 \n\t" \
"cmp %1,%2\n\t" /* Compare with expected value */ \
"jnz Lhwloc1\n\t" /* Unexpected, failure */ \
TRY_TOGGLE /* Try to set/clear */
TRY_TOGGLE /* Try to clear/set */
"mov $1,%0\n\t" /* Passed the test! */
"Lhwloc1: \n\t"
"popfl \n\t" /* Restore flags */
: "=r" (ret), "=&r" (tmp), "=&r" (tmp2));
return ret;
}
#endif /* HWLOC_X86_32_ARCH */
#ifdef HWLOC_X86_64_ARCH
static __hwloc_inline int hwloc_have_cpuid(void) { return 1; }
#endif /* HWLOC_X86_64_ARCH */
static __hwloc_inline void hwloc_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
{
/* Note: gcc might want to use bx or the stack for %1 addressing, so we can't
* use them :/ */
#ifdef HWLOC_X86_64_ARCH
unsigned long sav_rbx;
asm(
"mov %%rbx,%2\n\t"
"cpuid\n\t"
"xchg %2,%%rbx\n\t"
"movl %k2,%1\n\t"
: "+a" (*eax), "=m" (*ebx), "=&r"(sav_rbx),
"+c" (*ecx), "=&d" (*edx));
#elif defined(HWLOC_X86_32_ARCH)
unsigned long sav_ebx;
asm(
"mov %%ebx,%2\n\t"
"cpuid\n\t"
"xchg %2,%%ebx\n\t"
"movl %k2,%1\n\t"
: "+a" (*eax), "=m" (*ebx), "=&r"(sav_ebx),
"+c" (*ecx), "=&d" (*edx));
#else
#error unknown architecture
#endif
}
#endif /* HWLOC_PRIVATE_CPUID_H */

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

@ -0,0 +1,57 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009, 2011 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* The configuration file */
#ifndef HWLOC_DEBUG_H
#define HWLOC_DEBUG_H
#include <private/autogen/config.h>
#ifdef HWLOC_DEBUG
#include <stdarg.h>
#include <stdio.h>
#endif
static __hwloc_inline void hwloc_debug(const char *s __hwloc_attribute_unused, ...)
{
#ifdef HWLOC_DEBUG
va_list ap;
va_start(ap, s);
vfprintf(stderr, s, ap);
va_end(ap);
#endif
}
#ifdef HWLOC_DEBUG
#define hwloc_debug_bitmap(fmt, bitmap) do { \
char *s; \
hwloc_bitmap_asprintf(&s, bitmap); \
fprintf(stderr, fmt, s); \
free(s); \
} while (0)
#define hwloc_debug_1arg_bitmap(fmt, arg1, bitmap) do { \
char *s; \
hwloc_bitmap_asprintf(&s, bitmap); \
fprintf(stderr, fmt, arg1, s); \
free(s); \
} while (0)
#define hwloc_debug_2args_bitmap(fmt, arg1, arg2, bitmap) do { \
char *s; \
hwloc_bitmap_asprintf(&s, bitmap); \
fprintf(stderr, fmt, arg1, arg2, s); \
free(s); \
} while (0)
#else
#define hwloc_debug_bitmap(s, bitmap) do { } while(0)
#define hwloc_debug_1arg_bitmap(s, arg1, bitmap) do { } while(0)
#define hwloc_debug_2args_bitmap(s, arg1, arg2, bitmap) do { } while(0)
#endif
#endif /* HWLOC_DEBUG_H */

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

@ -0,0 +1,347 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2010 inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* Misc macros and inlines. */
#ifndef HWLOC_PRIVATE_MISC_H
#define HWLOC_PRIVATE_MISC_H
#include <hwloc/autogen/config.h>
#include <private/autogen/config.h>
/* Compile-time assertion */
#define HWLOC_BUILD_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)]))
#define HWLOC_BITS_PER_LONG (HWLOC_SIZEOF_UNSIGNED_LONG * 8)
#define HWLOC_BITS_PER_INT (HWLOC_SIZEOF_UNSIGNED_INT * 8)
#if (HWLOC_BITS_PER_LONG != 32) && (HWLOC_BITS_PER_LONG != 64)
#error "unknown size for unsigned long."
#endif
#if (HWLOC_BITS_PER_INT != 16) && (HWLOC_BITS_PER_INT != 32) && (HWLOC_BITS_PER_INT != 64)
#error "unknown size for unsigned int."
#endif
/**
* ffsl helpers.
*/
#if defined(HWLOC_HAVE_BROKEN_FFS)
/* System has a broken ffs().
* We must check the before __GNUC__ or HWLOC_HAVE_FFSL
*/
# define HWLOC_NO_FFS
#elif defined(__GNUC__)
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
/* Starting from 3.4, gcc has a long variant. */
# define hwloc_ffsl(x) __builtin_ffsl(x)
# else
# define hwloc_ffs(x) __builtin_ffs(x)
# define HWLOC_NEED_FFSL
# endif
#elif defined(HWLOC_HAVE_FFSL)
# ifndef HWLOC_HAVE_DECL_FFSL
extern int ffsl(long) __hwloc_attribute_const;
# endif
# define hwloc_ffsl(x) ffsl(x)
#elif defined(HWLOC_HAVE_FFS)
# ifndef HWLOC_HAVE_DECL_FFS
extern int ffs(int) __hwloc_attribute_const;
# endif
# define hwloc_ffs(x) ffs(x)
# define HWLOC_NEED_FFSL
#else /* no ffs implementation */
# define HWLOC_NO_FFS
#endif
#ifdef HWLOC_NO_FFS
/* no ffs or it is known to be broken */
static __hwloc_inline int
hwloc_ffsl(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffsl(unsigned long x)
{
int i;
if (!x)
return 0;
i = 1;
#if HWLOC_BITS_PER_LONG >= 64
if (!(x & 0xfffffffful)) {
x >>= 32;
i += 32;
}
#endif
if (!(x & 0xffffu)) {
x >>= 16;
i += 16;
}
if (!(x & 0xff)) {
x >>= 8;
i += 8;
}
if (!(x & 0xf)) {
x >>= 4;
i += 4;
}
if (!(x & 0x3)) {
x >>= 2;
i += 2;
}
if (!(x & 0x1)) {
x >>= 1;
i += 1;
}
return i;
}
#elif defined(HWLOC_NEED_FFSL)
/* We only have an int ffs(int) implementation, build a long one. */
/* First make it 32 bits if it was only 16. */
static __hwloc_inline int
hwloc_ffs32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffs32(unsigned long x)
{
#if HWLOC_BITS_PER_INT == 16
int low_ffs, hi_ffs;
low_ffs = hwloc_ffs(x & 0xfffful);
if (low_ffs)
return low_ffs;
hi_ffs = hwloc_ffs(x >> 16);
if (hi_ffs)
return hi_ffs + 16;
return 0;
#else
return hwloc_ffs(x);
#endif
}
/* Then make it 64 bit if longs are. */
static __hwloc_inline int
hwloc_ffsl(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffsl(unsigned long x)
{
#if HWLOC_BITS_PER_LONG == 64
int low_ffs, hi_ffs;
low_ffs = hwloc_ffs32(x & 0xfffffffful);
if (low_ffs)
return low_ffs;
hi_ffs = hwloc_ffs32(x >> 32);
if (hi_ffs)
return hi_ffs + 32;
return 0;
#else
return hwloc_ffs32(x);
#endif
}
#endif
/**
* flsl helpers.
*/
#ifdef __GNUC_____
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
# define hwloc_flsl(x) (x ? 8*sizeof(long) - __builtin_clzl(x) : 0)
# else
# define hwloc_fls(x) (x ? 8*sizeof(int) - __builtin_clz(x) : 0)
# define HWLOC_NEED_FLSL
# endif
#elif defined(HWLOC_HAVE_FLSL)
# ifndef HWLOC_HAVE_DECL_FLSL
extern int flsl(long) __hwloc_attribute_const;
# endif
# define hwloc_flsl(x) flsl(x)
#elif defined(HWLOC_HAVE_CLZL)
# ifndef HWLOC_HAVE_DECL_CLZL
extern int clzl(long) __hwloc_attribute_const;
# endif
# define hwloc_flsl(x) (x ? 8*sizeof(long) - clzl(x) : 0)
#elif defined(HWLOC_HAVE_FLS)
# ifndef HWLOC_HAVE_DECL_FLS
extern int fls(int) __hwloc_attribute_const;
# endif
# define hwloc_fls(x) fls(x)
# define HWLOC_NEED_FLSL
#elif defined(HWLOC_HAVE_CLZ)
# ifndef HWLOC_HAVE_DECL_CLZ
extern int clz(int) __hwloc_attribute_const;
# endif
# define hwloc_fls(x) (x ? 8*sizeof(int) - clz(x) : 0)
# define HWLOC_NEED_FLSL
#else /* no fls implementation */
static __hwloc_inline int
hwloc_flsl(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_flsl(unsigned long x)
{
int i = 0;
if (!x)
return 0;
i = 1;
#if HWLOC_BITS_PER_LONG >= 64
if ((x & 0xffffffff00000000ul)) {
x >>= 32;
i += 32;
}
#endif
if ((x & 0xffff0000u)) {
x >>= 16;
i += 16;
}
if ((x & 0xff00)) {
x >>= 8;
i += 8;
}
if ((x & 0xf0)) {
x >>= 4;
i += 4;
}
if ((x & 0xc)) {
x >>= 2;
i += 2;
}
if ((x & 0x2)) {
x >>= 1;
i += 1;
}
return i;
}
#endif
#ifdef HWLOC_NEED_FLSL
/* We only have an int fls(int) implementation, build a long one. */
/* First make it 32 bits if it was only 16. */
static __hwloc_inline int
hwloc_fls32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_fls32(unsigned long x)
{
#if HWLOC_BITS_PER_INT == 16
int low_fls, hi_fls;
hi_fls = hwloc_fls(x >> 16);
if (hi_fls)
return hi_fls + 16;
low_fls = hwloc_fls(x & 0xfffful);
if (low_fls)
return low_fls;
return 0;
#else
return hwloc_fls(x);
#endif
}
/* Then make it 64 bit if longs are. */
static __hwloc_inline int
hwloc_flsl(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_flsl(unsigned long x)
{
#if HWLOC_BITS_PER_LONG == 64
int low_fls, hi_fls;
hi_fls = hwloc_fls32(x >> 32);
if (hi_fls)
return hi_fls + 32;
low_fls = hwloc_fls32(x & 0xfffffffful);
if (low_fls)
return low_fls;
return 0;
#else
return hwloc_fls32(x);
#endif
}
#endif
static __hwloc_inline int
hwloc_weight_long(unsigned long w) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_weight_long(unsigned long w)
{
#if HWLOC_BITS_PER_LONG == 32
#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
return __builtin_popcount(w);
#else
unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
#endif
#else /* HWLOC_BITS_PER_LONG == 32 */
#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
return __builtin_popcountll(w);
#else
unsigned long res;
res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
#endif
#endif /* HWLOC_BITS_PER_LONG == 64 */
}
#if !HAVE_DECL_STRTOULL
unsigned long long int strtoull(const char *nptr, char **endptr, int base);
#endif
#endif /* HWLOC_PRIVATE_MISC_H */

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

@ -0,0 +1,299 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
*
* See COPYING in top-level directory.
*/
/* Internal types and helpers. */
#ifdef HWLOC_INSIDE_PLUGIN
/*
* these declarations are internal only, they are not available to plugins
* (many functions below are internal static symbols).
*/
#error This file should not be used in plugins
#endif
#ifndef HWLOC_PRIVATE_H
#define HWLOC_PRIVATE_H
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/bitmap.h>
#include <private/components.h>
#include <private/debug.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#include <string.h>
enum hwloc_ignore_type_e {
HWLOC_IGNORE_TYPE_NEVER = 0,
HWLOC_IGNORE_TYPE_KEEP_STRUCTURE,
HWLOC_IGNORE_TYPE_ALWAYS
};
#define HWLOC_DEPTH_MAX 128
struct hwloc_topology {
unsigned nb_levels; /* Number of horizontal levels */
unsigned next_group_depth; /* Depth of the next Group object that we may create */
unsigned level_nbobjects[HWLOC_DEPTH_MAX]; /* Number of objects on each horizontal level */
struct hwloc_obj **levels[HWLOC_DEPTH_MAX]; /* Direct access to levels, levels[l = 0 .. nblevels-1][0..level_nbobjects[l]] */
unsigned long flags;
int type_depth[HWLOC_OBJ_TYPE_MAX];
enum hwloc_ignore_type_e ignored_types[HWLOC_OBJ_TYPE_MAX];
int is_thissystem;
int is_loaded;
hwloc_pid_t pid; /* Process ID the topology is view from, 0 for self */
unsigned bridge_nbobjects;
struct hwloc_obj **bridge_level;
struct hwloc_obj *first_bridge, *last_bridge;
unsigned pcidev_nbobjects;
struct hwloc_obj **pcidev_level;
struct hwloc_obj *first_pcidev, *last_pcidev;
unsigned osdev_nbobjects;
struct hwloc_obj **osdev_level;
struct hwloc_obj *first_osdev, *last_osdev;
struct hwloc_binding_hooks {
int (*set_thisproc_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
int (*get_thisproc_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*set_thisthread_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
int (*get_thisthread_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*set_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);
int (*get_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
#ifdef hwloc_thread_t
int (*set_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_cpuset_t set, int flags);
int (*get_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_cpuset_t set, int flags);
#endif
int (*get_thisproc_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*get_thisthread_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*get_proc_last_cpu_location)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
int (*set_thisproc_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_thisproc_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*set_thisthread_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_thisthread_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*set_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*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);
int (*get_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
/* This has to return the same kind of pointer as alloc_membind, so that free_membind can be used on it */
void *(*alloc)(hwloc_topology_t topology, size_t len);
/* alloc_membind has to always succeed if !(flags & HWLOC_MEMBIND_STRICT).
* see hwloc_alloc_or_fail which is convenient for that. */
void *(*alloc_membind)(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*free_membind)(hwloc_topology_t topology, void *addr, size_t len);
} binding_hooks;
struct hwloc_topology_support support;
void (*userdata_export_cb)(void *reserved, struct hwloc_topology *topology, struct hwloc_obj *obj);
void (*userdata_import_cb)(struct hwloc_topology *topology, struct hwloc_obj *obj, const char *name, const void *buffer, size_t length);
struct hwloc_os_distances_s {
hwloc_obj_type_t type;
int nbobjs;
unsigned *indexes; /* array of OS indexes before we can convert them into objs. always available.
*/
struct hwloc_obj **objs; /* array of objects, in the same order as above.
* either given (by a backend) together with the indexes array above.
* or build from the above indexes array when not given (by the user).
*/
float *distances; /* distance matrices, ordered according to the above indexes/objs array.
* distance from i to j is stored in slot i*nbnodes+j.
* will be copied into the main logical-index-ordered distance at the end of the discovery.
*/
int forced; /* set if the user forced a matrix to ignore the OS one */
struct hwloc_os_distances_s *prev, *next;
} *first_osdist, *last_osdist;
/* list of enabled backends. */
struct hwloc_backend * backends;
};
extern void hwloc_alloc_obj_cpusets(hwloc_obj_t obj);
extern void hwloc_setup_pu_level(struct hwloc_topology *topology, unsigned nb_pus);
extern int hwloc_get_sysctlbyname(const char *name, int64_t *n);
extern int hwloc_get_sysctl(int name[], unsigned namelen, int *n);
extern unsigned hwloc_fallback_nbprocessors(struct hwloc_topology *topology);
extern void hwloc_connect_children(hwloc_obj_t obj);
extern int hwloc_connect_levels(hwloc_topology_t topology);
extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology);
extern void hwloc_topology_clear(struct hwloc_topology *topology);
/* set native OS binding hooks */
extern void hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support);
/* set either native OS binding hooks (if thissystem), or dummy ones */
extern void hwloc_set_binding_hooks(struct hwloc_topology *topology);
#if defined(HWLOC_LINUX_SYS)
extern void hwloc_set_linuxfs_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_LINUX_SYS */
#if defined(HWLOC_BGQ_SYS)
extern void hwloc_set_bgq_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_BGQ_SYS */
#ifdef HWLOC_SOLARIS_SYS
extern void hwloc_set_solaris_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_SOLARIS_SYS */
#ifdef HWLOC_AIX_SYS
extern void hwloc_set_aix_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_AIX_SYS */
#ifdef HWLOC_OSF_SYS
extern void hwloc_set_osf_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_OSF_SYS */
#ifdef HWLOC_WIN_SYS
extern void hwloc_set_windows_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_WIN_SYS */
#ifdef HWLOC_DARWIN_SYS
extern void hwloc_set_darwin_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_DARWIN_SYS */
#ifdef HWLOC_FREEBSD_SYS
extern void hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_FREEBSD_SYS */
#ifdef HWLOC_NETBSD_SYS
extern void hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_NETBSD_SYS */
#ifdef HWLOC_HPUX_SYS
extern void hwloc_set_hpux_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_HPUX_SYS */
/* Insert uname-specific names/values in the object infos array */
extern void hwloc_add_uname_info(struct hwloc_topology *topology);
/* Free obj and its attributes assuming it doesn't have any children/parent anymore */
extern void hwloc_free_unlinked_object(hwloc_obj_t obj);
/* Duplicate src and its children under newparent in newtopology */
extern void hwloc__duplicate_objects(struct hwloc_topology *newtopology, struct hwloc_obj *newparent, struct hwloc_obj *src);
/* This can be used for the alloc field to get allocated data that can be freed by free() */
void *hwloc_alloc_heap(hwloc_topology_t topology, size_t len);
/* This can be used for the alloc field to get allocated data that can be freed by munmap() */
void *hwloc_alloc_mmap(hwloc_topology_t topology, size_t len);
/* This can be used for the free_membind field to free data using free() */
int hwloc_free_heap(hwloc_topology_t topology, void *addr, size_t len);
/* This can be used for the free_membind field to free data using munmap() */
int hwloc_free_mmap(hwloc_topology_t topology, void *addr, size_t len);
/* Allocates unbound memory or fail, depending on whether STRICT is requested
* or not */
static __hwloc_inline void *
hwloc_alloc_or_fail(hwloc_topology_t topology, size_t len, int flags)
{
if (flags & HWLOC_MEMBIND_STRICT)
return NULL;
return hwloc_alloc(topology, len);
}
extern void hwloc_distances_init(struct hwloc_topology *topology);
extern void hwloc_distances_clear(struct hwloc_topology *topology);
extern void hwloc_distances_destroy(struct hwloc_topology *topology);
extern void hwloc_distances_set(struct hwloc_topology *topology, hwloc_obj_type_t type, unsigned nbobjs, unsigned *indexes, hwloc_obj_t *objs, float *distances, int force);
extern void hwloc_distances_set_from_env(struct hwloc_topology *topology);
extern void hwloc_distances_restrict_os(struct hwloc_topology *topology);
extern void hwloc_distances_restrict(struct hwloc_topology *topology, unsigned long flags);
extern void hwloc_distances_finalize_os(struct hwloc_topology *topology);
extern void hwloc_distances_finalize_logical(struct hwloc_topology *topology);
extern void hwloc_clear_object_distances(struct hwloc_obj *obj);
extern void hwloc_clear_object_distances_one(struct hwloc_distances_s *distances);
extern void hwloc_group_by_distances(struct hwloc_topology *topology);
#ifdef HAVE_USELOCALE
#include "locale.h"
#ifdef HAVE_XLOCALE_H
#include "xlocale.h"
#endif
#define hwloc_localeswitch_declare locale_t __old_locale = (locale_t)0, __new_locale
#define hwloc_localeswitch_init() do { \
__new_locale = newlocale(LC_ALL_MASK, "C", (locale_t)0); \
if (__new_locale != (locale_t)0) \
__old_locale = uselocale(__new_locale); \
} while (0)
#define hwloc_localeswitch_fini() do { \
if (__new_locale != (locale_t)0) { \
uselocale(__old_locale); \
freelocale(__new_locale); \
} \
} while(0)
#else /* HAVE_USELOCALE */
#define hwloc_localeswitch_declare int __dummy_nolocale __hwloc_attribute_unused
#define hwloc_localeswitch_init()
#define hwloc_localeswitch_fini()
#endif /* HAVE_USELOCALE */
#if !HAVE_DECL_FABSF
#define fabsf(f) fabs((double)(f))
#endif
#if HAVE_DECL__SC_PAGE_SIZE
#define hwloc_getpagesize() sysconf(_SC_PAGE_SIZE)
#elif HAVE_DECL__SC_PAGESIZE
#define hwloc_getpagesize() sysconf(_SC_PAGESIZE)
#elif defined HAVE_GETPAGESIZE
#define hwloc_getpagesize() getpagesize()
#else
#undef hwloc_getpagesize
#endif
/* encode src buffer into target buffer.
* targsize must be at least 4*((srclength+2)/3)+1.
* target will be 0-terminated.
*/
extern int hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize);
/* decode src buffer into target buffer.
* src is 0-terminated.
* targsize must be at least srclength*3/4+1 (srclength not including \0)
* but only srclength*3/4 characters will be meaningful
* (the next one may be partially written during decoding, but it should be ignored).
*/
extern int hwloc_decode_from_base64(char const *src, char *target, size_t targsize);
/* Check whether needle matches the beginning of haystack, at least n, and up
* to a colon or \0 */
extern int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n);
#ifdef HWLOC_HAVE_ATTRIBUTE_FORMAT
# if HWLOC_HAVE_ATTRIBUTE_FORMAT
# define __hwloc_attribute_format(type, str, arg) __attribute__((__format__(type, str, arg)))
# else
# define __hwloc_attribute_format(type, str, arg)
# endif
#else
# define __hwloc_attribute_format(type, str, arg)
#endif
/* On some systems, snprintf returns the size of written data, not the actually
* 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);
#endif /* HWLOC_PRIVATE_H */

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

@ -0,0 +1,59 @@
/*
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifdef HWLOC_INSIDE_PLUGIN
/*
* these declarations are internal only, they are not available to plugins
* (functions below are internal static symbols).
*/
#error This file should not be used in plugins
#endif
#ifndef HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H
#define HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H
/* SPARC Chip Modes. */
#define MODE_UNKNOWN 0
#define MODE_SPITFIRE 1
#define MODE_BLACKBIRD 2
#define MODE_CHEETAH 3
#define MODE_SPARC64_VI 4
#define MODE_T1 5
#define MODE_T2 6
#define MODE_SPARC64_VII 7
#define MODE_ROCK 8
/* SPARC Chip Implementations. */
#define IMPL_SPARC64_VI 0x6
#define IMPL_SPARC64_VII 0x7
#define IMPL_SPITFIRE 0x10
#define IMPL_BLACKBIRD 0x11
#define IMPL_SABRE 0x12
#define IMPL_HUMMINGBIRD 0x13
#define IMPL_CHEETAH 0x14
#define IMPL_CHEETAHPLUS 0x15
#define IMPL_JALAPENO 0x16
#define IMPL_JAGUAR 0x18
#define IMPL_PANTHER 0x19
#define IMPL_NIAGARA 0x23
#define IMPL_NIAGARA_2 0x24
#define IMPL_ROCK 0x25
/* Default Mfg, Cache, Speed settings */
#define TI_MANUFACTURER 0x17
#define TWO_MEG_CACHE 2097152
#define SPITFIRE_SPEED 142943750
char* hwloc_solaris_get_chip_type(void);
char* hwloc_solaris_get_chip_model(void);
#endif /* HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H */

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

@ -0,0 +1,79 @@
/*
* Copyright © 2009-2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifndef PRIVATE_XML_H
#define PRIVATE_XML_H 1
#include <hwloc.h>
#include <sys/types.h>
HWLOC_DECLSPEC int hwloc__xml_verbose(void);
typedef struct hwloc__xml_import_state_s {
struct hwloc__xml_import_state_s *parent;
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);
/* opaque data used to store backend-specific data.
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
*/
char data[32];
} * hwloc__xml_import_state_t;
struct hwloc_xml_backend_data_s {
/* xml backend parameters */
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 (*backend_exit)(struct hwloc_xml_backend_data_s *bdata);
void *data; /* libxml2 doc, or nolibxml buffer */
struct hwloc_xml_imported_distances_s {
hwloc_obj_t root;
struct hwloc_distances_s distances;
struct hwloc_xml_imported_distances_s *prev, *next;
} *first_distances, *last_distances;
};
typedef struct hwloc__xml_export_state_s {
struct hwloc__xml_export_state_s *parent;
void (*new_child)(struct hwloc__xml_export_state_s *parentstate, struct hwloc__xml_export_state_s *state, const char *name);
void (*new_prop)(struct hwloc__xml_export_state_s *state, const char *name, const char *value);
void (*add_content)(struct hwloc__xml_export_state_s *state, const char *buffer, size_t length);
void (*end_object)(struct hwloc__xml_export_state_s *state, const char *name);
/* opaque data used to store backend-specific data.
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
*/
char data[40];
} * hwloc__xml_export_state_t;
HWLOC_DECLSPEC void hwloc__xml_export_object (hwloc__xml_export_state_t state, struct hwloc_topology *topology, struct hwloc_obj *obj);
/******************
* XML components *
******************/
struct hwloc_xml_callbacks {
int (*backend_init)(struct hwloc_xml_backend_data_s *bdata, const char *xmlpath, const char *xmlbuffer, int xmlbuflen);
int (*export_file)(struct hwloc_topology *topology, const char *filename);
int (*export_buffer)(struct hwloc_topology *topology, char **xmlbuffer, int *buflen);
void (*free_buffer)(void *xmlbuffer);
};
struct hwloc_xml_component {
struct hwloc_xml_callbacks *nolibxml_callbacks;
struct hwloc_xml_callbacks *libxml_callbacks;
};
HWLOC_DECLSPEC void hwloc_xml_callbacks_register(struct hwloc_xml_component *component);
HWLOC_DECLSPEC void hwloc_xml_callbacks_reset(void);
#endif /* PRIVATE_XML_H */

233
opal/mca/hwloc/hwloc172/hwloc/src/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,233 @@
# Copyright © 2009-2013 Inria. All rights reserved.
# Copyright © 2009-2012 Université Bordeaux 1
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
# Copyright © 2011-2012 Oracle and/or its affiliates. All rights reserved.
# See COPYING in top-level directory.
AM_CFLAGS = $(HWLOC_CFLAGS)
AM_CPPFLAGS = $(HWLOC_CPPFLAGS) -DHWLOC_INSIDE_LIBHWLOC
AM_LDFLAGS = $(HWLOC_LDFLAGS)
EXTRA_DIST = dolib.c
# If we're in standalone mode, build the installable library.
# Otherwise, build the embedded library.
if HWLOC_BUILD_STANDALONE
lib_LTLIBRARIES = libhwloc.la
else
noinst_LTLIBRARIES = libhwloc_embedded.la
endif
pluginsdir = $(libdir)/hwloc
plugins_LTLIBRARIES =
plugins_ldflags = -module -avoid-version
AM_CPPFLAGS += -DHWLOC_PLUGINS_DIR=\"$(pluginsdir)\"
# Sources and ldflags
sources = \
topology.c \
traversal.c \
distances.c \
components.c \
bind.c \
bitmap.c \
misc.c \
base64.c \
topology-noos.c \
topology-synthetic.c \
topology-custom.c \
topology-xml.c \
topology-xml-nolibxml.c
ldflags =
# Conditionally add to the sources and ldflags
if HWLOC_HAVE_LIBXML2
if HWLOC_XML_LIBXML_BUILD_STATIC
sources += topology-xml-libxml.c
else
plugins_LTLIBRARIES += hwloc_xml_libxml.la
hwloc_xml_libxml_la_SOURCES = topology-xml-libxml.c
hwloc_xml_libxml_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_LIBXML2_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_xml_libxml_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_LIBXML2_LIBS)
endif
endif HWLOC_HAVE_LIBXML2
if HWLOC_HAVE_PCI
if HWLOC_PCI_BUILD_STATIC
sources += topology-pci.c
else
plugins_LTLIBRARIES += hwloc_pci.la
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_LDFLAGS = $(plugins_ldflags) $(HWLOC_PCIUTILS_LIBS) $(HWLOC_PCIACCESS_LIBS)
endif
endif HWLOC_HAVE_PCI
if HWLOC_HAVE_OPENCL
if HWLOC_OPENCL_BUILD_STATIC
sources += topology-opencl.c
else
plugins_LTLIBRARIES += hwloc_opencl.la
hwloc_opencl_la_SOURCES = topology-opencl.c
hwloc_opencl_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_OPENCL_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_opencl_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_OPENCL_LIBS)
endif
endif HWLOC_HAVE_OPENCL
if HWLOC_HAVE_CUDART
if HWLOC_CUDA_BUILD_STATIC
sources += topology-cuda.c
else
plugins_LTLIBRARIES += hwloc_cuda.la
hwloc_cuda_la_SOURCES = topology-cuda.c
hwloc_cuda_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_CUDA_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_cuda_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_CUDA_LIBS)
endif
endif HWLOC_HAVE_CUDART
if HWLOC_HAVE_NVML
if HWLOC_NVML_BUILD_STATIC
sources += topology-nvml.c
else
plugins_LTLIBRARIES += hwloc_nvml.la
hwloc_nvml_la_SOURCES = topology-nvml.c
hwloc_nvml_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_NVML_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_nvml_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_NVML_LIBS)
endif
endif HWLOC_HAVE_NVML
if HWLOC_HAVE_GL
if HWLOC_GL_BUILD_STATIC
sources += topology-gl.c
else
plugins_LTLIBRARIES += hwloc_gl.la
hwloc_gl_la_SOURCES = topology-gl.c
hwloc_gl_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_GL_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_gl_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_GL_LIBS)
endif
endif HWLOC_HAVE_GL
if HWLOC_HAVE_SOLARIS
sources += topology-solaris.c
sources += topology-solaris-chiptype.c
endif HWLOC_HAVE_SOLARIS
if HWLOC_HAVE_LINUX
sources += topology-linux.c
endif HWLOC_HAVE_LINUX
if HWLOC_HAVE_BGQ
sources += topology-bgq.c
endif HWLOC_HAVE_BGQ
if HWLOC_HAVE_AIX
sources += topology-aix.c
ldflags += -lpthread
endif HWLOC_HAVE_AIX
if HWLOC_HAVE_OSF
sources += topology-osf.c
ldflags += -lnuma -lpthread
endif HWLOC_HAVE_OSF
if HWLOC_HAVE_HPUX
sources += topology-hpux.c
ldflags += -lpthread
endif HWLOC_HAVE_HPUX
if HWLOC_HAVE_WINDOWS
sources += topology-windows.c
endif HWLOC_HAVE_WINDOWS
if HWLOC_HAVE_DARWIN
sources += topology-darwin.c
endif HWLOC_HAVE_DARWIN
if HWLOC_HAVE_FREEBSD
sources += topology-freebsd.c
endif HWLOC_HAVE_FREEBSD
if HWLOC_HAVE_NETBSD
sources += topology-netbsd.c
ldflags += -lpthread
endif HWLOC_HAVE_NETBSD
if HWLOC_HAVE_CPUID
sources += topology-x86.c
endif HWLOC_HAVE_CPUID
if HWLOC_HAVE_GCC
ldflags += -no-undefined
endif HWLOC_HAVE_GCC
if HWLOC_HAVE_WINDOWS
# Windows specific rules
LC_MESSAGES=C
export LC_MESSAGES
ldflags += -Xlinker --output-def -Xlinker .libs/libhwloc.def
if HWLOC_HAVE_MS_LIB
dolib$(EXEEXT): dolib.c
$(CC_FOR_BUILD) $< -o $@
.libs/libhwloc.lib: libhwloc.la dolib$(EXEEXT)
[ ! -r .libs/libhwloc.def ] || ./dolib$(EXEEXT) "$(HWLOC_MS_LIB)" $(HWLOC_MS_LIB_ARCH) .libs/libhwloc.def $(libhwloc_so_version) .libs/libhwloc.lib
all-local: .libs/libhwloc.lib
clean-local:
$(RM) dolib$(EXEEXT)
endif HWLOC_HAVE_MS_LIB
install-exec-hook:
[ ! -r .libs/libhwloc.def ] || $(INSTALL) .libs/libhwloc.def $(DESTDIR)$(libdir)
if HWLOC_HAVE_MS_LIB
[ ! -r .libs/libhwloc.def ] || $(INSTALL) .libs/libhwloc.lib $(DESTDIR)$(libdir)
[ ! -r .libs/libhwloc.def ] || $(INSTALL) .libs/libhwloc.exp $(DESTDIR)$(libdir)
endif HWLOC_HAVE_MS_LIB
uninstall-local:
rm -f $(DESTDIR)$(libdir)/libhwloc.def
if HWLOC_HAVE_MS_LIB
rm -f $(DESTDIR)$(libdir)/libhwloc.lib $(DESTDIR)$(libdir)/libhwloc.exp
endif HWLOC_HAVE_MS_LIB
# End of Windows specific rules
endif HWLOC_HAVE_WINDOWS
# Installable library
libhwloc_la_SOURCES = $(sources)
libhwloc_la_LDFLAGS = $(ldflags) -version-info $(libhwloc_so_version) $(HWLOC_LIBS)
if HWLOC_HAVE_PLUGINS
AM_CPPFLAGS += $(LTDLINCL)
libhwloc_la_LDFLAGS += -export-dynamic
libhwloc_la_LIBADD = $(LIBLTDL)
endif
# Embedded library (note the lack of a .so version number -- that
# intentionally only appears in the installable library). Also note
# the lack of _LDFLAGS -- all libs are added by the upper layer (via
# HWLOC_EMBEDDED_LIBS).
libhwloc_embedded_la_SOURCES = $(sources)
# XML data (only install if we're building in standalone mode)
if HWLOC_BUILD_STANDALONE
xml_DATA = $(srcdir)/hwloc.dtd
xmldir = $(pkgdatadir)
EXTRA_DIST += hwloc.dtd
endif
DISTCLEANFILES = static-components.h
if HWLOC_HAVE_PLUGINS
check_LTLIBRARIES = hwloc_fake.la
hwloc_fake_la_SOURCES = topology-fake.c
hwloc_fake_la_LDFLAGS = $(plugins_ldflags) -rpath /nowhere # force libtool to build a shared-library even it's check-only
endif

2239
opal/mca/hwloc/hwloc172/hwloc/src/Makefile.in Обычный файл

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

306
opal/mca/hwloc/hwloc172/hwloc/src/base64.c Обычный файл
Просмотреть файл

@ -0,0 +1,306 @@
/*
* Copyright © 2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*
* Modifications after import:
* - removed all #if
* - updated prototypes
* - updated #include
*/
/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */
/*
* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
/* OPENBSD ORIGINAL: lib/libc/net/base64.c */
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
-------------------------------------------------
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <private/private.h>
int
hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize)
{
size_t datalength = 0;
unsigned char input[3];
unsigned char output[4];
unsigned int i;
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1)
target[datalength++] = Pad64;
else
target[datalength++] = Base64[output[2]];
target[datalength++] = Pad64;
}
if (datalength >= targsize)
return (-1);
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (datalength);
}
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
int
hwloc_decode_from_base64(char const *src, char *target, size_t targsize)
{
unsigned int tarindex, state;
int ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src++) != '\0') {
if (isspace(ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr(Base64, ch);
if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
case 0:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] = (pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex+1] = ((pos - Base64) & 0x0f)
<< 4 ;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex+1] = ((pos - Base64) & 0x03)
<< 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}

780
opal/mca/hwloc/hwloc172/hwloc/src/bind.c Обычный файл
Просмотреть файл

@ -0,0 +1,780 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2011 inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <hwloc/helper.h>
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>
/* TODO: HWLOC_GNU_SYS, HWLOC_IRIX_SYS,
*
* IRIX: see MP_MUSTRUN / _DSM_MUSTRUN, pthread_setrunon_np, /hw, procss_cpulink, numa_create
*
* We could use glibc's sched_setaffinity generically when it is available
*
* Darwin and OpenBSD don't seem to have binding facilities.
*/
static hwloc_const_bitmap_t
hwloc_fix_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set)
{
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
if (!topology_set) {
/* The topology is composed of several systems, the cpuset is ambiguous. */
errno = EXDEV;
return NULL;
}
if (hwloc_bitmap_iszero(set)) {
errno = EINVAL;
return NULL;
}
if (!hwloc_bitmap_isincluded(set, complete_set)) {
errno = EINVAL;
return NULL;
}
if (hwloc_bitmap_isincluded(topology_set, set))
set = complete_set;
return set;
}
int
hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set, int flags)
{
set = hwloc_fix_cpubind(topology, set);
if (!set)
return -1;
if (flags & HWLOC_CPUBIND_PROCESS) {
if (topology->binding_hooks.set_thisproc_cpubind)
return topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
} else if (flags & HWLOC_CPUBIND_THREAD) {
if (topology->binding_hooks.set_thisthread_cpubind)
return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
} else {
if (topology->binding_hooks.set_thisproc_cpubind)
return topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
else if (topology->binding_hooks.set_thisthread_cpubind)
return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_get_cpubind(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
{
if (flags & HWLOC_CPUBIND_PROCESS) {
if (topology->binding_hooks.get_thisproc_cpubind)
return topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
} else if (flags & HWLOC_CPUBIND_THREAD) {
if (topology->binding_hooks.get_thisthread_cpubind)
return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
} else {
if (topology->binding_hooks.get_thisproc_cpubind)
return topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
else if (topology->binding_hooks.get_thisthread_cpubind)
return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, int flags)
{
set = hwloc_fix_cpubind(topology, set);
if (!set)
return -1;
if (topology->binding_hooks.set_proc_cpubind)
return topology->binding_hooks.set_proc_cpubind(topology, pid, set, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
{
if (topology->binding_hooks.get_proc_cpubind)
return topology->binding_hooks.get_proc_cpubind(topology, pid, set, flags);
errno = ENOSYS;
return -1;
}
#ifdef hwloc_thread_t
int
hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_bitmap_t set, int flags)
{
set = hwloc_fix_cpubind(topology, set);
if (!set)
return -1;
if (topology->binding_hooks.set_thread_cpubind)
return topology->binding_hooks.set_thread_cpubind(topology, tid, set, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_bitmap_t set, int flags)
{
if (topology->binding_hooks.get_thread_cpubind)
return topology->binding_hooks.get_thread_cpubind(topology, tid, set, flags);
errno = ENOSYS;
return -1;
}
#endif
int
hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
{
if (flags & HWLOC_CPUBIND_PROCESS) {
if (topology->binding_hooks.get_thisproc_last_cpu_location)
return topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
} else if (flags & HWLOC_CPUBIND_THREAD) {
if (topology->binding_hooks.get_thisthread_last_cpu_location)
return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
} else {
if (topology->binding_hooks.get_thisproc_last_cpu_location)
return topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
else if (topology->binding_hooks.get_thisthread_last_cpu_location)
return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
{
if (topology->binding_hooks.get_proc_last_cpu_location)
return topology->binding_hooks.get_proc_last_cpu_location(topology, pid, set, flags);
errno = ENOSYS;
return -1;
}
static hwloc_const_nodeset_t
hwloc_fix_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
{
hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology);
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
if (!hwloc_topology_get_topology_cpuset(topology)) {
/* The topology is composed of several systems, the nodeset is thus
* ambiguous. */
errno = EXDEV;
return NULL;
}
if (!complete_nodeset) {
/* There is no NUMA node */
errno = ENODEV;
return NULL;
}
if (hwloc_bitmap_iszero(nodeset)) {
errno = EINVAL;
return NULL;
}
if (!hwloc_bitmap_isincluded(nodeset, complete_nodeset)) {
errno = EINVAL;
return NULL;
}
if (hwloc_bitmap_isincluded(topology_nodeset, nodeset))
return complete_nodeset;
return nodeset;
}
static int
hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_const_cpuset_t cpuset)
{
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
if (!topology_set) {
/* The topology is composed of several systems, the cpuset is thus
* ambiguous. */
errno = EXDEV;
return -1;
}
if (!complete_nodeset) {
/* There is no NUMA node */
errno = ENODEV;
return -1;
}
if (hwloc_bitmap_iszero(cpuset)) {
errno = EINVAL;
return -1;
}
if (!hwloc_bitmap_isincluded(cpuset, complete_set)) {
errno = EINVAL;
return -1;
}
if (hwloc_bitmap_isincluded(topology_set, cpuset)) {
hwloc_bitmap_copy(nodeset, complete_nodeset);
return 0;
}
hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
return 0;
}
int
hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
return -1;
if (flags & HWLOC_MEMBIND_PROCESS) {
if (topology->binding_hooks.set_thisproc_membind)
return topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
} else if (flags & HWLOC_MEMBIND_THREAD) {
if (topology->binding_hooks.set_thisthread_membind)
return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
} else {
if (topology->binding_hooks.set_thisproc_membind)
return topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
else if (topology->binding_hooks.set_thisthread_membind)
return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_set_membind(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
int ret;
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
ret = -1;
else
ret = hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
return ret;
}
int
hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
if (flags & HWLOC_MEMBIND_PROCESS) {
if (topology->binding_hooks.get_thisproc_membind)
return topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
} else if (flags & HWLOC_MEMBIND_THREAD) {
if (topology->binding_hooks.get_thisthread_membind)
return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
} else {
if (topology->binding_hooks.get_thisproc_membind)
return topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
else if (topology->binding_hooks.get_thisthread_membind)
return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_get_membind(hwloc_topology_t topology, hwloc_cpuset_t set, hwloc_membind_policy_t * policy, int flags)
{
hwloc_nodeset_t nodeset;
int ret;
nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_membind_nodeset(topology, nodeset, policy, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
return ret;
}
int
hwloc_set_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
return -1;
if (topology->binding_hooks.set_proc_membind)
return topology->binding_hooks.set_proc_membind(topology, pid, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
int ret;
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
ret = -1;
else
ret = hwloc_set_proc_membind_nodeset(topology, pid, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
return ret;
}
int
hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
if (topology->binding_hooks.get_proc_membind)
return topology->binding_hooks.get_proc_membind(topology, pid, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, hwloc_membind_policy_t * policy, int flags)
{
hwloc_nodeset_t nodeset;
int ret;
nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_proc_membind_nodeset(topology, pid, nodeset, policy, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
return ret;
}
int
hwloc_set_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
return -1;
if (topology->binding_hooks.set_area_membind)
return topology->binding_hooks.set_area_membind(topology, addr, len, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
int ret;
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
ret = -1;
else
ret = hwloc_set_area_membind_nodeset(topology, addr, len, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
return ret;
}
int
hwloc_get_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
if (topology->binding_hooks.get_area_membind)
return topology->binding_hooks.get_area_membind(topology, addr, len, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_cpuset_t set, hwloc_membind_policy_t * policy, int flags)
{
hwloc_nodeset_t nodeset;
int ret;
nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_area_membind_nodeset(topology, addr, len, nodeset, policy, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
return ret;
}
void *
hwloc_alloc_heap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
{
void *p;
#if defined(hwloc_getpagesize) && defined(HAVE_POSIX_MEMALIGN)
errno = posix_memalign(&p, hwloc_getpagesize(), len);
if (errno)
p = NULL;
#elif defined(hwloc_getpagesize) && defined(HAVE_MEMALIGN)
p = memalign(hwloc_getpagesize(), len);
#else
p = malloc(len);
#endif
return p;
}
#ifdef MAP_ANONYMOUS
void *
hwloc_alloc_mmap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
{
return mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
}
#endif
int
hwloc_free_heap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len __hwloc_attribute_unused)
{
free(addr);
return 0;
}
#ifdef MAP_ANONYMOUS
int
hwloc_free_mmap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len)
{
if (!addr)
return 0;
return munmap(addr, len);
}
#endif
void *
hwloc_alloc(hwloc_topology_t topology, size_t len)
{
if (topology->binding_hooks.alloc)
return topology->binding_hooks.alloc(topology, len);
return hwloc_alloc_heap(topology, len);
}
void *
hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
void *p;
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
goto fallback;
if (flags & HWLOC_MEMBIND_MIGRATE) {
errno = EINVAL;
goto fallback;
}
if (topology->binding_hooks.alloc_membind)
return topology->binding_hooks.alloc_membind(topology, len, nodeset, policy, flags);
else if (topology->binding_hooks.set_area_membind) {
p = hwloc_alloc(topology, len);
if (!p)
return NULL;
if (topology->binding_hooks.set_area_membind(topology, p, len, nodeset, policy, flags) && flags & HWLOC_MEMBIND_STRICT) {
int error = errno;
free(p);
errno = error;
return NULL;
}
return p;
} else {
errno = ENOSYS;
}
fallback:
if (flags & HWLOC_MEMBIND_STRICT)
/* Report error */
return NULL;
/* Never mind, allocate anyway */
return hwloc_alloc(topology, len);
}
void *
hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
void *ret;
if (hwloc_fix_membind_cpuset(topology, nodeset, set)) {
if (flags & HWLOC_MEMBIND_STRICT)
ret = NULL;
else
ret = hwloc_alloc(topology, len);
} else
ret = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
return ret;
}
int
hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
{
if (topology->binding_hooks.free_membind)
return topology->binding_hooks.free_membind(topology, addr, len);
return hwloc_free_heap(topology, addr, len);
}
/*
* Empty binding hooks always returning success
*/
static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set)
{
hwloc_const_cpuset_t cpuset = hwloc_topology_get_complete_cpuset(topology);
if (cpuset) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
} else
return -1;
}
static int dontset_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, set);
}
static int dontset_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, set);
}
static int dontset_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, cpuset);
}
#ifdef hwloc_thread_t
static int dontset_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, cpuset);
}
#endif
static int dontset_return_complete_nodeset(hwloc_topology_t topology, hwloc_nodeset_t set, hwloc_membind_policy_t *policy)
{
hwloc_const_nodeset_t nodeset = hwloc_topology_get_complete_nodeset(topology);
if (nodeset) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
*policy = HWLOC_MEMBIND_DEFAULT;
return 0;
} else
return -1;
}
static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontset_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontset_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontset_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static void * dontalloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return malloc(size);
}
static int dontfree_membind(hwloc_topology_t topology __hwloc_attribute_unused, void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused)
{
free(addr);
return 0;
}
static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_thisproc_cpubind = dontset_thisproc_cpubind;
hooks->get_thisproc_cpubind = dontget_thisproc_cpubind;
hooks->set_thisthread_cpubind = dontset_thisthread_cpubind;
hooks->get_thisthread_cpubind = dontget_thisthread_cpubind;
hooks->set_proc_cpubind = dontset_proc_cpubind;
hooks->get_proc_cpubind = dontget_proc_cpubind;
#ifdef hwloc_thread_t
hooks->set_thread_cpubind = dontset_thread_cpubind;
hooks->get_thread_cpubind = dontget_thread_cpubind;
#endif
hooks->get_thisproc_last_cpu_location = dontget_thisproc_cpubind; /* cpubind instead of last_cpu_location is ok */
hooks->get_thisthread_last_cpu_location = dontget_thisthread_cpubind; /* cpubind instead of last_cpu_location is ok */
hooks->get_proc_last_cpu_location = dontget_proc_cpubind; /* cpubind instead of last_cpu_location is ok */
/* TODO: get_thread_last_cpu_location */
hooks->set_thisproc_membind = dontset_thisproc_membind;
hooks->get_thisproc_membind = dontget_thisproc_membind;
hooks->set_thisthread_membind = dontset_thisthread_membind;
hooks->get_thisthread_membind = dontget_thisthread_membind;
hooks->set_proc_membind = dontset_proc_membind;
hooks->get_proc_membind = dontget_proc_membind;
hooks->set_area_membind = dontset_area_membind;
hooks->get_area_membind = dontget_area_membind;
hooks->alloc_membind = dontalloc_membind;
hooks->free_membind = dontfree_membind;
}
void
hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support)
{
# ifdef HWLOC_LINUX_SYS
hwloc_set_linuxfs_hooks(hooks, support);
# endif /* HWLOC_LINUX_SYS */
# ifdef HWLOC_BGQ_SYS
hwloc_set_bgq_hooks(hooks, support);
# endif /* HWLOC_BGQ_SYS */
# ifdef HWLOC_AIX_SYS
hwloc_set_aix_hooks(hooks, support);
# endif /* HWLOC_AIX_SYS */
# ifdef HWLOC_OSF_SYS
hwloc_set_osf_hooks(hooks, support);
# endif /* HWLOC_OSF_SYS */
# ifdef HWLOC_SOLARIS_SYS
hwloc_set_solaris_hooks(hooks, support);
# endif /* HWLOC_SOLARIS_SYS */
# ifdef HWLOC_WIN_SYS
hwloc_set_windows_hooks(hooks, support);
# endif /* HWLOC_WIN_SYS */
# ifdef HWLOC_DARWIN_SYS
hwloc_set_darwin_hooks(hooks, support);
# endif /* HWLOC_DARWIN_SYS */
# ifdef HWLOC_FREEBSD_SYS
hwloc_set_freebsd_hooks(hooks, support);
# endif /* HWLOC_FREEBSD_SYS */
# ifdef HWLOC_NETBSD_SYS
hwloc_set_netbsd_hooks(hooks, support);
# endif /* HWLOC_NETBSD_SYS */
# ifdef HWLOC_HPUX_SYS
hwloc_set_hpux_hooks(hooks, support);
# endif /* HWLOC_HPUX_SYS */
}
/* If the represented system is actually not this system, use dummy binding hooks. */
void
hwloc_set_binding_hooks(struct hwloc_topology *topology)
{
if (topology->is_thissystem) {
hwloc_set_native_binding_hooks(&topology->binding_hooks, &topology->support);
/* every hook not set above will return ENOSYS */
} else {
/* not this system, use dummy binding hooks that do nothing (but don't return ENOSYS) */
hwloc_set_dummy_hooks(&topology->binding_hooks, &topology->support);
}
/* if not is_thissystem, set_cpubind is fake
* and get_cpubind returns the whole system cpuset,
* so don't report that set/get_cpubind as supported
*/
if (topology->is_thissystem) {
#define DO(which,kind) \
if (topology->binding_hooks.kind) \
topology->support.which##bind->kind = 1;
DO(cpu,set_thisproc_cpubind);
DO(cpu,get_thisproc_cpubind);
DO(cpu,set_proc_cpubind);
DO(cpu,get_proc_cpubind);
DO(cpu,set_thisthread_cpubind);
DO(cpu,get_thisthread_cpubind);
#ifdef hwloc_thread_t
DO(cpu,set_thread_cpubind);
DO(cpu,get_thread_cpubind);
#endif
DO(cpu,get_thisproc_last_cpu_location);
DO(cpu,get_proc_last_cpu_location);
DO(cpu,get_thisthread_last_cpu_location);
DO(mem,set_thisproc_membind);
DO(mem,get_thisproc_membind);
DO(mem,set_thisthread_membind);
DO(mem,get_thisthread_membind);
DO(mem,set_proc_membind);
DO(mem,get_proc_membind);
DO(mem,set_area_membind);
DO(mem,get_area_membind);
DO(mem,alloc_membind);
}
}

1163
opal/mca/hwloc/hwloc172/hwloc/src/bitmap.c Обычный файл

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

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

@ -0,0 +1,762 @@
/*
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2012 Université Bordeau 1
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/xml.h>
#define HWLOC_COMPONENT_STOP_NAME "stop"
#define HWLOC_COMPONENT_EXCLUDE_CHAR '-'
#define HWLOC_COMPONENT_SEPS ","
/* list of all registered discovery components, sorted by priority, higher priority first.
* noos is last because its priority is 0.
* others' priority is 10.
*/
static struct hwloc_disc_component * hwloc_disc_components = NULL;
static unsigned hwloc_components_users = 0; /* first one initializes, last ones destroys */
static int hwloc_components_verbose = 0;
#ifdef HWLOC_HAVE_PLUGINS
static int hwloc_plugins_verbose = 0;
#endif
#ifdef HWLOC_WIN_SYS
/* 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. */
#include <windows.h>
static LONG hwloc_components_mutex = 0;
#define HWLOC_COMPONENTS_LOCK() do { \
while (InterlockedCompareExchange(&hwloc_components_mutex, 1, 0) != 0) \
SwitchToThread(); \
} while (0)
#define HWLOC_COMPONENTS_UNLOCK() do { \
assert(hwloc_components_mutex == 1); \
hwloc_components_mutex = 0; \
} while (0)
#elif defined HWLOC_HAVE_PTHREAD_MUTEX
/* pthread mutex if available (except on windows) */
#include <pthread.h>
static pthread_mutex_t hwloc_components_mutex = PTHREAD_MUTEX_INITIALIZER;
#define HWLOC_COMPONENTS_LOCK() pthread_mutex_lock(&hwloc_components_mutex)
#define HWLOC_COMPONENTS_UNLOCK() pthread_mutex_unlock(&hwloc_components_mutex)
#else /* HWLOC_WIN_SYS || HWLOC_HAVE_PTHREAD_MUTEX */
#error No mutex implementation available
#endif
#ifdef HWLOC_HAVE_PLUGINS
#include <ltdl.h>
/* array of pointers to dynamically loaded plugins */
static struct hwloc__plugin_desc {
char *name;
struct hwloc_component *component;
char *filename;
lt_dlhandle handle;
struct hwloc__plugin_desc *next;
} *hwloc_plugins = NULL;
static int
hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
{
const char *basename;
lt_dlhandle handle;
char *componentsymbolname = NULL;
struct hwloc_component *component;
struct hwloc__plugin_desc *desc, **prevdesc;
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin dlforeach found `%s'\n", filename);
basename = strrchr(filename, '/');
if (!basename)
basename = filename;
else
basename++;
/* dlopen and get the component structure */
handle = lt_dlopenext(filename);
if (!handle) {
if (hwloc_plugins_verbose)
fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror());
goto out;
}
componentsymbolname = malloc(6+strlen(basename)+10+1);
sprintf(componentsymbolname, "%s_component", basename);
component = lt_dlsym(handle, componentsymbolname);
if (!component) {
if (hwloc_plugins_verbose)
fprintf(stderr, "Failed to find component symbol `%s'\n",
componentsymbolname);
goto out_with_handle;
}
if (component->abi != HWLOC_COMPONENT_ABI) {
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin symbol ABI %u instead of %u\n",
component->abi, HWLOC_COMPONENT_ABI);
goto out_with_handle;
}
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin contains expected symbol `%s'\n",
componentsymbolname);
free(componentsymbolname);
componentsymbolname = NULL;
if (HWLOC_COMPONENT_TYPE_DISC == component->type) {
if (strncmp(basename, "hwloc_", 6)) {
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin name `%s' doesn't match its type DISCOVERY\n", basename);
goto out_with_handle;
}
} else if (HWLOC_COMPONENT_TYPE_XML == component->type) {
if (strncmp(basename, "hwloc_xml_", 10)) {
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin name `%s' doesn't match its type XML\n", basename);
goto out_with_handle;
}
} else {
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin name `%s' has invalid type %u\n",
basename, (unsigned) component->type);
goto out_with_handle;
}
/* allocate a plugin_desc and queue it */
desc = malloc(sizeof(*desc));
if (!desc)
goto out_with_handle;
desc->name = strdup(basename);
desc->filename = strdup(filename);
desc->component = component;
desc->handle = handle;
desc->next = NULL;
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin descriptor `%s' ready\n", basename);
/* append to the list */
prevdesc = &hwloc_plugins;
while (*prevdesc)
prevdesc = &((*prevdesc)->next);
*prevdesc = desc;
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin descriptor `%s' queued\n", basename);
return 0;
out_with_handle:
lt_dlclose(handle);
free(componentsymbolname); /* NULL if already freed */
out:
return 0;
}
static void
hwloc_plugins_exit(void)
{
struct hwloc__plugin_desc *desc, *next;
if (hwloc_plugins_verbose)
fprintf(stderr, "Closing all plugins\n");
desc = hwloc_plugins;
while (desc) {
next = desc->next;
lt_dlclose(desc->handle);
free(desc->name);
free(desc->filename);
free(desc);
desc = next;
}
hwloc_plugins = NULL;
lt_dlexit();
}
static int
hwloc_plugins_init(void)
{
char *verboseenv;
char *path = HWLOC_PLUGINS_DIR;
char *env;
int err;
verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
hwloc_plugins_verbose = verboseenv ? atoi(verboseenv) : 0;
err = lt_dlinit();
if (err)
goto out;
env = getenv("HWLOC_PLUGINS_PATH");
if (env)
path = env;
hwloc_plugins = NULL;
if (hwloc_plugins_verbose)
fprintf(stderr, "Starting plugin dlforeach in %s\n", path);
err = lt_dlforeachfile(path, hwloc__dlforeach_cb, NULL);
if (err)
goto out_with_init;
return 0;
out_with_init:
hwloc_plugins_exit();
out:
return -1;
}
#endif /* HWLOC_HAVE_PLUGINS */
static const char *
hwloc_disc_component_type_string(hwloc_disc_component_type_t type)
{
switch (type) {
case HWLOC_DISC_COMPONENT_TYPE_CPU: return "cpu";
case HWLOC_DISC_COMPONENT_TYPE_GLOBAL: return "global";
case HWLOC_DISC_COMPONENT_TYPE_MISC: return "misc";
default: return "**unknown**";
}
}
static int
hwloc_disc_component_register(struct hwloc_disc_component *component,
const char *filename)
{
struct hwloc_disc_component **prev;
/* check that the component name is valid */
if (!strcmp(component->name, HWLOC_COMPONENT_STOP_NAME)) {
if (hwloc_components_verbose)
fprintf(stderr, "Cannot register discovery component with reserved name `" HWLOC_COMPONENT_STOP_NAME "'\n");
return -1;
}
if (strchr(component->name, HWLOC_COMPONENT_EXCLUDE_CHAR)
|| strcspn(component->name, HWLOC_COMPONENT_SEPS) != strlen(component->name)) {
if (hwloc_components_verbose)
fprintf(stderr, "Cannot register discovery component with name `%s' containing reserved characters `%c" HWLOC_COMPONENT_SEPS "'\n",
component->name, HWLOC_COMPONENT_EXCLUDE_CHAR);
return -1;
}
/* check that the component type is valid */
switch ((unsigned) component->type) {
case HWLOC_DISC_COMPONENT_TYPE_CPU:
case HWLOC_DISC_COMPONENT_TYPE_GLOBAL:
case HWLOC_DISC_COMPONENT_TYPE_MISC:
break;
default:
fprintf(stderr, "Cannot register discovery component `%s' with unknown type %u\n",
component->name, (unsigned) component->type);
return -1;
}
prev = &hwloc_disc_components;
while (NULL != *prev) {
if (!strcmp((*prev)->name, component->name)) {
/* if two components have the same name, only keep the highest priority one */
if ((*prev)->priority < component->priority) {
/* drop the existing component */
if (hwloc_components_verbose)
fprintf(stderr, "Dropping previously registered discovery component `%s', priority %u lower than new one %u\n",
(*prev)->name, (*prev)->priority, component->priority);
*prev = (*prev)->next;
} else {
/* drop the new one */
if (hwloc_components_verbose)
fprintf(stderr, "Ignoring new discovery component `%s', priority %u lower than previously registered one %u\n",
component->name, component->priority, (*prev)->priority);
return -1;
}
}
prev = &((*prev)->next);
}
if (hwloc_components_verbose)
fprintf(stderr, "Registered %s discovery component `%s' with priority %u (%s%s)\n",
hwloc_disc_component_type_string(component->type), component->name, component->priority,
filename ? "from plugin " : "statically build", filename ? filename : "");
prev = &hwloc_disc_components;
while (NULL != *prev) {
if ((*prev)->priority < component->priority)
break;
prev = &((*prev)->next);
}
component->next = *prev;
*prev = component;
return 0;
}
#include <static-components.h>
void
hwloc_components_init(struct hwloc_topology *topology __hwloc_attribute_unused)
{
#ifdef HWLOC_HAVE_PLUGINS
struct hwloc__plugin_desc *desc;
#endif
char *verboseenv;
unsigned i;
HWLOC_COMPONENTS_LOCK();
assert((unsigned) -1 != hwloc_components_users);
if (0 != hwloc_components_users++) {
HWLOC_COMPONENTS_UNLOCK();
goto ok;
}
verboseenv = getenv("HWLOC_COMPONENTS_VERBOSE");
hwloc_components_verbose = verboseenv ? atoi(verboseenv) : 0;
#ifdef HWLOC_HAVE_PLUGINS
hwloc_plugins_init();
#endif
/* hwloc_static_components is created by configure in static-components.h */
for(i=0; NULL != hwloc_static_components[i]; i++) {
if (hwloc_static_components[i]->flags) {
fprintf(stderr, "Ignoring static component with invalid flags %lx\n",
hwloc_static_components[i]->flags);
continue;
}
if (HWLOC_COMPONENT_TYPE_DISC == hwloc_static_components[i]->type)
hwloc_disc_component_register(hwloc_static_components[i]->data, NULL);
else if (HWLOC_COMPONENT_TYPE_XML == hwloc_static_components[i]->type)
hwloc_xml_callbacks_register(hwloc_static_components[i]->data);
else
assert(0);
}
/* dynamic plugins */
#ifdef HWLOC_HAVE_PLUGINS
for(desc = hwloc_plugins; NULL != desc; desc = desc->next) {
if (desc->component->flags) {
fprintf(stderr, "Ignoring plugin `%s' component with invalid flags %lx\n",
desc->name, desc->component->flags);
continue;
}
if (HWLOC_COMPONENT_TYPE_DISC == desc->component->type)
hwloc_disc_component_register(desc->component->data, desc->filename);
else if (HWLOC_COMPONENT_TYPE_XML == desc->component->type)
hwloc_xml_callbacks_register(desc->component->data);
else
assert(0);
}
#endif
HWLOC_COMPONENTS_UNLOCK();
ok:
topology->backends = NULL;
}
static struct hwloc_disc_component *
hwloc_disc_component_find(int type /* hwloc_disc_component_type_t or -1 if any */,
const char *name /* name of NULL if any */)
{
struct hwloc_disc_component *comp = hwloc_disc_components;
while (NULL != comp) {
if ((-1 == type || type == (int) comp->type)
&& (NULL == name || !strcmp(name, comp->name)))
return comp;
comp = comp->next;
}
return NULL;
}
/* used by set_xml(), set_synthetic(), ... environment variables, ... to force the first backend */
int
hwloc_disc_component_force_enable(struct hwloc_topology *topology,
int envvar_forced,
int type, const char *name,
const void *data1, const void *data2, const void *data3)
{
struct hwloc_disc_component *comp;
struct hwloc_backend *backend;
comp = hwloc_disc_component_find(type, name);
if (!comp) {
errno = ENOSYS;
return -1;
}
backend = comp->instantiate(comp, data1, data2, data3);
if (backend) {
backend->envvar_forced = envvar_forced;
if (topology->backends)
hwloc_backends_reset(topology);
return hwloc_backend_enable(topology, backend);
} else
return -1;
}
static int
hwloc_disc_component_try_enable(struct hwloc_topology *topology,
struct hwloc_disc_component *comp,
const char *comparg,
unsigned *excludes,
int envvar_forced,
int verbose_errors)
{
struct hwloc_backend *backend;
int err;
if ((*excludes) & comp->type) {
if (hwloc_components_verbose || verbose_errors)
fprintf(stderr, "Excluding %s discovery component `%s', conflicts with excludes 0x%x\n",
hwloc_disc_component_type_string(comp->type), comp->name, *excludes);
return -1;
}
backend = comp->instantiate(comp, comparg, NULL, NULL);
if (!backend) {
if (verbose_errors)
fprintf(stderr, "Failed to instantiate discovery component `%s'\n", comp->name);
return -1;
}
backend->envvar_forced = envvar_forced;
err = hwloc_backend_enable(topology, backend);
if (err < 0)
return -1;
*excludes |= comp->excludes;
return 0;
}
void
hwloc_disc_components_enable_others(struct hwloc_topology *topology)
{
struct hwloc_disc_component *comp;
struct hwloc_backend *backend;
unsigned excludes = 0;
int tryall = 1;
char *env;
env = getenv("HWLOC_COMPONENTS");
/* compute current excludes */
backend = topology->backends;
while (backend) {
excludes |= backend->component->excludes;
backend = backend->next;
}
/* enable explicitly listed components */
if (env) {
char *curenv = env;
size_t s;
while (*curenv) {
s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
if (s) {
char *arg;
char c;
/* replace libpci with pci for backward compatibility with v1.6 */
if (!strncmp(curenv, "libpci", s)) {
curenv[0] = curenv[1] = curenv[2] = *HWLOC_COMPONENT_SEPS;
curenv += 3;
s -= 3;
} else if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, "libpci", s-1)) {
curenv[3] = curenv[0];
curenv[0] = curenv[1] = curenv[2] = *HWLOC_COMPONENT_SEPS;
curenv += 3;
s -= 3;
/* skip this name, it's a negated one */
goto nextname;
}
if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR)
goto nextname;
if (!strncmp(curenv, HWLOC_COMPONENT_STOP_NAME, s)) {
tryall = 0;
break;
}
/* save the last char and replace with \0 */
c = curenv[s];
curenv[s] = '\0';
arg = strchr(curenv, '=');
if (arg) {
*arg = '\0';
arg++;
}
comp = hwloc_disc_component_find(-1, curenv);
if (comp) {
hwloc_disc_component_try_enable(topology, comp, arg, &excludes, 1 /* envvar forced */, 1 /* envvar forced need warnings */);
} else {
fprintf(stderr, "Cannot find discovery component `%s'\n", curenv);
}
/* restore last char (the second loop below needs env to be unmodified) */
curenv[s] = c;
}
nextname:
curenv += s;
if (*curenv)
/* Skip comma */
curenv++;
}
}
/* env is still the same, the above loop didn't modify it */
/* now enable remaining components (except the explicitly '-'-listed ones) */
if (tryall) {
comp = hwloc_disc_components;
while (NULL != comp) {
/* check if this component was explicitly excluded in env */
if (env) {
char *curenv = env;
while (*curenv) {
size_t s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, comp->name, s-1)) {
if (hwloc_components_verbose)
fprintf(stderr, "Excluding %s discovery component `%s' because of HWLOC_COMPONENTS environment variable\n",
hwloc_disc_component_type_string(comp->type), comp->name);
goto nextcomp;
}
curenv += s;
if (*curenv)
/* Skip comma */
curenv++;
}
}
hwloc_disc_component_try_enable(topology, comp, NULL, &excludes, 0 /* defaults, not envvar forced */, 0 /* defaults don't need warnings on conflicts */);
nextcomp:
comp = comp->next;
}
}
if (hwloc_components_verbose) {
/* print a summary */
int first = 1;
backend = topology->backends;
fprintf(stderr, "Final list of enabled discovery components: ");
while (backend != NULL) {
fprintf(stderr, "%s%s", first ? "" : ",", backend->component->name);
backend = backend->next;
first = 0;
}
fprintf(stderr, "\n");
}
}
void
hwloc_components_destroy_all(struct hwloc_topology *topology __hwloc_attribute_unused)
{
HWLOC_COMPONENTS_LOCK();
assert(0 != hwloc_components_users);
if (0 != --hwloc_components_users) {
HWLOC_COMPONENTS_UNLOCK();
return;
}
/* no need to unlink/free the list of components, they'll be unloaded below */
hwloc_disc_components = NULL;
hwloc_xml_callbacks_reset();
#ifdef HWLOC_HAVE_PLUGINS
hwloc_plugins_exit();
#endif
HWLOC_COMPONENTS_UNLOCK();
}
struct hwloc_backend *
hwloc_backend_alloc(struct hwloc_disc_component *component)
{
struct hwloc_backend * backend = malloc(sizeof(*backend));
if (!backend) {
errno = ENOMEM;
return NULL;
}
backend->component = component;
backend->flags = 0;
backend->discover = NULL;
backend->get_obj_cpuset = NULL;
backend->notify_new_object = NULL;
backend->disable = NULL;
backend->is_custom = 0;
backend->is_thissystem = -1;
backend->next = NULL;
backend->envvar_forced = 0;
return backend;
}
static void
hwloc_backend_disable(struct hwloc_backend *backend)
{
if (backend->disable)
backend->disable(backend);
free(backend);
}
int
hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *backend)
{
struct hwloc_backend **pprev;
/* check backend flags */
if (backend->flags & (~(HWLOC_BACKEND_FLAG_NEED_LEVELS))) {
fprintf(stderr, "Cannot enable %s discovery component `%s' with unknown flags %lx\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name, backend->flags);
return -1;
}
/* make sure we didn't already enable this backend, we don't want duplicates */
pprev = &topology->backends;
while (NULL != *pprev) {
if ((*pprev)->component == backend->component) {
if (hwloc_components_verbose)
fprintf(stderr, "Cannot enable %s discovery component `%s' twice\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name);
hwloc_backend_disable(backend);
errno = EBUSY;
return -1;
}
pprev = &((*pprev)->next);
}
if (hwloc_components_verbose)
fprintf(stderr, "Enabling %s discovery component `%s'\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name);
/* enqueue at the end */
pprev = &topology->backends;
while (NULL != *pprev)
pprev = &((*pprev)->next);
backend->next = *pprev;
*pprev = backend;
backend->topology = topology;
return 0;
}
void
hwloc_backends_is_thissystem(struct hwloc_topology *topology)
{
struct hwloc_backend *backend;
char *local_env;
/* Apply is_thissystem topology flag before we enforce envvar backends.
* If the application changed the backend with set_foo(),
* it may use set_flags() update the is_thissystem flag here.
* If it changes the backend with environment variables below,
* it may use HWLOC_THISSYSTEM envvar below as well.
*/
topology->is_thissystem = 1;
/* apply thissystem from normally-given backends (envvar_forced=0, either set_foo() or defaults) */
backend = topology->backends;
while (backend != NULL) {
if (backend->envvar_forced == 0 && backend->is_thissystem != -1) {
assert(backend->is_thissystem == 0);
topology->is_thissystem = 0;
}
backend = backend->next;
}
/* override set_foo() with flags */
if (topology->flags & HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM)
topology->is_thissystem = 1;
/* now apply envvar-forced backend (envvar_forced=1) */
backend = topology->backends;
while (backend != NULL) {
if (backend->envvar_forced == 1 && backend->is_thissystem != -1) {
assert(backend->is_thissystem == 0);
topology->is_thissystem = 0;
}
backend = backend->next;
}
/* override with envvar-given flag */
local_env = getenv("HWLOC_THISSYSTEM");
if (local_env)
topology->is_thissystem = atoi(local_env);
}
int
hwloc_backends_get_obj_cpuset(struct hwloc_backend *caller, struct hwloc_obj *obj, hwloc_bitmap_t cpuset)
{
struct hwloc_topology *topology = caller->topology;
struct hwloc_backend *backend = topology->backends;
/* use the first backend's get_obj_cpuset callback */
while (backend != NULL) {
if (backend->get_obj_cpuset)
return backend->get_obj_cpuset(backend, caller, obj, cpuset);
backend = backend->next;
}
return -1;
}
int
hwloc_backends_notify_new_object(struct hwloc_backend *caller, struct hwloc_obj *obj)
{
struct hwloc_backend *backend;
int res = 0;
backend = caller->topology->backends;
while (NULL != backend) {
if (backend != caller && backend->notify_new_object)
res += backend->notify_new_object(backend, caller, obj);
backend = backend->next;
}
return res;
}
void
hwloc_backends_disable_all(struct hwloc_topology *topology)
{
struct hwloc_backend *backend;
while (NULL != (backend = topology->backends)) {
struct hwloc_backend *next = backend->next;
if (hwloc_components_verbose)
fprintf(stderr, "Disabling %s discovery component `%s'\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name);
hwloc_backend_disable(backend);
topology->backends = next;
}
topology->backends = NULL;
}
void
hwloc_backends_reset(struct hwloc_topology *topology)
{
hwloc_backends_disable_all(topology);
if (topology->is_loaded) {
static int deprecated_warning = 0;
if (!deprecated_warning) {
if (!getenv("HWLOC_HIDE_DEPRECATED")) {
fprintf(stderr, "*** Modifying an already-loaded topology.\n");
fprintf(stderr, "*** This non-documented behavior will not be supported in future releases.\n");
fprintf(stderr, "*** Set HWLOC_HIDE_DEPRECATED in the environment to hide this message.\n");
}
deprecated_warning = 1;
}
hwloc_topology_clear(topology);
hwloc_distances_destroy(topology);
hwloc_topology_setup_defaults(topology);
topology->is_loaded = 0;
}
}

1029
opal/mca/hwloc/hwloc172/hwloc/src/distances.c Обычный файл

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

47
opal/mca/hwloc/hwloc172/hwloc/src/dolib.c Обычный файл
Просмотреть файл

@ -0,0 +1,47 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009 inria. All rights reserved.
* Copyright © 2009, 2012 Université Bordeaux 1
* See COPYING in top-level directory.
*/
/* Wrapper to avoid msys' tendency to turn / into \ and : into ; */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char *prog, *arch, *def, *version, *lib;
char s[1024];
char name[16];
int current, age, revision;
if (argc != 6) {
fprintf(stderr,"bad number of arguments");
exit(EXIT_FAILURE);
}
prog = argv[1];
arch = argv[2];
def = argv[3];
version = argv[4];
lib = argv[5];
if (sscanf(version, "%d:%d:%d", &current, &revision, &age) != 3)
exit(EXIT_FAILURE);
_snprintf(name, sizeof(name), "libhwloc-%d", current - age);
printf("using soname %s\n", name);
_snprintf(s, sizeof(s), "\"%s\" /machine:%s /def:%s /name:%s /out:%s",
prog, arch, def, name, lib);
if (system(s)) {
fprintf(stderr, "%s failed\n", s);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

57
opal/mca/hwloc/hwloc172/hwloc/src/hwloc.dtd Обычный файл
Просмотреть файл

@ -0,0 +1,57 @@
<!--
Copyright © 2009 CNRS
Copyright © 2009-2012 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux 1.
See COPYING in top-level directory.
-->
<!ELEMENT topology (object)+>
<!ELEMENT root (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 os_level CDATA "-1" >
<!ATTLIST object os_index CDATA "-1" >
<!ATTLIST object name CDATA "" >
<!ATTLIST object local_memory CDATA "0" >
<!ATTLIST object cache_size CDATA "0" >
<!ATTLIST object cache_linesize CDATA "0" >
<!ATTLIST object cache_associativity CDATA "0" >
<!ATTLIST object cache_type CDATA "0" >
<!ATTLIST object huge_page_size_kB CDATA "0" >
<!ATTLIST object huge_page_free CDATA "0" >
<!ATTLIST object depth CDATA "-1" >
<!ATTLIST object cpuset CDATA "0" >
<!ATTLIST object complete_cpuset CDATA "" >
<!ATTLIST object online_cpuset CDATA "" >
<!ATTLIST object allowed_cpuset CDATA "" >
<!ATTLIST object nodeset CDATA "" >
<!ATTLIST object complete_nodeset CDATA "" >
<!ATTLIST object allowed_nodeset CDATA "" >
<!ATTLIST object bridge_type CDATA "" >
<!ATTLIST object bridge_pci CDATA "" >
<!ATTLIST object pci_busid CDATA "" >
<!ATTLIST object pci_type CDATA "" >
<!ATTLIST object pci_link_speed CDATA "0." >
<!ATTLIST object osdev_type CDATA "" >
<!ELEMENT page_type EMPTY>
<!ATTLIST page_type size CDATA #REQUIRED>
<!ATTLIST page_type count CDATA #REQUIRED>
<!ELEMENT info EMPTY>
<!ATTLIST info name CDATA #REQUIRED>
<!ATTLIST info value CDATA #REQUIRED>
<!ELEMENT distances (latency*)>
<!ATTLIST distances nbobjs CDATA #REQUIRED>
<!ATTLIST distances relative_depth CDATA #REQUIRED>
<!ATTLIST distances latency_base CDATA #REQUIRED>
<!ELEMENT latency EMPTY>
<!ATTLIST latency value CDATA #REQUIRED>
<!ELEMENT userdata (#PCDATA)>
<!ATTLIST userdata name CDATA "" >
<!ATTLIST userdata length CDATA "0" >
<!ATTLIST userdata encoding CDATA "" >

106
opal/mca/hwloc/hwloc172/hwloc/src/misc.c Обычный файл
Просмотреть файл

@ -0,0 +1,106 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <private/private.h>
#include <private/misc.h>
#include <stdarg.h>
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
int hwloc_snprintf(char *str, size_t size, const char *format, ...)
{
int ret;
va_list ap;
static char bin;
size_t fakesize;
char *fakestr;
/* Some systems crash on str == NULL */
if (!size) {
str = &bin;
size = 1;
}
va_start(ap, format);
ret = vsnprintf(str, size, format, ap);
va_end(ap);
if (ret >= 0 && (size_t) ret != size-1)
return ret;
/* vsnprintf returned size-1 or -1. That could be a system which reports the
* written data and not the actually required room. Try increasing buffer
* size to get the latter. */
fakesize = size;
fakestr = NULL;
do {
fakesize *= 2;
free(fakestr);
fakestr = malloc(fakesize);
if (NULL == fakestr)
return -1;
va_start(ap, format);
errno = 0;
ret = vsnprintf(fakestr, fakesize, format, ap);
va_end(ap);
} while ((size_t) ret == fakesize-1 || (ret < 0 && (!errno || errno == ERANGE)));
if (ret >= 0 && size) {
if (size > (size_t) ret+1)
size = ret+1;
memcpy(str, fakestr, size-1);
str[size-1] = 0;
}
free(fakestr);
return ret;
}
int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n)
{
size_t i = 0;
while (*haystack && *haystack != ':') {
int ha = *haystack++;
int low_h = tolower(ha);
int ne = *needle++;
int low_n = tolower(ne);
if (low_h != low_n)
return 1;
i++;
}
return i < n;
}
void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused)
{
#ifdef HAVE_UNAME
struct utsname utsname;
if (uname(&utsname) < 0)
return;
if (hwloc_obj_get_info_by_name(topology->levels[0][0], "OSName"))
/* don't annotate twice */
return;
hwloc_obj_add_info(topology->levels[0][0], "OSName", utsname.sysname);
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", utsname.release);
hwloc_obj_add_info(topology->levels[0][0], "OSVersion", utsname.version);
hwloc_obj_add_info(topology->levels[0][0], "HostName", utsname.nodename);
hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname.machine);
#endif /* HAVE_UNAME */
}

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

@ -0,0 +1,855 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* TODO: use SIGRECONFIG & dr_reconfig for state change */
#include <private/autogen/config.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/misc.h>
#include <private/debug.h>
#include <procinfo.h>
#include <sys/types.h>
#include <sys/rset.h>
#include <sys/processor.h>
#include <sys/thread.h>
#include <sys/mman.h>
#include <sys/systemcfg.h>
#ifndef __power_pc
#define __power_pc() 0
#endif
#ifndef __power_4
#define __power_4() 0
#endif
#ifndef __power_5
#define __power_5() 0
#endif
#ifndef __power_6
#define __power_6() 0
#endif
#ifndef __power_7
#define __power_7() 0
#endif
static int
hwloc_aix_set_sth_cpubind(hwloc_topology_t topology, rstype_t what, rsid_t who, pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
rsethandle_t rad;
int res;
unsigned cpu;
if (flags & HWLOC_CPUBIND_NOMEMBIND) {
errno = ENOSYS;
return -1;
}
/* The resulting binding is always strict */
if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) {
if (ra_detachrset(what, who, 0))
return -1;
return 0;
}
rad = rs_alloc(RS_EMPTY);
hwloc_bitmap_foreach_begin(cpu, hwloc_set)
rs_op(RS_ADDRESOURCE, rad, NULL, R_PROCS, cpu);
hwloc_bitmap_foreach_end();
res = ra_attachrset(what, who, rad, 0);
if (res < 0 && errno == EPERM) {
/* EPERM may mean that one thread has ben bound with bindprocessor().
* Unbind the entire process (we can't unbind individual threads)
* and try again.
*/
bindprocessor(BINDPROCESS, pid, PROCESSOR_CLASS_ANY);
res = ra_attachrset(what, who, rad, 0);
}
rs_free(rad);
return res;
}
static int
hwloc_aix_get_sth_rset_cpubind(hwloc_topology_t topology, rstype_t what, rsid_t who, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused, int *boundp)
{
rsethandle_t rset;
unsigned cpu, maxcpus;
int res = -1;
int bound = 0;
rset = rs_alloc(RS_EMPTY);
if (ra_getrset(what, who, 0, rset) == -1)
goto out;
hwloc_bitmap_zero(hwloc_set);
maxcpus = rs_getinfo(rset, R_MAXPROCS, 0);
for (cpu = 0; cpu < maxcpus; cpu++)
if (rs_op(RS_TESTRESOURCE, rset, NULL, R_PROCS, cpu) == 1)
hwloc_bitmap_set(hwloc_set, cpu);
else
bound = 1;
hwloc_bitmap_and(hwloc_set, hwloc_set, hwloc_topology_get_complete_cpuset(topology));
res = 0;
*boundp = bound;
out:
rs_free(rset);
return res;
}
static int
hwloc_aix_get_pid_getthrds_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, pid_t pid, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
#if HWLOC_BITS_PER_LONG == 64
struct thrdentry64 thread_info;
tid64_t next_thread;
#else
struct thrdsinfo thread_info;
tid_t next_thread;
#endif
next_thread = 0;
/* TODO: get multiple at once */
#if HWLOC_BITS_PER_LONG == 64
while (getthrds64 (pid, &thread_info, sizeof (thread_info),
&next_thread, 1) == 1) {
#else
while (getthrds (pid, &thread_info, sizeof (thread_info),
&next_thread, 1) == 1) {
#endif
if (PROCESSOR_CLASS_ANY != thread_info.ti_cpuid)
hwloc_bitmap_set(hwloc_set, thread_info.ti_cpuid);
else
hwloc_bitmap_fill(hwloc_set);
}
/* TODO: what if the thread list changes and we get nothing? */
return 0;
}
static int
hwloc_aix_get_tid_getthrds_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, tid_t tid, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
#if HWLOC_BITS_PER_LONG == 64
struct thrdentry64 thread_info;
tid64_t next_thread;
#else
struct thrdsinfo thread_info;
tid_t next_thread;
#endif
pid_t pid = getpid();
next_thread = 0;
/* TODO: get multiple at once */
#if HWLOC_BITS_PER_LONG == 64
while (getthrds64 (pid, &thread_info, sizeof (thread_info),
&next_thread, 1) == 1) {
#else
while (getthrds (pid, &thread_info, sizeof (thread_info),
&next_thread, 1) == 1) {
#endif
if (thread_info.ti_tid == tid) {
if (PROCESSOR_CLASS_ANY != thread_info.ti_cpuid)
hwloc_bitmap_set(hwloc_set, thread_info.ti_cpuid);
else
hwloc_bitmap_fill(hwloc_set);
break;
}
}
/* TODO: what if the thread goes away in the meantime? */
return 0;
}
static int
hwloc_aix_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
rsid_t who;
who.at_pid = getpid();
return hwloc_aix_set_sth_cpubind(topology, R_PROCESS, who, who.at_pid, hwloc_set, flags);
}
static int
hwloc_aix_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags)
{
int ret, bound;
rsid_t who;
who.at_pid = getpid();
ret = hwloc_aix_get_sth_rset_cpubind(topology, R_PROCESS, who, hwloc_set, flags, &bound);
if (!ret && !bound) {
hwloc_bitmap_zero(hwloc_set);
ret = hwloc_aix_get_pid_getthrds_cpubind(topology, who.at_pid, hwloc_set, flags);
}
return ret;
}
#ifdef R_THREAD
static int
hwloc_aix_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
rsid_t who;
who.at_tid = thread_self();
return hwloc_aix_set_sth_cpubind(topology, R_THREAD, who, getpid(), hwloc_set, flags);
}
static int
hwloc_aix_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags)
{
int ret, bound;
rsid_t who;
who.at_tid = thread_self();
ret = hwloc_aix_get_sth_rset_cpubind(topology, R_THREAD, who, hwloc_set, flags, &bound);
if (!ret && !bound) {
hwloc_bitmap_zero(hwloc_set);
ret = hwloc_aix_get_tid_getthrds_cpubind(topology, who.at_tid, hwloc_set, flags);
}
return ret;
}
#endif /* R_THREAD */
static int
hwloc_aix_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags)
{
rsid_t who;
who.at_pid = pid;
return hwloc_aix_set_sth_cpubind(topology, R_PROCESS, who, pid, hwloc_set, flags);
}
static int
hwloc_aix_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t hwloc_set, int flags)
{
int ret, bound;
rsid_t who;
who.at_pid = pid;
ret = hwloc_aix_get_sth_rset_cpubind(topology, R_PROCESS, who, hwloc_set, flags, &bound);
if (!ret && !bound) {
hwloc_bitmap_zero(hwloc_set);
ret = hwloc_aix_get_pid_getthrds_cpubind(topology, who.at_pid, hwloc_set, flags);
}
return ret;
}
#ifdef R_THREAD
#ifdef HWLOC_HAVE_PTHREAD_GETTHRDS_NP
static int
hwloc_aix_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_const_bitmap_t hwloc_set, int flags)
{
struct __pthrdsinfo info;
int size;
if ((errno = pthread_getthrds_np(&pthread, PTHRDSINFO_QUERY_TID, &info, sizeof(info), NULL, &size)))
return -1;
{
rsid_t who;
who.at_tid = info.__pi_tid;
return hwloc_aix_set_sth_cpubind(topology, R_THREAD, who, getpid(), hwloc_set, flags);
}
}
static int
hwloc_aix_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_bitmap_t hwloc_set, int flags)
{
struct __pthrdsinfo info;
int size;
if (pthread_getthrds_np(&pthread, PTHRDSINFO_QUERY_TID, &info, sizeof(info), NULL, &size))
return -1;
{
int ret, bound;
rsid_t who;
who.at_tid = info.__pi_tid;
ret = hwloc_aix_get_sth_rset_cpubind(topology, R_THREAD, who, hwloc_set, flags, &bound);
if (!ret && !bound) {
hwloc_bitmap_zero(hwloc_set);
ret = hwloc_aix_get_tid_getthrds_cpubind(topology, who.at_tid, hwloc_set, flags);
}
return ret;
}
}
#endif /* HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
#endif /* R_THREAD */
static int
hwloc_aix_get_thisthread_last_cpu_location(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
cpu_t cpu;
if (topology->pid) {
errno = ENOSYS;
return -1;
}
cpu = mycpu();
if (cpu < 0)
return -1;
hwloc_bitmap_only(hwloc_set, cpu);
return 0;
}
#ifdef P_DEFAULT
static int
hwloc_aix_membind_policy_from_hwloc(uint_t *aix_policy, int policy)
{
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
*aix_policy = P_DEFAULT;
break;
case HWLOC_MEMBIND_FIRSTTOUCH:
*aix_policy = P_FIRST_TOUCH;
break;
case HWLOC_MEMBIND_INTERLEAVE:
*aix_policy = P_BALANCED;
break;
default:
errno = ENOSYS;
return -1;
}
return 0;
}
static int
hwloc_aix_prepare_membind(hwloc_topology_t topology, rsethandle_t *rad, hwloc_const_nodeset_t nodeset, int flags __hwloc_attribute_unused)
{
rsethandle_t rset, noderad;
int MCMlevel;
int node;
MCMlevel = rs_getinfo(NULL, R_MCMSDL, 0);
if ((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM))
rset = rs_alloc(RS_ALL);
else
rset = rs_alloc(RS_PARTITION);
*rad = rs_alloc(RS_EMPTY);
noderad = rs_alloc(RS_EMPTY);
hwloc_bitmap_foreach_begin(node, nodeset)
rs_getrad(rset, noderad, MCMlevel, node, 0);
rs_op(RS_UNION, noderad, *rad, 0, 0);
hwloc_bitmap_foreach_end();
rs_free(rset);
rs_free(noderad);
return 0;
}
static int
hwloc_aix_set_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who, pid_t pid, hwloc_const_bitmap_t nodeset, hwloc_membind_policy_t policy, int flags)
{
rsethandle_t rad;
int res;
if (flags & HWLOC_MEMBIND_NOCPUBIND) {
errno = ENOSYS;
return -1;
}
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
break;
default:
errno = ENOSYS;
return -1;
}
if (hwloc_aix_prepare_membind(topology, &rad, nodeset, flags))
return -1;
res = ra_attachrset(what, who, rad, 0);
if (res < 0 && errno == EPERM) {
/* EPERM may mean that one thread has ben bound with bindprocessor().
* Unbind the entire process (we can't unbind individual threads)
* and try again.
*/
bindprocessor(BINDPROCESS, pid, PROCESSOR_CLASS_ANY);
res = ra_attachrset(what, who, rad, 0);
}
rs_free(rad);
return res;
}
static int
hwloc_aix_get_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who, hwloc_bitmap_t nodeset, hwloc_membind_policy_t *policy, int flags __hwloc_attribute_unused)
{
hwloc_bitmap_t hwloc_set;
rsethandle_t rset;
unsigned cpu, maxcpus;
int res = -1;
int depth, n, i;
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth < 0) {
errno = EXDEV;
return -1;
}
n = hwloc_get_nbobjs_by_depth(topology, depth);
rset = rs_alloc(RS_EMPTY);
if (ra_getrset(what, who, 0, rset) == -1)
goto out;
hwloc_set = hwloc_bitmap_alloc();
maxcpus = rs_getinfo(rset, R_MAXPROCS, 0);
for (cpu = 0; cpu < maxcpus; cpu++)
if (rs_op(RS_TESTRESOURCE, rset, NULL, R_PROCS, cpu) == 1)
hwloc_bitmap_set(hwloc_set, cpu);
hwloc_bitmap_and(hwloc_set, hwloc_set, hwloc_topology_get_complete_cpuset(topology));
hwloc_bitmap_zero(nodeset);
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set))
hwloc_bitmap_set(nodeset, obj->os_index);
}
hwloc_bitmap_free(hwloc_set);
*policy = HWLOC_MEMBIND_DEFAULT;
res = 0;
out:
rs_free(rset);
return res;
}
static int
hwloc_aix_set_thisproc_membind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, hwloc_membind_policy_t policy, int flags)
{
rsid_t who;
who.at_pid = getpid();
return hwloc_aix_set_sth_membind(topology, R_PROCESS, who, who.at_pid, hwloc_set, policy, flags);
}
static int
hwloc_aix_get_thisproc_membind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, hwloc_membind_policy_t *policy, int flags)
{
rsid_t who;
who.at_pid = getpid();
return hwloc_aix_get_sth_membind(topology, R_PROCESS, who, hwloc_set, policy, flags);
}
#ifdef R_THREAD
static int
hwloc_aix_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, hwloc_membind_policy_t policy, int flags)
{
rsid_t who;
who.at_tid = thread_self();
return hwloc_aix_set_sth_membind(topology, R_THREAD, who, getpid(), hwloc_set, policy, flags);
}
static int
hwloc_aix_get_thisthread_membind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, hwloc_membind_policy_t *policy, int flags)
{
rsid_t who;
who.at_tid = thread_self();
return hwloc_aix_get_sth_membind(topology, R_THREAD, who, hwloc_set, policy, flags);
}
#endif /* R_THREAD */
static int
hwloc_aix_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, hwloc_membind_policy_t policy, int flags)
{
rsid_t who;
who.at_pid = pid;
return hwloc_aix_set_sth_membind(topology, R_PROCESS, who, pid, hwloc_set, policy, flags);
}
static int
hwloc_aix_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t hwloc_set, hwloc_membind_policy_t *policy, int flags)
{
rsid_t who;
who.at_pid = pid;
return hwloc_aix_get_sth_membind(topology, R_PROCESS, who, hwloc_set, policy, flags);
}
#ifdef R_THREAD
#if 0 /* def HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
static int
hwloc_aix_set_thread_membind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_const_bitmap_t hwloc_set, hwloc_membind_policy_t policy, int flags)
{
struct __pthrdsinfo info;
int size;
if ((errno = pthread_getthrds_np(&pthread, PTHRDSINFO_QUERY_TID, &info, sizeof(info), NULL, &size)))
return -1;
{
rsid_t who;
who.at_tid = info.__pi_tid;
return hwloc_aix_set_sth_membind(topology, R_THREAD, who, getpid(), hwloc_set, policy, flags);
}
}
static int
hwloc_aix_get_thread_membind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_bitmap_t hwloc_set, hwloc_membind_policy_t *policy, int flags)
{
struct __pthrdsinfo info;
int size;
if (pthread_getthrds_np(&pthread, PTHRDSINFO_QUERY_TID, &info, sizeof(info), NULL, &size))
return -1;
{
rsid_t who;
who.at_tid = info.__pi_tid;
return hwloc_aix_get_sth_membind(topology, R_THREAD, who, hwloc_set, policy, flags);
}
}
#endif /* HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
#endif /* R_THREAD */
#if 0
/* TODO: seems to be right, but doesn't seem to be working (EINVAL), even after
* aligning the range on 64K... */
static int
hwloc_aix_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)
{
subrange_t subrange;
rsid_t rsid = { .at_subrange = &subrange };
uint_t aix_policy;
int ret;
fprintf(stderr,"yop\n");
if ((flags & (HWLOC_MEMBIND_MIGRATE|HWLOC_MEMBIND_STRICT))
== (HWLOC_MEMBIND_MIGRATE|HWLOC_MEMBIND_STRICT)) {
errno = ENOSYS;
return -1;
}
subrange.su_offset = (uintptr_t) addr;
subrange.su_length = len;
subrange.su_rstype = R_RSET;
if (hwloc_aix_membind_policy_from_hwloc(&aix_policy, policy))
return -1;
if (hwloc_aix_prepare_membind(topology, &subrange.su_rsid.at_rset, nodeset, flags))
return -1;
subrange.su_policy = aix_policy;
res = ra_attachrset(R_SUBRANGE, rsid, subrange.su_rsid.at_rset, 0);
if (res < 0 && errno == EPERM) {
/* EPERM may mean that one thread has ben bound with bindprocessor().
* Unbind the entire process (we can't unbind individual threads)
* and try again.
* FIXME: actually check that this EPERM can happen
*/
bindprocessor(BINDPROCESS, getpid(), PROCESSOR_CLASS_ANY);
res = ra_attachrset(R_SUBRANGE, rsid, subrange.su_rsid.at_rset, 0);
}
rs_free(subrange.su_rsid.at_rset);
return ret;
}
#endif
static void *
hwloc_aix_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
void *ret;
rsid_t rsid;
uint_t aix_policy;
if (hwloc_aix_membind_policy_from_hwloc(&aix_policy, policy))
return hwloc_alloc_or_fail(topology, len, flags);
if (hwloc_aix_prepare_membind(topology, &rsid.at_rset, nodeset, flags))
return hwloc_alloc_or_fail(topology, len, flags);
ret = ra_mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0, R_RSET, rsid, aix_policy);
rs_free(rsid.at_rset);
return ret;
}
#endif /* P_DEFAULT */
static void
look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int level)
{
rsethandle_t rset, rad;
int i,maxcpus,j;
int nbnodes;
struct hwloc_obj *obj;
if ((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM))
rset = rs_alloc(RS_ALL);
else
rset = rs_alloc(RS_PARTITION);
rad = rs_alloc(RS_EMPTY);
nbnodes = rs_numrads(rset, sdl, 0);
if (nbnodes == -1) {
perror("rs_numrads");
return;
}
for (i = 0; i < nbnodes; i++) {
if (rs_getrad(rset, rad, sdl, i, 0)) {
fprintf(stderr,"rs_getrad(%d) failed: %s\n", i, strerror(errno));
continue;
}
if (!rs_getinfo(rad, R_NUMPROCS, 0))
continue;
/* It seems logical processors are numbered from 1 here, while the
* bindprocessor functions numbers them from 0... */
obj = hwloc_alloc_setup_object(type, i - (type == HWLOC_OBJ_PU));
obj->cpuset = hwloc_bitmap_alloc();
obj->os_level = sdl;
maxcpus = rs_getinfo(rad, R_MAXPROCS, 0);
for (j = 0; j < maxcpus; j++) {
if (rs_op(RS_TESTRESOURCE, rad, NULL, R_PROCS, j))
hwloc_bitmap_set(obj->cpuset, j);
}
switch(type) {
case HWLOC_OBJ_NODE:
obj->nodeset = hwloc_bitmap_alloc();
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.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize();
#ifdef HAVE__SC_LARGE_PAGESIZE
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
/* TODO: obj->memory.page_types[1].count = rs_getinfo(rset, R_LGPGFREE, 0) / hugepagesize */
break;
case HWLOC_OBJ_CACHE:
obj->attr->cache.size = _system_configuration.L2_cache_size;
obj->attr->cache.associativity = _system_configuration.L2_cache_asc;
obj->attr->cache.linesize = 0; /* unknown by default */
if (__power_pc())
if (__power_4() || __power_5() || __power_6() || __power_7())
obj->attr->cache.linesize = 128;
obj->attr->cache.depth = 2;
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; /* OK for power[4567], unknown for others */
break;
case HWLOC_OBJ_GROUP:
obj->attr->group.depth = level;
break;
case HWLOC_OBJ_CORE:
{
hwloc_obj_t obj2, obj3;
obj2 = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, i);
obj2->cpuset = hwloc_bitmap_dup(obj->cpuset);
obj2->attr->cache.size = _system_configuration.dcache_size;
obj2->attr->cache.associativity = _system_configuration.dcache_asc;
obj2->attr->cache.linesize = _system_configuration.dcache_line;
obj2->attr->cache.depth = 1;
if (_system_configuration.cache_attrib & (1<<30)) {
/* Unified cache */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
hwloc_debug("Adding an L1u cache for core %d\n", i);
hwloc_insert_object_by_cpuset(topology, obj2);
} else {
/* Separate Instruction and Data caches */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
hwloc_debug("Adding an L1d cache for core %d\n", i);
hwloc_insert_object_by_cpuset(topology, obj2);
obj3 = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, i);
obj3->cpuset = hwloc_bitmap_dup(obj->cpuset);
obj3->attr->cache.size = _system_configuration.icache_size;
obj3->attr->cache.associativity = _system_configuration.icache_asc;
obj3->attr->cache.linesize = _system_configuration.icache_line;
obj3->attr->cache.depth = 1;
obj3->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
hwloc_debug("Adding an L1i cache for core %d\n", i);
hwloc_insert_object_by_cpuset(topology, obj3);
}
break;
}
default:
break;
}
hwloc_debug_2args_bitmap("%s %d has cpuset %s\n",
hwloc_obj_type_string(type),
i, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
rs_free(rset);
rs_free(rad);
}
static int
hwloc_look_aix(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
int i;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
/* TODO: R_LGPGDEF/R_LGPGFREE for large pages */
hwloc_debug("Note: SMPSDL is at %d\n", rs_getinfo(NULL, R_SMPSDL, 0));
#ifdef R_REF1SDL
hwloc_debug("Note: REF1SDL is at %d\n", rs_getinfo(NULL, R_REF1SDL, 0));
#endif
for (i=0; i<=rs_getinfo(NULL, R_MAXSDL, 0); i++)
{
int known = 0;
#if 0
if (i == rs_getinfo(NULL, R_SMPSDL, 0))
/* Not enabled for now because I'm not sure what it corresponds to. On
* decrypthon it contains all the cpus. Is it a "machine" or a "system"
* level ?
*/
{
hwloc_debug("looking AIX \"SMP\" sdl %d\n", i);
look_rset(i, HWLOC_OBJ_MACHINE, topology, i);
known = 1;
}
#endif
if (i == rs_getinfo(NULL, R_MCMSDL, 0))
{
hwloc_debug("looking AIX node sdl %d\n", i);
look_rset(i, HWLOC_OBJ_NODE, topology, i);
known = 1;
}
# ifdef R_L2CSDL
if (i == rs_getinfo(NULL, R_L2CSDL, 0))
{
hwloc_debug("looking AIX L2 sdl %d\n", i);
look_rset(i, HWLOC_OBJ_CACHE, topology, i);
known = 1;
}
# endif
# ifdef R_PCORESDL
if (i == rs_getinfo(NULL, R_PCORESDL, 0))
{
hwloc_debug("looking AIX core sdl %d\n", i);
look_rset(i, HWLOC_OBJ_CORE, topology, i);
known = 1;
}
# endif
if (i == rs_getinfo(NULL, R_MAXSDL, 0))
{
hwloc_debug("looking AIX max sdl %d\n", i);
look_rset(i, HWLOC_OBJ_PU, topology, i);
known = 1;
topology->support.discovery->pu = 1;
}
/* Don't know how it should be rendered, make a misc object for it. */
if (!known)
{
hwloc_debug("looking AIX unknown sdl %d\n", i);
look_rset(i, HWLOC_OBJ_GROUP, topology, i);
}
}
hwloc_obj_add_info(topology->levels[0][0], "Backend", "AIX");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_aix_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_aix_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_aix_get_proc_cpubind;
#ifdef R_THREAD
#ifdef HWLOC_HAVE_PTHREAD_GETTHRDS_NP
hooks->set_thread_cpubind = hwloc_aix_set_thread_cpubind;
hooks->get_thread_cpubind = hwloc_aix_get_thread_cpubind;
#endif /* HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
#endif /* R_THREAD */
hooks->set_thisproc_cpubind = hwloc_aix_set_thisproc_cpubind;
hooks->get_thisproc_cpubind = hwloc_aix_get_thisproc_cpubind;
#ifdef R_THREAD
hooks->set_thisthread_cpubind = hwloc_aix_set_thisthread_cpubind;
hooks->get_thisthread_cpubind = hwloc_aix_get_thisthread_cpubind;
#endif /* R_THREAD */
hooks->get_thisthread_last_cpu_location = hwloc_aix_get_thisthread_last_cpu_location;
/* TODO: get_last_cpu_location: mycpu() only works for the current thread? */
#ifdef P_DEFAULT
hooks->set_proc_membind = hwloc_aix_set_proc_membind;
hooks->get_proc_membind = hwloc_aix_get_proc_membind;
#ifdef R_THREAD
#if 0 /* def HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
/* Does it really make sense to set the memory binding of another thread? */
hooks->set_thread_membind = hwloc_aix_set_thread_membind;
hooks->get_thread_membind = hwloc_aix_get_thread_membind;
#endif /* HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
#endif /* R_THREAD */
hooks->set_thisproc_membind = hwloc_aix_set_thisproc_membind;
hooks->get_thisproc_membind = hwloc_aix_get_thisproc_membind;
#ifdef R_THREAD
hooks->set_thisthread_membind = hwloc_aix_set_thisthread_membind;
hooks->get_thisthread_membind = hwloc_aix_get_thisthread_membind;
#endif /* R_THREAD */
/* hooks->set_area_membind = hwloc_aix_set_area_membind; */
/* get_area_membind is not available */
hooks->alloc_membind = hwloc_aix_alloc_membind;
hooks->alloc = hwloc_alloc_mmap;
hooks->free_membind = hwloc_free_mmap;
support->membind->firsttouch_membind = 1;
support->membind->bind_membind = 1;
support->membind->interleave_membind = 1;
#endif /* P_DEFAULT */
}
static struct hwloc_backend *
hwloc_aix_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_aix;
return backend;
}
static struct hwloc_disc_component hwloc_aix_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"aix",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_aix_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_aix_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_aix_disc_component
};

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

@ -0,0 +1,239 @@
/*
* Copyright © 2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <spi/include/kernel/location.h>
#include <spi/include/kernel/process.h>
static int
hwloc_look_bgq(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
unsigned i;
char *env;
if (!topology->levels[0][0]->cpuset) {
/* Nobody created objects yet, setup everything */
hwloc_bitmap_t set;
hwloc_obj_t obj;
#define HWLOC_BGQ_CORES 17 /* spare core ignored for now */
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
/* mark the 17th core (OS-reserved) as disallowed */
hwloc_bitmap_clr_range(topology->levels[0][0]->allowed_cpuset, (HWLOC_BGQ_CORES-1)*4, HWLOC_BGQ_CORES*4-1);
env = getenv("BG_THREADMODEL");
if (!env || atoi(env) != 2) {
/* process cannot use cores/threads outside of its Kernel_ThreadMask() */
uint64_t bgmask = Kernel_ThreadMask(Kernel_MyTcoord());
/* the mask is reversed, manually reverse it */
for(i=0; i<64; i++)
if (((bgmask >> i) & 1) == 0)
hwloc_bitmap_clr(topology->levels[0][0]->allowed_cpuset, 63-i);
}
/* a single memory bank */
set = hwloc_bitmap_alloc();
hwloc_bitmap_set(set, 0);
topology->levels[0][0]->nodeset = set;
topology->levels[0][0]->memory.local_memory = 16ULL*1024*1024*1024ULL;
/* socket */
obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, 0);
set = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(set, 0, HWLOC_BGQ_CORES*4-1);
obj->cpuset = set;
hwloc_obj_add_info(obj, "CPUModel", "IBM PowerPC A2");
hwloc_insert_object_by_cpuset(topology, obj);
/* shared L2 */
obj = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, -1);
obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2;
obj->attr->cache.size = 32*1024*1024;
obj->attr->cache.linesize = 128;
obj->attr->cache.associativity = 16;
hwloc_insert_object_by_cpuset(topology, obj);
/* Cores */
for(i=0; i<HWLOC_BGQ_CORES; i++) {
/* Core */
obj = hwloc_alloc_setup_object(HWLOC_OBJ_CORE, i);
set = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(set, i*4, i*4+3);
obj->cpuset = set;
hwloc_insert_object_by_cpuset(topology, obj);
/* L1d */
obj = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, -1);
obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
obj->attr->cache.depth = 1;
obj->attr->cache.size = 16*1024;
obj->attr->cache.linesize = 64;
obj->attr->cache.associativity = 8;
hwloc_insert_object_by_cpuset(topology, obj);
/* L1i */
obj = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, -1);
obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
obj->attr->cache.depth = 1;
obj->attr->cache.size = 16*1024;
obj->attr->cache.linesize = 64;
obj->attr->cache.associativity = 4;
hwloc_insert_object_by_cpuset(topology, obj);
/* there's also a L1p "prefetch cache" of 4kB with 128B lines */
}
/* PUs */
hwloc_setup_pu_level(topology, HWLOC_BGQ_CORES*4);
}
/* Add BGQ specific information */
hwloc_obj_add_info(topology->levels[0][0], "Backend", "BGQ");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
static int
hwloc_bgq_get_thread_cpubind(hwloc_topology_t topology, pthread_t thread, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
unsigned pu;
cpu_set_t bg_set;
int err;
if (topology->pid) {
errno = ENOSYS;
return -1;
}
err = pthread_getaffinity_np(thread, sizeof(bg_set), &bg_set);
if (err) {
errno = err;
return -1;
}
for(pu=0; pu<64; pu++)
if (CPU_ISSET(pu, &bg_set)) {
/* the binding cannot contain multiple PUs */
hwloc_bitmap_only(hwloc_set, pu);
break;
}
return 0;
}
static int
hwloc_bgq_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
if (topology->pid) {
errno = ENOSYS;
return -1;
}
hwloc_bitmap_only(hwloc_set, Kernel_ProcessorID());
return 0;
}
static int
hwloc_bgq_set_thread_cpubind(hwloc_topology_t topology, pthread_t thread, hwloc_const_bitmap_t hwloc_set, int flags)
{
unsigned pu;
cpu_set_t bg_set;
int err;
if (topology->pid) {
errno = ENOSYS;
return -1;
}
/* the binding cannot contain multiple PUs.
* keep the first PU only, and error out if STRICT.
*/
if (hwloc_bitmap_weight(hwloc_set) != 1) {
if ((flags & HWLOC_CPUBIND_STRICT)) {
errno = ENOSYS;
return -1;
}
}
pu = hwloc_bitmap_first(hwloc_set);
CPU_ZERO(&bg_set);
CPU_SET(pu, &bg_set);
err = pthread_setaffinity_np(thread, sizeof(bg_set), &bg_set);
if (err) {
errno = err;
return -1;
}
return 0;
}
static int
hwloc_bgq_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_bgq_set_thread_cpubind(topology, pthread_self(), hwloc_set, flags);
}
void
hwloc_set_bgq_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_thisthread_cpubind = hwloc_bgq_set_thisthread_cpubind;
hooks->set_thread_cpubind = hwloc_bgq_set_thread_cpubind;
hooks->get_thisthread_cpubind = hwloc_bgq_get_thisthread_cpubind;
hooks->get_thread_cpubind = hwloc_bgq_get_thread_cpubind;
/* threads cannot be bound to more than one PU, so get_last_cpu_location == get_cpubind */
hooks->get_thisthread_last_cpu_location = hwloc_bgq_get_thisthread_cpubind;
/* hooks->get_thread_last_cpu_location = hwloc_bgq_get_thread_cpubind; */
}
static struct hwloc_backend *
hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct utsname utsname;
struct hwloc_backend *backend;
char *env;
int err;
env = getenv("HWLOC_FORCE_BGQ");
if (!env || !atoi(env)) {
err = uname(&utsname);
if (err || strcmp(utsname.sysname, "CNK") || strcmp(utsname.machine, "BGQ")) {
fprintf(stderr, "*** Found unexpected uname sysname `%s' machine `%s', disabling BGQ backend.\n", utsname.sysname, utsname.machine);
fprintf(stderr, "*** Set HWLOC_FORCE_BGQ=1 in the environment to enforce the BGQ backend.\n");
return NULL;
}
}
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_bgq;
return backend;
}
static struct hwloc_disc_component hwloc_bgq_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
"bgq",
~0,
hwloc_bgq_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_bgq_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_bgq_disc_component
};

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

@ -0,0 +1,190 @@
/*
* Copyright © 2011 Université Bordeaux 1
* Copyright © 2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
#include <hwloc/cudart.h>
/* private headers allowed for convenience because this plugin is built within hwloc */
#include <private/misc.h>
#include <private/debug.h>
#include <cuda_runtime_api.h>
struct hwloc_cuda_backend_data_s {
unsigned nr_devices; /* -1 when unknown yet, first callback will setup */
struct hwloc_cuda_device_info_s {
int idx;
unsigned pcidomain, pcibus, pcidev, pcifunc;
} * devices;
};
/* query all PCI bus ids for later */
static void
hwloc_cuda_query_devices(struct hwloc_cuda_backend_data_s *data)
{
cudaError_t cures;
int nb, i;
/* mark the number of devices as 0 in case we fail below,
* so that we don't try again later.
*/
data->nr_devices = 0;
cures = cudaGetDeviceCount(&nb);
if (cures)
return;
/* allocate structs */
data->devices = malloc(nb * sizeof(*data->devices));
if (!data->devices)
return;
for (i = 0; i < nb; i++) {
struct hwloc_cuda_device_info_s *info = &data->devices[data->nr_devices];
int domain, bus, dev;
if (hwloc_cudart_get_device_pci_ids(NULL /* topology unused */, i, &domain, &bus, &dev))
continue;
info->idx = i;
info->pcidomain = (unsigned) domain;
info->pcibus = (unsigned) bus;
info->pcidev = (unsigned) dev;
info->pcifunc = 0;
/* validate this device */
data->nr_devices++;
}
return;
}
static int
hwloc_cuda_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc_backend *caller __hwloc_attribute_unused,
struct hwloc_obj *pcidev)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_cuda_backend_data_s *data = backend->private_data;
unsigned i;
if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
return 0;
if (!hwloc_topology_is_thissystem(topology)) {
hwloc_debug("%s", "\nno CUDA detection (not thissystem)\n");
return 0;
}
if (HWLOC_OBJ_PCI_DEVICE != pcidev->type)
return 0;
if (data->nr_devices == (unsigned) -1) {
/* first call, lookup all devices */
hwloc_cuda_query_devices(data);
/* if it fails, data->nr_devices = 0 so we won't do anything below and in next callbacks */
}
if (!data->nr_devices)
/* found no devices */
return 0;
for(i=0; i<data->nr_devices; i++) {
struct hwloc_cuda_device_info_s *info = &data->devices[i];
char cuda_name[32];
struct cudaDeviceProp prop;
hwloc_obj_t cuda_device;
cudaError_t cures;
if (info->pcidomain != pcidev->attr->pcidev.domain)
continue;
if (info->pcibus != pcidev->attr->pcidev.bus)
continue;
if (info->pcidev != pcidev->attr->pcidev.dev)
continue;
if (info->pcifunc != pcidev->attr->pcidev.func)
continue;
cuda_device = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1);
snprintf(cuda_name, sizeof(cuda_name), "cuda%d", info->idx);
cuda_device->name = strdup(cuda_name);
cuda_device->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN;
cuda_device->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC;
hwloc_obj_add_info(cuda_device, "CoProcType", "CUDA");
hwloc_obj_add_info(cuda_device, "Backend", "CUDA");
hwloc_obj_add_info(cuda_device, "GPUVendor", "NVIDIA Corporation");
cures = cudaGetDeviceProperties(&prop, info->idx);
if (!cures)
hwloc_obj_add_info(cuda_device, "GPUModel", prop.name);
hwloc_insert_object_by_parent(topology, pcidev, cuda_device);
return 1;
}
return 0;
}
static void
hwloc_cuda_backend_disable(struct hwloc_backend *backend)
{
struct hwloc_cuda_backend_data_s *data = backend->private_data;
free(data->devices);
free(data);
}
static struct hwloc_backend *
hwloc_cuda_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
struct hwloc_cuda_backend_data_s *data;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
data = malloc(sizeof(*data));
if (!data) {
free(backend);
return NULL;
}
/* the first callback will initialize those */
data->nr_devices = (unsigned) -1; /* unknown yet */
data->devices = NULL;
backend->private_data = data;
backend->disable = hwloc_cuda_backend_disable;
backend->notify_new_object = hwloc_cuda_backend_notify_new_object;
return backend;
}
static struct hwloc_disc_component hwloc_cuda_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_MISC,
"cuda",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_cuda_component_instantiate,
10, /* after pci */
NULL
};
#ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_cuda_component;
#endif
const struct hwloc_component hwloc_cuda_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_cuda_disc_component
};

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

@ -0,0 +1,96 @@
/*
* Copyright © 2011-2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
hwloc_obj_t
hwloc_custom_insert_group_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, int groupdepth)
{
hwloc_obj_t obj;
/* must be called between set_custom() and load(), so there's a single backend, the custom one */
if (topology->is_loaded || !topology->backends || !topology->backends->is_custom) {
errno = EINVAL;
return NULL;
}
obj = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, -1);
obj->attr->group.depth = groupdepth;
hwloc_insert_object_by_parent(topology, parent, obj);
/* insert_object_by_parent() doesn't merge during insert, so obj is still valid */
return obj;
}
int
hwloc_custom_insert_topology(struct hwloc_topology *newtopology,
struct hwloc_obj *newparent,
struct hwloc_topology *oldtopology,
struct hwloc_obj *oldroot)
{
/* must be called between set_custom() and load(), so there's a single backend, the custom one */
if (newtopology->is_loaded || !newtopology->backends || !newtopology->backends->is_custom) {
errno = EINVAL;
return -1;
}
if (!oldtopology->is_loaded) {
errno = EINVAL;
return -1;
}
hwloc__duplicate_objects(newtopology, newparent, oldroot ? oldroot : oldtopology->levels[0][0]);
return 0;
}
static int
hwloc_look_custom(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
assert(!topology->levels[0][0]->cpuset);
if (!topology->levels[0][0]->first_child) {
errno = EINVAL;
return -1;
}
topology->levels[0][0]->type = HWLOC_OBJ_SYSTEM;
return 1;
}
static struct hwloc_backend *
hwloc_custom_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_custom;
backend->is_custom = 1;
backend->is_thissystem = 0;
return backend;
}
static struct hwloc_disc_component hwloc_custom_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
"custom",
~0,
hwloc_custom_component_instantiate,
30,
NULL
};
const struct hwloc_component hwloc_custom_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_custom_disc_component
};

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

@ -0,0 +1,306 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2013 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* Detect topology change: registering for power management changes and check
* if for example hw.activecpu changed */
/* Apparently, Darwin people do not _want_ to provide binding functions. */
#include <private/autogen/config.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdlib.h>
#include <inttypes.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
static int
hwloc_look_darwin(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
int64_t _nprocs;
unsigned nprocs;
int64_t _npackages;
unsigned i, j, cpu;
struct hwloc_obj *obj;
size_t size;
int64_t l1dcachesize, l1icachesize;
int64_t cacheways[2];
int64_t l2cachesize;
int64_t cachelinesize;
int64_t memsize;
char cpumodel[64];
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
if (hwloc_get_sysctlbyname("hw.ncpu", &_nprocs) || _nprocs <= 0)
return -1;
nprocs = _nprocs;
topology->support.discovery->pu = 1;
hwloc_debug("%u procs\n", nprocs);
size = sizeof(cpumodel);
if (sysctlbyname("machdep.cpu.brand_string", cpumodel, &size, NULL, 0))
cpumodel[0] = '\0';
if (!hwloc_get_sysctlbyname("hw.packages", &_npackages) && _npackages > 0) {
unsigned npackages = _npackages;
int64_t _cores_per_package;
int64_t _logical_per_package;
unsigned logical_per_package;
hwloc_debug("%u packages\n", npackages);
if (!hwloc_get_sysctlbyname("machdep.cpu.logical_per_package", &_logical_per_package) && _logical_per_package > 0)
logical_per_package = _logical_per_package;
else
/* Assume the trivia. */
logical_per_package = nprocs / npackages;
hwloc_debug("%u threads per package\n", logical_per_package);
if (nprocs == npackages * logical_per_package)
for (i = 0; i < npackages; i++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, i);
obj->cpuset = hwloc_bitmap_alloc();
for (cpu = i*logical_per_package; cpu < (i+1)*logical_per_package; cpu++)
hwloc_bitmap_set(obj->cpuset, cpu);
hwloc_debug_1arg_bitmap("package %u has cpuset %s\n",
i, obj->cpuset);
if (cpumodel[0] != '\0')
hwloc_obj_add_info(obj, "CPUModel", cpumodel);
hwloc_insert_object_by_cpuset(topology, obj);
}
else
if (cpumodel[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUModel", cpumodel);
if (!hwloc_get_sysctlbyname("machdep.cpu.cores_per_package", &_cores_per_package) && _cores_per_package > 0) {
unsigned cores_per_package = _cores_per_package;
hwloc_debug("%u cores per package\n", cores_per_package);
if (!(logical_per_package % cores_per_package))
for (i = 0; i < npackages * cores_per_package; i++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_CORE, i);
obj->cpuset = hwloc_bitmap_alloc();
for (cpu = i*(logical_per_package/cores_per_package);
cpu < (i+1)*(logical_per_package/cores_per_package);
cpu++)
hwloc_bitmap_set(obj->cpuset, cpu);
hwloc_debug_1arg_bitmap("core %u has cpuset %s\n",
i, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
}
} else
if (cpumodel[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUModel", cpumodel);
if (hwloc_get_sysctlbyname("hw.l1dcachesize", &l1dcachesize))
l1dcachesize = 0;
if (hwloc_get_sysctlbyname("hw.l1icachesize", &l1icachesize))
l1icachesize = 0;
if (hwloc_get_sysctlbyname("hw.l2cachesize", &l2cachesize))
l2cachesize = 0;
if (hwloc_get_sysctlbyname("machdep.cpu.cache.L1_associativity", &cacheways[0]))
cacheways[0] = 0;
else if (cacheways[0] == 0xff)
cacheways[0] = -1;
if (hwloc_get_sysctlbyname("machdep.cpu.cache.L2_associativity", &cacheways[1]))
cacheways[1] = 0;
else if (cacheways[1] == 0xff)
cacheways[1] = -1;
if (hwloc_get_sysctlbyname("hw.cachelinesize", &cachelinesize))
cachelinesize = 0;
if (hwloc_get_sysctlbyname("hw.memsize", &memsize))
memsize = 0;
if (!sysctlbyname("hw.cacheconfig", NULL, &size, NULL, 0)) {
unsigned n = size / sizeof(uint32_t);
uint64_t *cacheconfig = NULL;
uint64_t *cachesize = NULL;
uint32_t *cacheconfig32 = NULL;
cacheconfig = malloc(sizeof(uint64_t) * n);
if (NULL == cacheconfig) {
goto out;
}
cachesize = malloc(sizeof(uint64_t) * n);
if (NULL == cachesize) {
goto out;
}
cacheconfig32 = malloc(sizeof(uint32_t) * n);
if (NULL == cacheconfig32) {
goto out;
}
if ((!sysctlbyname("hw.cacheconfig", cacheconfig, &size, NULL, 0))) {
/* Yeech. Darwin seemingly has changed from 32bit to 64bit integers for
* cacheconfig, with apparently no way for detection. Assume the machine
* won't have more than 4 billion cpus */
if (cacheconfig[0] > 0xFFFFFFFFUL) {
memcpy(cacheconfig32, cacheconfig, size);
for (i = 0 ; i < size / sizeof(uint32_t); i++)
cacheconfig[i] = cacheconfig32[i];
}
memset(cachesize, 0, sizeof(uint64_t) * n);
size = sizeof(uint64_t) * n;
if (sysctlbyname("hw.cachesize", cachesize, &size, NULL, 0)) {
if (n > 0)
cachesize[0] = memsize;
if (n > 1)
cachesize[1] = l1dcachesize;
if (n > 2)
cachesize[2] = l2cachesize;
}
hwloc_debug("%s", "caches");
for (i = 0; i < n && cacheconfig[i]; i++)
hwloc_debug(" %"PRIu64"(%"PRIu64"kB)", cacheconfig[i], cachesize[i] / 1024);
/* Now we know how many caches there are */
n = i;
hwloc_debug("\n%u cache levels\n", n - 1);
/* For each cache level (0 is memory) */
for (i = 0; i < n; i++) {
/* cacheconfig tells us how many cpus share it, let's iterate on each cache */
for (j = 0; j < (nprocs / cacheconfig[i]); j++) {
obj = hwloc_alloc_setup_object(i?HWLOC_OBJ_CACHE:HWLOC_OBJ_NODE, j);
if (!i) {
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, j);
}
obj->cpuset = hwloc_bitmap_alloc();
for (cpu = j*cacheconfig[i];
cpu < ((j+1)*cacheconfig[i]);
cpu++)
hwloc_bitmap_set(obj->cpuset, cpu);
if (i == 1 && l1icachesize) {
/* FIXME assuming that L1i and L1d are shared the same way. Darwin
* does not yet provide a way to know. */
hwloc_obj_t l1i = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, j);
l1i->cpuset = hwloc_bitmap_dup(obj->cpuset);
hwloc_debug_1arg_bitmap("L1icache %u has cpuset %s\n",
j, l1i->cpuset);
l1i->attr->cache.depth = i;
l1i->attr->cache.size = l1icachesize;
l1i->attr->cache.linesize = cachelinesize;
l1i->attr->cache.associativity = 0;
l1i->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
hwloc_insert_object_by_cpuset(topology, l1i);
}
if (i) {
hwloc_debug_2args_bitmap("L%ucache %u has cpuset %s\n",
i, j, obj->cpuset);
obj->attr->cache.depth = i;
obj->attr->cache.size = cachesize[i];
obj->attr->cache.linesize = cachelinesize;
if (i <= sizeof(cacheways) / sizeof(cacheways[0]))
obj->attr->cache.associativity = cacheways[i-1];
else
obj->attr->cache.associativity = 0;
if (i == 1 && l1icachesize)
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
else
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
} else {
hwloc_debug_1arg_bitmap("node %u has cpuset %s\n",
j, obj->cpuset);
obj->memory.local_memory = cachesize[i];
obj->memory.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize();
#ifdef HAVE__SC_LARGE_PAGESIZE
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
}
hwloc_insert_object_by_cpuset(topology, obj);
}
}
}
out:
if (NULL != cacheconfig) {
free(cacheconfig);
}
if (NULL != cachesize) {
free(cachesize);
}
if (NULL != cacheconfig32) {
free(cacheconfig32);
}
}
/* add PU objects */
hwloc_setup_pu_level(topology, nprocs);
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Darwin");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_darwin_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
}
static struct hwloc_backend *
hwloc_darwin_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_darwin;
return backend;
}
static struct hwloc_disc_component hwloc_darwin_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"darwin",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_darwin_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_darwin_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_darwin_disc_component
};

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

@ -0,0 +1,39 @@
/*
* Copyright © 2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <stdlib.h>
static struct hwloc_backend *
hwloc_fake_component_instantiate(struct hwloc_disc_component *component __hwloc_attribute_unused,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component instantiated\n");
return NULL;
}
static struct hwloc_disc_component hwloc_fake_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_MISC, /* so that it's always enabled when using the OS discovery */
"fake",
0, /* nothing to exclude */
hwloc_fake_component_instantiate,
100, /* make sure it's loaded before anything conflicting excludes it */
NULL
};
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_fake_component; /* never linked statically in the core */
const struct hwloc_component hwloc_fake_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_fake_disc_component
};

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

@ -0,0 +1,250 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <sys/types.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/param.h>
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
#ifdef HAVE_SYS_CPUSET_H
#include <sys/cpuset.h>
#endif
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#if defined(HAVE_SYS_CPUSET_H) && defined(HAVE_CPUSET_SETAFFINITY)
static void
hwloc_freebsd_bsd2hwloc(hwloc_bitmap_t hwloc_cpuset, const cpuset_t *cset)
{
unsigned cpu;
hwloc_bitmap_zero(hwloc_cpuset);
for (cpu = 0; cpu < CPU_SETSIZE; cpu++)
if (CPU_ISSET(cpu, cset))
hwloc_bitmap_set(hwloc_cpuset, cpu);
}
static void
hwloc_freebsd_hwloc2bsd(hwloc_const_bitmap_t hwloc_cpuset, cpuset_t *cset)
{
unsigned cpu;
CPU_ZERO(cset);
for (cpu = 0; cpu < CPU_SETSIZE; cpu++)
if (hwloc_bitmap_isset(hwloc_cpuset, cpu))
CPU_SET(cpu, cset);
}
static int
hwloc_freebsd_set_sth_affinity(hwloc_topology_t topology __hwloc_attribute_unused, cpulevel_t level, cpuwhich_t which, id_t id, hwloc_const_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
cpuset_t cset;
hwloc_freebsd_hwloc2bsd(hwloc_cpuset, &cset);
if (cpuset_setaffinity(level, which, id, sizeof(cset), &cset))
return -1;
return 0;
}
static int
hwloc_freebsd_get_sth_affinity(hwloc_topology_t topology __hwloc_attribute_unused, cpulevel_t level, cpuwhich_t which, id_t id, hwloc_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
cpuset_t cset;
if (cpuset_getaffinity(level, which, id, sizeof(cset), &cset))
return -1;
hwloc_freebsd_bsd2hwloc(hwloc_cpuset, &cset);
return 0;
}
static int
hwloc_freebsd_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_freebsd_set_sth_affinity(topology, CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, hwloc_cpuset, flags);
}
static int
hwloc_freebsd_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_freebsd_get_sth_affinity(topology, CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, hwloc_cpuset, flags);
}
static int
hwloc_freebsd_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_freebsd_set_sth_affinity(topology, CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, hwloc_cpuset, flags);
}
static int
hwloc_freebsd_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_freebsd_get_sth_affinity(topology, CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, hwloc_cpuset, flags);
}
static int
hwloc_freebsd_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_freebsd_set_sth_affinity(topology, CPU_LEVEL_WHICH, CPU_WHICH_PID, pid, hwloc_cpuset, flags);
}
static int
hwloc_freebsd_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_freebsd_get_sth_affinity(topology, CPU_LEVEL_WHICH, CPU_WHICH_PID, pid, hwloc_cpuset, flags);
}
#ifdef hwloc_thread_t
#if HAVE_DECL_PTHREAD_SETAFFINITY_NP
#pragma weak pthread_setaffinity_np
static int
hwloc_freebsd_set_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid, hwloc_const_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int err;
cpuset_t cset;
if (!pthread_setaffinity_np) {
errno = ENOSYS;
return -1;
}
hwloc_freebsd_hwloc2bsd(hwloc_cpuset, &cset);
err = pthread_setaffinity_np(tid, sizeof(cset), &cset);
if (err) {
errno = err;
return -1;
}
return 0;
}
#endif
#if HAVE_DECL_PTHREAD_GETAFFINITY_NP
#pragma weak pthread_getaffinity_np
static int
hwloc_freebsd_get_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid, hwloc_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int err;
cpuset_t cset;
if (!pthread_getaffinity_np) {
errno = ENOSYS;
return -1;
}
err = pthread_getaffinity_np(tid, sizeof(cset), &cset);
if (err) {
errno = err;
return -1;
}
hwloc_freebsd_bsd2hwloc(hwloc_cpuset, &cset);
return 0;
}
#endif
#endif
#endif
#if (defined HAVE_SYSCTL) && (defined HAVE_SYS_SYSCTL_H)
static void
hwloc_freebsd_node_meminfo_info(struct hwloc_topology *topology)
{
int mib[2] = { CTL_HW, HW_PHYSMEM };
size_t len = sizeof(topology->levels[0][0]->memory.local_memory);
sysctl(mib, 2, &topology->levels[0][0]->memory.local_memory, &len, NULL, 0);
}
#endif
static int
hwloc_look_freebsd(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->levels[0][0]->cpuset) {
/* Nobody (even the x86 backend) created objects yet, setup basic objects */
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs);
}
/* Add FreeBSD specific information */
#if (defined HAVE_SYSCTL) && (defined HAVE_SYS_SYSCTL_H)
hwloc_freebsd_node_meminfo_info(topology);
#endif
hwloc_obj_add_info(topology->levels[0][0], "Backend", "FreeBSD");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
#if defined(HAVE_SYS_CPUSET_H) && defined(HAVE_CPUSET_SETAFFINITY)
hooks->set_thisproc_cpubind = hwloc_freebsd_set_thisproc_cpubind;
hooks->get_thisproc_cpubind = hwloc_freebsd_get_thisproc_cpubind;
hooks->set_thisthread_cpubind = hwloc_freebsd_set_thisthread_cpubind;
hooks->get_thisthread_cpubind = hwloc_freebsd_get_thisthread_cpubind;
hooks->set_proc_cpubind = hwloc_freebsd_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_freebsd_get_proc_cpubind;
#ifdef hwloc_thread_t
#if HAVE_DECL_PTHREAD_SETAFFINITY_NP
hooks->set_thread_cpubind = hwloc_freebsd_set_thread_cpubind;
#endif
#if HAVE_DECL_PTHREAD_GETAFFINITY_NP
hooks->get_thread_cpubind = hwloc_freebsd_get_thread_cpubind;
#endif
#endif
#endif
/* TODO: get_last_cpu_location: find out ki_lastcpu */
}
static struct hwloc_backend *
hwloc_freebsd_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_freebsd;
return backend;
}
static struct hwloc_disc_component hwloc_freebsd_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"freebsd",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_freebsd_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_freebsd_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_freebsd_disc_component
};

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

@ -0,0 +1,260 @@
/*
* Copyright © 2012-2013 Blue Brain Project, BBP/EPFL. All rights reserved.
* Copyright © 2012-2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
/* private headers allowed for convenience because this plugin is built within hwloc */
#include <private/misc.h>
#include <private/debug.h>
#include <stdarg.h>
#include <errno.h>
#include <X11/Xlib.h>
#include <NVCtrl/NVCtrl.h>
#include <NVCtrl/NVCtrlLib.h>
#define HWLOC_GL_SERVER_MAX 10
#define HWLOC_GL_SCREEN_MAX 10
struct hwloc_gl_backend_data_s {
unsigned nr_display;
struct hwloc_gl_display_info_s {
char name[10];
unsigned port, device;
unsigned pcidomain, pcibus, pcidevice, pcifunc;
char *productname;
} display[HWLOC_GL_SERVER_MAX*HWLOC_GL_SCREEN_MAX];
};
static void
hwloc_gl_query_devices(struct hwloc_gl_backend_data_s *data)
{
int err;
unsigned i,j;
/* mark the number of display as 0 in case we fail below,
* so that we don't try again later.
*/
data->nr_display = 0;
for (i = 0; i < HWLOC_GL_SERVER_MAX; ++i) {
Display* display;
char displayName[10];
int opcode, event, error;
/* open X server */
snprintf(displayName, sizeof(displayName), ":%u", i);
display = XOpenDisplay(displayName);
if (!display)
continue;
/* Check for NV-CONTROL extension (it's per server) */
if(!XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error)) {
XCloseDisplay(display);
continue;
}
for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
struct hwloc_gl_display_info_s *info = &data->display[data->nr_display];
const int screen = j;
unsigned int *ptr_binary_data;
int data_length;
int gpu_number;
int nv_ctrl_pci_bus;
int nv_ctrl_pci_device;
int nv_ctrl_pci_domain;
int nv_ctrl_pci_func;
char *productname;
/* the server supports NV-CONTROL but it may contain non-NVIDIA screen that don't support it */
if (!XNVCTRLIsNvScreen(display, screen))
continue;
/* Gets the GPU number attached to the default screen. */
/* For further details, see the <NVCtrl/NVCtrlLib.h> */
err = XNVCTRLQueryTargetBinaryData (display, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
(unsigned char **) &ptr_binary_data, &data_length);
if (!err)
continue;
gpu_number = ptr_binary_data[1];
free(ptr_binary_data);
#ifdef NV_CTRL_PCI_DOMAIN
/* Gets the ID's of the GPU defined by gpu_number
* For further details, see the <NVCtrl/NVCtrlLib.h> */
err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
NV_CTRL_PCI_DOMAIN, &nv_ctrl_pci_domain);
if (!err)
continue;
#else
nv_ctrl_pci_domain = 0;
#endif
err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
NV_CTRL_PCI_BUS, &nv_ctrl_pci_bus);
if (!err)
continue;
err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
NV_CTRL_PCI_DEVICE, &nv_ctrl_pci_device);
if (!err)
continue;
err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
NV_CTRL_PCI_FUNCTION, &nv_ctrl_pci_func);
if (!err)
continue;
productname = NULL;
err = XNVCTRLQueryTargetStringAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
NV_CTRL_STRING_PRODUCT_NAME, &productname);
snprintf(info->name, sizeof(info->name), ":%u.%u", i, j);
info->port = i;
info->device = j;
info->pcidomain = nv_ctrl_pci_domain;
info->pcibus = nv_ctrl_pci_bus;
info->pcidevice = nv_ctrl_pci_device;
info->pcifunc = nv_ctrl_pci_func;
info->productname = productname;
hwloc_debug("GL device %s (product %s) on PCI 0000:%02x:%02x.%u\n", info->name, productname,
nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
/* validate this device */
data->nr_display++;
}
XCloseDisplay(display);
}
}
static int
hwloc_gl_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc_backend *caller __hwloc_attribute_unused,
struct hwloc_obj *pcidev)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_gl_backend_data_s *data = backend->private_data;
unsigned i, res;
if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
return 0;
if (!hwloc_topology_is_thissystem(topology)) {
hwloc_debug("%s", "\nno GL detection (not thissystem)\n");
return 0;
}
if (HWLOC_OBJ_PCI_DEVICE != pcidev->type)
return 0;
if (data->nr_display == (unsigned) -1) {
/* first call, lookup all display */
hwloc_gl_query_devices(data);
/* if it fails, data->nr_display = 0 so we won't do anything below and in next callbacks */
}
if (!data->nr_display)
/* found no display */
return 0;
/* now the display array is ready to use */
res = 0;
for(i=0; i<data->nr_display; i++) {
struct hwloc_gl_display_info_s *info = &data->display[i];
hwloc_obj_t osdev;
if (info->pcidomain != pcidev->attr->pcidev.domain)
continue;
if (info->pcibus != pcidev->attr->pcidev.bus)
continue;
if (info->pcidevice != pcidev->attr->pcidev.dev)
continue;
if (info->pcifunc != pcidev->attr->pcidev.func)
continue;
osdev = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1);
osdev->name = strdup(info->name);
osdev->logical_index = -1;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
hwloc_obj_add_info(osdev, "Backend", "GL");
hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
if (info->productname)
hwloc_obj_add_info(osdev, "GPUModel", info->productname);
hwloc_insert_object_by_parent(topology, pcidev, osdev);
res++;
/* there may be others */
}
return res;
}
static void
hwloc_gl_backend_disable(struct hwloc_backend *backend)
{
struct hwloc_gl_backend_data_s *data = backend->private_data;
unsigned i;
if (data->nr_display != (unsigned) -1) { /* could be -1 if --no-io */
for(i=0; i<data->nr_display; i++) {
struct hwloc_gl_display_info_s *info = &data->display[i];
free(info->productname);
}
}
free(backend->private_data);
}
static struct hwloc_backend *
hwloc_gl_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
struct hwloc_gl_backend_data_s *data;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
data = malloc(sizeof(*data));
if (!data) {
free(backend);
return NULL;
}
/* the first callback will initialize those */
data->nr_display = (unsigned) -1; /* unknown yet */
backend->private_data = data;
backend->disable = hwloc_gl_backend_disable;
backend->notify_new_object = hwloc_gl_backend_notify_new_object;
return backend;
}
static struct hwloc_disc_component hwloc_gl_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_MISC,
"gl",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_gl_component_instantiate,
10, /* after pci */
NULL
};
#ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component;
#endif
const struct hwloc_component hwloc_gl_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_gl_disc_component
};

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

@ -0,0 +1,302 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2010, 2013 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* TODO: psets? (Only for root)
* since 11i 1.6:
_SC_PSET_SUPPORT
pset_create/destroy/assign/setattr
pset_ctl/getattr
pset_bind()
pthread_pset_bind_np()
*/
#include <private/autogen/config.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#include <sys/mpctl.h>
#include <sys/mman.h>
#include <pthread.h>
static ldom_t
hwloc_hpux_find_ldom(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set)
{
int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1;
hwloc_obj_t obj;
if (!has_numa)
return -1;
obj = hwloc_get_first_largest_obj_inside_cpuset(topology, hwloc_set);
if (!hwloc_bitmap_isequal(obj->cpuset, hwloc_set) || obj->type != HWLOC_OBJ_NODE) {
/* Does not correspond to exactly one node */
return -1;
}
return obj->os_index;
}
static spu_t
hwloc_hpux_find_spu(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t hwloc_set)
{
spu_t cpu;
cpu = hwloc_bitmap_first(hwloc_set);
if (cpu != -1 && hwloc_bitmap_weight(hwloc_set) == 1)
return cpu;
return -1;
}
/* Note: get_cpubind not available on HP-UX */
static int
hwloc_hpux_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags)
{
ldom_t ldom;
spu_t cpu;
/* Drop previous binding */
mpctl(MPC_SETLDOM, MPC_LDOMFLOAT, pid);
mpctl(MPC_SETPROCESS, MPC_SPUFLOAT, pid);
if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology)))
return 0;
ldom = hwloc_hpux_find_ldom(topology, hwloc_set);
if (ldom != -1)
return mpctl(MPC_SETLDOM, ldom, pid);
cpu = hwloc_hpux_find_spu(topology, hwloc_set);
if (cpu != -1)
return mpctl(flags & HWLOC_CPUBIND_STRICT ? MPC_SETPROCESS_FORCE : MPC_SETPROCESS, cpu, pid);
errno = EXDEV;
return -1;
}
static int
hwloc_hpux_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_hpux_set_proc_cpubind(topology, MPC_SELFPID, hwloc_set, flags);
}
#ifdef hwloc_thread_t
static int
hwloc_hpux_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_const_bitmap_t hwloc_set, int flags)
{
ldom_t ldom, ldom2;
spu_t cpu, cpu2;
/* Drop previous binding */
pthread_ldom_bind_np(&ldom2, PTHREAD_LDOMFLOAT_NP, pthread);
pthread_processor_bind_np(PTHREAD_BIND_ADVISORY_NP, &cpu2, PTHREAD_SPUFLOAT_NP, pthread);
if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology)))
return 0;
ldom = hwloc_hpux_find_ldom(topology, hwloc_set);
if (ldom != -1)
return pthread_ldom_bind_np(&ldom2, ldom, pthread);
cpu = hwloc_hpux_find_spu(topology, hwloc_set);
if (cpu != -1)
return pthread_processor_bind_np(flags & HWLOC_CPUBIND_STRICT ? PTHREAD_BIND_FORCED_NP : PTHREAD_BIND_ADVISORY_NP, &cpu2, cpu, pthread);
errno = EXDEV;
return -1;
}
static int
hwloc_hpux_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_hpux_set_thread_cpubind(topology, PTHREAD_SELFTID_NP, hwloc_set, flags);
}
#endif
/* According to HP docs, HP-UX up to 11iv2 don't support migration */
#ifdef MAP_MEM_FIRST_TOUCH
static void*
hwloc_hpux_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
int mmap_flags;
/* Can not give a set of nodes. */
if (!hwloc_bitmap_isequal(nodeset, hwloc_topology_get_complete_nodeset(topology))) {
errno = EXDEV;
return hwloc_alloc_or_fail(topology, len, flags);
}
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
mmap_flags = 0;
break;
case HWLOC_MEMBIND_FIRSTTOUCH:
mmap_flags = MAP_MEM_FIRST_TOUCH;
break;
case HWLOC_MEMBIND_INTERLEAVE:
mmap_flags = MAP_MEM_INTERLEAVED;
break;
default:
errno = ENOSYS;
return NULL;
}
return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | mmap_flags, -1, 0);
}
#endif /* MAP_MEM_FIRST_TOUCH */
static int
hwloc_look_hpux(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1;
hwloc_obj_t *nodes = NULL, obj;
spu_t currentcpu;
ldom_t currentnode;
int i, nbnodes = 0;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
if (has_numa) {
nbnodes = mpctl(topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM ?
MPC_GETNUMLDOMS_SYS : MPC_GETNUMLDOMS, 0, 0);
hwloc_debug("%d nodes\n", nbnodes);
nodes = malloc(nbnodes * sizeof(*nodes));
i = 0;
currentnode = mpctl(topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM ?
MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0);
while (currentnode != -1 && i < nbnodes) {
hwloc_debug("node %d is %d\n", i, currentnode);
nodes[i] = obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, currentnode);
obj->cpuset = hwloc_bitmap_alloc();
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, currentnode);
/* TODO: obj->attr->node.memory_kB */
/* TODO: obj->attr->node.huge_page_free */
currentnode = mpctl(topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM ?
MPC_GETNEXTLDOM_SYS : MPC_GETNEXTLDOM, currentnode, 0);
i++;
}
}
i = 0;
currentcpu = mpctl(topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM ?
MPC_GETFIRSTSPU_SYS : MPC_GETFIRSTSPU, 0,0);
while (currentcpu != -1) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_PU, currentcpu);
obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->cpuset, currentcpu);
hwloc_debug("cpu %d\n", currentcpu);
if (nodes) {
/* Add this cpu to its node */
currentnode = mpctl(MPC_SPUTOLDOM, currentcpu, 0);
/* Hopefully it's just the same as previous cpu */
if (i >= nbnodes || (ldom_t) nodes[i]->os_index != currentnode)
for (i = 0; i < nbnodes; i++)
if ((ldom_t) nodes[i]->os_index == currentnode)
break;
if (i < nbnodes) {
hwloc_bitmap_set(nodes[i]->cpuset, currentcpu);
hwloc_debug("is in node %d\n", i);
} else {
hwloc_debug("%s", "is in no node?!\n");
}
}
/* Add cpu */
hwloc_insert_object_by_cpuset(topology, obj);
currentcpu = mpctl(topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM ?
MPC_GETNEXTSPU_SYS : MPC_GETNEXTSPU, currentcpu, 0);
}
if (nodes) {
/* Add nodes */
for (i = 0 ; i < nbnodes ; i++)
hwloc_insert_object_by_cpuset(topology, nodes[i]);
free(nodes);
}
topology->support.discovery->pu = 1;
hwloc_obj_add_info(topology->levels[0][0], "Backend", "HP-UX");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_hpux_set_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_hpux_set_thisproc_cpubind;
#ifdef hwloc_thread_t
hooks->set_thread_cpubind = hwloc_hpux_set_thread_cpubind;
hooks->set_thisthread_cpubind = hwloc_hpux_set_thisthread_cpubind;
#endif
#ifdef MAP_MEM_FIRST_TOUCH
hooks->alloc_membind = hwloc_hpux_alloc_membind;
hooks->alloc = hwloc_alloc_mmap;
hooks->free_membind = hwloc_free_mmap;
support->membind->firsttouch_membind = 1;
support->membind->bind_membind = 1;
support->membind->interleave_membind = 1;
#endif /* MAP_MEM_FIRST_TOUCH */
}
static struct hwloc_backend *
hwloc_hpux_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_hpux;
return backend;
}
static struct hwloc_disc_component hwloc_hpux_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"hpux",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_hpux_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_hpux_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_hpux_disc_component
};

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

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

@ -0,0 +1,197 @@
/*
* Copyright © 2012 Aleksej Saushev, The NetBSD Foundation
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#define _NETBSD_SOURCE /* request "_np" functions */
#include <private/autogen/config.h>
#include <sys/types.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/param.h>
#include <pthread.h>
#include <sched.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
static void
hwloc_netbsd_bsd2hwloc(hwloc_bitmap_t hwloc_cpuset, const cpuset_t *cpuset)
{
unsigned cpu, cpulimit;
int found = 0;
hwloc_bitmap_zero(hwloc_cpuset);
cpulimit = cpuset_size(cpuset) * CHAR_BIT;
for (cpu = 0; cpu < cpulimit; cpu++)
if (cpuset_isset(cpu, cpuset)) {
hwloc_bitmap_set(hwloc_cpuset, cpu);
found++;
}
/* when never bound, it returns an empty set, fill it instead */
if (!found)
hwloc_bitmap_fill(hwloc_cpuset);
}
static void
hwloc_netbsd_hwloc2bsd(hwloc_const_bitmap_t hwloc_cpuset, cpuset_t *cpuset)
{
unsigned cpu, cpulimit;
cpuset_zero(cpuset);
cpulimit = cpuset_size(cpuset) * CHAR_BIT;
for (cpu = 0; cpu < cpulimit; cpu++)
if (hwloc_bitmap_isset(hwloc_cpuset, cpu))
cpuset_set(cpu, cpuset);
}
static int
hwloc_netbsd_set_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
hwloc_netbsd_hwloc2bsd(hwloc_cpuset, cpuset);
status = sched_setaffinity_np(pid, cpuset_size(cpuset), cpuset);
cpuset_destroy(cpuset);
return status;
}
static int
hwloc_netbsd_get_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid, hwloc_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
status = sched_getaffinity_np(pid, cpuset_size(cpuset), cpuset);
hwloc_netbsd_bsd2hwloc(hwloc_cpuset, cpuset);
cpuset_destroy(cpuset);
return status;
}
static int
hwloc_netbsd_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_set_proc_cpubind(topology, 0, hwloc_cpuset, flags);
}
static int
hwloc_netbsd_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_get_proc_cpubind(topology, 0, hwloc_cpuset, flags);
}
static int
hwloc_netbsd_set_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid, hwloc_const_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
hwloc_netbsd_hwloc2bsd(hwloc_cpuset, cpuset);
status = pthread_setaffinity_np(tid, cpuset_size(cpuset), cpuset);
cpuset_destroy(cpuset);
if (status) {
errno = status;
return -1;
}
return 0;
}
static int
hwloc_netbsd_get_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid, hwloc_bitmap_t hwloc_cpuset, int flags __hwloc_attribute_unused)
{
int status;
cpuset_t *cpuset = cpuset_create();
status = pthread_getaffinity_np(tid, cpuset_size(cpuset), cpuset);
hwloc_netbsd_bsd2hwloc(hwloc_cpuset, cpuset);
cpuset_destroy(cpuset);
if (status) {
errno = status;
return -1;
}
return 0;
}
static int
hwloc_netbsd_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_set_thread_cpubind(topology, pthread_self(), hwloc_cpuset, flags);
}
static int
hwloc_netbsd_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_netbsd_get_thread_cpubind(topology, pthread_self(), hwloc_cpuset, flags);
}
static int
hwloc_look_netbsd(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->levels[0][0]->cpuset) {
/* Nobody (even the x86 backend) created objects yet, setup basic objects */
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs);
}
/* Add NetBSD specific information */
hwloc_obj_add_info(topology->levels[0][0], "Backend", "NetBSD");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_netbsd_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_netbsd_get_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_netbsd_set_thisproc_cpubind;
hooks->get_thisproc_cpubind = hwloc_netbsd_get_thisproc_cpubind;
hooks->set_thread_cpubind = hwloc_netbsd_set_thread_cpubind;
hooks->get_thread_cpubind = hwloc_netbsd_get_thread_cpubind;
hooks->set_thisthread_cpubind = hwloc_netbsd_set_thisthread_cpubind;
hooks->get_thisthread_cpubind = hwloc_netbsd_get_thisthread_cpubind;
}
static struct hwloc_backend *
hwloc_netbsd_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_netbsd;
return backend;
}
static struct hwloc_disc_component hwloc_netbsd_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"netbsd",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_netbsd_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_netbsd_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_netbsd_disc_component
};

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

@ -0,0 +1,57 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
static int
hwloc_look_noos(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, hwloc_fallback_nbprocessors(topology));
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
static struct hwloc_backend *
hwloc_noos_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_noos;
return backend;
}
static struct hwloc_disc_component hwloc_noos_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"no_os",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_noos_component_instantiate,
40, /* lower than native OS component, higher than globals */
NULL
};
const struct hwloc_component hwloc_noos_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_noos_disc_component
};

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

@ -0,0 +1,229 @@
/*
* Copyright © 2012 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
/* private headers allowed for convenience because this plugin is built within hwloc */
#include <private/misc.h>
#include <private/debug.h>
#include <nvml.h>
struct hwloc_nvml_backend_data_s {
unsigned nr_devices; /* -1 when unknown yet, first callback will setup */
struct hwloc_nvml_device_info_s {
char name[64];
char serial[64];
char uuid[64];
unsigned pcidomain, pcibus, pcidev, pcifunc;
float maxlinkspeed;
} * devices;
};
static void
hwloc_nvml_query_devices(struct hwloc_nvml_backend_data_s *data)
{
nvmlReturn_t ret;
unsigned nb, i;
/* mark the number of devices as 0 in case we fail below,
* so that we don't try again later.
*/
data->nr_devices = 0;
ret = nvmlInit();
if (NVML_SUCCESS != ret)
goto out;
ret = nvmlDeviceGetCount(&nb);
if (NVML_SUCCESS != ret)
goto out_with_init;
/* allocate structs */
data->devices = malloc(nb * sizeof(*data->devices));
if (!data->devices)
goto out_with_init;
for(i=0; i<nb; i++) {
struct hwloc_nvml_device_info_s *info = &data->devices[data->nr_devices];
nvmlPciInfo_t pci;
nvmlDevice_t device;
ret = nvmlDeviceGetHandleByIndex(i, &device);
assert(ret == NVML_SUCCESS);
ret = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != ret)
continue;
info->pcidomain = pci.domain;
info->pcibus = pci.bus;
info->pcidev = pci.device;
info->pcifunc = 0;
info->name[0] = '\0';
ret = nvmlDeviceGetName(device, info->name, sizeof(info->name));
/* these may fail with NVML_ERROR_NOT_SUPPORTED on old devices */
info->serial[0] = '\0';
ret = nvmlDeviceGetSerial(device, info->serial, sizeof(info->serial));
info->uuid[0] = '\0';
ret = nvmlDeviceGetUUID(device, info->uuid, sizeof(info->uuid));
info->maxlinkspeed = 0.0f;
#if HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION
{
unsigned maxwidth = 0, maxgen = 0;
float lanespeed;
nvmlDeviceGetMaxPcieLinkWidth(device, &maxwidth);
nvmlDeviceGetMaxPcieLinkGeneration(device, &maxgen);
/* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane
* PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane
* PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane
*/
lanespeed = maxgen <= 2 ? 2.5 * maxgen * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */
info->maxlinkspeed = lanespeed * maxwidth / 8; /* GB/s */
}
#endif
/* validate this device */
data->nr_devices++;
}
out_with_init:
nvmlShutdown();
out:
return;
}
static int
hwloc_nvml_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc_backend *caller __hwloc_attribute_unused,
struct hwloc_obj *pcidev)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_nvml_backend_data_s *data = backend->private_data;
unsigned i;
if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
return 0;
if (!hwloc_topology_is_thissystem(topology)) {
hwloc_debug("%s", "\nno NVML detection (not thissystem)\n");
return 0;
}
if (HWLOC_OBJ_PCI_DEVICE != pcidev->type)
return 0;
if (data->nr_devices == (unsigned) -1) {
/* first call, lookup all devices */
hwloc_nvml_query_devices(data);
/* if it fails, data->nr_devices = 0 so we won't do anything below and in next callbacks */
}
if (!data->nr_devices)
/* found no devices */
return 0;
/* now the devices array is ready to use */
for(i=0; i<data->nr_devices; i++) {
struct hwloc_nvml_device_info_s *info = &data->devices[i];
hwloc_obj_t osdev;
char buffer[64];
if (info->pcidomain != pcidev->attr->pcidev.domain)
continue;
if (info->pcibus != pcidev->attr->pcidev.bus)
continue;
if (info->pcidev != pcidev->attr->pcidev.dev)
continue;
if (info->pcifunc != pcidev->attr->pcidev.func)
continue;
osdev = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1);
snprintf(buffer, sizeof(buffer), "nvml%d", i);
osdev->name = strdup(buffer);
osdev->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
hwloc_obj_add_info(osdev, "Backend", "NVML");
hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
hwloc_obj_add_info(osdev, "GPUModel", info->name);
if (info->serial[0] != '\0')
hwloc_obj_add_info(osdev, "NVIDIASerial", info->serial);
if (info->uuid[0] != '\0')
hwloc_obj_add_info(osdev, "NVIDIAUUID", info->uuid);
hwloc_insert_object_by_parent(topology, pcidev, osdev);
if (info->maxlinkspeed != 0.0f)
/* we found the max link speed, replace the current link speed found by pci (or none) */
pcidev->attr->pcidev.linkspeed = info->maxlinkspeed;
return 1;
}
return 0;
}
static void
hwloc_nvml_backend_disable(struct hwloc_backend *backend)
{
struct hwloc_nvml_backend_data_s *data = backend->private_data;
free(data->devices);
free(data);
}
static struct hwloc_backend *
hwloc_nvml_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
struct hwloc_nvml_backend_data_s *data;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
data = malloc(sizeof(*data));
if (!data) {
free(backend);
return NULL;
}
/* the first callback will initialize those */
data->nr_devices = (unsigned) -1; /* unknown yet */
data->devices = NULL;
backend->private_data = data;
backend->disable = hwloc_nvml_backend_disable;
backend->notify_new_object = hwloc_nvml_backend_notify_new_object;
return backend;
}
static struct hwloc_disc_component hwloc_nvml_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_MISC,
"nvml",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_nvml_component_instantiate,
5, /* after pci, and after cuda since likely less useful */
NULL
};
#ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_nvml_component;
#endif
const struct hwloc_component hwloc_nvml_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_nvml_disc_component
};

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

@ -0,0 +1,318 @@
/*
* Copyright © 2012 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux 1. All right reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
/* private headers allowed for convenience because this plugin is built within hwloc */
#include <private/misc.h>
#include <private/debug.h>
#include <CL/cl_ext.h>
typedef enum hwloc_opencl_device_type_e {
HWLOC_OPENCL_DEVICE_AMD
} hwloc_opencl_device_type_t;
struct hwloc_opencl_backend_data_s {
unsigned nr_devices; /* -1 when unknown yet, first callback will setup */
struct hwloc_opencl_device_info_s {
hwloc_opencl_device_type_t type;
unsigned platformidx;
char platformname[64];
unsigned platformdeviceidx;
char devicename[64];
char devicevendor[64];
char devicetype[64];
union hwloc_opencl_device_info_u {
struct hwloc_opencl_device_info_amd_s {
unsigned pcidomain, pcibus, pcidev, pcifunc;
} amd;
} specific;
} * devices;
};
static void
hwloc_opencl_query_devices(struct hwloc_opencl_backend_data_s *data)
{
cl_platform_id *platform_ids = NULL;
cl_uint nr_platforms;
cl_device_id *device_ids = NULL;
cl_uint nr_devices, nr_total_devices, tmp;
cl_int clret;
unsigned curpfidx, curpfdvidx, i;
/* mark the number of devices as 0 in case we fail below,
* so that we don't try again later.
*/
data->nr_devices = 0;
/* count platforms, allocate and get them */
clret = clGetPlatformIDs(0, NULL, &nr_platforms);
if (CL_SUCCESS != clret || !nr_platforms)
goto out;
hwloc_debug("%u OpenCL platforms\n", nr_platforms);
platform_ids = malloc(nr_platforms * sizeof(*platform_ids));
if (!platform_ids)
goto out;
clret = clGetPlatformIDs(nr_platforms, platform_ids, &nr_platforms);
if (CL_SUCCESS != clret || !nr_platforms)
goto out_with_platform_ids;
/* how many devices, total? */
tmp = 0;
for(i=0; i<nr_platforms; i++) {
clret = clGetDeviceIDs(platform_ids[i], CL_DEVICE_TYPE_ALL, 0, NULL, &nr_devices);
if (CL_SUCCESS != clret)
goto out_with_platform_ids;
tmp += nr_devices;
}
nr_total_devices = tmp;
hwloc_debug("%u OpenCL devices total\n", nr_total_devices);
/* allocate structs */
device_ids = malloc(nr_total_devices * sizeof(*device_ids));
data->devices = malloc(nr_total_devices * sizeof(*data->devices));
if (!data->devices || !device_ids)
goto out_with_device_ids;
/* actually query device ids */
tmp = 0;
for(i=0; i<nr_platforms; i++) {
clret = clGetDeviceIDs(platform_ids[i], CL_DEVICE_TYPE_ALL, nr_total_devices - tmp, device_ids + tmp, &nr_devices);
if (CL_SUCCESS != clret)
goto out_with_device_ids;
tmp += nr_devices;
}
/* query individual devices */
curpfidx = 0;
curpfdvidx = 0;
for(i=0; i<nr_total_devices; i++) {
struct hwloc_opencl_device_info_s *info = &data->devices[data->nr_devices];
cl_platform_id platform_id = 0;
cl_device_type type;
#ifdef CL_DEVICE_TOPOLOGY_AMD
cl_device_topology_amd amdtopo;
#endif
hwloc_debug("Looking device %p\n", device_ids[i]);
info->platformname[0] = '\0';
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, NULL);
if (CL_SUCCESS != clret)
continue;
clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(info->platformname), info->platformname, NULL);
info->devicename[0] = '\0';
#ifdef CL_DEVICE_BOARD_NAME_AMD
clGetDeviceInfo(device_ids[i], CL_DEVICE_BOARD_NAME_AMD, sizeof(info->devicename), info->devicename, NULL);
#else
clGetDeviceInfo(device_ids[i], CL_DEVICE_NAME, sizeof(info->devicename), info->devicename, NULL);
#endif
info->devicevendor[0] = '\0';
clGetDeviceInfo(device_ids[i], CL_DEVICE_VENDOR, sizeof(info->devicevendor), info->devicevendor, NULL);
clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
switch (type) {
case CL_DEVICE_TYPE_CPU: /* FIXME: cannot happen in PCI devices? */
strcpy(info->devicetype, "CPU");
break;
case CL_DEVICE_TYPE_GPU:
strcpy(info->devicetype, "GPU");
break;
case CL_DEVICE_TYPE_ACCELERATOR:
strcpy(info->devicetype, "Accelerator");
break;
default:
strcpy(info->devicetype, "Unknown");
break;
}
hwloc_debug("platform %s device %s vendor %s type %s\n", info->platformname, info->devicename, info->devicevendor, info->devicetype);
/* find our indexes */
while (platform_id != platform_ids[curpfidx]) {
curpfidx++;
curpfdvidx = 0;
}
info->platformidx = curpfidx;
info->platformdeviceidx = curpfdvidx;
curpfdvidx++;
hwloc_debug("This is opencl%dd%d\n", info->platformidx, info->platformdeviceidx);
#ifdef CL_DEVICE_TOPOLOGY_AMD
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
hwloc_debug("no AMD-specific device information: %d\n", clret);
continue;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_debug("not a PCIe device: %u\n", amdtopo.raw.type);
continue;
}
info->type = HWLOC_OPENCL_DEVICE_AMD;
info->specific.amd.pcidomain = 0;
info->specific.amd.pcibus = amdtopo.pcie.bus;
info->specific.amd.pcidev = amdtopo.pcie.device;
info->specific.amd.pcifunc = amdtopo.pcie.function;
hwloc_debug("OpenCL device on PCI 0000:%02x:%02x.%u\n", amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function);
/* validate this device */
data->nr_devices++;
#endif /* HAVE_DECL_CL_DEVICE_TOPOLOGY_AMD */
}
free(device_ids);
free(platform_ids);
return;
out_with_device_ids:
free(device_ids);
free(data->devices);
data->devices = NULL;
out_with_platform_ids:
free(platform_ids);
out:
return;
}
static int
hwloc_opencl_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc_backend *caller __hwloc_attribute_unused,
struct hwloc_obj *pcidev)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_opencl_backend_data_s *data = backend->private_data;
unsigned i;
if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
return 0;
if (!hwloc_topology_is_thissystem(topology)) {
hwloc_debug("%s", "\nno OpenCL detection (not thissystem)\n");
return 0;
}
if (HWLOC_OBJ_PCI_DEVICE != pcidev->type)
return 0;
if (data->nr_devices == (unsigned) -1) {
/* first call, lookup all devices */
hwloc_opencl_query_devices(data);
/* if it fails, data->nr_devices = 0 so we won't do anything below and in next callbacks */
}
if (!data->nr_devices)
/* found no devices */
return 0;
/* now the devices array is ready to use */
for(i=0; i<data->nr_devices; i++) {
struct hwloc_opencl_device_info_s *info = &data->devices[i];
hwloc_obj_t osdev;
char buffer[64];
assert(info->type == HWLOC_OPENCL_DEVICE_AMD);
if (info->specific.amd.pcidomain != pcidev->attr->pcidev.domain)
continue;
if (info->specific.amd.pcibus != pcidev->attr->pcidev.bus)
continue;
if (info->specific.amd.pcidev != pcidev->attr->pcidev.dev)
continue;
if (info->specific.amd.pcifunc != pcidev->attr->pcidev.func)
continue;
osdev = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1);
snprintf(buffer, sizeof(buffer), "opencl%dd%d", info->platformidx, info->platformdeviceidx);
osdev->name = strdup(buffer);
osdev->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC;
hwloc_obj_add_info(osdev, "CoProcType", "OpenCL");
hwloc_obj_add_info(osdev, "Backend", "OpenCL");
hwloc_obj_add_info(osdev, "OpenCLDeviceType", info->devicetype);
if (info->devicevendor[0] != '\0')
hwloc_obj_add_info(osdev, "GPUVendor", info->devicevendor);
if (info->devicename[0] != '\0')
hwloc_obj_add_info(osdev, "GPUModel", info->devicename);
snprintf(buffer, sizeof(buffer), "%u", info->platformidx);
hwloc_obj_add_info(osdev, "OpenCLPlatformIndex", buffer);
if (info->platformname[0] != '\0')
hwloc_obj_add_info(osdev, "OpenCLPlatformName", info->platformname);
snprintf(buffer, sizeof(buffer), "%u", info->platformdeviceidx);
hwloc_obj_add_info(osdev, "OpenCLPlatformDeviceIndex", buffer);
hwloc_insert_object_by_parent(topology, pcidev, osdev);
return 1;
}
return 0;
}
static void
hwloc_opencl_backend_disable(struct hwloc_backend *backend)
{
struct hwloc_opencl_backend_data_s *data = backend->private_data;
free(data->devices);
free(data);
}
static struct hwloc_backend *
hwloc_opencl_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
struct hwloc_opencl_backend_data_s *data;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
data = malloc(sizeof(*data));
if (!data) {
free(backend);
return NULL;
}
/* the first callback will initialize those */
data->nr_devices = (unsigned) -1; /* unknown yet */
data->devices = NULL;
backend->private_data = data;
backend->disable = hwloc_opencl_backend_disable;
backend->notify_new_object = hwloc_opencl_backend_notify_new_object;
return backend;
}
static struct hwloc_disc_component hwloc_opencl_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_MISC,
"opencl",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_opencl_component_instantiate,
10, /* after pci */
NULL
};
#ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
#endif
const struct hwloc_component hwloc_opencl_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_opencl_disc_component
};

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

@ -0,0 +1,389 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#include <numa.h>
#include <radset.h>
#include <cpuset.h>
#include <sys/mman.h>
/*
* TODO
*
* nsg_init(), nsg_attach_pid(), RAD_MIGRATE/RAD_WAIT
* assign_pid_to_pset()
*
* pthread_use_only_cpu too?
*/
static int
prepare_radset(hwloc_topology_t topology __hwloc_attribute_unused, radset_t *radset, hwloc_const_bitmap_t hwloc_set)
{
unsigned cpu;
cpuset_t target_cpuset;
cpuset_t cpuset, xor_cpuset;
radid_t radid;
int ret = 0;
int ret_errno = 0;
int nbnodes = rad_get_num();
cpusetcreate(&target_cpuset);
cpuemptyset(target_cpuset);
hwloc_bitmap_foreach_begin(cpu, hwloc_set)
cpuaddset(target_cpuset, cpu);
hwloc_bitmap_foreach_end();
cpusetcreate(&cpuset);
cpusetcreate(&xor_cpuset);
for (radid = 0; radid < nbnodes; radid++) {
cpuemptyset(cpuset);
if (rad_get_cpus(radid, cpuset)==-1) {
fprintf(stderr,"rad_get_cpus(%d) failed: %s\n",radid,strerror(errno));
continue;
}
cpuxorset(target_cpuset, cpuset, xor_cpuset);
if (cpucountset(xor_cpuset) == 0) {
/* Found it */
radsetcreate(radset);
rademptyset(*radset);
radaddset(*radset, radid);
ret = 1;
goto out;
}
}
/* radset containing exactly this set of CPUs not found */
ret_errno = EXDEV;
out:
cpusetdestroy(&target_cpuset);
cpusetdestroy(&cpuset);
cpusetdestroy(&xor_cpuset);
errno = ret_errno;
return ret;
}
/* Note: get_cpubind not available on OSF */
static int
hwloc_osf_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t thread, hwloc_const_bitmap_t hwloc_set, int flags)
{
radset_t radset;
if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) {
if ((errno = pthread_rad_detach(thread)))
return -1;
return 0;
}
/* Apparently OSF migrates pages */
if (flags & HWLOC_CPUBIND_NOMEMBIND) {
errno = ENOSYS;
return -1;
}
if (!prepare_radset(topology, &radset, hwloc_set))
return -1;
if (flags & HWLOC_CPUBIND_STRICT) {
if ((errno = pthread_rad_bind(thread, radset, RAD_INSIST | RAD_WAIT)))
return -1;
} else {
if ((errno = pthread_rad_attach(thread, radset, RAD_WAIT)))
return -1;
}
radsetdestroy(&radset);
return 0;
}
static int
hwloc_osf_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags)
{
radset_t radset;
if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) {
if (rad_detach_pid(pid))
return -1;
return 0;
}
/* Apparently OSF migrates pages */
if (flags & HWLOC_CPUBIND_NOMEMBIND) {
errno = ENOSYS;
return -1;
}
if (!prepare_radset(topology, &radset, hwloc_set))
return -1;
if (flags & HWLOC_CPUBIND_STRICT) {
if (rad_bind_pid(pid, radset, RAD_INSIST | RAD_WAIT))
return -1;
} else {
if (rad_attach_pid(pid, radset, RAD_WAIT))
return -1;
}
radsetdestroy(&radset);
return 0;
}
static int
hwloc_osf_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_osf_set_thread_cpubind(topology, pthread_self(), hwloc_set, flags);
}
static int
hwloc_osf_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_osf_set_proc_cpubind(topology, getpid(), hwloc_set, flags);
}
static int
hwloc_osf_prepare_mattr(hwloc_topology_t topology __hwloc_attribute_unused, memalloc_attr_t *mattr, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags __hwloc_attribute_unused)
{
unsigned long osf_policy;
int node;
switch (policy) {
case HWLOC_MEMBIND_FIRSTTOUCH:
osf_policy = MPOL_THREAD;
break;
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
osf_policy = MPOL_DIRECTED;
break;
case HWLOC_MEMBIND_INTERLEAVE:
osf_policy = MPOL_STRIPPED;
break;
case HWLOC_MEMBIND_REPLICATE:
osf_policy = MPOL_REPLICATED;
break;
default:
errno = ENOSYS;
return -1;
}
memset(mattr, 0, sizeof(*mattr));
mattr->mattr_policy = osf_policy;
mattr->mattr_rad = RAD_NONE;
radsetcreate(&mattr->mattr_radset);
rademptyset(mattr->mattr_radset);
hwloc_bitmap_foreach_begin(node, nodeset)
radaddset(mattr->mattr_radset, node);
hwloc_bitmap_foreach_end();
return 0;
}
static int
hwloc_osf_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)
{
memalloc_attr_t mattr;
int behavior = 0;
int ret;
if (flags & HWLOC_MEMBIND_MIGRATE)
behavior |= MADV_CURRENT;
if (flags & HWLOC_MEMBIND_STRICT)
behavior |= MADV_INSIST;
if (hwloc_osf_prepare_mattr(topology, &mattr, nodeset, policy, flags))
return -1;
ret = nmadvise(addr, len, MADV_CURRENT, &mattr);
radsetdestroy(&mattr.mattr_radset);
return ret;
}
static void *
hwloc_osf_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
memalloc_attr_t mattr;
void *ptr;
if (hwloc_osf_prepare_mattr(topology, &mattr, nodeset, policy, flags))
return hwloc_alloc_or_fail(topology, len, flags);
/* TODO: rather use acreate/amalloc ? */
ptr = nmmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1,
0, &mattr);
radsetdestroy(&mattr.mattr_radset);
return ptr;
}
static int
hwloc_look_osf(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
cpu_cursor_t cursor;
unsigned nbnodes;
radid_t radid, radid2;
radset_t radset, radset2;
cpuid_t cpuid;
cpuset_t cpuset;
struct hwloc_obj *obj;
unsigned distance;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
nbnodes = rad_get_num();
cpusetcreate(&cpuset);
radsetcreate(&radset);
radsetcreate(&radset2);
{
hwloc_obj_t *nodes = calloc(nbnodes, sizeof(hwloc_obj_t));
unsigned *indexes = calloc(nbnodes, sizeof(unsigned));
float *distances = calloc(nbnodes*nbnodes, sizeof(float));
unsigned nfound;
numa_attr_t attr;
attr.nattr_type = R_RAD;
attr.nattr_descr.rd_radset = radset;
attr.nattr_flags = 0;
for (radid = 0; radid < (radid_t) nbnodes; radid++) {
rademptyset(radset);
radaddset(radset, radid);
cpuemptyset(cpuset);
if (rad_get_cpus(radid, cpuset)==-1) {
fprintf(stderr,"rad_get_cpus(%d) failed: %s\n",radid,strerror(errno));
continue;
}
indexes[radid] = radid;
nodes[radid] = obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, radid);
obj->cpuset = hwloc_bitmap_alloc();
obj->memory.local_memory = rad_get_physmem(radid) * hwloc_getpagesize();
obj->memory.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize();
#ifdef HAVE__SC_LARGE_PAGESIZE
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
cursor = SET_CURSOR_INIT;
while((cpuid = cpu_foreach(cpuset, 0, &cursor)) != CPU_NONE)
hwloc_bitmap_set(obj->cpuset, cpuid);
hwloc_debug_1arg_bitmap("node %d has cpuset %s\n",
radid, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
nfound = 0;
for (radid2 = 0; radid2 < (radid_t) nbnodes; radid2++)
distances[radid*nbnodes+radid2] = RAD_DIST_REMOTE;
for (distance = RAD_DIST_LOCAL; distance < RAD_DIST_REMOTE; distance++) {
attr.nattr_distance = distance;
/* get set of NUMA nodes at distance <= DISTANCE */
if (nloc(&attr, radset2)) {
fprintf(stderr,"nloc failed: %s\n", strerror(errno));
continue;
}
cursor = SET_CURSOR_INIT;
while ((radid2 = rad_foreach(radset2, 0, &cursor)) != RAD_NONE) {
if (distances[radid*nbnodes+radid2] == RAD_DIST_REMOTE) {
distances[radid*nbnodes+radid2] = (float) distance;
nfound++;
}
}
if (nfound == nbnodes)
/* Finished finding distances, no need to go up to RAD_DIST_REMOTE */
break;
}
}
hwloc_distances_set(topology, HWLOC_OBJ_NODE, nbnodes, indexes, nodes, distances, 0 /* OS cannot force */);
}
radsetdestroy(&radset2);
radsetdestroy(&radset);
cpusetdestroy(&cpuset);
/* add PU objects */
hwloc_setup_pu_level(topology, hwloc_fallback_nbprocessors(topology));
hwloc_obj_add_info(topology->levels[0][0], "Backend", "OSF");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_osf_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support)
{
hooks->set_thread_cpubind = hwloc_osf_set_thread_cpubind;
hooks->set_thisthread_cpubind = hwloc_osf_set_thisthread_cpubind;
hooks->set_proc_cpubind = hwloc_osf_set_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_osf_set_thisproc_cpubind;
hooks->set_area_membind = hwloc_osf_set_area_membind;
hooks->alloc_membind = hwloc_osf_alloc_membind;
hooks->alloc = hwloc_alloc_mmap;
hooks->free_membind = hwloc_free_mmap;
support->membind->firsttouch_membind = 1;
support->membind->bind_membind = 1;
support->membind->interleave_membind = 1;
support->membind->replicate_membind = 1;
}
static struct hwloc_backend *
hwloc_osf_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_osf;
return backend;
}
static struct hwloc_disc_component hwloc_osf_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"osf",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_osf_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_osf_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_osf_disc_component
};

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

@ -0,0 +1,837 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux 1
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/helper.h>
#include <hwloc/plugins.h>
/* private headers allowed for convenience because this plugin is built within hwloc */
#include <private/debug.h>
#include <private/misc.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <setjmp.h>
#if (defined HWLOC_HAVE_LIBPCIACCESS) && (defined HWLOC_HAVE_PCIUTILS)
#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
#ifdef HWLOC_HAVE_LIBPCIACCESS
#include <pciaccess.h>
#else /* HWLOC_HAVE_PCIUTILS */
#include <pci/pci.h>
#endif
#ifndef PCI_HEADER_TYPE
#define PCI_HEADER_TYPE 0x0e
#endif
#ifndef PCI_HEADER_TYPE_BRIDGE
#define PCI_HEADER_TYPE_BRIDGE 1
#endif
#ifndef PCI_CLASS_DEVICE
#define PCI_CLASS_DEVICE 0x0a
#endif
#ifndef PCI_CLASS_BRIDGE_PCI
#define PCI_CLASS_BRIDGE_PCI 0x0604
#endif
#ifndef PCI_REVISION_ID
#define PCI_REVISION_ID 0x08
#endif
#ifndef PCI_SUBSYSTEM_VENDOR_ID
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#endif
#ifndef PCI_SUBSYSTEM_ID
#define PCI_SUBSYSTEM_ID 0x2e
#endif
#ifndef PCI_PRIMARY_BUS
#define PCI_PRIMARY_BUS 0x18
#endif
#ifndef PCI_SECONDARY_BUS
#define PCI_SECONDARY_BUS 0x19
#endif
#ifndef PCI_SUBORDINATE_BUS
#define PCI_SUBORDINATE_BUS 0x1a
#endif
#ifndef PCI_EXP_LNKSTA
#define PCI_EXP_LNKSTA 18
#endif
#ifndef PCI_EXP_LNKSTA_SPEED
#define PCI_EXP_LNKSTA_SPEED 0x000f
#endif
#ifndef PCI_EXP_LNKSTA_WIDTH
#define PCI_EXP_LNKSTA_WIDTH 0x03f0
#endif
#ifndef PCI_CAP_ID_EXP
#define PCI_CAP_ID_EXP 0x10
#endif
#ifndef PCI_CAP_NORMAL
#define PCI_CAP_NORMAL 1
#endif
#ifndef PCI_STATUS
#define PCI_STATUS 0x06
#endif
#ifndef PCI_CAPABILITY_LIST
#define PCI_CAPABILITY_LIST 0x34
#endif
#ifndef PCI_STATUS_CAP_LIST
#define PCI_STATUS_CAP_LIST 0x10
#endif
#ifndef PCI_CAP_LIST_ID
#define PCI_CAP_LIST_ID 0
#endif
#ifndef PCI_CAP_LIST_NEXT
#define PCI_CAP_LIST_NEXT 1
#endif
#define CONFIG_SPACE_CACHESIZE_TRY 256
#define CONFIG_SPACE_CACHESIZE 64
static void
hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused,
struct hwloc_obj *pcidev, int depth __hwloc_attribute_unused)
{
char busid[14];
snprintf(busid, sizeof(busid), "%04x:%02x:%02x.%01x",
pcidev->attr->pcidev.domain, pcidev->attr->pcidev.bus, pcidev->attr->pcidev.dev, pcidev->attr->pcidev.func);
if (pcidev->type == HWLOC_OBJ_BRIDGE) {
if (pcidev->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST)
hwloc_debug("%*s HostBridge", depth, "");
else
hwloc_debug("%*s %s Bridge [%04x:%04x]", depth, "", busid,
pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id);
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);
} else
hwloc_debug("%*s %s Device [%04x:%04x (%04x:%04x) rev=%02x class=%04x]\n", depth, "", busid,
pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id,
pcidev->attr->pcidev.subvendor_id, pcidev->attr->pcidev.subdevice_id,
pcidev->attr->pcidev.revision, pcidev->attr->pcidev.class_id);
}
static void
hwloc_pci_traverse_setbridgedepth_cb(void * cbdata __hwloc_attribute_unused,
struct hwloc_obj *pcidev, int depth)
{
if (pcidev->type == HWLOC_OBJ_BRIDGE)
pcidev->attr->bridge.depth = depth;
}
static void
hwloc_pci_traverse_lookuposdevices_cb(void * cbdata,
struct hwloc_obj *pcidev, int depth __hwloc_attribute_unused)
{
struct hwloc_backend *backend = cbdata;
if (pcidev->type == HWLOC_OBJ_BRIDGE)
return;
hwloc_backends_notify_new_object(backend, pcidev);
}
static void
hwloc_pci__traverse(void * cbdata, struct hwloc_obj *root,
void (*cb)(void * cbdata, struct hwloc_obj *, int depth),
int depth)
{
struct hwloc_obj *child = root->first_child;
while (child) {
cb(cbdata, child, depth);
if (child->type == HWLOC_OBJ_BRIDGE)
hwloc_pci__traverse(cbdata, child, cb, depth+1);
child = child->next_sibling;
}
}
static void
hwloc_pci_traverse(void * cbdata, struct hwloc_obj *root,
void (*cb)(void * cbdata, struct hwloc_obj *, int depth))
{
hwloc_pci__traverse(cbdata, root, cb, 0);
}
enum hwloc_pci_busid_comparison_e {
HWLOC_PCI_BUSID_LOWER,
HWLOC_PCI_BUSID_HIGHER,
HWLOC_PCI_BUSID_INCLUDED,
HWLOC_PCI_BUSID_SUPERSET
};
static enum hwloc_pci_busid_comparison_e
hwloc_pci_compare_busids(struct hwloc_obj *a, struct hwloc_obj *b)
{
if (a->type == HWLOC_OBJ_BRIDGE)
assert(a->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI);
if (b->type == HWLOC_OBJ_BRIDGE)
assert(b->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI);
if (a->attr->pcidev.domain < b->attr->pcidev.domain)
return HWLOC_PCI_BUSID_LOWER;
if (a->attr->pcidev.domain > b->attr->pcidev.domain)
return HWLOC_PCI_BUSID_HIGHER;
if (a->type == HWLOC_OBJ_BRIDGE
&& b->attr->pcidev.bus >= a->attr->bridge.downstream.pci.secondary_bus
&& b->attr->pcidev.bus <= a->attr->bridge.downstream.pci.subordinate_bus)
return HWLOC_PCI_BUSID_SUPERSET;
if (b->type == HWLOC_OBJ_BRIDGE
&& a->attr->pcidev.bus >= b->attr->bridge.downstream.pci.secondary_bus
&& a->attr->pcidev.bus <= b->attr->bridge.downstream.pci.subordinate_bus)
return HWLOC_PCI_BUSID_INCLUDED;
if (a->attr->pcidev.bus < b->attr->pcidev.bus)
return HWLOC_PCI_BUSID_LOWER;
if (a->attr->pcidev.bus > b->attr->pcidev.bus)
return HWLOC_PCI_BUSID_HIGHER;
if (a->attr->pcidev.dev < b->attr->pcidev.dev)
return HWLOC_PCI_BUSID_LOWER;
if (a->attr->pcidev.dev > b->attr->pcidev.dev)
return HWLOC_PCI_BUSID_HIGHER;
if (a->attr->pcidev.func < b->attr->pcidev.func)
return HWLOC_PCI_BUSID_LOWER;
if (a->attr->pcidev.func > b->attr->pcidev.func)
return HWLOC_PCI_BUSID_HIGHER;
/* Should never reach here. Abort on both debug builds and
non-debug builds */
assert(0);
fprintf(stderr, "Bad assertion in hwloc %s:%d (aborting)\n", __FILE__, __LINE__);
exit(1);
}
static void
hwloc_pci_add_child_before(struct hwloc_obj *root, struct hwloc_obj *child, struct hwloc_obj *new)
{
if (child) {
new->prev_sibling = child->prev_sibling;
child->prev_sibling = new;
} else {
new->prev_sibling = root->last_child;
root->last_child = new;
}
if (new->prev_sibling)
new->prev_sibling->next_sibling = new;
else
root->first_child = new;
new->next_sibling = child;
}
static void
hwloc_pci_remove_child(struct hwloc_obj *root, struct hwloc_obj *child)
{
if (child->next_sibling)
child->next_sibling->prev_sibling = child->prev_sibling;
else
root->last_child = child->prev_sibling;
if (child->prev_sibling)
child->prev_sibling->next_sibling = child->next_sibling;
else
root->first_child = child->next_sibling;
child->prev_sibling = NULL;
child->next_sibling = NULL;
}
static void hwloc_pci_add_object(struct hwloc_obj *root, struct hwloc_obj *new);
static void
hwloc_pci_try_insert_siblings_below_new_bridge(struct hwloc_obj *root, struct hwloc_obj *new)
{
enum hwloc_pci_busid_comparison_e comp;
struct hwloc_obj *current, *next;
next = new->next_sibling;
while (next) {
current = next;
next = current->next_sibling;
comp = hwloc_pci_compare_busids(current, new);
assert(comp != HWLOC_PCI_BUSID_SUPERSET);
if (comp == HWLOC_PCI_BUSID_HIGHER)
continue;
assert(comp == HWLOC_PCI_BUSID_INCLUDED);
/* move this object below the new bridge */
hwloc_pci_remove_child(root, current);
hwloc_pci_add_object(new, current);
}
}
static void
hwloc_pci_add_object(struct hwloc_obj *root, struct hwloc_obj *new)
{
struct hwloc_obj *current;
current = root->first_child;
while (current) {
enum hwloc_pci_busid_comparison_e comp = hwloc_pci_compare_busids(new, current);
switch (comp) {
case HWLOC_PCI_BUSID_HIGHER:
/* go further */
current = current->next_sibling;
continue;
case HWLOC_PCI_BUSID_INCLUDED:
/* insert below current bridge */
hwloc_pci_add_object(current, new);
return;
case HWLOC_PCI_BUSID_LOWER:
case HWLOC_PCI_BUSID_SUPERSET:
/* insert before current object */
hwloc_pci_add_child_before(root, current, new);
/* walk next siblings and move them below new bridge if needed */
hwloc_pci_try_insert_siblings_below_new_bridge(root, new);
return;
}
}
/* add to the end of the list if higher than everybody */
hwloc_pci_add_child_before(root, NULL, new);
}
static struct hwloc_obj *
hwloc_pci_find_hostbridge_parent(struct hwloc_topology *topology, struct hwloc_backend *backend,
struct hwloc_obj *hostbridge)
{
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc();
struct hwloc_obj *parent;
char *env;
int err;
/* override the cpuset with the environment if given */
char envname[256];
snprintf(envname, sizeof(envname), "HWLOC_PCI_%04x_%02x_LOCALCPUS",
hostbridge->first_child->attr->pcidev.domain, hostbridge->first_child->attr->pcidev.bus);
env = getenv(envname);
if (env) {
/* force the hostbridge cpuset */
hwloc_debug("Overriding localcpus using %s in the environment\n", envname);
hwloc_bitmap_sscanf(cpuset, env);
} else {
/* get the hostbridge cpuset by acking the OS backend.
* it's not a PCI device, so we use its first child locality info.
*/
err = hwloc_backends_get_obj_cpuset(backend, hostbridge->first_child, cpuset);
if (err < 0)
/* if we got nothing, assume the hostbridge is attached to the top of hierarchy */
hwloc_bitmap_copy(cpuset, hwloc_topology_get_topology_cpuset(topology));
}
hwloc_debug_bitmap("Attaching hostbridge to cpuset %s\n", cpuset);
/* restrict to the existing topology cpuset to avoid errors later */
hwloc_bitmap_and(cpuset, cpuset, hwloc_topology_get_topology_cpuset(topology));
/* if the remaining cpuset is empty, take the root */
if (hwloc_bitmap_iszero(cpuset))
hwloc_bitmap_copy(cpuset, hwloc_topology_get_topology_cpuset(topology));
/* attach the hostbridge now that it contains the right objects */
parent = hwloc_get_obj_covering_cpuset(topology, cpuset);
/* in the worst case, we got the root object */
if (hwloc_bitmap_isequal(cpuset, parent->cpuset)) {
/* this object has the right cpuset, but it could be a cache or so,
* go up as long as the cpuset is the same
*/
while (parent->parent && hwloc_bitmap_isequal(parent->cpuset, parent->parent->cpuset))
parent = parent->parent;
} else {
/* the object we found is too large, insert an intermediate group */
hwloc_obj_t group_obj = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, -1);
if (group_obj) {
group_obj->cpuset = hwloc_bitmap_dup(cpuset);
group_obj->attr->group.depth = (unsigned) -1;
parent = hwloc__insert_object_by_cpuset(topology, group_obj, hwloc_report_os_error);
}
}
hwloc_bitmap_free(cpuset);
return parent;
}
#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
#ifndef HWLOC_HAVE_PCI_FIND_CAP
static unsigned
hwloc_pci_find_cap(const unsigned char *config, size_t config_size, unsigned cap)
{
unsigned char seen[256] = { 0 };
unsigned char ptr;
if (!(config[PCI_STATUS] & PCI_STATUS_CAP_LIST))
return 0;
for (ptr = config[PCI_CAPABILITY_LIST] & ~3;
ptr;
ptr = config[ptr + PCI_CAP_LIST_NEXT] & ~3) {
unsigned char id;
if (ptr >= config_size)
return 0;
/* Looped around! */
if (seen[ptr])
return 0;
seen[ptr] = 1;
id = config[ptr + PCI_CAP_LIST_ID];
if (id == cap)
return ptr;
if (id == 0xff)
break;
if (ptr + (unsigned) PCI_CAP_LIST_NEXT >= config_size)
return 0;
}
return 0;
}
#endif
static int
hwloc_look_pci(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_obj fakehostbridge; /* temporary object covering the whole PCI hierarchy until its complete */
unsigned current_hostbridge;
#ifdef HWLOC_HAVE_LIBPCIACCESS
int ret;
struct pci_device_iterator *iter;
struct pci_device *pcidev;
#else /* HWLOC_HAVE_PCIUTILS */
struct pci_access *pciaccess;
struct pci_dev *pcidev;
#endif
if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
return 0;
if (!hwloc_topology_is_thissystem(topology)) {
hwloc_debug("%s", "\nno PCI detection (not thissystem)\n");
return 0;
}
fakehostbridge.first_child = NULL;
fakehostbridge.last_child = NULL;
hwloc_debug("%s", "\nScanning PCI buses...\n");
/* initialize PCI scanning */
#ifdef HWLOC_HAVE_LIBPCIACCESS
ret = pci_system_init();
if (ret) {
hwloc_debug("%s", "Can not initialize libpciaccess\n");
return -1;
}
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 */
#ifdef HWLOC_HAVE_LIBPCIACCESS
for (pcidev = pci_device_next(iter);
pcidev;
pcidev = pci_device_next(iter))
#else /* HWLOC_HAVE_PCIUTILS */
for (pcidev = pciaccess->devices;
pcidev;
pcidev = pcidev->next)
#endif
{
const char *vendorname, *devicename, *fullname;
unsigned char config_space_cache[CONFIG_SPACE_CACHESIZE_TRY];
unsigned config_space_cachesize = CONFIG_SPACE_CACHESIZE_TRY;
struct hwloc_obj *obj;
unsigned char headertype;
unsigned os_index;
unsigned isbridge;
unsigned domain;
unsigned device_class;
unsigned short tmp16;
char name[128];
unsigned offset;
#ifdef HWLOC_HAVE_PCI_FIND_CAP
struct pci_cap *cap;
#endif
#ifdef HWLOC_HAVE_LIBPCIACCESS
pciaddr_t got;
#endif
/* cache what we need of the config space */
#ifdef HWLOC_HAVE_LIBPCIACCESS
pci_device_probe(pcidev);
pci_device_cfg_read(pcidev, config_space_cache, 0, CONFIG_SPACE_CACHESIZE_TRY, &got);
config_space_cachesize = got;
#else /* HWLOC_HAVE_PCIUTILS */
pci_read_block(pcidev, 0, config_space_cache, CONFIG_SPACE_CACHESIZE_TRY);
#endif
/* try to read the domain */
#if (defined HWLOC_HAVE_LIBPCIACCESS) || (defined HWLOC_HAVE_PCIDEV_DOMAIN)
domain = pcidev->domain;
#else
domain = 0; /* default domain number */
#endif
/* try to read the device_class */
#ifdef HWLOC_HAVE_LIBPCIACCESS
device_class = pcidev->device_class >> 8;
#else /* HWLOC_HAVE_PCIUTILS */
#ifdef HWLOC_HAVE_PCIDEV_DEVICE_CLASS
device_class = pcidev->device_class;
#else
HWLOC_BUILD_ASSERT(PCI_CLASS_DEVICE < CONFIG_SPACE_CACHESIZE);
device_class = config_space_cache[PCI_CLASS_DEVICE] | (config_space_cache[PCI_CLASS_DEVICE+1] << 8);
#endif
#endif
/* is this a bridge? */
HWLOC_BUILD_ASSERT(PCI_HEADER_TYPE < CONFIG_SPACE_CACHESIZE);
headertype = config_space_cache[PCI_HEADER_TYPE] & 0x7f;
isbridge = (device_class == PCI_CLASS_BRIDGE_PCI
&& headertype == PCI_HEADER_TYPE_BRIDGE);
/* might be useful for debugging (note that domain might be truncated) */
os_index = (domain << 20) + (pcidev->bus << 12) + (pcidev->dev << 4) + pcidev->func;
obj = hwloc_alloc_setup_object(isbridge ? HWLOC_OBJ_BRIDGE : HWLOC_OBJ_PCI_DEVICE, os_index);
obj->attr->pcidev.domain = domain;
obj->attr->pcidev.bus = pcidev->bus;
obj->attr->pcidev.dev = pcidev->dev;
obj->attr->pcidev.func = pcidev->func;
obj->attr->pcidev.vendor_id = pcidev->vendor_id;
obj->attr->pcidev.device_id = pcidev->device_id;
obj->attr->pcidev.class_id = device_class;
HWLOC_BUILD_ASSERT(PCI_REVISION_ID < CONFIG_SPACE_CACHESIZE);
obj->attr->pcidev.revision = config_space_cache[PCI_REVISION_ID];
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, config_space_cachesize, PCI_CAP_ID_EXP);
#endif /* HWLOC_HAVE_PCI_FIND_CAP */
if (0xffff == pcidev->vendor_id && 0xffff == pcidev->device_id) {
/* SR-IOV puts ffff:ffff in Virtual Function config space.
* The actual VF device ID is stored at a special (dynamic) location in the Physical Function config space.
* VF and PF have the same vendor ID.
*
* libpciaccess just returns ffff:ffff, needs to be fixed.
* linuxpci is OK because sysfs files are already fixed the kernel.
* pciutils is OK when it uses those Linux sysfs files.
*
* Reading these files is an easy way to work around the libpciaccess issue on Linux,
* but we have no way to know if this is caused by SR-IOV or not.
*
* TODO:
* If PF has CAP_ID_PCIX or CAP_ID_EXP (offset>0),
* look for extended capability PCI_EXT_CAP_ID_SRIOV,
* then read the VF device ID after it (PCI_IOV_DID bytes later).
* Needs access to extended config space (needs root on Linux).
* TODO:
* Add string info attributes in VF and PF objects?
*/
#ifdef HWLOC_LINUX_SYS
/* Workaround for Linux (the kernel returns the VF device/vendor IDs). */
char path[64];
char value[16];
FILE *file;
snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/vendor",
domain, pcidev->bus, pcidev->dev, pcidev->func);
file = fopen(path, "r");
if (file) {
fread(value, sizeof(value), 1, file);
fclose(file);
obj->attr->pcidev.vendor_id = strtoul(value, NULL, 16);
}
snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/device",
domain, pcidev->bus, pcidev->dev, pcidev->func);
file = fopen(path, "r");
if (file) {
fread(value, sizeof(value), 1, file);
fclose(file);
obj->attr->pcidev.device_id = strtoul(value, NULL, 16);
}
#endif
}
if (offset > 0) {
if (offset + PCI_EXP_LNKSTA + 4 >= config_space_cachesize) {
fprintf(stderr, "cannot read PCI_EXP_LNKSTA cap at %d (only %d cached)\n", offset + PCI_EXP_LNKSTA, CONFIG_SPACE_CACHESIZE);
} else {
unsigned linksta, speed, width;
float lanespeed;
memcpy(&linksta, &config_space_cache[offset + PCI_EXP_LNKSTA], 4);
speed = linksta & PCI_EXP_LNKSTA_SPEED; /* PCIe generation */
width = (linksta & PCI_EXP_LNKSTA_WIDTH) >> 4; /* how many lanes */
/* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane
* PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane
* PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane
*/
lanespeed = speed <= 2 ? 2.5 * speed * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */
obj->attr->pcidev.linkspeed = lanespeed * width / 8; /* GB/s */
}
}
if (isbridge) {
HWLOC_BUILD_ASSERT(PCI_PRIMARY_BUS < CONFIG_SPACE_CACHESIZE);
HWLOC_BUILD_ASSERT(PCI_SECONDARY_BUS < CONFIG_SPACE_CACHESIZE);
HWLOC_BUILD_ASSERT(PCI_SUBORDINATE_BUS < CONFIG_SPACE_CACHESIZE);
if (config_space_cache[PCI_PRIMARY_BUS] != pcidev->bus)
hwloc_debug(" %04x:%02x:%02x.%01x bridge with (ignored) invalid PCI_PRIMARY_BUS %02x\n",
domain, pcidev->bus, pcidev->dev, pcidev->func, config_space_cache[PCI_PRIMARY_BUS]);
obj->attr->bridge.upstream_type = HWLOC_OBJ_BRIDGE_PCI;
obj->attr->bridge.downstream_type = HWLOC_OBJ_BRIDGE_PCI;
obj->attr->bridge.downstream.pci.domain = domain;
obj->attr->bridge.downstream.pci.secondary_bus = config_space_cache[PCI_SECONDARY_BUS];
obj->attr->bridge.downstream.pci.subordinate_bus = config_space_cache[PCI_SUBORDINATE_BUS];
}
if (obj->type == HWLOC_OBJ_PCI_DEVICE) {
memcpy(&tmp16, &config_space_cache[PCI_SUBSYSTEM_VENDOR_ID], sizeof(tmp16));
HWLOC_BUILD_ASSERT(PCI_SUBSYSTEM_VENDOR_ID < CONFIG_SPACE_CACHESIZE);
obj->attr->pcidev.subvendor_id = tmp16;
memcpy(&tmp16, &config_space_cache[PCI_SUBSYSTEM_ID], sizeof(tmp16));
HWLOC_BUILD_ASSERT(PCI_SUBSYSTEM_ID < CONFIG_SPACE_CACHESIZE);
obj->attr->pcidev.subdevice_id = tmp16;
} else {
/* TODO:
* bridge must lookup PCI_CAP_ID_SSVID and then look at offset+PCI_SSVID_VENDOR/DEVICE_ID
* cardbus must look at PCI_CB_SUBSYSTEM_VENDOR_ID and PCI_CB_SUBSYSTEM_ID
*/
}
/* starting from pciutils 2.2, pci_lookup_name() takes a variable number
* of arguments, and supports the PCI_LOOKUP_NO_NUMBERS flag.
*/
#ifdef HWLOC_HAVE_LIBPCIACCESS
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)
hwloc_obj_add_info(obj, "PCIVendor", vendorname);
#ifdef HWLOC_HAVE_LIBPCIACCESS
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)
hwloc_obj_add_info(obj, "PCIDevice", devicename);
#ifdef HWLOC_HAVE_LIBPCIACCESS
snprintf(name, sizeof(name), "%s%s%s",
vendorname ? vendorname : "",
vendorname && devicename ? " " : "",
devicename ? devicename : "");
fullname = 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)
obj->name = strdup(fullname);
else
fullname = "??";
#endif /* HWLOC_HAVE_PCIUTILS */
hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s\n",
domain, pcidev->bus, pcidev->dev, pcidev->func,
device_class, pcidev->vendor_id, pcidev->device_id,
fullname);
hwloc_pci_add_object(&fakehostbridge, obj);
}
/* finalize device scanning */
#ifdef HWLOC_HAVE_LIBPCIACCESS
pci_iterator_destroy(iter);
pci_system_cleanup();
#else /* HWLOC_HAVE_PCIUTILS */
pci_cleanup(pciaccess);
#endif
hwloc_debug("%s", "\nPCI hierarchy after basic scan:\n");
hwloc_pci_traverse(NULL, &fakehostbridge, hwloc_pci_traverse_print_cb);
if (!fakehostbridge.first_child)
/* found nothing, exit */
return 0;
/* walk the hierarchy, set bridge depth and lookup OS devices */
hwloc_pci_traverse(NULL, &fakehostbridge, hwloc_pci_traverse_setbridgedepth_cb);
hwloc_pci_traverse(backend, &fakehostbridge, hwloc_pci_traverse_lookuposdevices_cb);
/*
* fakehostbridge lists all objects connected to any upstream bus in the machine.
* We now create one real hostbridge object per upstream bus.
* It's not actually a PCI device so we have to create it.
*/
current_hostbridge = 0;
while (fakehostbridge.first_child) {
/* start a new host bridge */
struct hwloc_obj *hostbridge = hwloc_alloc_setup_object(HWLOC_OBJ_BRIDGE, current_hostbridge++);
struct hwloc_obj *child = fakehostbridge.first_child;
struct hwloc_obj *next_child;
struct hwloc_obj *parent;
unsigned short current_domain = child->attr->pcidev.domain;
unsigned char current_bus = child->attr->pcidev.bus;
unsigned char current_subordinate = current_bus;
hwloc_debug("Starting new PCI hostbridge %04x:%02x\n", current_domain, current_bus);
/*
* attach all objects from the same upstream domain/bus
*/
next_child:
next_child = child->next_sibling;
hwloc_pci_remove_child(&fakehostbridge, child);
hwloc_pci_add_child_before(hostbridge, NULL, child);
/* compute hostbridge secondary/subordinate buses */
if (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.downstream.pci.subordinate_bus > current_subordinate)
current_subordinate = child->attr->bridge.downstream.pci.subordinate_bus;
/* use next child if it has the same domains/bus */
child = next_child;
if (child
&& child->attr->pcidev.domain == current_domain
&& child->attr->pcidev.bus == current_bus)
goto next_child;
/* finish setting up this hostbridge */
hostbridge->attr->bridge.upstream_type = HWLOC_OBJ_BRIDGE_HOST;
hostbridge->attr->bridge.downstream_type = HWLOC_OBJ_BRIDGE_PCI;
hostbridge->attr->bridge.downstream.pci.domain = current_domain;
hostbridge->attr->bridge.downstream.pci.secondary_bus = current_bus;
hostbridge->attr->bridge.downstream.pci.subordinate_bus = current_subordinate;
hwloc_debug("New PCI hostbridge %04x:[%02x-%02x]\n",
current_domain, current_bus, current_subordinate);
/* attach the hostbridge where it belongs */
parent = hwloc_pci_find_hostbridge_parent(topology, backend, hostbridge);
hwloc_insert_object_by_parent(topology, parent, hostbridge);
}
return 1;
}
static struct hwloc_backend *
hwloc_pci_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_pci;
return backend;
}
static struct hwloc_disc_component hwloc_pci_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_MISC,
"pci",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_pci_component_instantiate,
20,
NULL
};
#ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component;
#endif
const struct hwloc_component hwloc_pci_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_pci_disc_component
};

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

@ -0,0 +1,340 @@
/*
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 Université Bordeaux 1. All rights reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include <private/autogen/config.h>
#include <hwloc/autogen/config.h>
#include <private/solaris-chiptype.h>
#include <hwloc.h>
#include <stdlib.h>
#include <strings.h>
#ifdef HAVE_PICL_H
#include <sys/systeminfo.h>
#include <picl.h>
/*****************************************************************************
Order of this list is important for the assign_value and
assign_string_value routines
*****************************************************************************/
static const char* items[] = {
"clock-frequency",
"cpu-mhz",
"ecache-size",
"l2-cache-size",
"sectored-l2-cache-size",
"implementation#",
"manufacturer#",
"compatible",
"ProcessorType",
"vendor-id",
"brand-string"
};
#define NUM_ITEMS (sizeof(items) / sizeof(items[0]))
/*****************************************************************************
SPARC strings for chip modes and implementation
*****************************************************************************/
static const char* sparc_modes[] = {
"UNKNOWN",
"SPITFIRE",
"BLACKBIRD",
"CHEETAH",
"SPARC64_VI",
"T1",
"T2",
"SPARC64_VII",
"ROCK"
};
/*****************************************************************************
Default values are for Unknown so we can build up from there.
*****************************************************************************/
static long dss_chip_mode = MODE_UNKNOWN;
static long dss_chip_impl = IMPL_SPITFIRE;
static long dss_chip_cache = TWO_MEG_CACHE;
static long dss_chip_manufacturer = TI_MANUFACTURER;
static long long dss_chip_speed = SPITFIRE_SPEED;
static char dss_chip_type[PICL_PROPNAMELEN_MAX];
static char dss_chip_model[PICL_PROPNAMELEN_MAX];
static int called_cpu_probe = 0;
/*****************************************************************************
Assigns values based on the value of index. For this reason, the order of
the items array is important.
*****************************************************************************/
static void assign_value(int index, long long val) {
if (index == 0) { /* clock-frequency */
dss_chip_speed = val;
}
if (index == 1) { /* cpu-mhz */
dss_chip_speed = val * 1000000; /* Scale since value was in MHz */
}
else if ((index >= 2) && (index <= 4)) {
/* ecache-size, l2-cache-size, sectored-l2-cache-size */
dss_chip_cache = val;
}
else if (index == 5) {
/* implementation# T1, T2, and Rock do not have this, see RFE 6615268 */
dss_chip_impl = val;
if (dss_chip_impl == IMPL_SPITFIRE) {
dss_chip_mode = 1;
}
else if ((dss_chip_impl >= IMPL_BLACKBIRD) &&
(dss_chip_impl <= IMPL_HUMMINGBIRD)) {
dss_chip_mode = 2;
}
else if ((dss_chip_impl >= IMPL_CHEETAH) &&
(dss_chip_impl <= IMPL_PANTHER)) {
dss_chip_mode = 3;
}
else if (dss_chip_impl == IMPL_SPARC64_VI) {
dss_chip_mode = 4;
}
else if (dss_chip_impl == IMPL_NIAGARA) {
dss_chip_mode = 5;
}
else if (dss_chip_impl == IMPL_NIAGARA_2) {
dss_chip_mode = 6;
}
else if (dss_chip_impl == IMPL_SPARC64_VII) {
dss_chip_mode = 7;
}
else if (dss_chip_impl == IMPL_ROCK) {
dss_chip_mode = 8;
}
}
else if (index == 6) { /* manufacturer# */
dss_chip_manufacturer = val;
}
}
/*****************************************************************************
Assigns values based on the value of index. For this reason, the order of
the items array is important.
*****************************************************************************/
static void assign_string_value(int index, char* string_val) {
if (index == 7) { /* compatible */
if (strncasecmp(string_val, "FJSV,SPARC64-VI",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = 4;
}
else if (strncasecmp(string_val, "SUNW,UltraSPARC-T1",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = 5;
}
else if (strncasecmp(string_val, "SUNW,UltraSPARC-T2",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = 6;
}
else if (strncasecmp(string_val, "FJSV,SPARC64-VII",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = 7;
}
else if (strncasecmp(string_val, "SUNW,Rock",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = 8;
}
} else if (index == 8) { /* ProcessorType */
strncpy(&dss_chip_type[0], string_val, PICL_PROPNAMELEN_MAX);
} else if (index == 10) { /* brand-string */
strncpy(&dss_chip_model[0], string_val, PICL_PROPNAMELEN_MAX);
}
}
/*****************************************************************************
Gets called by probe_cpu. Cycles through the table values until we find
what we are looking for.
*****************************************************************************/
static void search_table(int index, picl_prophdl_t table_hdl) {
picl_prophdl_t col_hdl;
picl_prophdl_t row_hdl;
picl_propinfo_t p_info;
int val;
char string_val[PICL_PROPNAMELEN_MAX];
for (val = picl_get_next_by_col(table_hdl, &row_hdl); val != PICL_ENDOFLIST;
val = picl_get_next_by_col(row_hdl, &row_hdl)) {
if (val == PICL_SUCCESS) {
for (col_hdl = row_hdl; val != PICL_ENDOFLIST;
val = picl_get_next_by_row(col_hdl, &col_hdl)) {
if (val == PICL_SUCCESS) {
val = picl_get_propinfo(col_hdl, &p_info);
if (val == PICL_SUCCESS) {
if (p_info.type == PICL_PTYPE_CHARSTRING) {
val = picl_get_propval(col_hdl, &string_val, sizeof(string_val));
if (val == PICL_SUCCESS) {
assign_string_value(index, string_val);
}
}
}
}
}
}
}
}
/*****************************************************************************
Gets called by picl_walk_tree_by_class. Then it cycles through the properties
until we find what we are looking for. Once we are done, we return
PICL_WALK_TERMINATE to stop picl_walk_tree_by_class from traversing the tree.
Note that PICL_PTYPE_UNSIGNED_INT and PICL_PTYPE_INT can either be 4-bytes
or 8-bytes.
*****************************************************************************/
static int probe_cpu(picl_nodehdl_t node_hdl, void* dummy_arg __hwloc_attribute_unused) {
picl_prophdl_t p_hdl;
picl_prophdl_t table_hdl;
picl_propinfo_t p_info;
long long long_long_val;
unsigned int uint_val;
unsigned int index;
int int_val;
int val;
char string_val[PICL_PROPNAMELEN_MAX];
val = picl_get_first_prop(node_hdl, &p_hdl);
while (val == PICL_SUCCESS) {
called_cpu_probe = 1;
val = picl_get_propinfo(p_hdl, &p_info);
if (val == PICL_SUCCESS) {
for (index = 0; index < NUM_ITEMS; index++) {
if (strcasecmp(p_info.name, items[index]) == 0) {
if (p_info.type == PICL_PTYPE_UNSIGNED_INT) {
if (p_info.size == sizeof(uint_val)) {
val = picl_get_propval(p_hdl, &uint_val, sizeof(uint_val));
if (val == PICL_SUCCESS) {
long_long_val = uint_val;
assign_value(index, long_long_val);
}
}
else if (p_info.size == sizeof(long_long_val)) {
val = picl_get_propval(p_hdl, &long_long_val,
sizeof(long_long_val));
if (val == PICL_SUCCESS) {
assign_value(index, long_long_val);
}
}
}
else if (p_info.type == PICL_PTYPE_INT) {
if (p_info.size == sizeof(int_val)) {
val = picl_get_propval(p_hdl, &int_val, sizeof(int_val));
if (val == PICL_SUCCESS) {
long_long_val = int_val;
assign_value(index, long_long_val);
}
}
else if (p_info.size == sizeof(long_long_val)) {
val = picl_get_propval(p_hdl, &long_long_val,
sizeof(long_long_val));
if (val == PICL_SUCCESS) {
assign_value(index, long_long_val);
}
}
}
else if (p_info.type == PICL_PTYPE_CHARSTRING) {
val = picl_get_propval(p_hdl, &string_val, sizeof(string_val));
if (val == PICL_SUCCESS) {
assign_string_value(index, string_val);
}
}
else if (p_info.type == PICL_PTYPE_TABLE) {
val = picl_get_propval(p_hdl, &table_hdl, p_info.size);
if (val == PICL_SUCCESS) {
search_table(index, table_hdl);
}
}
break;
} else if (index == NUM_ITEMS-1) {
if (p_info.type == PICL_PTYPE_CHARSTRING) {
val = picl_get_propval(p_hdl, &string_val, sizeof(string_val));
if (val == PICL_SUCCESS) {
}
}
}
}
}
val = picl_get_next_prop(p_hdl, &p_hdl);
}
return PICL_WALK_TERMINATE;
}
/*****************************************************************************
Initializes, gets the root, then walks the picl tree looking for information
Currently, the "core" class is only needed for OPL systems
*****************************************************************************/
char* hwloc_solaris_get_chip_type(void) {
picl_nodehdl_t root;
int val;
static char chip_type[PICL_PROPNAMELEN_MAX];
val = picl_initialize();
if (val != PICL_SUCCESS) { /* Can't initialize session with PICL daemon */
return(NULL);
}
val = picl_get_root(&root);
if (val != PICL_SUCCESS) { /* Failed to get root node of the PICL tree */
return(NULL);
}
val = picl_walk_tree_by_class(root, "cpu", (void *)NULL, probe_cpu);
val = picl_walk_tree_by_class(root, "core", (void *)NULL, probe_cpu);
picl_shutdown();
if (called_cpu_probe) {
#if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_X86_32_ARCH)
/* PICL returns some corrupted chip_type strings on x86,
* and CPUType only used on Sparc anyway, at least for now.
* So we just ignore this attribute on x86. */
#else
strncpy(chip_type, dss_chip_type, PICL_PROPNAMELEN_MAX);
#endif
} else {
/* no picl information on machine available */
sysinfo(SI_HW_PROVIDER, chip_type, PICL_PROPNAMELEN_MAX);
}
return(chip_type);
}
/*****************************************************************************
Initializes, gets the root, then walks the picl tree looking for information
Currently, the "core" class is only needed for OPL systems
*****************************************************************************/
char *hwloc_solaris_get_chip_model(void) {
if (called_cpu_probe) {
if (dss_chip_mode != MODE_UNKNOWN) { /* SPARC chip */
strncpy(dss_chip_model, sparc_modes[dss_chip_mode],
PICL_PROPNAMELEN_MAX);
}
} else {
/* no picl information on machine available */
sysinfo(SI_PLATFORM, dss_chip_model, PICL_PROPNAMELEN_MAX);
}
return(dss_chip_model);
}
#else
char* hwloc_solaris_get_chip_type(void) {
return NULL;
}
char *hwloc_solaris_get_chip_model(void) {
return NULL;
}
#endif

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

@ -0,0 +1,803 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2011 Oracle and/or its affiliates. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#include <private/solaris-chiptype.h>
#include <stdio.h>
#include <errno.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/processor.h>
#include <sys/procset.h>
#include <sys/types.h>
#include <sys/mman.h>
#ifdef HAVE_LIBLGRP
# include <sys/lgrp_user.h>
#endif
/* TODO: use psets? (only for root)
* TODO: get cache info from prtdiag? (it is setgid sys to be able to read from
* crw-r----- 1 root sys 88, 0 nov 3 14:35 /devices/pseudo/devinfo@0:devinfo
* and run (apparently undocumented) ioctls on it.
*/
static int
hwloc_solaris_set_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_const_bitmap_t hwloc_set, int flags)
{
unsigned target_cpu;
/* The resulting binding is always strict */
if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) {
if (processor_bind(idtype, id, PBIND_NONE, NULL) != 0)
return -1;
#ifdef HAVE_LIBLGRP
if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth >= 0) {
int n = hwloc_get_nbobjs_by_depth(topology, depth);
int i;
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE);
}
}
}
#endif /* HAVE_LIBLGRP */
return 0;
}
#ifdef HAVE_LIBLGRP
if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth >= 0) {
int n = hwloc_get_nbobjs_by_depth(topology, depth);
int i;
int ok;
hwloc_bitmap_t target = hwloc_bitmap_alloc();
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set))
hwloc_bitmap_or(target, target, obj->cpuset);
}
ok = hwloc_bitmap_isequal(target, hwloc_set);
hwloc_bitmap_free(target);
if (ok) {
/* Ok, managed to achieve hwloc_set by just combining NUMA nodes */
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) {
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_STRONG);
} else {
if (flags & HWLOC_CPUBIND_STRICT)
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE);
else
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_WEAK);
}
}
return 0;
}
}
}
#endif /* HAVE_LIBLGRP */
if (hwloc_bitmap_weight(hwloc_set) != 1) {
errno = EXDEV;
return -1;
}
target_cpu = hwloc_bitmap_first(hwloc_set);
if (processor_bind(idtype, id,
(processorid_t) (target_cpu), NULL) != 0)
return -1;
return 0;
}
static int
hwloc_solaris_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_solaris_set_sth_cpubind(topology, P_PID, pid, hwloc_set, flags);
}
static int
hwloc_solaris_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_solaris_set_sth_cpubind(topology, P_PID, P_MYID, hwloc_set, flags);
}
static int
hwloc_solaris_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_solaris_set_sth_cpubind(topology, P_LWPID, P_MYID, hwloc_set, flags);
}
#ifdef HAVE_LIBLGRP
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)
{
processorid_t binding;
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
int n;
int i;
if (depth < 0) {
errno = ENOSYS;
return -1;
}
/* first check if processor_bind() was used to bind to a single processor rather than to an lgroup */
if ( processor_bind(idtype, id, PBIND_QUERY, &binding) == 0 && binding != PBIND_NONE ) {
hwloc_bitmap_only(hwloc_set, binding);
return 0;
}
/* if not, check lgroups */
hwloc_bitmap_zero(hwloc_set);
n = hwloc_get_nbobjs_by_depth(topology, depth);
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
lgrp_affinity_t aff = lgrp_affinity_get(idtype, id, obj->os_index);
if (aff == LGRP_AFF_STRONG)
hwloc_bitmap_or(hwloc_set, hwloc_set, obj->cpuset);
}
if (hwloc_bitmap_iszero(hwloc_set))
hwloc_bitmap_copy(hwloc_set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
static int
hwloc_solaris_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t hwloc_set, int flags)
{
return hwloc_solaris_get_sth_cpubind(topology, P_PID, pid, hwloc_set, flags);
}
static int
hwloc_solaris_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags)
{
return hwloc_solaris_get_sth_cpubind(topology, P_PID, P_MYID, hwloc_set, flags);
}
static int
hwloc_solaris_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags)
{
return hwloc_solaris_get_sth_cpubind(topology, P_LWPID, P_MYID, hwloc_set, flags);
}
#endif /* HAVE_LIBLGRP */
/* TODO: given thread, probably not easy because of the historical n:m implementation */
#ifdef HAVE_LIBLGRP
static int
hwloc_solaris_set_sth_membind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
int depth;
int n, i;
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
break;
default:
errno = ENOSYS;
return -1;
}
if (flags & HWLOC_MEMBIND_NOCPUBIND) {
errno = ENOSYS;
return -1;
}
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
if (depth < 0) {
errno = EXDEV;
return -1;
}
n = hwloc_get_nbobjs_by_depth(topology, depth);
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
if (hwloc_bitmap_isset(nodeset, obj->os_index)) {
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_STRONG);
} else {
if (flags & HWLOC_CPUBIND_STRICT)
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE);
else
lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_WEAK);
}
}
return 0;
}
static int
hwloc_solaris_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_solaris_set_sth_membind(topology, P_PID, pid, nodeset, policy, flags);
}
static int
hwloc_solaris_set_thisproc_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_solaris_set_sth_membind(topology, P_PID, P_MYID, nodeset, policy, flags);
}
static int
hwloc_solaris_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_solaris_set_sth_membind(topology, P_LWPID, P_MYID, nodeset, policy, flags);
}
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)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE);
int n;
int i;
if (depth < 0) {
errno = ENOSYS;
return -1;
}
hwloc_bitmap_zero(nodeset);
n = hwloc_get_nbobjs_by_depth(topology, depth);
for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i);
lgrp_affinity_t aff = lgrp_affinity_get(idtype, id, obj->os_index);
if (aff == LGRP_AFF_STRONG)
hwloc_bitmap_set(nodeset, obj->os_index);
}
if (hwloc_bitmap_iszero(nodeset))
hwloc_bitmap_copy(nodeset, hwloc_topology_get_complete_nodeset(topology));
*policy = HWLOC_MEMBIND_DEFAULT;
return 0;
}
static int
hwloc_solaris_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags)
{
return hwloc_solaris_get_sth_membind(topology, P_PID, pid, nodeset, policy, flags);
}
static int
hwloc_solaris_get_thisproc_membind(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags)
{
return hwloc_solaris_get_sth_membind(topology, P_PID, P_MYID, nodeset, policy, flags);
}
static int
hwloc_solaris_get_thisthread_membind(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags)
{
return hwloc_solaris_get_sth_membind(topology, P_LWPID, P_MYID, nodeset, policy, flags);
}
#endif /* HAVE_LIBLGRP */
#ifdef MADV_ACCESS_LWP
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)
{
int advice;
size_t remainder;
/* Can not give a set of nodes just for an area. */
if (!hwloc_bitmap_isequal(nodeset, hwloc_topology_get_complete_nodeset(topology))) {
errno = EXDEV;
return -1;
}
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
advice = MADV_ACCESS_DEFAULT;
break;
case HWLOC_MEMBIND_FIRSTTOUCH:
case HWLOC_MEMBIND_NEXTTOUCH:
advice = MADV_ACCESS_LWP;
break;
case HWLOC_MEMBIND_INTERLEAVE:
advice = MADV_ACCESS_MANY;
break;
default:
errno = ENOSYS;
return -1;
}
remainder = (uintptr_t) addr & (sysconf(_SC_PAGESIZE)-1);
addr = (char*) addr - remainder;
len += remainder;
return madvise((void*) addr, len, advice);
}
#endif
#ifdef HAVE_LIBLGRP
static void
browse(struct hwloc_topology *topology, lgrp_cookie_t cookie, lgrp_id_t lgrp, hwloc_obj_t *glob_lgrps, unsigned *curlgrp)
{
int n;
hwloc_obj_t obj;
lgrp_mem_size_t mem_size;
n = lgrp_cpus(cookie, lgrp, NULL, 0, LGRP_CONTENT_HIERARCHY);
if (n == -1)
return;
/* Is this lgrp a NUMA node? */
if ((mem_size = lgrp_mem_size(cookie, lgrp, LGRP_MEM_SZ_INSTALLED, LGRP_CONTENT_DIRECT)) > 0)
{
int i;
processorid_t *cpuids;
cpuids = malloc(sizeof(processorid_t) * n);
assert(cpuids != NULL);
obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, lgrp);
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, lgrp);
obj->cpuset = hwloc_bitmap_alloc();
glob_lgrps[(*curlgrp)++] = obj;
lgrp_cpus(cookie, lgrp, cpuids, n, LGRP_CONTENT_HIERARCHY);
for (i = 0; i < n ; i++) {
hwloc_debug("node %ld's cpu %d is %d\n", lgrp, i, cpuids[i]);
hwloc_bitmap_set(obj->cpuset, cpuids[i]);
}
hwloc_debug_1arg_bitmap("node %ld has cpuset %s\n",
lgrp, obj->cpuset);
/* or LGRP_MEM_SZ_FREE */
hwloc_debug("node %ld has %lldkB\n", lgrp, mem_size/1024);
obj->memory.local_memory = mem_size;
obj->memory.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize();
#ifdef HAVE__SC_LARGE_PAGESIZE
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
hwloc_insert_object_by_cpuset(topology, obj);
free(cpuids);
}
n = lgrp_children(cookie, lgrp, NULL, 0);
{
lgrp_id_t *lgrps;
int i;
lgrps = malloc(sizeof(lgrp_id_t) * n);
assert(lgrps != NULL);
lgrp_children(cookie, lgrp, lgrps, n);
hwloc_debug("lgrp %ld has %d children\n", lgrp, n);
for (i = 0; i < n ; i++)
{
browse(topology, cookie, lgrps[i], glob_lgrps, curlgrp);
}
hwloc_debug("lgrp %ld's children done\n", lgrp);
free(lgrps);
}
}
static void
hwloc_look_lgrp(struct hwloc_topology *topology)
{
lgrp_cookie_t cookie;
unsigned curlgrp = 0;
int nlgrps;
lgrp_id_t root;
if ((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM))
cookie = lgrp_init(LGRP_VIEW_OS);
else
cookie = lgrp_init(LGRP_VIEW_CALLER);
if (cookie == LGRP_COOKIE_NONE)
{
hwloc_debug("lgrp_init failed: %s\n", strerror(errno));
return;
}
nlgrps = lgrp_nlgrps(cookie);
root = lgrp_root(cookie);
{
hwloc_obj_t *glob_lgrps = calloc(nlgrps, sizeof(hwloc_obj_t));
browse(topology, cookie, root, glob_lgrps, &curlgrp);
#ifdef HAVE_LGRP_LATENCY_COOKIE
{
float *distances = calloc(curlgrp*curlgrp, sizeof(float));
unsigned *indexes = calloc(curlgrp,sizeof(unsigned));
unsigned i, j;
for (i = 0; i < curlgrp; i++) {
indexes[i] = glob_lgrps[i]->os_index;
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);
}
hwloc_distances_set(topology, HWLOC_OBJ_NODE, curlgrp, indexes, glob_lgrps, distances, 0 /* OS cannot force */);
}
#endif /* HAVE_LGRP_LATENCY_COOKIE */
}
lgrp_fini(cookie);
}
#endif /* LIBLGRP */
#ifdef HAVE_LIBKSTAT
#include <kstat.h>
static int
hwloc_look_kstat(struct hwloc_topology *topology)
{
/* FIXME this assumes that all sockets are identical */
char *CPUType = hwloc_solaris_get_chip_type();
char *CPUModel = hwloc_solaris_get_chip_model();
kstat_ctl_t *kc = kstat_open();
kstat_t *ksp;
kstat_named_t *stat;
unsigned look_cores = 1, look_chips = 1;
unsigned Pproc_max = 0;
unsigned Pproc_alloc = 256;
struct hwloc_solaris_Pproc {
unsigned Lsock, Psock, Lcore, Lproc;
} * Pproc = malloc(Pproc_alloc * sizeof(*Pproc));
unsigned Lproc_num = 0;
unsigned Lproc_alloc = 256;
struct hwloc_solaris_Lproc {
unsigned Pproc;
} * Lproc = malloc(Lproc_alloc * sizeof(*Lproc));
unsigned Lcore_num = 0;
unsigned Lcore_alloc = 256;
struct hwloc_solaris_Lcore {
unsigned Pcore, Psock;
} * Lcore = malloc(Lcore_alloc * sizeof(*Lcore));
unsigned Lsock_num = 0;
unsigned Lsock_alloc = 256;
struct hwloc_solaris_Lsock {
unsigned Psock;
} * Lsock = malloc(Lsock_alloc * sizeof(*Lsock));
unsigned sockid, coreid, cpuid;
unsigned i;
for (i = 0; i < Pproc_alloc; i++) {
Pproc[i].Lproc = -1;
Pproc[i].Lsock = -1;
Pproc[i].Psock = -1;
Pproc[i].Lcore = -1;
}
if (!kc) {
hwloc_debug("kstat_open failed: %s\n", strerror(errno));
free(Pproc);
free(Lproc);
free(Lcore);
free(Lsock);
return 0;
}
for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next)
{
if (strncmp("cpu_info", ksp->ks_module, 8))
continue;
cpuid = ksp->ks_instance;
if (kstat_read(kc, ksp, NULL) == -1)
{
fprintf(stderr, "kstat_read failed for CPU%u: %s\n", cpuid, strerror(errno));
continue;
}
hwloc_debug("cpu%u\n", cpuid);
if (cpuid >= Pproc_alloc) {
Pproc_alloc *= 2;
Pproc = realloc(Pproc, Pproc_alloc * sizeof(*Pproc));
for(i = Pproc_alloc/2; i < Pproc_alloc; i++) {
Pproc[i].Lproc = -1;
Pproc[i].Lsock = -1;
Pproc[i].Psock = -1;
Pproc[i].Lcore = -1;
}
}
Pproc[cpuid].Lproc = Lproc_num;
if (Lproc_num >= Lproc_alloc) {
Lproc_alloc *= 2;
Lproc = realloc(Lproc, Lproc_alloc * sizeof(*Lproc));
}
Lproc[Lproc_num].Pproc = cpuid;
Lproc_num++;
if (cpuid >= Pproc_max)
Pproc_max = cpuid + 1;
stat = (kstat_named_t *) kstat_data_lookup(ksp, "state");
if (!stat)
hwloc_debug("could not read state for CPU%u: %s\n", cpuid, strerror(errno));
else if (stat->data_type != KSTAT_DATA_CHAR)
hwloc_debug("unknown kstat type %d for cpu state\n", stat->data_type);
else
{
hwloc_debug("cpu%u's state is %s\n", cpuid, stat->value.c);
if (strcmp(stat->value.c, "on-line"))
/* not online */
hwloc_bitmap_clr(topology->levels[0][0]->online_cpuset, cpuid);
}
if (look_chips) do {
/* Get Chip ID */
stat = (kstat_named_t *) kstat_data_lookup(ksp, "chip_id");
if (!stat)
{
if (Lsock_num)
fprintf(stderr, "could not read socket id for CPU%u: %s\n", cpuid, strerror(errno));
else
hwloc_debug("could not read socket id for CPU%u: %s\n", cpuid, strerror(errno));
look_chips = 0;
continue;
}
switch (stat->data_type) {
case KSTAT_DATA_INT32:
sockid = stat->value.i32;
break;
case KSTAT_DATA_UINT32:
sockid = stat->value.ui32;
break;
#ifdef _INT64_TYPE
case KSTAT_DATA_UINT64:
sockid = stat->value.ui64;
break;
case KSTAT_DATA_INT64:
sockid = stat->value.i64;
break;
#endif
default:
fprintf(stderr, "chip_id type %d unknown\n", stat->data_type);
look_chips = 0;
continue;
}
Pproc[cpuid].Psock = sockid;
for (i = 0; i < Lsock_num; i++)
if (sockid == Lsock[i].Psock)
break;
Pproc[cpuid].Lsock = i;
hwloc_debug("%u on socket %u (%u)\n", cpuid, i, sockid);
if (i == Lsock_num) {
if (Lsock_num == Lsock_alloc) {
Lsock_alloc *= 2;
Lsock = realloc(Lsock, Lsock_alloc * sizeof(*Lsock));
}
Lsock[Lsock_num++].Psock = sockid;
}
} while(0);
if (look_cores) do {
/* Get Core ID */
stat = (kstat_named_t *) kstat_data_lookup(ksp, "core_id");
if (!stat)
{
if (Lcore_num)
fprintf(stderr, "could not read core id for CPU%u: %s\n", cpuid, strerror(errno));
else
hwloc_debug("could not read core id for CPU%u: %s\n", cpuid, strerror(errno));
look_cores = 0;
continue;
}
switch (stat->data_type) {
case KSTAT_DATA_INT32:
coreid = stat->value.i32;
break;
case KSTAT_DATA_UINT32:
coreid = stat->value.ui32;
break;
#ifdef _INT64_TYPE
case KSTAT_DATA_UINT64:
coreid = stat->value.ui64;
break;
case KSTAT_DATA_INT64:
coreid = stat->value.i64;
break;
#endif
default:
fprintf(stderr, "core_id type %d unknown\n", stat->data_type);
look_cores = 0;
continue;
}
for (i = 0; i < Lcore_num; i++)
if (coreid == Lcore[i].Pcore && Pproc[cpuid].Psock == Lcore[i].Psock)
break;
Pproc[cpuid].Lcore = i;
hwloc_debug("%u on core %u (%u)\n", cpuid, i, coreid);
if (i == Lcore_num) {
if (Lcore_num == Lcore_alloc) {
Lcore_alloc *= 2;
Lcore = realloc(Lcore, Lcore_alloc * sizeof(*Lcore));
}
Lcore[Lcore_num].Psock = Pproc[cpuid].Psock;
Lcore[Lcore_num++].Pcore = coreid;
}
} while(0);
/* Note: there is also clog_id for the Thread ID (not unique) and
* pkg_core_id for the core ID (not unique). They are not useful to us
* however. */
}
if (look_chips) {
struct hwloc_obj *obj;
unsigned j,k;
hwloc_debug("%d Sockets\n", Lsock_num);
for (j = 0; j < Lsock_num; j++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, Lsock[j].Psock);
if (CPUType)
hwloc_obj_add_info(obj, "CPUType", CPUType);
if (CPUModel)
hwloc_obj_add_info(obj, "CPUModel", CPUModel);
obj->cpuset = hwloc_bitmap_alloc();
for(k=0; k<Pproc_max; k++)
if (Pproc[k].Lsock == j)
hwloc_bitmap_set(obj->cpuset, k);
hwloc_debug_1arg_bitmap("Socket %d has cpuset %s\n", j, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
hwloc_debug("%s", "\n");
}
if (look_cores) {
struct hwloc_obj *obj;
unsigned j,k;
hwloc_debug("%d Cores\n", Lcore_num);
for (j = 0; j < Lcore_num; j++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_CORE, Lcore[j].Pcore);
obj->cpuset = hwloc_bitmap_alloc();
for(k=0; k<Pproc_max; k++)
if (Pproc[k].Lcore == j)
hwloc_bitmap_set(obj->cpuset, k);
hwloc_debug_1arg_bitmap("Core %d has cpuset %s\n", j, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
hwloc_debug("%s", "\n");
}
if (Lproc_num) {
struct hwloc_obj *obj;
unsigned j,k;
hwloc_debug("%d PUs\n", Lproc_num);
for (j = 0; j < Lproc_num; j++) {
obj = hwloc_alloc_setup_object(HWLOC_OBJ_PU, Lproc[j].Pproc);
obj->cpuset = hwloc_bitmap_alloc();
for(k=0; k<Pproc_max; k++)
if (Pproc[k].Lproc == j)
hwloc_bitmap_set(obj->cpuset, k);
hwloc_debug_1arg_bitmap("PU %d has cpuset %s\n", j, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
hwloc_debug("%s", "\n");
}
kstat_close(kc);
free(Pproc);
free(Lproc);
free(Lcore);
free(Lsock);
return Lproc_num > 0;
}
#endif /* LIBKSTAT */
static int
hwloc_look_solaris(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors (topology);
int alreadypus = 0;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
#ifdef HAVE_LIBLGRP
hwloc_look_lgrp(topology);
#endif /* HAVE_LIBLGRP */
#ifdef HAVE_LIBKSTAT
nbprocs = 0;
if (hwloc_look_kstat(topology) > 0)
alreadypus = 1;
#endif /* HAVE_LIBKSTAT */
if (!alreadypus)
hwloc_setup_pu_level(topology, nbprocs);
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Solaris");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_solaris_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_solaris_set_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_solaris_set_thisproc_cpubind;
hooks->set_thisthread_cpubind = hwloc_solaris_set_thisthread_cpubind;
#ifdef HAVE_LIBLGRP
hooks->get_proc_cpubind = hwloc_solaris_get_proc_cpubind;
hooks->get_thisproc_cpubind = hwloc_solaris_get_thisproc_cpubind;
hooks->get_thisthread_cpubind = hwloc_solaris_get_thisthread_cpubind;
hooks->set_proc_membind = hwloc_solaris_set_proc_membind;
hooks->set_thisproc_membind = hwloc_solaris_set_thisproc_membind;
hooks->set_thisthread_membind = hwloc_solaris_set_thisthread_membind;
hooks->get_proc_membind = hwloc_solaris_get_proc_membind;
hooks->get_thisproc_membind = hwloc_solaris_get_thisproc_membind;
hooks->get_thisthread_membind = hwloc_solaris_get_thisthread_membind;
#endif /* HAVE_LIBLGRP */
#ifdef MADV_ACCESS_LWP
hooks->set_area_membind = hwloc_solaris_set_area_membind;
support->membind->firsttouch_membind = 1;
support->membind->bind_membind = 1;
support->membind->interleave_membind = 1;
support->membind->nexttouch_membind = 1;
#endif
}
static struct hwloc_backend *
hwloc_solaris_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_solaris;
return backend;
}
static struct hwloc_disc_component hwloc_solaris_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"solaris",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_solaris_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_solaris_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_solaris_disc_component
};

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

@ -0,0 +1,444 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/misc.h>
#include <private/debug.h>
#include <limits.h>
#include <assert.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
struct hwloc_synthetic_backend_data_s {
/* synthetic backend parameters */
char *string;
#define HWLOC_SYNTHETIC_MAX_DEPTH 128
unsigned arity[HWLOC_SYNTHETIC_MAX_DEPTH];
hwloc_obj_type_t type[HWLOC_SYNTHETIC_MAX_DEPTH];
unsigned id[HWLOC_SYNTHETIC_MAX_DEPTH];
unsigned depth[HWLOC_SYNTHETIC_MAX_DEPTH]; /* For cache/misc */
};
/* Read from description a series of integers describing a symmetrical
topology and update the hwloc_synthetic_backend_data_s accordingly. On
success, return zero. */
static int
hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data,
const char *description)
{
const char *pos, *next_pos;
unsigned long item, count;
unsigned i;
int cache_depth = 0, group_depth = 0;
int nb_machine_levels = 0, nb_node_levels = 0;
int nb_pu_levels = 0;
int verbose = 0;
char *env = getenv("HWLOC_SYNTHETIC_VERBOSE");
if (env)
verbose = atoi(env);
for (pos = description, count = 1; *pos; pos = next_pos) {
#define HWLOC_OBJ_TYPE_UNKNOWN ((hwloc_obj_type_t) -1)
hwloc_obj_type_t type = HWLOC_OBJ_TYPE_UNKNOWN;
while (*pos == ' ')
pos++;
if (!*pos)
break;
if (*pos < '0' || *pos > '9') {
if (!hwloc_namecoloncmp(pos, "machines", 2)) {
type = HWLOC_OBJ_MACHINE;
} else if (!hwloc_namecoloncmp(pos, "nodes", 1))
type = HWLOC_OBJ_NODE;
else if (!hwloc_namecoloncmp(pos, "sockets", 1))
type = HWLOC_OBJ_SOCKET;
else if (!hwloc_namecoloncmp(pos, "cores", 2))
type = HWLOC_OBJ_CORE;
else if (!hwloc_namecoloncmp(pos, "caches", 2))
type = HWLOC_OBJ_CACHE;
else if (!hwloc_namecoloncmp(pos, "pus", 1))
type = HWLOC_OBJ_PU;
else if (!hwloc_namecoloncmp(pos, "misc", 2))
type = HWLOC_OBJ_MISC;
else if (!hwloc_namecoloncmp(pos, "group", 2))
type = HWLOC_OBJ_GROUP;
else if (verbose)
fprintf(stderr, "Synthetic string with unknown object type `%s'\n", pos);
next_pos = strchr(pos, ':');
if (!next_pos) {
if (verbose)
fprintf(stderr,"Synthetic string doesn't have a `:' after object type at '%s'\n", pos);
errno = EINVAL;
return -1;
}
pos = next_pos + 1;
}
item = strtoul(pos, (char **)&next_pos, 0);
if (next_pos == pos) {
if (verbose)
fprintf(stderr,"Synthetic string doesn't have a number of objects at '%s'\n", pos);
errno = EINVAL;
return -1;
}
if (count + 1 >= HWLOC_SYNTHETIC_MAX_DEPTH) {
if (verbose)
fprintf(stderr,"Too many synthetic levels, max %d\n", HWLOC_SYNTHETIC_MAX_DEPTH);
errno = EINVAL;
return -1;
}
if (item > UINT_MAX) {
if (verbose)
fprintf(stderr,"Too big arity, max %u\n", UINT_MAX);
errno = EINVAL;
return -1;
}
data->arity[count-1] = (unsigned)item;
data->type[count] = type;
count++;
}
if (count <= 0) {
if (verbose)
fprintf(stderr, "Synthetic string doesn't contain any object\n");
errno = EINVAL;
return -1;
}
for(i=count-1; i>0; i--) {
hwloc_obj_type_t type;
type = data->type[i];
if (type == HWLOC_OBJ_TYPE_UNKNOWN) {
if (i == count-1)
type = HWLOC_OBJ_PU;
else {
switch (data->type[i+1]) {
case HWLOC_OBJ_PU: type = HWLOC_OBJ_CORE; break;
case HWLOC_OBJ_CORE: type = HWLOC_OBJ_CACHE; break;
case HWLOC_OBJ_CACHE: type = HWLOC_OBJ_SOCKET; break;
case HWLOC_OBJ_SOCKET: type = HWLOC_OBJ_NODE; break;
case HWLOC_OBJ_NODE:
case HWLOC_OBJ_GROUP: type = HWLOC_OBJ_GROUP; break;
case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_MISC: type = HWLOC_OBJ_MISC; break;
default:
assert(0);
}
}
data->type[i] = type;
}
switch (type) {
case HWLOC_OBJ_PU:
if (nb_pu_levels) {
if (verbose)
fprintf(stderr, "Synthetic string can not have several PU levels\n");
errno = EINVAL;
return -1;
}
nb_pu_levels++;
break;
case HWLOC_OBJ_CACHE:
cache_depth++;
break;
case HWLOC_OBJ_GROUP:
group_depth++;
break;
case HWLOC_OBJ_NODE:
nb_node_levels++;
break;
case HWLOC_OBJ_MACHINE:
nb_machine_levels++;
break;
default:
break;
}
}
if (!nb_pu_levels) {
if (verbose)
fprintf(stderr, "Synthetic string missing ending number of PUs\n");
errno = EINVAL;
return -1;
}
if (nb_pu_levels > 1) {
if (verbose)
fprintf(stderr, "Synthetic string can not have several PU levels\n");
errno = EINVAL;
return -1;
}
if (nb_node_levels > 1) {
if (verbose)
fprintf(stderr, "Synthetic string can not have several NUMA node levels\n");
errno = EINVAL;
return -1;
}
if (nb_machine_levels > 1) {
if (verbose)
fprintf(stderr, "Synthetic string can not have several machine levels\n");
errno = EINVAL;
return -1;
}
if (nb_machine_levels)
data->type[0] = HWLOC_OBJ_SYSTEM;
else {
data->type[0] = HWLOC_OBJ_MACHINE;
nb_machine_levels++;
}
if (cache_depth == 1)
/* if there is a single cache level, make it L2 */
cache_depth = 2;
for (i=0; i<count; i++) {
hwloc_obj_type_t type = data->type[i];
if (type == HWLOC_OBJ_GROUP)
data->depth[i] = group_depth--;
else if (type == HWLOC_OBJ_CACHE)
data->depth[i] = cache_depth--;
}
data->string = strdup(description);
data->arity[count-1] = 0;
return 0;
}
/*
* Recursively build objects whose cpu start at first_cpu
* - level gives where to look in the type, arity and id arrays
* - the id array is used as a variable to get unique IDs for a given level.
* - generated memory should be added to *memory_kB.
* - generated cpus should be added to parent_cpuset.
* - next cpu number to be used should be returned.
*/
static unsigned
hwloc__look_synthetic(struct hwloc_topology *topology,
struct hwloc_synthetic_backend_data_s *data,
int level, unsigned first_cpu,
hwloc_bitmap_t parent_cpuset)
{
hwloc_obj_t obj;
unsigned i;
hwloc_obj_type_t type = data->type[level];
/* pre-hooks */
switch (type) {
case HWLOC_OBJ_MISC:
break;
case HWLOC_OBJ_GROUP:
break;
case HWLOC_OBJ_SYSTEM:
case HWLOC_OBJ_BRIDGE:
case HWLOC_OBJ_PCI_DEVICE:
case HWLOC_OBJ_OS_DEVICE:
/* Shouldn't happen. */
abort();
break;
case HWLOC_OBJ_MACHINE:
break;
case HWLOC_OBJ_NODE:
break;
case HWLOC_OBJ_SOCKET:
break;
case HWLOC_OBJ_CACHE:
break;
case HWLOC_OBJ_CORE:
break;
case HWLOC_OBJ_PU:
break;
case HWLOC_OBJ_TYPE_MAX:
/* Should never happen */
assert(0);
break;
}
obj = hwloc_alloc_setup_object(type, data->id[level]++);
obj->cpuset = hwloc_bitmap_alloc();
if (!data->arity[level]) {
hwloc_bitmap_set(obj->cpuset, first_cpu++);
} else {
for (i = 0; i < data->arity[level]; i++)
first_cpu = hwloc__look_synthetic(topology, data, level + 1, first_cpu, obj->cpuset);
}
if (type == HWLOC_OBJ_NODE) {
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, obj->os_index);
}
hwloc_bitmap_or(parent_cpuset, parent_cpuset, obj->cpuset);
/* post-hooks */
switch (type) {
case HWLOC_OBJ_MISC:
break;
case HWLOC_OBJ_GROUP:
obj->attr->group.depth = data->depth[level];
break;
case HWLOC_OBJ_SYSTEM:
case HWLOC_OBJ_BRIDGE:
case HWLOC_OBJ_PCI_DEVICE:
case HWLOC_OBJ_OS_DEVICE:
abort();
break;
case HWLOC_OBJ_MACHINE:
break;
case HWLOC_OBJ_NODE:
/* 1GB in memory nodes, 256k 4k-pages. */
obj->memory.local_memory = 1024*1024*1024;
obj->memory.page_types_len = 1;
obj->memory.page_types = malloc(sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = 4096;
obj->memory.page_types[0].count = 256*1024;
break;
case HWLOC_OBJ_SOCKET:
break;
case HWLOC_OBJ_CACHE:
obj->attr->cache.depth = data->depth[level];
obj->attr->cache.linesize = 64;
if (obj->attr->cache.depth == 1) {
/* 32Kb in L1d */
obj->attr->cache.size = 32*1024;
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
} else {
/* *4 at each level, starting from 1MB for L2, unified */
obj->attr->cache.size = 256*1024 << (2*obj->attr->cache.depth);
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
}
break;
case HWLOC_OBJ_CORE:
break;
case HWLOC_OBJ_PU:
break;
case HWLOC_OBJ_TYPE_MAX:
/* Should never happen */
assert(0);
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
return first_cpu;
}
static int
hwloc_look_synthetic(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_synthetic_backend_data_s *data = backend->private_data;
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc();
unsigned first_cpu = 0, i;
assert(!topology->levels[0][0]->cpuset);
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
topology->support.discovery->pu = 1;
/* start with id=0 for each level */
for (i = 0; data->arity[i] > 0; i++)
data->id[i] = 0;
/* ... including the last one */
data->id[i] = 0;
/* update first level type according to the synthetic type array */
topology->levels[0][0]->type = data->type[0];
for (i = 0; i < data->arity[0]; i++)
first_cpu = hwloc__look_synthetic(topology, data, 1, first_cpu, cpuset);
hwloc_bitmap_free(cpuset);
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Synthetic");
hwloc_obj_add_info(topology->levels[0][0], "SyntheticDescription", data->string);
return 1;
}
static void
hwloc_synthetic_backend_disable(struct hwloc_backend *backend)
{
struct hwloc_synthetic_backend_data_s *data = backend->private_data;
free(data->string);
free(data);
}
static struct hwloc_backend *
hwloc_synthetic_component_instantiate(struct hwloc_disc_component *component,
const void *_data1,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
struct hwloc_synthetic_backend_data_s *data;
int err;
if (!_data1) {
errno = EINVAL;
goto out;
}
backend = hwloc_backend_alloc(component);
if (!backend)
goto out;
data = malloc(sizeof(*data));
if (!data) {
errno = ENOMEM;
goto out_with_backend;
}
err = hwloc_backend_synthetic_init(data, (const char *) _data1);
if (err < 0)
goto out_with_data;
backend->private_data = data;
backend->discover = hwloc_look_synthetic;
backend->disable = hwloc_synthetic_backend_disable;
backend->is_thissystem = 0;
return backend;
out_with_data:
free(data);
out_with_backend:
free(backend);
out:
return NULL;
}
static struct hwloc_disc_component hwloc_synthetic_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
"synthetic",
~0,
hwloc_synthetic_component_instantiate,
30,
NULL
};
const struct hwloc_component hwloc_synthetic_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_synthetic_disc_component
};

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

@ -0,0 +1,812 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* To try to get all declarations duplicated below. */
#define _WIN32_WINNT 0x0601
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#include <windows.h>
#ifndef HAVE_KAFFINITY
typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
#endif
#ifndef HAVE_PROCESSOR_CACHE_TYPE
typedef enum _PROCESSOR_CACHE_TYPE {
CacheUnified,
CacheInstruction,
CacheData,
CacheTrace
} PROCESSOR_CACHE_TYPE;
#endif
#ifndef CACHE_FULLY_ASSOCIATIVE
#define CACHE_FULLY_ASSOCIATIVE 0xFF
#endif
#ifndef HAVE_CACHE_DESCRIPTOR
typedef struct _CACHE_DESCRIPTOR {
BYTE Level;
BYTE Associativity;
WORD LineSize;
DWORD Size; /* in bytes */
PROCESSOR_CACHE_TYPE Type;
} CACHE_DESCRIPTOR, *PCACHE_DESCRIPTOR;
#endif
#ifndef HAVE_LOGICAL_PROCESSOR_RELATIONSHIP
typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
RelationProcessorCore,
RelationNumaNode,
RelationCache,
RelationProcessorPackage,
RelationGroup,
RelationAll = 0xffff
} LOGICAL_PROCESSOR_RELATIONSHIP;
#else /* HAVE_LOGICAL_PROCESSOR_RELATIONSHIP */
# ifndef HAVE_RELATIONPROCESSORPACKAGE
# define RelationProcessorPackage 3
# define RelationGroup 4
# define RelationAll 0xffff
# endif /* HAVE_RELATIONPROCESSORPACKAGE */
#endif /* HAVE_LOGICAL_PROCESSOR_RELATIONSHIP */
#ifndef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION
typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
ULONG_PTR ProcessorMask;
LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
_ANONYMOUS_UNION
union {
struct {
BYTE flags;
} ProcessorCore;
struct {
DWORD NodeNumber;
} NumaNode;
CACHE_DESCRIPTOR Cache;
ULONGLONG Reserved[2];
} DUMMYUNIONNAME;
} SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
#endif
/* Extended interface, for group support */
#ifndef HAVE_GROUP_AFFINITY
typedef struct _GROUP_AFFINITY {
KAFFINITY Mask;
WORD Group;
WORD Reserved[3];
} GROUP_AFFINITY, *PGROUP_AFFINITY;
#endif
#ifndef HAVE_PROCESSOR_RELATIONSHIP
typedef struct _PROCESSOR_RELATIONSHIP {
BYTE Flags;
BYTE Reserved[21];
WORD GroupCount;
GROUP_AFFINITY GroupMask[ANYSIZE_ARRAY];
} PROCESSOR_RELATIONSHIP, *PPROCESSOR_RELATIONSHIP;
#endif
#ifndef HAVE_NUMA_NODE_RELATIONSHIP
typedef struct _NUMA_NODE_RELATIONSHIP {
DWORD NodeNumber;
BYTE Reserved[20];
GROUP_AFFINITY GroupMask;
} NUMA_NODE_RELATIONSHIP, *PNUMA_NODE_RELATIONSHIP;
#endif
#ifndef HAVE_CACHE_RELATIONSHIP
typedef struct _CACHE_RELATIONSHIP {
BYTE Level;
BYTE Associativity;
WORD LineSize;
DWORD CacheSize;
PROCESSOR_CACHE_TYPE Type;
BYTE Reserved[20];
GROUP_AFFINITY GroupMask;
} CACHE_RELATIONSHIP, *PCACHE_RELATIONSHIP;
#endif
#ifndef HAVE_PROCESSOR_GROUP_INFO
typedef struct _PROCESSOR_GROUP_INFO {
BYTE MaximumProcessorCount;
BYTE ActiveProcessorCount;
BYTE Reserved[38];
KAFFINITY ActiveProcessorMask;
} PROCESSOR_GROUP_INFO, *PPROCESSOR_GROUP_INFO;
#endif
#ifndef HAVE_GROUP_RELATIONSHIP
typedef struct _GROUP_RELATIONSHIP {
WORD MaximumGroupCount;
WORD ActiveGroupCount;
ULONGLONG Reserved[2];
PROCESSOR_GROUP_INFO GroupInfo[ANYSIZE_ARRAY];
} GROUP_RELATIONSHIP, *PGROUP_RELATIONSHIP;
#endif
#ifndef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX {
LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
DWORD Size;
_ANONYMOUS_UNION
union {
PROCESSOR_RELATIONSHIP Processor;
NUMA_NODE_RELATIONSHIP NumaNode;
CACHE_RELATIONSHIP Cache;
GROUP_RELATIONSHIP Group;
/* Odd: no member to tell the cpu mask of the package... */
} DUMMYUNIONNAME;
} SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;
#endif
#ifndef HAVE_PSAPI_WORKING_SET_EX_BLOCK
typedef union _PSAPI_WORKING_SET_EX_BLOCK {
ULONG_PTR Flags;
struct {
unsigned Valid :1;
unsigned ShareCount :3;
unsigned Win32Protection :11;
unsigned Shared :1;
unsigned Node :6;
unsigned Locked :1;
unsigned LargePage :1;
};
} PSAPI_WORKING_SET_EX_BLOCK;
#endif
#ifndef HAVE_PSAPI_WORKING_SET_EX_INFORMATION
typedef struct _PSAPI_WORKING_SET_EX_INFORMATION {
PVOID VirtualAddress;
PSAPI_WORKING_SET_EX_BLOCK VirtualAttributes;
} PSAPI_WORKING_SET_EX_INFORMATION;
#endif
static void hwloc_bitmap_set_ith_ULONG_PTR(hwloc_bitmap_t set, unsigned i, ULONG_PTR mask)
{
/* ULONG_PTR is 64/32bits depending on the arch
* while unsigned long is always 32bits */
#if SIZEOF_VOID_P == 8
hwloc_bitmap_set_ith_ulong(set, 2*i, mask & 0xffffffff);
hwloc_bitmap_set_ith_ulong(set, 2*i+1, mask >> 32);
#else
hwloc_bitmap_set_ith_ulong(set, i, mask);
#endif
}
/* TODO: SetThreadIdealProcessor */
static int
hwloc_win_set_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t thread, hwloc_const_bitmap_t hwloc_set, int flags)
{
DWORD mask;
if (flags & HWLOC_CPUBIND_NOMEMBIND) {
errno = ENOSYS;
return -1;
}
/* TODO: groups SetThreadGroupAffinity */
/* The resulting binding is always strict */
mask = hwloc_bitmap_to_ulong(hwloc_set);
if (!SetThreadAffinityMask(thread, mask))
return -1;
return 0;
}
/* TODO: SetThreadGroupAffinity to get affinity */
static int
hwloc_win_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_win_set_thread_cpubind(topology, GetCurrentThread(), hwloc_set, flags);
}
static int
hwloc_win_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
int ret;
hwloc_cpuset_t cpuset;
if ((policy != HWLOC_MEMBIND_DEFAULT && policy != HWLOC_MEMBIND_BIND)
|| flags & HWLOC_MEMBIND_NOCPUBIND) {
errno = ENOSYS;
return -1;
}
cpuset = hwloc_bitmap_alloc();
hwloc_cpuset_from_nodeset(topology, cpuset, nodeset);
ret = hwloc_win_set_thisthread_cpubind(topology, cpuset, flags & HWLOC_MEMBIND_STRICT?HWLOC_CPUBIND_STRICT:0);
hwloc_bitmap_free(cpuset);
return ret;
}
static int
hwloc_win_set_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t proc, hwloc_const_bitmap_t hwloc_set, int flags)
{
DWORD mask;
if (flags & HWLOC_CPUBIND_NOMEMBIND) {
errno = ENOSYS;
return -1;
}
/* TODO: groups, hard: has to manually bind all threads into the other group,
* and the bind the process inside the group */
/* The resulting binding is always strict */
mask = hwloc_bitmap_to_ulong(hwloc_set);
if (!SetProcessAffinityMask(proc, mask))
return -1;
return 0;
}
static int
hwloc_win_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
int ret;
hwloc_cpuset_t cpuset;
if ((policy != HWLOC_MEMBIND_DEFAULT && policy != HWLOC_MEMBIND_BIND)
|| flags & HWLOC_MEMBIND_NOCPUBIND) {
errno = ENOSYS;
return -1;
}
cpuset = hwloc_bitmap_alloc();
hwloc_cpuset_from_nodeset(topology, cpuset, nodeset);
ret = hwloc_win_set_proc_cpubind(topology, pid, cpuset, flags & HWLOC_MEMBIND_STRICT?HWLOC_CPUBIND_STRICT:0);
hwloc_bitmap_free(cpuset);
return ret;
}
static int
hwloc_win_get_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t proc, hwloc_bitmap_t hwloc_set, int flags)
{
DWORD_PTR proc_mask, sys_mask;
if (flags & HWLOC_CPUBIND_NOMEMBIND) {
errno = ENOSYS;
return -1;
}
/* TODO: groups, GetProcessGroupAffinity, or merge SetThreadGroupAffinity for all threads */
if (!GetProcessAffinityMask(proc, &proc_mask, &sys_mask))
return -1;
hwloc_bitmap_from_ulong(hwloc_set, proc_mask);
return 0;
}
static int
hwloc_win_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
int ret;
hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
ret = hwloc_win_get_proc_cpubind(topology, pid, cpuset, flags & HWLOC_MEMBIND_STRICT?HWLOC_CPUBIND_STRICT:0);
if (!ret) {
*policy = HWLOC_MEMBIND_BIND;
hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
}
hwloc_bitmap_free(cpuset);
return ret;
}
static int
hwloc_win_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags)
{
return hwloc_win_set_proc_cpubind(topology, GetCurrentProcess(), hwloc_set, flags);
}
static int
hwloc_win_set_thisproc_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_win_set_proc_membind(topology, GetCurrentProcess(), nodeset, policy, flags);
}
static int
hwloc_win_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_cpuset, int flags)
{
return hwloc_win_get_proc_cpubind(topology, GetCurrentProcess(), hwloc_cpuset, flags);
}
static int
hwloc_win_get_thisproc_membind(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
return hwloc_win_get_proc_membind(topology, GetCurrentProcess(), nodeset, policy, flags);
}
static LPVOID (WINAPI *VirtualAllocExNumaProc)(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, DWORD nndPreferred);
static BOOL (WINAPI *VirtualFreeExProc)(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
static BOOL (WINAPI *QueryWorkingSetExProc)(HANDLE hProcess, PVOID pv, DWORD cb);
static int hwloc_win_get_VirtualAllocExNumaProc(void) {
if (VirtualAllocExNumaProc == NULL) {
FARPROC alloc_fun = NULL, free_fun = NULL;
HMODULE kernel32;
kernel32 = LoadLibrary("kernel32.dll");
if (kernel32) {
alloc_fun = GetProcAddress(kernel32, "VirtualAllocExNuma");
free_fun = GetProcAddress(kernel32, "VirtualFreeEx");
}
if (!alloc_fun || !free_fun) {
VirtualAllocExNumaProc = (FARPROC) -1;
errno = ENOSYS;
return -1;
}
VirtualAllocExNumaProc = alloc_fun;
VirtualFreeExProc = free_fun;
} else if ((FARPROC) VirtualAllocExNumaProc == (FARPROC)-1) {
errno = ENOSYS;
return -1;
}
return 0;
}
static void *
hwloc_win_alloc(hwloc_topology_t topology __hwloc_attribute_unused, size_t len) {
return VirtualAlloc(NULL, len, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
static void *
hwloc_win_alloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) {
int node;
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND:
break;
default:
errno = ENOSYS;
return hwloc_alloc_or_fail(topology, len, flags);
}
if (flags & HWLOC_MEMBIND_STRICT) {
errno = ENOSYS;
return NULL;
}
if (hwloc_bitmap_weight(nodeset) != 1) {
/* Not a single node, can't do this */
errno = EXDEV;
return hwloc_alloc_or_fail(topology, len, flags);
}
node = hwloc_bitmap_first(nodeset);
return VirtualAllocExNumaProc(GetCurrentProcess(), NULL, len, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE, node);
}
static int
hwloc_win_free_membind(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len __hwloc_attribute_unused) {
if (!addr)
return 0;
if (!VirtualFreeExProc(GetCurrentProcess(), addr, 0, MEM_RELEASE))
return -1;
return 0;
}
static int hwloc_win_get_QueryWorkingSetExProc(void) {
if (QueryWorkingSetExProc == NULL) {
FARPROC fun = NULL;
HMODULE kernel32, psapi;
kernel32 = LoadLibrary("kernel32.dll");
if (kernel32)
fun = GetProcAddress(kernel32, "K32QueryWorkingSetEx");
if (!fun) {
psapi = LoadLibrary("psapi.dll");
if (psapi)
fun = GetProcAddress(psapi, "QueryWorkingSetEx");
}
if (!fun) {
QueryWorkingSetExProc = (FARPROC) -1;
errno = ENOSYS;
return -1;
}
QueryWorkingSetExProc = fun;
} else if ((FARPROC) QueryWorkingSetExProc == (FARPROC)-1) {
errno = ENOSYS;
return -1;
}
return 0;
}
static int
hwloc_win_get_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
SYSTEM_INFO SystemInfo;
DWORD page_size;
uintptr_t start;
unsigned nb;
GetSystemInfo(&SystemInfo);
page_size = SystemInfo.dwPageSize;
start = (((uintptr_t) addr) / page_size) * page_size;
nb = (((uintptr_t) addr + len - start) + page_size - 1) / page_size;
if (!nb)
nb = 1;
{
PSAPI_WORKING_SET_EX_INFORMATION *pv;
unsigned i;
pv = calloc(nb, sizeof(*pv));
for (i = 0; i < nb; i++)
pv[i].VirtualAddress = (void*) (start + i * page_size);
if (!QueryWorkingSetExProc(GetCurrentProcess(), pv, nb * sizeof(*pv))) {
free(pv);
return -1;
}
*policy = HWLOC_MEMBIND_BIND;
if (flags & HWLOC_MEMBIND_STRICT) {
unsigned node = pv[0].VirtualAttributes.Node;
for (i = 1; i < nb; i++) {
if (pv[i].VirtualAttributes.Node != node) {
errno = EXDEV;
free(pv);
return -1;
}
}
hwloc_bitmap_only(nodeset, node);
free(pv);
return 0;
}
hwloc_bitmap_zero(nodeset);
for (i = 0; i < nb; i++)
hwloc_bitmap_set(nodeset, pv[i].VirtualAttributes.Node);
free(pv);
return 0;
}
}
static int
hwloc_look_windows(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
BOOL (WINAPI *GetLogicalProcessorInformationProc)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, PDWORD ReturnLength);
BOOL (WINAPI *GetLogicalProcessorInformationExProc)(LOGICAL_PROCESSOR_RELATIONSHIP relationship, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Buffer, PDWORD ReturnLength);
BOOL (WINAPI *GetNumaAvailableMemoryNodeProc)(UCHAR Node, PULONGLONG AvailableBytes);
BOOL (WINAPI *GetNumaAvailableMemoryNodeExProc)(USHORT Node, PULONGLONG AvailableBytes);
SYSTEM_INFO SystemInfo;
DWORD length;
HMODULE kernel32;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return 0;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
GetSystemInfo(&SystemInfo);
kernel32 = LoadLibrary("kernel32.dll");
if (kernel32) {
GetLogicalProcessorInformationProc = GetProcAddress(kernel32, "GetLogicalProcessorInformation");
GetNumaAvailableMemoryNodeProc = GetProcAddress(kernel32, "GetNumaAvailableMemoryNode");
GetNumaAvailableMemoryNodeExProc = GetProcAddress(kernel32, "GetNumaAvailableMemoryNodeEx");
GetLogicalProcessorInformationExProc = GetProcAddress(kernel32, "GetLogicalProcessorInformationEx");
if (!GetLogicalProcessorInformationExProc && GetLogicalProcessorInformationProc) {
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION procInfo;
unsigned id;
unsigned i;
struct hwloc_obj *obj;
hwloc_obj_type_t type;
length = 0;
procInfo = NULL;
while (1) {
if (GetLogicalProcessorInformationProc(procInfo, &length))
break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
procInfo = realloc(procInfo, length);
}
assert(!length || procInfo);
for (i = 0; i < length / sizeof(*procInfo); i++) {
/* Ignore unknown caches */
if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction)
continue;
id = -1;
switch (procInfo[i].Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NODE;
id = procInfo[i].NumaNode.NodeNumber;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_SOCKET;
break;
case RelationCache:
type = HWLOC_OBJ_CACHE;
break;
case RelationProcessorCore:
type = HWLOC_OBJ_CORE;
break;
case RelationGroup:
default:
type = HWLOC_OBJ_GROUP;
break;
}
obj = hwloc_alloc_setup_object(type, id);
obj->cpuset = hwloc_bitmap_alloc();
hwloc_debug("%s#%u mask %lx\n", hwloc_obj_type_string(type), id, procInfo[i].ProcessorMask);
/* ProcessorMask is a ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, 0, procInfo[i].ProcessorMask);
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) {
case HWLOC_OBJ_NODE:
{
ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail)))
obj->memory.local_memory = avail;
obj->memory.page_types_len = 2;
obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types));
obj->memory.page_types_len = 1;
obj->memory.page_types[0].size = SystemInfo.dwPageSize;
#ifdef HAVE__SC_LARGE_PAGESIZE
obj->memory.page_types_len++;
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
break;
}
case HWLOC_OBJ_CACHE:
obj->attr->cache.size = procInfo[i].Cache.Size;
obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ;
obj->attr->cache.linesize = procInfo[i].Cache.LineSize;
obj->attr->cache.depth = procInfo[i].Cache.Level;
switch (procInfo->Cache.Type) {
case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
default:
hwloc_free_unlinked_object(obj);
continue;
}
break;
case HWLOC_OBJ_GROUP:
obj->attr->group.depth = procInfo[i].Relationship == RelationGroup;
break;
default:
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
}
free(procInfo);
}
if (GetLogicalProcessorInformationExProc) {
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX procInfoTotal, procInfo;
unsigned id;
struct hwloc_obj *obj;
hwloc_obj_type_t type;
length = 0;
procInfoTotal = NULL;
while (1) {
if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length))
break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
procInfoTotal = realloc(procInfoTotal, length);
}
for (procInfo = procInfoTotal;
(void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length);
procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) {
unsigned num, i;
GROUP_AFFINITY *GroupMask;
/* Ignore unknown caches */
if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction)
continue;
id = -1;
switch (procInfo->Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NODE;
num = 1;
GroupMask = &procInfo->NumaNode.GroupMask;
id = procInfo->NumaNode.NodeNumber;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_SOCKET;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
case RelationCache:
type = HWLOC_OBJ_CACHE;
num = 1;
GroupMask = &procInfo->Cache.GroupMask;
break;
case RelationProcessorCore:
type = HWLOC_OBJ_CORE;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
case RelationGroup:
/* So strange an interface... */
for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) {
KAFFINITY mask;
obj = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, id);
obj->cpuset = hwloc_bitmap_alloc();
mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask;
hwloc_debug("group %u %d cpus mask %lx\n", id,
procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask);
/* KAFFINITY is ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, id, mask);
hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
continue;
default:
/* Don't know how to get the mask. */
hwloc_debug("unknown relation %d\n", procInfo->Relationship);
continue;
}
obj = hwloc_alloc_setup_object(type, id);
obj->cpuset = hwloc_bitmap_alloc();
for (i = 0; i < num; i++) {
hwloc_debug("%s#%u %d: mask %d:%lx\n", hwloc_obj_type_string(type), id, i, GroupMask[i].Group, GroupMask[i].Mask);
/* GROUP_AFFINITY.Mask is KAFFINITY, which is ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, GroupMask[i].Group, GroupMask[i].Mask);
}
hwloc_debug("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) {
case HWLOC_OBJ_NODE:
{
ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail)))
obj->memory.local_memory = avail;
obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types));
obj->memory.page_types_len = 1;
obj->memory.page_types[0].size = SystemInfo.dwPageSize;
#ifdef HAVE__SC_LARGE_PAGESIZE
obj->memory.page_types_len++;
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
break;
}
case HWLOC_OBJ_CACHE:
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.linesize = procInfo->Cache.LineSize;
obj->attr->cache.depth = procInfo->Cache.Level;
switch (procInfo->Cache.Type) {
case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
default:
hwloc_free_unlinked_object(obj);
continue;
}
break;
default:
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
}
free(procInfoTotal);
}
}
/* add PU objects */
hwloc_setup_pu_level(topology, hwloc_fallback_nbprocessors(topology));
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Windows");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
return 1;
}
void
hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support)
{
hooks->set_proc_cpubind = hwloc_win_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_win_get_proc_cpubind;
hooks->set_thread_cpubind = hwloc_win_set_thread_cpubind;
hooks->set_thisproc_cpubind = hwloc_win_set_thisproc_cpubind;
hooks->get_thisproc_cpubind = hwloc_win_get_thisproc_cpubind;
hooks->set_thisthread_cpubind = hwloc_win_set_thisthread_cpubind;
/* TODO: get_last_cpu_location: use GetCurrentProcessorNumber */
hooks->set_proc_membind = hwloc_win_set_proc_membind;
hooks->get_proc_membind = hwloc_win_get_proc_membind;
hooks->set_thisproc_membind = hwloc_win_set_thisproc_membind;
hooks->get_thisproc_membind = hwloc_win_get_thisproc_membind;
hooks->set_thisthread_membind = hwloc_win_set_thisthread_membind;
if (!hwloc_win_get_VirtualAllocExNumaProc()) {
hooks->alloc_membind = hwloc_win_alloc_membind;
hooks->alloc = hwloc_win_alloc;
hooks->free_membind = hwloc_win_free_membind;
support->membind->bind_membind = 1;
}
if (!hwloc_win_get_QueryWorkingSetExProc())
hooks->get_area_membind = hwloc_win_get_area_membind;
}
static struct hwloc_backend *
hwloc_windows_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->discover = hwloc_look_windows;
return backend;
}
static struct hwloc_disc_component hwloc_windows_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"windows",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_windows_component_instantiate,
50,
NULL
};
const struct hwloc_component hwloc_windows_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_windows_disc_component
};

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

@ -0,0 +1,922 @@
/*
* Copyright © 2010-2013 Inria. All rights reserved.
* Copyright © 2010-2012 Université Bordeaux 1
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*
*
* This backend is only used when the operating system does not export
* the necessary hardware topology information to user-space applications.
* Currently, only the FreeBSD backend relies on this x86 backend.
*
* Other backends such as Linux have their own way to retrieve various
* pieces of hardware topology information from the operating system
* on various architectures, without having to use this x86-specific code.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/private.h>
#include <private/debug.h>
#include <private/misc.h>
#include <private/cpuid.h>
#define has_topoext(features) ((features)[6] & (1 << 22))
struct cacheinfo {
unsigned type;
unsigned level;
unsigned nbthreads_sharing;
unsigned linesize;
unsigned linepart;
int ways;
unsigned sets;
unsigned size;
};
struct procinfo {
unsigned present;
unsigned apicid;
unsigned max_log_proc;
unsigned max_nbcores;
unsigned max_nbthreads;
unsigned socketid;
unsigned nodeid;
unsigned unitid;
unsigned logprocid;
unsigned threadid;
unsigned coreid;
unsigned *otherids;
unsigned levels;
unsigned numcaches;
struct cacheinfo *cache;
char cpumodel[3*4*4+1];
};
enum cpuid_type {
intel,
amd,
unknown
};
static void fill_amd_cache(struct procinfo *infos, unsigned level, unsigned cpuid)
{
struct cacheinfo *cache;
unsigned cachenum;
unsigned size = 0;
if (level == 1)
size = ((cpuid >> 24)) << 10;
else if (level == 2)
size = ((cpuid >> 16)) << 10;
else if (level == 3)
size = ((cpuid >> 18)) << 19;
if (!size)
return;
cachenum = infos->numcaches++;
infos->cache = realloc(infos->cache, infos->numcaches*sizeof(*infos->cache));
cache = &infos->cache[cachenum];
cache->type = 1;
cache->level = level;
if (level <= 2)
cache->nbthreads_sharing = 1;
else
cache->nbthreads_sharing = infos->max_log_proc;
cache->linesize = cpuid & 0xff;
cache->linepart = 0;
if (level == 1) {
cache->ways = (cpuid >> 16) & 0xff;
if (cache->ways == 0xff)
/* Fully associative */
cache->ways = -1;
} else {
static const unsigned ways_tab[] = { 0, 1, 2, 0, 4, 0, 8, 0, 16, 0, 32, 48, 64, 96, 128, -1 };
unsigned ways = (cpuid >> 12) & 0xf;
cache->ways = ways_tab[ways];
}
cache->size = size;
cache->sets = 0;
hwloc_debug("cache L%u t%u linesize %u ways %u size %uKB\n", cache->level, cache->nbthreads_sharing, cache->linesize, cache->ways, cache->size >> 10);
}
/* Fetch information from the processor itself thanks to cpuid and store it in
* 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)
{
unsigned eax, ebx, ecx = 0, edx;
unsigned cachenum;
struct cacheinfo *cache;
infos->present = 1;
eax = 0x01;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
infos->apicid = ebx >> 24;
if (edx & (1 << 28))
infos->max_log_proc = 1 << hwloc_flsl(((ebx >> 16) & 0xff) - 1);
else
infos->max_log_proc = 1;
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->logprocid = infos->apicid % infos->max_log_proc;
hwloc_debug("phys %u thread %u\n", infos->socketid, infos->logprocid);
if (highest_ext_cpuid >= 0x80000004) {
unsigned regs[4] = { 0 };
regs[0] = 0x80000002;
hwloc_cpuid(&regs[0], &regs[1], &regs[2], &regs[3]);
memcpy(infos->cpumodel, regs, 4*4);
regs[0] = 0x80000003;
hwloc_cpuid(&regs[0], &regs[1], &regs[2], &regs[3]);
memcpy(infos->cpumodel + 4*4, regs, 4*4);
regs[0] = 0x80000004;
hwloc_cpuid(&regs[0], &regs[1], &regs[2], &regs[3]);
memcpy(infos->cpumodel + 4*4*2, regs, 4*4);
infos->cpumodel[3*4*4] = 0;
} else
infos->cpumodel[0] = 0;
/* Intel doesn't actually provide 0x80000008 information */
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000008) {
unsigned coreidsize;
eax = 0x80000008;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
coreidsize = (ecx >> 12) & 0xf;
hwloc_debug("core ID size: %u\n", coreidsize);
if (!coreidsize) {
infos->max_nbcores = (ecx & 0xff) + 1;
} else
infos->max_nbcores = 1 << coreidsize;
hwloc_debug("Thus max # of cores: %u\n", infos->max_nbcores);
/* Still no multithreaded AMD */
infos->max_nbthreads = 1 ;
hwloc_debug("and max # of threads: %u\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);
}
infos->numcaches = 0;
infos->cache = NULL;
/* AMD topology extension */
if (cpuid_type != intel && has_topoext(features)) {
unsigned apic_id, node_id, nodes_per_proc, unit_id, cores_per_unit;
eax = 0x8000001e;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
infos->apicid = apic_id = eax;
infos->nodeid = node_id = ecx & 0xff;
nodes_per_proc = ((ecx >> 8) & 7) + 1;
if (nodes_per_proc > 2) {
hwloc_debug("warning: undefined value %d, assuming it means %d\n", nodes_per_proc, nodes_per_proc);
}
infos->unitid = unit_id = ebx & 0xff;
cores_per_unit = ((ebx >> 8) & 3) + 1;
hwloc_debug("x2APIC %08x, %d nodes, node %d, %d cores in unit %d\n", apic_id, nodes_per_proc, node_id, cores_per_unit, unit_id);
for (cachenum = 0; ; cachenum++) {
unsigned type;
eax = 0x8000001d;
ecx = cachenum;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
type = eax & 0x1f;
if (type == 0)
break;
infos->numcaches++;
}
cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache));
for (cachenum = 0; ; cachenum++) {
unsigned linesize, linepart, ways, sets;
unsigned type;
eax = 0x8000001d;
ecx = cachenum;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
type = eax & 0x1f;
if (type == 0)
break;
cache->type = type;
cache->level = (eax >> 5) & 0x7;
/* Note: actually number of cores */
cache->nbthreads_sharing = ((eax >> 14) & 0xfff) + 1;
cache->linesize = linesize = (ebx & 0xfff) + 1;
cache->linepart = linepart = ((ebx >> 12) & 0x3ff) + 1;
ways = ((ebx >> 22) & 0x3ff) + 1;
if (eax & (1 << 9))
/* Fully associative */
cache->ways = -1;
else
cache->ways = ways;
cache->sets = sets = ecx + 1;
cache->size = linesize * linepart * ways * sets;
hwloc_debug("cache %u type %u L%u t%u c%u linesize %u linepart %u ways %u sets %u, size %uKB\n", cachenum, cache->type, cache->level, cache->nbthreads_sharing, infos->max_nbcores, linesize, linepart, ways, sets, cache->size >> 10);
cache++;
}
} else {
/* Intel doesn't actually provide 0x80000005 information */
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000005) {
eax = 0x80000005;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
fill_amd_cache(infos, 1, ecx);
}
/* Intel doesn't actually provide 0x80000006 information */
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000006) {
eax = 0x80000006;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
fill_amd_cache(infos, 2, ecx);
fill_amd_cache(infos, 3, edx);
}
}
/* AMD doesn't actually provide 0x04 information */
if (cpuid_type != amd && highest_cpuid >= 0x04) {
for (cachenum = 0; ; cachenum++) {
unsigned type;
eax = 0x04;
ecx = cachenum;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
type = eax & 0x1f;
hwloc_debug("cache %u type %u\n", cachenum, type);
if (type == 0)
break;
infos->numcaches++;
}
cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache));
for (cachenum = 0; ; cachenum++) {
unsigned linesize, linepart, ways, sets;
unsigned type;
eax = 0x04;
ecx = cachenum;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
type = eax & 0x1f;
if (type == 0)
break;
cache->type = type;
cache->level = (eax >> 5) & 0x7;
cache->nbthreads_sharing = ((eax >> 14) & 0xfff) + 1;
infos->max_nbcores = ((eax >> 26) & 0x3f) + 1;
cache->linesize = linesize = (ebx & 0xfff) + 1;
cache->linepart = linepart = ((ebx >> 12) & 0x3ff) + 1;
ways = ((ebx >> 22) & 0x3ff) + 1;
if (eax & (1 << 9))
/* Fully associative */
cache->ways = -1;
else
cache->ways = ways;
cache->sets = sets = ecx + 1;
cache->size = linesize * linepart * ways * sets;
hwloc_debug("cache %u type %u L%u t%u c%u linesize %u linepart %u ways %u sets %u, 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++;
}
}
if (cpuid_type == intel && highest_cpuid >= 0x0b) {
unsigned level, apic_nextshift, apic_number, apic_type, apic_id = 0, apic_shift = 0, id;
for (level = 0; ; level++) {
ecx = level;
eax = 0x0b;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
if (!eax && !ebx)
break;
}
if (level) {
infos->levels = level;
infos->otherids = malloc(level * sizeof(*infos->otherids));
for (level = 0; ; level++) {
ecx = level;
eax = 0x0b;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
if (!eax && !ebx)
break;
apic_nextshift = eax & 0x1f;
apic_number = ebx & 0xffff;
apic_type = (ecx & 0xff00) >> 8;
apic_id = edx;
id = (apic_id >> apic_shift) & ((1 << (apic_nextshift - apic_shift)) - 1);
hwloc_debug("x2APIC %08x %d: nextshift %d num %2d type %d id %2d\n", apic_id, level, apic_nextshift, apic_number, apic_type, id);
infos->apicid = apic_id;
infos->otherids[level] = UINT_MAX;
switch (apic_type) {
case 1:
infos->threadid = id;
break;
case 2:
infos->coreid = id;
break;
default:
hwloc_debug("x2APIC %d: unknown type %d\n", level, apic_type);
infos->otherids[level] = apic_id >> apic_shift;
break;
}
apic_shift = apic_nextshift;
}
infos->socketid = apic_id >> apic_shift;
hwloc_debug("x2APIC remainder: %d\n", infos->socketid);
} else
infos->otherids = NULL;
} else
infos->otherids = NULL;
}
/* Analyse information stored in infos, and build/annotate topology levels accordingly */
static void summarize(hwloc_topology_t topology, struct procinfo *infos, unsigned nbprocs,
int fulldiscovery)
{
hwloc_bitmap_t complete_cpuset = hwloc_bitmap_alloc();
unsigned i, j, l, level, type;
unsigned nbsockets = 0;
int one = -1;
for (i = 0; i < nbprocs; i++)
if (infos[i].present) {
hwloc_bitmap_set(complete_cpuset, i);
one = i;
}
if (one == -1) {
hwloc_bitmap_free(complete_cpuset);
return;
}
/* Ideally, when fulldiscovery=0, we could add any object that doesn't exist yet.
* But what if the x86 and the native backends disagree because one is buggy? Which one to trust?
* Only annotate existing objects for now.
*/
/* Look for sockets */
if (fulldiscovery) {
hwloc_bitmap_t sockets_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t socket_cpuset;
hwloc_obj_t socket;
while ((i = hwloc_bitmap_first(sockets_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid;
socket_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) {
if (infos[j].socketid == socketid) {
hwloc_bitmap_set(socket_cpuset, j);
hwloc_bitmap_clr(sockets_cpuset, j);
}
}
socket = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, socketid);
socket->cpuset = socket_cpuset;
if (infos[i].cpumodel[0]) {
const char *c = infos[i].cpumodel;
while (*c == ' ')
c++;
hwloc_obj_add_info(socket, "CPUModel", c);
}
hwloc_debug_1arg_bitmap("os socket %u has cpuset %s\n",
socketid, socket_cpuset);
hwloc_insert_object_by_cpuset(topology, socket);
nbsockets++;
}
hwloc_bitmap_free(sockets_cpuset);
} else {
/* Annotate sockets previously-existing sockets */
hwloc_obj_t socket = NULL;
int same = 1;
nbsockets = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_SOCKET);
/* check whether all sockets have the same info */
for(i=1; i<nbprocs; i++) {
if (strcmp(infos[i].cpumodel, infos[0].cpumodel)) {
same = 0;
break;
}
}
/* now iterate over sockets and annotate them */
while ((socket = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_SOCKET, socket)) != NULL) {
if (socket->os_index == (unsigned) -1) {
/* try to fix the socket OS index if unknown.
* FIXME: ideally, we should check all bits in case x86 and the native backend disagree.
*/
for(i=0; i<nbprocs; i++) {
if (hwloc_bitmap_isset(socket->cpuset, i)) {
socket->os_index = infos[i].socketid;
break;
}
}
}
if (!hwloc_obj_get_info_by_name(socket, "CPUModel")) {
/* add a CPUModel info */
for(i=0; i<nbprocs; i++)
/* if there's a single socket, 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 (nbsockets == 1 || infos[i].socketid == socket->os_index || (same && socket->os_index == (unsigned) -1)) {
if (infos[i].cpumodel[0]) {
const char *c = infos[i].cpumodel;
while (*c == ' ')
c++;
hwloc_obj_add_info(socket, "CPUModel", c);
}
break;
}
}
}
}
/* If there was no socket, annotate the Machine instead */
if ((!nbsockets) && infos[0].cpumodel[0]) {
const char *c = infos[0].cpumodel;
while (*c == ' ')
c++;
hwloc_obj_add_info(hwloc_get_root_obj(topology), "CPUModel", c);
}
/* Look for Numa nodes inside sockets */
if (fulldiscovery) {
hwloc_bitmap_t nodes_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t node_cpuset;
hwloc_obj_t node;
while ((i = hwloc_bitmap_first(nodes_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid;
unsigned nodeid = infos[i].nodeid;
if (nodeid == (unsigned)-1) {
hwloc_bitmap_clr(nodes_cpuset, i);
continue;
}
node_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) {
if (infos[j].nodeid == (unsigned) -1) {
hwloc_bitmap_clr(nodes_cpuset, j);
continue;
}
if (infos[j].socketid == socketid && infos[j].nodeid == nodeid) {
hwloc_bitmap_set(node_cpuset, j);
hwloc_bitmap_clr(nodes_cpuset, j);
}
}
node = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, nodeid);
node->cpuset = node_cpuset;
hwloc_debug_1arg_bitmap("os node %u has cpuset %s\n",
nodeid, node_cpuset);
hwloc_insert_object_by_cpuset(topology, node);
}
hwloc_bitmap_free(nodes_cpuset);
}
/* Look for Compute units inside sockets */
if (fulldiscovery) {
hwloc_bitmap_t units_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t unit_cpuset;
hwloc_obj_t unit;
while ((i = hwloc_bitmap_first(units_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid;
unsigned unitid = infos[i].unitid;
if (unitid == (unsigned)-1) {
hwloc_bitmap_clr(units_cpuset, i);
continue;
}
unit_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) {
if (infos[j].unitid == (unsigned) -1) {
hwloc_bitmap_clr(units_cpuset, j);
continue;
}
if (infos[j].socketid == socketid && infos[j].unitid == unitid) {
hwloc_bitmap_set(unit_cpuset, j);
hwloc_bitmap_clr(units_cpuset, j);
}
}
unit = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, unitid);
unit->cpuset = unit_cpuset;
hwloc_debug_1arg_bitmap("os unit %u has cpuset %s\n",
unitid, unit_cpuset);
hwloc_insert_object_by_cpuset(topology, unit);
}
hwloc_bitmap_free(units_cpuset);
}
/* Look for unknown objects */
if (infos[one].otherids) {
for (level = infos[one].levels-1; level <= infos[one].levels-1; level--) {
if (infos[one].otherids[level] != UINT_MAX) {
hwloc_bitmap_t unknowns_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t unknown_cpuset;
hwloc_obj_t unknown_obj;
while ((i = hwloc_bitmap_first(unknowns_cpuset)) != (unsigned) -1) {
unsigned unknownid = infos[i].otherids[level];
unknown_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) {
if (infos[j].otherids[level] == unknownid) {
hwloc_bitmap_set(unknown_cpuset, j);
hwloc_bitmap_clr(unknowns_cpuset, j);
}
}
unknown_obj = hwloc_alloc_setup_object(HWLOC_OBJ_MISC, unknownid);
unknown_obj->cpuset = unknown_cpuset;
unknown_obj->os_level = level;
hwloc_debug_2args_bitmap("os unknown%d %u has cpuset %s\n",
level, unknownid, unknown_cpuset);
hwloc_insert_object_by_cpuset(topology, unknown_obj);
}
hwloc_bitmap_free(unknowns_cpuset);
}
}
}
/* Look for cores */
if (fulldiscovery) {
hwloc_bitmap_t cores_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t core_cpuset;
hwloc_obj_t core;
while ((i = hwloc_bitmap_first(cores_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid;
unsigned coreid = infos[i].coreid;
if (coreid == (unsigned) -1) {
hwloc_bitmap_clr(cores_cpuset, i);
continue;
}
core_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) {
if (infos[j].coreid == (unsigned) -1) {
hwloc_bitmap_clr(cores_cpuset, j);
continue;
}
if (infos[j].socketid == socketid && infos[j].coreid == coreid) {
hwloc_bitmap_set(core_cpuset, j);
hwloc_bitmap_clr(cores_cpuset, j);
}
}
core = hwloc_alloc_setup_object(HWLOC_OBJ_CORE, coreid);
core->cpuset = core_cpuset;
hwloc_debug_1arg_bitmap("os core %u has cpuset %s\n",
coreid, core_cpuset);
hwloc_insert_object_by_cpuset(topology, core);
}
hwloc_bitmap_free(cores_cpuset);
}
/* Look for caches */
/* First find max level */
level = 0;
for (i = 0; i < nbprocs; i++)
for (j = 0; j < infos[i].numcaches; j++)
if (infos[i].cache[j].level > level)
level = infos[i].cache[j].level;
/* Look for known types */
if (fulldiscovery) while (level > 0) {
for (type = 1; type <= 3; type++) {
/* Look for caches of that type at level level */
{
hwloc_bitmap_t caches_cpuset = hwloc_bitmap_dup(complete_cpuset);
hwloc_bitmap_t cache_cpuset;
hwloc_obj_t cache;
while ((i = hwloc_bitmap_first(caches_cpuset)) != (unsigned) -1) {
unsigned socketid = infos[i].socketid;
for (l = 0; l < infos[i].numcaches; l++) {
if (infos[i].cache[l].level == level && infos[i].cache[l].type == type)
break;
}
if (l == infos[i].numcaches) {
/* no cache Llevel of that type in i */
hwloc_bitmap_clr(caches_cpuset, i);
continue;
}
/* Found a matching cache, now look for others sharing it */
{
unsigned cacheid = infos[i].apicid / infos[i].cache[l].nbthreads_sharing;
cache_cpuset = hwloc_bitmap_alloc();
for (j = i; j < nbprocs; j++) {
unsigned l2;
for (l2 = 0; l2 < infos[j].numcaches; l2++) {
if (infos[j].cache[l2].level == level && infos[j].cache[l2].type == type)
break;
}
if (l2 == infos[j].numcaches) {
/* no cache Llevel of that type in j */
hwloc_bitmap_clr(caches_cpuset, j);
continue;
}
if (infos[j].socketid == socketid && infos[j].apicid / infos[j].cache[l2].nbthreads_sharing == cacheid) {
hwloc_bitmap_set(cache_cpuset, j);
hwloc_bitmap_clr(caches_cpuset, j);
}
}
cache = hwloc_alloc_setup_object(HWLOC_OBJ_CACHE, cacheid);
cache->attr->cache.depth = level;
cache->attr->cache.size = infos[i].cache[l].size;
cache->attr->cache.linesize = infos[i].cache[l].linesize;
cache->attr->cache.associativity = infos[i].cache[l].ways;
switch (infos[i].cache[l].type) {
case 1:
cache->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case 2:
cache->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
case 3:
cache->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
}
cache->cpuset = cache_cpuset;
hwloc_debug_2args_bitmap("os L%u cache %u has cpuset %s\n",
level, cacheid, cache_cpuset);
hwloc_insert_object_by_cpuset(topology, cache);
}
}
hwloc_bitmap_free(caches_cpuset);
}
}
level--;
}
for (i = 0; i < nbprocs; i++) {
free(infos[i].cache);
if (infos[i].otherids)
free(infos[i].otherids);
}
hwloc_bitmap_free(complete_cpuset);
}
#if defined HWLOC_FREEBSD_SYS && defined HAVE_CPUSET_SETID
#include <sys/param.h>
#include <sys/cpuset.h>
typedef cpusetid_t hwloc_x86_os_state_t;
static void hwloc_x86_os_state_save(hwloc_x86_os_state_t *state)
{
/* temporary make all cpus available during discovery */
cpuset_getid(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, state);
cpuset_setid(CPU_WHICH_PID, -1, 0);
}
static void hwloc_x86_os_state_restore(hwloc_x86_os_state_t *state)
{
/* restore initial cpuset */
cpuset_setid(CPU_WHICH_PID, -1, *state);
}
#else /* !defined HWLOC_FREEBSD_SYS || !defined HAVE_CPUSET_SETID */
typedef void * hwloc_x86_os_state_t;
static void hwloc_x86_os_state_save(hwloc_x86_os_state_t *state __hwloc_attribute_unused) { }
static void hwloc_x86_os_state_restore(hwloc_x86_os_state_t *state __hwloc_attribute_unused) { }
#endif /* !defined HWLOC_FREEBSD_SYS || !defined HAVE_CPUSET_SETID */
#define INTEL_EBX ('G' | ('e'<<8) | ('n'<<16) | ('u'<<24))
#define INTEL_EDX ('i' | ('n'<<8) | ('e'<<16) | ('I'<<24))
#define INTEL_ECX ('n' | ('t'<<8) | ('e'<<16) | ('l'<<24))
#define AMD_EBX ('A' | ('u'<<8) | ('t'<<16) | ('h'<<24))
#define AMD_EDX ('e' | ('n'<<8) | ('t'<<16) | ('i'<<24))
#define AMD_ECX ('c' | ('A'<<8) | ('M'<<16) | ('D'<<24))
static
int hwloc_look_x86(struct hwloc_topology *topology, unsigned nbprocs, int fulldiscovery)
{
unsigned eax, ebx, ecx = 0, edx;
hwloc_bitmap_t orig_cpuset;
unsigned i;
unsigned highest_cpuid;
unsigned highest_ext_cpuid;
/* This stores cpuid features with the same indexing as Linux */
unsigned features[10] = { 0 };
struct procinfo *infos = NULL;
enum cpuid_type cpuid_type = unknown;
hwloc_x86_os_state_t os_state;
struct hwloc_binding_hooks hooks;
struct hwloc_topology_support support;
struct hwloc_topology_membind_support memsupport __hwloc_attribute_unused;
int ret = -1;
memset(&hooks, 0, sizeof(hooks));
support.membind = &memsupport;
hwloc_set_native_binding_hooks(&hooks, &support);
if (!(hooks.get_thisproc_cpubind && hooks.set_thisproc_cpubind)
&& !(hooks.get_thisthread_cpubind && hooks.set_thisthread_cpubind))
goto out;
if (!hwloc_have_cpuid())
goto out;
infos = calloc(nbprocs, sizeof(struct procinfo));
if (NULL == infos)
goto out;
for (i = 0; i < nbprocs; i++) {
infos[i].nodeid = (unsigned) -1;
infos[i].socketid = (unsigned) -1;
infos[i].unitid = (unsigned) -1;
infos[i].coreid = (unsigned) -1;
infos[i].threadid = (unsigned) -1;
}
eax = 0x00;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
highest_cpuid = eax;
if (ebx == INTEL_EBX && ecx == INTEL_ECX && edx == INTEL_EDX)
cpuid_type = intel;
if (ebx == AMD_EBX && ecx == AMD_ECX && edx == AMD_EDX)
cpuid_type = amd;
hwloc_debug("highest cpuid %x, cpuid type %u\n", highest_cpuid, cpuid_type);
if (highest_cpuid < 0x01) {
goto out_with_infos;
}
eax = 0x01;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
features[0] = edx;
features[4] = ecx;
eax = 0x80000000;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
highest_ext_cpuid = eax;
hwloc_debug("highest extended cpuid %x\n", highest_ext_cpuid);
if (highest_cpuid >= 0x7) {
eax = 0x7;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
features[9] = ebx;
}
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000001) {
eax = 0x80000001;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
features[1] = edx;
features[6] = ecx;
}
hwloc_x86_os_state_save(&os_state);
orig_cpuset = hwloc_bitmap_alloc();
if (hooks.get_thisthread_cpubind && hooks.set_thisthread_cpubind) {
if (!hooks.get_thisthread_cpubind(topology, orig_cpuset, HWLOC_CPUBIND_STRICT)) {
hwloc_bitmap_t set = hwloc_bitmap_alloc();
for (i = 0; i < nbprocs; i++) {
hwloc_bitmap_only(set, i);
hwloc_debug("binding to CPU%d\n", i);
if (hooks.set_thisthread_cpubind(topology, set, HWLOC_CPUBIND_STRICT)) {
hwloc_debug("could not bind to CPU%d: %s\n", i, strerror(errno));
continue;
}
look_proc(&infos[i], highest_cpuid, highest_ext_cpuid, features, cpuid_type);
}
hwloc_bitmap_free(set);
hooks.set_thisthread_cpubind(topology, orig_cpuset, 0);
hwloc_bitmap_free(orig_cpuset);
summarize(topology, infos, nbprocs, fulldiscovery);
ret = fulldiscovery; /* success, but objects added only if fulldiscovery */
goto out_with_os_state;
}
}
if (hooks.get_thisproc_cpubind && hooks.set_thisproc_cpubind) {
if (!hooks.get_thisproc_cpubind(topology, orig_cpuset, HWLOC_CPUBIND_STRICT)) {
hwloc_bitmap_t set = hwloc_bitmap_alloc();
for (i = 0; i < nbprocs; i++) {
hwloc_bitmap_only(set, i);
hwloc_debug("binding to CPU%d\n", i);
if (hooks.set_thisproc_cpubind(topology, set, HWLOC_CPUBIND_STRICT)) {
hwloc_debug("could not bind to CPU%d: %s\n", i, strerror(errno));
continue;
}
look_proc(&infos[i], highest_cpuid, highest_ext_cpuid, features, cpuid_type);
}
hwloc_bitmap_free(set);
hooks.set_thisproc_cpubind(topology, orig_cpuset, 0);
hwloc_bitmap_free(orig_cpuset);
summarize(topology, infos, nbprocs, fulldiscovery);
ret = fulldiscovery; /* success, but objects added only if fulldiscovery */
goto out_with_os_state;
}
}
hwloc_bitmap_free(orig_cpuset);
out_with_os_state:
hwloc_x86_os_state_restore(&os_state);
out_with_infos:
if (NULL != infos) {
free(infos);
}
out:
return ret;
}
static int
hwloc_x86_discover(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
int alreadypus = 0;
int ret;
if (!topology->is_thissystem) {
hwloc_debug("%s", "\nno x86 detection (not thissystem)\n");
return 0;
}
if (topology->levels[0][0]->cpuset) {
/* somebody else discovered things */
if (topology->nb_levels == 2 && topology->level_nbobjects[1] == nbprocs) {
/* only PUs were discovered, as much as we would, complete the topology with everything else */
alreadypus = 1;
goto fulldiscovery;
}
/* several object types were added, we can't easily complete, just annotate a bit */
ret = hwloc_look_x86(topology, nbprocs, 0);
if (ret)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86");
return 0;
} else {
/* topology is empty, initialize it */
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
}
fulldiscovery:
hwloc_look_x86(topology, nbprocs, 1);
/* if failed, just continue and create PUs */
if (!alreadypus)
hwloc_setup_pu_level(topology, nbprocs);
hwloc_obj_add_info(topology->levels[0][0], "Backend", "x86");
return 1;
}
static struct hwloc_backend *
hwloc_x86_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->flags = HWLOC_BACKEND_FLAG_NEED_LEVELS;
backend->discover = hwloc_x86_discover;
return backend;
}
static struct hwloc_disc_component hwloc_x86_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_CPU,
"x86",
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_x86_component_instantiate,
45, /* between native and no_os */
NULL
};
const struct hwloc_component hwloc_x86_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_x86_disc_component
};

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

@ -0,0 +1,380 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
/* private headers allowed because this plugin is built within hwloc */
#include <private/xml.h>
#include <private/debug.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
/*******************
* Common routines *
*******************/
static void hwloc_libxml2_error_callback(void * ctx __hwloc_attribute_unused, const char * msg __hwloc_attribute_unused, ...) { /* do nothing */ }
static void
hwloc_libxml2_disable_stderrwarnings(void)
{
static int first = 1;
if (first) {
xmlSetGenericErrorFunc(NULL, hwloc__xml_verbose() ? xmlGenericError : hwloc_libxml2_error_callback);
first = 0;
}
}
/*******************
* Import routines *
*******************/
typedef struct hwloc__libxml_import_state_data_s {
xmlNode *node; /* current libxml node, always valid */
xmlNode *child; /* last processed child, or NULL if none yet */
xmlAttr *attr; /* last processed attribute, or NULL if none yet */
} * hwloc__libxml_import_state_data_t;
static int
hwloc__libxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlAttr *attr;
if (lstate->attr)
attr = lstate->attr->next;
else
attr = lstate->node->properties;
for (; attr; attr = attr->next)
if (attr->type == XML_ATTRIBUTE_NODE) {
/* use the first valid attribute content */
xmlNode *subnode;
for (subnode = attr->children; subnode; subnode = subnode->next) {
if (subnode->type == XML_TEXT_NODE) {
if (subnode->content && subnode->content[0] != '\0' && subnode->content[0] != '\n') {
*namep = (char *) attr->name;
*valuep = (char *) subnode->content;
lstate->attr = attr;
return 0;
}
} else {
if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unexpected xml attr node type %u\n", subnode->type);
}
}
} else {
if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unexpected xml attr type %u\n", attr->type);
}
return -1;
}
static int
hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate,
char **tagp)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
hwloc__libxml_import_state_data_t lchildstate = (void*) childstate->data;
xmlNode *child;
childstate->parent = state;
childstate->next_attr = state->next_attr;
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)
return 0;
child = lstate->child->next;
for (; child; child = child->next)
if (child->type == XML_ELEMENT_NODE) {
lstate->child = lchildstate->node = child;
lchildstate->child = child->children;
lchildstate->attr = NULL;
*tagp = (char*) child->name;
return 1;
} else if (child->type == XML_TEXT_NODE) {
if (child->content && child->content[0] != '\0' && child->content[0] != '\n')
if (hwloc__xml_verbose())
fprintf(stderr, "ignoring object text content %s\n", (const char*) child->content);
} else if (child->type != XML_COMMENT_NODE) {
if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unexpected xml node type %u\n", child->type);
}
return 0;
}
static int
hwloc__libxml_import_close_tag(hwloc__xml_import_state_t state __hwloc_attribute_unused)
{
return 0;
}
static void
hwloc__libxml_import_close_child(hwloc__xml_import_state_t state __hwloc_attribute_unused)
{
/* nothing to do */
}
static int
hwloc__libxml_import_get_content(hwloc__xml_import_state_t state,
char **beginp, size_t expected_length)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlNode *child;
size_t length;
child = lstate->node->children;
if (!child)
return 0;
if (child->type != XML_TEXT_NODE)
return 0;
length = strlen((char *) child->content);
if (length != expected_length)
return -1;
*beginp = (char *) child->content;
return 1;
}
static void
hwloc__libxml_import_close_content(hwloc__xml_import_state_t state __hwloc_attribute_unused)
{
/* nothing to do */
}
static int
hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlNode* root_node;
xmlDtd *dtd;
assert(sizeof(*lstate) <= sizeof(state->data));
dtd = xmlGetIntSubset((xmlDoc*) bdata->data);
if (!dtd) {
if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topology without DTD\n");
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")) {
if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topology with wrong DTD SystemID (%s instead of %s)\n",
(char *) dtd->SystemID, "hwloc.dtd");
}
root_node = xmlDocGetRootElement((xmlDoc*) bdata->data);
if (strcmp((const char *) root_node->name, "topology") && strcmp((const char *) root_node->name, "root")) {
/* root node should be in "topology" class (or "root" if importing from < 1.0) */
if (hwloc__xml_verbose())
fprintf(stderr, "ignoring object of class `%s' not at the top the xml hierarchy\n", (const char *) root_node->name);
goto failed;
}
state->next_attr = hwloc__libxml_import_next_attr;
state->find_child = hwloc__libxml_import_find_child;
state->close_tag = hwloc__libxml_import_close_tag;
state->close_child = hwloc__libxml_import_close_child;
state->get_content = hwloc__libxml_import_get_content;
state->close_content = hwloc__libxml_import_close_content;
state->parent = NULL;
lstate->node = root_node;
lstate->child = root_node->children;
lstate->attr = NULL;
return 0; /* success */
failed:
return -1; /* failed */
}
/********************
* Backend routines *
********************/
static void
hwloc_libxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
{
xmlFreeDoc((xmlDoc*)bdata->data);
}
static int
hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{
xmlDoc *doc = NULL;
LIBXML_TEST_VERSION;
hwloc_libxml2_disable_stderrwarnings();
errno = 0; /* set to 0 so that we know if libxml2 changed it */
if (xmlpath)
doc = xmlReadFile(xmlpath, NULL, 0);
else if (xmlbuffer)
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0);
if (!doc) {
if (!errno)
/* libxml2 read the file fine, but it got an error during parsing */
errno = EINVAL;
return -1;
}
bdata->look_init = hwloc_libxml_look_init;
bdata->look_failed = NULL;
bdata->backend_exit = hwloc_libxml_backend_exit;
bdata->data = doc;
return 0;
}
/*******************
* Export routines *
*******************/
typedef struct hwloc__libxml_export_state_data_s {
xmlNodePtr current_node; /* current node to output */
} * hwloc__libxml_export_state_data_t;
static void
hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state,
const char *name)
{
hwloc__libxml_export_state_data_t lpdata = (void *) parentstate->data;
hwloc__libxml_export_state_data_t ldata = (void *) state->data;
state->parent = parentstate;
state->new_child = parentstate->new_child;
state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object;
ldata->current_node = xmlNewChild(lpdata->current_node, NULL, BAD_CAST name, NULL);
}
static void
hwloc__libxml_export_new_prop(hwloc__xml_export_state_t state, const char *name, const char *value)
{
hwloc__libxml_export_state_data_t ldata = (void *) state->data;
xmlNewProp(ldata->current_node, BAD_CAST name, BAD_CAST value);
}
static void
hwloc__libxml_export_end_object(hwloc__xml_export_state_t state __hwloc_attribute_unused, const char *name __hwloc_attribute_unused)
{
/* nothing to do */
}
static void
hwloc__libxml_export_add_content(hwloc__xml_export_state_t state, const char *buffer, size_t length)
{
hwloc__libxml_export_state_data_t ldata = (void *) state->data;
xmlNodeAddContentLen(ldata->current_node, BAD_CAST buffer, length);
}
static xmlDocPtr
hwloc__libxml2_prepare_export(hwloc_topology_t topology)
{
struct hwloc__xml_export_state_s state;
hwloc__libxml_export_state_data_t data = (void *) state.data;
xmlDocPtr doc = NULL; /* document pointer */
xmlNodePtr root_node = NULL; /* root pointer */
assert(sizeof(*data) <= sizeof(state.data));
LIBXML_TEST_VERSION;
hwloc_libxml2_disable_stderrwarnings();
/* Creates a new document, a node and set it as a root node. */
doc = xmlNewDoc(BAD_CAST "1.0");
root_node = xmlNewNode(NULL, BAD_CAST "topology");
xmlDocSetRootElement(doc, root_node);
/* Creates a DTD declaration. Isn't mandatory. */
(void) xmlCreateIntSubset(doc, BAD_CAST "topology", NULL, BAD_CAST "hwloc.dtd");
state.new_child = hwloc__libxml_export_new_child;
state.new_prop = hwloc__libxml_export_new_prop;
state.add_content = hwloc__libxml_export_add_content;
state.end_object = hwloc__libxml_export_end_object;
data->current_node = root_node;
hwloc__xml_export_object (&state, topology, hwloc_get_root_obj(topology));
return doc;
}
static int
hwloc_libxml_export_file(hwloc_topology_t topology, const char *filename)
{
xmlDocPtr doc;
int ret;
errno = 0; /* set to 0 so that we know if libxml2 changed it */
doc = hwloc__libxml2_prepare_export(topology);
ret = xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1);
xmlFreeDoc(doc);
if (ret < 0) {
if (!errno)
/* libxml2 likely got an error before doing I/O */
errno = EINVAL;
return ret;
}
return 0;
}
static int
hwloc_libxml_export_buffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen)
{
xmlDocPtr doc = hwloc__libxml2_prepare_export(topology);
xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
xmlFreeDoc(doc);
return 0;
}
static void
hwloc_libxml_free_buffer(void *xmlbuffer)
{
xmlFree(BAD_CAST xmlbuffer);
}
/*************
* Callbacks *
*************/
static struct hwloc_xml_callbacks hwloc_xml_libxml_callbacks = {
hwloc_libxml_backend_init,
hwloc_libxml_export_file,
hwloc_libxml_export_buffer,
hwloc_libxml_free_buffer
};
static struct hwloc_xml_component hwloc_libxml_xml_component = {
NULL,
&hwloc_xml_libxml_callbacks
};
#ifdef HWLOC_INSIDE_PLUGIN
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_libxml_component;
#endif
const struct hwloc_component hwloc_xml_libxml_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_XML,
0,
&hwloc_libxml_xml_component
};

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

@ -0,0 +1,660 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
#include <private/private.h>
#include <private/xml.h>
#include <private/debug.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/*******************
* Import routines *
*******************/
struct hwloc__nolibxml_backend_data_s {
size_t buflen; /* size of both buffer and copy buffers, set during backend_init() */
char *buffer; /* allocated and filled during backend_init() */
char *copy; /* allocated during backend_init(), used later during actual parsing */
};
typedef struct hwloc__nolibxml_import_state_data_s {
char *tagbuffer; /* buffer containing the next tag */
char *attrbuffer; /* buffer containing the next attribute of the current node */
char *tagname; /* tag name of the current node */
int closed; /* set if the current node is auto-closing */
} * hwloc__nolibxml_import_state_data_t;
static char *
hwloc__nolibxml_import_ignore_spaces(char *buffer)
{
return buffer + strspn(buffer, " \t\n");
}
static int
hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
int namelen;
size_t len, escaped;
char *buffer, *value, *end;
/* find the beginning of an attribute */
buffer = hwloc__nolibxml_import_ignore_spaces(nstate->attrbuffer);
namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz_");
if (buffer[namelen] != '=' || buffer[namelen+1] != '\"')
return -1;
buffer[namelen] = '\0';
*namep = buffer;
/* find the beginning of its value, and unescape it */
*valuep = value = buffer+namelen+2;
len = 0; escaped = 0;
while (value[len+escaped] != '\"') {
if (value[len+escaped] == '&') {
if (!strncmp(&value[1+len+escaped], "#10;", 4)) {
escaped += 4;
value[len] = '\n';
} else if (!strncmp(&value[1+len+escaped], "#13;", 4)) {
escaped += 4;
value[len] = '\r';
} else if (!strncmp(&value[1+len+escaped], "#9;", 3)) {
escaped += 3;
value[len] = '\t';
} else if (!strncmp(&value[1+len+escaped], "quot;", 5)) {
escaped += 5;
value[len] = '\"';
} else if (!strncmp(&value[1+len+escaped], "lt;", 3)) {
escaped += 3;
value[len] = '<';
} else if (!strncmp(&value[1+len+escaped], "gt;", 3)) {
escaped += 3;
value[len] = '>';
} else if (!strncmp(&value[1+len+escaped], "amp;", 4)) {
escaped += 4;
value[len] = '&';
} else {
return -1;
}
} else {
value[len] = value[len+escaped];
}
len++;
if (value[len+escaped] == '\0')
return -1;
}
value[len] = '\0';
/* find next attribute */
end = &value[len+escaped+1]; /* skip the ending " */
nstate->attrbuffer = hwloc__nolibxml_import_ignore_spaces(end);
return 0;
}
static int
hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate,
char **tagp)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data;
char *buffer = nstate->tagbuffer;
char *end;
int namelen;
childstate->parent = state;
childstate->next_attr = state->next_attr;
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 */
if (nstate->closed)
return 0;
/* find the beginning of the tag */
buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
if (buffer[0] != '<')
return -1;
buffer++;
/* if closing tag, return nothing and do not advance */
if (buffer[0] == '/')
return 0;
/* normal tag */
*tagp = nchildstate->tagname = buffer;
/* find the end, mark it and return it */
end = strchr(buffer, '>');
if (!end)
return -1;
end[0] = '\0';
nchildstate->tagbuffer = end+1;
/* handle auto-closing tags */
if (end[-1] == '/') {
nchildstate->closed = 1;
end[-1] = '\0';
} else
nchildstate->closed = 0;
/* find attributes */
namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz_");
/* cannot be without attributes */
assert(buffer[namelen] != '\0');
if (buffer[namelen] != ' ')
return -1;
/* found a space, likely starting attributes */
buffer[namelen] = '\0';
nchildstate->attrbuffer = buffer+namelen+1;
return 1;
}
static int
hwloc__nolibxml_import_close_tag(hwloc__xml_import_state_t state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
char *buffer = nstate->tagbuffer;
char *end;
/* auto-closed tags need nothing */
if (nstate->closed)
return 0;
/* find the beginning of the tag */
buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
if (buffer[0] != '<')
return -1;
buffer++;
/* find the end, mark it and return it to the parent */
end = strchr(buffer, '>');
if (!end)
return -1;
end[0] = '\0';
nstate->tagbuffer = end+1;
/* if closing tag, return nothing */
if (buffer[0] != '/' || strcmp(buffer+1, nstate->tagname) )
return -1;
return 0;
}
static void
hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
hwloc__nolibxml_import_state_data_t nparent = (void*) state->parent->data;
nparent->tagbuffer = nstate->tagbuffer;
}
static int
hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
char **beginp, size_t expected_length)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
char *buffer = nstate->tagbuffer;
size_t length;
char *end;
/* auto-closed tags have no content */
if (nstate->closed)
return 0;
/* find the next tag, where the content ends */
end = strchr(buffer, '<');
if (!end)
return -1;
length = (size_t) (end-buffer);
if (length != expected_length)
return -1;
nstate->tagbuffer = end;
*end = '\0'; /* mark as 0-terminated for now */
*beginp = buffer;
return 1;
}
static void
hwloc__nolibxml_import_close_content(hwloc__xml_import_state_t state)
{
/* put back the '<' that we overwrote to 0-terminate the content */
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
*nstate->tagbuffer = '<';
}
static int
hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
char *buffer;
assert(sizeof(*nstate) <= sizeof(state->data));
/* use a copy in the temporary buffer, we may modify during parsing */
buffer = nbdata->copy;
memcpy(buffer, nbdata->buffer, nbdata->buflen);
/* skip headers */
while (!strncmp(buffer, "<?xml ", 6) || !strncmp(buffer, "<!DOCTYPE ", 10)) {
buffer = strchr(buffer, '\n');
if (!buffer)
goto failed;
buffer++;
}
/* find topology tag */
if (strncmp(buffer, "<topology>", 10))
goto failed;
state->next_attr = hwloc__nolibxml_import_next_attr;
state->find_child = hwloc__nolibxml_import_find_child;
state->close_tag = hwloc__nolibxml_import_close_tag;
state->close_child = hwloc__nolibxml_import_close_child;
state->get_content = hwloc__nolibxml_import_get_content;
state->close_content = hwloc__nolibxml_import_close_content;
state->parent = NULL;
nstate->closed = 0;
nstate->tagbuffer = buffer+10;
nstate->tagname = (char *) "topology";
nstate->attrbuffer = NULL;
return 0; /* success */
failed:
return -1; /* failed */
}
static void
hwloc_nolibxml_look_failed(struct hwloc_xml_backend_data_s *bdata __hwloc_attribute_unused)
{
/* not only when verbose */
fprintf(stderr, "Failed to parse XML input with the minimalistic parser. If it was not\n"
"generated by hwloc, try enabling full XML support with libxml2.\n");
}
/********************
* Backend routines *
********************/
static void
hwloc_nolibxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
{
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
free(nbdata->buffer);
free(nbdata->copy);
free(nbdata);
}
static int
hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{
struct hwloc__nolibxml_backend_data_s *nbdata = malloc(sizeof(*nbdata));
if (!nbdata)
goto out;
bdata->data = nbdata;
if (xmlbuffer) {
nbdata->buffer = malloc(xmlbuflen);
if (!nbdata->buffer)
goto out_with_nbdata;
nbdata->buflen = xmlbuflen;
memcpy(nbdata->buffer, xmlbuffer, xmlbuflen);
} else {
FILE * file;
size_t buflen, offset, readlen;
struct stat statbuf;
char *buffer;
size_t ret;
if (!strcmp(xmlpath, "-"))
xmlpath = "/dev/stdin";
file = fopen(xmlpath, "r");
if (!file)
goto out_with_nbdata;
/* find the required buffer size for regular files, or use 4k when unknown, we'll realloc later if needed */
buflen = 4096;
if (!stat(xmlpath, &statbuf))
if (S_ISREG(statbuf.st_mode))
buflen = statbuf.st_size+1; /* one additional byte so that the first fread() gets EOF too */
buffer = malloc(buflen+1); /* one more byte for the ending \0 */
if (!buffer) {
fclose(file);
goto out_with_nbdata;
}
offset = 0; readlen = buflen;
while (1) {
ret = fread(buffer+offset, 1, readlen, file);
offset += ret;
buffer[offset] = 0;
if (ret != readlen)
break;
buflen *= 2;
buffer = realloc(buffer, buflen+1);
if (!buffer) {
fclose(file);
goto out_with_nbdata;
}
readlen = buflen/2;
}
fclose(file);
nbdata->buffer = buffer;
nbdata->buflen = offset+1;
}
/* allocate a temporary copy buffer that we may modify during parsing */
nbdata->copy = malloc(nbdata->buflen);
if (!nbdata->copy)
goto out_with_buffer;
bdata->look_init = hwloc_nolibxml_look_init;
bdata->look_failed = hwloc_nolibxml_look_failed;
bdata->backend_exit = hwloc_nolibxml_backend_exit;
return 0;
out_with_buffer:
free(nbdata->buffer);
out_with_nbdata:
free(nbdata);
out:
return -1;
}
/*******************
* Export routines *
*******************/
typedef struct hwloc__nolibxml_export_state_data_s {
char *buffer; /* (moving) buffer where to write */
size_t written; /* how many bytes were written (or would have be written if not truncated) */
size_t remaining; /* how many bytes are still available in the buffer */
unsigned indent; /* indentation level for the next line */
unsigned nr_children;
unsigned has_content;
} * hwloc__nolibxml_export_state_data_t;
static void
hwloc__nolibxml_export_update_buffer(hwloc__nolibxml_export_state_data_t ndata, int res)
{
if (res >= 0) {
ndata->written += res;
if (res >= (int) ndata->remaining)
res = ndata->remaining>0 ? ndata->remaining-1 : 0;
ndata->buffer += res;
ndata->remaining -= res;
}
}
static char *
hwloc__nolibxml_export_escape_string(const char *src)
{
int fulllen, sublen;
char *escaped, *dst;
fulllen = strlen(src);
sublen = strcspn(src, "\n\r\t\"<>&");
if (sublen == fulllen)
return NULL; /* nothing to escape */
escaped = malloc(fulllen*6+1); /* escaped chars are replaced by at most 6 char */
dst = escaped;
memcpy(dst, src, sublen);
src += sublen;
dst += sublen;
while (*src) {
int replen;
switch (*src) {
case '\n': strcpy(dst, "&#10;"); replen=5; break;
case '\r': strcpy(dst, "&#13;"); replen=5; break;
case '\t': strcpy(dst, "&#9;"); replen=4; break;
case '\"': strcpy(dst, "&quot;"); replen=6; break;
case '<': strcpy(dst, "&lt;"); replen=4; break;
case '>': strcpy(dst, "&gt;"); replen=4; break;
case '&': strcpy(dst, "&amp;"); replen=5; break;
default: replen=0; break;
}
dst+=replen; src++;
sublen = strcspn(src, "\n\r\t\"<>&");
memcpy(dst, src, sublen);
src += sublen;
dst += sublen;
}
*dst = 0;
return escaped;
}
static void
hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state,
const char *name)
{
hwloc__nolibxml_export_state_data_t npdata = (void *) parentstate->data;
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
int res;
assert(!npdata->has_content);
if (!npdata->nr_children) {
res = hwloc_snprintf(npdata->buffer, npdata->remaining, ">\n");
hwloc__nolibxml_export_update_buffer(npdata, res);
}
npdata->nr_children++;
state->parent = parentstate;
state->new_child = parentstate->new_child;
state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object;
ndata->buffer = npdata->buffer;
ndata->written = npdata->written;
ndata->remaining = npdata->remaining;
ndata->indent = npdata->indent + 2;
ndata->nr_children = 0;
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%*s<%s", npdata->indent, "", name);
hwloc__nolibxml_export_update_buffer(ndata, res);
}
static void
hwloc__nolibxml_export_new_prop(hwloc__xml_export_state_t state, const char *name, const char *value)
{
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
char *escaped = hwloc__nolibxml_export_escape_string(value);
int res = hwloc_snprintf(ndata->buffer, ndata->remaining, " %s=\"%s\"", name, escaped ? (const char *) escaped : value);
hwloc__nolibxml_export_update_buffer(ndata, res);
free(escaped);
}
static void
hwloc__nolibxml_export_end_object(hwloc__xml_export_state_t state, const char *name)
{
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
hwloc__nolibxml_export_state_data_t npdata = (void *) state->parent->data;
int res;
assert (!(ndata->has_content && ndata->nr_children));
if (ndata->has_content) {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "</%s>\n", name);
} else if (ndata->nr_children) {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%*s</%s>\n", npdata->indent, "", name);
} else {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "/>\n");
}
hwloc__nolibxml_export_update_buffer(ndata, res);
npdata->buffer = ndata->buffer;
npdata->written = ndata->written;
npdata->remaining = ndata->remaining;
}
static void
hwloc__nolibxml_export_add_content(hwloc__xml_export_state_t state, const char *buffer, size_t length)
{
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
int res;
assert(!ndata->nr_children);
if (!ndata->has_content) {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, ">");
hwloc__nolibxml_export_update_buffer(ndata, res);
}
ndata->has_content = 1;
res = hwloc_snprintf(ndata->buffer, ndata->remaining, buffer, length);
hwloc__nolibxml_export_update_buffer(ndata, res);
}
static size_t
hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int buflen)
{
struct hwloc__xml_export_state_s state, childstate;
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
int res;
assert(sizeof(*ndata) <= sizeof(state.data));
state.new_child = hwloc__nolibxml_export_new_child;
state.new_prop = hwloc__nolibxml_export_new_prop;
state.add_content = hwloc__nolibxml_export_add_content;
state.end_object = hwloc__nolibxml_export_end_object;
ndata->indent = 0;
ndata->written = 0;
ndata->buffer = xmlbuffer;
ndata->remaining = buflen;
ndata->nr_children = 1; /* don't close a non-existing previous tag when opening the topology tag */
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topology SYSTEM \"hwloc.dtd\">\n");
hwloc__nolibxml_export_update_buffer(ndata, res);
hwloc__nolibxml_export_new_child(&state, &childstate, "topology");
hwloc__xml_export_object (&childstate, topology, hwloc_get_root_obj(topology));
hwloc__nolibxml_export_end_object(&childstate, "topology");
return ndata->written+1;
}
static int
hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buflenp)
{
char *buffer;
size_t bufferlen, res;
bufferlen = 16384; /* random guess for large enough default */
buffer = malloc(bufferlen);
res = hwloc___nolibxml_prepare_export(topology, buffer, bufferlen);
if (res > bufferlen) {
buffer = realloc(buffer, res);
hwloc___nolibxml_prepare_export(topology, buffer, res);
}
*bufferp = buffer;
*buflenp = res;
return 0;
}
static int
hwloc_nolibxml_export_file(hwloc_topology_t topology, const char *filename)
{
FILE *file;
char *buffer;
int bufferlen;
int ret;
ret = hwloc_nolibxml_export_buffer(topology, &buffer, &bufferlen);
if (ret < 0)
return -1;
if (!strcmp(filename, "-")) {
file = stdout;
} else {
file = fopen(filename, "w");
if (!file) {
free(buffer);
return -1;
}
}
ret = fwrite(buffer, 1, bufferlen-1 /* don't write the ending \0 */, file);
if (ret == bufferlen-1) {
ret = 0;
} else {
errno = ferror(file);
ret = -1;
}
free(buffer);
if (file != stdout)
fclose(file);
return ret;
}
static void
hwloc_nolibxml_free_buffer(void *xmlbuffer)
{
free(xmlbuffer);
}
/*************
* Callbacks *
*************/
static struct hwloc_xml_callbacks hwloc_xml_nolibxml_callbacks = {
hwloc_nolibxml_backend_init,
hwloc_nolibxml_export_file,
hwloc_nolibxml_export_buffer,
hwloc_nolibxml_free_buffer
};
static struct hwloc_xml_component hwloc_nolibxml_xml_component = {
&hwloc_xml_nolibxml_callbacks,
NULL
};
const struct hwloc_component hwloc_xml_nolibxml_component = {
HWLOC_COMPONENT_ABI,
HWLOC_COMPONENT_TYPE_XML,
0,
&hwloc_nolibxml_xml_component
};

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

2947
opal/mca/hwloc/hwloc172/hwloc/src/topology.c Обычный файл

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

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