Remove a lot of kruft from the hwloc paffinity directory that we're
not using in Open MPI (i.e., that stuff is only used in the standalone builds of hwloc -- it's not compiled/installed/used by Open MPI). This commit was SVN r23416.
Этот коммит содержится в:
родитель
b7a57ffb66
Коммит
57d89d1c0c
@ -1,143 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand `-c -o'.
|
||||
|
||||
scriptversion=2009-10-06.20; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand `-c -o'.
|
||||
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file `INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
eat=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||
# So we strip `-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no `-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# `.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use `[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1502
opal/mca/paffinity/hwloc/hwloc/config/config.guess
поставляемый
1502
opal/mca/paffinity/hwloc/hwloc/config/config.guess
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1731
opal/mca/paffinity/hwloc/hwloc/config/config.sub
поставляемый
1731
opal/mca/paffinity/hwloc/hwloc/config/config.sub
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,630 +0,0 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u="sed s,\\\\\\\\,/,g"
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
@ -1,520 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,376 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
|
||||
# 2008, 2009 Free Software Foundation, Inc.
|
||||
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run=:
|
||||
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
|
||||
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
|
||||
|
||||
# In the cases where this matters, `missing' is being run in the
|
||||
# srcdir already.
|
||||
if test -f configure.ac; then
|
||||
configure_ac=configure.ac
|
||||
else
|
||||
configure_ac=configure.in
|
||||
fi
|
||||
|
||||
msg="missing on your system"
|
||||
|
||||
case $1 in
|
||||
--run)
|
||||
# Try to run requested program, and just exit if it succeeds.
|
||||
run=
|
||||
shift
|
||||
"$@" && exit 0
|
||||
# Exit code 63 means version mismatch. This often happens
|
||||
# when the user try to use an ancient version of a tool on
|
||||
# a file that requires a minimum version. In this case we
|
||||
# we should proceed has if the program had been absent, or
|
||||
# if --run hadn't been passed.
|
||||
if test $? = 63; then
|
||||
run=:
|
||||
msg="probably too old"
|
||||
fi
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||
error status if there is no known handling for PROGRAM.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
--run try to run the given command, and emulate it if it fails
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal touch file \`aclocal.m4'
|
||||
autoconf touch file \`configure'
|
||||
autoheader touch file \`config.h.in'
|
||||
autom4te touch the output file, or create a stub one
|
||||
automake touch all \`Makefile.in' files
|
||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
flex create \`lex.yy.c', if possible, from existing .c
|
||||
help2man touch the output file
|
||||
lex create \`lex.yy.c', if possible, from existing .c
|
||||
makeinfo touch the output file
|
||||
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
|
||||
\`g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: Unknown \`$1' option"
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# normalize program name to check for.
|
||||
program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
# Now exit if we have it, but it failed. Also exit now if we
|
||||
# don't have it and --version was passed (most likely to detect
|
||||
# the program). This is about non-GNU programs, so use $1 not
|
||||
# $program.
|
||||
case $1 in
|
||||
lex*|yacc*)
|
||||
# Not GNU programs, they don't have --version.
|
||||
;;
|
||||
|
||||
tar*)
|
||||
if test -n "$run"; then
|
||||
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
# Could not run --version or --help. This is probably someone
|
||||
# running `$TOOL --version' or `$TOOL --help' to check whether
|
||||
# $TOOL exists and not knowing $TOOL uses missing.
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If it does not exist, or fails to run (possibly an outdated version),
|
||||
# try to emulate it.
|
||||
case $program in
|
||||
aclocal*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||
any GNU archive site."
|
||||
touch aclocal.m4
|
||||
;;
|
||||
|
||||
autoconf*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`${configure_ac}'. You might want to install the
|
||||
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||
archive site."
|
||||
touch configure
|
||||
;;
|
||||
|
||||
autoheader*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||
from any GNU archive site."
|
||||
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||
test -z "$files" && files="config.h"
|
||||
touch_files=
|
||||
for f in $files; do
|
||||
case $f in
|
||||
*:*) touch_files="$touch_files "`echo "$f" |
|
||||
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||
*) touch_files="$touch_files $f.in";;
|
||||
esac
|
||||
done
|
||||
touch $touch_files
|
||||
;;
|
||||
|
||||
automake*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||
You might want to install the \`Automake' and \`Perl' packages.
|
||||
Grab them from any GNU archive site."
|
||||
find . -type f -name Makefile.am -print |
|
||||
sed 's/\.am$/.in/' |
|
||||
while read f; do touch "$f"; done
|
||||
;;
|
||||
|
||||
autom4te*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, but is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them.
|
||||
You can get \`$1' as part of \`Autoconf' from any GNU
|
||||
archive site."
|
||||
|
||||
file=`echo "$*" | sed -n "$sed_output"`
|
||||
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
|
||||
if test -f "$file"; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
echo "#! /bin/sh"
|
||||
echo "# Created by GNU Automake missing as a replacement of"
|
||||
echo "# $ $@"
|
||||
echo "exit 0"
|
||||
chmod +x $file
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
bison*|yacc*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' $msg. You should only need it if
|
||||
you modified a \`.y' file. You may need the \`Bison' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Bison' from any GNU archive site."
|
||||
rm -f y.tab.c y.tab.h
|
||||
if test $# -ne 1; then
|
||||
eval LASTARG="\${$#}"
|
||||
case $LASTARG in
|
||||
*.y)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||
if test -f "$SRCFILE"; then
|
||||
cp "$SRCFILE" y.tab.c
|
||||
fi
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||
if test -f "$SRCFILE"; then
|
||||
cp "$SRCFILE" y.tab.h
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if test ! -f y.tab.h; then
|
||||
echo >y.tab.h
|
||||
fi
|
||||
if test ! -f y.tab.c; then
|
||||
echo 'main() { return 0; }' >y.tab.c
|
||||
fi
|
||||
;;
|
||||
|
||||
lex*|flex*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.l' file. You may need the \`Flex' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Flex' from any GNU archive site."
|
||||
rm -f lex.yy.c
|
||||
if test $# -ne 1; then
|
||||
eval LASTARG="\${$#}"
|
||||
case $LASTARG in
|
||||
*.l)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||
if test -f "$SRCFILE"; then
|
||||
cp "$SRCFILE" lex.yy.c
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if test ! -f lex.yy.c; then
|
||||
echo 'main() { return 0; }' >lex.yy.c
|
||||
fi
|
||||
;;
|
||||
|
||||
help2man*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a dependency of a manual page. You may need the
|
||||
\`Help2man' package in order for those modifications to take
|
||||
effect. You can get \`Help2man' from any GNU archive site."
|
||||
|
||||
file=`echo "$*" | sed -n "$sed_output"`
|
||||
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
|
||||
if test -f "$file"; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
echo ".ab help2man is required to generate this page"
|
||||
exit $?
|
||||
fi
|
||||
;;
|
||||
|
||||
makeinfo*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||
indirectly affecting the aspect of the manual. The spurious
|
||||
call might also be the consequence of using a buggy \`make' (AIX,
|
||||
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||
the \`GNU make' package. Grab either from any GNU archive site."
|
||||
# The file to touch is that specified with -o ...
|
||||
file=`echo "$*" | sed -n "$sed_output"`
|
||||
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
|
||||
if test -z "$file"; then
|
||||
# ... or it is the one specified with @setfilename ...
|
||||
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '
|
||||
/^@setfilename/{
|
||||
s/.* \([^ ]*\) *$/\1/
|
||||
p
|
||||
q
|
||||
}' $infile`
|
||||
# ... or it is derived from the source name (dir/f.texi becomes f.info)
|
||||
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
|
||||
fi
|
||||
# If the file does not exist, the user really needs makeinfo;
|
||||
# let's fail without touching anything.
|
||||
test -f $file || exit 1
|
||||
touch $file
|
||||
;;
|
||||
|
||||
tar*)
|
||||
shift
|
||||
|
||||
# We have already tried tar in the generic part.
|
||||
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||
# messages.
|
||||
if (gnutar --version > /dev/null 2>&1); then
|
||||
gnutar "$@" && exit 0
|
||||
fi
|
||||
if (gtar --version > /dev/null 2>&1); then
|
||||
gtar "$@" && exit 0
|
||||
fi
|
||||
firstarg="$1"
|
||||
if shift; then
|
||||
case $firstarg in
|
||||
*o*)
|
||||
firstarg=`echo "$firstarg" | sed s/o//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
case $firstarg in
|
||||
*h*)
|
||||
firstarg=`echo "$firstarg" | sed s/h//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||
You may want to install GNU tar or Free paxutils, or check the
|
||||
command line arguments."
|
||||
exit 1
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them. Check the \`README' file,
|
||||
it often tells you about the needed prerequisites for installing
|
||||
this package. You may also peek at any GNU archive site, in case
|
||||
some other package would contain this missing \`$1' program."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
21114
opal/mca/paffinity/hwloc/hwloc/configure
поставляемый
21114
opal/mca/paffinity/hwloc/hwloc/configure
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,473 +0,0 @@
|
||||
# Copyright © 2009 INRIA, Université Bordeaux 1
|
||||
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
|
||||
AM_CPPFLAGS = $(HWLOC_CPPFLAGS)
|
||||
|
||||
DOCDIR = $(HWLOC_top_builddir)/doc
|
||||
DOX_CONFIG = $(HWLOC_top_srcdir)/doc/doxygen.cfg
|
||||
|
||||
DOX_DIR = doxygen-doc
|
||||
DOX_HTML_DIR = $(DOX_DIR)/html
|
||||
DOX_MAN_DIR = $(DOX_DIR)/man
|
||||
DOX_LATEX_DIR = $(DOX_DIR)/latex
|
||||
DOX_A4PDF = doxygen-doc/$(PACKAGE)-a4.pdf
|
||||
DOX_LETTERPDF = doxygen-doc/$(PACKAGE)-letter.pdf
|
||||
DOX_TAG = $(DOX_DIR)/$(PACKAGE).tag
|
||||
|
||||
#
|
||||
# The goal is that Doxygen output (i.e., the documentation) is
|
||||
# included in release tarballs; there is no need to build anything
|
||||
# from tarballs. Developers will need to build the docs the first
|
||||
# time they build after a checkout (or if something in the docs
|
||||
# changes, etc.).
|
||||
#
|
||||
# Note that by listing directories in EXTRA_DIST, we pick up the whole
|
||||
# tree (e.g., everything in the man and latex directories).
|
||||
#
|
||||
|
||||
PREBUILT_IMAGES = images/dudley.png images/emmett.png images/hagrid.png
|
||||
image_built_sources = images/diagram.png images/diagram.eps
|
||||
|
||||
EXTRA_DIST = \
|
||||
hwloc.doxy \
|
||||
doxygen.css \
|
||||
doxygen.cfg \
|
||||
images/diagram.fig \
|
||||
www.open-mpi.org.cfg \
|
||||
www.open-mpi.org-css.inc \
|
||||
www.open-mpi.org-footer.inc \
|
||||
www.open-mpi.org-header.inc \
|
||||
$(PREBUILT_IMAGES) \
|
||||
$(image_built_sources)
|
||||
|
||||
#
|
||||
# Files where the doxygen inputs live (i.e., dependencies). Make the
|
||||
# generated tagfile depend on these files, which will force them to be
|
||||
# regenerated (i.e., re-run doxygen) whenever any of these files
|
||||
# change.
|
||||
#
|
||||
|
||||
dox_inputs = $(DOX_CONFIG) \
|
||||
$(srcdir)/hwloc.doxy \
|
||||
$(HWLOC_top_srcdir)/include/hwloc.h \
|
||||
$(HWLOC_top_srcdir)/include/hwloc/helper.h \
|
||||
$(HWLOC_top_srcdir)/include/hwloc/cpuset.h \
|
||||
$(HWLOC_top_srcdir)/include/hwloc/glibc-sched.h \
|
||||
$(HWLOC_top_srcdir)/include/hwloc/linux.h \
|
||||
$(HWLOC_top_srcdir)/include/hwloc/linux-libnuma.h \
|
||||
$(HWLOC_top_srcdir)/include/hwloc/openfabrics-verbs.h
|
||||
|
||||
#
|
||||
# Create the images that we need for the PDF output and the HTML
|
||||
# output. There is not an easy way to check if the output of
|
||||
# AC_PATH_PROG found something in configure.ac (!), so we have to put
|
||||
# a run-time check here to see if fig2dev was found. :-(
|
||||
#
|
||||
# Note that BUILD_DOXYGEN will automatically be false if we're not
|
||||
# building standalone.
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_DOXYGEN
|
||||
BUILT_SOURCES = $(image_built_sources)
|
||||
|
||||
images/diagram.png: $(srcdir)/images/diagram.fig
|
||||
$(MKDIR_P) images
|
||||
@if test "x$(FIG2DEV)" = "x"; then \
|
||||
echo "ERROR: Cannot find the 'fig2dev' executable -- cannot make $@"; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(FIG2DEV) -L png $< $@
|
||||
|
||||
images/diagram.eps: $(srcdir)/images/diagram.fig
|
||||
$(MKDIR_P) images
|
||||
@if test "x$(FIG2DEV)" = "x"; then \
|
||||
echo "ERROR: Cannot find the 'fig2dev' executable -- cannot make $@"; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(FIG2DEV) -L eps $< $@
|
||||
endif
|
||||
|
||||
#
|
||||
# Rules for running doxygen. It depends on the built images and the
|
||||
# dox_inputs.
|
||||
# Remove useless manpages, they have too long filenames anyway because
|
||||
# of nested structurre/union declarations.
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_DOXYGEN
|
||||
$(DOX_TAG): $(BUILT_SOURCES) $(dox_inputs) $(PREBUILT_IMAGES)
|
||||
rm -fr $(DOX_DIR)
|
||||
$(DOXYGEN) $(DOX_CONFIG)
|
||||
-sed -i \
|
||||
-e 's/__hwloc_restrict/restrict/g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-restrict/restrict/g' \
|
||||
-e 's/__hwloc_attribute_unused//g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-attribute\\_\\-unused//g' \
|
||||
-e 's/__hwloc_attribute_malloc//g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-attribute\\_\\-malloc//g' \
|
||||
-e 's/__hwloc_attribute_const//g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-attribute\\_\\-const//g' \
|
||||
-e 's/__hwloc_attribute_pure//g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-attribute\\_\\-pure//g' \
|
||||
-e 's/__hwloc_attribute_deprecated//g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-attribute\\_\\-deprecated//g' \
|
||||
-e 's/HWLOC_DECLSPEC//g' \
|
||||
-e 's/HWLOC\\_\\-DECLSPEC//g' \
|
||||
-e 's/__hwloc_inline/inline/g' \
|
||||
-e 's/\\_\\-\\_\\-hwloc\\_\\-inline/inline/g' \
|
||||
$(DOX_DIR)/html/*.html $(DOX_DIR)/latex/*.tex $(DOX_DIR)/man/man3/*.3
|
||||
@echo "Work-around spurious leading _ in doxygen filenames..."
|
||||
(cd $(DOX_DIR)/man/man3 ; \
|
||||
for i in _hwloc* ; do \
|
||||
[ ! -f $$i ] || mv $$i $${i#_} ; \
|
||||
done)
|
||||
@echo "Removing useless manpages..."
|
||||
@mkdir $(DOX_DIR)/man.tmp
|
||||
@mv $(man3_MANS) $(DOX_DIR)/man.tmp/
|
||||
@rm -rf $(DOX_DIR)/man/man3
|
||||
@mv $(DOX_DIR)/man.tmp $(DOX_DIR)/man/man3
|
||||
if HWLOC_DOXYGEN_BROKEN_SHORT_NAMES
|
||||
@echo "Work-around buggy doxygen filenames..."
|
||||
-@mv -f $(DOX_DIR)/html/termsanddefs.html $(DOX_DIR)/html/a00001.html
|
||||
-@mv -f $(DOX_DIR)/latex/termsanddefs.tex $(DOX_DIR)/latex/a00001.tex
|
||||
-@mv -f $(DOX_DIR)/html/tools.html $(DOX_DIR)/html/a00002.html
|
||||
-@mv -f $(DOX_DIR)/latex/tools.tex $(DOX_DIR)/latex/a00002.tex
|
||||
-@mv -f $(DOX_DIR)/html/envvar.html $(DOX_DIR)/html/a00003.html
|
||||
-@mv -f $(DOX_DIR)/latex/envvar.tex $(DOX_DIR)/latex/a00003.tex
|
||||
-@mv -f $(DOX_DIR)/html/interoperability.html $(DOX_DIR)/html/a00004.html
|
||||
-@mv -f $(DOX_DIR)/latex/interoperability.tex $(DOX_DIR)/latex/a00004.tex
|
||||
-@mv -f $(DOX_DIR)/html/threadsafety.html $(DOX_DIR)/html/a00005.html
|
||||
-@mv -f $(DOX_DIR)/latex/threadsafety.tex $(DOX_DIR)/latex/a00005.tex
|
||||
-@mv -f $(DOX_DIR)/html/embed.html $(DOX_DIR)/html/a00006.html
|
||||
-@mv -f $(DOX_DIR)/latex/embed.tex $(DOX_DIR)/latex/a00006.tex
|
||||
-@mv -f $(DOX_DIR)/html/switchfromplpa.html $(DOX_DIR)/html/a00007.html
|
||||
-@mv -f $(DOX_DIR)/latex/switchfromplpa.tex $(DOX_DIR)/latex/a00007.tex
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# Rules for building the PDF
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_DOXYGEN
|
||||
|
||||
# The Doxygen config is set to generate a4 latex -- no transformation
|
||||
# is necessary.
|
||||
$(DOX_A4PDF): $(DOX_TAG)
|
||||
cd $(DOX_LATEX_DIR); \
|
||||
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
cp refman.tex a4-refman.tex; \
|
||||
$(PDFLATEX) a4-refman.tex; \
|
||||
$(MAKEINDEX) a4-refman.idx; \
|
||||
$(PDFLATEX) a4-refman.tex; \
|
||||
done=0; repeat=5; \
|
||||
while test $$done = 0 -a $$repeat -gt 0; do \
|
||||
if $(EGREP) 'Rerun (LaTeX|to get cross-references right)' a4-refman.log > /dev/null 2>&1; then \
|
||||
$(PDFLATEX) a4-refman.tex; \
|
||||
repeat=`expr $$repeat - 1`; \
|
||||
else \
|
||||
done=1; \
|
||||
fi; \
|
||||
done; \
|
||||
mv a4-refman.pdf $(DOCDIR)/$(DOX_A4PDF)
|
||||
|
||||
# The Doxygen config is set to generate a4 latex -- slightly transform
|
||||
# to make suitable for US letter.
|
||||
$(DOX_LETTERPDF): $(DOX_TAG)
|
||||
cd $(DOX_LATEX_DIR); \
|
||||
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
|
||||
sed -e 's/a4paper/letterpaper/g' -e 's/\\usepackage{a4wide}//' refman.tex > letter-refman.tex; \
|
||||
$(PDFLATEX) letter-refman.tex; \
|
||||
$(MAKEINDEX) letter-refman.idx; \
|
||||
$(PDFLATEX) letter-refman.tex; \
|
||||
done=0; repeat=5; \
|
||||
while test $$done = 0 -a $$repeat -gt 0; do \
|
||||
if $(EGREP) 'Rerun (LaTeX|to get cross-references right)' letter-refman.log > /dev/null 2>&1; then \
|
||||
$(PDFLATEX) letter-refman.tex; \
|
||||
repeat=`expr $$repeat - 1`; \
|
||||
else \
|
||||
done=1; \
|
||||
fi; \
|
||||
done; \
|
||||
mv letter-refman.pdf $(DOCDIR)/$(DOX_LETTERPDF)
|
||||
endif
|
||||
|
||||
#
|
||||
# Note that we want to use our own doxygen.css file; not the one that
|
||||
# doxygen installs in the HTML directory. So manually copy it over.
|
||||
# Be a little clever: only copy the doxygen.css file over if it exists
|
||||
# in DOX_HTML_DIR (which is in the build tree). If the html tree
|
||||
# doesn't exist in the build tree, then we're using an html tree in
|
||||
# the source tree, and we don't need to copy over the doxygen.css
|
||||
# because we didn't build the html tree (e.g., the html tree came
|
||||
# pre-bundled in a tarball).
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_DOXYGEN
|
||||
all-local: $(DOX_TAG)
|
||||
if test -d $(DOX_HTML_DIR) -a -f $(DOX_HTML_DIR)/doxygen.css; then \
|
||||
cp -f $(srcdir)/doxygen.css $(DOX_HTML_DIR); \
|
||||
fi
|
||||
endif
|
||||
|
||||
#
|
||||
# Un/install the generated PDF and man pages (just like BUILD_DOXYGEN,
|
||||
# INSTALL_DOXYGEN will automatically be false if we're not building in
|
||||
# standalone mode).
|
||||
#
|
||||
|
||||
if HWLOC_INSTALL_DOXYGEN
|
||||
dist_pdf_DATA = $(DOX_A4PDF) $(DOX_LETTERPDF)
|
||||
endif
|
||||
|
||||
#
|
||||
# Install the HWLOC_* and hwloc_* man pages. It would be great to
|
||||
# figure out how to not have to list every installable man page here
|
||||
# in the Makefile.am... :-(
|
||||
#
|
||||
|
||||
if HWLOC_INSTALL_DOXYGEN
|
||||
man3_MANS = \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_CPUBIND_PROCESS.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_CPUBIND_STRICT.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_CPUBIND_THREAD.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_CACHE.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_CORE.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_MACHINE.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_MISC.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_GROUP.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_NODE.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_PU.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_SOCKET.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_OBJ_SYSTEM.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_TYPE_DEPTH_MULTIPLE.3 \
|
||||
$(DOX_MAN_DIR)/man3/HWLOC_TYPE_DEPTH_UNKNOWN.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_compare_types.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpubind_policy_t.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_alloc.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_free.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_dup.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_copy.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_all_but_cpu.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_and.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_andnot.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_clr.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_clr_range.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_compare.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_compare_first.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_fill.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_first.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_foreach_begin.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_foreach_end.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_glibc_sched_affinity.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_ith_ulong.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_linux_libnuma_bitmask.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_linux_libnuma_nodemask.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_linux_libnuma_ulongs.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_string.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_from_ulong.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_intersects.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_isequal.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_isfull.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_isincluded.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_isset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_iszero.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_last.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_next.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_not.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_or.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_set.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_set_range.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_singlify.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_snprintf.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_asprintf.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_t.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_to_glibc_sched_affinity.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_to_ith_ulong.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_to_linux_libnuma_bitmask.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_to_linux_libnuma_nodemask.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_to_linux_libnuma_ulongs.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_to_ulong.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_weight.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_cpuset_xor.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_distribute.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_closest_objs.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_common_ancestor_obj.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_cache_covering_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_child_covering_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_covering_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_depth_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_get_allowed_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_get_complete_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_get_online_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_get_topology_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_first_largest_obj_inside_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_largest_objs_inside_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_nbobjs_inside_cpuset_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_nbobjs_inside_cpuset_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_child.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_obj_covering_cpuset_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_obj_covering_cpuset_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_obj_inside_cpuset_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_obj_inside_cpuset_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_obj_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_next_obj_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_pu_obj_by_os_index.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_below_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_below_array_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_inside_cpuset_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_inside_cpuset_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_obj_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_ancestor_obj_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_ancestor_obj_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_shared_cache_covering_obj.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_root_obj.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_type_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_nbobjs_by_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_nbobjs_by_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_type_or_above_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_type_or_below_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_ibv_get_device_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_linux_parse_cpumap_file.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_attr_u.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_attr_u_hwloc_cache_attr_s.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_attr_u_hwloc_machine_attr_s.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_attr_u_hwloc_group_attr_s.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_memory_s.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_cpuset_snprintf.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_is_in_subtree.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_type_snprintf.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_attr_snprintf.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_snprintf.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_t.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_type_of_string.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_type_string.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_obj_type_t.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_cpubind.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_proc_cpubind.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_get_thread_cpubind.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_set_cpubind.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_set_proc_cpubind.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_set_thread_cpubind.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_check.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_destroy.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_export_xml.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_insert_misc_object_by_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_insert_misc_object_by_parent.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_flags_e.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_get_depth.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_get_support.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_ignore_all_keep_structure.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_ignore_type.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_ignore_type_keep_structure.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_init.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_is_thissystem.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_load.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_set_flags.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_set_fsroot.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_set_pid.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_set_synthetic.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_set_xml.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_support.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_discovery_support.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_cpubind_support.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwloc_topology_t.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_binding.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_configuration.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_conversion.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_cpuset.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_creation.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_glibc_sched.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_binding.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_find_cache.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_find_covering.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_find_coverings.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_find_inside.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_traversal.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_traversal_basic.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_helper_types.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_information.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_linux_libnuma_bitmask.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_linux_libnuma_nodemask.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_linux_libnuma_ulongs.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_objects.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_traversal.3 \
|
||||
$(DOX_MAN_DIR)/man3/hwlocality_types.3
|
||||
endif
|
||||
|
||||
#
|
||||
# Put in these rules to force the generation of the man pages and get
|
||||
# all the dependencies right. Additionally, this forces a
|
||||
# serialization during parallel builds (e.g., "make -j X") to ensure
|
||||
# that we don't get partial target errors.
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_DOXYGEN
|
||||
$(man3_MANS): $(DOX_TAG)
|
||||
# Enforce some ordering so that "make -j X" works properly (i.e.,
|
||||
# doesn't try to build both PDFs at the same time)
|
||||
$(DOX_A4PDF): $(DOX_TAG) $(DOX_LETTERPDF)
|
||||
$(DOX_LETTERPDF): $(DOX_TAG)
|
||||
$(DOX_HTML_DIR): $(DOX_TAG)
|
||||
$(DOX_LATEX_DIR): $(DOX_TAG)
|
||||
$(DOX_MAN_DIR): $(DOX_TAG)
|
||||
endif
|
||||
|
||||
#
|
||||
# Make sure that the documentation example works
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_TESTS
|
||||
TESTS = hwloc-hello
|
||||
check_PROGRAMS = $(TESTS)
|
||||
endif HWLOC_BUILD_TESTS
|
||||
|
||||
hwloc_hello_LDADD = $(HWLOC_top_builddir)/src/libhwloc.la
|
||||
hwloc_hello_DEPENDENCIES = $(hwloc_hello_LDADD)
|
||||
|
||||
#
|
||||
# Only remove the actual generated documentation files for maintainers
|
||||
#
|
||||
|
||||
MAINTAINERCLEANFILES = $(DOX_TAG) \
|
||||
-r \
|
||||
$(DOX_HTML_DIR) \
|
||||
$(DOX_MAN_DIR) \
|
||||
$(DOX_LATEX_DIR) \
|
||||
$(DOX_A4PDF) \
|
||||
$(DOX_LETTERPDF)
|
||||
|
||||
#
|
||||
# Rules for creating the top-level README file. There does not appear
|
||||
# to be an easy way to know if AC_PATH_PROG found something in
|
||||
# configure.ac (!), so put a run-time check here to see if we have
|
||||
# w3c.
|
||||
#
|
||||
# Just like BUILD_DOXYGEN, BUILD_README will automatically be false if
|
||||
# we're not building standalone.
|
||||
#
|
||||
|
||||
if HWLOC_BUILD_README
|
||||
doc readme: all $(HWLOC_top_srcdir)/README
|
||||
$(HWLOC_top_srcdir)/README: $(DOX_HTML_DIR)
|
||||
LC_ALL=C $(HWLOC_W3_GENERATOR) $(DOX_HTML_DIR)/index.html | sed -n -e 's/^ //' -e '/^Introduction$$/,$$p' > $@
|
||||
else
|
||||
doc readme: no-build-readme
|
||||
$(HWLOC_top_srcdir)/README: no-build-readme
|
||||
|
||||
no-build-readme:
|
||||
@echo "ERROR: You do not have the 'w3m' or 'lynx' executables to build the README, or do not have the 'doxygen' executable to build the docs."
|
||||
@echo "ERROR: Cannot continue."
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
#DOCUPLOADHOST=sync.bordeaux.inria.fr
|
||||
#DOCUPLOADOPTS=
|
||||
#doc-upload: @DX_DOCDIR@/html
|
||||
# echo FIXME
|
||||
# false
|
||||
# rsync -avz --delete --chmod=ug+rwX,o+rX $(DOCUPLOADOPTS) @DX_DOCDIR@/html/ $(DOCUPLOADHOST):/web/runtime/libtopology/doc/
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,21 +0,0 @@
|
||||
# Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
|
||||
# See big comments in doxygen.cfg about the purpose of this file.
|
||||
|
||||
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
|
||||
INPUT = \
|
||||
@top_srcdir@/doc/hwloc.doxy \
|
||||
@top_srcdir@/include/hwloc.h \
|
||||
@top_srcdir@/include/hwloc/helper.h \
|
||||
@top_srcdir@/include/hwloc/cpuset.h \
|
||||
@top_srcdir@/include/hwloc/glibc-sched.h \
|
||||
@top_srcdir@/include/hwloc/linux.h \
|
||||
@top_srcdir@/include/hwloc/linux-libnuma.h \
|
||||
@top_srcdir@/include/hwloc/openfabrics-verbs.h
|
||||
|
||||
EXAMPLE_PATH = @top_srcdir@/doc
|
||||
|
||||
IMAGE_PATH = @top_srcdir@/doc/images images
|
||||
|
||||
INCLUDE_PATH = @top_srcdir@/doc
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,108 +0,0 @@
|
||||
body {
|
||||
font-size: 13px;
|
||||
/* margin-top: 0px; */
|
||||
}
|
||||
|
||||
div.menu {
|
||||
text-align: center;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 3px;
|
||||
background: #eeeeff;
|
||||
font-variant: small-caps;
|
||||
/* position: fixed;*/
|
||||
width: 100%;
|
||||
}
|
||||
div.menu a {
|
||||
text-decoration: none;
|
||||
color: #0020a0;
|
||||
}
|
||||
div.menu hr.menu {
|
||||
height: 4px;
|
||||
background: #fe0;
|
||||
border: 0px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font: bold normal 2.5em sans-serif ;
|
||||
margin: 0px;
|
||||
color: #0020a0;
|
||||
}
|
||||
h1.sub {
|
||||
font: bold normal 2em sans-serif ;
|
||||
text-align: right ;
|
||||
color: #0020a0;
|
||||
}
|
||||
h1 a {
|
||||
color: #0020a0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: bold normal small-caps 1.5em sans-serif ;
|
||||
color: #0020a0;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font: bold normal small-caps 1em sans-serif ;
|
||||
color: #0020a0;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
h6.mirrors {
|
||||
text-align: right;
|
||||
margin: 0px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
div.section {
|
||||
background: #eeeeff;
|
||||
padding-left: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 6px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 8px;
|
||||
background: #fe0;
|
||||
border: 0px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 12px;
|
||||
background: #dddddd;
|
||||
padding: 3px;
|
||||
padding-left: 0px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.publis-desc {
|
||||
text-align: right;
|
||||
font-style: italic;
|
||||
font-size: 12px;
|
||||
padding-left: 15%;
|
||||
}
|
||||
|
||||
p.updated {
|
||||
text-align: right;
|
||||
font-size: 10px;
|
||||
font-style: italic;
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
/* Example hwloc API program.
|
||||
*
|
||||
* Copyright © 2009 INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* hwloc-hello.c
|
||||
*/
|
||||
|
||||
#include <hwloc.h>
|
||||
|
||||
static void print_children(hwloc_topology_t topology, hwloc_obj_t obj,
|
||||
int depth)
|
||||
{
|
||||
char string[128];
|
||||
unsigned i;
|
||||
|
||||
hwloc_obj_snprintf(string, sizeof(string), topology, obj, "#", 0);
|
||||
printf("%*s%s\n", 2*depth, "", string);
|
||||
for (i = 0; i < obj->arity; i++) {
|
||||
print_children(topology, obj->children[i], depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int depth;
|
||||
unsigned i;
|
||||
unsigned long size;
|
||||
int levels;
|
||||
char string[128];
|
||||
int topodepth;
|
||||
hwloc_topology_t topology;
|
||||
hwloc_cpuset_t cpuset;
|
||||
hwloc_obj_t obj;
|
||||
|
||||
/* Allocate and initialize topology object. */
|
||||
hwloc_topology_init(&topology);
|
||||
|
||||
/* ... Optionally, put detection configuration here to ignore
|
||||
some objects types, define a synthetic topology, etc....
|
||||
|
||||
The default is to detect all the objects of the machine that
|
||||
the caller is allowed to access. See Configure Topology
|
||||
Detection. */
|
||||
|
||||
/* Perform the topology detection. */
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
/* Optionally, get some additional topology information
|
||||
in case we need the topology depth later. */
|
||||
topodepth = hwloc_topology_get_depth(topology);
|
||||
|
||||
/*****************************************************************
|
||||
* First example:
|
||||
* Walk the topology with an array style, from level 0 (always
|
||||
* the system level) to the lowest level (always the proc level).
|
||||
*****************************************************************/
|
||||
for (depth = 0; depth < topodepth; depth++) {
|
||||
printf("*** Objects at level %d\n", depth);
|
||||
for (i = 0; i < hwloc_get_nbobjs_by_depth(topology, depth);
|
||||
i++) {
|
||||
hwloc_obj_snprintf(string, sizeof(string), topology,
|
||||
hwloc_get_obj_by_depth(topology, depth, i),
|
||||
"#", 0);
|
||||
printf("Index %u: %s\n", i, string);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* Second example:
|
||||
* Walk the topology with a tree style.
|
||||
*****************************************************************/
|
||||
printf("*** Printing overall tree\n");
|
||||
print_children(topology, hwloc_get_root_obj(topology), 0);
|
||||
|
||||
/*****************************************************************
|
||||
* Third example:
|
||||
* Print the number of sockets.
|
||||
*****************************************************************/
|
||||
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET);
|
||||
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
|
||||
printf("*** The number of sockets is unknown\n");
|
||||
} else {
|
||||
printf("*** %u socket(s)\n",
|
||||
hwloc_get_nbobjs_by_depth(topology, depth));
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
* Fourth example:
|
||||
* Compute the amount of cache that the first logical processor
|
||||
* has above it.
|
||||
*****************************************************************/
|
||||
levels = 0;
|
||||
size = 0;
|
||||
for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0);
|
||||
obj;
|
||||
obj = obj->parent)
|
||||
if (obj->type == HWLOC_OBJ_CACHE) {
|
||||
levels++;
|
||||
size += obj->attr->cache.size;
|
||||
}
|
||||
printf("*** Logical processor 0 has %d caches totaling %luKB\n",
|
||||
levels, size / 1024);
|
||||
|
||||
/*****************************************************************
|
||||
* Fifth example:
|
||||
* Bind to only one thread of the last core of the machine.
|
||||
*
|
||||
* First find out where cores are, or else smaller sets of CPUs if
|
||||
* the OS doesn't have the notion of a "core".
|
||||
*****************************************************************/
|
||||
depth = hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_CORE);
|
||||
|
||||
/* Get last core. */
|
||||
obj = hwloc_get_obj_by_depth(topology, depth,
|
||||
hwloc_get_nbobjs_by_depth(topology, depth) - 1);
|
||||
if (obj) {
|
||||
/* Get a copy of its cpuset that we may modify. */
|
||||
cpuset = hwloc_cpuset_dup(obj->cpuset);
|
||||
|
||||
/* Get only one logical processor (in case the core is
|
||||
SMT/hyperthreaded). */
|
||||
hwloc_cpuset_singlify(cpuset);
|
||||
|
||||
/* And try to bind ourself there. */
|
||||
if (hwloc_set_cpubind(topology, cpuset, 0)) {
|
||||
char *str;
|
||||
hwloc_cpuset_asprintf(&str, obj->cpuset);
|
||||
printf("Couldn't bind to cpuset %s\n", str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
/* Free our cpuset copy */
|
||||
hwloc_cpuset_free(cpuset);
|
||||
}
|
||||
|
||||
/* Destroy topology object. */
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,890 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
/*! \mainpage Hardware Locality
|
||||
|
||||
<h1 class="sub">Portable abstraction of hierarchical architectures for high-performance computing</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
\htmlonly
|
||||
<div class="section" id="introduction">
|
||||
\endhtmlonly
|
||||
\section Introduction
|
||||
|
||||
hwloc provides command line tools and a C API to obtain the
|
||||
hierarchical map of key computing elements, such as: NUMA memory
|
||||
nodes, shared caches, processor sockets, processor cores, and
|
||||
processing units (logical processors or "threads").
|
||||
hwloc also gathers various attributes such as
|
||||
cache and memory information, and is portable across a variety of
|
||||
different operating systems and platforms.
|
||||
|
||||
hwloc primarily aims at helping high-performance computing (HPC)
|
||||
applications, but is also applicable to any project seeking to exploit
|
||||
code and/or data locality on modern computing platforms.
|
||||
|
||||
*** Note that the hwloc project represents the merger of the
|
||||
libtopology project from INRIA and the Portable Linux Processor
|
||||
Affinity (PLPA) sub-project from Open MPI. <em>Both of these prior
|
||||
projects are now deprecated.</em> The first hwloc release is essentially a
|
||||
"re-branding" of the libtopology code base, but with both a few
|
||||
genuinely new features and a few PLPA-like features added in. More
|
||||
new features and more PLPA-like features will be added to hwloc over
|
||||
time. See \ref switchfromplpa for more details about converting
|
||||
your application from PLPA to hwloc.
|
||||
|
||||
hwloc supports the following operating systems:
|
||||
|
||||
<ul>
|
||||
<li>Linux (including old kernels not having sysfs topology
|
||||
information, with knowledge of cpusets, offline cpus, ScaleMP vSMP,
|
||||
and Kerrighed support)</li>
|
||||
<li>Solaris</li>
|
||||
<li>AIX</li>
|
||||
<li>Darwin / OS X</li>
|
||||
<li>FreeBSD and its variants, such as kFreeBSD/GNU</li>
|
||||
<li>OSF/1 (a.k.a., Tru64)</li>
|
||||
<li>HP-UX</li>
|
||||
<li>Microsoft Windows</li>
|
||||
</ul>
|
||||
|
||||
hwloc only reports the number of processors on unsupported operating
|
||||
systems; no topology information is available.
|
||||
|
||||
For development and debugging purposes, hwloc also offers the ability to
|
||||
work on "fake" topologies:
|
||||
|
||||
<ul>
|
||||
<li> Symmetrical tree of resources generated from a list of level arities</li>
|
||||
<li> Remote machine simulation through the gathering of Linux sysfs topology files</li>
|
||||
</ul>
|
||||
|
||||
hwloc can display the topology in a human-readable format, either in
|
||||
graphical mode (X11), or by exporting in one of several different
|
||||
formats, including: plain text, PDF, PNG, and FIG (see Examples
|
||||
below). Note that some of the export formats require additional
|
||||
support libraries.
|
||||
|
||||
hwloc offers a programming interface for manipulating topologies and
|
||||
objects. It also brings a powerful CPU bitmap API that is used to
|
||||
describe topology objects location on physical/logical processors. See
|
||||
the \ref interface below. It may also be used to binding applications
|
||||
onto certain cores or memory nodes. Several utility programs are also
|
||||
provided to ease command-line manipulation of topology objects,
|
||||
binding of processes, and so on.
|
||||
|
||||
\htmlonly
|
||||
</div><div class="section" id="installation">
|
||||
\endhtmlonly
|
||||
\section installation Installation
|
||||
|
||||
hwloc (http://www.open-mpi.org/projects/hwloc/) is available under the
|
||||
BSD license. It is hosted as a sub-project of the overall Open MPI
|
||||
project (http://www.open-mpi.org/). Note that hwloc does not require
|
||||
any functionality from Open MPI -- it is a wholly separate (and much
|
||||
smaller!) project and code base. It just happens to be hosted as part
|
||||
of the overall Open MPI project.
|
||||
|
||||
Nightly development snapshots are available on the web site.
|
||||
Additionally, the code can be directly checked out of Subversion:
|
||||
|
||||
\code
|
||||
shell$ svn checkout http://svn.open-mpi.org/svn/hwloc/trunk hwloc-trunk
|
||||
shell$ cd hwloc-trunk
|
||||
shell$ ./autogen.sh
|
||||
\endcode
|
||||
|
||||
Note that GNU Autoconf >=2.63, Automake >=1.10 and Libtool >=2.2.6 are
|
||||
required when building from a Subversion checkout.
|
||||
|
||||
Installation by itself is the fairly common GNU-based process:
|
||||
|
||||
\code
|
||||
shell$ ./configure --prefix=...
|
||||
shell$ make
|
||||
shell$ make install
|
||||
\endcode
|
||||
|
||||
The hwloc command-line tool "lstopo" produces human-readable topology
|
||||
maps, as mentioned above. It can also export maps to the "fig" file
|
||||
format. Support for PDF, Postscript, and PNG exporting is provided if
|
||||
the "Cairo" development package can be found when hwloc is configured
|
||||
and build. Similarly, lstopo's XML support requires the libxml2
|
||||
development package.
|
||||
|
||||
\htmlonly
|
||||
</div><div class="section" id="examples">
|
||||
\endhtmlonly
|
||||
\section examples Examples
|
||||
|
||||
On a 4-socket 2-core machine with hyperthreading, the \c lstopo tool
|
||||
may show the following outputs:
|
||||
|
||||
\image html dudley.png
|
||||
\image latex dudley.png "" width=9cm
|
||||
|
||||
\verbatim
|
||||
Machine (16GB)
|
||||
Socket #0 + L3 #0 (4096KB)
|
||||
L2 #0 (1024KB) + L1 #0 (16KB) + Core #0
|
||||
PU #0 (phys=0)
|
||||
PU #1 (phys=8)
|
||||
L2 #1 (1024KB) + L1 #1 (16KB) + Core #1
|
||||
PU #2 (phys=4)
|
||||
PU #3 (phys=12)
|
||||
Socket #1 + L3 #1 (4096KB)
|
||||
L2 #2 (1024KB) + L1 #2 (16KB) + Core #2
|
||||
PU #4 (phys=1)
|
||||
PU #5 (phys=9)
|
||||
L2 #3 (1024KB) + L1 #3 (16KB) + Core #3
|
||||
PU #6 (phys=5)
|
||||
PU #7 (phys=13)
|
||||
Socket #2 + L3 #2 (4096KB)
|
||||
L2 #4 (1024KB) + L1 #4 (16KB) + Core #4
|
||||
PU #8 (phys=2)
|
||||
PU #9 (phys=10)
|
||||
L2 #5 (1024KB) + L1 #5 (16KB) + Core #5
|
||||
PU #10 (phys=6)
|
||||
PU #11 (phys=14)
|
||||
Socket #3 + L3 #3 (4096KB)
|
||||
L2 #6 (1024KB) + L1 #6 (16KB) + Core #6
|
||||
PU #12 (phys=3)
|
||||
PU #13 (phys=11)
|
||||
L2 #7 (1024KB) + L1 #7 (16KB) + Core #7
|
||||
PU #14 (phys=7)
|
||||
PU #15 (phys=15)
|
||||
\endverbatim
|
||||
|
||||
On a 4-socket 2-core Opteron NUMA machine, the \c lstopo tool may
|
||||
show the following outputs:
|
||||
|
||||
\image html hagrid.png
|
||||
\image latex hagrid.png width=\textwidth
|
||||
|
||||
\verbatim
|
||||
Machine (64GB)
|
||||
NUMANode #0 (phys=0 8190MB) + Socket #0
|
||||
L2 #0 (1024KB) + L1 #0 (64KB) + Core #0 + PU #0 (phys=0)
|
||||
L2 #1 (1024KB) + L1 #1 (64KB) + Core #1 + PU #1 (phys=1)
|
||||
NUMANode #1 (phys=1 8192MB) + Socket #1
|
||||
L2 #2 (1024KB) + L1 #2 (64KB) + Core #2 + PU #2 (phys=2)
|
||||
L2 #3 (1024KB) + L1 #3 (64KB) + Core #3 + PU #3 (phys=3)
|
||||
NUMANode #2 (phys=2 8192MB) + Socket #2
|
||||
L2 #4 (1024KB) + L1 #4 (64KB) + Core #4 + PU #4 (phys=4)
|
||||
L2 #5 (1024KB) + L1 #5 (64KB) + Core #5 + PU #5 (phys=5)
|
||||
NUMANode #3 (phys=3 8192MB) + Socket #3
|
||||
L2 #6 (1024KB) + L1 #6 (64KB) + Core #6 + PU #6 (phys=6)
|
||||
L2 #7 (1024KB) + L1 #7 (64KB) + Core #7 + PU #7 (phys=7)
|
||||
NUMANode #4 (phys=4 8192MB) + Socket #4
|
||||
L2 #8 (1024KB) + L1 #8 (64KB) + Core #8 + PU #8 (phys=8)
|
||||
L2 #9 (1024KB) + L1 #9 (64KB) + Core #9 + PU #9 (phys=9)
|
||||
NUMANode #5 (phys=5 8192MB) + Socket #5
|
||||
L2 #10 (1024KB) + L1 #10 (64KB) + Core #10 + PU #10 (phys=10)
|
||||
L2 #11 (1024KB) + L1 #11 (64KB) + Core #11 + PU #11 (phys=11)
|
||||
NUMANode #6 (phys=6 8192MB) + Socket #6
|
||||
L2 #12 (1024KB) + L1 #12 (64KB) + Core #12 + PU #12 (phys=12)
|
||||
L2 #13 (1024KB) + L1 #13 (64KB) + Core #13 + PU #13 (phys=13)
|
||||
NUMANode #7 (phys=7 8192MB) + Socket #7
|
||||
L2 #14 (1024KB) + L1 #14 (64KB) + Core #14 + PU #14 (phys=14)
|
||||
L2 #15 (1024KB) + L1 #15 (64KB) + Core #15 + PU #15 (phys=15)
|
||||
\endverbatim
|
||||
|
||||
On a 2-socket quad-core Xeon (pre-Nehalem, with 2 dual-core dies into
|
||||
each socket):
|
||||
|
||||
\image html emmett.png
|
||||
\image latex emmett.png "" width=7cm
|
||||
|
||||
\verbatim
|
||||
Machine (16GB)
|
||||
Socket #0
|
||||
L2 #0 (4096KB)
|
||||
L1 #0 (32KB) + Core #0 + PU #0 (phys=0)
|
||||
L1 #1 (32KB) + Core #1 + PU #1 (phys=4)
|
||||
L2 #1 (4096KB)
|
||||
L1 #2 (32KB) + Core #2 + PU #2 (phys=2)
|
||||
L1 #3 (32KB) + Core #3 + PU #3 (phys=6)
|
||||
Socket #1
|
||||
L2 #2 (4096KB)
|
||||
L1 #4 (32KB) + Core #4 + PU #4 (phys=1)
|
||||
L1 #5 (32KB) + Core #5 + PU #5 (phys=5)
|
||||
L2 #3 (4096KB)
|
||||
L1 #6 (32KB) + Core #6 + PU #6 (phys=3)
|
||||
L1 #7 (32KB) + Core #7 + PU #7 (phys=7)
|
||||
\endverbatim
|
||||
|
||||
\htmlonly
|
||||
</div><div class="section" id="interface">
|
||||
\endhtmlonly
|
||||
|
||||
\section interface 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. Developers should
|
||||
also look at hwloc/helper.h, which provides good higher-level topology
|
||||
traversal examples.
|
||||
|
||||
Each object contains a cpuset describing the list of processing units that
|
||||
it contains. These cpusets may be used for \ref hwlocality_binding.
|
||||
hwloc offers an extensive cpuset manipulation interface in
|
||||
hwloc/cpuset.h.
|
||||
|
||||
Moreover, hwloc also comes with additional helpers for
|
||||
interoperability with several commonly used environments.
|
||||
See the \ref interoperability section for details.
|
||||
|
||||
To precisely define the vocabulary used by hwloc, a \ref termsanddefs
|
||||
section is available and should probably be read first.
|
||||
|
||||
Further documentation is available in a full set of HTML pages, man
|
||||
pages, and self-contained PDF files (formatted for both both US letter
|
||||
and A4 formats) in the source tarball in doc/doxygen-doc/. If you are
|
||||
building from a Subversion checkout, you will need to have Doxygen and
|
||||
pdflatex installed -- the documentation will be built during the
|
||||
normal "make" process. The documentation is installed during "make
|
||||
install" to $prefix/share/doc/hwloc/ and your systems default man page
|
||||
tree (under $prefix, of course).
|
||||
|
||||
The following section presents an example of API usage.
|
||||
|
||||
\section interface_example API example
|
||||
|
||||
The following small C example (named ``hwloc-hello.c'') prints the
|
||||
topology of the machine and bring the process to the first logical processor
|
||||
of the second core of the machine.
|
||||
|
||||
\include hwloc-hello.c
|
||||
|
||||
hwloc provides a \c pkg-config executable to obtain relevant compiler
|
||||
and linker flags. For example, it can be used thusly to compile
|
||||
applications that utilize the hwloc library (assuming GNU Make):
|
||||
|
||||
\verbatim
|
||||
CFLAGS += $(pkg-config --cflags hwloc)
|
||||
LDLIBS += $(pkg-config --libs hwloc)
|
||||
cc hwloc-hello.c $(CFLAGS) -o hwloc-hello $(LDLIBS)
|
||||
\endverbatim
|
||||
|
||||
On a machine with 4GB of RAM and 2 processor sockets -- each socket of
|
||||
which has two processing cores -- the output from running \c
|
||||
hwloc-hello could be something like the following:
|
||||
|
||||
\verbatim
|
||||
shell$ ./hwloc-hello
|
||||
*** Objects at level 0
|
||||
Index 0: Machine(3938MB)
|
||||
*** Objects at level 1
|
||||
Index 0: Socket#0
|
||||
Index 1: Socket#1
|
||||
*** Objects at level 2
|
||||
Index 0: Core#0
|
||||
Index 1: Core#1
|
||||
Index 2: Core#3
|
||||
Index 3: Core#2
|
||||
*** Objects at level 3
|
||||
Index 0: PU#0
|
||||
Index 1: PU#1
|
||||
Index 2: PU#2
|
||||
Index 3: PU#3
|
||||
*** Printing overall tree
|
||||
Machine(3938MB)
|
||||
Socket#0
|
||||
Core#0
|
||||
PU#0
|
||||
Core#1
|
||||
PU#1
|
||||
Socket#1
|
||||
Core#3
|
||||
PU#2
|
||||
Core#2
|
||||
PU#3
|
||||
*** 2 socket(s)
|
||||
shell$
|
||||
\endverbatim
|
||||
|
||||
\htmlonly
|
||||
</div><div class="section" id="bugs">
|
||||
\endhtmlonly
|
||||
\section bugs Questions and bugs
|
||||
|
||||
Questions should be sent to the devel mailing
|
||||
list (http://www.open-mpi.org/community/lists/hwloc.php).
|
||||
Bug reports should be reported in the tracker
|
||||
(https://svn.open-mpi.org/trac/hwloc/).
|
||||
|
||||
If hwloc discovers an incorrect topology for your machine, the very
|
||||
first thing you should check is to ensure that you have the most
|
||||
recent updates installed for your operating system. Indeed, most of
|
||||
hwloc topology discovery relies on hardware information retrieved
|
||||
through the operation system (e.g., via the /sys virtual filesystem of
|
||||
the Linux kernel). If upgrading your OS or Linux kernel does not
|
||||
solve your problem, you may also want to ensure that you are running
|
||||
the most recent version of the BIOS for your machine.
|
||||
|
||||
If those things fail, contact us on the mailing list for additional
|
||||
help. Please attach the output of lstopo after having given the
|
||||
--enable-debug option to ./configure and rebuilt completely, to get
|
||||
debugging output.
|
||||
|
||||
\htmlonly
|
||||
</div><div class="section" id="credits">
|
||||
\endhtmlonly
|
||||
\section history History / credits
|
||||
|
||||
hwloc is the evolution and merger of the libtopology
|
||||
(http://runtime.bordeaux.inria.fr/libtopology/) project and the Portable
|
||||
Linux Processor Affinity (PLPA) (http://www.open-mpi.org/projects/plpa/)
|
||||
project. Because of functional and ideological overlap, these two code bases
|
||||
and ideas were merged and released under the name "hwloc" as an Open MPI
|
||||
sub-project.
|
||||
|
||||
libtopology was initially developed by the INRIA Runtime Team-Project
|
||||
(http://runtime.bordeaux.inria.fr/) (headed by Raymond Namyst
|
||||
(http://dept-info.labri.fr/~namyst/). PLPA was initially developed by
|
||||
the Open MPI development team as a sub-project. Both are now deprecated
|
||||
in favor of hwloc, which is distributed as an Open MPI sub-project.
|
||||
|
||||
\htmlonly
|
||||
</div>
|
||||
\endhtmlonly
|
||||
|
||||
|
||||
|
||||
\page termsanddefs Terms and Definitions
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>Object</dt>
|
||||
<dd>Interesting kind of part of the system, such as a Core, a Cache,
|
||||
a Memory node, etc. The different types detected by hwloc are
|
||||
detailed in the ::hwloc_obj_type_t enumeration.
|
||||
|
||||
They are topologically sorted by CPU set into a tree.
|
||||
</dd>
|
||||
|
||||
<dt>CPU set</dt>
|
||||
<dd>The set of logical processors (or processing units) logically included in an object
|
||||
(if it makes sense). They are always expressed using physical logical
|
||||
processor numbers (as announced by the OS). They are just masks, they do \em
|
||||
not have any relation with an operating system actual binding notion like
|
||||
Linux' cpusets.</dd>
|
||||
|
||||
<dt>Parent object</dt>
|
||||
<dd>The object logically containing the current object, for example
|
||||
because its CPU set includes the CPU set of the current object.</dd>
|
||||
|
||||
<dt>Ancestor object</dt>
|
||||
<dd>The parent object, or its own parent object, and so on.</dd>
|
||||
|
||||
<dt>Children object(s)</dt>
|
||||
<dd>The object (or objects) contained in the current object because
|
||||
their CPU set is included in the CPU set of the current object.</dd>
|
||||
|
||||
<dt>Arity</dt>
|
||||
<dd>The number of children of an object.</dd>
|
||||
|
||||
<dt>Sibling objects</dt>
|
||||
<dd>Objects of the same type which have the same parent.</dd>
|
||||
|
||||
<dt>Sibling rank</dt>
|
||||
<dd>Index to uniquely identify objects of the same type which have
|
||||
the same parent, and is always in the range [0, parent_arity).</dd>
|
||||
|
||||
<dt>Cousin objects</dt>
|
||||
<dd>Objects of the same type as the current object.</dd>
|
||||
|
||||
<dt>Level</dt>
|
||||
<dd>Set of objects of the same type.</dd>
|
||||
|
||||
<dt>OS index</dt>
|
||||
<dd>The index that the operating system (OS) uses to identify the
|
||||
object. This may be completely arbitrary, or it may depend on the
|
||||
BIOS configuration.</dd>
|
||||
|
||||
<dt>Depth</dt>
|
||||
<dd>Nesting level in the object tree, starting from the 0th object.</dd>
|
||||
|
||||
<dt>Logical index</dt>
|
||||
<dd>Index to uniquely identify objects of the same type. It
|
||||
expresses proximity in a generic way. This index is always linear
|
||||
and in the range [0, num_objs_same_type_same_level). Think of it
|
||||
as ``cousin rank.'' The ordering is based on topology first, and
|
||||
then on OS CPU numbers, so it is stable across everything except
|
||||
firmware CPU renumbering.</dd>
|
||||
|
||||
<dt>Logical processor</dt>
|
||||
<dt>Processing unit</dt>
|
||||
<dd>The smallest processing element that can be represented by a hwloc
|
||||
object. It may be a single-core processor, a core of a multicore
|
||||
processor, or a single thread in SMT processor.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
The following diagram can help to understand the vocabulary of the relationships
|
||||
by showing the example of a machine with two dual core sockets (with no
|
||||
hardware threads); thus, a topology with 4 levels. Each box with rounded corner
|
||||
corresponds to one hwloc_obj_t, containing the values of the different integer
|
||||
fields (depth, logical_index, etc.), and arrows show to which other hwloc_obj_t
|
||||
pointers point to (first_child, parent, etc.)
|
||||
|
||||
\image html diagram.png
|
||||
\image latex diagram.eps width=\textwidth
|
||||
|
||||
It should be noted that for PU objects, the logical index -- as
|
||||
computed linearly by hwloc -- is not the same as the OS index.
|
||||
|
||||
|
||||
|
||||
\page tools Command-line tools
|
||||
|
||||
hwloc comes with an extensive C programming interface and several
|
||||
command line utilities. Each of them is fully documented in its own
|
||||
manual page; the following is a summary of the available command line
|
||||
tools.
|
||||
|
||||
\section cli_lstopo lstopo
|
||||
|
||||
lstopo (also known as hwloc-info and hwloc-ls) displays the
|
||||
hierarchical topology map of the current system. The output may be
|
||||
graphic or textual, and can also be exported to numerous file
|
||||
formats such as PDF, PNG, XML, and others.
|
||||
|
||||
Note that lstopo can read XML files and/or alternate chroot
|
||||
filesystems and display topological maps representing those systems
|
||||
(e.g., use lstopo to output an XML file on one system, and then use
|
||||
lstopo to read in that XML file and display it on a different system).
|
||||
|
||||
\section cli_hwloc_bind hwloc-bind
|
||||
|
||||
hwloc-bind binds processes to specific hardware objects through a
|
||||
flexible syntax. A simple example is binding an executable to
|
||||
specific cores (or sockets or cpusets or ...). The hwloc-bind(1) man
|
||||
page provides much more detail on what is possible.
|
||||
|
||||
hwloc-bind can also be used to retrieve the current process' binding.
|
||||
|
||||
\section cli_hwloc_calc hwloc-calc
|
||||
|
||||
hwloc-calc is generally used to create cpuset strings to pass to
|
||||
hwloc-bind. Although hwloc-bind accepts many forms of object
|
||||
specification (i.e., cpuset strings are one of many forms that
|
||||
hwloc-bind understands), they can be useful, compact representations
|
||||
in shell scripts, for example.
|
||||
|
||||
hwloc-calc generates cpuset strings from given hardware objects with
|
||||
the ability to aggregate them, intersect them, and more. hwloc-calc
|
||||
generally uses the same syntax than hwloc-bind, but multiple instances
|
||||
may be composed to generate complex combinations.
|
||||
|
||||
Note that hwloc-calc can also generate lists of logical processors or
|
||||
NUMA nodes that are convenient to pass to some external tools such as
|
||||
taskset or numactl.
|
||||
|
||||
\section cli_hwloc_distrib hwloc-distrib
|
||||
|
||||
hwloc-distrib generates a set of cpuset strings that are uniformly
|
||||
distributed across the machine for the given number of processes.
|
||||
These strings may be used with hwloc-bind to run processes to maximize
|
||||
their memory bandwidth by properly distributing them across the
|
||||
machine.
|
||||
|
||||
|
||||
|
||||
\page envvar Environment variables
|
||||
|
||||
The behavior of the hwloc library and tools may be tuned thanks to the
|
||||
following environment variables.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>HWLOC_XMLFILE=/path/to/file.xml</dt>
|
||||
<dd>enforces the discovery from the given XML file as if
|
||||
hwloc_topology_set_xml() had been called.
|
||||
This file may have been generated earlier with lstopo file.xml.
|
||||
For convenience, this backend provides empty binding hooks which just
|
||||
return success. To have hwloc still actually call OS-specific hooks,
|
||||
HWLOC_THISSYSTEM should be set 1 in the environment too, to assert that
|
||||
the loaded file is really the underlying system.
|
||||
</dd>
|
||||
|
||||
<dt>HWLOC_FSROOT=/path/to/linux/filesystem-root/</dt>
|
||||
<dd>switches to reading the topology from the specified
|
||||
Linux filesystem root instead of the main file-system root, as if
|
||||
hwloc_topology_set_fsroot() had been called.
|
||||
Not using the main file-system root causes hwloc_topology_is_thissystem()
|
||||
to return 0.
|
||||
For convenience, this backend provides empty binding hooks which just
|
||||
return success. To have hwloc still actually call OS-specific hooks,
|
||||
HWLOC_THISSYSTEM should be set 1 in the environment too, to assert that
|
||||
the loaded file is really the underlying system.
|
||||
</dd>
|
||||
|
||||
<dt>HWLOC_THISSYSTEM=1</dt>
|
||||
<dd>enforces the return value of hwloc_topology_is_thissystem().
|
||||
It means that it makes hwloc assume that the selected backend provides the
|
||||
topology for the system on which we are running, even if it is not the
|
||||
OS-specific backend but the XML backend for instance.
|
||||
This means making the binding functions actually call the OS-specific
|
||||
system calls and really do binding, while the XML backend would otherwise
|
||||
provide empty hooks just returning success.
|
||||
This can be used for efficiency reasons to first detect the topology once,
|
||||
save it to an XML file, and quickly reload it later through the XML
|
||||
backend, but still having binding functions actually do bind.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
\page interoperability Interoperability with other software
|
||||
|
||||
Although hwloc offers its own portable interface, it still may have to
|
||||
interoperate with specific or non-portable libraries that manipulate
|
||||
similar kinds of objects. hwloc therefore offers several specific
|
||||
"helpers" to assist converting between those specific interfaces and
|
||||
hwloc.
|
||||
|
||||
Some external libraries may be specific to a particular OS; others may
|
||||
not always be available. The hwloc core therefore generally does not
|
||||
explicitly depend on these types of libraries. However, when a custom
|
||||
application uses or otherwise depends on such a library, it may
|
||||
optionally include the corresponding hwloc helper to extend the hwloc
|
||||
interface with dedicated helpers.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>Linux specific features</dt>
|
||||
<dd>
|
||||
hwloc/linux.h offers Linux-specific helpers that utilize some
|
||||
non-portable features of the Linux system, such as binding threads
|
||||
through their thread ID ("tid") or parsing kernel CPU mask files.
|
||||
</dd>
|
||||
|
||||
<dt>Linux libnuma</dt>
|
||||
<dd>
|
||||
hwloc/linux-libnuma.h provides conversion helpers between hwloc CPU
|
||||
sets and libnuma-specific types, such as nodemasks and bitmasks. It
|
||||
helps you use libnuma memory-binding functions with hwloc CPU sets.
|
||||
</dd>
|
||||
|
||||
<dt>Glibc</dt>
|
||||
<dd>
|
||||
hwloc/glibc-sched.h offers conversion routines between Glibc and
|
||||
hwloc CPU sets in order to use hwloc with functions such as
|
||||
sched_setaffinity().
|
||||
</dd>
|
||||
|
||||
<dt>OpenFabrics Verbs</dt>
|
||||
<dd>
|
||||
hwloc/openfabrics-verbs.h helps interoperability with the
|
||||
OpenFabrics Verbs interface. For example, it can return a list of
|
||||
processors near an OpenFabrics device.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
\page threadsafety Thread safety
|
||||
|
||||
Like most libraries that mainly fill data structures, hwloc is not
|
||||
thread safe but rather reentrant: all state is held in a \ref
|
||||
hwloc_topology_t instance without mutex protection. That means, for
|
||||
example, that two threads can safely operate on and modify two
|
||||
different \ref hwloc_topology_t instances, but they should not
|
||||
simultaneously invoke functions that modify the <em>same</em>
|
||||
instance. Similarly, one thread should not modify a \ref
|
||||
hwloc_topology_t instance while another thread is reading or
|
||||
traversing it. However, two threads can safely read or traverse the
|
||||
same \ref hwloc_topology_t instance concurrently.
|
||||
|
||||
When running in multiprocessor environments, be aware that proper thread
|
||||
synchronization and/or memory coherency protection is needed to pass hwloc
|
||||
data (such as \ref hwloc_topology_t pointers) from one processor
|
||||
to another (e.g., a mutex, semaphore, or a memory barrier).
|
||||
Note that this is not a hwloc-specific requirement, but it is worth
|
||||
mentioning.
|
||||
|
||||
For reference, \ref hwloc_topology_t modification operations include
|
||||
(but may not be limited to):
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>Creation and destruction</dt>
|
||||
<dd><tt>hwloc_topology_init(), hwloc_topology_load(),
|
||||
hwloc_topology_destroy()</tt> (see \ref hwlocality_creation) imply
|
||||
major modifications of the structure, including freeing some
|
||||
objects. No other thread cannot access the topology or any of its
|
||||
objects at the same time.
|
||||
|
||||
Also references to objects inside the topology are not valid anymore
|
||||
after these functions return. </dd>
|
||||
|
||||
<dt>Runtime topology modifications</dt>
|
||||
<dd><tt>hwloc_topology_insert_misc_object_by_*</tt> (see \ref
|
||||
hwlocality_tinker) may modify the topology significantly by adding
|
||||
objects inside the tree, changing the topology depth, etc.
|
||||
|
||||
Although references to former objects <em>may</em> still be valid
|
||||
after insertion, it is strongly advised to not rely on any such
|
||||
guarantee and always re-consult the topology to reacquire new
|
||||
instances of objects. </dd>
|
||||
|
||||
<dt>Locating topologies</dt>
|
||||
|
||||
<dd><tt>hwloc_topology_ignore*</tt>, <tt>hwloc_topology_set*</tt>
|
||||
(see \ref hwlocality_configuration) do not modify the topology
|
||||
directly, but they do modify internal structures describing the
|
||||
behavior of the next invocation of <tt>hwloc_topology_load()</tt>.
|
||||
Hence, all of these functions should not be used concurrently.
|
||||
|
||||
Note that these functions do not modify the current topology until
|
||||
it is actually reloaded; it is possible to use them while other
|
||||
threads are only read the current topology. </dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
\page embed Embedding hwloc in other software
|
||||
|
||||
It can be desirable to include hwloc in a larger software package (be
|
||||
sure to check out the LICENSE file) so that users don't have to
|
||||
separately download and install it before installing your software.
|
||||
This can be advantageous to ensure that your software uses a
|
||||
known-tested/good version of hwloc, or for use on systems that do not
|
||||
have hwloc pre-installed.
|
||||
|
||||
When used in "embedded" mode, hwloc will:
|
||||
|
||||
- not install any header files
|
||||
- not build any documentation files
|
||||
- not build or install any executables or tests
|
||||
- not build <tt>libhwloc.*</tt> -- instead, it will build
|
||||
<tt>libhwloc_embedded.*</tt>
|
||||
|
||||
There are two ways to put hwloc into "embedded" mode. The first is
|
||||
directly from the configure command line:
|
||||
|
||||
\verbatim
|
||||
shell$ ./configure --enable-embedded-mode ...
|
||||
\endverbatim
|
||||
|
||||
The second requires that your software project uses the GNU Autoconf /
|
||||
Automake / Libtool tool chain to build your software. If you do this,
|
||||
you can directly integrate hwloc's m4 configure macro into your
|
||||
configure script. You can then invoke hwloc's configuration tests and
|
||||
build setup by calling an m4 macro (see below).
|
||||
|
||||
\section embedding_m4 Using hwloc's m4 embedding capabilities
|
||||
|
||||
Every project is different, and there are many different ways of
|
||||
integrating hwloc into yours. What follows is <em>one</em> example of
|
||||
how to do it.
|
||||
|
||||
If your project uses recent versions Autoconf, Automake, and Libtool
|
||||
to build, you can use hwloc's embedded m4 capabilities. We have
|
||||
tested the embedded m4 with projects that use Autoconf 2.65, Automake
|
||||
1.11.1, and Libtool 2.2.6b. Slightly earlier versions of may also
|
||||
work but are untested. Autoconf versions prior to 2.63 are almost
|
||||
certain to not work because hwloc uses macros that were introduced in
|
||||
2.63.
|
||||
|
||||
You can either copy all the config/hwloc*m4 files from the hwloc
|
||||
source tree to the directory where your project's m4 files reside, or
|
||||
you can tell aclocal to find more m4 files in the embedded hwloc's
|
||||
"config" subdirectory (e.g., add "-Ipath/to/embedded/hwloc/config" to
|
||||
your Makefile.am's ACLOCAL_AMFLAGS).
|
||||
|
||||
The following macros can then be used from your configure script (only
|
||||
HWLOC_INIT <em>must</em> be invoked if using the m4 macros):
|
||||
|
||||
- HWLOC_INIT(config-dir-prefix, action-upon-success,
|
||||
action-upon-failure): Invoke the hwloc configuration tests and setup
|
||||
the hwloc tree to build. The first argument is the prefix to use
|
||||
for AC_OUTPUT files -- it's where the hwloc tree is located relative
|
||||
to <tt>$top_srcdir</tt>. Hence, if your embedded hwloc is located
|
||||
in the source tree at contrib/hwloc, you should pass
|
||||
<tt>[contrib/hwloc]</tt> as the first argument. If HWLOC_INIT and
|
||||
the rest of <tt>configure</tt> completes successfully, then "make"
|
||||
traversals of the hwloc tree with standard Automake targets (all,
|
||||
clean, install, etc.) should behave as expected. For example, it is
|
||||
safe to list the hwloc directory in the SUBDIRS of a higher-level
|
||||
Makefile.am. <strong>NOTE: If the HWLOC_SET_SYMBOL_PREFIX macro is
|
||||
used, it must be invoked <em>before</em> HWLOC_INIT.</strong>
|
||||
|
||||
- HWLOC_SET_SYMBOL_PREFIX(foo_): Tells the hwloc to prefix all of
|
||||
hwloc's types and public symbols with "foo_"; meaning that function
|
||||
hwloc_init() becomes foo_hwloc_init(). Enum values are prefixed
|
||||
with an upper-case translation if the prefix supplied;
|
||||
HWLOC_OBJ_SYSTEM becomes FOO_HWLOC_OBJ_SYSTEM. This is recommended
|
||||
behavior if you are including hwloc in middleware -- it is possible
|
||||
that your software will be combined with other software that links
|
||||
to another copy of hwloc. If both uses of hwloc utilize different
|
||||
symbol prefixes, there will be no type/symbol clashes, and
|
||||
everything will compile, link, and run successfully. If you both
|
||||
embed hwloc without changing the symbol prefix and also link against
|
||||
an external hwloc, you may get multiple symbol definitions when
|
||||
linking your final library or application.
|
||||
|
||||
- HWLOC_DO_AM_CONDITIONALS: If you embed hwloc in a larger project and
|
||||
build it conditionally (e.g., if HWLOC_INIT is invoked
|
||||
conditionally), you must unconditionally invoke
|
||||
HWLOC_DO_AM_CONDITIONALS to avoid warnings from Automake (for the
|
||||
cases where hwloc is not selected to be built). This macro is
|
||||
necessary because hwloc uses some AM_CONDITIONALs to build itself,
|
||||
and AM_CONDITIONALs cannot be defined conditionally. Note that it
|
||||
is safe (but unnecessary) to call HWLOC_DO_AM_CONDITIONALS even if
|
||||
HWLOC_INIT is invoked unconditionally.
|
||||
|
||||
NOTE: When using the HWLOC_INIT m4 macro, it may be necessary to
|
||||
explicitly invoke AC_CANONICAL_TARGET and/or AC_USE_SYSTEM_EXTENSIONS
|
||||
macros early in the configure script (e.g., after AC_INIT but before
|
||||
AM_INIT_AUTOMAKE). See the Autoconf documentation for further
|
||||
information.
|
||||
|
||||
|
||||
\section embedding_example Example embedding hwloc
|
||||
|
||||
Here's an example of integrating with a larger project named sandbox
|
||||
that already uses Autoconf, Automake, and Libtool to build itself:
|
||||
|
||||
\verbatim
|
||||
# First, cd into the sandbox project source tree
|
||||
shell$ cd sandbox
|
||||
shell$ cp -r /somewhere/else/hwloc-<version> my-embedded-hwloc
|
||||
shell$ edit Makefile.am
|
||||
1. Add "-Imy-embedded-hwloc/config" to ACLOCAL_AMFLAGS
|
||||
2. Add "my-embedded-hwloc" to SUBDIRS
|
||||
3. Add "$(HWLOC_EMBEDDED_LDADD)" and "$(HWLOC_EMBEDDED_LIBS)" to
|
||||
sandbox's executable's LDADD line. The former is the name of the
|
||||
Libtool convenience library that hwloc will generate. The latter
|
||||
is any dependent support libraries that may be needed by
|
||||
$(HWLOC_EMBEDDED_LDADD).
|
||||
4. Add "$(HWLOC_EMBEDDED_CPPFLAGS)" to AM_CPPFLAGS
|
||||
shell$ edit configure.ac
|
||||
1. Add "HWLOC_SET_SYMBOL_PREFIX(sandbox_hwloc_)" line
|
||||
2. Add "HWLOC_INIT([my-embedded-hwloc], [happy=yes], [happy=no])" line
|
||||
3. Add error checking for happy=no case
|
||||
shell$ edit sandbox.c
|
||||
1. Add #include <hwloc.h>
|
||||
2. Add calls to sandbox_hwloc_init() and other hwloc API functions
|
||||
\endverbatim
|
||||
|
||||
Now you can bootstrap, configure, build, and run the sandbox as normal
|
||||
-- all calls to "sandbox_hwloc_*" will use the embedded hwloc rather
|
||||
than any system-provided copy of hwloc.
|
||||
|
||||
|
||||
|
||||
\page switchfromplpa Switching from PLPA to hwloc
|
||||
|
||||
Although PLPA and hwloc share some of the same ideas, their
|
||||
programming interfaces are quite different. After much debate, it was
|
||||
decided <em>not</em> to emulate the PLPA API with hwloc's API because
|
||||
hwloc's API is already far more rich than PLPA's.
|
||||
|
||||
More specifically, exploiting modern computing architecture
|
||||
<em>requires</em> the flexible functionality provided by the hwloc API
|
||||
-- the PLPA API is too rigid in its definitions and practices to
|
||||
handle the evolving server hardware landscape (e.g., PLPA only
|
||||
understands cores and sockets; hwloc understands a much larger set
|
||||
of hardware objects).
|
||||
|
||||
As such, even though it is fully possible to emulate the PLPA API with
|
||||
hwloc (e.g., only deal with sockets and cores), and while the
|
||||
documentation below describes how to do this, we encourage any
|
||||
existing PLPA application authors to actually re-think their
|
||||
application in terms of more than just sockets and cores. In short,
|
||||
we encourage you to use the full hwloc API to exploit <em>all</em> the
|
||||
hardware.
|
||||
|
||||
|
||||
\section switchfromplpa_caching Topology context vs. caching
|
||||
|
||||
First, all hwloc functions take a \p topology parameter. This
|
||||
parameter serves as an internal storage for the result of the topology
|
||||
discovery. It replaces PLPA's caching abilities and even lets you
|
||||
manipulate multiple topologies as the same time, if needed.
|
||||
|
||||
Thus, all programs should first run hwloc_topology_init() and
|
||||
hwloc_topology_destroy() as they did plpa_init() and plpa_finalize()
|
||||
in the past.
|
||||
|
||||
|
||||
\section switchfromplpa_hierarchy Hierarchy vs. Core@Socket
|
||||
|
||||
PLPA was designed to understand only cores and sockets. hwloc offers
|
||||
many more different types of objects (e.g., cores, sockets, hardware
|
||||
threads, NUMA nodes, and others) and stores them within a tree of
|
||||
resources.
|
||||
|
||||
To emulate the PLPA model, it is possible to find sockets using
|
||||
functions such as hwloc_get_obj_by_type(). Iterating over sockets is
|
||||
also possible using hwloc_get_next_obj_by_type(). Then, finding a
|
||||
core within a socket may be done using
|
||||
hwloc_get_obj_inside_cpuset_by_type() or
|
||||
hwloc_get_next_obj_inside_cpuset_by_type().
|
||||
|
||||
It is also possible to directly find an object "below" another object
|
||||
using hwloc_get_obj_below_by_type() (or
|
||||
hwloc_get_obj_below_array_by_type()).
|
||||
|
||||
|
||||
\section switchfromplpa_indexes Logical vs. Physical/OS indexes
|
||||
|
||||
hwloc manipulates logical indexes, meaning indexes specified with
|
||||
regard to the ordering of objects in the hwloc-provided hierarchical
|
||||
tree. Physical or OS indexes may be entirely hidden if not strictly
|
||||
required. The reason for this is that physical/OS indexes may change
|
||||
with the OS or with the BIOS version. They may be non-consecutive,
|
||||
multiple objects may have the same physical/OS indexes, making their
|
||||
manipulation tricky and highly non-portable.
|
||||
|
||||
Note that hwloc tries very hard to always present a hierarchical tree
|
||||
with the same logical ordering, regardless of physical or OS index
|
||||
ordering.
|
||||
|
||||
It is still possible to retrieve physical/OS indexes through the \p
|
||||
os_index field of objects, but such practice should be avoided as much
|
||||
as possible for the reasons described above (except perhaps for
|
||||
prettyprinting / debugging purposes).
|
||||
|
||||
::HWLOC_OBJ_PU objects are supposed to have different physical/OS
|
||||
indexes since the OS uses them for binding. The \p os_index field of
|
||||
these objects provides the identifier that may be used for such
|
||||
binding, and hwloc_get_proc_obj_by_os_index() finds the object
|
||||
associated with a specific OS index.
|
||||
|
||||
But as mentioned above, we discourage the use of these conversion
|
||||
methods for actual binding. Instead, hwloc offers its own binding
|
||||
model using the \p cpuset field of objects. These cpusets may be
|
||||
duplicated, modified, combined, etc. (see hwloc/cpuset.h for details)
|
||||
and then passed to hwloc_set_cpubind() for binding.
|
||||
|
||||
|
||||
\section switchfromplpa_counting Counting specification
|
||||
|
||||
PLPA offers a countspec parameter to specify whether counting all
|
||||
CPUs, only the online ones or only the offline ones. However, some
|
||||
operating systems do not expose the topology of offline CPUs (i.e.,
|
||||
offline CPUs are not reported at all by the OS). Also, some
|
||||
processors may not be visible to the current application due to
|
||||
administrative restrictions. Finally, some processors let you
|
||||
shutdown a single hardware thread in a core, making some of the PLPA
|
||||
features irrelevant.
|
||||
|
||||
hwloc stores in the hierarchical tree of objects all CPUs that have
|
||||
known topology information. It then provides the applications with
|
||||
several cpusets that contain the list of CPUs that are actually known,
|
||||
that have topology information, that are online, or that are available
|
||||
to the application. These cpusets may be retrieved with
|
||||
hwloc_topology_get_online_cpuset() and other similar functions to
|
||||
filter the object that are relevant or not.
|
||||
|
||||
*/
|
@ -1,2 +0,0 @@
|
||||
<link href="tabs.css" rel="stylesheet" type="text/css">
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
@ -1,2 +0,0 @@
|
||||
<?php
|
||||
include_once("$topdir/includes/footer.inc");
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
$topdir = "../../../..";
|
||||
# Note that we must use the PHP "$$" indirection to assign to the
|
||||
# "title" variable, because if we list "$ title" (without the space)
|
||||
# in this file, Doxygen will replace it with a string title.
|
||||
$ver = basename(getcwd());
|
||||
$thwarting_doxygen_preprocessor = "title";
|
||||
$$thwarting_doxygen_preprocessor = "Portable Hardware Locality (hwloc) Documentation: $ver";
|
||||
$header_include_file = "$topdir/projects/hwloc/doc/$ver/www.open-mpi.org-css.inc";
|
||||
|
||||
include_once("$topdir/projects/hwloc/nav.inc");
|
||||
include_once("$topdir/includes/header.inc");
|
||||
include_once("$topdir/includes/code.inc");
|
||||
?>
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,61 +0,0 @@
|
||||
# Copyright 2009 INRIA, Université Bordeaux 1
|
||||
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
|
||||
AM_CFLAGS = $(HWLOC_CFLAGS)
|
||||
AM_CPPFLAGS = $(HWLOC_CPPFLAGS)
|
||||
AM_LDFLAGS = $(HWLOC_LDFLAGS)
|
||||
|
||||
SUBDIRS = linux ports xml
|
||||
|
||||
LIBS =
|
||||
|
||||
if HWLOC_BUILD_TESTS
|
||||
check_PROGRAMS = hwloc_cpuset_string \
|
||||
hwloc_get_closest_objs \
|
||||
hwloc_get_obj_covering_cpuset \
|
||||
hwloc_get_cache_covering_cpuset \
|
||||
hwloc_get_largest_objs_inside_cpuset \
|
||||
hwloc_get_next_obj_covering_cpuset \
|
||||
hwloc_get_obj_inside_cpuset \
|
||||
hwloc_get_shared_cache_covering_obj \
|
||||
hwloc_get_obj_below_array_by_type \
|
||||
hwloc_cpuset_first_last_weight \
|
||||
hwloc_cpuset_singlify \
|
||||
hwloc_type_depth \
|
||||
hwloc_bind \
|
||||
hwloc_object_userdata \
|
||||
hwloc_synthetic \
|
||||
hwloc_is_thissystem \
|
||||
hwloc_insert_misc
|
||||
|
||||
if HWLOC_HAVE_LINUX_LIBNUMA
|
||||
check_PROGRAMS += linux-libnuma
|
||||
endif HWLOC_HAVE_LINUX_LIBNUMA
|
||||
|
||||
if HWLOC_HAVE_SCHED_SETAFFINITY
|
||||
check_PROGRAMS += glibc-sched
|
||||
endif HWLOC_HAVE_SCHED_SETAFFINITY
|
||||
|
||||
if HWLOC_HAVE_LIBIBVERBS
|
||||
check_PROGRAMS += openfabrics-verbs
|
||||
endif HWLOC_HAVE_LIBIBVERBS
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
# The library has a different name depending on whether we are
|
||||
# building in standalone or embedded mode.
|
||||
if HWLOC_BUILD_STANDALONE
|
||||
hwloc_lib = libhwloc.la
|
||||
else
|
||||
hwloc_lib = libhwloc_embedded.la
|
||||
endif
|
||||
|
||||
LIBS += $(HWLOC_top_builddir)/src/$(hwloc_lib)
|
||||
|
||||
linux_libnuma_LDFLAGS = -lnuma
|
||||
openfabrics_verbs_LDFLAGS = -libverbs
|
||||
if !HWLOC_HAVE_WINDOWS
|
||||
hwloc_bind_LDFLAGS = -lpthread
|
||||
endif !HWLOC_HAVE_WINDOWS
|
||||
|
||||
endif HWLOC_BUILD_TESTS
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
#include <hwloc/glibc-sched.h>
|
||||
|
||||
/* check the linux libnuma helpers */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
hwloc_cpuset_t hwlocset;
|
||||
cpu_set_t schedset;
|
||||
hwloc_obj_t obj;
|
||||
int err;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
|
||||
hwlocset = hwloc_cpuset_dup(hwloc_topology_get_complete_cpuset(topology));
|
||||
hwloc_cpuset_to_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset));
|
||||
#ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY
|
||||
err = sched_setaffinity(0, sizeof(schedset));
|
||||
#else
|
||||
err = sched_setaffinity(0, sizeof(schedset), &schedset);
|
||||
#endif
|
||||
assert(!err);
|
||||
hwloc_cpuset_free(hwlocset);
|
||||
|
||||
#ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY
|
||||
err = sched_getaffinity(0, sizeof(schedset));
|
||||
#else
|
||||
err = sched_getaffinity(0, sizeof(schedset), &schedset);
|
||||
#endif
|
||||
assert(!err);
|
||||
hwlocset = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset));
|
||||
assert(hwloc_cpuset_isincluded(hwlocset, hwloc_topology_get_complete_cpuset(topology)));
|
||||
hwloc_cpuset_andnot(hwlocset, hwlocset, hwloc_topology_get_online_cpuset(topology));
|
||||
hwloc_cpuset_andnot(hwlocset, hwlocset, hwloc_topology_get_allowed_cpuset(topology));
|
||||
assert(hwloc_cpuset_iszero(hwlocset));
|
||||
hwloc_cpuset_free(hwlocset);
|
||||
|
||||
obj = hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1) - 1);
|
||||
assert(obj);
|
||||
assert(obj->type == HWLOC_OBJ_PU);
|
||||
|
||||
hwlocset = hwloc_cpuset_dup(obj->cpuset);
|
||||
hwloc_cpuset_to_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset));
|
||||
#ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY
|
||||
err = sched_setaffinity(0, sizeof(schedset));
|
||||
#else
|
||||
err = sched_setaffinity(0, sizeof(schedset), &schedset);
|
||||
#endif
|
||||
assert(!err);
|
||||
hwloc_cpuset_free(hwlocset);
|
||||
|
||||
#ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY
|
||||
err = sched_getaffinity(0, sizeof(schedset));
|
||||
#else
|
||||
err = sched_getaffinity(0, sizeof(schedset), &schedset);
|
||||
#endif
|
||||
assert(!err);
|
||||
hwlocset = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset));
|
||||
assert(hwloc_cpuset_isequal(hwlocset, obj->cpuset));
|
||||
hwloc_cpuset_free(hwlocset);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
return 0;
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
#include <private/config.h>
|
||||
|
||||
/* check the binding functions */
|
||||
hwloc_topology_t topology;
|
||||
const struct hwloc_topology_support *support;
|
||||
|
||||
static void result_set(const char *msg, int err, int supported)
|
||||
{
|
||||
const char *errmsg = strerror(errno);
|
||||
if (err)
|
||||
printf("%-40s: FAILED (%d, %s)%s\n", msg, errno, errmsg, supported ? "" : " (expected)");
|
||||
else
|
||||
printf("%-40s: OK%s\n", msg, supported ? "" : " (unexpected)");
|
||||
}
|
||||
|
||||
static void result_get(const char *msg, hwloc_const_cpuset_t expected, hwloc_const_cpuset_t result, int err, int supported)
|
||||
{
|
||||
const char *errmsg = strerror(errno);
|
||||
if (err)
|
||||
printf("%-40s: FAILED (%d, %s)%s\n", msg, errno, errmsg, supported ? "" : " (expected)");
|
||||
else if (hwloc_cpuset_isequal(expected, result))
|
||||
printf("%-40s: OK%s\n", msg, supported ? "" : " (unexpected)");
|
||||
else {
|
||||
char *expected_s, *result_s;
|
||||
hwloc_cpuset_asprintf(&expected_s, expected);
|
||||
hwloc_cpuset_asprintf(&result_s, result);
|
||||
printf("%-40s: expected %s, got %s\n", msg, expected_s, result_s);
|
||||
}
|
||||
}
|
||||
|
||||
static void test(hwloc_const_cpuset_t cpuset, int flags)
|
||||
{
|
||||
hwloc_cpuset_t new_cpuset = hwloc_cpuset_alloc();
|
||||
result_set("Bind this singlethreaded process", hwloc_set_cpubind(topology, cpuset, flags), support->cpubind->set_thisproc_cpubind || support->cpubind->set_thisthread_cpubind);
|
||||
result_get("Get this singlethreaded process", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags), support->cpubind->get_thisproc_cpubind || support->cpubind->get_thisthread_cpubind);
|
||||
result_set("Bind this thread", hwloc_set_cpubind(topology, cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->set_thisthread_cpubind);
|
||||
result_get("Get this thread", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->get_thisthread_cpubind);
|
||||
result_set("Bind this whole process", hwloc_set_cpubind(topology, cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_thisproc_cpubind);
|
||||
result_get("Get this whole process", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_thisproc_cpubind);
|
||||
|
||||
#ifdef HWLOC_WIN_SYS
|
||||
result_set("Bind process", hwloc_set_proc_cpubind(topology, GetCurrentProcess(), cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_proc_cpubind);
|
||||
result_get("Get process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, GetCurrentProcess(), new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_proc_cpubind);
|
||||
result_set("Bind thread", hwloc_set_thread_cpubind(topology, GetCurrentThread(), cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->set_thread_cpubind);
|
||||
result_get("Get thread", cpuset, new_cpuset, hwloc_get_thread_cpubind(topology, GetCurrentThread(), new_cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->get_thread_cpubind);
|
||||
#else /* !HWLOC_WIN_SYS */
|
||||
result_set("Bind whole process", hwloc_set_proc_cpubind(topology, getpid(), cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_proc_cpubind);
|
||||
result_get("Get whole process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, getpid(), new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_proc_cpubind);
|
||||
result_set("Bind process", hwloc_set_proc_cpubind(topology, getpid(), cpuset, flags), support->cpubind->set_proc_cpubind);
|
||||
result_get("Get process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, getpid(), new_cpuset, flags), support->cpubind->get_proc_cpubind);
|
||||
#ifdef hwloc_thread_t
|
||||
result_set("Bind thread", hwloc_set_thread_cpubind(topology, pthread_self(), cpuset, flags), support->cpubind->set_thread_cpubind);
|
||||
result_get("Get thread", cpuset, new_cpuset, hwloc_get_thread_cpubind(topology, pthread_self(), new_cpuset, flags), support->cpubind->get_thread_cpubind);
|
||||
#endif
|
||||
#endif /* !HWLOC_WIN_SYS */
|
||||
printf("\n");
|
||||
hwloc_cpuset_free(new_cpuset);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_cpuset_t set;
|
||||
hwloc_obj_t obj;
|
||||
char *str = NULL;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
support = hwloc_topology_get_support(topology);
|
||||
|
||||
obj = hwloc_get_root_obj(topology);
|
||||
set = hwloc_cpuset_dup(obj->cpuset);
|
||||
|
||||
while (hwloc_cpuset_isequal(obj->cpuset, set)) {
|
||||
if (!obj->arity)
|
||||
break;
|
||||
obj = obj->children[0];
|
||||
}
|
||||
|
||||
hwloc_cpuset_asprintf(&str, set);
|
||||
printf("system set is %s\n", str);
|
||||
free(str);
|
||||
|
||||
test(set, 0);
|
||||
|
||||
printf("now strict\n");
|
||||
test(set, HWLOC_CPUBIND_STRICT);
|
||||
|
||||
hwloc_cpuset_free(set);
|
||||
set = hwloc_cpuset_dup(obj->cpuset);
|
||||
hwloc_cpuset_asprintf(&str, set);
|
||||
printf("obj set is %s\n", str);
|
||||
free(str);
|
||||
|
||||
test(set, 0);
|
||||
|
||||
printf("now strict\n");
|
||||
test(set, HWLOC_CPUBIND_STRICT);
|
||||
|
||||
hwloc_cpuset_singlify(set);
|
||||
hwloc_cpuset_asprintf(&str, set);
|
||||
printf("singlified to %s\n", str);
|
||||
free(str);
|
||||
|
||||
test(set, 0);
|
||||
|
||||
printf("now strict\n");
|
||||
test(set, HWLOC_CPUBIND_STRICT);
|
||||
|
||||
hwloc_cpuset_free(set);
|
||||
hwloc_topology_destroy(topology);
|
||||
return 0;
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_cpuset_first(), _last(), _next() and _weight() */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_cpuset_t set;
|
||||
int i, cpu, expected_cpu;
|
||||
|
||||
/* empty set */
|
||||
set = hwloc_cpuset_alloc();
|
||||
assert(hwloc_cpuset_first(set) == -1);
|
||||
assert(hwloc_cpuset_last(set) == -1);
|
||||
assert(hwloc_cpuset_next(set, 0) == -1);
|
||||
assert(hwloc_cpuset_weight(set) == 0);
|
||||
|
||||
/* full set */
|
||||
hwloc_cpuset_fill(set);
|
||||
assert(hwloc_cpuset_first(set) == 0);
|
||||
assert(hwloc_cpuset_last(set) == HWLOC_NBMAXCPUS-1);
|
||||
assert(hwloc_cpuset_next(set, 0) == 1);
|
||||
assert(hwloc_cpuset_next(set, 1) == 2);
|
||||
assert(hwloc_cpuset_next(set, 2) == 3);
|
||||
assert(hwloc_cpuset_next(set, 30) == 31);
|
||||
assert(hwloc_cpuset_next(set, 31) == 32);
|
||||
assert(hwloc_cpuset_next(set, 32) == 33);
|
||||
assert(hwloc_cpuset_next(set, 62) == 63);
|
||||
assert(hwloc_cpuset_next(set, 63) == 64);
|
||||
assert(hwloc_cpuset_next(set, 64) == 65);
|
||||
assert(hwloc_cpuset_next(set, HWLOC_NBMAXCPUS-3) == HWLOC_NBMAXCPUS-2);
|
||||
assert(hwloc_cpuset_next(set, HWLOC_NBMAXCPUS-2) == HWLOC_NBMAXCPUS-1);
|
||||
assert(hwloc_cpuset_next(set, HWLOC_NBMAXCPUS-1) == -1);
|
||||
assert(hwloc_cpuset_weight(set) == HWLOC_NBMAXCPUS);
|
||||
|
||||
/* custom sets */
|
||||
hwloc_cpuset_zero(set);
|
||||
hwloc_cpuset_set_range(set, 36, 59);
|
||||
assert(hwloc_cpuset_first(set) == 36);
|
||||
assert(hwloc_cpuset_last(set) == 59);
|
||||
assert(hwloc_cpuset_next(set, 0) == 36);
|
||||
assert(hwloc_cpuset_next(set, 36) == 37);
|
||||
assert(hwloc_cpuset_next(set, 59) == -1);
|
||||
assert(hwloc_cpuset_weight(set) == 24);
|
||||
hwloc_cpuset_set_range(set, 136, 259);
|
||||
assert(hwloc_cpuset_first(set) == 36);
|
||||
assert(hwloc_cpuset_last(set) == 259);
|
||||
assert(hwloc_cpuset_next(set, 59) == 136);
|
||||
assert(hwloc_cpuset_next(set, 259) == -1);
|
||||
assert(hwloc_cpuset_weight(set) == 148);
|
||||
hwloc_cpuset_clr(set, 199);
|
||||
assert(hwloc_cpuset_first(set) == 36);
|
||||
assert(hwloc_cpuset_last(set) == 259);
|
||||
assert(hwloc_cpuset_next(set, 198) == 200);
|
||||
assert(hwloc_cpuset_next(set, 199) == 200);
|
||||
assert(hwloc_cpuset_weight(set) == 147);
|
||||
|
||||
i = 0;
|
||||
hwloc_cpuset_foreach_begin(cpu, set) {
|
||||
if (0 <= i && i < 24)
|
||||
expected_cpu = i + 36;
|
||||
else if (24 <= i && i < 87)
|
||||
expected_cpu = i + 112;
|
||||
else if (87 <= i && i < 147)
|
||||
expected_cpu = i + 113;
|
||||
|
||||
assert(expected_cpu == cpu);
|
||||
|
||||
i++;
|
||||
} hwloc_cpuset_foreach_end();
|
||||
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_cpuset_singlify() */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_cpuset_t orig, expected;
|
||||
|
||||
orig = hwloc_cpuset_alloc();
|
||||
expected = hwloc_cpuset_alloc();
|
||||
|
||||
/* empty set gives empty set */
|
||||
hwloc_cpuset_singlify(orig);
|
||||
assert(hwloc_cpuset_iszero(orig));
|
||||
|
||||
/* full set gives first bit only */
|
||||
hwloc_cpuset_fill(orig);
|
||||
hwloc_cpuset_singlify(orig);
|
||||
hwloc_cpuset_zero(expected);
|
||||
hwloc_cpuset_set(expected, 0);
|
||||
assert(!hwloc_cpuset_compare(orig, expected));
|
||||
|
||||
/* actual non-trivial set */
|
||||
hwloc_cpuset_zero(orig);
|
||||
hwloc_cpuset_set(orig, 45);
|
||||
hwloc_cpuset_set(orig, 46);
|
||||
hwloc_cpuset_set(orig, 517);
|
||||
hwloc_cpuset_singlify(orig);
|
||||
hwloc_cpuset_zero(expected);
|
||||
hwloc_cpuset_set(expected, 45);
|
||||
assert(!hwloc_cpuset_compare(orig, expected));
|
||||
|
||||
hwloc_cpuset_free(orig);
|
||||
hwloc_cpuset_free(expected);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_cpuset_asprintf(), hwloc_obj_cpuset_snprintf() and hwloc_cpuset_from_string() */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
char *string = NULL;
|
||||
int stringlen, len;
|
||||
hwloc_obj_t obj;
|
||||
hwloc_cpuset_t set;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, "6 5 4 3 2");
|
||||
hwloc_topology_load(topology);
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
|
||||
obj = hwloc_get_root_obj(topology);
|
||||
stringlen = hwloc_cpuset_asprintf(&string, obj->cpuset);
|
||||
printf("system cpuset is %s\n", string);
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(set, string);
|
||||
assert(hwloc_cpuset_isequal(set, obj->cpuset));
|
||||
hwloc_cpuset_free(set);
|
||||
printf("system cpuset converted back and forth, ok\n");
|
||||
|
||||
printf("truncating system cpuset to NULL buffer\n");
|
||||
len = hwloc_obj_cpuset_snprintf(NULL, 0, 1, &obj);
|
||||
assert(len == stringlen);
|
||||
|
||||
printf("truncating system cpuset to 0 char (no modification)\n");
|
||||
memset(string, 'X', 1);
|
||||
string[1] = 0;
|
||||
len = hwloc_obj_cpuset_snprintf(string, 0, 1, &obj);
|
||||
assert(len == stringlen);
|
||||
assert(string[0] == 'X');
|
||||
|
||||
printf("truncating system cpuset to 1 char (empty string)\n");
|
||||
memset(string, 'X', 2);
|
||||
string[2] = 0;
|
||||
len = hwloc_obj_cpuset_snprintf(string, 1, 1, &obj);
|
||||
printf("got %s\n", string);
|
||||
assert(len == stringlen);
|
||||
assert(string[0] == 0);
|
||||
assert(string[1] == 'X');
|
||||
|
||||
printf("truncating system cpuset to 10 chars (single 32bit subset except last char)\n");
|
||||
memset(string, 'X', 11);
|
||||
string[11] = 0;
|
||||
len = hwloc_obj_cpuset_snprintf(string, 10, 1, &obj);
|
||||
printf("got %s\n", string);
|
||||
assert(len == stringlen);
|
||||
assert(string[8] == 'f');
|
||||
assert(string[9] == 0);
|
||||
assert(string[10] == 'X');
|
||||
|
||||
printf("truncating system cpuset to 11 chars (single 32bit subset)\n");
|
||||
memset(string, 'X', 12);
|
||||
string[12] = 0;
|
||||
len = hwloc_obj_cpuset_snprintf(string, 11, 1, &obj);
|
||||
printf("got %s\n", string);
|
||||
assert(len == stringlen);
|
||||
assert(string[9] == 'f');
|
||||
assert(string[10] == 0);
|
||||
assert(string[11] == 'X');
|
||||
|
||||
printf("truncating system cpuset to 23 chars (two 32bit subsets with ending comma)\n");
|
||||
memset(string, 'X', 24);
|
||||
string[24] = 0;
|
||||
len = hwloc_obj_cpuset_snprintf(string, 23, 1, &obj);
|
||||
printf("got %s\n", string);
|
||||
assert(len == stringlen);
|
||||
assert(string[20] == 'f');
|
||||
assert(string[21] == ',');
|
||||
assert(string[22] == 0);
|
||||
assert(string[23] == 'X');
|
||||
|
||||
printf("truncating system cpuset to 51 chars (truncate to four and a half 32bit subsets)\n");
|
||||
memset(string, 'X', 52);
|
||||
string[52] = 0;
|
||||
len = hwloc_obj_cpuset_snprintf(string, 51, 1, &obj);
|
||||
printf("got %s\n", string);
|
||||
assert(len == stringlen);
|
||||
assert(string[49] == 'f');
|
||||
assert(string[50] == 0);
|
||||
assert(string[51] == 'X');
|
||||
|
||||
obj = hwloc_get_obj_by_depth(topology, depth-1, 0);
|
||||
hwloc_obj_cpuset_snprintf(string, stringlen+1, 1, &obj);
|
||||
printf("first cpu cpuset is %s\n", string);
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(set, string);
|
||||
assert(hwloc_cpuset_isequal(set, obj->cpuset));
|
||||
hwloc_cpuset_free(set);
|
||||
printf("first cpu cpuset converted back and forth, ok\n");
|
||||
|
||||
obj = hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1) - 1);
|
||||
hwloc_obj_cpuset_snprintf(string, stringlen+1, 1, &obj);
|
||||
printf("last cpu cpuset is %s\n", string);
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(set, string);
|
||||
assert(hwloc_cpuset_isequal(set, obj->cpuset));
|
||||
hwloc_cpuset_free(set);
|
||||
printf("last cpu cpuset converted back and forth, ok\n");
|
||||
|
||||
// hwloc_cpuset_from_string(set, "1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4,8,10,20\n");
|
||||
// char *s = hwloc_cpuset_printf_value(&set);
|
||||
// printf("%s\n", s);
|
||||
// free(s);
|
||||
// will be truncated after ",4," since it's too large
|
||||
|
||||
free(string);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_get_cache_covering_cpuset() */
|
||||
|
||||
#define SYNTHETIC_TOPOLOGY_DESCRIPTION "6 5 4 3 2" /* 736bits wide topology */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_obj_t obj, cache;
|
||||
hwloc_cpuset_t set;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
/* check the cache above a given cpu */
|
||||
#define CPUINDEX 180
|
||||
set = hwloc_cpuset_alloc();
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX);
|
||||
assert(obj);
|
||||
hwloc_cpuset_or(set, set, obj->cpuset);
|
||||
cache = hwloc_get_cache_covering_cpuset(topology, set);
|
||||
assert(cache);
|
||||
assert(cache->type == HWLOC_OBJ_CACHE);
|
||||
assert(cache->logical_index == CPUINDEX/2/3);
|
||||
assert(hwloc_obj_is_in_subtree(topology, obj, cache));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* check the cache above two nearby cpus */
|
||||
#define CPUINDEX1 180
|
||||
#define CPUINDEX2 183
|
||||
set = hwloc_cpuset_alloc();
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX1);
|
||||
assert(obj);
|
||||
hwloc_cpuset_or(set, set, obj->cpuset);
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX2);
|
||||
assert(obj);
|
||||
hwloc_cpuset_or(set, set, obj->cpuset);
|
||||
cache = hwloc_get_cache_covering_cpuset(topology, set);
|
||||
assert(cache);
|
||||
assert(cache->type == HWLOC_OBJ_CACHE);
|
||||
assert(cache->logical_index == CPUINDEX1/2/3);
|
||||
assert(cache->logical_index == CPUINDEX2/2/3);
|
||||
assert(hwloc_obj_is_in_subtree(topology, obj, cache));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* check no cache above two distant cpus */
|
||||
#undef CPUINDEX1
|
||||
#define CPUINDEX1 300
|
||||
set = hwloc_cpuset_alloc();
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX1);
|
||||
assert(obj);
|
||||
hwloc_cpuset_or(set, set, obj->cpuset);
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX2);
|
||||
assert(obj);
|
||||
hwloc_cpuset_or(set, set, obj->cpuset);
|
||||
cache = hwloc_get_cache_covering_cpuset(topology, set);
|
||||
assert(!cache);
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* check no cache above higher level */
|
||||
set = hwloc_cpuset_alloc();
|
||||
obj = hwloc_get_obj_by_depth(topology, 2, 0);
|
||||
assert(obj);
|
||||
hwloc_cpuset_or(set, set, obj->cpuset);
|
||||
cache = hwloc_get_cache_covering_cpuset(topology, set);
|
||||
assert(!cache);
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* check hwloc_get_closest_objs()
|
||||
*
|
||||
* - get the last object of the last level
|
||||
* - get all closest objects
|
||||
* - get the common ancestor of last level and its less close object.
|
||||
* - check that the ancestor is the system level
|
||||
*/
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
hwloc_obj_t last;
|
||||
hwloc_obj_t *closest;
|
||||
unsigned found;
|
||||
int err;
|
||||
unsigned numprocs;
|
||||
hwloc_obj_t ancestor;
|
||||
|
||||
err = hwloc_topology_init (&topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
hwloc_topology_set_synthetic (topology, "2 3 4 5");
|
||||
|
||||
err = hwloc_topology_load (topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
|
||||
/* get the last object of last level */
|
||||
numprocs = hwloc_get_nbobjs_by_depth(topology, depth-1);
|
||||
last = hwloc_get_obj_by_depth(topology, depth-1, numprocs-1);
|
||||
|
||||
/* allocate the array of closest objects */
|
||||
closest = malloc(numprocs * sizeof(*closest));
|
||||
assert(closest);
|
||||
|
||||
/* get closest levels */
|
||||
found = hwloc_get_closest_objs (topology, last, closest, numprocs);
|
||||
printf("looked for %u closest entries, found %u\n", numprocs, found);
|
||||
assert(found == numprocs-1);
|
||||
|
||||
/* check first found is closest */
|
||||
assert(closest[0] == hwloc_get_obj_by_depth(topology, depth-1, numprocs-5 /* arity is 5 on last level */));
|
||||
/* check some other expected positions */
|
||||
assert(closest[found-1] == hwloc_get_obj_by_depth(topology, depth-1, 1*3*4*5-1 /* last of first half */));
|
||||
assert(closest[found/2-1] == hwloc_get_obj_by_depth(topology, depth-1, 1*3*4*5+2*4*5-1 /* last of second third of second half */));
|
||||
assert(closest[found/2/3-1] == hwloc_get_obj_by_depth(topology, depth-1, 1*3*4*5+2*4*5+3*5-1 /* last of third quarter of third third of second half */));
|
||||
|
||||
/* get ancestor of last and less close object */
|
||||
ancestor = hwloc_get_common_ancestor_obj(topology, last, closest[found-1]);
|
||||
assert(hwloc_obj_is_in_subtree(topology, last, ancestor));
|
||||
assert(hwloc_obj_is_in_subtree(topology, closest[found-1], ancestor));
|
||||
assert(ancestor == hwloc_get_root_obj(topology));
|
||||
printf("ancestor type %u depth %u number %u is system level\n",
|
||||
ancestor->type, ancestor->depth, ancestor->logical_index);
|
||||
|
||||
free(closest);
|
||||
hwloc_topology_destroy (topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_get_largest_objs_inside_cpuset()
|
||||
* and hwloc_get_first_largest_obj_inside_cpuset()
|
||||
*/
|
||||
|
||||
#define SYNTHETIC_TOPOLOGY_DESCRIPTION "6 5 4 3 2" /* 736bits wide topology */
|
||||
|
||||
#define GIVEN_LARGESPLIT_CPUSET_STRING "8000,,,,,,,,,,,,,,,,,,,,,,1" /* first and last(735th) bit set */
|
||||
#define GIVEN_TOOLARGE_CPUSET_STRING "10000,,,,,,,,,,,,,,,,,,,,,,0" /* 736th bit is too large for the 720-wide topology */
|
||||
#define GIVEN_HARD_CPUSET_STRING "07ff,ffffffff,e0000000"
|
||||
|
||||
#define OBJ_MAX 16
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
hwloc_obj_t objs[OBJ_MAX];
|
||||
hwloc_obj_t obj;
|
||||
hwloc_cpuset_t set;
|
||||
int ret;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION);
|
||||
hwloc_topology_load(topology);
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
|
||||
/* just get the system object */
|
||||
obj = hwloc_get_root_obj(topology);
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, obj->cpuset, objs, 1);
|
||||
assert(ret == 1);
|
||||
assert(objs[0] == obj);
|
||||
objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, obj->cpuset);
|
||||
assert(objs[0] == obj);
|
||||
|
||||
/* just get the very last object */
|
||||
obj = hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1)-1);
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, obj->cpuset, objs, 1);
|
||||
assert(ret == 1);
|
||||
assert(objs[0] == obj);
|
||||
|
||||
/* try an empty one */
|
||||
set = hwloc_cpuset_alloc();
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 1);
|
||||
assert(ret == 0);
|
||||
objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set);
|
||||
assert(objs[0] == NULL);
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* try an impossible one */
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(set, GIVEN_TOOLARGE_CPUSET_STRING);
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 1);
|
||||
assert(ret == -1);
|
||||
objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set);
|
||||
assert(objs[0] == NULL);
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* try a harder one with 1 obj instead of 2 needed */
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(set, GIVEN_LARGESPLIT_CPUSET_STRING);
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 1);
|
||||
assert(ret == 1);
|
||||
assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0));
|
||||
objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set);
|
||||
assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0));
|
||||
/* try a harder one with lots of objs instead of 2 needed */
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 2);
|
||||
assert(ret == 2);
|
||||
assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0));
|
||||
assert(objs[1] == hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1)-1));
|
||||
objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set);
|
||||
hwloc_cpuset_andnot(set, set, objs[0]->cpuset);
|
||||
objs[1] = hwloc_get_first_largest_obj_inside_cpuset(topology, set);
|
||||
hwloc_cpuset_andnot(set, set, objs[1]->cpuset);
|
||||
objs[2] = hwloc_get_first_largest_obj_inside_cpuset(topology, set);
|
||||
assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0));
|
||||
assert(objs[1] == hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1)-1));
|
||||
assert(objs[2] == NULL);
|
||||
assert(hwloc_cpuset_iszero(set));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* try a very hard one */
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(set, GIVEN_HARD_CPUSET_STRING);
|
||||
ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, OBJ_MAX);
|
||||
assert(objs[0] == hwloc_get_obj_by_depth(topology, 5, 29));
|
||||
assert(objs[1] == hwloc_get_obj_by_depth(topology, 3, 5));
|
||||
assert(objs[2] == hwloc_get_obj_by_depth(topology, 3, 6));
|
||||
assert(objs[3] == hwloc_get_obj_by_depth(topology, 3, 7));
|
||||
assert(objs[4] == hwloc_get_obj_by_depth(topology, 2, 2));
|
||||
assert(objs[5] == hwloc_get_obj_by_depth(topology, 4, 36));
|
||||
assert(objs[6] == hwloc_get_obj_by_depth(topology, 5, 74));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* check hwloc_get_next_obj_covering_cpuset*()
|
||||
*/
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_cpuset_t set;
|
||||
hwloc_obj_t obj;
|
||||
int depth;
|
||||
int err;
|
||||
|
||||
err = hwloc_topology_init (&topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
set = hwloc_cpuset_alloc();
|
||||
|
||||
|
||||
|
||||
hwloc_topology_set_synthetic (topology, "nodes:8 cores:2 1");
|
||||
err = hwloc_topology_load (topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
hwloc_cpuset_from_string(set, "00008f18");
|
||||
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, NULL);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 1, 1));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, obj);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 1, 2));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, obj);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 1, 4));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, obj);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 1, 5));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, obj);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 1, 7));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, obj);
|
||||
assert(!obj);
|
||||
|
||||
|
||||
|
||||
hwloc_topology_set_synthetic (topology, "nodes:2 socket:5 cores:3 4");
|
||||
err = hwloc_topology_load (topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
hwloc_cpuset_from_string(set, "0ff08000");
|
||||
|
||||
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET);
|
||||
assert(depth == 2);
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, NULL);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, depth, 1));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, obj);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, depth, 2));
|
||||
obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, obj);
|
||||
assert(!obj);
|
||||
|
||||
|
||||
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
hwloc_topology_destroy (topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* check hwloc_get_obj_below_array_by_type()
|
||||
*/
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_obj_t obj;
|
||||
hwloc_obj_type_t typev[4];
|
||||
unsigned idxv[4];
|
||||
int err;
|
||||
|
||||
err = hwloc_topology_init (&topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
hwloc_topology_set_synthetic (topology, "node:3 socket:3 core:3 proc:3");
|
||||
|
||||
err = hwloc_topology_load (topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
|
||||
/* find the first thread */
|
||||
typev[0] = HWLOC_OBJ_NODE; idxv[0] = 0;
|
||||
typev[1] = HWLOC_OBJ_SOCKET; idxv[1] = 0;
|
||||
typev[2] = HWLOC_OBJ_CORE; idxv[2] = 0;
|
||||
typev[3] = HWLOC_OBJ_PU; idxv[3] = 0;
|
||||
obj = hwloc_get_obj_below_array_by_type(topology, 4, typev, idxv);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 4, 0));
|
||||
|
||||
/* find the last core */
|
||||
typev[0] = HWLOC_OBJ_NODE; idxv[0] = 2;
|
||||
typev[1] = HWLOC_OBJ_SOCKET; idxv[1] = 2;
|
||||
typev[2] = HWLOC_OBJ_CORE; idxv[2] = 2;
|
||||
obj = hwloc_get_obj_below_array_by_type(topology, 3, typev, idxv);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 3, 26));
|
||||
|
||||
/* misc tests */
|
||||
|
||||
typev[0] = HWLOC_OBJ_SOCKET; idxv[0] = 2;
|
||||
obj = hwloc_get_obj_below_array_by_type(topology, 1, typev, idxv);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 2, 2));
|
||||
|
||||
typev[0] = HWLOC_OBJ_NODE; idxv[0] = 2;
|
||||
typev[1] = HWLOC_OBJ_CORE; idxv[1] = 2;
|
||||
obj = hwloc_get_obj_below_array_by_type(topology, 2, typev, idxv);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 3, 20));
|
||||
/* check that hwloc_get_obj_below_by_type works as well */
|
||||
obj = hwloc_get_obj_below_by_type(topology, typev[0], idxv[0], typev[1], idxv[1]);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 3, 20));
|
||||
|
||||
typev[0] = HWLOC_OBJ_SOCKET; idxv[0] = 1;
|
||||
typev[1] = HWLOC_OBJ_PU; idxv[1] = 1;
|
||||
obj = hwloc_get_obj_below_array_by_type(topology, 2, typev, idxv);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 4, 10));
|
||||
/* check that hwloc_get_obj_below_by_type works as well */
|
||||
obj = hwloc_get_obj_below_by_type(topology, typev[0], idxv[0], typev[1], idxv[1]);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 4, 10));
|
||||
|
||||
|
||||
hwloc_topology_destroy (topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_get_obj_covering_cpuset() */
|
||||
|
||||
#define SYNTHETIC_TOPOLOGY_DESCRIPTION "6 5 4 3 2" /* 736bits wide topology */
|
||||
|
||||
#define GIVEN_CPUSET_STRING "0x0,0x0fff,0xf0000000"
|
||||
#define EXPECTED_CPUSET_STRING "0x0000ffff,0xff000000"
|
||||
#define GIVEN_LARGESPLIT_CPUSET_STRING "0x8000,,,,,,,,,,,,,,,,,,,,,,0x1" /* first and last(735th) bit set */
|
||||
#define GIVEN_TOOLARGE_CPUSET_STRING "0x10000,,,,,,,,,,,,,,,,,,,,,,0x0" /* 736th bit is too large for the 720-wide topology */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
char *string = NULL;
|
||||
hwloc_obj_t obj;
|
||||
hwloc_cpuset_t set;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION);
|
||||
hwloc_topology_load(topology);
|
||||
set = hwloc_cpuset_alloc();
|
||||
|
||||
hwloc_cpuset_from_string(set, GIVEN_CPUSET_STRING);
|
||||
obj = hwloc_get_obj_covering_cpuset(topology, set);
|
||||
|
||||
assert(obj);
|
||||
fprintf(stderr, "found covering object type %s covering cpuset %s\n",
|
||||
hwloc_obj_type_string(obj->type), GIVEN_CPUSET_STRING);
|
||||
assert(hwloc_cpuset_isincluded(set, obj->cpuset));
|
||||
|
||||
hwloc_cpuset_asprintf(&string, obj->cpuset);
|
||||
fprintf(stderr, "covering object of %s is %s, expected %s\n",
|
||||
GIVEN_CPUSET_STRING, string, EXPECTED_CPUSET_STRING);
|
||||
assert(!strcmp(EXPECTED_CPUSET_STRING, string));
|
||||
free(string);
|
||||
|
||||
hwloc_cpuset_from_string(set, GIVEN_LARGESPLIT_CPUSET_STRING);
|
||||
obj = hwloc_get_obj_covering_cpuset(topology, set);
|
||||
assert(obj == hwloc_get_root_obj(topology));
|
||||
fprintf(stderr, "found system as covering object of first+last cpus cpuset %s\n",
|
||||
GIVEN_LARGESPLIT_CPUSET_STRING);
|
||||
|
||||
hwloc_cpuset_from_string(set, GIVEN_TOOLARGE_CPUSET_STRING);
|
||||
obj = hwloc_get_obj_covering_cpuset(topology, set);
|
||||
assert(!obj);
|
||||
fprintf(stderr, "found no covering object for too-large cpuset %s\n",
|
||||
GIVEN_TOOLARGE_CPUSET_STRING);
|
||||
|
||||
hwloc_cpuset_free(set);
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* check hwloc_get_obj_inside_cpuset*()
|
||||
*/
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_obj_t obj, root;
|
||||
int err;
|
||||
|
||||
err = hwloc_topology_init (&topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
hwloc_topology_set_synthetic (topology, "nodes:2 sockets:3 caches:4 cores:5 6");
|
||||
|
||||
err = hwloc_topology_load (topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/* there is no second system object */
|
||||
root = hwloc_get_root_obj (topology);
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_SYSTEM, 1);
|
||||
assert(!obj);
|
||||
|
||||
/* first system object is the top-level object of the topology */
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_MACHINE, 0);
|
||||
assert(obj == hwloc_get_root_obj(topology));
|
||||
|
||||
/* first next-object object is the top-level object of the topology */
|
||||
obj = hwloc_get_next_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_MACHINE, NULL);
|
||||
assert(obj == hwloc_get_root_obj(topology));
|
||||
/* there is no next object after the system object */
|
||||
obj = hwloc_get_next_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_SYSTEM, obj);
|
||||
assert(!obj);
|
||||
|
||||
/* check last PU */
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_PU, 2*3*4*5*6-1);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 5, 2*3*4*5*6-1));
|
||||
/* there is no next PU after the last one */
|
||||
obj = hwloc_get_next_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_PU, obj);
|
||||
assert(!obj);
|
||||
|
||||
|
||||
/* check there are 20 cores inside first socket */
|
||||
root = hwloc_get_obj_by_depth(topology, 2, 0);
|
||||
assert(hwloc_get_nbobjs_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_CORE) == 20);
|
||||
|
||||
/* check there are 12 caches inside last node */
|
||||
root = hwloc_get_obj_by_depth(topology, 1, 1);
|
||||
assert(hwloc_get_nbobjs_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_CACHE) == 12);
|
||||
|
||||
|
||||
/* check first PU of second socket */
|
||||
root = hwloc_get_obj_by_depth(topology, 2, 1);
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_PU, 0);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 5, 4*5*6));
|
||||
|
||||
/* check third core of third socket */
|
||||
root = hwloc_get_obj_by_depth(topology, 2, 2);
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_CORE, 2);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 4, 2*4*5+2));
|
||||
|
||||
/* check first socket of second node */
|
||||
root = hwloc_get_obj_by_depth(topology, 1, 1);
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_SOCKET, 0);
|
||||
assert(obj == hwloc_get_obj_by_depth(topology, 2, 3));
|
||||
|
||||
/* there is no node inside sockets */
|
||||
root = hwloc_get_obj_by_depth(topology, 2, 0);
|
||||
obj = hwloc_get_obj_inside_cpuset_by_type(topology, root->cpuset, HWLOC_OBJ_NODE, 0);
|
||||
assert(!obj);
|
||||
|
||||
hwloc_topology_destroy (topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check hwloc_get_shared_cache_covering_obj() */
|
||||
|
||||
#define SYNTHETIC_TOPOLOGY_DESCRIPTION_SHARED "6 5 4 3 2" /* 736bits wide topology */
|
||||
#define SYNTHETIC_TOPOLOGY_DESCRIPTION_NONSHARED "6 5 4 1 2" /* 736bits wide topology */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_obj_t obj, cache;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION_SHARED);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
/* check the cache above a given cpu */
|
||||
#define CPUINDEX 180
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX);
|
||||
assert(obj);
|
||||
cache = hwloc_get_shared_cache_covering_obj(topology, obj);
|
||||
assert(cache);
|
||||
assert(cache->type == HWLOC_OBJ_CACHE);
|
||||
assert(cache->logical_index == CPUINDEX/2/3);
|
||||
assert(hwloc_obj_is_in_subtree(topology, obj, cache));
|
||||
|
||||
/* check no shared cache above the L2 cache */
|
||||
obj = hwloc_get_obj_by_depth(topology, 3, 0);
|
||||
assert(obj);
|
||||
cache = hwloc_get_shared_cache_covering_obj(topology, obj);
|
||||
assert(!cache);
|
||||
|
||||
/* check no shared cache above the node */
|
||||
obj = hwloc_get_obj_by_depth(topology, 1, 0);
|
||||
assert(obj);
|
||||
cache = hwloc_get_shared_cache_covering_obj(topology, obj);
|
||||
assert(!cache);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION_NONSHARED);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
/* check the cache above a given cpu */
|
||||
#define CPUINDEX 180
|
||||
obj = hwloc_get_obj_by_depth(topology, 5, CPUINDEX);
|
||||
assert(obj);
|
||||
cache = hwloc_get_shared_cache_covering_obj(topology, obj);
|
||||
assert(cache);
|
||||
assert(cache->type == HWLOC_OBJ_CACHE);
|
||||
assert(cache->logical_index == CPUINDEX/2/1);
|
||||
assert(hwloc_obj_is_in_subtree(topology, obj, cache));
|
||||
|
||||
/* check no shared-cache above the core */
|
||||
obj = hwloc_get_obj_by_depth(topology, 4, CPUINDEX/2);
|
||||
assert(obj);
|
||||
cache = hwloc_get_shared_cache_covering_obj(topology, obj);
|
||||
assert(!cache);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_cpuset_t cpuset;
|
||||
hwloc_obj_t obj;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
hwloc_topology_check(topology);
|
||||
cpuset = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_set(cpuset, 0);
|
||||
obj = hwloc_topology_insert_misc_object_by_cpuset(topology, cpuset, "test");
|
||||
hwloc_topology_insert_misc_object_by_parent(topology, obj, "test2");
|
||||
hwloc_topology_check(topology);
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Check the is_thissystem flag behavior */
|
||||
|
||||
static void result(const char *msg, int err)
|
||||
{
|
||||
const char *errmsg = strerror(errno);
|
||||
if (err)
|
||||
printf("%-30s: FAILED (%d, %s)\n", msg, errno, errmsg);
|
||||
else
|
||||
printf("%-30s: OK\n", msg);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_cpuset_t cpuset;
|
||||
int err;
|
||||
|
||||
/* check the OS topology */
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
assert(hwloc_topology_is_thissystem(topology));
|
||||
|
||||
cpuset = hwloc_cpuset_dup(hwloc_topology_get_complete_cpuset(topology));
|
||||
result("Binding with OS backend", hwloc_set_cpubind(topology, cpuset, 0));
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
/* We're assume there is a real processor numbered 0 */
|
||||
hwloc_cpuset_zero(cpuset);
|
||||
hwloc_cpuset_set(cpuset, 0);
|
||||
|
||||
/* check a synthetic topology */
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, "1");
|
||||
hwloc_topology_load(topology);
|
||||
assert(!hwloc_topology_is_thissystem(topology));
|
||||
|
||||
err = hwloc_set_cpubind(topology, cpuset, 0);
|
||||
result("Binding with synthetic backend", err);
|
||||
assert(!err);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
/* check a synthetic topology but assuming it's the system topology */
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_flags(topology, HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM);
|
||||
hwloc_topology_set_synthetic(topology, "1");
|
||||
hwloc_topology_load(topology);
|
||||
assert(hwloc_topology_is_thissystem(topology));
|
||||
|
||||
result("Binding with synthetic backend faking is_thissystem", hwloc_set_cpubind(topology, cpuset, 0));
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
hwloc_cpuset_free(cpuset);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check that object userdata is properly initialized */
|
||||
|
||||
static void check(hwloc_topology_t topology)
|
||||
{
|
||||
unsigned depth;
|
||||
unsigned i,j;
|
||||
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
for(i=0; i<depth; i++) {
|
||||
for(j=0; j<hwloc_get_nbobjs_by_depth(topology, i); j++) {
|
||||
assert(hwloc_get_obj_by_depth(topology, i, j)->userdata == NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
|
||||
/* check the real topology */
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
check(topology);
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
/* check a synthetic topology */
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, "6 5 4 3 2");
|
||||
hwloc_topology_load(topology);
|
||||
check(topology);
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check that object userdata is properly initialized */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
unsigned i,j, width;
|
||||
|
||||
/* check a synthetic topology */
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, "2 3 4 5 6");
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
/* internal checks */
|
||||
|
||||
hwloc_topology_check(topology);
|
||||
|
||||
/* local checks */
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
assert(depth == 6);
|
||||
|
||||
width = 1;
|
||||
for(i=0; i<6; i++) {
|
||||
/* check arities */
|
||||
assert(hwloc_get_nbobjs_by_depth(topology, i) == width);
|
||||
for(j=0; j<width; j++) {
|
||||
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, i, j);
|
||||
assert(obj);
|
||||
assert(obj->arity == (i<5 ? i+2 : 0));
|
||||
}
|
||||
width *= i+2;
|
||||
}
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* check topo_get_type{,_or_above,_or_below}_depth()
|
||||
* and hwloc_get_depth_type()
|
||||
*/
|
||||
|
||||
#define SYNTHETIC_TOPOLOGY_DESCRIPTION "machine:3 group:2 group:2 core:3 cache:2 cache:2 2"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
assert(hwloc_topology_get_depth(topology) == 8);
|
||||
|
||||
assert(hwloc_get_depth_type(topology, 0) == HWLOC_OBJ_SYSTEM);
|
||||
assert(hwloc_get_depth_type(topology, 1) == HWLOC_OBJ_MACHINE);
|
||||
assert(hwloc_get_depth_type(topology, 2) == HWLOC_OBJ_GROUP);
|
||||
assert(hwloc_get_depth_type(topology, 3) == HWLOC_OBJ_GROUP);
|
||||
assert(hwloc_get_depth_type(topology, 4) == HWLOC_OBJ_CORE);
|
||||
assert(hwloc_get_depth_type(topology, 5) == HWLOC_OBJ_CACHE);
|
||||
assert(hwloc_get_depth_type(topology, 6) == HWLOC_OBJ_CACHE);
|
||||
assert(hwloc_get_depth_type(topology, 7) == HWLOC_OBJ_PU);
|
||||
|
||||
assert(hwloc_get_type_depth(topology, HWLOC_OBJ_MACHINE) == 1);
|
||||
assert(hwloc_get_type_depth(topology, HWLOC_OBJ_CORE) == 4);
|
||||
assert(hwloc_get_type_depth(topology, HWLOC_OBJ_PU) == 7);
|
||||
|
||||
assert(hwloc_get_type_depth(topology, HWLOC_OBJ_NODE) == HWLOC_TYPE_DEPTH_UNKNOWN);
|
||||
assert(hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_NODE) == 3);
|
||||
assert(hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_NODE) == 4);
|
||||
assert(hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET) == HWLOC_TYPE_DEPTH_UNKNOWN);
|
||||
assert(hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_SOCKET) == 3);
|
||||
assert(hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_SOCKET) == 4);
|
||||
assert(hwloc_get_type_depth(topology, HWLOC_OBJ_CACHE) == HWLOC_TYPE_DEPTH_MULTIPLE);
|
||||
assert(hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_CACHE) == HWLOC_TYPE_DEPTH_MULTIPLE);
|
||||
assert(hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_CACHE) == HWLOC_TYPE_DEPTH_MULTIPLE);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
#include <assert.h>
|
||||
#define NUMA_VERSION1_COMPATIBILITY
|
||||
#include <hwloc/linux-libnuma.h>
|
||||
|
||||
/* check the linux libnuma helpers */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_cpuset_t set, set2;
|
||||
hwloc_obj_t node;
|
||||
struct bitmask *bitmask, *bitmask2;
|
||||
nodemask_t nodemask, nodemask2;
|
||||
unsigned long mask;
|
||||
unsigned long maxnode;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
/* convert full nodemask/bitmask to cpuset */
|
||||
set = hwloc_cpuset_alloc();
|
||||
/* gather all nodes if any, or the whole system if no nodes */
|
||||
if (hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NODE)) {
|
||||
node = NULL;
|
||||
while ((node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, node)) != NULL)
|
||||
hwloc_cpuset_or(set, set, node->cpuset);
|
||||
} else {
|
||||
hwloc_cpuset_or(set, set, hwloc_topology_get_complete_cpuset(topology));
|
||||
}
|
||||
|
||||
set2 = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_linux_libnuma_bitmask(topology, set2, numa_all_nodes_ptr);
|
||||
assert(hwloc_cpuset_isequal(set, set2));
|
||||
hwloc_cpuset_free(set2);
|
||||
|
||||
set2 = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_linux_libnuma_nodemask(topology, set2, &numa_all_nodes);
|
||||
assert(hwloc_cpuset_isequal(set, set2));
|
||||
hwloc_cpuset_free(set2);
|
||||
|
||||
|
||||
/* convert full cpuset to nodemask/bitmask */
|
||||
bitmask = hwloc_cpuset_to_linux_libnuma_bitmask(topology, set);
|
||||
assert(numa_bitmask_equal(bitmask, numa_all_nodes_ptr));
|
||||
numa_bitmask_free(bitmask);
|
||||
|
||||
hwloc_cpuset_to_linux_libnuma_nodemask(topology, set, &nodemask);
|
||||
assert(!memcmp(&nodemask, &numa_all_nodes, sizeof(nodemask_t)));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
/* convert empty nodemask/bitmask to cpuset */
|
||||
nodemask_zero(&nodemask);
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_linux_libnuma_nodemask(topology, set, &nodemask);
|
||||
assert(hwloc_cpuset_iszero(set));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
bitmask = numa_bitmask_alloc(1);
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_linux_libnuma_bitmask(topology, set, bitmask);
|
||||
numa_bitmask_free(bitmask);
|
||||
assert(hwloc_cpuset_iszero(set));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
mask=0;
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_linux_libnuma_ulongs(topology, set, &mask, HWLOC_BITS_PER_LONG);
|
||||
assert(hwloc_cpuset_iszero(set));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
|
||||
/* convert empty nodemask/bitmask from cpuset */
|
||||
set = hwloc_cpuset_alloc();
|
||||
bitmask = hwloc_cpuset_to_linux_libnuma_bitmask(topology, set);
|
||||
bitmask2 = numa_bitmask_alloc(1);
|
||||
assert(numa_bitmask_equal(bitmask, bitmask2));
|
||||
numa_bitmask_free(bitmask);
|
||||
numa_bitmask_free(bitmask2);
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_to_linux_libnuma_nodemask(topology, set, &nodemask);
|
||||
nodemask_zero(&nodemask2);
|
||||
assert(nodemask_equal(&nodemask, &nodemask2));
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
set = hwloc_cpuset_alloc();
|
||||
maxnode = HWLOC_BITS_PER_LONG;
|
||||
hwloc_cpuset_to_linux_libnuma_ulongs(topology, set, &mask, &maxnode);
|
||||
assert(!mask);
|
||||
assert(!maxnode);
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
|
||||
/* convert first node nodemask/bitmask from/to cpuset */
|
||||
node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NODE, NULL);
|
||||
if (node) {
|
||||
hwloc_cpuset_to_linux_libnuma_nodemask(topology, node->cpuset, &nodemask);
|
||||
assert(nodemask_isset(&nodemask, node->os_index));
|
||||
nodemask_clr(&nodemask, node->os_index);
|
||||
nodemask_zero(&nodemask2);
|
||||
assert(nodemask_equal(&nodemask, &nodemask2));
|
||||
|
||||
bitmask = hwloc_cpuset_to_linux_libnuma_bitmask(topology, node->cpuset);
|
||||
assert(numa_bitmask_isbitset(bitmask, node->os_index));
|
||||
numa_bitmask_clearbit(bitmask, node->os_index);
|
||||
bitmask2 = numa_bitmask_alloc(1);
|
||||
assert(numa_bitmask_equal(bitmask, bitmask2));
|
||||
numa_bitmask_free(bitmask);
|
||||
numa_bitmask_free(bitmask2);
|
||||
|
||||
maxnode = HWLOC_BITS_PER_LONG;
|
||||
hwloc_cpuset_to_linux_libnuma_ulongs(topology, node->cpuset, &mask, &maxnode);
|
||||
if (node->os_index >= HWLOC_BITS_PER_LONG) {
|
||||
assert(!maxnode);
|
||||
assert(!mask);
|
||||
} else {
|
||||
assert(maxnode = node->os_index + 1);
|
||||
assert(mask == (1U<<node->os_index));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
return 0;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <infiniband/verbs.h>
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
#include <hwloc/openfabrics-verbs.h>
|
||||
|
||||
/* check the ibverbs helpers */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
struct ibv_device **dev_list, *dev;
|
||||
int count, i;
|
||||
|
||||
dev_list = ibv_get_device_list(&count);
|
||||
if (!dev_list) {
|
||||
fprintf(stderr, "ibv_get_device_list failed\n");
|
||||
return 0;
|
||||
}
|
||||
printf("ibv_get_device_list found %d devices\n", count);
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
for(i=0; i<count; i++) {
|
||||
hwloc_cpuset_t set;
|
||||
dev = dev_list[i];
|
||||
|
||||
set = hwloc_cpuset_alloc();
|
||||
hwloc_ibv_get_device_cpuset(topology, dev, set);
|
||||
if (!set) {
|
||||
printf("failed to get cpuset for device %d (%s)\n",
|
||||
i, ibv_get_device_name(dev));
|
||||
} else {
|
||||
char *cpuset_string = NULL;
|
||||
hwloc_cpuset_asprintf(&cpuset_string, set);
|
||||
printf("got cpuset %s for device %d (%s)\n",
|
||||
cpuset_string, i, ibv_get_device_name(dev));
|
||||
free(cpuset_string);
|
||||
hwloc_cpuset_free(set);
|
||||
}
|
||||
}
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
ibv_free_device_list(dev_list);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
# Copyright 2009 INRIA, Université Bordeaux 1
|
||||
# Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
|
||||
AM_CFLAGS = $(HWLOC_CFLAGS)
|
||||
AM_CPPFLAGS = $(HWLOC_CPPFLAGS)
|
||||
AM_LDFLAGS = $(HWLOC_LDFLAGS)
|
||||
|
||||
LIBS += $(HWLOC_top_builddir)/src/libhwloc.la
|
||||
|
||||
EXTRA_DIST = test-hwloc-distrib.output
|
||||
|
||||
# Only build the utilities if we're building in standalone mode
|
||||
if HWLOC_BUILD_UTILS
|
||||
bin_PROGRAMS = lstopo hwloc-calc hwloc-bind hwloc-distrib
|
||||
endif
|
||||
|
||||
lstopo_SOURCES = lstopo.h lstopo.c lstopo-color.c lstopo-text.c lstopo-draw.c lstopo-fig.c
|
||||
if HWLOC_HAVE_CAIRO
|
||||
lstopo_SOURCES += lstopo-cairo.c
|
||||
endif
|
||||
if HWLOC_HAVE_XML
|
||||
lstopo_SOURCES += lstopo-xml.c
|
||||
endif
|
||||
if HWLOC_HAVE_WINDOWS
|
||||
lstopo_SOURCES += lstopo-windows.c
|
||||
endif
|
||||
lstopo_CFLAGS = $(HWLOC_CAIRO_CFLAGS) $(HWLOC_XML_CFLAGS)
|
||||
lstopo_LDADD = $(HWLOC_CAIRO_LIBS) $(HWLOC_XML_LIBS) -lm $(HWLOC_TERMCAP_LIBS) $(HWLOC_X11_LIBS)
|
||||
|
||||
hwloc_calc_SOURCES = hwloc-calc.c hwloc-calc.h
|
||||
|
||||
# Only run the tests if we're building standalone, because the tests
|
||||
# call hwloc executables.
|
||||
if HWLOC_BUILD_TESTS
|
||||
if !HWLOC_HAVE_MINGW32
|
||||
TESTS = test-hwloc-distrib.sh
|
||||
endif !HWLOC_HAVE_MINGW32
|
||||
endif HWLOC_BUILD_TESTS
|
||||
|
||||
# Only install man pages if we're building in standalone mode
|
||||
if HWLOC_BUILD_UTILS
|
||||
man1_pages = lstopo.1 hwloc-bind.1 hwloc-distrib.1 hwloc-calc.1
|
||||
man7_pages = hwloc.7
|
||||
man_pages = $(man7_pages) $(man1_pages)
|
||||
EXTRA_DIST += $(man1_pages:.1=.1in) $(man7_pages:.7=.7in)
|
||||
nodist_man_MANS = $(man_pages)
|
||||
|
||||
.1in.1:
|
||||
@ echo Creating $@ man page...
|
||||
@ sed -e 's/#PACKAGE_NAME#/@PACKAGE_NAME@/g' \
|
||||
-e 's/#PACKAGE_VERSION#/@PACKAGE_VERSION@/g' \
|
||||
-e 's/#HWLOC_DATE#/@HWLOC_RELEASE_DATE@/g' \
|
||||
> $@ < $<
|
||||
|
||||
.3in.3:
|
||||
@ echo Creating $@ man page...
|
||||
@ sed -e 's/#PACKAGE_NAME#/@PACKAGE_NAME@/g' \
|
||||
-e 's/#PACKAGE_VERSION#/@PACKAGE_VERSION@/g' \
|
||||
-e 's/#HWLOC_DATE#/@HWLOC_RELEASE_DATE@/g' \
|
||||
> $@ < $<
|
||||
|
||||
.7in.7:
|
||||
@ echo Creating $@ man page...
|
||||
@ sed -e 's/#PACKAGE_NAME#/@PACKAGE_NAME@/g' \
|
||||
-e 's/#PACKAGE_VERSION#/@PACKAGE_VERSION@/g' \
|
||||
-e 's/#HWLOC_DATE#/@HWLOC_RELEASE_DATE@/g' \
|
||||
> $@ < $<
|
||||
|
||||
install-exec-hook: install-man
|
||||
rm -f $(DESTDIR)$(bindir)/hwloc-ls$(EXEEXT) $(DESTDIR)$(bindir)/hwloc-info$(EXEEXT) $(DESTDIR)$(bindir)/hwloc-mask$(EXEEXT)
|
||||
cd $(DESTDIR)$(bindir) && $(LN_S) lstopo$(EXEEXT) hwloc-ls$(EXEEXT) && $(LN_S) lstopo$(EXEEXT) hwloc-info$(EXEEXT) && $(LN_S) hwloc-calc$(EXEEXT) hwloc-mask$(EXEEXT)
|
||||
rm -f $(DESTDIR)$(man1dir)/hwloc-ls.1 $(DESTDIR)$(man1dir)/hwloc-info.1 $(DESTDIR)$(man1dir)/hwloc-mask.1
|
||||
cd $(DESTDIR)$(man1dir) && $(LN_S) lstopo.1 hwloc-ls.1 && $(LN_S) lstopo.1 hwloc-info.1 && $(LN_S) hwloc-calc.1 hwloc-mask.1
|
||||
|
||||
uninstall-local:
|
||||
rm -f $(DESTDIR)$(bindir)/hwloc-ls$(EXEEXT) $(DESTDIR)$(bindir)/hwloc-info$(EXEEXT) $(DESTDIR)$(bindir)/hwloc-mask$(EXEEXT)
|
||||
rm -f $(DESTDIR)$(man1dir)/hwloc-ls.1 $(DESTDIR)$(man1dir)/hwloc-info.1 $(DESTDIR)$(man1dir)/hwloc-mask.1
|
||||
|
||||
distclean-local:
|
||||
rm -f $(man_pages)
|
||||
endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,148 +0,0 @@
|
||||
.\" -*- nroff -*-
|
||||
.\" Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
.TH HWLOC-BIND "1" "#HWLOC_DATE#" "#PACKAGE_VERSION#" "#PACKAGE_NAME#"
|
||||
.SH NAME
|
||||
hwloc-bind \- Launch a command that is bound to specific processors
|
||||
and/or memory.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Synopsis Section
|
||||
.\" **************************
|
||||
.SH SYNOPSIS
|
||||
.
|
||||
.B hwloc-bind
|
||||
[\fIoptions\fR] \fI<location1> [<location2> [...] ] [--] <command> \fR...
|
||||
.
|
||||
.\" **************************
|
||||
.\" Options Section
|
||||
.\" **************************
|
||||
.SH OPTIONS
|
||||
.
|
||||
See below for a description of valid <location> formats.
|
||||
.TP 10
|
||||
\fB\-\-get\fR
|
||||
Report the current bindings.
|
||||
.TP
|
||||
\fB\-\-single\fR
|
||||
Bind on a single CPU to prevent migration.
|
||||
.TP
|
||||
\fB\-\-strict\fR
|
||||
Require strict binding.
|
||||
.TP
|
||||
\fB\-\-get\fR
|
||||
Retrieve the current process binding
|
||||
.TP
|
||||
\fB\-\-pid\fR <pid>
|
||||
Operate on pid <pid>
|
||||
.TP
|
||||
\fB\-p\fR \fB\-\-physical\fR
|
||||
take OS/physical indexes instead of logical indexes
|
||||
.TP
|
||||
\fB\-l\fR \fB\-\-logical\fR
|
||||
take logical indexes instead of physical/OS indexes (default)
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
Verbose output.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Report version and exit.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Description Section
|
||||
.\" **************************
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
hwloc-bind execs an executable (with optional command line arguments)
|
||||
that is bound to the specified location (or list of locations). Upon
|
||||
successful execution, hwloc-bind simply sets bindings and then execs
|
||||
the executable over itself.
|
||||
.
|
||||
.PP
|
||||
.B NOTE:
|
||||
It is highly recommended that you read the hwloc(7) overview page
|
||||
before reading this man page. Most of the concepts described in
|
||||
hwloc(7) directly apply to the hwloc-bind utility.
|
||||
.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Examples Section
|
||||
.\" **************************
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
hwloc-bind's operation is best described through several examples.
|
||||
.
|
||||
.PP
|
||||
To run the echo command on the first logical processor of the second
|
||||
socket:
|
||||
|
||||
hwloc-bind socket:1.pu:0 -- echo hello
|
||||
|
||||
which is exactly equivalent to
|
||||
|
||||
hwloc-bind socket:1.pu:0 echo hello
|
||||
|
||||
To bind the "echo" command to the first core of the second socket and
|
||||
the second core of the first socket:
|
||||
|
||||
hwloc-bind socket:1.core:0 socket:0.core:1 echo hello
|
||||
|
||||
Note that binding the "echo" command to multiple processors is
|
||||
probably meaningless (because "echo" is likely implemented as a
|
||||
single-threaded application); these examples just serve to show what
|
||||
hwloc-bind can do.
|
||||
.
|
||||
.PP
|
||||
To run on the three first sockets on the second and third nodes:
|
||||
|
||||
hwloc-bind node:1-2.socket:0:3 echo hello
|
||||
|
||||
To run on processor with physical index 2 in socket with physical index 1:
|
||||
|
||||
hwloc-bind --physical socket:1.core:2 echo hello
|
||||
|
||||
To run on odd cores within even sockets:
|
||||
|
||||
hwloc-bind socket:even.core:odd echo hello
|
||||
|
||||
To run on the first socket, except on its second and fifth cores:
|
||||
|
||||
hwloc-bind socket:0 ~socket:0.core:1 ~socket:0.core:4 echo hello
|
||||
|
||||
The --get option can report current bindings. This example shows
|
||||
nesting hwloc-bind invocations to set a binding and then report it:
|
||||
|
||||
hwloc-bind node:1.socket:2 hwloc-bind --get
|
||||
|
||||
On one of the hwloc developer's machines, this example
|
||||
.
|
||||
reports "0x00004444,0x44000000". The mask reported on your machine
|
||||
may be different.
|
||||
.
|
||||
.PP
|
||||
Locations may also be specified as a hex bit mask (typically generated
|
||||
by hwloc-calc). For example:
|
||||
|
||||
hwloc-bind 0x00004444,0x44000000 echo hello
|
||||
hwloc-bind `hwloc-calc node:1.socket:2` echo hello
|
||||
.
|
||||
.\" **************************
|
||||
.\" Return value section
|
||||
.\" **************************
|
||||
.SH RETURN VALUE
|
||||
Upon successful execution, hwloc-bind execs the command over itself.
|
||||
The return value is therefore whatever the return value of the command
|
||||
is.
|
||||
.
|
||||
.PP
|
||||
hwloc-bind will return nonzero if any kind of error occurs, such as
|
||||
(but not limited to): failure to parse the command line, failure to
|
||||
retrieve process bindings, or lack of a command to execute.
|
||||
.
|
||||
.\" **************************
|
||||
.\" See also section
|
||||
.\" **************************
|
||||
.SH SEE ALSO
|
||||
.
|
||||
.ft R
|
||||
hwloc(7), lstopo(1), hwloc-calc(1), hwloc-distrib(1)
|
||||
.sp
|
@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/private.h>
|
||||
#include <hwloc-calc.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
static void usage(FILE *where)
|
||||
{
|
||||
fprintf(where, "Usage: hwloc-bind [options] <location> -- command ...\n");
|
||||
fprintf(where, " <location> may be a space-separated list of cpusets or objects\n");
|
||||
fprintf(where, " as supported by the hwloc-calc utility.\n");
|
||||
fprintf(where, "Options:\n");
|
||||
fprintf(where, " -l --logical\ttake logical object indexes (default)\n");
|
||||
fprintf(where, " -p --physical\ttake physical object indexes\n");
|
||||
fprintf(where, " --single\tbind on a single CPU to prevent migration\n");
|
||||
fprintf(where, " --strict\trequire strict binding\n");
|
||||
fprintf(where, " --get\t\tretrieve current process binding\n");
|
||||
fprintf(where, " --pid <pid>\toperate on process <pid>\n");
|
||||
fprintf(where, " -v\t\tverbose messages\n");
|
||||
fprintf(where, " --version\treport version and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
hwloc_cpuset_t cpu_set; /* invalid until bind_cpus is set */
|
||||
int get_binding = 0;
|
||||
int bind_cpus = 0;
|
||||
int single = 0;
|
||||
int verbose = 0;
|
||||
int logical = 1;
|
||||
int flags = 0;
|
||||
int opt;
|
||||
int ret;
|
||||
hwloc_pid_t pid = 0;
|
||||
char **orig_argv = argv;
|
||||
|
||||
cpu_set = hwloc_cpuset_alloc();
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
|
||||
/* skip argv[0], handle options */
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
while (argc >= 1) {
|
||||
if (!strcmp(argv[0], "--")) {
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
}
|
||||
|
||||
opt = 0;
|
||||
|
||||
if (*argv[0] == '-') {
|
||||
if (!strcmp(argv[0], "-v")) {
|
||||
verbose = 1;
|
||||
goto next;
|
||||
}
|
||||
else if (!strcmp(argv[0], "--help")) {
|
||||
usage(stdout);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else if (!strcmp(argv[0], "--single")) {
|
||||
single = 1;
|
||||
goto next;
|
||||
}
|
||||
else if (!strcmp(argv[0], "--strict")) {
|
||||
flags |= HWLOC_CPUBIND_STRICT;
|
||||
goto next;
|
||||
}
|
||||
else if (!strcmp(argv[0], "--pid")) {
|
||||
if (argc < 2) {
|
||||
usage (stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pid = atoi(argv[1]);
|
||||
opt = 1;
|
||||
goto next;
|
||||
}
|
||||
else if (!strcmp (argv[0], "--version")) {
|
||||
printf("%s %s\n", orig_argv[0], VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--logical")) {
|
||||
logical = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--physical")) {
|
||||
logical = 0;
|
||||
goto next;
|
||||
}
|
||||
else if (!strcmp (argv[0], "--get")) {
|
||||
get_binding = 1;
|
||||
goto next;
|
||||
}
|
||||
|
||||
usage(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = hwloc_mask_process_arg(topology, depth, argv[0], logical, cpu_set, verbose);
|
||||
if (ret < 0) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "assuming the command starts at %s\n", argv[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* we found at least one binding argument */
|
||||
bind_cpus = 1;
|
||||
|
||||
next:
|
||||
argc -= opt+1;
|
||||
argv += opt+1;
|
||||
}
|
||||
|
||||
if (get_binding) {
|
||||
char *s;
|
||||
int err;
|
||||
if (pid)
|
||||
err = hwloc_get_proc_cpubind(topology, pid, cpu_set, 0);
|
||||
else
|
||||
err = hwloc_get_cpubind(topology, cpu_set, 0);
|
||||
if (err) {
|
||||
const char *errmsg = strerror(errno);
|
||||
fprintf(stderr, "hwloc_get_cpubind failed (errno %d %s)\n", errno, errmsg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
s = hwloc_cpuset_printf_value(cpu_set);
|
||||
printf("%s\n", s);
|
||||
free(s);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (bind_cpus) {
|
||||
if (verbose) {
|
||||
char *s = hwloc_cpuset_printf_value(cpu_set);
|
||||
fprintf(stderr, "binding on cpu set %s\n", s);
|
||||
free(s);
|
||||
}
|
||||
if (single)
|
||||
hwloc_cpuset_singlify(cpu_set);
|
||||
if (pid)
|
||||
ret = hwloc_set_proc_cpubind(topology, pid, cpu_set, flags);
|
||||
else
|
||||
ret = hwloc_set_cpubind(topology, cpu_set, flags);
|
||||
if (ret) {
|
||||
int bind_errno = errno;
|
||||
const char *errmsg = strerror(bind_errno);
|
||||
char *s = hwloc_cpuset_printf_value(cpu_set);
|
||||
fprintf(stderr, "hwloc_set_cpubind %s failed (errno %d %s)\n", s, bind_errno, errmsg);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
hwloc_cpuset_free(cpu_set);
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
if (pid)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
if (0 == argc) {
|
||||
fprintf(stderr, "%s: nothing to do!\n", orig_argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = execvp(argv[0], argv);
|
||||
if (ret) {
|
||||
fprintf(stderr, "%s: Failed to launch executable \"%s\"\n",
|
||||
orig_argv[0], argv[0]);
|
||||
perror("execvp");
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
.\" -*- nroff -*-
|
||||
.TH HWLOC-CALC "1" "#HWLOC_DATE#" "#PACKAGE_VERSION#" "#PACKAGE_NAME#"
|
||||
.SH NAME
|
||||
hwloc-calc \- Operate on cpu mask strings and objects
|
||||
.
|
||||
.\" **************************
|
||||
.\" Synopsis Section
|
||||
.\" **************************
|
||||
.SH SYNOPSIS
|
||||
.
|
||||
.B hwloc-calc
|
||||
[\fIoptions\fR] \fI<location1> [<location2> [...] ]
|
||||
.
|
||||
.\" **************************
|
||||
.\" Options Section
|
||||
.\" **************************
|
||||
.SH OPTIONS
|
||||
.
|
||||
.TP 10
|
||||
\fB\-p\fR \fB\-\-physical\fR
|
||||
Use OS/physical indexes instead of logical indexes for both input and output.
|
||||
.TP
|
||||
\fB\-l\fR \fB\-\-logical\fR
|
||||
Use logical indexes instead of physical/OS indexes for both input and output (default).
|
||||
.TP
|
||||
\fB\-\-pi\fR \fB\-\-physical\-input\fR
|
||||
Use OS/physical indexes instead of logical indexes for input.
|
||||
.TP
|
||||
\fB\-\-li\fR \fB\-\-logical\-input\fR
|
||||
Use logical indexes instead of physical/OS indexes for input (default).
|
||||
.TP
|
||||
\fB\-\-po\fR \fB\-\-physical\-input\fR
|
||||
Use OS/physical indexes instead of logical indexes for output.
|
||||
.TP
|
||||
\fB\-\-lo\fR \fB\-\-logical\-output\fR
|
||||
Use logical indexes instead of physical/OS indexes for output (default).
|
||||
.TP
|
||||
\fB\-\-proclist\fR
|
||||
Report the comma-separated list of processors' indexes instead of the cpu mask string.
|
||||
When combined with \fB\-\-physical\fR, the list is convenient to pass to external
|
||||
tools such as taskset or numactl \fB\-\-physcpubind\fR.
|
||||
.TP
|
||||
\fB\-\-nodelist\fR
|
||||
Report the comma-separated list of memory nodes' indexes instead of the cpu mask string.
|
||||
When combined with \fB\-\-physical\fR, the list is convenient to pass to external
|
||||
tools such as numactl \fB\-\-membind\fR.
|
||||
.TP
|
||||
\fB\-\-objects\fR
|
||||
Report the list of highest objects instead of the cpu mask string.
|
||||
.TP
|
||||
\fB\-\-single\fR
|
||||
Singlify the output to a single CPU.
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
Verbose output.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Report version and exit.
|
||||
.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Description Section
|
||||
.\" **************************
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
hwloc-calc generates and manipulates CPU mask strings or objects.
|
||||
Both input and output may be either objects (with physical or logical
|
||||
indexes) or CPU mask strings (no logical or physical index involved).
|
||||
.
|
||||
.PP
|
||||
.B NOTE:
|
||||
It is highly recommended that you read the hwloc(7) overview page
|
||||
before reading this man page. Most of the concepts described in
|
||||
hwloc(7) directly apply to the hwloc-calc utility.
|
||||
.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Examples Section
|
||||
.\" **************************
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
hwloc-calc's operation is best described through several examples.
|
||||
.
|
||||
.PP
|
||||
To display the CPU mask corresponding to the second socket:
|
||||
|
||||
hwloc-calc socket:1
|
||||
|
||||
To display the CPU mask corresponding to the third socket, excluding
|
||||
its even numbered logical priocessors:
|
||||
|
||||
hwloc-calc socket:2 ~proc:even
|
||||
|
||||
To combine two CPU masks:
|
||||
|
||||
hwloc-calc 0x0000ffff 0xff000000
|
||||
|
||||
To display the list of logical processors included in the second
|
||||
socket:
|
||||
|
||||
hwloc-calc --proclist socket:1
|
||||
|
||||
To display the list of NUMA nodes, by physical indexes, that intersect a given CPU mask:
|
||||
|
||||
hwloc-calc --physical --nodelist 0xf0f0f0f0
|
||||
|
||||
To display the physical index of a processor given by its logical index:
|
||||
|
||||
hwloc-calc proc:2 --physical-output --proclist
|
||||
|
||||
To combine both physical and logical indexes as input:
|
||||
|
||||
hwloc-calc proc:2 --physical-input proc:3
|
||||
|
||||
.
|
||||
.\" **************************
|
||||
.\" Return value section
|
||||
.\" **************************
|
||||
.SH RETURN VALUE
|
||||
Upon successful execution, hwloc-calc displays the CPU mask string.
|
||||
The return value is 0.
|
||||
.
|
||||
.
|
||||
.PP
|
||||
hwloc-calc will return nonzero if any kind of error occurs, such as
|
||||
(but not limited to): failure to parse the command line.
|
||||
.
|
||||
.\" **************************
|
||||
.\" See also section
|
||||
.\" **************************
|
||||
.SH SEE ALSO
|
||||
.
|
||||
.ft R
|
||||
hwloc(7)
|
||||
.sp
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/private.h>
|
||||
#include <hwloc-calc.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static void usage(FILE *where)
|
||||
{
|
||||
fprintf(where, "Usage: hwloc-calc [options] <location> ...\n");
|
||||
fprintf(where, " <location> may be a space-separated list of cpusets or objects\n");
|
||||
fprintf(where, " as supported by the hwloc-bind utility.\n");
|
||||
fprintf(where, "Options:\n");
|
||||
fprintf(where, " -l --logical\tuse logical object indexes (default)\n");
|
||||
fprintf(where, " -p --physical\tuse physical object indexes\n");
|
||||
fprintf(where, " --li --logical-input\tuse logical indexes for input (default)\n");
|
||||
fprintf(where, " --lo --logical-output\tuse logical indexes for output (default)\n");
|
||||
fprintf(where, " --pi --physical-input\tuse physical indexes for input\n");
|
||||
fprintf(where, " --po --physical-output\tuse physical indexes for output\n");
|
||||
fprintf(where, " --PUlist\treport the list of processing units' indexes in the CPU set\n");
|
||||
fprintf(where, " --nodelist\treport the list of memory nodes' indexes near the CPU set\n");
|
||||
fprintf(where, " --objects\treport the list of largest objects in the CPU set\n");
|
||||
fprintf(where, " --single\tsinglify the output to a single CPU\n");
|
||||
fprintf(where, " -v\t\tverbose messages\n");
|
||||
fprintf(where, " --version\treport version and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
unsigned depth;
|
||||
hwloc_cpuset_t set;
|
||||
int verbose = 0;
|
||||
int logicali = 1;
|
||||
int logicalo = 1;
|
||||
int nodelist = 0;
|
||||
int pulist = 0;
|
||||
int showobjs = 0;
|
||||
int singlify = 0;
|
||||
char **orig_argv = argv;
|
||||
|
||||
set = hwloc_cpuset_alloc();
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
depth = hwloc_topology_get_depth(topology);
|
||||
|
||||
while (argc >= 2) {
|
||||
if (*argv[1] == '-') {
|
||||
if (!strcmp(argv[1], "-v")) {
|
||||
verbose = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--help")) {
|
||||
usage(stdout);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (!strcasecmp(argv[1], "--pulist") || !strcmp(argv[1], "--proclist") /* backward compat with 0.9 */) {
|
||||
pulist = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--nodelist")) {
|
||||
nodelist = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--objects")) {
|
||||
showobjs = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--version")) {
|
||||
printf("%s %s\n", orig_argv[0], VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (!strcmp(argv[1], "-l") || !strcmp(argv[1], "--logical")) {
|
||||
logicali = 1;
|
||||
logicalo = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--li") || !strcmp(argv[1], "--logical-input")) {
|
||||
logicali = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--lo") || !strcmp(argv[1], "--logical-output")) {
|
||||
logicalo = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "-p") || !strcmp(argv[1], "--physical")) {
|
||||
logicali = 0;
|
||||
logicalo = 0;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--pi") || !strcmp(argv[1], "--physical-input")) {
|
||||
logicali = 0;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--po") || !strcmp(argv[1], "--physical-output")) {
|
||||
logicalo = 0;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[1], "--single")) {
|
||||
singlify = 1;
|
||||
goto next;
|
||||
}
|
||||
usage(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (hwloc_mask_process_arg(topology, depth, argv[1], logicali, set, verbose) < 0) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "ignored unrecognized argument %s\n", argv[1]);
|
||||
}
|
||||
|
||||
next:
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (singlify)
|
||||
hwloc_cpuset_singlify(set);
|
||||
|
||||
if (showobjs) {
|
||||
hwloc_cpuset_t remaining = hwloc_cpuset_dup(set);
|
||||
int first = 1;
|
||||
while (!hwloc_cpuset_iszero(remaining)) {
|
||||
char type[64];
|
||||
unsigned idx;
|
||||
hwloc_obj_t obj = hwloc_get_first_largest_obj_inside_cpuset(topology, remaining);
|
||||
hwloc_obj_type_snprintf(type, sizeof(type), obj, 1);
|
||||
idx = logicalo ? obj->logical_index : obj->os_index;
|
||||
if (idx == (unsigned) -1)
|
||||
printf("%s%s", first ? "" : " ", type);
|
||||
else
|
||||
printf("%s%s:%u", first ? "" : " ", type, idx);
|
||||
hwloc_cpuset_andnot(remaining, remaining, obj->cpuset);
|
||||
first = 0;
|
||||
}
|
||||
printf("\n");
|
||||
hwloc_cpuset_free(remaining);
|
||||
} else if (pulist) {
|
||||
hwloc_obj_t proc, prev = NULL;
|
||||
while ((proc = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PU, prev)) != NULL) {
|
||||
if (prev)
|
||||
printf(",");
|
||||
printf("%u", logicalo ? proc->logical_index : proc->os_index);
|
||||
prev = proc;
|
||||
}
|
||||
printf("\n");
|
||||
} else if (nodelist) {
|
||||
hwloc_obj_t node, prev = NULL;
|
||||
while ((node = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_NODE, prev)) != NULL) {
|
||||
if (prev)
|
||||
printf(",");
|
||||
printf("%u", logicalo ? node->logical_index : node->os_index);
|
||||
prev = node;
|
||||
}
|
||||
printf("\n");
|
||||
} else {
|
||||
char *string = NULL;
|
||||
hwloc_cpuset_asprintf(&string, set);
|
||||
printf("%s\n", string);
|
||||
free(string);
|
||||
}
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
|
||||
hwloc_cpuset_free(set);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_MASK_H
|
||||
#define HWLOC_MASK_H
|
||||
|
||||
#include <private/config.h>
|
||||
#include <private/private.h>
|
||||
#include <private/misc.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef enum hwloc_mask_append_mode_e {
|
||||
HWLOC_MASK_APPEND_ADD,
|
||||
HWLOC_MASK_APPEND_CLR,
|
||||
HWLOC_MASK_APPEND_AND,
|
||||
HWLOC_MASK_APPEND_XOR,
|
||||
} hwloc_mask_append_mode_t;
|
||||
|
||||
static inline int
|
||||
hwloc_mask_append_cpuset(hwloc_cpuset_t set, hwloc_const_cpuset_t newset,
|
||||
hwloc_mask_append_mode_t mode, int verbose)
|
||||
{
|
||||
char *s1 = hwloc_cpuset_printf_value(newset);
|
||||
char *s2 = hwloc_cpuset_printf_value(set);
|
||||
switch (mode) {
|
||||
case HWLOC_MASK_APPEND_ADD:
|
||||
if (verbose)
|
||||
fprintf(stderr, "adding %s to %s\n",
|
||||
s1, s2);
|
||||
hwloc_cpuset_or(set, set, newset);
|
||||
break;
|
||||
case HWLOC_MASK_APPEND_CLR:
|
||||
if (verbose)
|
||||
fprintf(stderr, "clearing %s from %s\n",
|
||||
s1, s2);
|
||||
hwloc_cpuset_andnot(set, set, newset);
|
||||
break;
|
||||
case HWLOC_MASK_APPEND_AND:
|
||||
if (verbose)
|
||||
fprintf(stderr, "and'ing %s from %s\n",
|
||||
s1, s2);
|
||||
hwloc_cpuset_and(set, set, newset);
|
||||
break;
|
||||
case HWLOC_MASK_APPEND_XOR:
|
||||
if (verbose)
|
||||
fprintf(stderr, "xor'ing %s from %s\n",
|
||||
s1, s2);
|
||||
hwloc_cpuset_xor(set, set, newset);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
free(s1);
|
||||
free(s2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline hwloc_obj_t __hwloc_attribute_pure
|
||||
hwloc_mask_get_obj_inside_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t rootset,
|
||||
unsigned depth, unsigned i, int logical)
|
||||
{
|
||||
if (logical) {
|
||||
return hwloc_get_obj_inside_cpuset_by_depth(topology, rootset, depth, i);
|
||||
} else {
|
||||
hwloc_obj_t obj = NULL;
|
||||
while ((obj = hwloc_get_next_obj_inside_cpuset_by_depth(topology, rootset, depth, obj)) != NULL) {
|
||||
if (obj->os_index == i)
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
hwloc_mask_append_object(hwloc_topology_t topology, unsigned topodepth,
|
||||
hwloc_const_cpuset_t rootset, const char *string, int logical,
|
||||
hwloc_cpuset_t set, int verbose)
|
||||
{
|
||||
hwloc_obj_t obj;
|
||||
unsigned depth, width;
|
||||
char *sep, *sep2, *sep3;
|
||||
unsigned first, wrap, amount, step;
|
||||
unsigned i,j;
|
||||
|
||||
if (!hwloc_namecoloncmp(string, "system", 2))
|
||||
depth = hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_SYSTEM);
|
||||
else if (!hwloc_namecoloncmp(string, "machine", 1))
|
||||
depth = hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_MACHINE);
|
||||
else if (!hwloc_namecoloncmp(string, "node", 1))
|
||||
depth = hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_NODE);
|
||||
else if (!hwloc_namecoloncmp(string, "socket", 2))
|
||||
depth = hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_SOCKET);
|
||||
else if (!hwloc_namecoloncmp(string, "core", 1))
|
||||
depth = hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_CORE);
|
||||
else if (!hwloc_namecoloncmp(string, "pu", 1) || !hwloc_namecoloncmp(string, "proc", 1) /* backward compat with 0.9 */)
|
||||
depth = hwloc_get_type_or_above_depth(topology, HWLOC_OBJ_PU);
|
||||
else {
|
||||
char *end;
|
||||
depth = strtol(string, &end, 0);
|
||||
if (end == string) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "invalid object name %s\n", string);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth >= topodepth) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "ignoring invalid depth %u\n", depth);
|
||||
return -1;
|
||||
}
|
||||
width = hwloc_get_nbobjs_by_depth(topology, depth);
|
||||
|
||||
sep = strchr(string, ':');
|
||||
if (!sep) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "missing colon separator in argument %s\n", string);
|
||||
return -1;
|
||||
}
|
||||
|
||||
first = atoi(sep+1);
|
||||
amount = 1;
|
||||
step = 1;
|
||||
wrap = 0;
|
||||
if (!isdigit(*(sep+1))) {
|
||||
if (!strncmp(sep+1, "all", 3)) {
|
||||
first = 0;
|
||||
amount = width;
|
||||
} else if (!strncmp(sep+1, "odd", 3)) {
|
||||
first = 1;
|
||||
step = 2;
|
||||
amount = (width+1)/2;
|
||||
} else if (!strncmp(sep+1, "even", 4)) {
|
||||
first = 0;
|
||||
step = 2;
|
||||
amount = (width+1)/2;
|
||||
}
|
||||
}
|
||||
|
||||
sep3 = strchr(sep+1, '.');
|
||||
|
||||
sep2 = strchr(sep+1, '-');
|
||||
if (sep2 && (sep2 < sep3 || !sep3)) {
|
||||
if (*(sep2+1) == '\0')
|
||||
amount = width-first;
|
||||
else
|
||||
amount = atoi(sep2+1)-first+1;
|
||||
} else {
|
||||
sep2 = strchr(sep+1, ':');
|
||||
if (sep2 && (sep2 < sep3 || !sep3)) {
|
||||
amount = atoi(sep2+1);
|
||||
wrap = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=first, j=0; j<amount; i+=step, j++) {
|
||||
if (wrap && i==width)
|
||||
i = 0;
|
||||
|
||||
obj = hwloc_mask_get_obj_inside_cpuset_by_depth(topology, rootset, depth, i, logical);
|
||||
if (verbose) {
|
||||
char * s = hwloc_cpuset_printf_value(rootset);
|
||||
if (obj)
|
||||
printf("object #%u depth %u below cpuset %s found\n",
|
||||
i, depth, s);
|
||||
else
|
||||
printf("object #%u depth %u below cpuset %s does not exist\n",
|
||||
i, depth, s);
|
||||
free(s);
|
||||
}
|
||||
if (obj) {
|
||||
if (sep3)
|
||||
hwloc_mask_append_object(topology, topodepth, obj->cpuset, sep3+1, logical, set, verbose);
|
||||
else
|
||||
/* add to the temporary cpuset
|
||||
* and let the caller add/clear/and/xor for the actual final cpuset depending on cmdline options
|
||||
*/
|
||||
hwloc_mask_append_cpuset(set, obj->cpuset, HWLOC_MASK_APPEND_ADD, verbose);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
hwloc_mask_process_arg(hwloc_topology_t topology, unsigned topodepth,
|
||||
const char *arg, int logical, hwloc_cpuset_t set,
|
||||
int verbose)
|
||||
{
|
||||
char *colon;
|
||||
hwloc_mask_append_mode_t mode = HWLOC_MASK_APPEND_ADD;
|
||||
int err;
|
||||
|
||||
if (*arg == '~') {
|
||||
mode = HWLOC_MASK_APPEND_CLR;
|
||||
arg++;
|
||||
} else if (*arg == 'x') {
|
||||
mode = HWLOC_MASK_APPEND_AND;
|
||||
arg++;
|
||||
} else if (*arg == '^') {
|
||||
mode = HWLOC_MASK_APPEND_XOR;
|
||||
arg++;
|
||||
}
|
||||
|
||||
colon = strchr(arg, ':');
|
||||
if (colon) {
|
||||
hwloc_cpuset_t newset = hwloc_cpuset_alloc();
|
||||
err = hwloc_mask_append_object(topology, topodepth, hwloc_topology_get_complete_cpuset(topology), arg, logical, newset, verbose);
|
||||
if (!err)
|
||||
err = hwloc_mask_append_cpuset(set, newset, mode, verbose);
|
||||
hwloc_cpuset_free(newset);
|
||||
} else {
|
||||
/* try to parse as a comma-separated list of integer with 0x as an optional prefix */
|
||||
char *tmp = (char*) arg;
|
||||
hwloc_cpuset_t newset;
|
||||
while (1) {
|
||||
char *next = strchr(tmp, ',');
|
||||
size_t len;
|
||||
if (strncasecmp(tmp, "0x", 2) == 0) {
|
||||
tmp += 2;
|
||||
if (',' == *tmp || 0 == *tmp) {
|
||||
err = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
len = next ? (size_t) (next-tmp) : strlen(tmp);
|
||||
if (len != strspn(tmp, "0123456789abcdefABCDEF")) {
|
||||
err = -1;
|
||||
goto out;
|
||||
}
|
||||
if (!next)
|
||||
break;
|
||||
tmp = next+1;
|
||||
}
|
||||
newset = hwloc_cpuset_alloc();
|
||||
hwloc_cpuset_from_string(newset, arg);
|
||||
err = hwloc_mask_append_cpuset(set, newset, mode, verbose);
|
||||
hwloc_cpuset_free(newset);
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* HWLOC_MASK_H */
|
@ -1,106 +0,0 @@
|
||||
.\" -*- nroff -*-
|
||||
.TH HWLOC-DISTRIB "1" "#HWLOC_DATE#" "#PACKAGE_VERSION#" "#PACKAGE_NAME#"
|
||||
.SH NAME
|
||||
hwloc-distrib \- Build a number of cpu masks distributed on the system
|
||||
.
|
||||
.\" **************************
|
||||
.\" Synopsis Section
|
||||
.\" **************************
|
||||
.SH SYNOPSIS
|
||||
.B topodistrib
|
||||
[\fIoptions\fR] \fI<integer>\fR
|
||||
.
|
||||
.\" **************************
|
||||
.\" Options Section
|
||||
.\" **************************
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-single\fR
|
||||
Singlify each output to a single CPU.
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
Verbose messages.
|
||||
.TP
|
||||
\fB\-\-synthetic\fR "2 2"
|
||||
Simulate a fake hierarchy.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Report version and exit.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Description Section
|
||||
.\" **************************
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
hwloc-distrib generates a series of CPU masks in an attempt to
|
||||
distribute a set of processes around multiple processors in a single
|
||||
server. These masks can be used with hwloc-bind(1).
|
||||
.
|
||||
.PP
|
||||
.B NOTE:
|
||||
It is highly recommended that you read the hwloc(7) overview page
|
||||
before reading this man page. Most of the concepts described in
|
||||
hwloc(7) directly apply to the hwloc-bind utility.
|
||||
.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Examples Section
|
||||
.\" **************************
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
hwloc-distrib's operation is best described through several examples.
|
||||
.
|
||||
.PP
|
||||
If 4 processes have to be distributed across a machine, their CPU masks
|
||||
may be obtained with:
|
||||
|
||||
$ hwloc-distrib 4
|
||||
0x0000000f
|
||||
0x00000f00
|
||||
0x000000f0
|
||||
0x0000f000
|
||||
|
||||
To get a single processor of each CPU masks (prevent migration in case
|
||||
of binding)
|
||||
|
||||
$ hwloc-distrib 4 --single
|
||||
0x00000001
|
||||
0x00000100
|
||||
0x00000010
|
||||
0x00001000
|
||||
|
||||
Each output line may be converted independently with hwloc-calc and xargs:
|
||||
|
||||
$ hwloc-distrib 4 --single | xargs -n 1 hwloc-calc --objects
|
||||
PU:0
|
||||
PU:1
|
||||
PU:2
|
||||
PU:3
|
||||
|
||||
To convert the output into a list of processors that may be passed to
|
||||
dplace -c inside a mpirun command line:
|
||||
|
||||
$ hwloc-distrib 4 --single | xargs hwloc-calc --pulist
|
||||
0,8,4,16
|
||||
.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Return value section
|
||||
.\" **************************
|
||||
.SH RETURN VALUE
|
||||
Upon successful execution, hwloc-distrib displays one or more CPU mask
|
||||
strings. The return value is 0.
|
||||
.
|
||||
.
|
||||
.PP
|
||||
hwloc-distrib will return nonzero if any kind of error occurs, such as
|
||||
(but not limited to) failure to parse the command line.
|
||||
.
|
||||
.\" **************************
|
||||
.\" See also section
|
||||
.\" **************************
|
||||
.SH SEE ALSO
|
||||
.
|
||||
.ft R
|
||||
hwloc(7)
|
||||
.sp
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/private.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
static void usage(FILE *where)
|
||||
{
|
||||
fprintf(where, "Usage: hwloc-distrib [options] number\n");
|
||||
fprintf(where, "Options:\n");
|
||||
fprintf(where, " --single\tsinglify each output to a single CPU\n");
|
||||
fprintf(where, " -v\t\t\tverbose messages\n");
|
||||
fprintf(where, " --synthetic \"2 2\"\tsimulate a fake hierarchy\n");
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
fprintf(where, " --xml <path>\t\tread topology from XML file <path>\n");
|
||||
#endif
|
||||
fprintf(where, " --version\t\treport version and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
long n = -1;
|
||||
char * synthetic = NULL;
|
||||
const char * xmlpath = NULL;
|
||||
int singlify = 0;
|
||||
int verbose = 0;
|
||||
char **orig_argv = argv;
|
||||
|
||||
/* skip argv[0], handle options */
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
while (argc >= 1) {
|
||||
if (!strcmp(argv[0], "--")) {
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*argv[0] == '-') {
|
||||
if (!strcmp(argv[0], "--single")) {
|
||||
singlify = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[0], "-v")) {
|
||||
verbose = 1;
|
||||
goto next;
|
||||
}
|
||||
if (!strcmp(argv[0], "--help")) {
|
||||
usage(stdout);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (!strcmp (argv[0], "--synthetic")) {
|
||||
if (argc <= 2) {
|
||||
usage(stdout);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
synthetic = argv[1];
|
||||
argv++;
|
||||
argc--;
|
||||
goto next;
|
||||
}
|
||||
else if (!strcmp (argv[0], "--version")) {
|
||||
printf("%s %s\n", orig_argv[0], VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
if (!strcmp (argv[0], "--xml")) {
|
||||
if (argc <= 2) {
|
||||
usage(stdout);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlpath = argv[1];
|
||||
argc--;
|
||||
argv++;
|
||||
if (!strcmp(xmlpath, "-"))
|
||||
xmlpath = "/dev/stdin";
|
||||
goto next;
|
||||
}
|
||||
#endif /* HWLOC_HAVE_XML */
|
||||
|
||||
usage(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (n != -1) {
|
||||
fprintf(stderr,"duplicate number\n");
|
||||
usage(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
n = atol(argv[0]);
|
||||
|
||||
next:
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (n == -1) {
|
||||
fprintf(stderr,"need a number\n");
|
||||
usage(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "distributing %ld\n", n);
|
||||
|
||||
{
|
||||
long i;
|
||||
hwloc_cpuset_t cpuset[n];
|
||||
hwloc_topology_t topology;
|
||||
|
||||
hwloc_topology_init(&topology);
|
||||
if (synthetic)
|
||||
hwloc_topology_set_synthetic(topology, synthetic);
|
||||
if (xmlpath)
|
||||
hwloc_topology_set_xml(topology, xmlpath);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
hwloc_distribute(topology, hwloc_get_root_obj(topology), cpuset, n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char *str = NULL;
|
||||
if (singlify)
|
||||
hwloc_cpuset_singlify(cpuset[i]);
|
||||
hwloc_cpuset_asprintf(&str, cpuset[i]);
|
||||
printf("%s\n", str);
|
||||
free(str);
|
||||
hwloc_cpuset_free(cpuset[i]);
|
||||
}
|
||||
hwloc_topology_destroy(topology);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,290 +0,0 @@
|
||||
.\" -*- nroff -*-
|
||||
.\" Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
|
||||
.TH HWLOC "1" "#HWLOC_DATE#" "#PACKAGE_VERSION#" "#PACKAGE_NAME#"
|
||||
.SH NAME
|
||||
hwloc - General information about hwloc ("hardware locality").
|
||||
.
|
||||
.\" **************************
|
||||
.\" Description Section
|
||||
.\" **************************
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
hwloc provides command line tools and a C API to obtain the
|
||||
hierarchical map of key computing elements, such as: NUMA memory
|
||||
nodes, shared caches, processor sockets, processor cores, and
|
||||
processor "threads". hwloc also gathers various attributes such as
|
||||
cache and memory information, and is portable across a variety of
|
||||
different operating systems and platforms.
|
||||
.
|
||||
.
|
||||
.SS Definitions
|
||||
Hwloc has some specific definitions for terms that are used in this
|
||||
man page and other hwloc documentation.
|
||||
.
|
||||
.TP 5
|
||||
.B Hwloc CPU set:
|
||||
A set of processors included in an hwloc object, expressed as a bitmask
|
||||
indexed by the physical numbers of the CPUs (as announced by the OS).
|
||||
The hwloc definition
|
||||
of "CPU set" does not carry any the same connotations as Linux's "CPU
|
||||
set" (e.g., process affinity, etc.).
|
||||
.
|
||||
.TP
|
||||
.B Linux CPU set:
|
||||
See http://www.mjmwired.net/kernel/Documentation/cpusets.txt for a
|
||||
discussion of Linux CPU sets. A
|
||||
super-short-ignoring-many-details description (taken from that page)
|
||||
is:
|
||||
.
|
||||
.\" Force a paragraph break, but keep the indentation
|
||||
.TP
|
||||
\
|
||||
.
|
||||
"Cpusets provide a mechanism for assigning a set of CPUs and Memory
|
||||
Nodes to a set of tasks."
|
||||
.
|
||||
.TP
|
||||
.B Linux Cgroup:
|
||||
See http://www.mjmwired.net/kernel/Documentation/cgroups.txt for a
|
||||
discussion of Linux control groups. A
|
||||
super-short-ignoring-many-details description (taken from that page)
|
||||
is:
|
||||
.
|
||||
.\" Force a paragraph break, but keep the indentation
|
||||
.TP
|
||||
\
|
||||
"Control Groups provide a mechanism for aggregating/partitioning sets
|
||||
of tasks, and all their future children, into hierarchical groups
|
||||
with specialized behaviour."
|
||||
.
|
||||
.PP
|
||||
To be clear, hwloc supports all of the above concepts. It is simply
|
||||
worth noting that they are 3 different things.
|
||||
.
|
||||
.SS Location Specification
|
||||
.
|
||||
Locations refer to specific regions within a topology. Before reading
|
||||
the rest of this man page, it may be useful to read lstopo(1) and/or
|
||||
run lstopo on your machine to see the reported topology tree. Seeing
|
||||
and understanding a topology tree will definitely help in
|
||||
understanding the concepts that are discussed below.
|
||||
.
|
||||
.PP
|
||||
Locations can be specified in multiple ways:
|
||||
.
|
||||
.TP 10
|
||||
.B Tuples:
|
||||
Tuples of hwloc "objects" and associated indexes can be specified in
|
||||
the form
|
||||
.IR object:index .
|
||||
Hwloc objects represent types of mapped items (e.g., sockets, cores,
|
||||
etc.) in a topology tree; indexes are non-negative integers that
|
||||
specify a unique physical object in a topology tree. Both concepts
|
||||
are described in detail, below.
|
||||
.\" Force a paragraph break, but keep the indentation.
|
||||
.TP
|
||||
\
|
||||
Chaining multiple tuples together in the more general form
|
||||
.I object1:index[.object2:index2[...]]
|
||||
is permissable. While the first tuple's object may appear anywhere in
|
||||
the topology, the Nth tuple's object must have a shallower topology
|
||||
depth than the (N+1)th tuple's object. Put simply: as you move right
|
||||
in a tuple chain, objects must go deeper in the topology tree.
|
||||
When using logical indexes (default),
|
||||
indexes specified in chained tuples are relative to the scope of the
|
||||
parent object. For example, "socket:0.core:1" refers to the second
|
||||
core in the first socket.
|
||||
When using OS/physical indexes, the first object matching the given
|
||||
index is used.
|
||||
.
|
||||
.TP
|
||||
.B Hex:
|
||||
Locations can also be specified as hexidecimal bitmasks prefixed
|
||||
.
|
||||
with "0x". Commas must be used to separate the hex digits into blocks
|
||||
of 8, such as "0xffc0140,0x00020110".
|
||||
.
|
||||
Leading zeros in each block do not need to be specified.
|
||||
.
|
||||
For example, "0xffc0140,0x20110" is equivalent to the prior example,
|
||||
and "0x0000000f" is exactly equivalent to "0xf". Intermediate blocks
|
||||
of 8 digits that are all zeoro can be left empty; "0xff0,,0x13" is
|
||||
equivalent to "0xff0,0x00000000,0x13".
|
||||
.
|
||||
.PP
|
||||
Multiple locations can be specified on the hwloc-bind command line
|
||||
(delimited by whitespace); the first token of the execution command is
|
||||
assumed to either follow "--" (if specified) or the first token that
|
||||
is unrecognized as a location.
|
||||
.
|
||||
By default, multiple locations are added, meaning that the binding
|
||||
will be wider in the sense that the process may run on more objects.
|
||||
If prefixed with "~", the given location will be cleared instead of
|
||||
added to the current list of locations.
|
||||
If prefixed with "x", the given location will be and'ed instead of
|
||||
added to the current list.
|
||||
If prefixed with "^", the given location will be xor'ed.
|
||||
.
|
||||
More complex operations may be performed by using
|
||||
.R hwloc-calc
|
||||
to compute intermediate values.
|
||||
.
|
||||
.SS Hwloc Objects
|
||||
.
|
||||
.PP
|
||||
Objects can be any of the following strings
|
||||
.
|
||||
(listed from "biggest" to "smallest"):
|
||||
.
|
||||
.TP 10
|
||||
.B machine
|
||||
A set of processors and memory.
|
||||
.
|
||||
.TP
|
||||
.B node
|
||||
A NUMA node; a set of processors around memory which the processors
|
||||
can directly access.
|
||||
.
|
||||
.TP
|
||||
.B socket
|
||||
Typically a physical package or chip, it is a grouping of one or more
|
||||
processors.
|
||||
.
|
||||
.TP
|
||||
.B core
|
||||
A single, physical processing unit which may still contain multiple
|
||||
logical processors, such as hardware threads.
|
||||
.
|
||||
.TP
|
||||
.B proc
|
||||
Short for
|
||||
.I processor
|
||||
(not
|
||||
.IR process !).
|
||||
The smallest physical execution unit that hwloc recognizes. For
|
||||
example, there may be multiple procs on a core (e.g.,
|
||||
hardware threads).
|
||||
.PP
|
||||
The additional
|
||||
.B system
|
||||
type can be used when several machines form an overall single system image
|
||||
(SSI), such as Kerrighed.
|
||||
.
|
||||
.PP
|
||||
Finally, note that an object can be denoted by its numeric "depth" in
|
||||
the topology graph. See the Examples section for more information.
|
||||
.
|
||||
.SS Hwloc Indexes
|
||||
Indexes are integer values that uniquely specify a given object of a
|
||||
specific type. Indexes can be expressed either as
|
||||
.I logical
|
||||
values or
|
||||
.I physical
|
||||
values.
|
||||
While
|
||||
.B hwloc-bind accepts logical indexes as
|
||||
.BR input
|
||||
by default.
|
||||
Passing
|
||||
.B --physical
|
||||
switches to physical/OS indexes.
|
||||
Both logical and physical indexes are described on this man page.
|
||||
.
|
||||
.PP
|
||||
.I Logical
|
||||
indexes are relative to the object order in the output from the
|
||||
lstopo command. They always start with 0 and increment by 1 for each
|
||||
successive object.
|
||||
.
|
||||
.PP
|
||||
.I Physical
|
||||
indexes are how the operating system refers to objects. Note that
|
||||
while physical indexes are non-negative integer values, the hardware
|
||||
and/or operating system may choose arbitrary values -- they may not
|
||||
start with 0, and successive objects may not have consecutive values.
|
||||
.
|
||||
.PP
|
||||
For example, if the first few lines of lstopo -p output are the
|
||||
following:
|
||||
.
|
||||
|
||||
System(32GB)
|
||||
Node#0(16GB)
|
||||
Socket#0 + L2(4MB)
|
||||
L1(32KB) + Core#16 + P#0
|
||||
L1(32KB) + Core#18 + P#2
|
||||
Socket#1 + L2(4MB)
|
||||
L1(32KB) + Core#16 + P#1
|
||||
L1(32KB) + Core#18 + P#3
|
||||
|
||||
The first core on the second socket is logically number 2 (i.e.,
|
||||
logically the 3rd core, starting from 0). Its physical index is
|
||||
16, but note that another core
|
||||
.I also
|
||||
has a physical index of 16. Hence, physical indexes may only be
|
||||
relevant within the scope of their parent (or set of grandparents).
|
||||
In this example, to uniquely identify logical core 2 with
|
||||
physical indexes, you must specify (at a minimum) both a socket and a
|
||||
core: socket 1, core 16.
|
||||
.PP
|
||||
Index values, regardless of whether they are logical or physical, can
|
||||
be expressed in several different forms (where X, Y, and N are
|
||||
positive integers):
|
||||
.
|
||||
.TP 10
|
||||
.B X
|
||||
The object with index value X.
|
||||
.
|
||||
.TP
|
||||
.B X-Y
|
||||
All the objects with index values >= X and <= Y.
|
||||
.
|
||||
.TP
|
||||
.B X-
|
||||
All the objects with index values >= X.
|
||||
.
|
||||
.TP
|
||||
.B X:N
|
||||
N objects starting with index X, possibly wrapping around the end of
|
||||
the level.
|
||||
.
|
||||
.TP
|
||||
.B all
|
||||
A special index value indicating all valid index values.
|
||||
.
|
||||
.TP
|
||||
.B odd
|
||||
A special index value indicating all valid odd index values.
|
||||
.
|
||||
.TP
|
||||
.B even
|
||||
A special index value indicating all valid even index values.
|
||||
.
|
||||
.PP
|
||||
.IR REMEMBER :
|
||||
hwloc's command line tools accept
|
||||
.I logical
|
||||
indexes for location values by default.
|
||||
Use
|
||||
.BR --physical " and " --logical
|
||||
to switch from one mode to another.
|
||||
.
|
||||
.\" **************************
|
||||
.\" See also section
|
||||
.\" **************************
|
||||
.SH SEE ALSO
|
||||
.
|
||||
Hwloc's command line tool documentation: lstopo(1), hwloc-bind(1),
|
||||
hwloc-calc(1), hwloc-distrib(1).
|
||||
.
|
||||
.PP
|
||||
Hwloc has many C API functions, each of which have their own man page.
|
||||
Some top-level man pages are also provided, grouping similar functions
|
||||
together. A few good places to start might include:
|
||||
hwlocality_objects(3), hwlocality_types(3), hwlocality_creation(3),
|
||||
hwlocality_cpuset(3), hwlocality_information(3), and
|
||||
hwlocality_binding(3).
|
||||
.
|
||||
.PP
|
||||
For a listing of all available hwloc man pages, look at all "hwloc*"
|
||||
files in the man1 and man3 directories.
|
@ -1,475 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
|
||||
#ifdef HWLOC_HAVE_CAIRO
|
||||
#include <cairo.h>
|
||||
|
||||
#if CAIRO_HAS_PDF_SURFACE
|
||||
#include <cairo-pdf.h>
|
||||
#endif /* CAIRO_HAS_PDF_SURFACE */
|
||||
|
||||
#if CAIRO_HAS_PS_SURFACE
|
||||
#include <cairo-ps.h>
|
||||
#endif /* CAIRO_HAS_PS_SURFACE */
|
||||
|
||||
#if CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif /* CAIRO_HAS_SVG_SURFACE */
|
||||
|
||||
#ifndef HWLOC_HAVE_X11
|
||||
/* In case X11 headers aren't availble, forcefully disable Cairo/Xlib. */
|
||||
# undef CAIRO_HAS_XLIB_SURFACE
|
||||
# define CAIRO_HAS_XLIB_SURFACE 0
|
||||
#endif
|
||||
|
||||
#if CAIRO_HAS_XLIB_SURFACE
|
||||
#include <cairo-xlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#endif /* CAIRO_HAS_XLIB_SURFACE */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
#if (CAIRO_HAS_XLIB_SURFACE + CAIRO_HAS_PNG_FUNCTIONS + CAIRO_HAS_PDF_SURFACE + CAIRO_HAS_PS_SURFACE + CAIRO_HAS_SVG_SURFACE)
|
||||
/* Cairo methods */
|
||||
static void
|
||||
topo_cairo_box(void *output, int r, int g, int b, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned width, unsigned y, unsigned height)
|
||||
{
|
||||
cairo_t *c = output;
|
||||
cairo_rectangle(c, x, y, width, height);
|
||||
cairo_set_source_rgb(c, (float)r / 255, (float) g / 255, (float) b / 255);
|
||||
cairo_fill(c);
|
||||
|
||||
cairo_rectangle(c, x, y, width, height);
|
||||
cairo_set_source_rgb(c, 0, 0, 0);
|
||||
cairo_set_line_width(c, 1);
|
||||
cairo_stroke(c);
|
||||
}
|
||||
|
||||
static void
|
||||
topo_cairo_line(void *output, int r, int g, int b, unsigned depth __hwloc_attribute_unused, unsigned x1, unsigned y1, unsigned x2, unsigned y2)
|
||||
{
|
||||
cairo_t *c = output;
|
||||
cairo_move_to(c, x1, y1);
|
||||
cairo_set_source_rgb(c, (float) r / 255, (float) g / 255, (float) b / 255);
|
||||
cairo_set_line_width(c, 1);
|
||||
cairo_line_to(c, x2, y2);
|
||||
cairo_stroke(c);
|
||||
}
|
||||
|
||||
static void
|
||||
topo_cairo_text(void *output, int r, int g, int b, int size, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned y, const char *text)
|
||||
{
|
||||
cairo_t *c = output;
|
||||
cairo_move_to(c, x, y + size);
|
||||
cairo_set_font_size(c, size);
|
||||
cairo_set_source_rgb(c, (float)r / 255, (float) g / 255, (float) b / 255);
|
||||
cairo_show_text(c, text);
|
||||
}
|
||||
|
||||
#if (CAIRO_HAS_PNG_FUNCTIONS + CAIRO_HAS_PDF_SURFACE + CAIRO_HAS_PS_SURFACE + CAIRO_HAS_SVG_SURFACE)
|
||||
static cairo_status_t
|
||||
topo_cairo_write(void *closure, const unsigned char *data, unsigned int length)
|
||||
{
|
||||
if (fwrite(data, length, 1, closure) < 1)
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* (CAIRO_HAS_PNG_FUNCTIONS + CAIRO_HAS_PDF_SURFACE + CAIRO_HAS_PS_SURFACE + CAIRO_HAS_SVG_SURFACE) */
|
||||
|
||||
static void
|
||||
topo_cairo_paint(struct draw_methods *methods, int logical, hwloc_topology_t topology, cairo_surface_t *cs)
|
||||
{
|
||||
cairo_t *c;
|
||||
c = cairo_create(cs);
|
||||
output_draw(methods, logical, topology, c);
|
||||
cairo_show_page(c);
|
||||
cairo_destroy(c);
|
||||
}
|
||||
|
||||
static void null_declare_color (void *output __hwloc_attribute_unused, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused) {}
|
||||
#endif /* (CAIRO_HAS_XLIB_SURFACE + CAIRO_HAS_PNG_FUNCTIONS + CAIRO_HAS_PDF_SURFACE + CAIRO_HAS_PS_SURFACE + CAIRO_HAS_SVG_SURFACE) */
|
||||
|
||||
|
||||
#if CAIRO_HAS_XLIB_SURFACE
|
||||
/* X11 back-end */
|
||||
|
||||
struct display {
|
||||
Display *dpy;
|
||||
cairo_surface_t *cs;
|
||||
Window win;
|
||||
Cursor hand;
|
||||
int screen_width, screen_height; /** visible part size */
|
||||
int width, height; /** total size */
|
||||
int x, y; /** top left corner of the visible part */
|
||||
};
|
||||
|
||||
static void *
|
||||
x11_start(void *output __hwloc_attribute_unused, int width, int height)
|
||||
{
|
||||
cairo_surface_t *cs;
|
||||
Display *dpy;
|
||||
Window root, top, win;
|
||||
int scr;
|
||||
Screen *screen;
|
||||
int screen_width = width, screen_height = height;
|
||||
struct display *disp;
|
||||
Cursor hand;
|
||||
|
||||
if (!(dpy = XOpenDisplay(NULL))) {
|
||||
fprintf(stderr, "couldn't connect to X\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
scr = DefaultScreen(dpy);
|
||||
screen = ScreenOfDisplay(dpy, scr);
|
||||
if (screen_width >= screen->width)
|
||||
screen_width = screen->width;
|
||||
if (screen_height >= screen->height)
|
||||
screen_height = screen->height;
|
||||
root = RootWindow(dpy, scr);
|
||||
top = XCreateSimpleWindow(dpy, root, 0, 0, screen_width, screen_height, 0, WhitePixel(dpy, scr), WhitePixel(dpy, scr));
|
||||
win = XCreateSimpleWindow(dpy, top, 0, 0, width, height, 0, WhitePixel(dpy, scr), WhitePixel(dpy, scr));
|
||||
hand = XCreateFontCursor(dpy, XC_fleur);
|
||||
XDefineCursor(dpy, win, hand);
|
||||
|
||||
XSelectInput(dpy, win,
|
||||
KeyPressMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask |
|
||||
ExposureMask);
|
||||
XSelectInput(dpy,top, StructureNotifyMask);
|
||||
XMapWindow(dpy, win);
|
||||
XMapWindow(dpy, top);
|
||||
|
||||
cs = cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, scr), width, height);
|
||||
|
||||
disp = malloc(sizeof(*disp));
|
||||
disp->dpy = dpy;
|
||||
disp->cs = cs;
|
||||
disp->win = win;
|
||||
disp->hand = hand;
|
||||
disp->screen_width = screen_width;
|
||||
disp->screen_height = screen_height;
|
||||
disp->width = width;
|
||||
disp->height = height;
|
||||
disp->x = 0;
|
||||
disp->y = 0;
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
static struct draw_methods x11_draw_methods = {
|
||||
.start = x11_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = topo_cairo_box,
|
||||
.line = topo_cairo_line,
|
||||
.text = topo_cairo_text,
|
||||
};
|
||||
|
||||
/** Clip coordinates of the visible part. */
|
||||
static void
|
||||
move_x11(struct display *disp)
|
||||
{
|
||||
if (disp->width <= disp->screen_width) {
|
||||
disp->x = 0;
|
||||
} else {
|
||||
if (disp->x < 0)
|
||||
disp->x = 0;
|
||||
if (disp->x >= disp->width - disp->screen_width)
|
||||
disp->x = disp->width - disp->screen_width;
|
||||
}
|
||||
|
||||
if (disp->height <= disp->screen_height) {
|
||||
disp->y = 0;
|
||||
} else {
|
||||
if (disp->y < 0)
|
||||
disp->y = 0;
|
||||
if (disp->y >= disp->height - disp->screen_height)
|
||||
disp->y = disp->height - disp->screen_height;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
output_x11(hwloc_topology_t topology, const char *filename __hwloc_attribute_unused, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
struct display *disp = output_draw_start(&x11_draw_methods, logical, topology, NULL);
|
||||
int finish = 0;
|
||||
int state = 0;
|
||||
int x = 0, y = 0; /* shut warning down */
|
||||
int lastx = disp->x, lasty = disp->y;
|
||||
|
||||
topo_cairo_paint(&x11_draw_methods, logical, topology, disp->cs);
|
||||
|
||||
while (!finish) {
|
||||
XEvent e;
|
||||
if (!XEventsQueued(disp->dpy, QueuedAfterFlush)) {
|
||||
/* No pending event, flush moving windows before waiting for next event */
|
||||
if (disp->x != lastx || disp->y != lasty) {
|
||||
XMoveWindow(disp->dpy, disp->win, -disp->x, -disp->y);
|
||||
lastx = disp->x;
|
||||
lasty = disp->y;
|
||||
}
|
||||
}
|
||||
XNextEvent(disp->dpy, &e);
|
||||
switch (e.type) {
|
||||
case Expose:
|
||||
if (e.xexpose.count < 1)
|
||||
topo_cairo_paint(&x11_draw_methods, logical, topology, disp->cs);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if (state) {
|
||||
disp->x -= e.xmotion.x_root - x;
|
||||
disp->y -= e.xmotion.y_root - y;
|
||||
x = e.xmotion.x_root;
|
||||
y = e.xmotion.y_root;
|
||||
move_x11(disp);
|
||||
}
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
disp->screen_width = e.xconfigure.width;
|
||||
disp->screen_height = e.xconfigure.height;
|
||||
move_x11(disp);
|
||||
if (disp->x != lastx || disp->y != lasty)
|
||||
XMoveWindow(disp->dpy, disp->win, -disp->x, -disp->y);
|
||||
break;
|
||||
case ButtonPress:
|
||||
if (e.xbutton.button == Button1) {
|
||||
state = 1;
|
||||
x = e.xbutton.x_root;
|
||||
y = e.xbutton.y_root;
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if (e.xbutton.button == Button1)
|
||||
state = 0;
|
||||
break;
|
||||
case MappingNotify:
|
||||
XRefreshKeyboardMapping(&e.xmapping);
|
||||
break;
|
||||
case KeyPress: {
|
||||
KeySym keysym;
|
||||
XLookupString(&e.xkey, NULL, 0, &keysym, NULL);
|
||||
switch (keysym) {
|
||||
case XK_q:
|
||||
case XK_Q:
|
||||
case XK_Escape:
|
||||
finish = 1;
|
||||
break;
|
||||
case XK_Left:
|
||||
disp->x -= disp->screen_width/10;
|
||||
move_x11(disp);
|
||||
break;
|
||||
case XK_Right:
|
||||
disp->x += disp->screen_width/10;
|
||||
move_x11(disp);
|
||||
break;
|
||||
case XK_Up:
|
||||
disp->y -= disp->screen_height/10;
|
||||
move_x11(disp);
|
||||
break;
|
||||
case XK_Down:
|
||||
disp->y += disp->screen_height/10;
|
||||
move_x11(disp);
|
||||
break;
|
||||
case XK_Page_Up:
|
||||
if (e.xkey.state & ControlMask) {
|
||||
disp->x -= disp->screen_width;
|
||||
move_x11(disp);
|
||||
} else {
|
||||
disp->y -= disp->screen_height;
|
||||
move_x11(disp);
|
||||
}
|
||||
break;
|
||||
case XK_Page_Down:
|
||||
if (e.xkey.state & ControlMask) {
|
||||
disp->x += disp->screen_width;
|
||||
move_x11(disp);
|
||||
} else {
|
||||
disp->y += disp->screen_height;
|
||||
move_x11(disp);
|
||||
}
|
||||
break;
|
||||
case XK_Home:
|
||||
disp->x = 0;
|
||||
disp->y = 0;
|
||||
move_x11(disp);
|
||||
break;
|
||||
case XK_End:
|
||||
disp->x = INT_MAX;
|
||||
disp->y = INT_MAX;
|
||||
move_x11(disp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cairo_surface_destroy(disp->cs);
|
||||
XFreeCursor(disp->dpy, disp->hand);
|
||||
XCloseDisplay(disp->dpy);
|
||||
free(disp);
|
||||
}
|
||||
#endif /* CAIRO_HAS_XLIB_SURFACE */
|
||||
|
||||
|
||||
#if CAIRO_HAS_PNG_FUNCTIONS
|
||||
/* PNG back-end */
|
||||
static void *
|
||||
png_start(void *output __hwloc_attribute_unused, int width, int height)
|
||||
{
|
||||
return cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
||||
}
|
||||
|
||||
static struct draw_methods png_draw_methods = {
|
||||
.start = png_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = topo_cairo_box,
|
||||
.line = topo_cairo_line,
|
||||
.text = topo_cairo_text,
|
||||
};
|
||||
|
||||
void
|
||||
output_png(hwloc_topology_t topology, const char *filename, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output = open_file(filename, "w");
|
||||
cairo_surface_t *cs;
|
||||
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
cs = output_draw_start(&png_draw_methods, logical, topology, output);
|
||||
|
||||
topo_cairo_paint(&png_draw_methods, logical, topology, cs);
|
||||
cairo_surface_write_to_png_stream(cs, topo_cairo_write, output);
|
||||
cairo_surface_destroy(cs);
|
||||
fclose(output);
|
||||
}
|
||||
#endif /* CAIRO_HAS_PNG_FUNCTIONS */
|
||||
|
||||
|
||||
#if CAIRO_HAS_PDF_SURFACE
|
||||
/* PDF back-end */
|
||||
static void *
|
||||
pdf_start(void *output, int width, int height)
|
||||
{
|
||||
return cairo_pdf_surface_create_for_stream(topo_cairo_write, output, width, height);
|
||||
}
|
||||
|
||||
static struct draw_methods pdf_draw_methods = {
|
||||
.start = pdf_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = topo_cairo_box,
|
||||
.line = topo_cairo_line,
|
||||
.text = topo_cairo_text,
|
||||
};
|
||||
|
||||
void
|
||||
output_pdf(hwloc_topology_t topology, const char *filename, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output = open_file(filename, "w");
|
||||
cairo_surface_t *cs;
|
||||
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
cs = output_draw_start(&pdf_draw_methods, logical, topology, output);
|
||||
|
||||
topo_cairo_paint(&pdf_draw_methods, logical, topology, cs);
|
||||
cairo_surface_flush(cs);
|
||||
cairo_surface_destroy(cs);
|
||||
fclose(output);
|
||||
}
|
||||
#endif /* CAIRO_HAS_PDF_SURFACE */
|
||||
|
||||
|
||||
#if CAIRO_HAS_PS_SURFACE
|
||||
/* PS back-end */
|
||||
static void *
|
||||
ps_start(void *output, int width, int height)
|
||||
{
|
||||
return cairo_ps_surface_create_for_stream(topo_cairo_write, output, width, height);
|
||||
}
|
||||
|
||||
static struct draw_methods ps_draw_methods = {
|
||||
.start = ps_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = topo_cairo_box,
|
||||
.line = topo_cairo_line,
|
||||
.text = topo_cairo_text,
|
||||
};
|
||||
|
||||
void
|
||||
output_ps(hwloc_topology_t topology, const char *filename, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output = open_file(filename, "w");
|
||||
cairo_surface_t *cs;
|
||||
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
cs = output_draw_start(&ps_draw_methods, logical, topology, output);
|
||||
|
||||
topo_cairo_paint(&ps_draw_methods, logical, topology, cs);
|
||||
cairo_surface_flush(cs);
|
||||
cairo_surface_destroy(cs);
|
||||
fclose(output);
|
||||
}
|
||||
#endif /* CAIRO_HAS_PS_SURFACE */
|
||||
|
||||
|
||||
#if CAIRO_HAS_SVG_SURFACE
|
||||
/* SVG back-end */
|
||||
static void *
|
||||
svg_start(void *output, int width, int height)
|
||||
{
|
||||
return cairo_svg_surface_create_for_stream(topo_cairo_write, output, width, height);
|
||||
}
|
||||
|
||||
static struct draw_methods svg_draw_methods = {
|
||||
.start = svg_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = topo_cairo_box,
|
||||
.line = topo_cairo_line,
|
||||
.text = topo_cairo_text,
|
||||
};
|
||||
|
||||
void
|
||||
output_svg(hwloc_topology_t topology, const char *filename, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output = open_file(filename, "w");
|
||||
cairo_surface_t *cs;
|
||||
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
cs = output_draw_start(&svg_draw_methods, logical, topology, output);
|
||||
|
||||
topo_cairo_paint(&svg_draw_methods, logical, topology, cs);
|
||||
cairo_surface_flush(cs);
|
||||
cairo_surface_destroy(cs);
|
||||
fclose(output);
|
||||
}
|
||||
#endif /* CAIRO_HAS_SVG_SURFACE */
|
||||
|
||||
#endif /* CAIRO */
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
static struct color {
|
||||
int r, g, b;
|
||||
} *colors;
|
||||
|
||||
static int numcolors;
|
||||
|
||||
static int
|
||||
find_color(int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numcolors; i++)
|
||||
if (colors[i].r == r && colors[i].g == g && colors[i].b == b)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
rgb_to_color(int r, int g, int b)
|
||||
{
|
||||
int color = find_color(r, g, b);
|
||||
|
||||
if (color != -1)
|
||||
return color;
|
||||
|
||||
fprintf(stderr, "color #%02x%02x%02x not declared\n", r, g, b);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
declare_color(int r, int g, int b)
|
||||
{
|
||||
int color = find_color(r, g, b);
|
||||
|
||||
if (color != -1)
|
||||
return color;
|
||||
|
||||
color = numcolors++;
|
||||
colors = realloc(colors, sizeof(*colors) * (numcolors));
|
||||
colors[color].r = r;
|
||||
colors[color].g = g;
|
||||
colors[color].b = b;
|
||||
|
||||
return color;
|
||||
}
|
@ -1,757 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <private/private.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
#define EPOXY_R_COLOR 0xe7
|
||||
#define EPOXY_G_COLOR 0xff
|
||||
#define EPOXY_B_COLOR 0xb5
|
||||
|
||||
#define SOCKET_R_COLOR 0xde
|
||||
#define SOCKET_G_COLOR 0xde
|
||||
#define SOCKET_B_COLOR 0xde
|
||||
|
||||
#define MEMORY_R_COLOR 0xef
|
||||
#define MEMORY_G_COLOR 0xdf
|
||||
#define MEMORY_B_COLOR 0xde
|
||||
|
||||
#define CORE_R_COLOR 0xbe
|
||||
#define CORE_G_COLOR 0xbe
|
||||
#define CORE_B_COLOR 0xbe
|
||||
|
||||
#define THREAD_R_COLOR 0xff
|
||||
#define THREAD_G_COLOR 0xff
|
||||
#define THREAD_B_COLOR 0xff
|
||||
|
||||
#define RUNNING_R_COLOR 0
|
||||
#define RUNNING_G_COLOR 0xff
|
||||
#define RUNNING_B_COLOR 0
|
||||
|
||||
#define FORBIDDEN_R_COLOR 0xff
|
||||
#define FORBIDDEN_G_COLOR 0
|
||||
#define FORBIDDEN_B_COLOR 0
|
||||
|
||||
#define OFFLINE_R_COLOR 0
|
||||
#define OFFLINE_G_COLOR 0
|
||||
#define OFFLINE_B_COLOR 0
|
||||
|
||||
#define CACHE_R_COLOR 0xff
|
||||
#define CACHE_G_COLOR 0xff
|
||||
#define CACHE_B_COLOR 0xff
|
||||
|
||||
#define MACHINE_R_COLOR EPOXY_R_COLOR
|
||||
#define MACHINE_G_COLOR EPOXY_G_COLOR
|
||||
#define MACHINE_B_COLOR EPOXY_B_COLOR
|
||||
|
||||
#define NODE_R_COLOR ((EPOXY_R_COLOR * 100) / 110)
|
||||
#define NODE_G_COLOR ((EPOXY_G_COLOR * 100) / 110)
|
||||
#define NODE_B_COLOR ((EPOXY_B_COLOR * 100) / 110)
|
||||
|
||||
#define SYSTEM_R_COLOR 0xff
|
||||
#define SYSTEM_G_COLOR 0xff
|
||||
#define SYSTEM_B_COLOR 0xff
|
||||
|
||||
#define MISC_R_COLOR 0xff
|
||||
#define MISC_G_COLOR 0xff
|
||||
#define MISC_B_COLOR 0xff
|
||||
|
||||
/* preferred width/height compromise */
|
||||
#define RATIO (4.f/3.f)
|
||||
|
||||
/* do we prefer ratio1 over ratio2? */
|
||||
static int prefer_ratio(float ratio1, float ratio2) {
|
||||
float _ratio1 = (ratio1) / RATIO;
|
||||
float _ratio2 = (ratio2) / RATIO;
|
||||
if (_ratio1 < 1)
|
||||
_ratio1 = 1/_ratio1;
|
||||
if (_ratio2 < 1)
|
||||
_ratio2 = 1/_ratio2;
|
||||
return _ratio1 < _ratio2;
|
||||
}
|
||||
|
||||
static void* null_start(void *output, int width __hwloc_attribute_unused, int height __hwloc_attribute_unused) { return output; }
|
||||
static void null_declare_color(void *output __hwloc_attribute_unused, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused) { }
|
||||
static void null_box(void *output __hwloc_attribute_unused, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x __hwloc_attribute_unused, unsigned width __hwloc_attribute_unused, unsigned y __hwloc_attribute_unused, unsigned height __hwloc_attribute_unused) { }
|
||||
static void null_line(void *output __hwloc_attribute_unused, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x1 __hwloc_attribute_unused, unsigned y1_arg __hwloc_attribute_unused, unsigned x2 __hwloc_attribute_unused, unsigned y2 __hwloc_attribute_unused) { }
|
||||
static void null_text(void *output __hwloc_attribute_unused, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused, int size __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x __hwloc_attribute_unused, unsigned y __hwloc_attribute_unused, const char *text __hwloc_attribute_unused) { }
|
||||
|
||||
static struct draw_methods null_draw_methods = {
|
||||
.start = null_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = null_box,
|
||||
.line = null_line,
|
||||
.text = null_text,
|
||||
};
|
||||
|
||||
/*
|
||||
* foo_draw functions take a OBJ, computes which size it needs, recurse into
|
||||
* sublevels with null_draw_methods to recursively compute the needed size
|
||||
* without actually drawing anything, then draw things about OBJ (chip draw,
|
||||
* cache size information etc) at (X,Y), recurse into sublevels again to
|
||||
* actually draw things, and return in RETWIDTH and RETHEIGHT the amount of
|
||||
* space that the drawing took.
|
||||
*
|
||||
* For generic detailed comments, see the node_draw function.
|
||||
*/
|
||||
|
||||
typedef void (*foo_draw)(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t obj, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight);
|
||||
|
||||
static foo_draw get_type_fun(hwloc_obj_type_t type);
|
||||
|
||||
/*
|
||||
* Helper to recurse into sublevels, either horizontally or vertically
|
||||
* Updates caller's totwidth/myheight and maxwidth/maxheight
|
||||
* Needs textwidth, border, topology, output, depth, x and y
|
||||
*/
|
||||
|
||||
#define RECURSE_BEGIN(obj, border) do { \
|
||||
hwloc_obj_t *subobjs = obj->children; \
|
||||
unsigned numsubobjs = obj->arity; \
|
||||
unsigned width, height; \
|
||||
unsigned maxwidth __hwloc_attribute_unused, maxheight __hwloc_attribute_unused; \
|
||||
maxwidth = maxheight = 0; \
|
||||
totwidth = (border) + mywidth; \
|
||||
totheight = (border) + myheight; \
|
||||
if (numsubobjs) { \
|
||||
unsigned i; \
|
||||
|
||||
#define RECURSE_FOR() \
|
||||
/* Iterate over subobjects */ \
|
||||
for (i = 0; i < numsubobjs; i++) { \
|
||||
|
||||
/* Recursive call */
|
||||
#define RECURSE_CALL_FUN(methods) \
|
||||
get_type_fun(subobjs[i]->type)(topology, methods, logical, subobjs[i], output, depth-1, x + totwidth, &width, y + totheight, &height) \
|
||||
|
||||
#define RECURSE_END_HORIZ(separator, border) \
|
||||
/* Add the subobject's width and separator */ \
|
||||
totwidth += width + (separator); \
|
||||
/* Update maximum height */ \
|
||||
if (height > maxheight) \
|
||||
maxheight = height; \
|
||||
} \
|
||||
\
|
||||
/* Remove spurious separator on the right */ \
|
||||
totwidth -= (separator); \
|
||||
\
|
||||
/* Make sure there is width for the heading text */ \
|
||||
/* Add subobjects height */ \
|
||||
totheight += maxheight; \
|
||||
/* And add border below */ \
|
||||
totheight += (border); \
|
||||
} \
|
||||
if (totwidth < textwidth) \
|
||||
totwidth = textwidth; \
|
||||
/* Add border on the right */ \
|
||||
totwidth += (border); \
|
||||
/* Update returned values */ \
|
||||
*retwidth = totwidth; \
|
||||
*retheight = totheight; \
|
||||
} while(0)
|
||||
|
||||
#define RECURSE_END_VERT(separator, border) \
|
||||
/* Add the subobject's height and separator */ \
|
||||
totheight += height + (separator); \
|
||||
if (width > maxwidth) \
|
||||
/* Update maximum width */ \
|
||||
maxwidth = width; \
|
||||
} \
|
||||
/* Remove spurious separator at the bottom */ \
|
||||
totheight -= (separator); \
|
||||
} \
|
||||
\
|
||||
/* Make sure there is width for the heading text */ \
|
||||
if (maxwidth < textwidth) \
|
||||
maxwidth = textwidth; \
|
||||
/* Add subobjects width */ \
|
||||
totwidth += maxwidth; \
|
||||
/* And add border on the right */ \
|
||||
totwidth += (border); \
|
||||
/* Add border at the bottom */ \
|
||||
totheight = totheight + (border); \
|
||||
/* Update returned values */ \
|
||||
*retwidth = totwidth; \
|
||||
*retheight = totheight; \
|
||||
} while(0)
|
||||
|
||||
/* Pack objects horizontally */
|
||||
#define RECURSE_HORIZ(obj, methods, separator, border) \
|
||||
RECURSE_BEGIN(obj, border) \
|
||||
RECURSE_FOR() \
|
||||
RECURSE_CALL_FUN(methods); \
|
||||
RECURSE_END_HORIZ(separator, border)
|
||||
|
||||
/* Pack objects vertically */
|
||||
#define RECURSE_VERT(obj, methods, separator, border) \
|
||||
RECURSE_BEGIN(obj, border) \
|
||||
RECURSE_FOR() \
|
||||
RECURSE_CALL_FUN(methods); \
|
||||
RECURSE_END_VERT(separator, border)
|
||||
|
||||
#define RECURSE_RECT_BEGIN(obj, methods, separator, border) \
|
||||
RECURSE_BEGIN(obj, border) \
|
||||
unsigned obj_maxwidth = 0, obj_maxheight = 0; \
|
||||
unsigned area; \
|
||||
float idealtotheight; \
|
||||
unsigned rows, columns; \
|
||||
float under_ratio, over_ratio; \
|
||||
RECURSE_FOR() \
|
||||
RECURSE_CALL_FUN(&null_draw_methods); \
|
||||
if (height > obj_maxheight) \
|
||||
obj_maxheight = height; \
|
||||
if (width > obj_maxwidth) \
|
||||
obj_maxwidth = width; \
|
||||
} \
|
||||
/* Total area for subobjects */ \
|
||||
area = (obj_maxwidth + (separator)) * (obj_maxheight + (separator)) * numsubobjs; \
|
||||
/* Ideal total height for spreading that area with RATIO */ \
|
||||
idealtotheight = (float) sqrt(area/RATIO); \
|
||||
/* Underestimated number of rows */ \
|
||||
rows = idealtotheight / (obj_maxheight + (separator)); \
|
||||
columns = rows ? (numsubobjs + rows - 1) / rows : 1; \
|
||||
/* Ratio obtained by underestimation */ \
|
||||
under_ratio = (float) (columns * (obj_maxwidth + (separator))) / (rows * (obj_maxheight + (separator))); \
|
||||
\
|
||||
/* try to overestimate too */ \
|
||||
rows++; \
|
||||
columns = (numsubobjs + rows - 1) / rows; \
|
||||
/* Ratio obtained by overestimation */ \
|
||||
over_ratio = (float) (columns * (obj_maxwidth + (separator))) / (rows * (obj_maxheight + (separator))); \
|
||||
/* Did we actually preferred underestimation? (good row/column fit or good ratio) */ \
|
||||
if (rows > 1 && prefer_ratio(under_ratio, over_ratio)) { \
|
||||
rows--; \
|
||||
columns = (numsubobjs + rows - 1) / rows; \
|
||||
} \
|
||||
if (force_horiz) { \
|
||||
rows = 1; \
|
||||
columns = numsubobjs; \
|
||||
} \
|
||||
if (force_vert) { \
|
||||
columns = 1; \
|
||||
rows = numsubobjs; \
|
||||
} \
|
||||
\
|
||||
RECURSE_FOR() \
|
||||
/* Newline? */ \
|
||||
if (i && i%columns == 0) { \
|
||||
totwidth = (border) + mywidth; \
|
||||
/* Add the same height to all rows */ \
|
||||
totheight += obj_maxheight + (separator); \
|
||||
} \
|
||||
|
||||
#define RECURSE_RECT_END(obj, methods, separator, border) \
|
||||
if (totwidth + width + (separator) > maxwidth) \
|
||||
maxwidth = totwidth + width + (separator); \
|
||||
/* Add the same width to all columns */ \
|
||||
totwidth += obj_maxwidth + (separator); \
|
||||
} \
|
||||
/* Remove spurious separator on the right */ \
|
||||
maxwidth -= (separator); \
|
||||
/* Make sure there is width for the heading text */ \
|
||||
if (maxwidth < textwidth) \
|
||||
maxwidth = textwidth; \
|
||||
/* Compute total width */ \
|
||||
totwidth = maxwidth + (border); \
|
||||
/* Add the last row's height and border at the bottom */ \
|
||||
totheight += obj_maxheight + (border); \
|
||||
/* Update returned values */ \
|
||||
*retwidth = totwidth; \
|
||||
*retheight = totheight; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Pack objects in a grid */
|
||||
#define RECURSE_RECT(obj, methods, separator, border) do {\
|
||||
if (obj->arity && obj->children[0]->type == HWLOC_OBJ_NODE) { \
|
||||
/* Nodes shouldn't be put with an arbitrary geometry, as NUMA distances may not be that way */ \
|
||||
int pvert = prefer_vert(topology, logical, level, output, depth, x, y, separator); \
|
||||
if (pvert) \
|
||||
RECURSE_VERT(level, methods, separator, border); \
|
||||
else \
|
||||
RECURSE_HORIZ(level, methods, separator, border); \
|
||||
} else {\
|
||||
RECURSE_RECT_BEGIN(obj, methods, separator, border) \
|
||||
RECURSE_CALL_FUN(methods); \
|
||||
RECURSE_RECT_END(obj, methods, separator, border); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Dynamic programming */
|
||||
|
||||
/* Per-object data: width and height of drawing for this object and sub-objects */
|
||||
struct dyna_save {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
/* Save the computed size */
|
||||
#define DYNA_SAVE() do { \
|
||||
if (!level->userdata) { \
|
||||
struct dyna_save *save = malloc(sizeof(*save)); \
|
||||
save->width = *retwidth; \
|
||||
save->height = *retheight; \
|
||||
level->userdata = save; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Check whether we already computed the size and we are not actually drawing, in that case return it */
|
||||
#define DYNA_CHECK() do { \
|
||||
if (level->userdata && methods == &null_draw_methods) { \
|
||||
struct dyna_save *save = level->userdata; \
|
||||
*retwidth = save->width; \
|
||||
*retheight = save->height; \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
prefer_vert(hwloc_topology_t topology, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned y, unsigned separator)
|
||||
{
|
||||
float horiz_ratio, vert_ratio;
|
||||
unsigned textwidth = 0;
|
||||
unsigned mywidth = 0, myheight = 0;
|
||||
unsigned totwidth, *retwidth = &totwidth, totheight, *retheight = &totheight;
|
||||
RECURSE_HORIZ(level, &null_draw_methods, separator, 0);
|
||||
horiz_ratio = (float)totwidth / totheight;
|
||||
RECURSE_VERT(level, &null_draw_methods, separator, 0);
|
||||
vert_ratio = (float)totwidth / totheight;
|
||||
return force_vert || (!force_horiz && prefer_ratio(vert_ratio, horiz_ratio));
|
||||
}
|
||||
|
||||
static int
|
||||
lstopo_obj_snprintf(char *text, size_t textlen, hwloc_obj_t obj, int logical)
|
||||
{
|
||||
unsigned idx = logical ? obj->logical_index : obj->os_index;
|
||||
const char *indexprefix = logical ? " #" : " p#";
|
||||
char typestr[32];
|
||||
char indexstr[32]= "";
|
||||
char attrstr[256];
|
||||
int attrlen;
|
||||
hwloc_obj_type_snprintf(typestr, sizeof(typestr), obj, 0);
|
||||
if (idx != (unsigned)-1 && obj->depth != 0)
|
||||
snprintf(indexstr, sizeof(indexstr), "%s%u", indexprefix, idx);
|
||||
attrlen = hwloc_obj_attr_snprintf(attrstr, sizeof(attrstr), obj, " ", 0);
|
||||
if (attrlen > 0)
|
||||
return snprintf(text, textlen, "%s%s (%s)", typestr, indexstr, attrstr);
|
||||
else
|
||||
return snprintf(text, textlen, "%s%s", typestr, indexstr);
|
||||
}
|
||||
|
||||
static void
|
||||
pu_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight;
|
||||
unsigned textwidth = fontsize ? (6-logical)*fontsize : gridsize;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_HORIZ(level, &null_draw_methods, 0, gridsize);
|
||||
|
||||
if (hwloc_cpuset_isset(level->online_cpuset, level->os_index))
|
||||
if (!hwloc_cpuset_isset(level->allowed_cpuset, level->os_index))
|
||||
methods->box(output, FORBIDDEN_R_COLOR, FORBIDDEN_G_COLOR, FORBIDDEN_B_COLOR, depth, x, *retwidth, y, *retheight);
|
||||
else {
|
||||
hwloc_cpuset_t bind = hwloc_cpuset_alloc();
|
||||
if (pid != (hwloc_pid_t) -1 && pid != 0)
|
||||
hwloc_get_proc_cpubind(topology, pid, bind, 0);
|
||||
else if (pid == 0)
|
||||
hwloc_get_cpubind(topology, bind, 0);
|
||||
if (bind && hwloc_cpuset_isset(bind, level->os_index))
|
||||
methods->box(output, RUNNING_R_COLOR, RUNNING_G_COLOR, RUNNING_B_COLOR, depth, x, *retwidth, y, *retheight);
|
||||
else
|
||||
methods->box(output, THREAD_R_COLOR, THREAD_G_COLOR, THREAD_B_COLOR, depth, x, *retwidth, y, *retheight);
|
||||
hwloc_cpuset_free(bind);
|
||||
}
|
||||
else
|
||||
methods->box(output, OFFLINE_R_COLOR, OFFLINE_G_COLOR, OFFLINE_B_COLOR, depth, x, *retwidth, y, *retheight);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
if (hwloc_cpuset_isset(level->online_cpuset, level->os_index))
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
else
|
||||
methods->text(output, 0xff, 0xff, 0xff, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
|
||||
RECURSE_HORIZ(level, methods, 0, gridsize);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
cache_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = gridsize + (fontsize ? (fontsize + gridsize) : 0) + gridsize, totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = fontsize ? ((logical ? level->logical_index : level->os_index) == (unsigned) -1 ? 7*fontsize : 9*fontsize) : 0;
|
||||
/* Do not separate objects when in L1 (SMT) */
|
||||
unsigned separator = level->attr->cache.depth > 1 ? gridsize : 0;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_RECT(level, &null_draw_methods, separator, 0);
|
||||
|
||||
methods->box(output, CACHE_R_COLOR, CACHE_G_COLOR, CACHE_B_COLOR, depth, x, totwidth, y, myheight - gridsize);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
|
||||
RECURSE_RECT(level, methods, separator, 0);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
core_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = 5*fontsize;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_RECT(level, &null_draw_methods, 0, gridsize);
|
||||
|
||||
methods->box(output, CORE_R_COLOR, CORE_G_COLOR, CORE_B_COLOR, depth, x, totwidth, y, totheight);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
|
||||
RECURSE_RECT(level, methods, 0, gridsize);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
socket_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = 6*fontsize;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize);
|
||||
|
||||
methods->box(output, SOCKET_R_COLOR, SOCKET_G_COLOR, SOCKET_B_COLOR, depth, x, totwidth, y, totheight);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
|
||||
RECURSE_RECT(level, methods, gridsize, gridsize);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
node_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
/* Reserve room for the heading memory box and separator */
|
||||
unsigned myheight = (fontsize ? (gridsize + fontsize) : 0) + gridsize + gridsize;
|
||||
/* Currently filled height */
|
||||
unsigned totheight;
|
||||
/* Nothing on the left */
|
||||
unsigned mywidth = 0;
|
||||
/* Currently filled width */
|
||||
unsigned totwidth;
|
||||
/* Width of the heading text, thus minimal width */
|
||||
unsigned textwidth = 11*fontsize;
|
||||
|
||||
/* Check whether dynamic programming can save us time */
|
||||
DYNA_CHECK();
|
||||
|
||||
/* Compute the size needed by sublevels */
|
||||
RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize);
|
||||
|
||||
/* Draw the epoxy box */
|
||||
methods->box(output, NODE_R_COLOR, NODE_G_COLOR, NODE_B_COLOR, depth, x, totwidth, y, totheight);
|
||||
/* Draw the memory box */
|
||||
methods->box(output, MEMORY_R_COLOR, MEMORY_G_COLOR, MEMORY_B_COLOR, depth-1, x + gridsize, totwidth - 2 * gridsize, y + gridsize, myheight - gridsize);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
/* Output text */
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-2, x + 2 * gridsize, y + 2 * gridsize, text);
|
||||
}
|
||||
|
||||
/* Restart, now really drawing sublevels */
|
||||
RECURSE_RECT(level, methods, gridsize, gridsize);
|
||||
|
||||
/* Save result for dynamic programming */
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
machine_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = 11*fontsize;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize);
|
||||
|
||||
methods->box(output, MACHINE_R_COLOR, MACHINE_G_COLOR, MACHINE_B_COLOR, depth, x, totwidth, y, totheight);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
|
||||
RECURSE_RECT(level, methods, gridsize, gridsize);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
system_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = 10*fontsize;
|
||||
int vert = prefer_vert(topology, logical, level, output, depth, x, y, gridsize);
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
if (level->arity > 1 && level->children[0]->type == HWLOC_OBJ_MACHINE) {
|
||||
/* network of machines, either horizontal or vertical */
|
||||
if (vert) {
|
||||
mywidth += gridsize;
|
||||
RECURSE_VERT(level, &null_draw_methods, gridsize, gridsize);
|
||||
} else
|
||||
RECURSE_HORIZ(level, &null_draw_methods, gridsize, gridsize);
|
||||
} else
|
||||
RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize);
|
||||
|
||||
methods->box(output, SYSTEM_R_COLOR, SYSTEM_G_COLOR, SYSTEM_B_COLOR, depth, x, totwidth, y, totheight);
|
||||
|
||||
if (fontsize) {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
|
||||
if (level->arity > 1 && level->children[0]->type == HWLOC_OBJ_MACHINE) {
|
||||
if (vert) {
|
||||
unsigned top = 0, bottom = 0;
|
||||
unsigned center;
|
||||
RECURSE_BEGIN(level, gridsize)
|
||||
RECURSE_FOR()
|
||||
RECURSE_CALL_FUN(methods);
|
||||
center = y + totheight + height / 2;
|
||||
if (!top)
|
||||
top = center;
|
||||
bottom = center;
|
||||
methods->line(output, 0, 0, 0, depth, x + mywidth, center, x + mywidth + gridsize, center);
|
||||
RECURSE_END_VERT(gridsize, gridsize);
|
||||
|
||||
if (level->arity > 1 && level->children[0]->type == HWLOC_OBJ_MACHINE)
|
||||
methods->line(output, 0, 0, 0, depth, x + mywidth, top, x + mywidth, bottom);
|
||||
} else {
|
||||
unsigned left = 0, right = 0;
|
||||
unsigned center;
|
||||
RECURSE_BEGIN(level, gridsize)
|
||||
RECURSE_FOR()
|
||||
RECURSE_CALL_FUN(methods);
|
||||
center = x + totwidth + width / 2;
|
||||
if (!left)
|
||||
left = center;
|
||||
right = center;
|
||||
methods->line(output, 0, 0, 0, depth, center, y + myheight, center, y + myheight + gridsize);
|
||||
RECURSE_END_HORIZ(gridsize, gridsize);
|
||||
|
||||
if (level->arity > 1 && level->children[0]->type == HWLOC_OBJ_MACHINE)
|
||||
methods->line(output, 0, 0, 0, depth, left, y + myheight, right, y + myheight);
|
||||
}
|
||||
} else
|
||||
RECURSE_RECT(level, methods, gridsize, gridsize);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
group_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = level->name ? strlen(level->name) * fontsize : 6*fontsize;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize);
|
||||
|
||||
methods->box(output, MISC_R_COLOR, MISC_G_COLOR, MISC_B_COLOR, depth, x, totwidth, y, totheight);
|
||||
|
||||
if (fontsize) {
|
||||
if (level->name) {
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, level->name);
|
||||
} else {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
}
|
||||
|
||||
RECURSE_RECT(level, methods, gridsize, gridsize);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
misc_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight)
|
||||
{
|
||||
unsigned boxheight = gridsize + (fontsize ? (fontsize + gridsize) : 0);
|
||||
unsigned myheight = boxheight + (level->arity?gridsize:0), totheight;
|
||||
unsigned mywidth = 0, totwidth;
|
||||
unsigned textwidth = level->name ? strlen(level->name) * fontsize : 6*fontsize;
|
||||
|
||||
DYNA_CHECK();
|
||||
|
||||
RECURSE_HORIZ(level, &null_draw_methods, gridsize, 0);
|
||||
|
||||
methods->box(output, MISC_R_COLOR, MISC_G_COLOR, MISC_B_COLOR, depth, x, totwidth, y, boxheight);
|
||||
|
||||
if (fontsize) {
|
||||
if (level->name) {
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, level->name);
|
||||
} else {
|
||||
char text[64];
|
||||
lstopo_obj_snprintf(text, sizeof(text), level, logical);
|
||||
methods->text(output, 0, 0, 0, fontsize, depth-1, x + gridsize, y + gridsize, text);
|
||||
}
|
||||
}
|
||||
|
||||
RECURSE_HORIZ(level, methods, gridsize, 0);
|
||||
|
||||
DYNA_SAVE();
|
||||
}
|
||||
|
||||
static void
|
||||
fig(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned y)
|
||||
{
|
||||
unsigned totwidth, totheight;
|
||||
|
||||
system_draw(topology, methods, logical, level, output, depth, x, &totwidth, y, &totheight);
|
||||
}
|
||||
|
||||
/*
|
||||
* given a type, return a pointer FUN to the function that draws it.
|
||||
*/
|
||||
static foo_draw
|
||||
get_type_fun(hwloc_obj_type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case HWLOC_OBJ_SYSTEM: return system_draw;
|
||||
case HWLOC_OBJ_MACHINE: return machine_draw;
|
||||
case HWLOC_OBJ_NODE: return node_draw;
|
||||
case HWLOC_OBJ_SOCKET: return socket_draw;
|
||||
case HWLOC_OBJ_CACHE: return cache_draw;
|
||||
case HWLOC_OBJ_CORE: return core_draw;
|
||||
case HWLOC_OBJ_PU: return pu_draw;
|
||||
case HWLOC_OBJ_GROUP: return group_draw;
|
||||
case HWLOC_OBJ_MISC: return misc_draw;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy drawing methods to get the bounding box.
|
||||
*/
|
||||
|
||||
struct coords {
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
};
|
||||
|
||||
static void
|
||||
getmax_box(void *output, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned width, unsigned y, unsigned height)
|
||||
{
|
||||
struct coords *coords = output;
|
||||
|
||||
if (x > coords->x)
|
||||
coords->x = x;
|
||||
if (x + width > coords->x)
|
||||
coords->x = x + width;
|
||||
if (y > coords->y)
|
||||
coords->y = y;
|
||||
if (y + height > coords->y)
|
||||
coords->y = y + height;
|
||||
}
|
||||
|
||||
static void
|
||||
getmax_line(void *output, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x1_arg, unsigned y1_arg, unsigned x2_arg, unsigned y2_arg)
|
||||
{
|
||||
struct coords *coords = output;
|
||||
|
||||
if (x1_arg > coords->x)
|
||||
coords->x = x1_arg;
|
||||
if (x2_arg > coords->x)
|
||||
coords->x = x2_arg;
|
||||
if (y1_arg > coords->y)
|
||||
coords->y = y1_arg;
|
||||
if (y2_arg > coords->y)
|
||||
coords->y = y2_arg;
|
||||
}
|
||||
|
||||
static struct draw_methods getmax_draw_methods = {
|
||||
.start = null_start,
|
||||
.declare_color = null_declare_color,
|
||||
.box = getmax_box,
|
||||
.line = getmax_line,
|
||||
.text = null_text,
|
||||
};
|
||||
|
||||
void *
|
||||
output_draw_start(struct draw_methods *methods, int logical, hwloc_topology_t topology, void *output)
|
||||
{
|
||||
struct coords coords = { .x = 0, .y = 0};
|
||||
fig(topology, &getmax_draw_methods, logical, hwloc_get_root_obj(topology), &coords, 100, 0, 0);
|
||||
output = methods->start(output, coords.x, coords.y);
|
||||
methods->declare_color(output, 0, 0, 0);
|
||||
methods->declare_color(output, NODE_R_COLOR, NODE_G_COLOR, NODE_B_COLOR);
|
||||
methods->declare_color(output, SOCKET_R_COLOR, SOCKET_G_COLOR, SOCKET_B_COLOR);
|
||||
methods->declare_color(output, MEMORY_R_COLOR, MEMORY_G_COLOR, MEMORY_B_COLOR);
|
||||
methods->declare_color(output, CORE_R_COLOR, CORE_G_COLOR, CORE_B_COLOR);
|
||||
methods->declare_color(output, THREAD_R_COLOR, THREAD_G_COLOR, THREAD_B_COLOR);
|
||||
methods->declare_color(output, RUNNING_R_COLOR, RUNNING_G_COLOR, RUNNING_B_COLOR);
|
||||
methods->declare_color(output, FORBIDDEN_R_COLOR, FORBIDDEN_G_COLOR, FORBIDDEN_B_COLOR);
|
||||
methods->declare_color(output, OFFLINE_R_COLOR, OFFLINE_G_COLOR, OFFLINE_B_COLOR);
|
||||
methods->declare_color(output, CACHE_R_COLOR, CACHE_G_COLOR, CACHE_B_COLOR);
|
||||
methods->declare_color(output, MACHINE_R_COLOR, MACHINE_G_COLOR, MACHINE_B_COLOR);
|
||||
methods->declare_color(output, SYSTEM_R_COLOR, SYSTEM_G_COLOR, SYSTEM_B_COLOR);
|
||||
methods->declare_color(output, MISC_R_COLOR, MISC_G_COLOR, MISC_B_COLOR);
|
||||
return output;
|
||||
}
|
||||
|
||||
void
|
||||
output_draw(struct draw_methods *methods, int logical, hwloc_topology_t topology, void *output)
|
||||
{
|
||||
fig(topology, methods, logical, hwloc_get_root_obj(topology), output, 100, 0, 0);
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
/* .fig back-end. */
|
||||
|
||||
#define FIG_FACTOR 20
|
||||
|
||||
static void *
|
||||
fig_start(void *output_, int width __hwloc_attribute_unused, int height __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output = output_;
|
||||
fprintf(output, "#FIG 3.2 Produced by hwloc's lstopo\n");
|
||||
fprintf(output, "Landscape\n");
|
||||
fprintf(output, "Center\n");
|
||||
fprintf(output, "Inches\n");
|
||||
fprintf(output, "letter\n");
|
||||
fprintf(output, "100.00\n"); /* magnification */
|
||||
fprintf(output, "Single\n"); /* single page */
|
||||
fprintf(output, "-2\n"); /* no transparent color */
|
||||
fprintf(output, "1200 2\n"); /* 1200 ppi resolution, upper left origin */
|
||||
return output;
|
||||
}
|
||||
|
||||
static int __hwloc_attribute_const
|
||||
rgb_to_fig(int r, int g, int b)
|
||||
{
|
||||
if (r == 0xff && g == 0xff && b == 0xff)
|
||||
return 7;
|
||||
|
||||
if (!r && !g && !b)
|
||||
return 0;
|
||||
|
||||
return 32 + rgb_to_color(r, g, b);
|
||||
}
|
||||
|
||||
static void
|
||||
fig_declare_color(void *output_, int r, int g, int b)
|
||||
{
|
||||
FILE *output = output_;
|
||||
int color;
|
||||
|
||||
if (r == 0xff && g == 0xff && b == 0xff)
|
||||
return;
|
||||
|
||||
if (!r && !g && !b)
|
||||
return;
|
||||
|
||||
color = declare_color(r, g, b);
|
||||
|
||||
fprintf(output, "0 %d #%02x%02x%02x\n", 32 + color, r, g, b);
|
||||
}
|
||||
|
||||
static void
|
||||
fig_box(void *output_, int r, int g, int b, unsigned depth, unsigned x, unsigned width, unsigned y, unsigned height)
|
||||
{
|
||||
FILE *output = output_;
|
||||
x *= FIG_FACTOR;
|
||||
y *= FIG_FACTOR;
|
||||
width *= FIG_FACTOR;
|
||||
height *= FIG_FACTOR;
|
||||
fprintf(output, "2 2 0 1 0 %d %u -1 20 0.0 0 0 -1 0 0 5\n\t", rgb_to_fig(r, g, b), depth);
|
||||
fprintf(output, " %u %u", x, y);
|
||||
fprintf(output, " %u %u", x + width, y);
|
||||
fprintf(output, " %u %u", x + width, y + height);
|
||||
fprintf(output, " %u %u", x, y + height);
|
||||
fprintf(output, " %u %u", x, y);
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
fig_line(void *output_, int r, int g, int b, unsigned depth, unsigned x1, unsigned y1, unsigned x2, unsigned y2)
|
||||
{
|
||||
FILE *output = output_;
|
||||
x1 *= FIG_FACTOR;
|
||||
y1 *= FIG_FACTOR;
|
||||
x2 *= FIG_FACTOR;
|
||||
y2 *= FIG_FACTOR;
|
||||
fprintf(output, "2 1 0 1 0 %d %u -1 -1 0.0 0 0 -1 0 0 2\n\t", rgb_to_fig(r, g, b), depth);
|
||||
fprintf(output, " %u %u", x1, y1);
|
||||
fprintf(output, " %u %u", x2, y2);
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
fig_text(void *output_, int r, int g, int b, int size, unsigned depth, unsigned x, unsigned y, const char *text)
|
||||
{
|
||||
FILE *output = output_;
|
||||
unsigned len = strlen(text);
|
||||
int color = rgb_to_fig(r, g, b);
|
||||
x *= FIG_FACTOR;
|
||||
y *= FIG_FACTOR;
|
||||
size = (size * 16) / 10;
|
||||
fprintf(output, "4 0 %d %u -1 0 %d 0.0 4 %d %u %u %u %s\\001\n", color, depth, size, size * 10, len * size * 10, x, y + size * 10, text);
|
||||
}
|
||||
|
||||
static struct draw_methods fig_draw_methods = {
|
||||
.start = fig_start,
|
||||
.declare_color = fig_declare_color,
|
||||
.box = fig_box,
|
||||
.line = fig_line,
|
||||
.text = fig_text,
|
||||
};
|
||||
|
||||
void
|
||||
output_fig (hwloc_topology_t topology, const char *filename, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output = open_file(filename, "w");
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
output = output_draw_start(&fig_draw_methods, logical, topology, output);
|
||||
output_draw(&fig_draw_methods, logical, topology, output);
|
||||
fclose(output);
|
||||
}
|
@ -1,700 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
#include <locale.h>
|
||||
#endif /* HAVE_SETLOCALE */
|
||||
|
||||
#ifdef HAVE_NL_LANGINFO
|
||||
#include <langinfo.h>
|
||||
#endif /* HAVE_NL_LANGINFO */
|
||||
|
||||
#ifdef HAVE_PUTWC
|
||||
#include <wchar.h>
|
||||
#endif /* HAVE_PUTWC */
|
||||
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
#include <curses.h>
|
||||
#include <term.h>
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
#define indent(output, i) \
|
||||
fprintf (output, "%*s", (int) i, "");
|
||||
|
||||
/*
|
||||
* Console fashion text output
|
||||
*/
|
||||
|
||||
static void
|
||||
output_console_obj (hwloc_obj_t l, FILE *output, int logical, int verbose_mode)
|
||||
{
|
||||
char type[32], attr[256], phys[32] = "";
|
||||
unsigned idx = logical ? l->logical_index : l->os_index;
|
||||
const char *indexprefix = logical ? " #" : " p#";
|
||||
if (show_cpuset < 2) {
|
||||
if (l->type == HWLOC_OBJ_MISC && l->name)
|
||||
fprintf(output, "%s", l->name);
|
||||
else {
|
||||
hwloc_obj_type_snprintf (type, sizeof(type), l, verbose_mode-1);
|
||||
fprintf(output, "%s", type);
|
||||
}
|
||||
if (l->depth != 0 && idx != (unsigned)-1)
|
||||
fprintf(output, "%s%u", indexprefix, idx);
|
||||
if (logical && l->os_index != (unsigned) -1 &&
|
||||
(verbose_mode >= 2 || l->type == HWLOC_OBJ_PU || l->type == HWLOC_OBJ_NODE))
|
||||
snprintf(phys, sizeof(phys), "phys=%u", l->os_index);
|
||||
hwloc_obj_attr_snprintf (attr, sizeof(attr), l, " ", verbose_mode-1);
|
||||
if (*phys || *attr) {
|
||||
const char *separator = *phys != '\0' && *attr!= '\0' ? " " : "";
|
||||
fprintf(output, " (%s%s%s)",
|
||||
phys, separator, attr);
|
||||
}
|
||||
if (verbose_mode >= 2 && l->name && l->type != HWLOC_OBJ_MISC)
|
||||
fprintf(output, " \"%s\"", l->name);
|
||||
}
|
||||
if (!l->cpuset)
|
||||
return;
|
||||
if (show_cpuset == 1)
|
||||
fprintf(output, " cpuset=");
|
||||
if (show_cpuset) {
|
||||
char *cpusetstr;
|
||||
hwloc_cpuset_asprintf(&cpusetstr, l->cpuset);
|
||||
fprintf(output, "%s", cpusetstr);
|
||||
free(cpusetstr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Recursively output topology in a console fashion */
|
||||
static void
|
||||
output_topology (hwloc_topology_t topology, hwloc_obj_t l, hwloc_obj_t parent, FILE *output, int i, int logical, int verbose_mode)
|
||||
{
|
||||
unsigned x;
|
||||
int group_identical = (verbose_mode <= 1) && !show_cpuset;
|
||||
if (group_identical
|
||||
&& parent && parent->arity == 1
|
||||
&& l->cpuset && parent->cpuset && hwloc_cpuset_isequal(l->cpuset, parent->cpuset)) {
|
||||
/* in non-verbose mode, merge objects with their parent is they are exactly identical */
|
||||
fprintf(output, " + ");
|
||||
} else {
|
||||
if (parent)
|
||||
fprintf(output, "\n");
|
||||
indent (output, 2*i);
|
||||
i++;
|
||||
}
|
||||
output_console_obj(l, output, logical, verbose_mode);
|
||||
if (l->arity || (!i && !l->arity))
|
||||
{
|
||||
for (x=0; x<l->arity; x++)
|
||||
output_topology (topology, l->children[x], l, output, i, logical, verbose_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Recursive so that multiple depth types are properly shown */
|
||||
static void
|
||||
output_only (hwloc_topology_t topology, hwloc_obj_t l, FILE *output, int logical, int verbose_mode)
|
||||
{
|
||||
unsigned x;
|
||||
if (show_only == l->type) {
|
||||
output_console_obj (l, output, logical, verbose_mode);
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
for (x=0; x<l->arity; x++)
|
||||
output_only (topology, l->children[x], output, logical, verbose_mode);
|
||||
}
|
||||
|
||||
void output_console(hwloc_topology_t topology, const char *filename, int logical, int verbose_mode)
|
||||
{
|
||||
unsigned topodepth;
|
||||
FILE *output;
|
||||
|
||||
if (!filename || !strcmp(filename, "-"))
|
||||
output = stdout;
|
||||
else {
|
||||
output = open_file(filename, "w");
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
topodepth = hwloc_topology_get_depth(topology);
|
||||
|
||||
/*
|
||||
* if verbose_mode == 0, only print the summary.
|
||||
* if verbose_mode == 1, only print the topology tree.
|
||||
* if verbose_mode > 1, print both.
|
||||
*/
|
||||
|
||||
if (show_only != (hwloc_obj_type_t)-1) {
|
||||
if (verbose_mode > 1)
|
||||
fprintf(output, "Only showing %s objects\n", hwloc_obj_type_string(show_only));
|
||||
output_only (topology, hwloc_get_root_obj(topology), output, logical, verbose_mode);
|
||||
} else if (verbose_mode >= 1) {
|
||||
output_topology (topology, hwloc_get_root_obj(topology), NULL, output, 0, logical, verbose_mode);
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
if (verbose_mode > 1 || !verbose_mode) {
|
||||
unsigned depth;
|
||||
for (depth = 0; depth < topodepth; depth++) {
|
||||
hwloc_obj_type_t type = hwloc_get_depth_type (topology, depth);
|
||||
unsigned nbobjs = hwloc_get_nbobjs_by_depth (topology, depth);
|
||||
indent(output, depth);
|
||||
fprintf (output, "depth %u:\t%u %s%s (type #%u)\n",
|
||||
depth, nbobjs, hwloc_obj_type_string (type), nbobjs>1?"s":"", type);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose_mode > 1) {
|
||||
hwloc_const_cpuset_t complete = hwloc_topology_get_complete_cpuset(topology);
|
||||
hwloc_const_cpuset_t topo = hwloc_topology_get_topology_cpuset(topology);
|
||||
hwloc_const_cpuset_t online = hwloc_topology_get_online_cpuset(topology);
|
||||
hwloc_const_cpuset_t allowed = hwloc_topology_get_allowed_cpuset(topology);
|
||||
|
||||
if (!hwloc_cpuset_isequal(topo, complete)) {
|
||||
hwloc_cpuset_t unknown = hwloc_cpuset_alloc();
|
||||
char *unknownstr;
|
||||
hwloc_cpuset_copy(unknown, complete);
|
||||
hwloc_cpuset_andnot(unknown, unknown, topo);
|
||||
hwloc_cpuset_asprintf(&unknownstr, unknown);
|
||||
fprintf (output, "%d processors not represented in topology: %s\n", hwloc_cpuset_weight(unknown), unknownstr);
|
||||
free(unknownstr);
|
||||
hwloc_cpuset_free(unknown);
|
||||
}
|
||||
if (!hwloc_cpuset_isequal(online, complete)) {
|
||||
hwloc_cpuset_t offline = hwloc_cpuset_alloc();
|
||||
char *offlinestr;
|
||||
hwloc_cpuset_copy(offline, complete);
|
||||
hwloc_cpuset_andnot(offline, offline, online);
|
||||
hwloc_cpuset_asprintf(&offlinestr, offline);
|
||||
fprintf (output, "%d processors offline: %s\n", hwloc_cpuset_weight(offline), offlinestr);
|
||||
free(offlinestr);
|
||||
hwloc_cpuset_free(offline);
|
||||
}
|
||||
if (!hwloc_cpuset_isequal(allowed, online)) {
|
||||
if (!hwloc_cpuset_isincluded(online, allowed)) {
|
||||
hwloc_cpuset_t forbidden = hwloc_cpuset_alloc();
|
||||
char *forbiddenstr;
|
||||
hwloc_cpuset_copy(forbidden, online);
|
||||
hwloc_cpuset_andnot(forbidden, forbidden, allowed);
|
||||
hwloc_cpuset_asprintf(&forbiddenstr, forbidden);
|
||||
fprintf(output, "%d processors online but not allowed: %s\n", hwloc_cpuset_weight(forbidden), forbiddenstr);
|
||||
free(forbiddenstr);
|
||||
hwloc_cpuset_free(forbidden);
|
||||
}
|
||||
if (!hwloc_cpuset_isincluded(allowed, online)) {
|
||||
hwloc_cpuset_t potential = hwloc_cpuset_alloc();
|
||||
char *potentialstr;
|
||||
hwloc_cpuset_copy(potential, allowed);
|
||||
hwloc_cpuset_andnot(potential, potential, online);
|
||||
hwloc_cpuset_asprintf(&potentialstr, potential);
|
||||
fprintf(output, "%d processors allowed but not online: %s\n", hwloc_cpuset_weight(potential), potentialstr);
|
||||
free(potentialstr);
|
||||
hwloc_cpuset_free(potential);
|
||||
}
|
||||
}
|
||||
if (!hwloc_topology_is_thissystem(topology))
|
||||
fprintf (output, "Topology not from this system\n");
|
||||
}
|
||||
|
||||
fclose(output);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pretty text output
|
||||
*/
|
||||
|
||||
/* Uses unicode bars if available */
|
||||
#ifdef HAVE_PUTWC
|
||||
typedef wchar_t character;
|
||||
#define PRIchar "lc"
|
||||
#define putcharacter(c,f) putwc(c,f)
|
||||
#else /* HAVE_PUTWC */
|
||||
typedef unsigned char character;
|
||||
#define PRIchar "c"
|
||||
#define putcharacter(c,f) putc(c,f)
|
||||
#endif /* HAVE_PUTWC */
|
||||
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
static int myputchar(int c) {
|
||||
return putcharacter(c, stdout);
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
|
||||
/* Off-screen rendering buffer */
|
||||
struct cell {
|
||||
character c;
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
int fr, fg, fb;
|
||||
int br, bg, bb;
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
};
|
||||
|
||||
struct display {
|
||||
struct cell **cells;
|
||||
int width;
|
||||
int height;
|
||||
int utf8;
|
||||
};
|
||||
|
||||
/* Allocate the off-screen buffer */
|
||||
static void *
|
||||
text_start(void *output __hwloc_attribute_unused, int width, int height)
|
||||
{
|
||||
int j, i;
|
||||
struct display *disp = malloc(sizeof(*disp));
|
||||
/* terminals usually have narrow characters, so let's make them wider */
|
||||
width /= (gridsize/2);
|
||||
height /= gridsize;
|
||||
disp->cells = malloc(height * sizeof(*disp->cells));
|
||||
disp->width = width;
|
||||
disp->height = height;
|
||||
for (j = 0; j < height; j++) {
|
||||
disp->cells[j] = calloc(width, sizeof(**disp->cells));
|
||||
for (i = 0; i < width; i++)
|
||||
disp->cells[j][i].c = ' ';
|
||||
}
|
||||
#ifdef HAVE_NL_LANGINFO
|
||||
disp->utf8 = !strcmp(nl_langinfo(CODESET), "UTF-8");
|
||||
#endif /* HAVE_NL_LANGINFO */
|
||||
return disp;
|
||||
}
|
||||
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
/* Standard terminfo strings */
|
||||
static char *initc = NULL, *initp = NULL;
|
||||
|
||||
/* Set text color to bright white or black according to the background */
|
||||
static int set_textcolor(int rr, int gg, int bb)
|
||||
{
|
||||
if (!initc && !initp && rr + gg + bb < 2) {
|
||||
if (enter_bold_mode)
|
||||
tputs(enter_bold_mode, 1, myputchar);
|
||||
return 7;
|
||||
} else {
|
||||
if (exit_attribute_mode)
|
||||
tputs(exit_attribute_mode, 1, myputchar);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_color(int fr, int fg, int fb, int br, int bg, int bb)
|
||||
{
|
||||
char *toput;
|
||||
int color, textcolor;
|
||||
|
||||
if (initc || initp) {
|
||||
/* Can set rgb color, easy */
|
||||
textcolor = rgb_to_color(fr, fg, fb) + 16;
|
||||
color = rgb_to_color(br, bg, bb) + 16;
|
||||
} else {
|
||||
/* Magic trigger: it seems to separate colors quite well */
|
||||
int brr = br >= 0xe0;
|
||||
int bgg = bg >= 0xe0;
|
||||
int bbb = bb >= 0xe0;
|
||||
|
||||
if (set_a_background)
|
||||
/* ANSI colors */
|
||||
color = (brr << 0) | (bgg << 1) | (bbb << 2);
|
||||
else
|
||||
/* Legacy colors */
|
||||
color = (brr << 2) | (bgg << 1) | (bbb << 0);
|
||||
textcolor = set_textcolor(brr, bgg, bbb);
|
||||
}
|
||||
|
||||
/* And now output magic string to TTY */
|
||||
if (set_a_foreground) {
|
||||
/* foreground */
|
||||
if ((toput = tparm(set_a_foreground, textcolor, 0, 0, 0, 0, 0, 0, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
/* background */
|
||||
if ((toput = tparm(set_a_background, color, 0, 0, 0, 0, 0, 0, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
} else if (set_foreground) {
|
||||
/* foreground */
|
||||
if ((toput = tparm(set_foreground, textcolor, 0, 0, 0, 0, 0, 0, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
/* background */
|
||||
if ((toput = tparm(set_background, color, 0, 0, 0, 0, 0, 0, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
} else if (set_color_pair) {
|
||||
/* pair */
|
||||
if ((toput = tparm(set_color_pair, color, 0, 0, 0, 0, 0, 0, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
}
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
|
||||
/* We we can, allocate rgb colors */
|
||||
static void
|
||||
text_declare_color(void *output __hwloc_attribute_unused, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused)
|
||||
{
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
int color = declare_color(r, g, b);
|
||||
/* Yes, values seem to range from 0 to 1000 inclusive */
|
||||
int rr = (r * 1001) / 256;
|
||||
int gg = (g * 1001) / 256;
|
||||
int bb = (b * 1001) / 256;
|
||||
char *toput;
|
||||
|
||||
if (initc) {
|
||||
if ((toput = tparm(initc, color + 16, rr, gg, bb, 0, 0, 0, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
} else if (initp) {
|
||||
if ((toput = tparm(initp, color + 16, 0, 0, 0, rr, gg, bb, 0, 0)))
|
||||
tputs(toput, 1, myputchar);
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
}
|
||||
|
||||
/* output text, erasing any previous content */
|
||||
static void
|
||||
put(struct display *disp, int x, int y, character c, int fr __hwloc_attribute_unused, int fg __hwloc_attribute_unused, int fb __hwloc_attribute_unused, int br __hwloc_attribute_unused, int bg __hwloc_attribute_unused, int bb __hwloc_attribute_unused)
|
||||
{
|
||||
if (x >= disp->width || y >= disp->height) {
|
||||
/* fprintf(stderr, "%"PRIchar" overflowed to (%d,%d)\n", c, x, y); */
|
||||
return;
|
||||
}
|
||||
disp->cells[y][x].c = c;
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
if (fr != -1) {
|
||||
disp->cells[y][x].fr = fr;
|
||||
disp->cells[y][x].fg = fg;
|
||||
disp->cells[y][x].fb = fb;
|
||||
}
|
||||
if (br != -1) {
|
||||
disp->cells[y][x].br = br;
|
||||
disp->cells[y][x].bg = bg;
|
||||
disp->cells[y][x].bb = bb;
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
}
|
||||
|
||||
/* Where bars of a character go to */
|
||||
enum {
|
||||
up = (1<<0),
|
||||
down = (1<<1),
|
||||
left = (1<<2),
|
||||
right = (1<<3)
|
||||
};
|
||||
|
||||
/* Convert a bar character into its directions */
|
||||
static int
|
||||
to_directions(struct display *disp, character c)
|
||||
{
|
||||
#ifdef HAVE_PUTWC
|
||||
if (disp->utf8) {
|
||||
switch (c) {
|
||||
case L'\x250c': return down|right;
|
||||
case L'\x2510': return down|left;
|
||||
case L'\x2514': return up|right;
|
||||
case L'\x2518': return up|left;
|
||||
case L'\x2500': return left|right;
|
||||
case L'\x2502': return down|up;
|
||||
case L'\x2577': return down;
|
||||
case L'\x2575': return up;
|
||||
case L'\x2576': return right;
|
||||
case L'\x2574': return left;
|
||||
case L'\x251c': return down|up|right;
|
||||
case L'\x2524': return down|up|left;
|
||||
case L'\x252c': return down|left|right;
|
||||
case L'\x2534': return up|left|right;
|
||||
case L'\x253c': return down|up|left|right;
|
||||
default: return 0;
|
||||
}
|
||||
} else
|
||||
#endif /* HAVE_PUTWC */
|
||||
{
|
||||
switch (c) {
|
||||
case L'-': return left|right;
|
||||
case L'|': return down|up;
|
||||
case L'/':
|
||||
case L'\\':
|
||||
case L'+': return down|up|left|right;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Produce a bar character given the wanted directions */
|
||||
static character
|
||||
from_directions(struct display *disp, int direction)
|
||||
{
|
||||
#ifdef HAVE_PUTWC
|
||||
if (disp->utf8) {
|
||||
static const wchar_t chars[] = {
|
||||
[down|right] = L'\x250c',
|
||||
[down|left] = L'\x2510',
|
||||
[up|right] = L'\x2514',
|
||||
[up|left] = L'\x2518',
|
||||
[left|right] = L'\x2500',
|
||||
[down|up] = L'\x2502',
|
||||
[down] = L'\x2577',
|
||||
[up] = L'\x2575',
|
||||
[right] = L'\x2576',
|
||||
[left] = L'\x2574',
|
||||
[down|up|right] = L'\x251c',
|
||||
[down|up|left] = L'\x2524',
|
||||
[down|left|right] = L'\x252c',
|
||||
[up|left|right] = L'\x2534',
|
||||
[down|up|left|right] = L'\x253c',
|
||||
[0] = L' ',
|
||||
};
|
||||
return chars[direction];
|
||||
} else
|
||||
#endif /* HAVE_PUTWC */
|
||||
{
|
||||
static const char chars[] = {
|
||||
[down|right] = '/',
|
||||
[down|left] = '\\',
|
||||
[up|right] = '\\',
|
||||
[up|left] = '/',
|
||||
[left|right] = '-',
|
||||
[down|up] = '|',
|
||||
[down] = '|',
|
||||
[up] = '|',
|
||||
[right] = '-',
|
||||
[left] = '-',
|
||||
[down|up|right] = '+',
|
||||
[down|up|left] = '+',
|
||||
[down|left|right] = '+',
|
||||
[up|left|right] = '+',
|
||||
[down|up|left|right] = '+',
|
||||
[0] = ' ',
|
||||
};
|
||||
return chars[direction];
|
||||
}
|
||||
}
|
||||
|
||||
/* output bars, merging with existing bars: `andnot' are removed, `or' are added */
|
||||
static void
|
||||
merge(struct display *disp, int x, int y, int or, int andnot, int r, int g, int b)
|
||||
{
|
||||
character current = disp->cells[y][x].c;
|
||||
int directions = (to_directions(disp, current) & ~andnot) | or;
|
||||
put(disp, x, y, from_directions(disp, directions), -1, -1, -1, r, g, b);
|
||||
}
|
||||
|
||||
/* Now we can implement the standard drawing helpers */
|
||||
static void
|
||||
text_box(void *output, int r, int g, int b, unsigned depth __hwloc_attribute_unused, unsigned x1, unsigned width, unsigned y1, unsigned height)
|
||||
{
|
||||
struct display *disp = output;
|
||||
unsigned i, j;
|
||||
unsigned x2, y2;
|
||||
x1 /= (gridsize/2);
|
||||
width /= (gridsize/2);
|
||||
y1 /= gridsize;
|
||||
height /= gridsize;
|
||||
x2 = x1 + width - 1;
|
||||
y2 = y1 + height - 1;
|
||||
|
||||
/* Corners */
|
||||
merge(disp, x1, y1, down|right, 0, r, g, b);
|
||||
merge(disp, x2, y1, down|left, 0, r, g, b);
|
||||
merge(disp, x1, y2, up|right, 0, r, g, b);
|
||||
merge(disp, x2, y2, up|left, 0, r, g, b);
|
||||
|
||||
for (i = 1; i < width - 1; i++) {
|
||||
/* upper line */
|
||||
merge(disp, x1 + i, y1, left|right, down, r, g, b);
|
||||
/* lower line */
|
||||
merge(disp, x1 + i, y2, left|right, up, r, g, b);
|
||||
}
|
||||
for (j = 1; j < height - 1; j++) {
|
||||
/* left line */
|
||||
merge(disp, x1, y1 + j, up|down, right, r, g, b);
|
||||
/* right line */
|
||||
merge(disp, x2, y1 + j, up|down, left, r, g, b);
|
||||
}
|
||||
for (j = y1 + 1; j < y2; j++) {
|
||||
for (i = x1 + 1; i < x2; i++) {
|
||||
put(disp, i, j, ' ', -1, -1, -1, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
text_line(void *output, int r __hwloc_attribute_unused, int g __hwloc_attribute_unused, int b __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x1, unsigned y1, unsigned x2, unsigned y2)
|
||||
{
|
||||
struct display *disp = output;
|
||||
unsigned i, j, z;
|
||||
x1 /= (gridsize/2);
|
||||
y1 /= gridsize;
|
||||
x2 /= (gridsize/2);
|
||||
y2 /= gridsize;
|
||||
|
||||
/* Canonicalize coordinates */
|
||||
if (x1 > x2) {
|
||||
z = x1;
|
||||
x1 = x2;
|
||||
x2 = z;
|
||||
}
|
||||
if (y1 > y2) {
|
||||
z = y1;
|
||||
y1 = y2;
|
||||
y2 = z;
|
||||
}
|
||||
|
||||
/* vertical/horizontal should be enough, but should mix with existing
|
||||
* characters for better output ! */
|
||||
|
||||
if (x1 == x2) {
|
||||
/* Vertical */
|
||||
if (y1 == y2) {
|
||||
/* Hu ?! That's a point, let's do nothing... */
|
||||
} else {
|
||||
/* top */
|
||||
merge(disp, x1, y1, down, 0, -1, -1, -1);
|
||||
/* bottom */
|
||||
merge(disp, x1, y2, up, 0, -1, -1, -1);
|
||||
}
|
||||
for (j = y1 + 1; j < y2; j++)
|
||||
merge(disp, x1, j, down|up, 0, -1, -1, -1);
|
||||
} else if (y1 == y2) {
|
||||
/* Horizontal */
|
||||
/* left */
|
||||
merge(disp, x1, y1, right, 0, -1, -1, -1);
|
||||
/* right */
|
||||
merge(disp, x2, y1, left, 0, -1, -1, -1);
|
||||
for (i = x1 + 1; i < x2; i++)
|
||||
merge(disp, i, y1, left|right, 0, -1, -1, -1);
|
||||
} else {
|
||||
/* Unsupported, sorry */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
text_text(void *output, int r, int g, int b, int size __hwloc_attribute_unused, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned y, const char *text)
|
||||
{
|
||||
struct display *disp = output;
|
||||
x /= (gridsize/2);
|
||||
y /= gridsize;
|
||||
for ( ; *text; text++)
|
||||
put(disp, x++, y, *text, r, g, b, -1, -1, -1);
|
||||
}
|
||||
|
||||
static struct draw_methods text_draw_methods = {
|
||||
.start = text_start,
|
||||
.declare_color = text_declare_color,
|
||||
.box = text_box,
|
||||
.line = text_line,
|
||||
.text = text_text,
|
||||
};
|
||||
|
||||
void output_text(hwloc_topology_t topology, const char *filename, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
FILE *output;
|
||||
struct display *disp;
|
||||
int i, j;
|
||||
int lfr, lfg, lfb; /* Last foreground color */
|
||||
int lbr, lbg, lbb; /* Last background color */
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
int term = 0;
|
||||
char *tmp;
|
||||
#endif
|
||||
|
||||
if (!filename || !strcmp(filename, "-"))
|
||||
output = stdout;
|
||||
else {
|
||||
output = open_file(filename, "w");
|
||||
if (!output) {
|
||||
fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to use utf-8 characters */
|
||||
#ifdef HAVE_SETLOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
#endif /* HAVE_SETLOCALE */
|
||||
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
/* If we are outputing to a tty, use colors */
|
||||
if (output == stdout && isatty(STDOUT_FILENO)) {
|
||||
term = !setupterm(NULL, STDOUT_FILENO, NULL);
|
||||
|
||||
if (term) {
|
||||
/* reset colors */
|
||||
if (orig_colors)
|
||||
tputs(orig_colors, 1, myputchar);
|
||||
|
||||
/* Get terminfo(5) strings */
|
||||
initp = initialize_pair;
|
||||
if (max_pairs <= 16 || !initp || !set_color_pair) {
|
||||
/* Can't use max_pairs to define our own colors */
|
||||
initp = NULL;
|
||||
if (max_colors > 16)
|
||||
if (can_change)
|
||||
initc = initialize_color;
|
||||
}
|
||||
/* Prevent a trivial compiler warning because the param of
|
||||
tgetflag is (char*), not (const char*). */
|
||||
tmp = strdup("lhs");
|
||||
if (tgetflag(tmp)) {
|
||||
/* Sorry, I'm lazy to convert colors and I don't know any terminal
|
||||
* using LHS anyway */
|
||||
initc = initp = 0;
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
|
||||
disp = output_draw_start(&text_draw_methods, logical, topology, output);
|
||||
output_draw(&text_draw_methods, logical, topology, disp);
|
||||
|
||||
lfr = lfg = lfb = -1;
|
||||
lbr = lbg = lbb = -1;
|
||||
for (j = 0; j < disp->height; j++) {
|
||||
for (i = 0; i < disp->width; i++) {
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
if (term) {
|
||||
/* TTY output, use colors */
|
||||
int fr = disp->cells[j][i].fr;
|
||||
int fg = disp->cells[j][i].fg;
|
||||
int fb = disp->cells[j][i].fb;
|
||||
int br = disp->cells[j][i].br;
|
||||
int bg = disp->cells[j][i].bg;
|
||||
int bb = disp->cells[j][i].bb;
|
||||
|
||||
/* Avoid too much work for the TTY */
|
||||
if (fr != lfr || fg != lfg || fb != lfb
|
||||
|| br != lbr || bg != lbg || bb != lbb) {
|
||||
set_color(fr, fg, fb, br, bg, bb);
|
||||
lfr = fr;
|
||||
lfg = fg;
|
||||
lfb = fb;
|
||||
lbr = br;
|
||||
lbg = bg;
|
||||
lbb = bb;
|
||||
}
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
putcharacter(disp->cells[j][i].c, output);
|
||||
}
|
||||
#ifdef HWLOC_HAVE_LIBTERMCAP
|
||||
/* Keep the rest of the line as default */
|
||||
if (term && orig_pair) {
|
||||
lfr = lfg = lfb = -1;
|
||||
lbr = lbg = lbb = -1;
|
||||
tputs(orig_pair, 1, myputchar);
|
||||
}
|
||||
#endif /* HWLOC_HAVE_LIBTERMCAP */
|
||||
putcharacter('\n', output);
|
||||
}
|
||||
}
|
@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
/* windows back-end. */
|
||||
|
||||
static struct color {
|
||||
int r, g, b;
|
||||
HGDIOBJ brush;
|
||||
} *colors;
|
||||
|
||||
static int numcolors;
|
||||
|
||||
static HGDIOBJ
|
||||
rgb_to_brush(int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numcolors; i++)
|
||||
if (colors[i].r == r && colors[i].g == g && colors[i].b == b)
|
||||
return colors[i].brush;
|
||||
|
||||
fprintf(stderr, "color #%02x%02x%02x not declared\n", r, g, b);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct draw_methods windows_draw_methods;
|
||||
|
||||
static hwloc_topology_t the_topology;
|
||||
static int the_logical;
|
||||
static int state, control;
|
||||
static int x, y, x_delta, y_delta;
|
||||
static int finish;
|
||||
static int the_width, the_height;
|
||||
static int win_width, win_height;
|
||||
|
||||
static LRESULT CALLBACK
|
||||
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
int redraw = 0;
|
||||
switch (message) {
|
||||
case WM_PAINT: {
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
output_draw(&windows_draw_methods, the_logical, the_topology, &ps);
|
||||
EndPaint(hwnd, &ps);
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONDOWN:
|
||||
state = 1;
|
||||
x = GET_X_LPARAM(lparam);
|
||||
y = GET_Y_LPARAM(lparam);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
state = 0;
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
if (!(wparam & MK_LBUTTON))
|
||||
state = 0;
|
||||
if (state) {
|
||||
int new_x = GET_X_LPARAM(lparam);
|
||||
int new_y = GET_Y_LPARAM(lparam);
|
||||
x_delta -= new_x - x;
|
||||
y_delta -= new_y - y;
|
||||
x = new_x;
|
||||
y = new_y;
|
||||
redraw = 1;
|
||||
}
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
switch (wparam) {
|
||||
case 'q':
|
||||
case 'Q':
|
||||
case VK_ESCAPE:
|
||||
finish = 1;
|
||||
break;
|
||||
case VK_LEFT:
|
||||
x_delta -= win_width/10;
|
||||
redraw = 1;
|
||||
break;
|
||||
case VK_RIGHT:
|
||||
x_delta += win_width/10;
|
||||
redraw = 1;
|
||||
break;
|
||||
case VK_UP:
|
||||
y_delta -= win_height/10;
|
||||
redraw = 1;
|
||||
break;
|
||||
case VK_DOWN:
|
||||
y_delta += win_height/10;
|
||||
redraw = 1;
|
||||
break;
|
||||
case VK_PRIOR:
|
||||
if (control) {
|
||||
x_delta -= win_width;
|
||||
redraw = 1;
|
||||
} else {
|
||||
y_delta -= win_height;
|
||||
redraw = 1;
|
||||
}
|
||||
break;
|
||||
case VK_NEXT:
|
||||
if (control) {
|
||||
x_delta += win_width;
|
||||
redraw = 1;
|
||||
} else {
|
||||
y_delta += win_height;
|
||||
redraw = 1;
|
||||
}
|
||||
break;
|
||||
case VK_HOME:
|
||||
x_delta = 0;
|
||||
y_delta = 0;
|
||||
redraw = 1;
|
||||
break;
|
||||
case VK_END:
|
||||
x_delta = INT_MAX;
|
||||
y_delta = INT_MAX;
|
||||
redraw = 1;
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
control = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
switch (wparam) {
|
||||
case VK_CONTROL:
|
||||
control = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_SIZE:
|
||||
win_width = LOWORD(lparam);
|
||||
win_height = HIWORD(lparam);
|
||||
redraw = 1;
|
||||
break;
|
||||
}
|
||||
if (redraw) {
|
||||
if (x_delta > the_width - win_width)
|
||||
x_delta = the_width - win_width;
|
||||
if (y_delta > the_height - win_height)
|
||||
y_delta = the_height - win_height;
|
||||
if (x_delta < 0)
|
||||
x_delta = 0;
|
||||
if (y_delta < 0)
|
||||
y_delta = 0;
|
||||
RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
|
||||
}
|
||||
return DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
static void *
|
||||
windows_start(void *output_ __hwloc_attribute_unused, int width, int height)
|
||||
{
|
||||
WNDCLASS wndclass = {
|
||||
.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH),
|
||||
.hCursor = LoadCursor(NULL, IDC_SIZEALL),
|
||||
.hIcon = LoadIcon(NULL, IDI_APPLICATION),
|
||||
.lpfnWndProc = WndProc,
|
||||
.lpszClassName = "lstopo",
|
||||
};
|
||||
HWND toplevel;
|
||||
|
||||
win_width = width + 2*GetSystemMetrics(SM_CXSIZEFRAME);
|
||||
win_height = height + 2*GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
|
||||
|
||||
if (win_width > GetSystemMetrics(SM_CXFULLSCREEN))
|
||||
win_width = GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
|
||||
if (win_height > GetSystemMetrics(SM_CYFULLSCREEN))
|
||||
win_height = GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
|
||||
RegisterClass(&wndclass);
|
||||
toplevel = CreateWindow("lstopo", "lstopo", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
win_width, win_height, NULL, NULL, NULL, NULL);
|
||||
|
||||
the_width = width;
|
||||
the_height = height;
|
||||
|
||||
ShowWindow(toplevel, SW_SHOWDEFAULT);
|
||||
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
static void
|
||||
windows_declare_color(void *output_ __hwloc_attribute_unused, int r, int g, int b)
|
||||
{
|
||||
HBRUSH brush;
|
||||
COLORREF color = RGB(r, g, b);
|
||||
|
||||
brush = CreateSolidBrush(color);
|
||||
if (!brush) {
|
||||
fprintf(stderr,"Could not allocate color %02x%02x%02x\n", r, g, b);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
colors = realloc(colors, sizeof(*colors) * (numcolors + 1));
|
||||
colors[numcolors].r = r;
|
||||
colors[numcolors].g = g;
|
||||
colors[numcolors].b = b;
|
||||
colors[numcolors].brush = (HGDIOBJ) brush;
|
||||
numcolors++;
|
||||
}
|
||||
|
||||
static void
|
||||
windows_box(void *output, int r, int g, int b, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned width, unsigned y, unsigned height)
|
||||
{
|
||||
PAINTSTRUCT *ps = output;
|
||||
SelectObject(ps->hdc, rgb_to_brush(r, g, b));
|
||||
SetBkColor(ps->hdc, RGB(r, g, b));
|
||||
Rectangle(ps->hdc, x - x_delta, y - y_delta, x + width - x_delta, y + height - y_delta);
|
||||
}
|
||||
|
||||
static void
|
||||
windows_line(void *output, int r, int g, int b, unsigned depth __hwloc_attribute_unused, unsigned x1, unsigned y1, unsigned x2, unsigned y2)
|
||||
{
|
||||
PAINTSTRUCT *ps = output;
|
||||
SelectObject(ps->hdc, rgb_to_brush(r, g, b));
|
||||
MoveToEx(ps->hdc, x1 - x_delta, y1 - y_delta, NULL);
|
||||
LineTo(ps->hdc, x2 - x_delta, y2 - y_delta);
|
||||
}
|
||||
|
||||
static void
|
||||
windows_text(void *output, int r, int g, int b, int size, unsigned depth __hwloc_attribute_unused, unsigned x, unsigned y, const char *text)
|
||||
{
|
||||
PAINTSTRUCT *ps = output;
|
||||
HFONT font;
|
||||
SetTextColor(ps->hdc, RGB(r, g, b));
|
||||
font = CreateFont(size, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL);
|
||||
SelectObject(ps->hdc, (HGDIOBJ) font);
|
||||
TextOut(ps->hdc, x - x_delta, y - y_delta, text, strlen(text));
|
||||
DeleteObject(font);
|
||||
}
|
||||
|
||||
struct draw_methods windows_draw_methods = {
|
||||
.start = windows_start,
|
||||
.declare_color = windows_declare_color,
|
||||
.box = windows_box,
|
||||
.line = windows_line,
|
||||
.text = windows_text,
|
||||
};
|
||||
|
||||
void
|
||||
output_windows (hwloc_topology_t topology, const char *filename __hwloc_attribute_unused, int logical, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
HWND toplevel;
|
||||
the_topology = topology;
|
||||
the_logical = logical;
|
||||
toplevel = output_draw_start(&windows_draw_methods, logical, topology, NULL);
|
||||
UpdateWindow(toplevel);
|
||||
MSG msg;
|
||||
while (!finish && GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
|
||||
#include <hwloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
void output_xml(hwloc_topology_t topology, const char *filename, int logical __hwloc_attribute_unused, int verbose_mode __hwloc_attribute_unused)
|
||||
{
|
||||
if (!strcasecmp(filename, "-.xml"))
|
||||
filename = "-";
|
||||
|
||||
hwloc_topology_export_xml(topology, filename);
|
||||
}
|
||||
|
||||
#endif /* HWLOC_HAVE_XML */
|
@ -1,289 +0,0 @@
|
||||
.\" -*- nroff -*-
|
||||
.\" Copyright © 2010 Cisco Systems, Inc. All rights reserved.
|
||||
.TH LSTOPO "1" "#HWLOC_DATE#" "#PACKAGE_VERSION#" "#PACKAGE_NAME#"
|
||||
.SH NAME
|
||||
lstopo \- Show the topology of the system (note that hwloc-bind(1)
|
||||
provides a detailed explanation of the hwloc system; it should be read
|
||||
before reading this man page).
|
||||
.
|
||||
.\" **************************
|
||||
.\" Synopsis Section
|
||||
.\" **************************
|
||||
.SH SYNOPSIS
|
||||
.
|
||||
.B lstopo
|
||||
[ \fIoptions \fR]... [ \fIfilename \fR]
|
||||
.
|
||||
.\" **************************
|
||||
.\" Options Section
|
||||
.\" **************************
|
||||
.SH OPTIONS
|
||||
.
|
||||
.TP
|
||||
\fB\-v\fR \fB\-\-verbose\fR
|
||||
Include additional detail.
|
||||
.TP
|
||||
\fB\-s\fR \fB\-\-silent\fR
|
||||
Opposite of --verbose (default).
|
||||
.TP
|
||||
\fB\-l\fR \fB\-\-logical\fR
|
||||
Display hwloc logical indexes instead of physical/OS indexes (default).
|
||||
These indexes are prefixed with "#".
|
||||
The physical indexes of some objects (PU and Node by default, all
|
||||
objects if verbose) will appear as object attribute "phys=...".
|
||||
.TP
|
||||
\fB\-p\fR \fB\-\-physical\fR
|
||||
Display OS/physical indexes instead of hwloc logical indexes.
|
||||
These indexes are prefixed with "p#" instead of "#".
|
||||
.TP
|
||||
\fB\-c\fR \fB\-\-cpuset\fR
|
||||
Display the cpuset of each object.
|
||||
.TP
|
||||
\fB\-C\fR \fB\-\-cpuset\-only\fR
|
||||
Only display the cpuset of each object; do not display anything else
|
||||
about the object.
|
||||
.TP
|
||||
\fB\-\-only\fR <type>
|
||||
Only show objects of the given type in the text output.
|
||||
.TP
|
||||
\fB\-\-ignore\fR <type>
|
||||
Ignore all objects of type <type> in the topology.
|
||||
.TP
|
||||
\fB\-\-no\-caches\fR
|
||||
Do not show caches.
|
||||
.TP
|
||||
\fB\-\-no\-useless\-caches\fR
|
||||
Do not show caches which do not have a hierarchical impact.
|
||||
.TP
|
||||
\fB\-\-whole\-system\fR
|
||||
Do not consider administration limitations.
|
||||
.TP
|
||||
\fB\-\-merge\fR
|
||||
Do not show levels that do not have a hierarchical impact.
|
||||
.TP
|
||||
\fB\-\-xml\fR <path>
|
||||
Read topology from XML file <path> (instead of discovering the
|
||||
topology on the local machine). If <path> is "\-", the standard input
|
||||
is used. XML support must have been compiled in to hwloc for this
|
||||
option to be usable.
|
||||
.TP
|
||||
\fB\-\-fsys\-root\fR <path>
|
||||
Read topology from the chroot specified by <path> (instead of
|
||||
discovering the topology on the local machine). This option is
|
||||
generally only available on Linux.
|
||||
.TP
|
||||
\fB\-\-pid\fR <pid>
|
||||
Detect topology as seen by process <pid>, i.e. as if process <pid> did the
|
||||
discovery itself, and show its current binding. Note that this can for instance
|
||||
change the set of allowed processors. If 0 is given as pid, the current binding for the lstopo process will be shown.
|
||||
.TP
|
||||
\fB\-\-top\fR
|
||||
Show existing processes as misc objects in the output. To avoid uselessly
|
||||
cluttering the output, only processes that are restricted to some part of the
|
||||
machine are shown. On Linux, kernel threads are not shown.
|
||||
.TP
|
||||
\fB\-\-synthetic\fR <specification>
|
||||
Simulate a fake hierarchy (instead of discovering the topology on the
|
||||
local machine).
|
||||
.TP
|
||||
\fB\-\-fontsize\fR <size>
|
||||
Set size of text font.
|
||||
.TP
|
||||
\fB\-\-gridsize\fR <size>
|
||||
Set size of margin between elements.
|
||||
.TP
|
||||
\fB\-\-horiz\fR
|
||||
Horizontal graphic layout instead of nearly 4/3 ratio.
|
||||
.TP
|
||||
\fB\-\-vert\fR
|
||||
Vertical graphic layout instead of nearly 4/3 ratio.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
Report version and exit.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Description Section
|
||||
.\" **************************
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
lstopo is capable of displaying a topological map of the system in a
|
||||
variety of different output formats. If no filename is specified and
|
||||
the DISPLAY environment variable is set, lstopo displays the map in a
|
||||
graphical window. If no filename is specified and the DISPLAY
|
||||
environment variable is
|
||||
.I not
|
||||
set, a text summary is displayed.
|
||||
.
|
||||
.PP
|
||||
The filename specified directly implies the output format that will be
|
||||
used; see the OUTPUT FORMATS section, below. Output formats that
|
||||
support color will indicate specific characteristics about individual
|
||||
CPUs by their color; see the COLORS section, below.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Output Formats Section
|
||||
.\" **************************
|
||||
.SH OUTPUT FORMATS
|
||||
.
|
||||
.TP
|
||||
.B \-
|
||||
Send a text summary to stdout.
|
||||
.
|
||||
.TP
|
||||
.B /dev/stdout
|
||||
Send a text summary to stdout. It is effectively the same as
|
||||
specifying "\-".
|
||||
.
|
||||
.TP
|
||||
.B <filename>.txt
|
||||
If the filename ends in ".txt", lstopo outputs an ASCII art
|
||||
representation of the map.
|
||||
.
|
||||
.TP
|
||||
.B \-.txt
|
||||
If the entire filename is "\-.txt", lstopo outputs the same ASCII art
|
||||
representation as other ".txt" filenames, but with two execeptions: 1)
|
||||
the output is sent to stdout, and 2) if colors are supported on the
|
||||
terminal, the ASCII art will be colorized.
|
||||
.
|
||||
.TP
|
||||
.B <filename>.fig
|
||||
If the filename ends in ".fig", lstopo outputs a representation of the
|
||||
map that can be loaded in Xfig.
|
||||
.
|
||||
.TP
|
||||
.B <filename>.pdf
|
||||
If the filename ends in ".pdf" and lstopo was compiled with the proper
|
||||
support, lstopo outputs a PDF representation of the map.
|
||||
.
|
||||
.TP
|
||||
.B <filename>.ps
|
||||
If the filename ends in ".ps" and lstopo was compiled with the proper
|
||||
support, lstopo outputs a Postscript representation of the map.
|
||||
.
|
||||
.TP
|
||||
.B <filename>.png
|
||||
If the filename ends in ".png" and lstopo was compiled with the proper
|
||||
support, lstopo outputs a PNG representation of the map.
|
||||
.
|
||||
.TP
|
||||
.B <filename>.svg
|
||||
If the filename ends in ".svn" and lstopo was compiled with the proper
|
||||
support, lstopo outputs an SVG representation of the map.
|
||||
.
|
||||
.TP
|
||||
.B <filename>.xml
|
||||
If the filename ends in ".xml" and lstopo was compiled with the proper
|
||||
support, lstopo outputs an XML representation of the map.
|
||||
It may be reused later, even on another machine, with lstopo \-\-xml,
|
||||
the HWLOC_XMLFILE environment variable, or the hwloc_topology_set_xml()
|
||||
function.
|
||||
.
|
||||
.PP
|
||||
See the output of "lstopo \-\-help" for a specific list of what
|
||||
graphical output formats are supported in your hwloc installation.
|
||||
.
|
||||
.\" **************************
|
||||
.\" Colors Section
|
||||
.\" **************************
|
||||
.SH COLORS
|
||||
Individual CPUs are colored in the semi-graphical and graphical output
|
||||
formats to indicate different characteristics:
|
||||
.TP
|
||||
Green
|
||||
The CPU is in the current CPU binding mask.
|
||||
.TP
|
||||
White
|
||||
The CPU is in the allowed set (see below), but it is not in the
|
||||
current CPU binding mask.
|
||||
.TP
|
||||
Red
|
||||
The CPU is not in the allowed set (see below).
|
||||
.TP
|
||||
Black
|
||||
The CPU is offline (not all OS's support displaying offline CPUs).
|
||||
.
|
||||
.PP
|
||||
The "allowed set" is the set of CPUs to which the current process is
|
||||
allowed to bind. The allowed set is usually either inherited from the
|
||||
parent process or set by administrative qpolicies on the system. Linux
|
||||
cpusets are one example of limiting the allowed set for a process and
|
||||
its children to be less than the full set of CPUs on the system.
|
||||
.PP
|
||||
Different processes may therefore have different CPUs in the allowed
|
||||
set. Hence, invoking lstopo in different contexts and/or as different
|
||||
users may display different colors for the same individual CPUs (e.g.,
|
||||
running lstopo in one context may show a specific CPU as red, but
|
||||
running lstopo in a different context may show the same CPU as white).
|
||||
.
|
||||
.\" **************************
|
||||
.\" Layout Section
|
||||
.\" **************************
|
||||
.SH LAYOUT
|
||||
In its graphical output, lstopo uses simple rectangular heuristics
|
||||
to try to achieve a 4/3 ratio between width and height. However,
|
||||
in the particular case of NUMA nodes, the layout is always a flat
|
||||
rectangle, to avoid letting the user believe any particular NUMA
|
||||
topology (lstopo is not able to render that yet).
|
||||
.
|
||||
.\" **************************
|
||||
.\" Examples Section
|
||||
.\" **************************
|
||||
.SH EXAMPLES
|
||||
.
|
||||
To display the machine topology in text mode:
|
||||
|
||||
lstopo -
|
||||
|
||||
To display in graphical mode (assuming that the DISPLAY environment
|
||||
variable is set to a relevant value):
|
||||
|
||||
lstopo
|
||||
|
||||
To export the topology to a PNG file:
|
||||
|
||||
lstopo file.png
|
||||
|
||||
To export a XML file on a machine and later display the corresponding
|
||||
graphic output on another machine:
|
||||
|
||||
machine1$ lstopo file.xml
|
||||
<transfer file.xml from machine1 to machine2>
|
||||
machine2$ lstopo --xml file.xml
|
||||
|
||||
To display a summary of the topology:
|
||||
|
||||
lstopo -s
|
||||
|
||||
To get more details about the topology:
|
||||
|
||||
lstopo -v
|
||||
|
||||
To only show cores:
|
||||
|
||||
lstopo --only core
|
||||
|
||||
To show cpusets:
|
||||
|
||||
lstopo --cpuset
|
||||
|
||||
To only show the cpusets of sockets:
|
||||
|
||||
lstopo --only socket --cpuset-only
|
||||
|
||||
Simulate a fake hierarchy; this example shows with 2 NUMA nodes of 2
|
||||
processor units:
|
||||
|
||||
lstopo --synthetic "n:2 2"
|
||||
|
||||
To count the number of logical processors in the system
|
||||
|
||||
lstopo --only pu | wc -l
|
||||
.\" **************************
|
||||
.\" See also section
|
||||
.\" **************************
|
||||
.SH SEE ALSO
|
||||
.
|
||||
.ft R
|
||||
hwloc-bind(1)
|
||||
.sp
|
@ -1,415 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* Copyright © 2009 Cisco Systems, Inc. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HWLOC_HAVE_CAIRO
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#include "lstopo.h"
|
||||
|
||||
int logical = 1;
|
||||
hwloc_obj_type_t show_only = (hwloc_obj_type_t) -1;
|
||||
int show_cpuset = 0;
|
||||
unsigned int fontsize = 10;
|
||||
unsigned int gridsize = 10;
|
||||
unsigned int force_horiz = 0;
|
||||
unsigned int force_vert = 0;
|
||||
unsigned int top = 0;
|
||||
hwloc_pid_t pid = (hwloc_pid_t) -1;
|
||||
|
||||
FILE *open_file(const char *filename, const char *mode)
|
||||
{
|
||||
const char *extn = strrchr(filename, '.');
|
||||
|
||||
if (filename[0] == '-' && extn == filename + 1)
|
||||
return stdout;
|
||||
|
||||
return fopen(filename, mode);
|
||||
}
|
||||
|
||||
static void add_process_objects(hwloc_topology_t topology)
|
||||
{
|
||||
hwloc_obj_t root;
|
||||
hwloc_cpuset_t cpuset;
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
const struct hwloc_topology_support *support;
|
||||
|
||||
root = hwloc_get_root_obj(topology);
|
||||
|
||||
support = hwloc_topology_get_support(topology);
|
||||
|
||||
if (!support->cpubind->get_thisproc_cpubind)
|
||||
return;
|
||||
|
||||
dir = opendir("/proc");
|
||||
if (!dir)
|
||||
return;
|
||||
cpuset = hwloc_cpuset_alloc();
|
||||
|
||||
while ((dirent = readdir(dir))) {
|
||||
long local_pid;
|
||||
char *end;
|
||||
char name[64];
|
||||
|
||||
local_pid = strtol(dirent->d_name, &end, 10);
|
||||
if (*end)
|
||||
/* Not a number */
|
||||
continue;
|
||||
|
||||
snprintf(name, sizeof(name), "%ld", local_pid);
|
||||
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
{
|
||||
char path[6 + strlen(dirent->d_name) + 1 + 7 + 1];
|
||||
char cmd[64], *c;
|
||||
int file;
|
||||
ssize_t n;
|
||||
|
||||
snprintf(path, sizeof(path), "/proc/%s/cmdline", dirent->d_name);
|
||||
|
||||
if ((file = open(path, O_RDONLY)) >= 0) {
|
||||
n = read(file, cmd, sizeof(cmd) - 1);
|
||||
close(file);
|
||||
|
||||
if (n <= 0)
|
||||
/* Ignore kernel threads and errors */
|
||||
continue;
|
||||
|
||||
cmd[n] = 0;
|
||||
if ((c = strchr(cmd, ' ')))
|
||||
*c = 0;
|
||||
snprintf(name, sizeof(name), "%ld %s", local_pid, cmd);
|
||||
}
|
||||
}
|
||||
#endif /* HWLOC_LINUX_SYS */
|
||||
|
||||
if (hwloc_get_proc_cpubind(topology, local_pid, cpuset, 0))
|
||||
continue;
|
||||
|
||||
if (hwloc_cpuset_isincluded(root->cpuset, cpuset))
|
||||
continue;
|
||||
|
||||
hwloc_topology_insert_misc_object_by_cpuset(topology, cpuset, name);
|
||||
}
|
||||
|
||||
hwloc_cpuset_free(cpuset);
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
static void usage(char *name, FILE *where)
|
||||
{
|
||||
fprintf (where, "Usage: %s [ options ] ... [ filename ]\n\n", name);
|
||||
fprintf (where, "See lstopo(1) for more details.\n\n");
|
||||
fprintf (where, "Supported output file formats: .txt, .fig"
|
||||
#ifdef HWLOC_HAVE_CAIRO
|
||||
#if CAIRO_HAS_PDF_SURFACE
|
||||
", .pdf"
|
||||
#endif /* CAIRO_HAS_PDF_SURFACE */
|
||||
#if CAIRO_HAS_PS_SURFACE
|
||||
", .ps"
|
||||
#endif /* CAIRO_HAS_PS_SURFACE */
|
||||
#if CAIRO_HAS_PNG_FUNCTIONS
|
||||
", .png"
|
||||
#endif /* CAIRO_HAS_PNG_FUNCTIONS */
|
||||
#if CAIRO_HAS_SVG_SURFACE
|
||||
", .svg"
|
||||
#endif /* CAIRO_HAS_SVG_SURFACE */
|
||||
#endif /* HWLOC_HAVE_CAIRO */
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
", .xml"
|
||||
#endif /* HWLOC_HAVE_XML */
|
||||
"\n");
|
||||
fprintf (where, "\nOptions:\n");
|
||||
fprintf (where, " -l --logical Display hwloc logical object indexes (default)\n");
|
||||
fprintf (where, " -p --physical Display physical object indexes\n");
|
||||
fprintf (where, " -v --verbose Include additional detail\n");
|
||||
fprintf (where, " -s --silent Opposite of --verbose (default)\n");
|
||||
fprintf (where, " -c --cpuset Show the cpuset of each object\n");
|
||||
fprintf (where, " -C --cpuset-only Only show the cpuset of each ofbject\n");
|
||||
fprintf (where, " --only <type> Only show the given type in the text output\n");
|
||||
fprintf (where, " --ignore <type> Ignore objects of the given type\n");
|
||||
fprintf (where, " --no-caches Do not show caches\n");
|
||||
fprintf (where, " --no-useless-caches Do not show caches which do not have a hierarchical\n"
|
||||
" impact\n");
|
||||
fprintf (where, " --whole-system Do not consider administration limitations\n");
|
||||
fprintf (where, " --merge Do not show levels that do not have a hierarcical\n"
|
||||
" impact\n");
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
fprintf (where, " --xml <path> Read topology from XML file <path>\n");
|
||||
#endif
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
fprintf (where, " --fsys-root <path> Chroot containing the /proc and /sys of another system\n");
|
||||
#endif
|
||||
fprintf (where, " --pid <pid> Detect topology as seen by process <pid>\n");
|
||||
fprintf (where, " --top Display processes within the hierarchy\n");
|
||||
fprintf (where, " --synthetic \"n:2 2\" Simulate a fake hierarchy, here with 2 NUMA nodes of 2\n"
|
||||
" processors\n");
|
||||
fprintf (where, " --fontsize 10 Set size of text font\n");
|
||||
fprintf (where, " --gridsize 10 Set size of margin between elements\n");
|
||||
fprintf (where, " --horiz Horizontal graphic layout instead of nearly 4/3 ratio\n");
|
||||
fprintf (where, " --vert Vertical graphic layout instead of nearly 4/3 ratio\n");
|
||||
fprintf (where, " --version Report version and exit\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int err;
|
||||
int verbose_mode = 1;
|
||||
hwloc_topology_t topology;
|
||||
const char *filename = NULL;
|
||||
unsigned long flags = 0;
|
||||
int merge = 0;
|
||||
int ignorecache = 0;
|
||||
char * callname;
|
||||
char * synthetic = NULL;
|
||||
const char * xmlpath = NULL;
|
||||
char * fsysroot = NULL;
|
||||
int force_console = 0;
|
||||
int opt;
|
||||
|
||||
callname = strrchr(argv[0], '/');
|
||||
if (!callname)
|
||||
callname = argv[0];
|
||||
else
|
||||
callname++;
|
||||
|
||||
err = hwloc_topology_init (&topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
while (argc >= 2)
|
||||
{
|
||||
opt = 0;
|
||||
if (!strcmp (argv[1], "-v") || !strcmp (argv[1], "--verbose")) {
|
||||
verbose_mode++;
|
||||
force_console = 1;
|
||||
} else if (!strcmp (argv[1], "-s") || !strcmp (argv[1], "--silent")) {
|
||||
verbose_mode--;
|
||||
force_console = 1;
|
||||
} else if (!strcmp (argv[1], "-h") || !strcmp (argv[1], "--help")) {
|
||||
usage(callname, stdout);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else if (!strcmp (argv[1], "-l") || !strcmp (argv[1], "--logical"))
|
||||
logical = 1;
|
||||
else if (!strcmp (argv[1], "-p") || !strcmp (argv[1], "--physical"))
|
||||
logical = 0;
|
||||
else if (!strcmp (argv[1], "-c") || !strcmp (argv[1], "--cpuset"))
|
||||
show_cpuset = 1;
|
||||
else if (!strcmp (argv[1], "-C") || !strcmp (argv[1], "--cpuset-only"))
|
||||
show_cpuset = 2;
|
||||
else if (!strcmp (argv[1], "--only")) {
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
show_only = hwloc_obj_type_of_string(argv[2]);
|
||||
opt = 1;
|
||||
}
|
||||
else if (!strcmp (argv[1], "--ignore")) {
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
hwloc_topology_ignore_type(topology, hwloc_obj_type_of_string(argv[2]));
|
||||
opt = 1;
|
||||
}
|
||||
else if (!strcmp (argv[1], "--no-caches"))
|
||||
ignorecache = 2;
|
||||
else if (!strcmp (argv[1], "--no-useless-caches"))
|
||||
ignorecache = 1;
|
||||
else if (!strcmp (argv[1], "--whole-system"))
|
||||
flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM;
|
||||
else if (!strcmp (argv[1], "--merge"))
|
||||
merge = 1;
|
||||
else if (!strcmp (argv[1], "--horiz"))
|
||||
force_horiz = 1;
|
||||
else if (!strcmp (argv[1], "--vert"))
|
||||
force_vert = 1;
|
||||
else if (!strcmp (argv[1], "--fontsize")) {
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fontsize = atoi(argv[2]);
|
||||
opt = 1;
|
||||
}
|
||||
else if (!strcmp (argv[1], "--gridsize")) {
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
gridsize = atoi(argv[2]);
|
||||
opt = 1;
|
||||
}
|
||||
else if (!strcmp (argv[1], "--synthetic")) {
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
synthetic = argv[2]; opt = 1;
|
||||
} else if (!strcmp (argv[1], "--xml")) {
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
xmlpath = argv[2]; opt = 1;
|
||||
if (!strcmp(xmlpath, "-")) {
|
||||
xmlpath = "/dev/stdin";
|
||||
}
|
||||
#else /* HWLOC_HAVE_XML */
|
||||
fprintf(stderr, "This installation of hwloc does not support --xml, sorry.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
#endif /* HWLOC_HAVE_XML */
|
||||
} else if (!strcmp (argv[1], "--fsys-root")) {
|
||||
#ifdef HWLOC_LINUX_SYS
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fsysroot = argv[2]; opt = 1;
|
||||
#else /* HWLOC_LINUX_SYS */
|
||||
fprintf(stderr, "This installation of hwloc does not support --fsys-root, sorry.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
#endif /* HWLOC_LINUX_SYS */
|
||||
} else if (!strcmp (argv[1], "--pid")) {
|
||||
if (argc <= 2) {
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pid = atoi(argv[2]); opt = 1;
|
||||
} else if (!strcmp (argv[1], "--top"))
|
||||
top = 1;
|
||||
else if (!strcmp (argv[1], "--version")) {
|
||||
printf("%s %s\n", callname, VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
if (filename) {
|
||||
fprintf (stderr, "Unrecognized options: %s\n", argv[1]);
|
||||
usage (callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
} else
|
||||
filename = argv[1];
|
||||
}
|
||||
argc -= opt+1;
|
||||
argv += opt+1;
|
||||
}
|
||||
|
||||
if (show_only != (hwloc_obj_type_t)-1) {
|
||||
merge = 0;
|
||||
force_console = 1;
|
||||
}
|
||||
if (show_cpuset)
|
||||
force_console = 1;
|
||||
|
||||
hwloc_topology_set_flags(topology, flags);
|
||||
|
||||
if (ignorecache > 1) {
|
||||
hwloc_topology_ignore_type(topology, HWLOC_OBJ_CACHE);
|
||||
} else if (ignorecache) {
|
||||
hwloc_topology_ignore_type_keep_structure(topology, HWLOC_OBJ_CACHE);
|
||||
}
|
||||
if (merge)
|
||||
hwloc_topology_ignore_all_keep_structure(topology);
|
||||
|
||||
if (synthetic)
|
||||
if (hwloc_topology_set_synthetic(topology, synthetic))
|
||||
return EXIT_FAILURE;
|
||||
if (xmlpath) {
|
||||
if (hwloc_topology_set_xml(topology, xmlpath)) {
|
||||
perror("Setting target XML file");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (fsysroot) {
|
||||
if (hwloc_topology_set_fsroot(topology, fsysroot)) {
|
||||
perror("Setting target filesystem root");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (pid != (hwloc_pid_t) -1 && pid != 0) {
|
||||
if (hwloc_topology_set_pid(topology, pid)) {
|
||||
perror("Setting target pid");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
err = hwloc_topology_load (topology);
|
||||
if (err)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (top)
|
||||
add_process_objects(topology);
|
||||
|
||||
if (!filename && !strcmp(callname,"hwloc-info")) {
|
||||
/* behave kind-of plpa-info */
|
||||
filename = "-";
|
||||
verbose_mode--;
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
#ifdef HWLOC_HAVE_CAIRO
|
||||
#if CAIRO_HAS_XLIB_SURFACE && defined HWLOC_HAVE_X11
|
||||
if (!force_console && getenv("DISPLAY"))
|
||||
output_x11(topology, NULL, logical, verbose_mode);
|
||||
else
|
||||
#endif /* CAIRO_HAS_XLIB_SURFACE */
|
||||
#endif /* HWLOC_HAVE_CAIRO */
|
||||
#ifdef HWLOC_WIN_SYS
|
||||
output_windows(topology, NULL, logical, verbose_mode);
|
||||
#else
|
||||
output_console(topology, NULL, logical, verbose_mode);
|
||||
#endif
|
||||
} else if (!strcmp(filename, "-")
|
||||
|| !strcmp(filename, "/dev/stdout"))
|
||||
output_console(topology, filename, logical, verbose_mode);
|
||||
else if (strstr(filename, ".txt"))
|
||||
output_text(topology, filename, logical, verbose_mode);
|
||||
else if (strstr(filename, ".fig"))
|
||||
output_fig(topology, filename, logical, verbose_mode);
|
||||
#ifdef HWLOC_HAVE_CAIRO
|
||||
#if CAIRO_HAS_PNG_FUNCTIONS
|
||||
else if (strstr(filename, ".png"))
|
||||
output_png(topology, filename, logical, verbose_mode);
|
||||
#endif /* CAIRO_HAS_PNG_FUNCTIONS */
|
||||
#if CAIRO_HAS_PDF_SURFACE
|
||||
else if (strstr(filename, ".pdf"))
|
||||
output_pdf(topology, filename, logical, verbose_mode);
|
||||
#endif /* CAIRO_HAS_PDF_SURFACE */
|
||||
#if CAIRO_HAS_PS_SURFACE
|
||||
else if (strstr(filename, ".ps"))
|
||||
output_ps(topology, filename, logical, verbose_mode);
|
||||
#endif /* CAIRO_HAS_PS_SURFACE */
|
||||
#if CAIRO_HAS_SVG_SURFACE
|
||||
else if (strstr(filename, ".svg"))
|
||||
output_svg(topology, filename, logical, verbose_mode);
|
||||
#endif /* CAIRO_HAS_SVG_SURFACE */
|
||||
#endif /* HWLOC_HAVE_CAIRO */
|
||||
#ifdef HWLOC_HAVE_XML
|
||||
else if (strstr(filename, ".xml"))
|
||||
output_xml(topology, filename, logical, verbose_mode);
|
||||
#endif
|
||||
else {
|
||||
fprintf(stderr, "file format not supported\n");
|
||||
usage(callname, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hwloc_topology_destroy (topology);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_LSTOPO_H
|
||||
#define UTILS_LSTOPO_H
|
||||
|
||||
#include <private/config.h>
|
||||
#include <hwloc.h>
|
||||
|
||||
extern hwloc_obj_type_t show_only;
|
||||
extern int show_cpuset;
|
||||
extern hwloc_pid_t pid;
|
||||
|
||||
typedef void output_method (struct hwloc_topology *topology, const char *output, int logical, int verbose_mode);
|
||||
|
||||
FILE *open_file(const char *filename, const char *mode) __hwloc_attribute_malloc;
|
||||
|
||||
extern output_method output_console, output_text, output_x11, output_fig, output_png, output_pdf, output_ps, output_svg, output_windows, output_xml;
|
||||
|
||||
struct draw_methods {
|
||||
void* (*start) (void *output, int width, int height);
|
||||
void (*declare_color) (void *output, int r, int g, int b);
|
||||
void (*box) (void *output, int r, int g, int b, unsigned depth, unsigned x, unsigned width, unsigned y, unsigned height);
|
||||
void (*line) (void *output, int r, int g, int b, unsigned depth, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
|
||||
void (*text) (void *output, int r, int g, int b, int size, unsigned depth, unsigned x, unsigned y, const char *text);
|
||||
};
|
||||
|
||||
extern unsigned int gridsize, fontsize, force_horiz, force_vert;
|
||||
|
||||
extern void *output_draw_start(struct draw_methods *draw_methods, int logical, struct hwloc_topology *topology, void *output);
|
||||
extern void output_draw(struct draw_methods *draw_methods, int logical, struct hwloc_topology *topology, void *output);
|
||||
|
||||
int rgb_to_color(int r, int g, int b) __hwloc_attribute_const;
|
||||
int declare_color(int r, int g, int b);
|
||||
|
||||
#endif /* UTILS_LSTOPO_H */
|
@ -1,52 +0,0 @@
|
||||
0x0000000f
|
||||
0x000000f0
|
||||
|
||||
0x00000003
|
||||
0x0000000c
|
||||
0x00000030
|
||||
0x000000c0
|
||||
|
||||
0x00000001
|
||||
0x00000002
|
||||
0x00000004
|
||||
0x00000008
|
||||
0x00000010
|
||||
0x00000020
|
||||
0x00000040
|
||||
0x00000080
|
||||
|
||||
0x00000001
|
||||
0x00000001
|
||||
0x00000002
|
||||
0x00000002
|
||||
0x00000004
|
||||
0x00000004
|
||||
0x00000008
|
||||
0x00000010
|
||||
0x00000010
|
||||
0x00000020
|
||||
0x00000040
|
||||
0x00000040
|
||||
0x00000080
|
||||
|
||||
0x00000001
|
||||
0x00000001
|
||||
0x00000002
|
||||
0x00000002
|
||||
0x00000004
|
||||
0x00000004
|
||||
0x00000008
|
||||
0x00000008
|
||||
0x00000010
|
||||
0x00000010
|
||||
0x00000020
|
||||
0x00000020
|
||||
0x00000040
|
||||
0x00000040
|
||||
0x00000080
|
||||
0x00000080
|
||||
|
||||
0x00000007
|
||||
0x00000038
|
||||
0x0003fe00
|
||||
0x07fc0000
|
@ -1,36 +0,0 @@
|
||||
#!/bin/sh
|
||||
#-*-sh-*-
|
||||
|
||||
#
|
||||
# Copyright © 2009 CNRS, INRIA, Université Bordeaux 1
|
||||
# See COPYING in top-level directory.
|
||||
#
|
||||
|
||||
: ${TMPDIR=/tmp}
|
||||
{
|
||||
tmp=`
|
||||
(umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null
|
||||
` &&
|
||||
test -n "$tmp" && test -d "$tmp"
|
||||
} || {
|
||||
tmp=$TMPDIR/foo$$-$RANDOM
|
||||
(umask 077 && mkdir "$tmp")
|
||||
} || exit $?
|
||||
file="$tmp/test-hwloc-distrib.output"
|
||||
|
||||
set -e
|
||||
(
|
||||
./hwloc-distrib --synthetic "2 2 2" 2
|
||||
echo
|
||||
./hwloc-distrib --synthetic "2 2 2" 4
|
||||
echo
|
||||
./hwloc-distrib --synthetic "2 2 2" 8
|
||||
echo
|
||||
./hwloc-distrib --synthetic "2 2 2" 13
|
||||
echo
|
||||
./hwloc-distrib --synthetic "2 2 2" 16
|
||||
echo
|
||||
./hwloc-distrib --synthetic "3 3 3" 4
|
||||
) > "$file"
|
||||
diff @HWLOC_DIFF_U@ $srcdir/test-hwloc-distrib.output "$file"
|
||||
rm -rf "$tmp"
|
Загрузка…
Ссылка в новой задаче
Block a user