1
1
This commit was SVN r32652.
Этот коммит содержится в:
Ralph Castain 2014-08-31 03:13:06 +00:00
родитель e49ca05f11
Коммит 60eb7124ab
114 изменённых файлов: 7535 добавлений и 4439 удалений

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

@ -1,11 +0,0 @@
Applied the following patches from the upstream hwloc 1.7 branch after
the v1.7.2 release:
5198d4c Only include <malloc.h> if necessary
438d9ed linux/NUMA: Work around buggy NUMA node cpusets
Applied this from the upstream hwloc master, slightly modified for this
local version of v1.7 that we have:
7489287 topology-linux.c: ensure fd is marked as close-on-exec
3aa0ed6 topology-linux.c: Stevens says we should GETFD before we SETFD, so we do

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

@ -1,155 +0,0 @@
# -*- 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$OPAL_TOP_SRCDIR/$file/include"
AS_IF([test "$OPAL_TOP_BUILDDIR" != "$OPAL_TOP_SRCDIR"],
[CPPFLAGS="$CPPFLAGS -I$OPAL_TOP_BUILDDIR/$file/include"])
unset file
])
OPAL_VAR_SCOPE_POP
# This must be run unconditionally
HWLOC_DO_AM_CONDITIONALS
])dnl
# MCA_hwloc_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 CPPFLAGS_save])
# 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=$OPAL_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='$(OPAL_TOP_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

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

@ -1,61 +0,0 @@
# 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=
# 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=r5778M
# The date when this release was created
date="Sep 03, 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

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

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

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

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

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

@ -1,837 +0,0 @@
/*
* 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
};

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

@ -1,5 +1,6 @@
#
# Copyright (c) 2011-2013 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2014 Intel, Inc. All right reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
@ -17,16 +18,16 @@ EXTRA_DIST = \
SUBDIRS = hwloc
# Headers and sources
headers = hwloc172.h
sources = hwloc172_component.c
headers = hwloc191.h
sources = hwloc191_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 = \
noinst_LTLIBRARIES = libmca_hwloc_hwloc191.la
libmca_hwloc_hwloc191_la_SOURCES = $(headers) $(sources)
nodist_libmca_hwloc_hwloc191_la_SOURCES = $(nodist_headers)
libmca_hwloc_hwloc191_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc191_LDFLAGS)
libmca_hwloc_hwloc191_la_LIBADD = $(opal_hwloc_hwloc191_LIBS)
libmca_hwloc_hwloc191_la_DEPENDENCIES = \
$(HWLOC_top_builddir)/src/libhwloc_embedded.la
# Since the rest of the code base includes the underlying hwloc.h, we
@ -46,7 +47,7 @@ headers += \
hwloc/include/private/private.h \
hwloc/include/private/debug.h \
hwloc/include/private/misc.h \
hwloc/include/private/cpuid.h
hwloc/include/private/cpuid-x86.h
nodist_headers = hwloc/include/hwloc/autogen/config.h
if HWLOC_HAVE_LINUX

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

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

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

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

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

@ -1,6 +1,6 @@
# Copyright © 2009 inria. All rights reserved.
# Copyright © 2009-2014 Inria. All rights reserved.
# Copyright © 2009 Université Bordeaux 1
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory.
# Note that the -I directory must *exactly* match what was specified
@ -29,52 +29,35 @@ endif
# Only install the valgrind suppressions file if we're building in standalone mode
if HWLOC_BUILD_STANDALONE
dist_opaldata_DATA = contrib/hwloc-valgrind.supp
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.
# dist", so we have to include config/distscript.sh.
#
EXTRA_DIST = \
README VERSION COPYING AUTHORS \
config/hwloc_get_version.sh \
config/distscript.csh
config/distscript.sh
# Only install entire visual studio subdirectory if we're building in standalone mode
if HWLOC_BUILD_STANDALONE
EXTRA_DIST += contrib/windows
endif
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:
env LS_COLORS= csh "$(top_srcdir)/config/distscript.csh" "$(top_srcdir)" "$(distdir)" "$(HWLOC_VERSION)" "$(HWLOC_SVN_R)"
endif HWLOC_BUILD_README
endif HWLOC_BUILD_DOXYGEN
sh "$(top_srcdir)/config/distscript.sh" "$(top_srcdir)" "$(distdir)" "$(HWLOC_VERSION)"
endif HWLOC_BUILD_STANDALONE
#
# Build the top-level README file
# Build the documenation and top-level README file
#
if HWLOC_BUILD_STANDALONE
.PHONY: doc readme
doc readme:
$(MAKE) -C doc readme
$(MAKE) -C doc
endif HWLOC_BUILD_STANDALONE
if HWLOC_BUILD_STANDALONE

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

@ -1,5 +1,5 @@
Copyright © 2009 CNRS
Copyright © 2009-2013 Inria. All rights reserved.
Copyright © 2009-2014 Inria. All rights reserved.
Copyright © 2009-2013 Université Bordeaux 1
Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
@ -17,6 +17,141 @@ bug fixes (and other actions) for each version of hwloc since version
in v0.9.1).
Version 1.9.1
-------------
* Fix a crash when the PCI locality is invalid. Attach to the root object
instead. Thanks to Nicolas Denoyelle for reporting the issue.
* Fix -f in lstopo manpage. Thanks to Jirka Hladky for reporting the issue.
* Fix hwloc_obj_type_sscanf() and others when strncasecmp() is not properly
available. Thanks to Nick Papior Andersen for reporting the problem.
* Mark Linux file descriptors as close-on-exec to avoid leaks on exec.
* Fix some minor memory leaks.
Version 1.9.0
-------------
* API
+ Add hwloc_obj_type_sscanf() to extend hwloc_obj_type_of_string() with
type-specific attributes such as Cache/Group depth and Cache type.
hwloc_obj_type_of_string() is moved to hwloc/deprecated.h.
+ Add hwloc_linux_get_tid_last_cpu_location() for retrieving the
last CPU where a Linux thread given by TID ran.
+ Add hwloc_distrib() to extend the old hwloc_distribute[v]() functions.
hwloc_distribute[v]() is moved to hwloc/deprecated.h.
+ Don't mix total and local memory when displaying verbose object attributes
with hwloc_obj_attr_snprintf() or in lstopo.
* Backends
+ Add CPUVendor, CPUModelNumber and CPUFamilyNumber info attributes for
x86, ia64 and Xeon Phi sockets on Linux, to extend the x86-specific
support added in v1.8.1. Requested by Ralph Castain.
+ Add many CPU- and Platform-related info attributes on ARM and POWER
platforms, in the Machine and Socket objects.
+ Add CUDA info attributes describing the number of multiprocessors and
cores and the size of the global, shared and L2 cache memories in CUDA
OS devices.
+ Add OpenCL info attributes describing the number of compute units and
the global memory size in OpenCL OS devices.
+ The synthetic backend now accepts extended types such as L2Cache, L1i or
Group3. lstopo also exports synthetic strings using these extended types.
* Tools
+ lstopo
- Do not overwrite output files by default anymore.
Pass -f or --force to enforce it.
- Display OpenCL, CUDA and Xeon Phi numbers of cores and memory sizes
in the graphical output.
- Fix export to stdout when specifying a Cairo-based output type
with --of.
+ hwloc-ps
- Add -e or --get-last-cpu-location to report where processes/threads
run instead of where they are bound.
- Report locations as likely-more-useful objects such as Cores or Sockets
instead of Caches when possible.
+ hwloc-bind
- Fix failure on Windows when not using --pid.
- Add -e as a synonym to --get-last-cpu-location.
+ hwloc-distrib
- Add --reverse to distribute using last objects first and singlify
into last bits first. Thanks to Jirka Hladky for the suggestion.
+ hwloc-info
- Report unified caches when looking for data or instruction cache
ancestor objects.
* Misc
+ Add experimental Visual Studio support under contrib/windows.
Thanks to Eloi Gaudry for his help and for providing the first draft.
+ Fix some overzealous assertions and warnings about the ordering of
objects on a level with respect to cpusets. The ordering is only
guaranteed for complete cpusets (based on the first bit in sets).
+ Fix some memory leaks when importing xml diffs and when exporting a
"too complex" entry.
Version 1.8.1
-------------
* Fix the cpuid code on Windows 64bits so that the x86 backend gets
enabled as expected and can populate CPU information.
Thanks to Robin Scher for reporting the problem.
* Add CPUVendor/CPUModelNumber/CPUFamilyNumber attributes when running
on x86 architecture. Thanks to Ralph Castain for the suggestion.
* Work around buggy BIOS reporting duplicate NUMA nodes on Linux.
Thanks to Jeff Becker for reporting the problem and testing the patch.
* Add a name to the lstopo graphical window. Thanks to Michael Prokop
for reporting the issue.
Version 1.8.0
-------------
* New components
+ Add the "linuxpci" component that always works on Linux even when
libpciaccess and libpci aren't available (and even with a modified
file-system root). By default the old "pci" component runs first
because "linuxpci" lacks device names (obj->name is always NULL).
* API
+ Add the topology difference API in hwloc/diff.h for manipulating
many similar topologies.
+ Add hwloc_topology_dup() for duplicating an entire topology.
+ hwloc.h and hwloc/helper.h have been reorganized to clarify the
documentation sections. The actual inline code has moved out of hwloc.h
into the new hwloc/inlines.h.
+ Deprecated functions are now in hwloc/deprecated.h, and not in the
official documentation anymore.
* Tools
+ Add hwloc-diff and hwloc-patch tools together with the new diff API.
+ Add hwloc-compress-dir to (de)compress an entire directory of XML files
using hwloc-diff and hwloc-patch.
+ Object colors in the graphical output of lstopo may be changed by adding
a "lstopoStyle" info attribute. See CUSTOM COLORS in the lstopo(1) manpage
for details. Thanks to Jirka Hladky for discussing the idea.
+ hwloc-gather-topology may now gather I/O-related files on Linux when
--io is given. Only the linuxpci component supports discovering I/O
objects from these extended tarballs.
+ hwloc-annotate now supports --ri to remove/replace info attributes with
a given name.
+ hwloc-info supports "root" and "all" special locations for dumping
information about the root object.
+ lstopo now supports --append-legend to append custom lines of text
to the legend in the graphical output. Thanks to Jirka Hladky for
discussing the idea.
+ hwloc-calc and friends have a more robust parsing of locations given
on the command-line and they report useful error messages about it.
+ Add --whole-system to hwloc-bind, hwloc-calc, hwloc-distances and
hwloc-distrib, and add --restrict to hwloc-bind for uniformity among
tools.
* Misc
+ Calling hwloc_topology_load() or hwloc_topology_set_*() on an already
loaded topology now returns an error (deprecated since release 1.6.1).
+ Fix the initialisation of cpusets and nodesets in Group objects added
when inserting PCI hostbridges.
+ Never merge Group objects that were added explicitly by the user with
hwloc_custom_insert_group_object_by_parent().
+ Add a sanity check during dynamic plugin loading to prevent some
crashes when hwloc is dynamically loaded by another plugin mechanisms.
+ Add --with-hwloc-plugins-path to specify the install/load directories
of plugins.
+ Add the MICSerialNumber info attribute to the root object when running
hwloc inside a Xeon Phi to match the same attribute in the MIC OS device
when running in the host.
Version 1.7.2
-------------
* Do not create invalid block OS devices on very old Linux kernel such
@ -276,7 +411,7 @@ Version 1.5.0
- 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
+ Instruction caches are enabled in lstopo by default. Use --no-icaches
to disable them.
+ Add -t/--threads to show threads in hwloc-ps.
* Removal of obsolete components
@ -344,7 +479,7 @@ Version 1.4.1
* 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
* 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

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

@ -25,7 +25,8 @@ 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)
knowledge of cpusets, offline CPUs, ScaleMP vSMP, NumaScale NumaConnect,
and Kerrighed support)
* Solaris
* AIX
* Darwin / OS X
@ -87,8 +88,8 @@ 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$ git clone https://github.com/open-mpi/hwloc.git
shell$ cd hwloc
shell$ ./autogen.sh
Note that GNU Autoconf >=2.63, Automake >=1.10 and Libtool >=2.2.6 are required
@ -110,13 +111,16 @@ 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:
* hwloc can use one of two different libraries for full I/O device discovery:
1. libpciaccess (BSD). The relevant development package is usually
libpciaccess-devel or libpciaccess-dev.
2. libpci, from the pciutils package (GPL). The relevant development
package is usually pciutils-devel or libpci-dev.
On Linux, PCI discovery may still be performed even if none of the above
libraries can be used.
* the AMD OpenCL implementation for OpenCL device discovery.
* the NVIDIA CUDA Toolkit for CUDA device discovery.
* the NVIDIA Tesla Development Kit for NVML device discovery.
@ -353,12 +357,12 @@ And the same output in XML (line breaks added, only PU #0 shown):
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).
The basic interface is available in hwloc.h. Some higher-level functions are
available in hwloc/helper.h to reduce the need to manually manipulate objects
and follow links between them. Documentation for all these is provided later in
this document. Developers may also want to look at hwloc/inlines.h which
contains the actual inline code of some hwloc.h routines, and at this document,
which provides good higher-level topology traversal examples.
To precisely define the vocabulary used by hwloc, a Terms and Definitions
section is available and should probably be read first.
@ -662,7 +666,7 @@ 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/).
https://git.open-mpi.org/trac/hwloc/).
If hwloc discovers an incorrect topology for your machine, the very first thing
you should check is to ensure that you have the most recent updates installed
@ -675,7 +679,7 @@ 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
/proc + /sys tarball generated by the installed script hwloc-gather-topology
when submitting problems about Linux, or send the output of kstat cpu_info in
the Solaris case, or the output of sysctl hw in the Darwin or BSD cases.
@ -703,9 +707,9 @@ The documentation chapters include
* CPU and Memory Binding Overview
* I/O Devices
* Multi-node Topologies
* Object Attributes
* Object attributes
* Importing and exporting topologies from/to XML files
* Synthetic Topologies
* Synthetic topologies
* Interoperability With Other Software
* Thread Safety
* Components and plugins
@ -714,7 +718,3 @@ The documentation chapters include
Make sure to have had a look at those too!
-------------------------------------------------------------------------------
Generated on Tue Sep 3 2013 10:24:22 for Hardware Locality (hwloc) by doxygen
1.8.4

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

@ -0,0 +1,42 @@
# 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.
# If snapshot=1, then use the value from snapshot_version as the
# entire hwloc version (i.e., ignore major, minor, release, and
# greek). This is only set to 1 when making snapshot tarballs.
snapshot=0
snapshot_version=gitclone
# major, minor, and release are generally combined in the form
# <major>.<minor>.<release>. If release is zero, then it is omitted.
major=1
minor=9
release=1
# 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=
# The date when this release was created
date="Aug 25, 2014"
# 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 git master (and developer branches)
# is always 0:0:0.
# 2. Version numbers are described in the Libtool current:revision:age
# format.
libhwloc_so_version=10:1:5

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

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.13.1 -*- Autoconf -*-
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# Copyright (C) 1996-2012 Free Software Foundation, Inc.
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.13'
[am__api_version='1.14'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.13.1], [],
m4_if([$1], [1.14.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -51,7 +51,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.13.1])dnl
[AM_AUTOMAKE_VERSION([1.14.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
@ -76,7 +76,8 @@ AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
: ${AR=ar}
AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
[am_cv_ar_interface=ar
[AC_LANG_PUSH([C])
am_cv_ar_interface=ar
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
[am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
AC_TRY_EVAL([am_ar_try])
@ -93,7 +94,7 @@ AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
fi
rm -f conftest.lib libconftest.a
])
])
AC_LANG_POP([C])])
case $am_cv_ar_interface in
ar)
@ -432,7 +433,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue
test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
@ -477,6 +478,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
m4_define([AC_PROG_CC],
m4_defn([AC_PROG_CC])
[_AM_PROG_CC_C_O
])
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@ -585,7 +592,48 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
])
# POSIX will say in a future version that running "rm -f" with no argument
# is OK; and we want to be able to make that assumption in our Makefile
# recipes. So use an aggressive probe to check that the usage we want is
# actually supported "in the wild" to an acceptable degree.
# See automake bug#10828.
# To make any issue more visible, cause the running configure to be aborted
# by default if the 'rm' program in use doesn't match our expectations; the
# user can still override this though.
if rm -f && rm -fr && rm -rf; then : OK; else
cat >&2 <<'END'
Oops!
Your 'rm' program seems unable to run without file operands specified
on the command line, even when the '-f' option is present. This is contrary
to the behaviour of most rm programs out there, and not conforming with
the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
Please tell bug-automake@gnu.org about your system, including the value
of your $PATH and any error possibly output before this message. This
can help us improve future automake versions.
END
if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
echo 'Configuration will proceed anyway, since you have set the' >&2
echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
echo >&2
else
cat >&2 <<'END'
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: <http://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
fi])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@ -593,7 +641,6 @@ dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@ -705,38 +752,6 @@ AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# 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.
# AM_PROG_CC_C_O
# --------------
# Like AC_PROG_CC_C_O, but changed for automake.
AC_DEFUN([AM_PROG_CC_C_O],
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([compile])dnl
# FIXME: we rely on the cache variable name because
# there is no other way.
set dummy $CC
am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
if test "$am_t" != yes; then
# Losing compiler, so override with the script.
# FIXME: It is wrong to rewrite CC.
# But if we don't then we get into trouble of one sort or another.
# A longer-term fix would be to have automake use am__CC in this case,
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
CC="$am_aux_dir/compile $CC"
fi
dnl Make sure AC_PROG_CC is never called again, or it will override our
dnl setting of CC.
m4_define([AC_PROG_CC],
[m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2013 Free Software Foundation, Inc.
@ -807,6 +822,53 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
#
# 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.
# _AM_PROG_CC_C_O
# ---------------
# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
# to automatically call this.
AC_DEFUN([_AM_PROG_CC_C_O],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([compile])dnl
AC_LANG_PUSH([C])dnl
AC_CACHE_CHECK(
[whether $CC understands -c and -o together],
[am_cv_prog_cc_c_o],
[AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
# Make sure it works both with $CC and with simple cc.
# Following AC_PROG_CC_C_O, we do the test twice because some
# compilers refuse to overwrite an existing .o file with -o,
# though they will create one.
am_cv_prog_cc_c_o=yes
for am_i in 1 2; do
if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
&& test -f conftest2.$ac_objext; then
: OK
else
am_cv_prog_cc_c_o=no
break
fi
done
rm -f core conftest*
unset am_i])
if test "$am_cv_prog_cc_c_o" != yes; then
# Losing compiler, so override with the script.
# FIXME: It is wrong to rewrite CC.
# But if we don't then we get into trouble of one sort or another.
# A longer-term fix would be to have automake use am__CC in this case,
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
CC="$am_aux_dir/compile $CC"
fi
AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
@ -1033,76 +1095,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
#
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
m4_if([$1], [v7],
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Loop over all known methods to create a tar archive until one works.
# We'll loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
# Do not fold the above two line into one, because Tru64 sh and
# Solaris sh will not grok spaces in the rhs of '-'.
for _am_tool in $_am_tools
do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar;
do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
m4_if([$1], [v7],
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
# tar/untar a dummy directory, and stop if the command works
[m4_case([$1],
[ustar],
[# The POSIX 1988 'ustar' format is defined with fixed-size fields.
# There is notably a 21 bits limit for the UID and the GID. In fact,
# the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
# and bug#13588).
am_max_uid=2097151 # 2^21 - 1
am_max_gid=$am_max_uid
# The $UID and $GID variables are not portable, so we need to resort
# to the POSIX-mandated id(1) utility. Errors in the 'id' calls
# below are definitely unexpected, so allow the users to see them
# (that is, avoid stderr redirection).
am_uid=`id -u || echo unknown`
am_gid=`id -g || echo unknown`
AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
if test $am_uid -le $am_max_uid; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
_am_tools=none
fi
AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
if test $am_gid -le $am_max_gid; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
_am_tools=none
fi],
[pax],
[],
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Go ahead even if we have the value already cached. We do so because we
# need to set the values for the 'am__tar' and 'am__untar' variables.
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
for _am_tool in $_am_tools; do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar; do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works.
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
AM_RUN_LOG([cat conftest.dir/file])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR

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

@ -1,10 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013 Free Software Foundation, Inc.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2012-12-29'
timestamp='2013-11-29'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -26,7 +24,7 @@ timestamp='2012-12-29'
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner.
# Originally written by Per Bothner.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
@ -52,9 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2012, 2013 Free Software Foundation, Inc.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -136,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
@ -857,21 +874,21 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@ -884,59 +901,54 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
LIBC=gnu
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
@ -955,54 +967,63 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or1k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
echo powerpc-unknown-linux-${LIBC}
exit ;;
ppc64le:Linux:*:*)
echo powerpc64le-unknown-linux-${LIBC}
exit ;;
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@ -1235,19 +1256,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
i386)
eval $set_cc_for_build
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
UNAME_PROCESSOR="x86_64"
fi
fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
# that puts up a graphical alert prompting to install
# developer tools. Any system running Mac OS X 10.7 or
# later (Darwin 11 and later) is required to have a 64-bit
# processor. This is not true of the ARM version of Darwin
# that Apple uses in portable devices.
UNAME_PROCESSOR=x86_64
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)

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

@ -1,10 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013 Free Software Foundation, Inc.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2012-12-29'
timestamp='2013-10-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -70,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2012, 2013 Free Software Foundation, Inc.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -256,12 +252,12 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
@ -269,6 +265,7 @@ case $basic_machine in
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
@ -290,16 +287,17 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 \
| or32 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
@ -327,7 +325,7 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@ -369,13 +367,13 @@ case $basic_machine in
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
@ -384,6 +382,7 @@ case $basic_machine in
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
@ -407,12 +406,13 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
@ -796,7 +796,7 @@ case $basic_machine in
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@ -832,7 +832,7 @@ case $basic_machine in
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i386-pc
basic_machine=i686-pc
os=-msys
;;
mvs)
@ -1354,7 +1354,7 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
@ -1500,9 +1500,6 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
@ -1551,6 +1548,9 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
@ -1594,6 +1594,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;

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

@ -1,7 +1,7 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2012-10-18.11; # UTC
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
@ -552,6 +552,7 @@ $ {
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;

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

@ -0,0 +1,130 @@
#!/bin/sh -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-2014 Inria. All rights reserved.
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
builddir="`pwd`"
srcdir=$1
cd "$srcdir"
srcdir=`pwd`
cd "$builddir"
distdir="$builddir/$2"
HWLOC_VERSION=$3
if test "$distdir" = ""; then
echo "Must supply relative distdir as argv[2] -- aborting"
exit 1
elif test "$HWLOC_VERSION" = ""; then
echo "Must supply version as argv[1] -- aborting"
exit 1
fi
#========================================================================
start=`date`
cat <<EOF
Creating hwloc distribution
In directory: `pwd`
Srcdir: $srcdir
Builddir: $builddir
Version: $HWLOC_VERSION
Started: $start
EOF
umask 022
if test ! -d "$distdir"; then
echo "*** ERROR: dist dir does not exist"
echo "*** ERROR: $distdir"
exit 1
fi
if test ! -d $srcdir/doc/doxygen-doc; then
echo "*** The srcdir does not already have a doxygen-doc tree built."
echo "*** hwloc's config/distscript.csh requires the docs to be built"
echo "*** in the srcdir before executing 'make dist'."
exit 1
fi
# Trivial helper function
doit() {
echo $*
eval $*
}
echo "*** Copying doxygen-doc tree to dist..."
echo "*** Directory: srcdir: $srcdir, distdir: $distdir, pwd: `pwd`"
doit mkdir -p $distdir/doc/doxygen-doc
doit chmod -R a=rwx $distdir/doc/doxygen-doc
doit rm -rf $distdir/doc/doxygen-doc
# We want to copy the entire directory tree to the distdir. In some
# cases, doxygen-doc may be a sym link, so we want the copy to follow
# the sym links. It's a bit of a portability nightmare, so try a few
# different ways...
# This seems to work on OS X and Linux (but not Solaris)
doit "tar c -C $srcdir -h -f - doc/doxygen-doc | tar x -C $distdir -f -"
if test ! -d $distdir/doc/doxygen-doc; then
# This seems to work on Linux and Solaris
doit cp -rpf $srcdir/doc/doxygen-doc/ $distdir/doc
fi
if test ! -d $distdir/doc/doxygen-doc; then
# This seems to work on OS X (probably redundant, but we know it works)
doit cp -rpf $srcdir/doc/doxygen-doc $distdir/doc
fi
# If we still failed, just error out
if test ! -d $distdir/doc/doxygen-doc; then
echo "ERROR: Cannot seem to copy a directory to the distdir :-("
exit 1
fi
echo "*** Copying new README"
ls -lf $distdir/README
doit 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"
doit rm -rf doc/doxygen-doc/latex
#
# All done
#
cat <<EOF
*** hwloc version $HWLOC_VERSION distribution created
Started: $start
Ended: `date`
EOF

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

@ -1,6 +1,6 @@
dnl -*- Autoconf -*-
dnl
dnl Copyright © 2009-2013 Inria. All rights reserved.
dnl Copyright © 2009-2014 Inria. All rights reserved.
dnl Copyright (c) 2009-2012 Université Bordeaux 1
dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology
@ -184,6 +184,11 @@ EOF])
hwloc_linux=yes
AC_MSG_RESULT([Linux])
hwloc_components="$hwloc_components linux"
if test x$enable_pci != xno; then
hwloc_components="$hwloc_components linuxpci"
AC_DEFINE(HWLOC_HAVE_LINUXPCI, 1, [Define to 1 if building the Linux PCI component])
hwloc_linuxpci_happy=yes
fi
;;
*-*-irix*)
AC_DEFINE(HWLOC_IRIX_SYS, 1, [Define to 1 on Irix])
@ -349,13 +354,11 @@ EOF])
AC_CHECK_HEADERS([dirent.h])
AC_CHECK_HEADERS([strings.h])
hwloc_strncasecmp=strncmp
AC_CHECK_FUNCS([strncasecmp], [
_HWLOC_CHECK_DECL([strncasecmp], [
hwloc_strncasecmp=strncasecmp
AC_DEFINE([HWLOC_HAVE_DECL_STRNCASECMP], [1], [Define to 1 if function `strncasecmp' is declared by system headers])
])
])
AC_DEFINE_UNQUOTED(hwloc_strncasecmp, $hwloc_strncasecmp, [Define this to either strncasecmp or strncmp])
AC_CHECK_FUNCS([strftime])
AC_CHECK_FUNCS([setlocale])
@ -439,9 +442,30 @@ EOF])
#include <sys/param.h>
#endif
])
AC_CHECK_DECLS([strtoull], [], [], [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([sysctl sysctlbyname])
# Do a full link test instead of just using AC_CHECK_FUNCS, which
# just checks to see if the symbol exists or not. For example,
# the prototype of sysctl uses u_int, which on some platforms
# (such as FreeBSD) is only defined under __BSD_VISIBLE, __USE_BSD
# or other similar definitions. So while the symbols "sysctl" and
# "sysctlbyname" might still be available in libc (which autoconf
# checks for), they might not be actually usable.
AC_TRY_LINK([
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
],
[return sysctl(NULL,0,NULL,NULL,NULL,0);],
AC_DEFINE([HAVE_SYSCTL],[1],[Define to '1' if sysctl is present and usable]))
AC_TRY_LINK([
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
],
[return sysctlbyname(NULL,NULL,NULL,NULL,0);],
AC_DEFINE([HAVE_SYSCTLBYNAME],[1],[Define to '1' if sysctlbyname is present and usable]))
case ${target} in
*-*-mingw*|*-*-cygwin*)
@ -888,15 +912,39 @@ EOF])
fi
# don't add LIBS/CFLAGS/REQUIRES yet, depends on plugins
# X11 support
AC_PATH_XTRA
CPPFLAGS_save=$CPPFLAGS
LIBS_save=$LIBS
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
LIBS="$LIBS $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS"
AC_CHECK_HEADERS([X11/Xlib.h],
[AC_CHECK_LIB([X11], [XOpenDisplay],
[
# the GL backend just needs XOpenDisplay
hwloc_enable_X11=yes
# lstopo needs more
AC_CHECK_HEADERS([X11/Xutil.h],
[AC_CHECK_HEADERS([X11/keysym.h],
[AC_DEFINE([HWLOC_HAVE_X11_KEYSYM], [1], [Define to 1 if X11 headers including Xutil.h and keysym.h are available.])])
AC_SUBST([HWLOC_X11_LIBS], ["-lX11"])
])
])
])
CPPFLAGS=$CPPFLAGS_save
LIBS=$LIBS_save
# GL Support
hwloc_gl_happy=no
if test "x$enable_gl" != "xno"; then
hwloc_gl_happy=yes
hwloc_gl_happy=yes
AS_IF([test "$hwloc_enable_X11" != "yes"],
[AC_MSG_WARN([X11 not found; GL disabled])
hwloc_gl_happy=no])
AC_CHECK_HEADERS([X11/Xlib.h], [
AC_CHECK_LIB([X11], [XOpenDisplay], [:], [hwloc_gl_happy=no])
], [hwloc_gl_happy=no])
AC_CHECK_HEADERS([NVCtrl/NVCtrl.h], [
AC_CHECK_LIB([XNVCtrl], [XNVCTRLQueryTargetAttribute], [:], [hwloc_gl_happy=no], [-lXext])
], [hwloc_gl_happy=no])
@ -941,27 +989,42 @@ EOF])
fi
# don't add LIBS/CFLAGS/REQUIRES yet, depends on plugins
# Try to compile the cpuid inlines
AC_MSG_CHECKING([for cpuid])
# Try to compile the x86 cpuid inlines
AC_MSG_CHECKING([for x86 cpuid])
old_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I$HWLOC_top_srcdir/include"
# We need hwloc_uint64_t but we can't use hwloc/autogen/config.h before configure ends.
# So pass #include/#define manually here for now.
CPUID_CHECK_HEADERS=
CPUID_CHECK_DEFINE=
if test "x$hwloc_windows" = xyes; then
X86_CPUID_CHECK_HEADERS="#include <windows.h>"
X86_CPUID_CHECK_DEFINE="#define hwloc_uint64_t DWORDLONG"
else
X86_CPUID_CHECK_DEFINE="#define hwloc_uint64_t uint64_t"
if test "x$ac_cv_header_stdint_h" = xyes; then
X86_CPUID_CHECK_HEADERS="#include <stdint.h>"
fi
fi
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
$X86_CPUID_CHECK_HEADERS
$X86_CPUID_CHECK_DEFINE
#define __hwloc_inline
#include <private/cpuid.h>
#include <private/cpuid-x86.h>
]], [[
if (hwloc_have_cpuid()) {
if (hwloc_have_x86_cpuid()) {
unsigned eax = 0, ebx, ecx = 0, edx;
hwloc_cpuid(&eax, &ebx, &ecx, &edx);
printf("highest cpuid %x\n", eax);
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
printf("highest x86 cpuid %x\n", eax);
return 0;
}
]])],
[AC_MSG_RESULT([yes])
AC_DEFINE(HWLOC_HAVE_CPUID, 1, [Define to 1 if you have cpuid])
hwloc_have_cpuid=yes],
AC_DEFINE(HWLOC_HAVE_X86_CPUID, 1, [Define to 1 if you have x86 cpuid])
hwloc_have_x86_cpuid=yes],
[AC_MSG_RESULT([no])])
if test "x$hwloc_have_cpuid" = xyes; then
if test "x$hwloc_have_x86_cpuid" = xyes; then
hwloc_components="$hwloc_components x86"
fi
CPPFLAGS="$old_CPPFLAGS"
@ -1028,6 +1091,15 @@ EOF])
HWLOC_CHECK_LTDL_DEPS
fi
AC_ARG_WITH([hwloc-plugins-path],
AC_HELP_STRING([--with-hwloc-plugins-path=dir:...],
[Colon-separated list of plugin directories. Default: "$prefix/lib/hwloc". Plugins will be installed in the first directory. They will be loaded from all of them, in order.]),
[HWLOC_PLUGINS_PATH="$with_hwloc_plugins_path"],
[HWLOC_PLUGINS_PATH="\$(libdir)/hwloc"])
AC_SUBST(HWLOC_PLUGINS_PATH)
HWLOC_PLUGINS_DIR=`echo "$HWLOC_PLUGINS_PATH" | cut -d: -f1`
AC_SUBST(HWLOC_PLUGINS_DIR)
# Static components output file
hwloc_static_components_dir=${HWLOC_top_builddir}/src
mkdir -p ${hwloc_static_components_dir}
@ -1182,7 +1254,7 @@ AC_DEFUN([HWLOC_DO_AM_CONDITIONALS],[
AM_CONDITIONAL([HWLOC_HAVE_X86_32], [test "x$hwloc_x86_32" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_X86_64], [test "x$hwloc_x86_64" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_CPUID], [test "x$hwloc_have_cpuid" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_X86_CPUID], [test "x$hwloc_have_x86_cpuid" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_PLUGINS], [test "x$hwloc_have_plugins" = "xyes"])
AM_CONDITIONAL([HWLOC_PCI_BUILD_STATIC], [test "x$hwloc_pci_component" = "xstatic"])
@ -1232,7 +1304,10 @@ dnl number of arguments (10). Success means the compiler couldn't really check.
AC_DEFUN([_HWLOC_CHECK_DECL], [
AC_MSG_CHECKING([whether function $1 is declared])
AC_REQUIRE([AC_PROG_CC])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT([$4])],[$1(1,2,3,4,5,6,7,8,9,10);])],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[AC_INCLUDES_DEFAULT([$4])
$1(int,long,int,long,int,long,int,long,int,long);],
[$1(1,2,3,4,5,6,7,8,9,10);])],
[AC_MSG_RESULT([no])
$3],
[AC_MSG_RESULT([yes])

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

@ -0,0 +1,99 @@
#!/bin/sh
#
# 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-2013 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
srcfile="$1"
option="$2"
if test -z "$srcfile"; then
option="--help"
else
: ${srcdir=.}
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/^date/HWLOC_RELEASE_DATE/
s/^snapshot_version/HWLOC_SNAPSHOT_VERSION/
s/^snapshot/HWLOC_SNAPSHOT/
t print
b
: print
p" < "$srcfile"`
eval "$ompi_vers"
# Only include the 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}"
# If HWLOC_SNAPSHOT=1, then use HWLOC_SNAPSHOT_VERSION
if test "$HWLOC_SNAPSHOT" = "1"; then
# First, verify that HWLOC_SNAPSHOT_VERSION isn't empty.
if test -z "$HWLOC_SNAPSHOT_VERSION"; then
echo "*** ERROR: $1 contains snapshot=1, but an empty value for snapshot_version" 1>&2
exit 1
fi
HWLOC_VERSION=$HWLOC_SNAPSHOT_VERSION
fi
fi
if test "$option" = ""; then
option="--version"
fi
fi
case "$option" in
--version)
echo $HWLOC_VERSION
;;
--release-date)
echo $HWLOC_RELEASE_DATE
;;
--snapshot)
echo $HWLOC_SNAPSHOT
;;
-h|--help)
cat <<EOF
$0 <srcfile> <option>
<srcfile> - Text version file
<option> - One of:
--version - Show version number
--release-date - Show the release date
--snapshot - Show whether this is a snapshot release or not
--help - This message
EOF
;;
*)
echo "Unrecognized option $option. Run $0 --help for options"
;;
esac
# All done
exit 0

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

@ -1,6 +1,6 @@
dnl -*- Autoconf -*-
dnl
dnl Copyright (c) 2009-2012 Inria. All rights reserved.
dnl Copyright (c) 2009-2014 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
@ -9,7 +9,7 @@ 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 © 2010-2014 Inria. All rights reserved.
dnl Copyright © 2006-2011 Cisco Systems, Inc. All rights reserved.
dnl
dnl See COPYING in top-level directory.
@ -116,9 +116,11 @@ AC_DEFUN([HWLOC_SETUP_DOCS],[
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])])
AS_IF([test ! -d "$srcdir/.hg" -a ! -d "$srcdir/.git"],
[AC_MSG_RESULT([no (doxygen generation is optional)])
test "x$enable_doxygen" = x && enable_doxygen=no],
[AC_MSG_RESULT([yes])
test "x$enable_doxygen" = x && enable_doxygen=yes])
# Generating the doxygen output requires a few tools. If we
# don't have all of them, refuse the build the docs.
@ -190,7 +192,7 @@ EOF
# 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/man/man3/hwloc_distrib.3" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-a4.pdf" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-letter.pdf"],
[hwloc_install_doxs=yes],
@ -203,7 +205,7 @@ EOF
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"],
[AS_IF([test -d "$srcdir/.hg" -o -d "$srcdir/.git"],
[hwloc_want_picky=1])])
if test "$enable_picky" = "yes"; then
if test "$GCC" = "yes"; then
@ -255,31 +257,6 @@ EOF
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
@ -409,16 +386,19 @@ int foo(void) {
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/hwloc-compress-dir]
hwloc_config_prefix[utils/test-hwloc-annotate.sh]
hwloc_config_prefix[utils/test-hwloc-assembler.sh]
hwloc_config_prefix[utils/test-hwloc-calc.sh]
hwloc_config_prefix[utils/test-hwloc-compress-dir.sh]
hwloc_config_prefix[utils/test-hwloc-diffpatch.sh]
hwloc_config_prefix[utils/test-hwloc-distances.sh]
hwloc_config_prefix[utils/test-hwloc-distrib.sh]
hwloc_config_prefix[utils/test-hwloc-info.sh]
hwloc_config_prefix[utils/test-hwloc-ls.sh]
hwloc_config_prefix[utils/test-fake-plugin.sh])
AC_CONFIG_COMMANDS([chmoding-scripts], [chmod +x ]hwloc_config_prefix[tests/linux/test-topology.sh ]hwloc_config_prefix[tests/xml/test-topology.sh ]hwloc_config_prefix[tests/linux/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])
AC_CONFIG_COMMANDS([chmoding-scripts], [chmod +x ]hwloc_config_prefix[tests/linux/test-topology.sh ]hwloc_config_prefix[tests/xml/test-topology.sh ]hwloc_config_prefix[tests/linux/hwloc-gather-topology ]hwloc_config_prefix[tests/linux/gather/test-gather-topology.sh ]hwloc_config_prefix[tests/wrapper.sh ]hwloc_config_prefix[utils/hwloc-assembler-remote ]hwloc_config_prefix[utils/hwloc-compress-dir ]hwloc_config_prefix[utils/test-hwloc-annotate.sh ]hwloc_config_prefix[utils/test-hwloc-assembler.sh ]hwloc_config_prefix[utils/test-hwloc-calc.sh ]hwloc_config_prefix[utils/test-hwloc-compress-dir.sh ]hwloc_config_prefix[utils/test-hwloc-diffpatch.sh ]hwloc_config_prefix[utils/test-hwloc-distances.sh ]hwloc_config_prefix[utils/test-hwloc-distrib.sh ]hwloc_config_prefix[utils/test-hwloc-info.sh ]hwloc_config_prefix[utils/test-hwloc-ls.sh ]hwloc_config_prefix[utils/test-fake-plugin.sh])
# These links are only needed in standalone mode. It would
# be nice to m4 foreach this somehow, but whenever I tried

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

@ -31,7 +31,7 @@
# HWLOC_PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
# hwloc note: Per https://svn.open-mpi.org/trac/hwloc/ticket/55, keep
# hwloc note: Per https://git.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

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

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

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

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

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

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

@ -1,7 +1,7 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
@ -160,7 +160,7 @@ give_advice ()
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)

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

@ -1,7 +1,7 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
scriptversion=2012-06-27.10; # UTC
scriptversion=2013-07-13.22; # UTC
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
@ -44,13 +44,12 @@ print_usage ()
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
[--enable-hard-errors={yes|no}] [--]
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
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.
@ -69,10 +68,23 @@ while test $# -gt 0; do
--enable-hard-errors) enable_hard_errors=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
*) break;;
esac
shift
done
missing_opts=
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
if test x"$missing_opts" != x; then
usage_error "the following mandatory options are missing:$missing_opts"
fi
if test $# -eq 0; then
usage_error "missing argument"
fi
if test $color_tests = yes; then
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
red='' # Red.

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

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

@ -13,7 +13,7 @@
#
AC_INIT([hwloc],
[m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --base]))],
[m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --version]))],
[http://www.open-mpi.org/projects/hwloc/], [hwloc])
AC_PREREQ(2.63)
AC_CONFIG_AUX_DIR(./config)
@ -50,29 +50,20 @@ 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`"
if test "$?" != "0"; then
AC_MSG_ERROR([Cannot continue])
fi
HWLOC_RELEASE_DATE="`$srcdir/config/hwloc_get_version.sh $srcdir/VERSION --release-date`"
AC_SUBST(HWLOC_VERSION)
AC_SUBST(HWLOC_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.
# 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}"
@ -193,9 +184,17 @@ append_env() {
if test x$hwloc_warn_may_use_libpci = xyes; then
echo
echo "***********************************************************************"
echo "PCI support could not be enabled because libpciaccess is not available."
if test "x$hwloc_linuxpci_happy" = "xyes"; then
echo "Full PCI support could not be enabled because libpciaccess is not available."
else
echo "PCI support could not be enabled because libpciaccess is not available."
fi
echo "libpci could be used instead but hwloc may be tainted by the GPL"
echo "license of pciutils. Add --enable-libpci to enable it."
if test "x$hwloc_linuxpci_happy" = "xyes"; then
echo "Only the Linux-specific PCI (linuxpci component) is enabled for now."
echo "It misses device names."
fi
echo "***********************************************************************"
fi
@ -205,13 +204,19 @@ 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"
if test "x$hwloc_pci_happy" = "xyes" -o "x$hwloc_linuxpci_happy" = "xyes"; then
test "x$hwloc_pci_happy" = "xyes" && hwloc_probepci_list="$hwloc_pci_lib"
test "x$hwloc_pci_happy$hwloc_linuxpci_happy" = "xyesyes" && hwloc_probepci_list="${hwloc_probepci_list}+"
test "x$hwloc_linuxpci_happy" = "xyes" && hwloc_probepci_list="${hwloc_probepci_list}linux"
hwloc_probeio_list="$hwloc_probeio_list PCI($hwloc_probepci_list)"
fi
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)"
test "x$hwloc_pci_happy" != "xyes" && test "x$hwloc_linuxpci_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"

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

@ -1,4 +1,4 @@
# Copyright © 2009-2012 Inria. All rights reserved.
# Copyright © 2009-2014 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.
@ -13,6 +13,8 @@ include_hwlocdir = $(includedir)/hwloc
include_hwloc_HEADERS = \
hwloc/bitmap.h \
hwloc/helper.h \
hwloc/inlines.h \
hwloc/diff.h \
hwloc/myriexpress.h \
hwloc/openfabrics-verbs.h \
hwloc/opencl.h \
@ -22,7 +24,8 @@ include_hwloc_HEADERS = \
hwloc/plugins.h \
hwloc/gl.h \
hwloc/intel-mic.h \
hwloc/rename.h
hwloc/rename.h \
hwloc/deprecated.h
include_hwloc_autogendir = $(includedir)/hwloc/autogen
nodist_include_hwloc_autogen_HEADERS = hwloc/autogen/config.h
@ -32,7 +35,7 @@ noinst_HEADERS = \
private/misc.h \
private/xml.h \
private/components.h \
private/cpuid.h
private/cpuid-x86.h
if HWLOC_HAVE_LINUX
include_hwloc_HEADERS += \

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -41,6 +41,7 @@
*
* See hwloc/bitmap.h for bitmap specific macros.
* See hwloc/helper.h for high-level topology traversal helpers.
* See hwloc/inlines.h for the actual inline code of some functions below.
*/
#ifndef HWLOC_H
@ -74,34 +75,19 @@ extern "C" {
*/
/** \brief Indicate at build time which hwloc API version is being used. */
#define HWLOC_API_VERSION 0x00010700
#define HWLOC_API_VERSION 0x00010900
/** \brief Indicate at runtime which hwloc API version was used at build time. */
HWLOC_DECLSPEC unsigned hwloc_get_api_version(void);
/** \brief Current component and plugin ABI version (see hwloc/plugins.h) */
#define HWLOC_COMPONENT_ABI 2
#define HWLOC_COMPONENT_ABI 3
/** @} */
/** \defgroup hwlocality_topology Topology context
* @{
*/
struct hwloc_topology;
/** \brief Topology context
*
* To be initialized with hwloc_topology_init() and built with hwloc_topology_load().
*/
typedef struct hwloc_topology * hwloc_topology_t;
/** @} */
/** \defgroup hwlocality_sets Object sets (hwloc_cpuset_t and hwloc_nodeset_t)
/** \defgroup hwlocality_object_sets Object Sets (hwloc_cpuset_t and hwloc_nodeset_t)
*
* Hwloc uses bitmaps to represent two distinct kinds of object sets:
* CPU sets (::hwloc_cpuset_t) and NUMA node sets (::hwloc_nodeset_t).
@ -153,7 +139,7 @@ typedef hwloc_const_bitmap_t hwloc_const_nodeset_t;
/** \defgroup hwlocality_types Topology Object Types
/** \defgroup hwlocality_object_types Object Types
* @{
*/
@ -314,7 +300,7 @@ enum hwloc_compare_types_e {
/** \defgroup hwlocality_objects Topology Objects
/** \defgroup hwlocality_objects Object Structure and Attributes
* @{
*/
@ -579,10 +565,17 @@ struct hwloc_obj_info_s {
/** \defgroup hwlocality_creation Create and Destroy Topologies
/** \defgroup hwlocality_creation Topology Creation and Destruction
* @{
*/
struct hwloc_topology;
/** \brief Topology context
*
* To be initialized with hwloc_topology_init() and built with hwloc_topology_load().
*/
typedef struct hwloc_topology * hwloc_topology_t;
/** \brief Allocate a topology context.
*
* \param[out] topologyp is assigned a pointer to the new allocated context.
@ -633,9 +626,9 @@ HWLOC_DECLSPEC void hwloc_topology_check(hwloc_topology_t topology);
/** \defgroup hwlocality_configuration Configure Topology Detection
/** \defgroup hwlocality_configuration Topology Detection Configuration and Query
*
* These functions can optionally be called between hwloc_topology_init() and
* Several functions can optionally be called between hwloc_topology_init() and
* hwloc_topology_load() to configure how the detection should be performed,
* e.g. to ignore some objects types, define a synthetic topology, etc.
*
@ -769,6 +762,14 @@ enum hwloc_topology_flags_e {
*/
HWLOC_DECLSPEC int hwloc_topology_set_flags (hwloc_topology_t topology, unsigned long flags);
/** \brief Get OR'ed flags of a topology.
*
* Get the OR'ed set of ::hwloc_topology_flags_e of a topology.
*
* \return the flags previously set with hwloc_topology_set_flags().
*/
HWLOC_DECLSPEC unsigned long hwloc_topology_get_flags (hwloc_topology_t topology);
/** \brief Change which pid the topology is viewed from
*
* On some systems, processes may have different views of the machine, for
@ -857,7 +858,7 @@ HWLOC_DECLSPEC int hwloc_topology_set_synthetic(hwloc_topology_t __hwloc_restric
* \return -1 with errno set to EINVAL on failure to read the XML file.
*
* \note See also hwloc_topology_set_userdata_import_callback()
* for importing application-specific userdata.
* for importing application-specific object userdata.
*
* \note For convenience, this backend provides empty binding hooks which just
* return success. To have hwloc still actually call OS-specific hooks, the
@ -885,7 +886,7 @@ HWLOC_DECLSPEC int hwloc_topology_set_xml(hwloc_topology_t __hwloc_restrict topo
* \return -1 with errno set to EINVAL on failure to read the XML buffer.
*
* \note See also hwloc_topology_set_userdata_import_callback()
* for importing application-specific userdata.
* for importing application-specific object userdata.
*
* \note For convenience, this backend provides empty binding hooks which just
* return success. To have hwloc still actually call OS-specific hooks, the
@ -910,6 +911,9 @@ HWLOC_DECLSPEC int hwloc_topology_set_xmlbuffer(hwloc_topology_t __hwloc_restric
* \note If nothing is inserted in the topology,
* hwloc_topology_load() will fail with errno set to EINVAL.
*
* \note The cpuset and nodeset of the root object are NULL because
* these sets are meaningless when assembling multiple topologies.
*
* \note On success, the custom component replaces the previously enabled
* component (if any), but the topology is not actually modified until
* hwloc_topology_load().
@ -937,6 +941,15 @@ HWLOC_DECLSPEC int hwloc_topology_set_distance_matrix(hwloc_topology_t __hwloc_r
hwloc_obj_type_t type, unsigned nbobjs,
unsigned *os_index, float *distances);
/** \brief Does the topology context come from this system?
*
* \return 1 if this topology context was built using the system
* running this program.
* \return 0 instead (for instance if using another file-system root,
* a XML topology file, or a synthetic topology).
*/
HWLOC_DECLSPEC int hwloc_topology_is_thissystem(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
/** \brief Flags describing actual discovery support for this topology. */
struct hwloc_topology_discovery_support {
/** \brief Detecting the number of PU objects is supported. */
@ -1023,220 +1036,7 @@ HWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(h
/** \defgroup hwlocality_xmlexport Exporting Topologies to XML.
* @{
*/
/** \brief Export the topology into an XML file.
*
* This file may be loaded later through hwloc_topology_set_xml().
*
* \return -1 if a failure occured.
*
* \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific userdata.
*
* \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently
* dropped.
*/
HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const char *xmlpath);
/** \brief Export the topology into a newly-allocated XML memory buffer.
*
* \p xmlbuffer is allocated by the callee and should be freed with
* hwloc_free_xmlbuffer() later in the caller.
*
* This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().
*
* \return -1 if a failure occured.
*
* \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific userdata.
*
* \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently
* dropped.
*/
HWLOC_DECLSPEC int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen);
/** \brief Free a buffer allocated by hwloc_topology_export_xmlbuffer() */
HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuffer);
/** \brief Set the application-specific callback for exporting userdata
*
* The object userdata pointer is not exported to XML by default because hwloc
* does not know what it contains.
*
* This function lets applications set \p export_cb to a callback function
* that converts this opaque userdata into an exportable string.
*
* \p export_cb is invoked during XML export for each object whose
* \p userdata pointer is not \c NULL.
* The callback should use hwloc_export_obj_userdata() or
* hwloc_export_obj_userdata_base64() to actually export
* something to XML (possibly multiple times per object).
*
* \p export_cb may be set to \c NULL if userdata should not be exported to XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
/** \brief Export some object userdata to XML
*
* This function may only be called from within the export() callback passed
* to hwloc_topology_set_userdata_export_callback().
* It may be invoked one of multiple times to export some userdata to XML.
* The \p buffer content of length \p length is stored with optional name
* \p name.
*
* When importing this XML file, the import() callback (if set) will be
* called exactly as many times as hwloc_export_obj_userdata() was called
* during export(). It will receive the corresponding \p name, \p buffer
* and \p length arguments.
*
* \p reserved, \p topology and \p obj must be the first three parameters
* that were given to the export callback.
*
* Only printable characters may be exported to XML string attributes.
* If a non-printable character is passed in \p name or \p buffer,
* the function returns -1 with errno set to EINVAL.
*
* If exporting binary data, the application should first encode into
* printable characters only (or use hwloc_export_obj_userdata_base64()).
* It should also take care of portability issues if the export may
* be reimported on a different architecture.
*/
HWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
/** \brief Encode and export some object userdata to XML
*
* This function is similar to hwloc_export_obj_userdata() but it encodes
* the input buffer into printable characters before exporting.
* On import, decoding is automatically performed before the data is given
* to the import() callback if any.
*
* This function may only be called from within the export() callback passed
* to hwloc_topology_set_userdata_export_callback().
*
* The function does not take care of portability issues if the export
* may be reimported on a different architecture.
*/
HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
/** \brief Set the application-specific callback for importing userdata
*
* On XML import, userdata is ignored by default because hwloc does not know
* how to store it in memory.
*
* This function lets applications set \p import_cb to a callback function
* that will get the XML-stored userdata and store it in the object as expected
* by the application.
*
* \p import_cb is called during hwloc_topology_load() as many times as
* hwloc_export_obj_userdata() was called during export. The topology
* is not entirely setup yet. Object attributes are ready to consult,
* but links between objects are not.
*
* \p import_cb may be \c NULL if userdata should be ignored during import.
*
* \note \p buffer contains \p length characters followed by a null byte ('\0').
*
* \note This function should be called before hwloc_topology_load().
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
/** @} */
/** \defgroup hwlocality_tinker Tinker With Topologies.
* @{
*/
/** \brief Add a MISC object to the topology
*
* A new MISC object will be created and inserted into the topology at the
* position given by bitmap \p cpuset. This offers a way to add new
* intermediate levels to the topology hierarchy.
*
* \p cpuset and \p name will be copied to setup the new object attributes.
*
* \return the newly-created object.
* \return \c NULL if the insertion conflicts with the existing topology tree.
*
* \note If \p name contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml().
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object_by_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, const char *name);
/** \brief Add a MISC object as a leaf of the topology
*
* A new MISC object will be created and inserted into the topology at the
* position given by parent. It is appended to the list of existing children,
* without ever adding any intermediate hierarchy level. This is useful for
* annotating the topology without actually changing the hierarchy.
*
* \p name will be copied to the setup the new object attributes.
* However, the new leaf object will not have any \p cpuset.
*
* \return the newly-created object
*
* \note If \p name contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml().
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name);
/** \brief Flags to be given to hwloc_topology_restrict(). */
enum hwloc_restrict_flags_e {
/** \brief Adapt distance matrices according to objects being removed during restriction.
* If this flag is not set, distance matrices are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_DISTANCES = (1<<0),
/** \brief Move Misc objects to ancestors if their parents are removed during restriction.
* If this flag is not set, Misc objects are removed when their parents are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_MISC = (1<<1),
/** \brief Move I/O objects to ancestors if their parents are removed during restriction.
* If this flag is not set, I/O devices and bridges are removed when their parents are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_IO = (1<<2)
};
/** \brief Restrict the topology to the given CPU set.
*
* Topology \p topology is modified so as to remove all objects that
* are not included (or partially included) in the CPU set \p cpuset.
* All objects CPU and node sets are restricted accordingly.
*
* \p flags is a OR'ed set of ::hwloc_restrict_flags_e.
*
* \note This call may not be reverted by restricting back to a larger
* cpuset. Once dropped during restriction, objects may not be brought
* back, except by loading another topology with hwloc_topology_load().
*
* \return 0 on success.
*
* \return -1 with errno set to EINVAL if the input cpuset is invalid.
* The topology is not modified in this case.
*
* \return -1 with errno set to ENOMEM on failure to allocate internal data.
* The topology is reinitialized in this case. It should be either
* destroyed with hwloc_topology_destroy() or configured and loaded again.
*/
HWLOC_DECLSPEC int hwloc_topology_restrict(hwloc_topology_t __hwloc_restrict topology, hwloc_const_cpuset_t cpuset, unsigned long flags);
/** @} */
/** \defgroup hwlocality_information Get Some Topology Information
/** \defgroup hwlocality_levels Object levels, depths and types
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
@ -1283,6 +1083,30 @@ enum hwloc_get_type_depth_e {
HWLOC_TYPE_DEPTH_OS_DEVICE = -5 /**< \brief Virtual depth for software device object level. \hideinitializer */
};
/** \brief Returns the depth of objects of type \p type or below
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically found
* inside \p type.
*
* If some objects of the given type exist in different levels, for instance
* L1 and L2 caches, the function returns HWLOC_TYPE_DEPTH_MULTIPLE.
*/
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the depth of objects of type \p type or above
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically
* containing \p type.
*
* If some objects of the given type exist in different levels, for instance
* L1 and L2 caches, the function returns HWLOC_TYPE_DEPTH_MULTIPLE.
*/
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
/** \brief Returns the type of objects at depth \p depth.
*
* \return -1 if depth \p depth does not exist.
@ -1300,46 +1124,14 @@ HWLOC_DECLSPEC unsigned hwloc_get_nbobjs_by_depth (hwloc_topology_t topology, un
*/
static __hwloc_inline int
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return -1; /* FIXME: agregate nbobjs from different levels? */
return hwloc_get_nbobjs_by_depth(topology, depth);
}
/** \brief Does the topology context come from this system?
/** \brief Returns the top-object of the topology-tree.
*
* \return 1 if this topology context was built using the system
* running this program.
* \return 0 instead (for instance if using another file-system root,
* a XML topology file, or a synthetic topology).
*/
HWLOC_DECLSPEC int hwloc_topology_is_thissystem(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
/** \brief Get OR'ed flags of a topology.
*
* Get the OR'ed set of ::hwloc_topology_flags_e of a topology.
*
* \return the flags previously set with hwloc_topology_set_flags().
*/
HWLOC_DECLSPEC unsigned long hwloc_topology_get_flags (hwloc_topology_t topology);
/** @} */
/** \defgroup hwlocality_traversal Retrieve Objects
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers.
* Its type is typically ::HWLOC_OBJ_MACHINE but it could be different
* for complex topologies.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx from depth \p depth */
HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, unsigned depth, unsigned idx) __hwloc_attribute_pure;
@ -1352,33 +1144,65 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, un
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
/** \brief Returns the next object at depth \p depth.
*
* If \p prev is \c NULL, return the first object at depth \p depth.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return NULL;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return NULL;
return hwloc_get_obj_by_depth(topology, depth, idx);
}
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev);
/** \brief Returns the next object of type \p type.
*
* If \p prev is \c NULL, return the first object at type \p type. If
* there are multiple or no depth for given type, return \c NULL and
* let the caller fallback to hwloc_get_next_obj_by_depth().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev);
/** @} */
/** \defgroup hwlocality_conversion Object/String Conversion
/** \defgroup hwlocality_object_strings Manipulating Object Type, Sets and Attributes as Strings
* @{
*/
/** \brief Return a stringified topology object type */
HWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwloc_attribute_const;
/** \brief Return an object type from the string
/** \brief Return an object type and attributes from a type string.
*
* \return -1 if unrecognized.
* Convert strings such as "socket" or "cache" into the corresponding types.
* Matching is case-insensitive, and only the first letters are actually
* required to match.
*
* Types that have specific attributes, for instance caches and groups,
* may be returned in \p depthattrp and \p typeattrp. They are ignored
* when these pointers are \c NULL.
*
* For instance "L2i" or "L2iCache" would return
* type HWLOC_OBJ_CACHE in \p typep, 2 in \p depthattrp,
* and HWLOC_OBJ_CACHE_TYPE_INSTRUCTION in \p typeattrp
* (this last pointer should point to a hwloc_obj_cache_type_t).
* "Group3" would return type HWLOC_OBJ_GROUP type and 3 in \p depthattrp.
* Attributes that are not specified in the string (for instance "Group"
* without a depth, or "L2Cache" without a cache type) are set to -1.
*
* \p typeattrd is only filled if the size specified in \p typeattrsize
* is large enough. It is currently only used for caches, and the required
* size is at least the size of hwloc_obj_cache_type_t.
*
* \return 0 if a type was correctly identified, otherwise -1.
*
* \note This is an extended version of the now deprecated hwloc_obj_type_of_string()
*/
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_obj_type_of_string (const char * string) __hwloc_attribute_pure;
HWLOC_DECLSPEC int hwloc_obj_type_sscanf(const char *string,
hwloc_obj_type_t *typep,
int *depthattrp,
void *typeattrp, size_t typeattrsize);
/** \brief Stringify the type of a given topology object into a human-readable form.
*
@ -1407,30 +1231,6 @@ HWLOC_DECLSPEC int hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_
HWLOC_DECLSPEC int hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj, const char * __hwloc_restrict separator,
int verbose);
/** \brief Stringify a given topology object into a human-readable form.
*
* \note This function is deprecated in favor of hwloc_obj_type_snprintf()
* and hwloc_obj_attr_snprintf() since it is not very flexible and
* only prints physical/OS indexes.
*
* Fill string \p string up to \p size characters with the description
* of topology object \p obj in topology \p topology.
*
* If \p verbose is set, a longer description is used. Otherwise a
* short description is used.
*
* \p indexprefix is used to prefix the \p os_index attribute number of
* the object in the description. If \c NULL, the \c # character is used.
*
* If \p size is 0, \p string 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_obj_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_topology_t topology, hwloc_obj_t obj,
const char * __hwloc_restrict indexprefix, int verbose);
/** \brief Stringify the cpuset containing a set of objects.
*
* If \p size is 0, \p string may safely be \c NULL.
@ -1448,15 +1248,6 @@ HWLOC_DECLSPEC int hwloc_obj_cpuset_snprintf(char * __hwloc_restrict str, size_t
*/
static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name) __hwloc_attribute_pure;
static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
{
unsigned i;
for(i=0; i<obj->infos_count; i++)
if (!strcmp(obj->infos[i].name, name))
return obj->infos[i].value;
return NULL;
}
/** \brief Add the given info name and value pair to the given object.
*
@ -1465,6 +1256,10 @@ hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
*
* The input strings are copied before being added in the object infos.
*
* \note This function may be used to enforce object colors in the lstopo
* graphical output by using "lstopoStyle" as a name and "Background=#rrggbb"
* as a value. See CUSTOM COLORS in the lstopo(1) manpage for details.
*
* \note If \p value contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml().
*/
@ -1598,7 +1393,11 @@ HWLOC_DECLSPEC int hwloc_get_cpubind(hwloc_topology_t topology, hwloc_cpuset_t s
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note HWLOC_CPUBIND_THREAD can not be used in \p flags.
* \note As a special case on Linux, if a tid (thread ID) is supplied
* instead of a pid (process ID) and HWLOC_CPUBIND_THREAD is passed in flags,
* the binding is applied to that specific thread.
*
* \note On non-Linux systems, HWLOC_CPUBIND_THREAD can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);
@ -1607,11 +1406,11 @@ HWLOC_DECLSPEC int hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
* and \p HANDLE on native Windows platforms.
*
* \note HWLOC_CPUBIND_THREAD can not be used in \p flags.
*
* \note As a special case on Linux, if a tid (thread ID) is supplied
* instead of a pid (process ID), the binding for that specific thread
* is returned.
* instead of a pid (process ID) and HWLOC_CPUBIND_THREAD is passed in flags,
* the binding for that specific thread is returned.
*
* \note On non-Linux systems, HWLOC_CPUBIND_THREAD can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
@ -1664,7 +1463,9 @@ HWLOC_DECLSPEC int hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_
*
* \note As a special case on Linux, if a tid (thread ID) is supplied
* instead of a pid (process ID) and HWLOC_CPUBIND_THREAD is passed in flags,
* the binding for that specific thread is returned.
* the last CPU location of that specific thread is returned.
*
* \note On non-Linux systems, HWLOC_CPUBIND_THREAD can not be used in \p flags.
*/
HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
@ -1715,7 +1516,7 @@ HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, h
*
* Each hwloc memory binding function is available in two forms: one
* that takes a CPU set argument and another that takes a NUMA memory
* node set argument (see \ref hwlocality_sets and \ref
* node set argument (see \ref hwlocality_object_sets and \ref
* hwlocality_bitmap for a discussion of CPU sets and NUMA memory node
* sets). The names of the latter form end with _nodeset. It is also
* possible to convert between CPU set and node set using
@ -2157,6 +1958,22 @@ HWLOC_DECLSPEC void *hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size
*/
HWLOC_DECLSPEC void *hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t cpuset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;
/** \brief Allocate some memory on the given nodeset \p nodeset
*
* This is similar to hwloc_alloc_membind except that it is allowed to change
* the current memory binding policy, thus providing more binding support, at
* the expense of changing the current state.
*/
static __hwloc_inline void *
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;
/** \brief Allocate some memory on the memory nodes near given cpuset \p cpuset
*
* This is similar to hwloc_alloc_membind_policy_nodeset, but for a given cpuset.
*/
static __hwloc_inline void *
hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;
/** \brief Free memory that was previously allocated by hwloc_alloc()
* or hwloc_alloc_membind().
*/
@ -2166,6 +1983,100 @@ HWLOC_DECLSPEC int hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
/** \defgroup hwlocality_tinker Modifying a loaded Topology
* @{
*/
/** \brief Add a MISC object to the topology
*
* A new MISC object will be created and inserted into the topology at the
* position given by bitmap \p cpuset. This offers a way to add new
* intermediate levels to the topology hierarchy.
*
* \p cpuset and \p name will be copied to setup the new object attributes.
*
* \return the newly-created object.
* \return \c NULL if the insertion conflicts with the existing topology tree.
*
* \note If \p name contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml().
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object_by_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, const char *name);
/** \brief Add a MISC object as a leaf of the topology
*
* A new MISC object will be created and inserted into the topology at the
* position given by parent. It is appended to the list of existing children,
* without ever adding any intermediate hierarchy level. This is useful for
* annotating the topology without actually changing the hierarchy.
*
* \p name will be copied to the setup the new object attributes.
* However, the new leaf object will not have any \p cpuset.
*
* \return the newly-created object
*
* \note If \p name contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml().
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name);
/** \brief Flags to be given to hwloc_topology_restrict(). */
enum hwloc_restrict_flags_e {
/** \brief Adapt distance matrices according to objects being removed during restriction.
* If this flag is not set, distance matrices are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_DISTANCES = (1<<0),
/** \brief Move Misc objects to ancestors if their parents are removed during restriction.
* If this flag is not set, Misc objects are removed when their parents are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_MISC = (1<<1),
/** \brief Move I/O objects to ancestors if their parents are removed during restriction.
* If this flag is not set, I/O devices and bridges are removed when their parents are removed.
* \hideinitializer
*/
HWLOC_RESTRICT_FLAG_ADAPT_IO = (1<<2)
};
/** \brief Restrict the topology to the given CPU set.
*
* Topology \p topology is modified so as to remove all objects that
* are not included (or partially included) in the CPU set \p cpuset.
* All objects CPU and node sets are restricted accordingly.
*
* \p flags is a OR'ed set of ::hwloc_restrict_flags_e.
*
* \note This call may not be reverted by restricting back to a larger
* cpuset. Once dropped during restriction, objects may not be brought
* back, except by loading another topology with hwloc_topology_load().
*
* \return 0 on success.
*
* \return -1 with errno set to EINVAL if the input cpuset is invalid.
* The topology is not modified in this case.
*
* \return -1 with errno set to ENOMEM on failure to allocate internal data.
* The topology is reinitialized in this case. It should be either
* destroyed with hwloc_topology_destroy() or configured and loaded again.
*/
HWLOC_DECLSPEC int hwloc_topology_restrict(hwloc_topology_t __hwloc_restrict topology, hwloc_const_cpuset_t cpuset, unsigned long flags);
/** \brief Duplicate a topology.
*
* The entire topology structure as well as its objects
* are duplicated into a new one.
*
* This is useful for keeping a backup while modifying a topology.
*/
HWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);
/** @} */
/** \defgroup hwlocality_custom Building Custom Topologies
*
* A custom topology may be initialized by calling hwloc_topology_set_custom()
@ -2191,6 +2102,9 @@ HWLOC_DECLSPEC int hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
*
* \p newparent may be either the root of \p newtopology or an object
* that was added through hwloc_custom_insert_group_object_by_parent().
*
* \note The cpuset and nodeset of the \p newparent object are not
* modified based on the contents of \p oldtopology.
*/
HWLOC_DECLSPEC int hwloc_custom_insert_topology(hwloc_topology_t newtopology, hwloc_obj_t newparent, hwloc_topology_t oldtopology, hwloc_obj_t oldroot);
@ -2209,6 +2123,11 @@ HWLOC_DECLSPEC int hwloc_custom_insert_topology(hwloc_topology_t newtopology, hw
*
* \p parent may be either the root of \p topology or an object that
* was added earlier through hwloc_custom_insert_group_object_by_parent().
*
* \note The cpuset and nodeset of the new group object are NULL because
* these sets are meaningless when assembling multiple topologies.
*
* \note The cpuset and nodeset of the \p parent object are not modified.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_custom_insert_group_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, int groupdepth);
@ -2216,6 +2135,136 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_custom_insert_group_object_by_parent(hwloc_topo
/** \defgroup hwlocality_xmlexport Exporting Topologies to XML
* @{
*/
/** \brief Export the topology into an XML file.
*
* This file may be loaded later through hwloc_topology_set_xml().
*
* \return -1 if a failure occured.
*
* \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific object userdata.
*
* \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently
* dropped.
*
* \note If \p name is "-", the XML output is sent to the standard output.
*/
HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const char *xmlpath);
/** \brief Export the topology into a newly-allocated XML memory buffer.
*
* \p xmlbuffer is allocated by the callee and should be freed with
* hwloc_free_xmlbuffer() later in the caller.
*
* This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().
*
* \return -1 if a failure occured.
*
* \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific object userdata.
*
* \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently
* dropped.
*/
HWLOC_DECLSPEC int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen);
/** \brief Free a buffer allocated by hwloc_topology_export_xmlbuffer() */
HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuffer);
/** \brief Set the application-specific callback for exporting object userdata
*
* The object userdata pointer is not exported to XML by default because hwloc
* does not know what it contains.
*
* This function lets applications set \p export_cb to a callback function
* that converts this opaque userdata into an exportable string.
*
* \p export_cb is invoked during XML export for each object whose
* \p userdata pointer is not \c NULL.
* The callback should use hwloc_export_obj_userdata() or
* hwloc_export_obj_userdata_base64() to actually export
* something to XML (possibly multiple times per object).
*
* \p export_cb may be set to \c NULL if userdata should not be exported to XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
/** \brief Export some object userdata to XML
*
* This function may only be called from within the export() callback passed
* to hwloc_topology_set_userdata_export_callback().
* It may be invoked one of multiple times to export some userdata to XML.
* The \p buffer content of length \p length is stored with optional name
* \p name.
*
* When importing this XML file, the import() callback (if set) will be
* called exactly as many times as hwloc_export_obj_userdata() was called
* during export(). It will receive the corresponding \p name, \p buffer
* and \p length arguments.
*
* \p reserved, \p topology and \p obj must be the first three parameters
* that were given to the export callback.
*
* Only printable characters may be exported to XML string attributes.
* If a non-printable character is passed in \p name or \p buffer,
* the function returns -1 with errno set to EINVAL.
*
* If exporting binary data, the application should first encode into
* printable characters only (or use hwloc_export_obj_userdata_base64()).
* It should also take care of portability issues if the export may
* be reimported on a different architecture.
*/
HWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
/** \brief Encode and export some object userdata to XML
*
* This function is similar to hwloc_export_obj_userdata() but it encodes
* the input buffer into printable characters before exporting.
* On import, decoding is automatically performed before the data is given
* to the import() callback if any.
*
* This function may only be called from within the export() callback passed
* to hwloc_topology_set_userdata_export_callback().
*
* The function does not take care of portability issues if the export
* may be reimported on a different architecture.
*/
HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
/** \brief Set the application-specific callback for importing userdata
*
* On XML import, userdata is ignored by default because hwloc does not know
* how to store it in memory.
*
* This function lets applications set \p import_cb to a callback function
* that will get the XML-stored userdata and store it in the object as expected
* by the application.
*
* \p import_cb is called during hwloc_topology_load() as many times as
* hwloc_export_obj_userdata() was called during export. The topology
* is not entirely setup yet. Object attributes are ready to consult,
* but links between objects are not.
*
* \p import_cb may be \c NULL if userdata should be ignored during import.
*
* \note \p buffer contains \p length characters followed by a null byte ('\0').
*
* \note This function should be called before hwloc_topology_load().
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
@ -2224,5 +2273,13 @@ HWLOC_DECLSPEC hwloc_obj_t hwloc_custom_insert_group_object_by_parent(hwloc_topo
/* high-level helpers */
#include <hwloc/helper.h>
/* inline code of some functions above */
#include <hwloc/inlines.h>
/* topology diffs */
#include <hwloc/diff.h>
/* deprecated headers */
#include <hwloc/deprecated.h>
#endif /* HWLOC_H */

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

@ -32,7 +32,7 @@ extern "C" {
*
* <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.
* \note CPU sets and nodesets are described in \ref hwlocality_object_sets.
*
* A bitmap may be of infinite size.
* @{

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

@ -31,7 +31,11 @@ extern "C" {
#endif
/** \defgroup hwlocality_cuda CUDA Driver API Specific Functions
/** \defgroup hwlocality_cuda Interoperability with the CUDA Driver API
*
* This interface offers ways to retrieve topology information about
* CUDA devices when using the CUDA Driver API.
*
* @{
*/

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

@ -31,7 +31,11 @@ extern "C" {
#endif
/** \defgroup hwlocality_cudart CUDA Runtime API Specific Functions
/** \defgroup hwlocality_cudart Interoperability with the CUDA Runtime API
*
* This interface offers ways to retrieve topology information about
* CUDA devices when using the CUDA Runtime API.
*
* @{
*/

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

@ -0,0 +1,93 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/**
* This file contains the inline code of functions declared in hwloc.h
*/
#ifndef HWLOC_DEPRECATED_H
#define HWLOC_DEPRECATED_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** \brief Return an object type from the string
*
* \return -1 if unrecognized.
*/
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_obj_type_of_string (const char * string) __hwloc_attribute_pure;
/** \brief Stringify a given topology object into a human-readable form.
*
* \note This function is deprecated in favor of hwloc_obj_type_snprintf()
* and hwloc_obj_attr_snprintf() since it is not very flexible and
* only prints physical/OS indexes.
*
* Fill string \p string up to \p size characters with the description
* of topology object \p obj in topology \p topology.
*
* If \p verbose is set, a longer description is used. Otherwise a
* short description is used.
*
* \p indexprefix is used to prefix the \p os_index attribute number of
* the object in the description. If \c NULL, the \c # character is used.
*
* If \p size is 0, \p string 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_obj_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_topology_t topology, hwloc_obj_t obj,
const char * __hwloc_restrict indexprefix, int verbose);
/** \brief Distribute \p n items over the topology under \p root
*
* Array \p cpuset will be filled with \p n cpusets recursively distributed
* linearly over the topology under \p root, down to depth \p until (which can
* be INT_MAX to distribute down to the finest level).
*
* This is typically useful when an application wants to distribute \p n
* threads over a machine, giving each of them as much private cache as
* possible and keeping them locally in number order.
*
* The caller may typically want to also call hwloc_bitmap_singlify()
* before binding a thread so that it does not move at all.
*
* \note This function requires the \p root object to have a CPU set.
*/
static __hwloc_inline void
hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until)
{
hwloc_distrib(topology, &root, 1, set, n, until, 0);
}
/** \brief Distribute \p n items over the topology under \p roots
*
* This is the same as hwloc_distribute, but takes an array of roots instead of
* just one root.
*
* \note This function requires the \p roots objects to have a CPU set.
*/
static __hwloc_inline void
hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until)
{
hwloc_distrib(topology, roots, n_roots, set, n, until, 0);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_INLINES_H */

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

@ -0,0 +1,299 @@
/*
* Copyright © 2013-2014 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Topology differences.
*/
#ifndef HWLOC_DIFF_H
#define HWLOC_DIFF_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_diff Topology differences
*
* Applications that manipulate many similar topologies, for instance
* one for each node of a homogeneous cluster, may want to compress
* topologies to reduce the memory footprint.
*
* This file offers a way to manipulate the difference between topologies
* and export/import it to/from XML.
* Compression may therefore be achieved by storing one topology
* entirely while the others are only described by their differences
* with the former.
* The actual topology can be reconstructed when actually needed by
* applying the precomputed difference to the reference topology.
*
* This interface targets very similar nodes.
* Only very simple differences between topologies are actually
* supported, for instance a change in the memory size, the name
* of the object, or some info attribute.
* More complex differences such as adding or removing objects cannot
* be represented in the difference structures and therefore return
* errors.
*
* It means that there is no need to apply the difference when
* looking at the tree organization (how many levels, how many
* objects per level, what kind of objects, CPU and node sets, etc)
* and when binding to objects.
* However the difference must be applied when looking at object
* attributes such as the name, the memory size or info attributes.
*
* @{
*/
/** \brief Type of one object attribute difference.
*/
typedef enum hwloc_topology_diff_obj_attr_type_e {
/** \brief The object local memory is modified.
* The union is a hwloc_topology_diff_obj_attr_uint64_s
* (and the index field is ignored).
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
/** \brief The object name is modified.
* The union is a hwloc_topology_diff_obj_attr_string_s
* (and the name field is ignored).
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
/** \brief the value of an info attribute is modified.
* The union is a hwloc_topology_diff_obj_attr_string_s.
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO
} hwloc_topology_diff_obj_attr_type_t;
/** \brief One object attribute difference.
*/
union hwloc_topology_diff_obj_attr_u {
struct hwloc_topology_diff_obj_attr_generic_s {
/* each part of the union must start with these */
hwloc_topology_diff_obj_attr_type_t type;
} generic;
/** \brief Integer attribute modification with an optional index. */
struct hwloc_topology_diff_obj_attr_uint64_s {
/* used for storing integer attributes */
hwloc_topology_diff_obj_attr_type_t type;
hwloc_uint64_t index; /* not used for SIZE */
hwloc_uint64_t oldvalue;
hwloc_uint64_t newvalue;
} uint64;
/** \brief String attribute modification with an optional name */
struct hwloc_topology_diff_obj_attr_string_s {
/* used for storing name and info pairs */
hwloc_topology_diff_obj_attr_type_t type;
char *name; /* not used for NAME */
char *oldvalue;
char *newvalue;
} string;
};
/** \brief Type of one element of a difference list.
*/
typedef enum hwloc_topology_diff_type_e {
/*< \brief An object attribute was changed.
* The union is a hwloc_topology_diff_obj_attr_s.
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,
/*< \brief The difference is too complex,
* it cannot be represented. The difference below
* this object has not been checked.
* hwloc_topology_diff_build() will return 1.
*
* The union is a hwloc_topology_diff_too_complex_s.
*/
HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
} hwloc_topology_diff_type_t;
/** \brief One element of a difference list between two topologies.
*/
typedef union hwloc_topology_diff_u {
struct hwloc_topology_diff_generic_s {
/* each part of the union must start with these */
hwloc_topology_diff_type_t type;
union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */
} generic;
/* A difference in an object attribute. */
struct hwloc_topology_diff_obj_attr_s {
hwloc_topology_diff_type_t type; /* must be HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
union hwloc_topology_diff_u * next;
/* List of attribute differences for a single object */
unsigned obj_depth;
unsigned obj_index;
union hwloc_topology_diff_obj_attr_u diff;
} obj_attr;
/* A difference that is too complex. */
struct hwloc_topology_diff_too_complex_s {
hwloc_topology_diff_type_t type; /* must be HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */
union hwloc_topology_diff_u * next;
/* Where we had to stop computing the diff in the first topology */
unsigned obj_depth;
unsigned obj_index;
} too_complex;
} * hwloc_topology_diff_t;
/** \brief Compute the difference between 2 topologies.
*
* The difference is stored as a list of hwloc_topology_diff_t entries
* starting at \p diff.
* It is computed by doing a depth-first traversal of both topology trees
* simultaneously.
*
* If the difference between 2 objects is too complex to be represented
* (for instance if some objects have different types, or different numbers
* of children), a special diff entry of type HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
* is queued.
* The computation of the diff does not continue below these objects.
* So each such diff entry means that the difference between two subtrees
* could not be computed.
*
* \return 0 if the difference can be represented properly.
*
* \return 0 with \p diff pointing to NULL if there is no difference
* between the topologies.
*
* \return 1 if the difference is too complex (see above). Some entries in
* the list will be of type HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX.
*
* \return -1 on any other error.
*
* \note \p flags is currently not used. It should be 0.
*
* \note The output diff has to be freed with hwloc_topology_diff_destroy().
*
* \note The output diff can only be exported to XML or passed to
* hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type
* HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.
*
* \note The output diff may be modified by removing some entries from
* the list. The removed entries should be freed by passing them to
* to hwloc_topology_diff_destroy() (possible as another list).
*/
HWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff);
/** \brief Flags to be given to hwloc_topology_diff_apply().
*/
enum hwloc_topology_diff_apply_flags_e {
/** \brief Apply topology diff in reverse direction.
* \hideinitializer
*/
HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0)
};
/** \brief Apply a topology diff to an existing topology.
*
* \p flags is an OR'ed set of hwloc_topology_diff_apply_flags_e.
*
* The new topology is modified in place. hwloc_topology_dup()
* may be used to duplicate it before patching.
*
* If the difference cannot be applied entirely, all previous applied
* elements are unapplied before returning.
*
* \return 0 on success.
*
* \return -N if applying the difference failed while trying
* to apply the N-th part of the difference. For instance -1
* is returned if the very first difference element could not
* be applied.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags);
/** \brief Destroy a list of topology differences.
*
* \note The \p topology parameter must be a valid topology
* but it is not required that it is related to \p diff.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_t topology, hwloc_topology_diff_t diff);
/** \brief Load a list of topology differences from a XML file.
*
* If not \c NULL, \p refname will be filled with the identifier
* string of the reference topology for the difference file,
* if any was specified in the XML file.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
*
* \note The \p topology parameter must be a valid topology
* but it is not required that it is related to \p diff.
*
* \note the pointer returned in refname should later be freed
* by the caller.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(hwloc_topology_t topology, const char *xmlpath, hwloc_topology_diff_t *diff, char **refname);
/** \brief Export a list of topology differences to a XML file.
*
* If not \c NULL, \p refname defines an identifier string
* for the reference topology which was used as a base when
* computing this difference.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
* This attribute is given back when reading the diff from XML.
*
* \note The \p topology parameter must be a valid topology
* but it is not required that it is related to \p diff.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_t topology, hwloc_topology_diff_t diff, const char *refname, const char *xmlpath);
/** \brief Load a list of topology differences from a XML buffer.
*
* If not \c NULL, \p refname will be filled with the identifier
* string of the reference topology for the difference file,
* if any was specified in the XML file.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
*
* \note The \p topology parameter must be a valid topology
* but it is not required that it is related to \p diff.
*
* \note the pointer returned in refname should later be freed
* by the caller.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(hwloc_topology_t topology, const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname);
/** \brief Export a list of topology differences to a XML buffer.
*
* If not \c NULL, \p refname defines an identifier string
* for the reference topology which was used as a base when
* computing this difference.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
* This attribute is given back when reading the diff from XML.
*
* \note The XML buffer should later be freed with hwloc_free_xmlbuffer().
*
* \note The \p topology parameter must be a valid topology
* but it is not required that it is related to \p diff.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_t topology, hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_HELPER_H */

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

@ -9,9 +9,6 @@
*
* 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
@ -28,7 +25,14 @@ extern "C" {
#endif
/** \defgroup hwlocality_gl OpenGL display specific functions
/** \defgroup hwlocality_gl Interoperability with OpenGL displays
*
* This interface offers ways to retrieve topology information about
* OpenGL displays.
*
* Only the NVIDIA display locality information is currently available,
* using the NV-CONTROL X11 extension and the NVCtrl library.
*
* @{
*/

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

@ -12,8 +12,6 @@
* 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
@ -36,7 +34,13 @@ extern "C" {
#ifdef HWLOC_HAVE_CPU_SET
/** \defgroup hwlocality_glibc_sched Helpers for manipulating glibc sched affinity
/** \defgroup hwlocality_glibc_sched Interoperability with glibc sched affinity
*
* This interface offers ways to convert between hwloc cpusets and glibc cpusets
* such as those manipulated by sched_getaffinity() or pthread_attr_setaffinity_np().
*
* \note Topology \p topology must match the current machine.
*
* @{
*/

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -26,229 +26,7 @@ extern "C" {
#endif
/** \defgroup hwlocality_helper_types Object Type Helpers
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers.
*/
/** \brief Returns the depth of objects of type \p type or below
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically found
* inside \p type.
*
* If some objects of the given type exist in different levels, for instance
* L1 and L2 caches, the function returns HWLOC_TYPE_DEPTH_MULTIPLE.
*/
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
return depth;
/* find the highest existing level with type order >= */
for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
return depth+1;
/* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth. */
/* abort(); */
}
/** \brief Returns the depth of objects of type \p type or above
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically
* containing \p type.
*
* If some objects of the given type exist in different levels, for instance
* L1 and L2 caches, the function returns HWLOC_TYPE_DEPTH_MULTIPLE.
*/
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
return depth;
/* find the lowest existing level with type order <= */
for(depth = 0; ; depth++)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
return depth-1;
/* Shouldn't ever happen, as there is always a PU level with higher order and known depth. */
/* abort(); */
}
/** @} */
/** \defgroup hwlocality_helper_traversal_basic Basic Traversal Helpers
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers.
*/
/** \brief Returns the top-object of the topology-tree.
*
* Its type is typically ::HWLOC_OBJ_MACHINE but it could be different
* for complex topologies. This function replaces the old deprecated
* hwloc_get_system_obj().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology)
{
return hwloc_get_obj_by_depth (topology, 0, 0);
}
/** \brief Returns the ancestor object of \p obj at depth \p depth. */
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
{
hwloc_obj_t ancestor = obj;
if (obj->depth < depth)
return NULL;
while (ancestor && ancestor->depth > depth)
ancestor = ancestor->parent;
return ancestor;
}
/** \brief Returns the ancestor object of \p obj with type \p type. */
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
{
hwloc_obj_t ancestor = obj->parent;
while (ancestor && ancestor->type != type)
ancestor = ancestor->parent;
return ancestor;
}
/** \brief Returns the next object at depth \p depth.
*
* If \p prev is \c NULL, return the first object at depth \p depth.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
{
if (!prev)
return hwloc_get_obj_by_depth (topology, depth, 0);
if (prev->depth != depth)
return NULL;
return prev->next_cousin;
}
/** \brief Returns the next object of type \p type.
*
* If \p prev is \c NULL, return the first object at type \p type. If
* there are multiple or no depth for given type, return \c NULL and
* let the caller fallback to hwloc_get_next_obj_by_depth().
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return NULL;
return hwloc_get_next_obj_by_depth (topology, depth, prev);
}
/** \brief Returns the object of type ::HWLOC_OBJ_PU with \p os_index.
*
* \note The \p os_index field of object should most of the times only be
* used for pretty-printing purpose. Type ::HWLOC_OBJ_PU is the only case
* where \p os_index could actually be useful, when manually binding to
* processors.
* However, using CPU sets to hide this complexity should often be preferred.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
{
hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
if (obj->os_index == os_index)
return obj;
return NULL;
}
/** \brief Return the next child.
*
* If \p prev is \c NULL, return the first child.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
{
if (!prev)
return parent->first_child;
if (prev->parent != parent)
return NULL;
return prev->next_sibling;
}
/** \brief Returns the common parent object to objects lvl1 and lvl2 */
static __hwloc_inline hwloc_obj_t
hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
{
/* the loop isn't so easy since intermediate ancestors may have
* different depth, causing us to alternate between using obj1->parent
* and obj2->parent. Also, even if at some point we find ancestors of
* of the same depth, their ancestors may have different depth again.
*/
while (obj1 != obj2) {
while (obj1->depth > obj2->depth)
obj1 = obj1->parent;
while (obj2->depth > obj1->depth)
obj2 = obj2->parent;
if (obj1 != obj2 && obj1->depth == obj2->depth) {
obj1 = obj1->parent;
obj2 = obj2->parent;
}
}
return obj1;
}
/** \brief Returns true if \p obj is inside the subtree beginning with \p subtree_root.
*
* \note This function assumes that both \p obj and \p subtree_root have a \p cpuset.
*/
static __hwloc_inline int
hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
{
return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
}
/** @} */
/** \defgroup hwlocality_helper_find_inside Finding Objects Inside a CPU set
/** \defgroup hwlocality_helper_find_inside Finding Objects inside a CPU set
* @{
*/
@ -271,10 +49,11 @@ hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const
return NULL;
while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {
/* while the object intersects without being included, look at its children */
hwloc_obj_t child = NULL;
while ((child = hwloc_get_next_child(topology, obj, child)) != NULL) {
hwloc_obj_t child = obj->first_child;
while (child) {
if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))
break;
child = child->next_sibling;
}
if (!child)
/* no child intersects, return their father */
@ -462,7 +241,7 @@ hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_u
/** \defgroup hwlocality_helper_find_covering Finding a single Object covering at least CPU set
/** \defgroup hwlocality_helper_find_covering Finding Objects covering at least CPU set
* @{
*/
@ -514,15 +293,6 @@ hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t s
}
}
/** @} */
/** \defgroup hwlocality_helper_find_coverings Finding a set of similar Objects covering at least a CPU set
* @{
*/
/** \brief Iterate through same-depth objects covering at least CPU set \p set
*
* If object \p prev is \c NULL, return the first object at depth \p
@ -574,7 +344,96 @@ hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_cons
/** \defgroup hwlocality_helper_find_cache Cache-specific Finding Helpers
/** \defgroup hwlocality_helper_ancestors Looking at Ancestor and Child Objects
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
* complete topology tree, including depths, child/sibling/cousin
* relationships, and an example of an asymmetric topology where one
* socket has fewer caches than its peers.
*/
/** \brief Returns the ancestor object of \p obj at depth \p depth. */
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)
{
hwloc_obj_t ancestor = obj;
if (obj->depth < depth)
return NULL;
while (ancestor && ancestor->depth > depth)
ancestor = ancestor->parent;
return ancestor;
}
/** \brief Returns the ancestor object of \p obj with type \p type. */
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)
{
hwloc_obj_t ancestor = obj->parent;
while (ancestor && ancestor->type != type)
ancestor = ancestor->parent;
return ancestor;
}
/** \brief Returns the common parent object to objects lvl1 and lvl2 */
static __hwloc_inline hwloc_obj_t
hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)
{
/* the loop isn't so easy since intermediate ancestors may have
* different depth, causing us to alternate between using obj1->parent
* and obj2->parent. Also, even if at some point we find ancestors of
* of the same depth, their ancestors may have different depth again.
*/
while (obj1 != obj2) {
while (obj1->depth > obj2->depth)
obj1 = obj1->parent;
while (obj2->depth > obj1->depth)
obj2 = obj2->parent;
if (obj1 != obj2 && obj1->depth == obj2->depth) {
obj1 = obj1->parent;
obj2 = obj2->parent;
}
}
return obj1;
}
/** \brief Returns true if \p obj is inside the subtree beginning with ancestor object \p subtree_root.
*
* \note This function assumes that both \p obj and \p subtree_root have a \p cpuset.
*/
static __hwloc_inline int
hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)
{
return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);
}
/** \brief Return the next child.
*
* If \p prev is \c NULL, return the first child.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)
{
if (!prev)
return parent->first_child;
if (prev->parent != parent)
return NULL;
return prev->next_sibling;
}
/** @} */
/** \defgroup hwlocality_helper_find_cache Looking at Cache Objects
* @{
*/
@ -673,7 +532,7 @@ hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute
/** \defgroup hwlocality_helper_traversal Advanced Traversal Helpers
/** \defgroup hwlocality_helper_find_misc Finding objects, miscellaneous helpers
* @{
*
* Be sure to see the figure in \ref termsanddefs that shows a
@ -682,6 +541,26 @@ hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute
* socket has fewer caches than its peers.
*/
/** \brief Returns the object of type ::HWLOC_OBJ_PU with \p os_index.
*
* \note The \p os_index field of object should most of the times only be
* used for pretty-printing purpose. Type ::HWLOC_OBJ_PU is the only case
* where \p os_index could actually be useful, when manually binding to
* processors.
* However, using CPU sets to hide this complexity should often be preferred.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)
{
hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)
if (obj->os_index == os_index)
return obj;
return NULL;
}
/** \brief Do a depth-first traversal of the topology to find and sort
*
* all objects that are at the same depth than \p src.
@ -761,15 +640,27 @@ hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_
/** \defgroup hwlocality_helper_binding Binding Helpers
/** \defgroup hwlocality_helper_distribute Distributing items over a topology
* @{
*/
/** \brief Distribute \p n items over the topology under \p root
/** \brief Flags to be given to hwloc_distrib().
*/
enum hwloc_distrib_flags_e {
/** \brief Distrib in reverse order, starting from the last objects.
* \hideinitializer
*/
HWLOC_DISTRIB_FLAG_REVERSE = (1UL<<0)
};
/** \brief Distribute \p n items over the topology under \p roots
*
* Array \p cpuset will be filled with \p n cpusets recursively distributed
* linearly over the topology under \p root, down to depth \p until (which can
* be INT_MAX to distribute down to the finest level).
* Array \p set will be filled with \p n cpusets recursively distributed
* linearly over the topology under objects \p roots, down to depth \p until
* (which can be INT_MAX to distribute down to the finest level).
*
* \p n_roots is usually 1 and \p roots only contains the topology root object
* so as to distribute over the entire topology.
*
* This is typically useful when an application wants to distribute \p n
* threads over a machine, giving each of them as much private cache as
@ -778,96 +669,61 @@ hwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_
* The caller may typically want to also call hwloc_bitmap_singlify()
* before binding a thread so that it does not move at all.
*
* \note This function requires the \p root object to have a CPU set.
*/
static __hwloc_inline void
hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *root, unsigned n_roots, hwloc_cpuset_t *cpuset, unsigned n, unsigned until);
static __hwloc_inline void
hwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until)
{
unsigned i;
if (!root->arity || n == 1 || root->depth >= until) {
/* Got to the bottom, we can't split any more, put everything there. */
for (i=0; i<n; i++)
set[i] = hwloc_bitmap_dup(root->cpuset);
return;
}
hwloc_distributev(topology, root->children, root->arity, set, n, until);
}
/** \brief Distribute \p n items over the topology under \p roots
*
* This is the same as hwloc_distribute, but takes an array of roots instead of
* just one root.
* \p flags should be 0 or a OR'ed set of ::hwloc_distrib_flags_e.
*
* \note This function requires the \p roots objects to have a CPU set.
*
* \note This function replaces the now deprecated hwloc_distribute()
* and hwloc_distributev() functions.
*/
static __hwloc_inline void
hwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until)
static __hwloc_inline int
hwloc_distrib(hwloc_topology_t topology,
hwloc_obj_t *roots, unsigned n_roots,
hwloc_cpuset_t *set,
unsigned n,
unsigned until, unsigned long flags)
{
unsigned i;
unsigned tot_weight;
hwloc_cpuset_t *cpusetp = set;
if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {
errno = EINVAL;
return -1;
}
tot_weight = 0;
for (i = 0; i < n_roots; i++)
if (roots[i]->cpuset)
tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);
for (i = 0; i < n_roots && tot_weight; i++) {
/* Give to roots[i] a portion proportional to its weight */
unsigned weight = roots[i]->cpuset ? hwloc_bitmap_weight(roots[i]->cpuset) : 0;
/* Give to roots[] a portion proportional to its weight */
hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
unsigned weight = root->cpuset ? hwloc_bitmap_weight(root->cpuset) : 0;
unsigned chunk = (n * weight + tot_weight-1) / tot_weight;
hwloc_distribute(topology, roots[i], cpusetp, chunk, until);
if (!root->arity || chunk == 1 || root->depth >= until) {
/* Got to the bottom, we can't split any more, put everything there. */
unsigned j;
for (j=0; j<n; j++)
cpusetp[j] = hwloc_bitmap_dup(root->cpuset);
} else {
/* Still more to distribute, recurse into children */
hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);
}
cpusetp += chunk;
tot_weight -= weight;
n -= chunk;
}
}
/** \brief Allocate some memory on the given nodeset \p nodeset
*
* This is similar to hwloc_alloc_membind except that it is allowed to change
* the current memory binding policy, thus providing more binding support, at
* the expense of changing the current state.
*/
static __hwloc_inline void *
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
if (p)
return p;
hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
p = hwloc_alloc(topology, len);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */
memset(p, 0, len);
return p;
}
/** \brief Allocate some memory on the memory nodes near given cpuset \p cpuset
*
* This is similar to hwloc_alloc_membind_policy_nodeset, but for a given cpuset.
*/
static __hwloc_inline void *
hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
if (p)
return p;
hwloc_set_membind(topology, set, policy, flags);
p = hwloc_alloc(topology, len);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */
memset(p, 0, len);
return p;
return 0;
}
/** @} */
/** \defgroup hwlocality_helper_cpuset Cpuset Helpers
/** \defgroup hwlocality_helper_topology_sets CPU and node sets of entire topologies
* @{
*/
/** \brief Get complete CPU set
@ -877,7 +733,7 @@ hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cp
* returned.
*
* \note The returned cpuset is not newly allocated and should thus not be
* changed or freed; hwloc_cpuset_dup must be used to obtain a local copy.
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -895,7 +751,7 @@ hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
* systems, NULL is returned.
*
* \note The returned cpuset is not newly allocated and should thus not be
* changed or freed; hwloc_cpuset_dup must be used to obtain a local copy.
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -912,7 +768,7 @@ hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
* returned.
*
* \note The returned cpuset is not newly allocated and should thus not be
* changed or freed; hwloc_cpuset_dup must be used to obtain a local copy.
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -929,7 +785,7 @@ hwloc_topology_get_online_cpuset(hwloc_topology_t topology)
* returned.
*
* \note The returned cpuset is not newly allocated and should thus not be
* changed or freed, hwloc_cpuset_dup must be used to obtain a local copy.
* changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -939,13 +795,6 @@ hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
return hwloc_get_root_obj(topology)->allowed_cpuset;
}
/** @} */
/** \defgroup hwlocality_helper_nodeset Nodeset Helpers
* @{
*/
/** \brief Get complete node set
*
* \return the complete node set of memory of the system. If the
@ -953,7 +802,7 @@ hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
* returned.
*
* \note The returned nodeset is not newly allocated and should thus not be
* changed or freed; hwloc_nodeset_dup must be used to obtain a local copy.
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_nodeset_t
hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -971,7 +820,7 @@ hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
* systems, NULL is returned.
*
* \note The returned nodeset is not newly allocated and should thus not be
* changed or freed; hwloc_nodeset_dup must be used to obtain a local copy.
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_nodeset_t
hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -988,7 +837,7 @@ hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
* returned.
*
* \note The returned nodeset is not newly allocated and should thus not be
* changed or freed, hwloc_nodeset_dup must be used to obtain a local copy.
* changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy.
*/
static __hwloc_inline hwloc_const_nodeset_t
hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
@ -1002,7 +851,7 @@ hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
/** \defgroup hwlocality_helper_nodeset_convert Conversion between cpuset and nodeset
/** \defgroup hwlocality_helper_nodeset_convert Converting between CPU sets and node sets
*
* There are two semantics for converting cpusets to nodesets depending on how
* non-NUMA machines are handled.
@ -1127,7 +976,7 @@ hwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t
/** \defgroup hwlocality_distances Distances
/** \defgroup hwlocality_distances Manipulating Distances
* @{
*/
@ -1266,7 +1115,7 @@ hwloc_get_latency(hwloc_topology_t topology,
/** \defgroup hwlocality_advanced_io Advanced I/O object traversal helpers
/** \defgroup hwlocality_advanced_io Finding I/O objects
* @{
*/

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

@ -0,0 +1,154 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/**
* This file contains the inline code of functions declared in hwloc.h
*/
#ifndef HWLOC_INLINES_H
#define HWLOC_INLINES_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#include <stdlib.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
return depth;
/* find the highest existing level with type order >= */
for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
return depth+1;
/* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth. */
/* abort(); */
}
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
return depth;
/* find the lowest existing level with type order <= */
for(depth = 0; ; depth++)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
return depth-1;
/* Shouldn't ever happen, as there is always a PU level with higher order and known depth. */
/* abort(); */
}
static __hwloc_inline int
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return -1; /* FIXME: agregate nbobjs from different levels? */
return hwloc_get_nbobjs_by_depth(topology, depth);
}
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return NULL;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return NULL;
return hwloc_get_obj_by_depth(topology, depth, idx);
}
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)
{
if (!prev)
return hwloc_get_obj_by_depth (topology, depth, 0);
if (prev->depth != depth)
return NULL;
return prev->next_cousin;
}
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return NULL;
return hwloc_get_next_obj_by_depth (topology, depth, prev);
}
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology)
{
return hwloc_get_obj_by_depth (topology, 0, 0);
}
static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
{
unsigned i;
for(i=0; i<obj->infos_count; i++)
if (!strcmp(obj->infos[i].name, name))
return obj->infos[i].value;
return NULL;
}
static __hwloc_inline void *
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);
if (p)
return p;
hwloc_set_membind_nodeset(topology, nodeset, policy, flags);
p = hwloc_alloc(topology, len);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */
memset(p, 0, len);
return p;
}
static __hwloc_inline void *
hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
if (p)
return p;
hwloc_set_membind(topology, set, policy, flags);
p = hwloc_alloc(topology, len);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */
memset(p, 0, len);
return p;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_INLINES_H */

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

@ -31,7 +31,11 @@ extern "C" {
#endif
/** \defgroup hwlocality_intel_mic Intel Xeon Phi (MIC) Specific Functions
/** \defgroup hwlocality_intel_mic Interoperability with Intel Xeon Phi (MIC)
*
* This interface offers ways to retrieve topology information about
* Intel Xeon Phi (MIC) devices.
*
* @{
*/

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 inria. All rights reserved.
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux 1
* See COPYING in top-level directory.
*/
@ -10,18 +10,7 @@
*
* 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
@ -35,7 +24,22 @@ extern "C" {
#endif
/** \defgroup hwlocality_linux_libnuma_ulongs Helpers for manipulating Linux libnuma unsigned long masks
/** \defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks
*
* This interface helps converting between Linux libnuma unsigned long masks
* and hwloc cpusets and nodesets.
*
* It 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.
*
* @{
*/
@ -198,7 +202,22 @@ hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset
/** \defgroup hwlocality_linux_libnuma_bitmask Helpers for manipulating Linux libnuma bitmask
/** \defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask
*
* This interface helps converting between Linux libnuma bitmasks
* and hwloc cpusets and nodesets.
*
* It 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.
*
* @{
*/

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2010 inria. All rights reserved.
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux 1
* See COPYING in top-level directory.
*/
@ -24,9 +24,9 @@ extern "C" {
#endif
/** \defgroup hwlocality_linux Linux-only helpers
/** \defgroup hwlocality_linux Linux-specific helpers
*
* This includes helpers for manipulating linux kernel cpumap files, and hwloc
* This includes helpers for manipulating Linux kernel cpumap files, and hwloc
* equivalents of the Linux sched_setaffinity and sched_getaffinity system calls.
*
* @{
@ -43,6 +43,9 @@ HWLOC_DECLSPEC int hwloc_linux_parse_cpumap_file(FILE *file, hwloc_cpuset_t set)
*
* The behavior is exactly the same as the Linux sched_setaffinity system call,
* but uses a hwloc cpuset.
*
* \note This is equivalent to calling hwloc_set_proc_cpubind() with
* HWLOC_CPUBIND_THREAD as flags.
*/
HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_const_cpuset_t set);
@ -50,9 +53,19 @@ HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t
*
* The behavior is exactly the same as the Linux sched_getaffinity system call,
* but uses a hwloc cpuset.
*
* \note This is equivalent to calling hwloc_get_proc_cpubind() with
* HWLOC_CPUBIND_THREAD as flags.
*/
HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_cpuset_t set);
/** \brief Get the last physical CPU where thread \p tid ran.
*
* \note This is equivalent to calling hwloc_get_proc_last_cpu_location() with
* HWLOC_CPUBIND_THREAD as flags.
*/
HWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topology, pid_t tid, hwloc_bitmap_t set);
/** @} */

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

@ -26,7 +26,11 @@ extern "C" {
#endif
/** \defgroup hwlocality_myriexpress Myrinet Express-Specific Functions
/** \defgroup hwlocality_myriexpress Interoperability with Myrinet Express
*
* This interface offers ways to retrieve topology information about
* Myrinet Express hardware.
*
* @{
*/

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

@ -28,7 +28,11 @@ extern "C" {
#endif
/** \defgroup hwlocality_nvml NVIDIA Management Library Specific Functions
/** \defgroup hwlocality_nvml Interoperability with the NVIDIA Management Library
*
* This interface offers ways to retrieve topology information about
* devices managed by the NVIDIA Management Library (NVML).
*
* @{
*/

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

@ -9,9 +9,6 @@
*
* 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
@ -35,7 +32,14 @@ extern "C" {
#endif
/** \defgroup hwlocality_opencl OpenCL Specific Functions
/** \defgroup hwlocality_opencl Interoperability with OpenCL
*
* This interface offers ways to retrieve topology information about
* OpenCL devices.
*
* Only the AMD OpenCL interface currently offers useful locality information
* about its devices.
*
* @{
*/

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

@ -33,7 +33,11 @@ extern "C" {
#endif
/** \defgroup hwlocality_openfabrics OpenFabrics-Specific Functions
/** \defgroup hwlocality_openfabrics Interoperability with OpenFabrics
*
* This interface offers ways to retrieve topology information about
* OpenFabrics devices.
*
* @{
*/

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

@ -1,5 +1,5 @@
/*
* Copyright © 2013 Inria. All rights reserved.
* Copyright © 2013-2014 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@ -13,11 +13,14 @@
struct hwloc_backend;
#include <hwloc.h>
#ifdef HWLOC_INSIDE_PLUGIN
/* needed for hwloc_plugin_check_namespace() */
#include <ltdl.h>
#endif
/** \defgroup hwlocality_disc_components Discovery components
/** \defgroup hwlocality_disc_components Components and Plugins: Discovery components
* @{
*/
@ -34,7 +37,7 @@ typedef enum hwloc_disc_component_type_e {
* \hideinitializer */
HWLOC_DISC_COMPONENT_TYPE_GLOBAL = (1<<1),
/** \brief PCI, etc.
/** \brief OpenCL, Cuda, etc.
* \hideinitializer */
HWLOC_DISC_COMPONENT_TYPE_MISC = (1<<2)
} hwloc_disc_component_type_t;
@ -94,7 +97,7 @@ struct hwloc_disc_component {
/** \defgroup hwlocality_disc_backends Discovery backends
/** \defgroup hwlocality_disc_backends Components and Plugins: Discovery backends
* @{
*/
@ -191,7 +194,7 @@ HWLOC_DECLSPEC int hwloc_backends_notify_new_object(struct hwloc_backend *caller
/** \defgroup hwlocality_generic_components Generic components
/** \defgroup hwlocality_generic_components Components and Plugins: Generic components
* @{
*/
@ -228,7 +231,7 @@ struct hwloc_component {
/** \defgroup hwlocality_components_core_funcs Core functions to be used by components
/** \defgroup hwlocality_components_core_funcs Components and Plugins: Core functions to be used by components
* @{
*/
@ -294,6 +297,95 @@ hwloc_alloc_setup_object(hwloc_obj_type_t type, signed os_index)
return obj;
}
/** \brief Setup object cpusets/nodesets by OR'ing its children.
*
* Used when adding an object late in the topology, after propagating sets up and down.
* The caller should use this after inserting by cpuset (which means the cpusets is already OK).
* Typical case: PCI backend adding a hostbridge parent.
*/
HWLOC_DECLSPEC int hwloc_fill_object_sets(hwloc_obj_t obj);
/** \brief Make sure that plugins can lookup core symbols.
*
* This is a sanity check to avoid lazy-lookup failures when libhwloc
* is loaded within a plugin, and later tries to load its own plugins.
* This may fail (and abort the program) if libhwloc symbols are in a
* private namespace.
*
* Plugins should call this function as an early sanity check to avoid
* later crashes if lazy symbol resolution is used by the upper layer that
* loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
*
* \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
* building the caller as a plugin.
*/
static __hwloc_inline int
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
{
#ifdef HWLOC_INSIDE_PLUGIN
lt_dlhandle handle;
void *sym;
handle = lt_dlopen(NULL);
if (!handle)
/* cannot check, assume things will work */
return 0;
sym = lt_dlsym(handle, symbol);
lt_dlclose(handle);
if (!sym) {
static int verboseenv_checked = 0;
static int verboseenv_value = 0;
if (!verboseenv_checked) {
char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
verboseenv_value = atoi(verboseenv);
verboseenv_checked = 1;
}
if (verboseenv_value)
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
pluginname, symbol);
return -1;
}
#endif /* HWLOC_INSIDE_PLUGIN */
return 0;
}
/** @} */
/** \defgroup hwlocality_components_pci_funcs Components and Plugins: PCI functions to be used by components
* @{
*/
/** \brief Insert a list of PCI devices and bridges in the backend topology.
*
* Insert a list of objects (either PCI device or bridges) starting at first_obj
* (linked by next_sibling in the topology, and ending with NULL).
* Objects are placed under the right bridges, and the remaining upstream bridges
* are then inserted in the topology by calling the get_obj_cpuset() callback to
* find their locality.
*/
HWLOC_DECLSPEC int hwloc_insert_pci_device_list(struct hwloc_backend *backend, struct hwloc_obj *first_obj);
/** \brief Return the offset of the given capability in the PCI config space buffer
*
* This function requires a 256-bytes config space. Unknown/unavailable bytes should be set to 0xff.
*/
HWLOC_DECLSPEC unsigned hwloc_pci_find_cap(const unsigned char *config, unsigned cap);
/** \brief Fill linkspeed by reading the PCI config space where PCI_CAP_ID_EXP is at position offset.
*
* Needs 20 bytes of EXP capability block starting at offset in the config space
* for registers up to link status.
*/
HWLOC_DECLSPEC int hwloc_pci_find_linkspeed(const unsigned char *config, unsigned offset, float *linkspeed);
/** \brief Modify the PCI device object into a bridge and fill its attribute if a bridge is found in the PCI config space.
*
* This function requires 64 bytes of common configuration header at the beginning of config.
*/
HWLOC_DECLSPEC int hwloc_pci_prepare_bridge(hwloc_obj_t obj, const unsigned char *config);
/** @} */

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2010-2013 Inria. All rights reserved.
* Copyright © 2010-2014 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@ -153,6 +153,7 @@ extern "C" {
#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_dup HWLOC_NAME(topology_dup)
#define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth)
#define hwloc_get_type_depth HWLOC_NAME(get_type_depth)
@ -175,10 +176,9 @@ extern "C" {
#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_sscanf HWLOC_NAME(obj_type_sscanf)
#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)
@ -302,7 +302,6 @@ extern "C" {
#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)
@ -330,8 +329,9 @@ extern "C" {
#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_distrib_flags_e HWLOC_NAME(distrib_flags_e)
#define HWLOC_DISTRIB_FLAG_REVERSE HWLOC_NAME_CAPS(DISTRIB_FLAG_REVERSE)
#define hwloc_distrib HWLOC_NAME(distrib)
#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)
@ -350,6 +350,36 @@ extern "C" {
#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)
/* diff.h */
#define hwloc_topology_diff_obj_attr_type_e HWLOC_NAME(topology_diff_obj_attr_type_e)
#define hwloc_topology_diff_obj_attr_type_t HWLOC_NAME(topology_diff_obj_attr_type_t)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_SIZE)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_NAME)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_INFO)
#define hwloc_topology_diff_obj_attr_u HWLOC_NAME(topology_diff_obj_attr_u)
#define hwloc_topology_diff_obj_attr_generic_s HWLOC_NAME(topology_diff_obj_attr_generic_s)
#define hwloc_topology_diff_obj_attr_uint64_s HWLOC_NAME(topology_diff_obj_attr_uint64_s)
#define hwloc_topology_diff_obj_attr_string_s HWLOC_NAME(topology_diff_obj_attr_string_s)
#define hwloc_topology_diff_type_e HWLOC_NAME(topology_diff_type_e)
#define hwloc_topology_diff_type_t HWLOC_NAME(topology_diff_type_t)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR)
#define HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX HWLOC_NAME_CAPS(TOPOLOGY_DIFF_TOO_COMPLEX)
#define hwloc_topology_diff_u HWLOC_NAME(topology_diff_u)
#define hwloc_topology_diff_t HWLOC_NAME(topology_diff_t)
#define hwloc_topology_diff_generic_s HWLOC_NAME(topology_diff_generic_s)
#define hwloc_topology_diff_obj_attr_s HWLOC_NAME(topology_diff_obj_attr_s)
#define hwloc_topology_diff_too_complex_s HWLOC_NAME(topology_diff_too_complex_s)
#define hwloc_topology_diff_build HWLOC_NAME(topology_diff_build)
#define hwloc_topology_diff_apply_flags_e HWLOC_NAME(topology_diff_apply_flags_e)
#define HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_APPLY_REVERSE)
#define hwloc_topology_diff_apply HWLOC_NAME(topology_diff_apply)
#define hwloc_topology_diff_destroy HWLOC_NAME(topology_diff_destroy)
#define hwloc_topology_diff_load_xml HWLOC_NAME(topology_diff_load_xml)
#define hwloc_topology_diff_export_xml HWLOC_NAME(topology_diff_export_xml)
#define hwloc_topology_diff_load_xmlbuffer HWLOC_NAME(topology_diff_load_xmlbuffer)
#define hwloc_topology_diff_export_xmlbuffer HWLOC_NAME(topology_diff_export_xmlbuffer)
/* glibc-sched.h */
#define hwloc_cpuset_to_glibc_sched_affinity HWLOC_NAME(cpuset_to_glibc_sched_affinity)
@ -371,6 +401,7 @@ extern "C" {
#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)
#define hwloc_linux_get_tid_last_cpu_location HWLOC_NAME(linux_get_tid_last_cpu_location)
/* openfabrics-verbs.h */
@ -445,6 +476,8 @@ extern "C" {
#define hwloc_component_type_t HWLOC_NAME(component_type_t)
#define hwloc_component HWLOC_NAME(component)
#define hwloc_plugin_check_namespace HWLOC_NAME(plugin_check_namespace)
#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)
@ -452,6 +485,19 @@ extern "C" {
#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)
#define hwloc_fill_object_sets HWLOC_NAME(fill_object_sets)
#define hwloc_insert_pci_device_list HWLOC_NAME(insert_pci_device_list)
#define hwloc_pci_find_cap HWLOC_NAME(pci_find_cap)
#define hwloc_pci_find_linkspeed HWLOC_NAME(pci_find_linkspeed)
#define hwloc_pci_prepare_bridge HWLOC_NAME(pci_prepare_bridge)
/* hwloc/deprecated.h */
#define hwloc_obj_type_of_string HWLOC_NAME(obj_type_of_string )
#define hwloc_obj_snprintf HWLOC_NAME(obj_snprintf)
#define hwloc_distributev HWLOC_NAME(distributev)
#define hwloc_distribute HWLOC_NAME(distribute)
/* private/debug.h */
@ -461,16 +507,19 @@ extern "C" {
#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_ffsl_manual HWLOC_NAME(ffsl_manual)
#define hwloc_ffs32 HWLOC_NAME(ffs32)
/* FIXME: hwloc_flsl may be a macro, but it may not be defined yet */
#define hwloc_ffsl_from_ffs32 HWLOC_NAME(ffsl_from_ffs32)
#define hwloc_flsl_manual HWLOC_NAME(flsl_manual)
#define hwloc_fls32 HWLOC_NAME(fls32)
#define hwloc_flsl_from_fls32 HWLOC_NAME(flsl_from_fls32)
#define hwloc_weight_long HWLOC_NAME(weight_long)
#define hwloc_strncasecmp HWLOC_NAME(strncasecmp)
/* private/cpuid.h */
/* private/cpuid-x86.h */
#define hwloc_have_cpuid HWLOC_NAME(have_cpuid)
#define hwloc_cpuid HWLOC_NAME(cpuid)
#define hwloc_have_x86_cpuid HWLOC_NAME(have_x86_cpuid)
#define hwloc_x86_cpuid HWLOC_NAME(x86_cpuid)
/* private/xml.h */
@ -478,10 +527,12 @@ extern "C" {
#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_import_diff HWLOC_NAME(_xml_import_diff)
#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_export_diff HWLOC_NAME(_xml_export_diff)
#define hwloc_xml_callbacks HWLOC_NAME(xml_callbacks)
#define hwloc_xml_component HWLOC_NAME(xml_component)
@ -493,7 +544,6 @@ extern "C" {
#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)
@ -523,6 +573,11 @@ extern "C" {
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
#define hwloc_topology_clear HWLOC_NAME(topology_clear)
#define hwloc__add_info HWLOC_NAME(_add_info)
#define hwloc__find_info_slot HWLOC_NAME(_find_info_slot)
#define hwloc__move_infos HWLOC_NAME(_move_infos)
#define hwloc__free_infos HWLOC_NAME(_free_infos)
#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)
@ -549,7 +604,6 @@ extern "C" {
#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)
@ -564,6 +618,8 @@ extern "C" {
#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64)
#define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64)
#define hwloc_obj_add_info_nodup HWLOC_NAME(obj_add_info_nodup)
/* private/solaris-chiptype.h */
#define hwloc_solaris_get_chip_type HWLOC_NAME(solaris_get_chip_type)

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

@ -275,10 +275,10 @@
/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `sysctl' function. */
/* Define to '1' if sysctl is present and usable */
#undef HAVE_SYSCTL
/* Define to 1 if you have the `sysctlbyname' function. */
/* Define to '1' if sysctlbyname is present and usable */
#undef HAVE_SYSCTLBYNAME
/* Define to 1 if the system has the type
@ -424,9 +424,6 @@
/* 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
@ -454,6 +451,9 @@
/* Define to 1 if function `flsl' is declared by system headers */
#undef HWLOC_HAVE_DECL_FLSL
/* Define to 1 if function `strncasecmp' is declared by system headers */
#undef HWLOC_HAVE_DECL_STRNCASECMP
/* Define to 1 if you have the `ffs' function. */
#undef HWLOC_HAVE_FFS
@ -478,6 +478,9 @@
/* Define to 1 if you have the `libxml2' library. */
#undef HWLOC_HAVE_LIBXML2
/* Define to 1 if building the Linux PCI component */
#undef HWLOC_HAVE_LINUXPCI
/* Define to 1 if mbind is available. */
#undef HWLOC_HAVE_MBIND
@ -528,8 +531,11 @@
/* 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 X11 headers including Xutil.h and keysym.h are available. */
#undef HWLOC_HAVE_X11_KEYSYM
/* Define to 1 if you have x86 cpuid */
#undef HWLOC_HAVE_X86_CPUID
/* Define to 1 if the _syscall3 macro works */
#undef HWLOC_HAVE__SYSCALL3
@ -543,21 +549,12 @@
/* 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
@ -595,9 +592,6 @@
*/
#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
@ -681,9 +675,6 @@
/* 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

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

@ -29,8 +29,6 @@ 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);

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

@ -1,17 +1,18 @@
/*
* Copyright © 2010-2012 Université Bordeaux 1
* Copyright © 2010 Cisco Systems, Inc. All rights reserved.
* Copyright © 2014 Inria. All rights reserved.
*
* See COPYING in top-level directory.
*/
/* Internals for x86's cpuid. */
#ifndef HWLOC_PRIVATE_CPUID_H
#define HWLOC_PRIVATE_CPUID_H
#ifndef HWLOC_PRIVATE_CPUID_X86_H
#define HWLOC_PRIVATE_CPUID_X86_H
#ifdef HWLOC_X86_32_ARCH
static __hwloc_inline int hwloc_have_cpuid(void)
#if (defined HWLOC_X86_32_ARCH) && (!defined HWLOC_HAVE_MSVC_CPUIDEX)
static __hwloc_inline int hwloc_have_x86_cpuid(void)
{
int ret;
unsigned tmp, tmp2;
@ -44,17 +45,25 @@ static __hwloc_inline int hwloc_have_cpuid(void)
: "=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 /* !defined HWLOC_X86_32_ARCH && !defined HWLOC_HAVE_MSVC_CPUIDEX*/
#if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_HAVE_MSVC_CPUIDEX)
static __hwloc_inline int hwloc_have_x86_cpuid(void) { return 1; }
#endif /* HWLOC_X86_64_ARCH */
static __hwloc_inline void hwloc_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
static __hwloc_inline void hwloc_x86_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
{
#ifdef HWLOC_HAVE_MSVC_CPUIDEX
int regs[4];
__cpuidex(regs, *eax, *ecx);
*eax = regs[0];
*ebx = regs[1];
*ecx = regs[2];
*edx = regs[3];
#else /* HWLOC_HAVE_MSVC_CPUIDEX */
/* 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;
hwloc_uint64_t sav_rbx;
asm(
"mov %%rbx,%2\n\t"
"cpuid\n\t"
@ -74,6 +83,7 @@ static __hwloc_inline void hwloc_cpuid(unsigned *eax, unsigned *ebx, unsigned *e
#else
#error unknown architecture
#endif
#endif /* HWLOC_HAVE_MSVC_CPUIDEX */
}
#endif /* HWLOC_PRIVATE_CPUID_H */
#endif /* HWLOC_PRIVATE_X86_CPUID_H */

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2010 inria. All rights reserved.
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -77,9 +77,9 @@ extern int ffs(int) __hwloc_attribute_const;
/* no ffs or it is known to be broken */
static __hwloc_inline int
hwloc_ffsl(unsigned long x) __hwloc_attribute_const;
hwloc_ffsl_manual(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffsl(unsigned long x)
hwloc_ffsl_manual(unsigned long x)
{
int i;
@ -116,6 +116,8 @@ hwloc_ffsl(unsigned long x)
return i;
}
/* always define hwloc_ffsl as a macro, to avoid renaming breakage */
#define hwloc_ffsl hwloc_ffsl_manual
#elif defined(HWLOC_NEED_FFSL)
@ -146,9 +148,9 @@ hwloc_ffs32(unsigned long x)
/* Then make it 64 bit if longs are. */
static __hwloc_inline int
hwloc_ffsl(unsigned long x) __hwloc_attribute_const;
hwloc_ffsl_from_ffs32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffsl(unsigned long x)
hwloc_ffsl_from_ffs32(unsigned long x)
{
#if HWLOC_BITS_PER_LONG == 64
int low_ffs, hi_ffs;
@ -166,6 +168,9 @@ hwloc_ffsl(unsigned long x)
return hwloc_ffs32(x);
#endif
}
/* always define hwloc_ffsl as a macro, to avoid renaming breakage */
#define hwloc_ffsl hwloc_ffsl_from_ffs32
#endif
/**
@ -217,9 +222,9 @@ extern int clz(int) __hwloc_attribute_const;
#else /* no fls implementation */
static __hwloc_inline int
hwloc_flsl(unsigned long x) __hwloc_attribute_const;
hwloc_flsl_manual(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_flsl(unsigned long x)
hwloc_flsl_manual(unsigned long x)
{
int i = 0;
@ -256,6 +261,8 @@ hwloc_flsl(unsigned long x)
return i;
}
/* always define hwloc_flsl as a macro, to avoid renaming breakage */
#define hwloc_flsl hwloc_flsl_manual
#endif
@ -288,9 +295,9 @@ hwloc_fls32(unsigned long x)
/* Then make it 64 bit if longs are. */
static __hwloc_inline int
hwloc_flsl(unsigned long x) __hwloc_attribute_const;
hwloc_flsl_from_fls32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_flsl(unsigned long x)
hwloc_flsl_from_fls32(unsigned long x)
{
#if HWLOC_BITS_PER_LONG == 64
int low_fls, hi_fls;
@ -308,6 +315,9 @@ hwloc_flsl(unsigned long x)
return hwloc_fls32(x);
#endif
}
/* always define hwloc_flsl as a macro, to avoid renaming breakage */
#define hwloc_flsl hwloc_flsl_from_fls32
#endif
static __hwloc_inline int
@ -344,4 +354,19 @@ hwloc_weight_long(unsigned long w)
unsigned long long int strtoull(const char *nptr, char **endptr, int base);
#endif
static __hwloc_inline int hwloc_strncasecmp(const char *s1, const char *s2, size_t n)
{
#ifdef HWLOC_HAVE_DECL_STRNCASECMP
return strncasecmp(s1, s2, n);
#else
while (n) {
char c1 = tolower(*s1), c2 = tolower(*s2);
if (!c1 || !c2 || c1 != c2)
return c1-c2;
n--; s1++; s2++;
}
return 0;
#endif
}
#endif /* HWLOC_PRIVATE_MISC_H */

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux 1
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
*
@ -139,6 +139,11 @@ 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);
extern void hwloc__add_info(struct hwloc_obj_info_s **infosp, unsigned *countp, const char *name, const char *value);
extern char ** hwloc__find_info_slot(struct hwloc_obj_info_s **infosp, unsigned *countp, const char *name);
extern void hwloc__move_infos(struct hwloc_obj_info_s **dst_infosp, unsigned *dst_countp, struct hwloc_obj_info_s **src_infosp, unsigned *src_countp);
extern void hwloc__free_infos(struct hwloc_obj_info_s *infos, unsigned count);
/* 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 */
@ -184,8 +189,11 @@ extern void hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *binding_hooks, st
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);
/* Insert uname-specific names/values in the object infos array.
* If cached_uname isn't NULL, it is used as a struct utsname instead of recalling uname.
* Any field that starts with \0 is ignored.
*/
extern void hwloc_add_uname_info(struct hwloc_topology *topology, void *cached_uname);
/* Free obj and its attributes assuming it doesn't have any children/parent anymore */
extern void hwloc_free_unlinked_object(hwloc_obj_t obj);
@ -216,7 +224,6 @@ hwloc_alloc_or_fail(hwloc_topology_t topology, size_t len, int flags)
}
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);
@ -296,4 +303,6 @@ extern int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n
* required size. hwloc_snprintf always report the actually required size. */
extern int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4);
extern void hwloc_obj_add_info_nodup(hwloc_obj_t obj, const char *name, const char *value, int nodup);
#endif /* HWLOC_PRIVATE_H */

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

@ -1,5 +1,5 @@
/*
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@ -28,6 +28,8 @@ typedef struct hwloc__xml_import_state_s {
char data[32];
} * hwloc__xml_import_state_t;
HWLOC_DECLSPEC int hwloc__xml_import_diff(hwloc__xml_import_state_t state, hwloc_topology_diff_t *firstdiffp);
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);
@ -57,6 +59,8 @@ typedef struct hwloc__xml_export_state_s {
HWLOC_DECLSPEC void hwloc__xml_export_object (hwloc__xml_export_state_t state, struct hwloc_topology *topology, struct hwloc_obj *obj);
HWLOC_DECLSPEC void hwloc__xml_export_diff(hwloc__xml_export_state_t parentstate, hwloc_topology_diff_t diff);
/******************
* XML components *
******************/
@ -66,6 +70,9 @@ struct hwloc_xml_callbacks {
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);
int (*import_diff)(const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *diff, char **refnamep);
int (*export_diff_file)(union hwloc_topology_diff_u *diff, const char *refname, const char *filename);
int (*export_diff_buffer)(union hwloc_topology_diff_u *diff, const char *refname, char **xmlbuffer, int *buflen);
};
struct hwloc_xml_component {

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

@ -1,4 +1,4 @@
# Copyright © 2009-2013 Inria. All rights reserved.
# Copyright © 2009-2014 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.
@ -19,10 +19,10 @@ else
noinst_LTLIBRARIES = libhwloc_embedded.la
endif
pluginsdir = $(libdir)/hwloc
pluginsdir = @HWLOC_PLUGINS_DIR@
plugins_LTLIBRARIES =
plugins_ldflags = -module -avoid-version
AM_CPPFLAGS += -DHWLOC_PLUGINS_DIR=\"$(pluginsdir)\"
plugins_ldflags = -module -avoid-version -lltdl
AM_CPPFLAGS += -DHWLOC_PLUGINS_PATH=\"$(HWLOC_PLUGINS_PATH)\"
# Sources and ldflags
@ -33,6 +33,8 @@ sources = \
components.c \
bind.c \
bitmap.c \
pci-common.c \
diff.c \
misc.c \
base64.c \
topology-noos.c \
@ -155,9 +157,9 @@ sources += topology-netbsd.c
ldflags += -lpthread
endif HWLOC_HAVE_NETBSD
if HWLOC_HAVE_CPUID
if HWLOC_HAVE_X86_CPUID
sources += topology-x86.c
endif HWLOC_HAVE_CPUID
endif HWLOC_HAVE_X86_CPUID
if HWLOC_HAVE_GCC
ldflags += -no-undefined

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

@ -1,5 +1,5 @@
/*
* Copyright © 2009-2013 Inria. All rights reserved.
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2012 Université Bordeau 1
* See COPYING in top-level directory.
*/
@ -90,7 +90,7 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror());
goto out;
}
componentsymbolname = malloc(6+strlen(basename)+10+1);
componentsymbolname = malloc(strlen(basename)+10+1);
sprintf(componentsymbolname, "%s_component", basename);
component = lt_dlsym(handle, componentsymbolname);
if (!component) {
@ -184,7 +184,7 @@ static int
hwloc_plugins_init(void)
{
char *verboseenv;
char *path = HWLOC_PLUGINS_DIR;
char *path = HWLOC_PLUGINS_PATH;
char *env;
int err;
@ -382,6 +382,11 @@ hwloc_disc_component_force_enable(struct hwloc_topology *topology,
struct hwloc_disc_component *comp;
struct hwloc_backend *backend;
if (topology->is_loaded) {
errno = EBUSY;
return -1;
}
comp = hwloc_disc_component_find(type, name);
if (!comp) {
errno = ENOSYS;
@ -392,7 +397,7 @@ hwloc_disc_component_force_enable(struct hwloc_topology *topology,
if (backend) {
backend->envvar_forced = envvar_forced;
if (topology->backends)
hwloc_backends_reset(topology);
hwloc_backends_disable_all(topology);
return hwloc_backend_enable(topology, backend);
} else
return -1;
@ -418,7 +423,7 @@ hwloc_disc_component_try_enable(struct hwloc_topology *topology,
backend = comp->instantiate(comp, comparg, NULL, NULL);
if (!backend) {
if (verbose_errors)
if (hwloc_components_verbose || verbose_errors)
fprintf(stderr, "Failed to instantiate discovery component `%s'\n", comp->name);
return -1;
}
@ -739,24 +744,3 @@ hwloc_backends_disable_all(struct hwloc_topology *topology)
}
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;
}
}

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

@ -0,0 +1,405 @@
/*
* Copyright © 2013 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <private/private.h>
#include <private/misc.h>
int hwloc_topology_diff_destroy(hwloc_topology_t topology __hwloc_attribute_unused,
hwloc_topology_diff_t diff)
{
hwloc_topology_diff_t next;
while (diff) {
next = diff->generic.next;
switch (diff->generic.type) {
default:
break;
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR:
switch (diff->obj_attr.diff.generic.type) {
default:
break;
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME:
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO:
free(diff->obj_attr.diff.string.name);
free(diff->obj_attr.diff.string.oldvalue);
free(diff->obj_attr.diff.string.newvalue);
break;
}
break;
}
free(diff);
diff = next;
}
return 0;
}
/************************
* Computing diffs
*/
static void hwloc_append_diff(hwloc_topology_diff_t newdiff,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
if (*firstdiffp)
(*lastdiffp)->generic.next = newdiff;
else
*firstdiffp = newdiff;
*lastdiffp = newdiff;
newdiff->generic.next = NULL;
}
static int hwloc_append_diff_too_complex(hwloc_obj_t obj1,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->too_complex.type = HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX;
newdiff->too_complex.obj_depth = obj1->depth;
newdiff->too_complex.obj_index = obj1->logical_index;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int hwloc_append_diff_obj_attr_string(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type,
const char *name,
const char *oldvalue,
const char *newvalue,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
if (obj->type == HWLOC_OBJ_MISC)
/* TODO: add a custom level/depth for Misc */
return hwloc_append_diff_too_complex(obj, firstdiffp, lastdiffp);
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.string.type = type;
newdiff->obj_attr.diff.string.name = name ? strdup(name) : NULL;
newdiff->obj_attr.diff.string.oldvalue = oldvalue ? strdup(oldvalue) : NULL;
newdiff->obj_attr.diff.string.newvalue = newvalue ? strdup(newvalue) : NULL;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type,
hwloc_uint64_t index,
hwloc_uint64_t oldvalue,
hwloc_uint64_t newvalue,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
if (obj->type == HWLOC_OBJ_MISC)
/* TODO: add a custom level/depth for Misc */
return hwloc_append_diff_too_complex(obj, firstdiffp, lastdiffp);
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.uint64.type = type;
newdiff->obj_attr.diff.uint64.index = index;
newdiff->obj_attr.diff.uint64.oldvalue = oldvalue;
newdiff->obj_attr.diff.uint64.newvalue = newvalue;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int
hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
hwloc_topology_t topo2, hwloc_obj_t obj2,
unsigned flags,
hwloc_topology_diff_t *firstdiffp, hwloc_topology_diff_t *lastdiffp)
{
unsigned i;
int err;
if (obj1->depth != obj2->depth)
goto out_too_complex;
if (obj1->type != obj2->type)
goto out_too_complex;
if (obj1->os_index != obj2->os_index)
goto out_too_complex;
#define _SETS_DIFFERENT(_set1, _set2) \
( ( !(_set1) != !(_set2) ) \
|| ( (_set1) && !hwloc_bitmap_isequal(_set1, _set2) ) )
#define SETS_DIFFERENT(_set, _obj1, _obj2) _SETS_DIFFERENT((_obj1)->_set, (_obj2)->_set)
if (SETS_DIFFERENT(cpuset, obj1, obj2)
|| SETS_DIFFERENT(complete_cpuset, obj1, obj2)
|| SETS_DIFFERENT(online_cpuset, obj1, obj2)
|| SETS_DIFFERENT(allowed_cpuset, obj1, obj2)
|| SETS_DIFFERENT(nodeset, obj1, obj2)
|| SETS_DIFFERENT(complete_nodeset, obj1, obj2)
|| SETS_DIFFERENT(allowed_nodeset, obj1, obj2))
goto out_too_complex;
/* no need to check logical_index, sibling_rank, symmetric_subtree */
if ((!obj1->name) != (!obj2->name)
|| (obj1->name && strcmp(obj1->name, obj2->name))) {
err = hwloc_append_diff_obj_attr_string(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
NULL,
obj1->name,
obj2->name,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
/* memory */
if (obj1->memory.local_memory != obj2->memory.local_memory) {
err = hwloc_append_diff_obj_attr_uint64(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
0,
obj1->memory.local_memory,
obj2->memory.local_memory,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
/* ignore memory page_types */
/* ignore os_level */
/* type-specific attrs */
switch (obj1->type) {
default:
break;
case HWLOC_OBJ_CACHE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->cache)))
goto out_too_complex;
break;
case HWLOC_OBJ_GROUP:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->group)))
goto out_too_complex;
break;
case HWLOC_OBJ_PCI_DEVICE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->pcidev)))
goto out_too_complex;
break;
case HWLOC_OBJ_BRIDGE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->bridge)))
goto out_too_complex;
break;
case HWLOC_OBJ_OS_DEVICE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->osdev)))
goto out_too_complex;
break;
}
/* distances */
if (obj1->distances_count != obj2->distances_count)
goto out_too_complex;
for(i=0; i<obj1->distances_count; i++) {
struct hwloc_distances_s *d1 = obj1->distances[i], *d2 = obj2->distances[i];
if (d1->relative_depth != d2->relative_depth
|| d1->nbobjs != d2->nbobjs
|| d1->latency_max != d2->latency_max
|| d1->latency_base != d2->latency_base
|| memcmp(d1->latency, d2->latency, d1->nbobjs * d1->nbobjs * sizeof(*d1->latency)))
goto out_too_complex;
}
/* infos */
if (obj1->infos_count != obj2->infos_count)
goto out_too_complex;
for(i=0; i<obj1->infos_count; i++) {
if (strcmp(obj1->infos[i].name, obj2->infos[i].name))
goto out_too_complex;
if (strcmp(obj1->infos[i].value, obj2->infos[i].value)) {
err = hwloc_append_diff_obj_attr_string(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO,
obj1->infos[i].name,
obj1->infos[i].value,
obj2->infos[i].value,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
}
/* ignore userdata */
/* children */
if (obj1->arity != obj2->arity)
goto out_too_complex;
for(i=0; i<obj1->arity; i++) {
err = hwloc_diff_trees(topo1, obj1->children[i],
topo2, obj2->children[i],
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
return 0;
out_too_complex:
hwloc_append_diff_too_complex(obj1, firstdiffp, lastdiffp);
return 0;
}
int hwloc_topology_diff_build(hwloc_topology_t topo1,
hwloc_topology_t topo2,
unsigned long flags,
hwloc_topology_diff_t *diffp)
{
hwloc_topology_diff_t lastdiff, tmpdiff;
int err;
if (flags != 0) {
errno = EINVAL;
return -1;
}
*diffp = NULL;
err = hwloc_diff_trees(topo1, hwloc_get_root_obj(topo1),
topo2, hwloc_get_root_obj(topo2),
flags,
diffp, &lastdiff);
if (!err) {
tmpdiff = *diffp;
while (tmpdiff) {
if (tmpdiff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX) {
err = 1;
break;
}
tmpdiff = tmpdiff->generic.next;
}
}
return err;
}
/********************
* Applying diffs
*/
static int
hwloc_apply_diff_one(hwloc_topology_t topology,
hwloc_topology_diff_t diff,
unsigned long flags)
{
int reverse = !!(flags & HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
switch (diff->generic.type) {
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR: {
struct hwloc_topology_diff_obj_attr_s *obj_attr = &diff->obj_attr;
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, obj_attr->obj_depth, obj_attr->obj_index);
if (!obj)
return -1;
switch (obj_attr->diff.generic.type) {
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE: {
hwloc_obj_t tmpobj;
hwloc_uint64_t oldvalue = reverse ? obj_attr->diff.uint64.newvalue : obj_attr->diff.uint64.oldvalue;
hwloc_uint64_t newvalue = reverse ? obj_attr->diff.uint64.oldvalue : obj_attr->diff.uint64.newvalue;
hwloc_uint64_t valuediff = newvalue - oldvalue;
if (obj->memory.local_memory != oldvalue)
return -1;
obj->memory.local_memory = newvalue;
tmpobj = obj;
while (tmpobj) {
tmpobj->memory.total_memory += valuediff;
tmpobj = tmpobj->parent;
}
break;
}
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME: {
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
if (!obj->name || strcmp(obj->name, oldvalue))
return -1;
free(obj->name);
obj->name = strdup(newvalue);
break;
}
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO: {
const char *name = obj_attr->diff.string.name;
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
unsigned i;
int found = 0;
for(i=0; i<obj->infos_count; i++) {
if (!strcmp(obj->infos[i].name, name)
&& !strcmp(obj->infos[i].value, oldvalue)) {
free(obj->infos[i].value);
obj->infos[i].value = strdup(newvalue);
found = 1;
break;
}
}
if (!found)
return -1;
break;
}
default:
return -1;
}
break;
}
default:
return -1;
}
return 0;
}
int hwloc_topology_diff_apply(hwloc_topology_t topology,
hwloc_topology_diff_t diff,
unsigned long flags)
{
hwloc_topology_diff_t tmpdiff, tmpdiff2;
int err, nr;
if (flags & ~HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE) {
errno = EINVAL;
return -1;
}
tmpdiff = diff;
nr = 0;
while (tmpdiff) {
nr++;
err = hwloc_apply_diff_one(topology, tmpdiff, flags);
if (err < 0)
goto cancel;
tmpdiff = tmpdiff->generic.next;
}
return 0;
cancel:
tmpdiff2 = tmpdiff;
tmpdiff = diff;
while (tmpdiff != tmpdiff2) {
hwloc_apply_diff_one(topology, tmpdiff, flags ^ HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
tmpdiff = tmpdiff->generic.next;
}
errno = EINVAL;
return -nr; /* return the index (starting at 1) of the first element that couldn't be applied */
}

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

@ -1,5 +1,5 @@
/*
* Copyright © 2010-2013 Inria. All rights reserved.
* Copyright © 2010-2014 Inria. All rights reserved.
* Copyright © 2011-2012 Université Bordeaux 1
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -23,20 +23,6 @@ void hwloc_distances_init(struct hwloc_topology *topology)
topology->first_osdist = topology->last_osdist = NULL;
}
/* called when reloading a topology.
* keep initial parameters (from set_distances and environment),
* but drop what was generated during previous load().
*/
void hwloc_distances_clear(struct hwloc_topology *topology)
{
struct hwloc_os_distances_s * osdist;
for(osdist = topology->first_osdist; osdist; osdist = osdist->next) {
/* remove final distance matrices, but keep physically-ordered ones */
free(osdist->objs);
osdist->objs = NULL;
}
}
/* called during topology destroy */
void hwloc_distances_destroy(struct hwloc_topology * topology)
{
@ -529,7 +515,7 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
fprintf(stderr, "*\n");
fprintf(stderr, "* Please report this error message to the hwloc user's mailing list,\n");
#ifdef HWLOC_LINUX_SYS
fprintf(stderr, "* along with the output from the hwloc-gather-topology.sh script.\n");
fprintf(stderr, "* along with the output from the hwloc-gather-topology script.\n");
#else
fprintf(stderr, "* along with any relevant topology information from your platform.\n");
#endif
@ -541,6 +527,9 @@ hwloc_distances__finalize_logical(struct hwloc_topology *topology,
hwloc_bitmap_free(nodeset);
return;
}
/* don't attach to Misc objects */
while (root->type == HWLOC_OBJ_MISC)
root = root->parent;
/* ideally, root has the exact cpuset and nodeset.
* but ignoring or other things that remove objects may cause the object array to reduce */
assert(hwloc_bitmap_isincluded(cpuset, root->cpuset));

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

@ -1,6 +1,6 @@
<!--
Copyright © 2009 CNRS
Copyright © 2009-2012 Inria. All rights reserved.
Copyright © 2009-2013 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux 1.
See COPYING in top-level directory.
-->
@ -55,3 +55,17 @@
<!ATTLIST userdata name CDATA "" >
<!ATTLIST userdata length CDATA "0" >
<!ATTLIST userdata encoding CDATA "" >
<!ELEMENT topologydiff (diff)*>
<!ATTLIST topologydiff refname CDATA "">
<!ELEMENT diff EMPTY>
<!ATTLIST diff type CDATA #REQUIRED>
<!ATTLIST diff obj_depth CDATA "-1" >
<!ATTLIST diff obj_index CDATA "-1" >
<!ATTLIST diff obj_attr_type CDATA "-1" >
<!ATTLIST diff obj_attr_index CDATA "-1" >
<!ATTLIST diff obj_attr_name CDATA "" >
<!ATTLIST diff obj_attr_newvalue CDATA "" >
<!ATTLIST diff obj_attr_oldvalue CDATA "" >

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2012 Inria. All rights reserved.
* Copyright © 2009-2014 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.
@ -85,22 +85,33 @@ int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n)
return i < n;
}
void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused)
void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused,
void *cached_uname __hwloc_attribute_unused)
{
#ifdef HAVE_UNAME
struct utsname utsname;
if (uname(&utsname) < 0)
return;
struct utsname _utsname, *utsname;
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);
if (cached_uname)
utsname = (struct utsname *) cached_uname;
else {
utsname = &_utsname;
if (uname(utsname) < 0)
return;
}
if (*utsname->sysname)
hwloc_obj_add_info(topology->levels[0][0], "OSName", utsname->sysname);
if (*utsname->release)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", utsname->release);
if (*utsname->version)
hwloc_obj_add_info(topology->levels[0][0], "OSVersion", utsname->version);
if (*utsname->nodename)
hwloc_obj_add_info(topology->levels[0][0], "HostName", utsname->nodename);
if (*utsname->machine)
hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine);
#endif /* HAVE_UNAME */
}

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

@ -0,0 +1,460 @@
/*
* Copyright © 2009-2014 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <hwloc/plugins.h>
#include <private/debug.h>
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);
if (parent == group_obj)
/* if didn't get merged, setup its sets */
hwloc_fill_object_sets(group_obj);
if (!parent)
/* Failed to insert the parent, maybe a conflicting cpuset, attach to the root object instead */
parent = hwloc_get_root_obj(topology);
}
}
hwloc_bitmap_free(cpuset);
return parent;
}
int
hwloc_insert_pci_device_list(struct hwloc_backend *backend,
struct hwloc_obj *first_obj)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_obj fakeparent;
struct hwloc_obj *obj;
unsigned current_hostbridge;
if (!first_obj)
/* found nothing, exit */
return 0;
/* first, organise object as tree under a fake parent object */
fakeparent.first_child = NULL;
fakeparent.last_child = NULL;
while (first_obj) {
obj = first_obj;
first_obj = obj->next_sibling;
hwloc_pci_add_object(&fakeparent, obj);
}
hwloc_debug("%s", "\nPCI hierarchy under fake parent:\n");
hwloc_pci_traverse(NULL, &fakeparent, hwloc_pci_traverse_print_cb);
/* walk the hierarchy, set bridge depth and lookup OS devices */
hwloc_pci_traverse(NULL, &fakeparent, hwloc_pci_traverse_setbridgedepth_cb);
hwloc_pci_traverse(backend, &fakeparent, hwloc_pci_traverse_lookuposdevices_cb);
/*
* fakeparent 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 (fakeparent.first_child) {
/* start a new host bridge */
struct hwloc_obj *hostbridge = hwloc_alloc_setup_object(HWLOC_OBJ_BRIDGE, current_hostbridge++);
struct hwloc_obj *child = fakeparent.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(&fakeparent, 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;
}
#define HWLOC_PCI_STATUS 0x06
#define HWLOC_PCI_STATUS_CAP_LIST 0x10
#define HWLOC_PCI_CAPABILITY_LIST 0x34
#define HWLOC_PCI_CAP_LIST_ID 0
#define HWLOC_PCI_CAP_LIST_NEXT 1
unsigned
hwloc_pci_find_cap(const unsigned char *config, unsigned cap)
{
unsigned char seen[256] = { 0 };
unsigned char ptr; /* unsigned char to make sure we stay within the 256-byte config space */
if (!(config[HWLOC_PCI_STATUS] & HWLOC_PCI_STATUS_CAP_LIST))
return 0;
for (ptr = config[HWLOC_PCI_CAPABILITY_LIST] & ~3;
ptr; /* exit if next is 0 */
ptr = config[ptr + HWLOC_PCI_CAP_LIST_NEXT] & ~3) {
unsigned char id;
/* Looped around! */
if (seen[ptr])
break;
seen[ptr] = 1;
id = config[ptr + HWLOC_PCI_CAP_LIST_ID];
if (id == cap)
return ptr;
if (id == 0xff) /* exit if id is 0 or 0xff */
break;
}
return 0;
}
#define HWLOC_PCI_EXP_LNKSTA 0x12
#define HWLOC_PCI_EXP_LNKSTA_SPEED 0x000f
#define HWLOC_PCI_EXP_LNKSTA_WIDTH 0x03f0
int
hwloc_pci_find_linkspeed(const unsigned char *config,
unsigned offset, float *linkspeed)
{
unsigned linksta, speed, width;
float lanespeed;
memcpy(&linksta, &config[offset + HWLOC_PCI_EXP_LNKSTA], 4);
speed = linksta & HWLOC_PCI_EXP_LNKSTA_SPEED; /* PCIe generation */
width = (linksta & HWLOC_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 */
*linkspeed = lanespeed * width / 8; /* GB/s */
return 0;
}
#define HWLOC_PCI_HEADER_TYPE 0x0e
#define HWLOC_PCI_HEADER_TYPE_BRIDGE 1
#define HWLOC_PCI_CLASS_BRIDGE_PCI 0x0604
#define HWLOC_PCI_PRIMARY_BUS 0x18
#define HWLOC_PCI_SECONDARY_BUS 0x19
#define HWLOC_PCI_SUBORDINATE_BUS 0x1a
int
hwloc_pci_prepare_bridge(hwloc_obj_t obj,
const unsigned char *config)
{
unsigned char headertype;
unsigned isbridge;
struct hwloc_pcidev_attr_s *pattr = &obj->attr->pcidev;
struct hwloc_bridge_attr_s *battr;
headertype = config[HWLOC_PCI_HEADER_TYPE] & 0x7f;
isbridge = (pattr->class_id == HWLOC_PCI_CLASS_BRIDGE_PCI
&& headertype == HWLOC_PCI_HEADER_TYPE_BRIDGE);
if (!isbridge)
return 0;
battr = &obj->attr->bridge;
if (config[HWLOC_PCI_PRIMARY_BUS] != pattr->bus)
hwloc_debug(" %04x:%02x:%02x.%01x bridge with (ignored) invalid PCI_PRIMARY_BUS %02x\n",
pattr->domain, pattr->bus, pattr->dev, pattr->func, config[HWLOC_PCI_PRIMARY_BUS]);
obj->type = HWLOC_OBJ_BRIDGE;
battr->upstream_type = HWLOC_OBJ_BRIDGE_PCI;
battr->downstream_type = HWLOC_OBJ_BRIDGE_PCI;
battr->downstream.pci.domain = pattr->domain;
battr->downstream.pci.secondary_bus = config[HWLOC_PCI_SECONDARY_BUS];
battr->downstream.pci.subordinate_bus = config[HWLOC_PCI_SUBORDINATE_BUS];
return 0;
}

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

@ -773,7 +773,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "AIX");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

@ -1,5 +1,5 @@
/*
* Copyright © 2013 Inria. All rights reserved.
* Copyright © 2013-2014 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@ -104,7 +104,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "BGQ");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}
@ -209,8 +209,9 @@ hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
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");
fprintf(stderr, "*** Found unexpected uname sysname `%s' machine `%s'\n", utsname.sysname, utsname.machine);
fprintf(stderr, "*** The BGQ backend is only enabled on compute nodes by default (sysname=CNK machine=BGQ)\n");
fprintf(stderr, "*** Set HWLOC_FORCE_BGQ=1 in the environment to enforce the BGQ backend anyway.\n");
return NULL;
}
}

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

@ -1,6 +1,6 @@
/*
* Copyright © 2011 Université Bordeaux 1
* Copyright © 2012 Inria. All rights reserved.
* Copyright © 2012-2014 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@ -64,6 +64,31 @@ hwloc_cuda_query_devices(struct hwloc_cuda_backend_data_s *data)
return;
}
static unsigned hwloc_cuda_cores_per_MP(int major, int minor)
{
/* based on CUDA C Programming Guide, Annex G */
switch (major) {
case 1:
switch (minor) {
case 0:
case 1:
case 2:
case 3: return 8;
}
break;
case 2:
switch (minor) {
case 0: return 32;
case 1: return 48;
}
break;
case 3:
return 192;
}
hwloc_debug("unknown compute capability %u.%u, disabling core display.\n", major, minor);
return 0;
}
static int
hwloc_cuda_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc_backend *caller __hwloc_attribute_unused,
struct hwloc_obj *pcidev)
@ -96,9 +121,11 @@ hwloc_cuda_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc
for(i=0; i<data->nr_devices; i++) {
struct hwloc_cuda_device_info_s *info = &data->devices[i];
char cuda_name[32];
char number[32];
struct cudaDeviceProp prop;
hwloc_obj_t cuda_device;
cudaError_t cures;
unsigned cores;
if (info->pcidomain != pcidev->attr->pcidev.domain)
continue;
@ -123,6 +150,24 @@ hwloc_cuda_backend_notify_new_object(struct hwloc_backend *backend, struct hwloc
if (!cures)
hwloc_obj_add_info(cuda_device, "GPUModel", prop.name);
snprintf(number, sizeof(number), "%llu", ((unsigned long long) prop.totalGlobalMem) >> 10);
hwloc_obj_add_info(cuda_device, "CUDAGlobalMemorySize", number);
snprintf(number, sizeof(number), "%llu", ((unsigned long long) prop.l2CacheSize) >> 10);
hwloc_obj_add_info(cuda_device, "CUDAL2CacheSize", number);
snprintf(number, sizeof(number), "%d", prop.multiProcessorCount);
hwloc_obj_add_info(cuda_device, "CUDAMultiProcessors", number);
cores = hwloc_cuda_cores_per_MP(prop.major, prop.minor);
if (cores) {
snprintf(number, sizeof(number), "%u", cores);
hwloc_obj_add_info(cuda_device, "CUDACoresPerMP", number);
}
snprintf(number, sizeof(number), "%llu", ((unsigned long long) prop.sharedMemPerBlock) >> 10);
hwloc_obj_add_info(cuda_device, "CUDASharedMemorySizePerMP", number);
hwloc_insert_object_by_parent(topology, pcidev, cuda_device);
return 1;
}
@ -147,6 +192,9 @@ hwloc_cuda_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend;
struct hwloc_cuda_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);

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

@ -20,6 +20,7 @@ hwloc_custom_insert_group_object_by_parent(struct hwloc_topology *topology, hwlo
obj = hwloc_alloc_setup_object(HWLOC_OBJ_GROUP, -1);
obj->attr->group.depth = groupdepth;
hwloc_obj_add_info(obj, "Backend", "Custom");
hwloc_insert_object_by_parent(topology, parent, obj);
/* insert_object_by_parent() doesn't merge during insert, so obj is still valid */
@ -51,15 +52,17 @@ static int
hwloc_look_custom(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
hwloc_obj_t root = topology->levels[0][0];
assert(!topology->levels[0][0]->cpuset);
assert(!root->cpuset);
if (!topology->levels[0][0]->first_child) {
if (!root->first_child) {
errno = EINVAL;
return -1;
}
topology->levels[0][0]->type = HWLOC_OBJ_SYSTEM;
root->type = HWLOC_OBJ_SYSTEM;
hwloc_obj_add_info(root, "Backend", "Custom");
return 1;
}

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

@ -265,7 +265,7 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Darwin");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

@ -15,6 +15,8 @@ hwloc_fake_component_instantiate(struct hwloc_disc_component *component __hwloc_
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
if (hwloc_plugin_check_namespace("fake", "hwloc_backend_alloc") < 0)
return NULL;
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component instantiated\n");
return NULL;

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

@ -192,7 +192,7 @@ hwloc_look_freebsd(struct hwloc_backend *backend)
#endif
hwloc_obj_add_info(topology->levels[0][0], "Backend", "FreeBSD");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

@ -218,6 +218,9 @@ hwloc_gl_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend;
struct hwloc_gl_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);

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

@ -247,7 +247,7 @@ hwloc_look_hpux(struct hwloc_backend *backend)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "HP-UX");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

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

@ -147,7 +147,7 @@ hwloc_look_netbsd(struct hwloc_backend *backend)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "NetBSD");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

@ -22,7 +22,7 @@ hwloc_look_noos(struct hwloc_backend *backend)
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);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

@ -185,6 +185,9 @@ hwloc_nvml_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend;
struct hwloc_nvml_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);

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

@ -1,5 +1,5 @@
/*
* Copyright © 2012 Inria. All rights reserved.
* Copyright © 2012-2014 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux 1. All right reserved.
* See COPYING in top-level directory.
*/
@ -30,6 +30,9 @@ struct hwloc_opencl_backend_data_s {
char devicevendor[64];
char devicetype[64];
unsigned computeunits;
unsigned long long globalmemsize;
union hwloc_opencl_device_info_u {
struct hwloc_opencl_device_info_amd_s {
unsigned pcidomain, pcibus, pcidev, pcifunc;
@ -99,6 +102,8 @@ hwloc_opencl_query_devices(struct hwloc_opencl_backend_data_s *data)
#ifdef CL_DEVICE_TOPOLOGY_AMD
cl_device_topology_amd amdtopo;
#endif
cl_ulong globalmemsize;
cl_uint computeunits;
hwloc_debug("Looking device %p\n", device_ids[i]);
@ -133,6 +138,12 @@ hwloc_opencl_query_devices(struct hwloc_opencl_backend_data_s *data)
break;
}
clGetDeviceInfo(device_ids[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(globalmemsize), &globalmemsize, NULL);
info->globalmemsize = globalmemsize / 1024;
clGetDeviceInfo(device_ids[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(computeunits), &computeunits, NULL);
info->computeunits = computeunits;
hwloc_debug("platform %s device %s vendor %s type %s\n", info->platformname, info->devicename, info->devicevendor, info->devicetype);
/* find our indexes */
@ -251,6 +262,12 @@ hwloc_opencl_backend_notify_new_object(struct hwloc_backend *backend, struct hwl
snprintf(buffer, sizeof(buffer), "%u", info->platformdeviceidx);
hwloc_obj_add_info(osdev, "OpenCLPlatformDeviceIndex", buffer);
snprintf(buffer, sizeof(buffer), "%u", info->computeunits);
hwloc_obj_add_info(osdev, "OpenCLComputeUnits", buffer);
snprintf(buffer, sizeof(buffer), "%llu", info->globalmemsize);
hwloc_obj_add_info(osdev, "OpenCLGlobalMemorySize", buffer);
hwloc_insert_object_by_parent(topology, pcidev, osdev);
return 1;
}
@ -275,6 +292,9 @@ hwloc_opencl_component_instantiate(struct hwloc_disc_component *component,
struct hwloc_backend *backend;
struct hwloc_opencl_backend_data_s *data;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);

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

@ -336,7 +336,7 @@ hwloc_look_osf(struct hwloc_backend *backend)
hwloc_obj_add_info(topology->levels[0][0], "Backend", "OSF");
if (topology->is_thissystem)
hwloc_add_uname_info(topology);
hwloc_add_uname_info(topology, NULL);
return 1;
}

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

@ -0,0 +1,416 @@
/*
* 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_CAP_ID_EXP
#define PCI_CAP_ID_EXP 0x10
#endif
#ifndef PCI_CAP_NORMAL
#define PCI_CAP_NORMAL 1
#endif
#define CONFIG_SPACE_CACHESIZE 256
#ifdef HWLOC_HAVE_PCIUTILS
/* Avoid letting libpci call exit(1) when no PCI bus is available. */
static jmp_buf err_buf;
static void
hwloc_pci_error(char *msg, ...)
{
va_list args;
va_start(args, msg);
fprintf(stderr, "pcilib: ");
vfprintf(stderr, msg, args);
fprintf(stderr, "\n");
longjmp(err_buf, 1);
}
static void
hwloc_pci_warning(char *msg __hwloc_attribute_unused, ...)
{
}
#endif
static int
hwloc_look_pci(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
struct hwloc_obj *first_obj = NULL, *last_obj = NULL;
#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_get_next_pcidev(topology, NULL)) {
hwloc_debug("%s", "PCI objects already added, ignoring pci backend.\n");
return 0;
}
if (!hwloc_topology_is_thissystem(topology)) {
hwloc_debug("%s", "\nno PCI detection (not thissystem)\n");
return 0;
}
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];
struct hwloc_obj *obj;
unsigned os_index;
unsigned domain;
unsigned device_class;
unsigned short tmp16;
char name[128];
unsigned offset;
#ifdef HWLOC_HAVE_PCI_FIND_CAP
struct pci_cap *cap;
#endif
/* initialize the config space in case we fail to read it (missing permissions, etc). */
memset(config_space_cache, 0xff, CONFIG_SPACE_CACHESIZE);
#ifdef HWLOC_HAVE_LIBPCIACCESS
pci_device_probe(pcidev);
pci_device_cfg_read(pcidev, config_space_cache, 0, CONFIG_SPACE_CACHESIZE, NULL);
#else /* HWLOC_HAVE_PCIUTILS */
pci_read_block(pcidev, 0, config_space_cache, CONFIG_SPACE_CACHESIZE); /* doesn't even tell how much it actually reads */
#endif
/* try to read the domain */
#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
device_class = config_space_cache[PCI_CLASS_DEVICE] | (config_space_cache[PCI_CLASS_DEVICE+1] << 8);
#endif
#endif
/* 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(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;
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, 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 (need extended config space (more than 256 bytes)),
* 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;
size_t read;
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) {
read = fread(value, 1, sizeof(value), file);
fclose(file);
if (read)
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) {
read = fread(value, 1, sizeof(value), file);
fclose(file);
if (read)
obj->attr->pcidev.device_id = strtoul(value, NULL, 16);
}
#endif
}
if (offset > 0 && offset + 20 /* size of PCI express block up to link status */ <= CONFIG_SPACE_CACHESIZE)
hwloc_pci_find_linkspeed(config_space_cache, offset, &obj->attr->pcidev.linkspeed);
hwloc_pci_prepare_bridge(obj, config_space_cache);
if (obj->type == HWLOC_OBJ_PCI_DEVICE) {
memcpy(&tmp16, &config_space_cache[PCI_SUBSYSTEM_VENDOR_ID], sizeof(tmp16));
obj->attr->pcidev.subvendor_id = tmp16;
memcpy(&tmp16, &config_space_cache[PCI_SUBSYSTEM_ID], sizeof(tmp16));
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.
*/
/* get the vendor name */
#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 && *vendorname)
hwloc_obj_add_info(obj, "PCIVendor", vendorname);
/* get the device name */
#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 && *devicename)
hwloc_obj_add_info(obj, "PCIDevice", devicename);
/* generate or get the fullname */
#ifdef HWLOC_HAVE_LIBPCIACCESS
snprintf(name, sizeof(name), "%s%s%s",
vendorname ? vendorname : "",
vendorname && devicename ? " " : "",
devicename ? devicename : "");
fullname = name;
if (*name)
obj->name = strdup(name);
#else /* HWLOC_HAVE_PCIUTILS */
fullname = pci_lookup_name(pciaccess, name, sizeof(name),
#if HAVE_DECL_PCI_LOOKUP_NO_NUMBERS
PCI_LOOKUP_VENDOR|PCI_LOOKUP_DEVICE|PCI_LOOKUP_NO_NUMBERS,
pcidev->vendor_id, pcidev->device_id
#else
PCI_LOOKUP_VENDOR|PCI_LOOKUP_DEVICE,
pcidev->vendor_id, pcidev->device_id, 0, 0
#endif
);
if (fullname && *fullname)
obj->name = strdup(fullname);
#endif /* HWLOC_HAVE_PCIUTILS */
hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s\n",
domain, pcidev->bus, pcidev->dev, pcidev->func,
device_class, pcidev->vendor_id, pcidev->device_id,
fullname && *fullname ? fullname : "??");
/* queue the object for now */
if (first_obj)
last_obj->next_sibling = obj;
else
first_obj = obj;
last_obj = obj;
}
/* finalize device scanning */
#ifdef HWLOC_HAVE_LIBPCIACCESS
pci_iterator_destroy(iter);
pci_system_cleanup();
#else /* HWLOC_HAVE_PCIUTILS */
pci_cleanup(pciaccess);
#endif
return hwloc_insert_pci_device_list(backend, first_obj);
}
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;
if (hwloc_plugin_check_namespace(component->name, "hwloc_backend_alloc") < 0)
return NULL;
/* thissystem may not be fully initialized yet, we'll check flags in discover() */
backend = hwloc_backend_alloc(component);
if (!backend)
return NULL;
backend->flags = HWLOC_BACKEND_FLAG_NEED_LEVELS;
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
};

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