diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000000..ca15f6f842 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,19 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +# All rights reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +include $(top_srcdir)/config/Makefile.options + +SUBDIRS = user install diff --git a/doc/user/Makefile.am b/doc/user/Makefile.am new file mode 100644 index 0000000000..c0bd360d7d --- /dev/null +++ b/doc/user/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +# All rights reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +include $(top_srcdir)/config/Makefile.options + +# The majority of stuff to build the PS/PDF files are included in a +# separate Makefile so that they can be invoked directly at "make +# dist" time without needing to generate a real "Makefile" from +# Makefile.am. + +include Makefile.latex + +# Now ensure that all the relevant files get picked up in the tarball. + +EXTRA_DIST = $(MAIN_TEX) $(OTHER_SRC_FILES) $(FIG_FILES) $(PNG_FILES) $(BIBTEX_SOURCES) Makefile.latex + +dist-hook: pdf + mv user.pdf $(DESTDIR)$(distdir)/../. diff --git a/doc/user/Makefile.latex b/doc/user/Makefile.latex new file mode 100644 index 0000000000..e298e82a4f --- /dev/null +++ b/doc/user/Makefile.latex @@ -0,0 +1,226 @@ +# -*-Makefile-*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University. +# All rights reserved. +# Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +# All rights reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ + +# +# This first section contains macros whose values that you need to +# fill in. +# + +# MAIN_TEX: In order to build your document, fill in the MAIN_TEX +# macro with the name of your main .tex file -- the one that you +# invoke LaTeX on. + +MAIN_TEX = user.tex + +# OTHER_SRC_FILES: Put in the names of all the other files that your +# thesis depends on (e.g., other .tex files, figures, etc.) in the +# OTHER_SRC_FILES macro. This is ensure that whenever one of the +# "other" files changes, "make" will rebuild your paper. + +LISTINGS_FILES = \ + listings.cfg \ + listings.sty \ + lstdoc.sty \ + lstlang1.sty \ + lstlang2.sty \ + lstlang3.sty \ + lstmisc.sty \ + lstpatch.sty + +OTHER_SRC_FILES = \ + defs.tex \ + version.tex \ + titlepage.tex \ + audience.tex \ + introduction.tex \ + release-notes.tex \ + getting-started.tex \ + mpi-details.tex \ + mca.tex \ + commands.tex \ + mca-orte.tex \ + mca-ompi.tex \ + debuggers.tex \ + troubleshooting.tex \ + misc.tex \ + bibliography.tex \ + $(LISTINGS_FILES) + +# Bibtex source files + +BIBTEX_SOURCES = refs.bib + +# xfig figures. .eps and .pdf files will be automatically generated +# from these. + +FIG_FILES = +PNG_FILES = openmpi_logo-only.png + +# Required commands + +LATEX = latex +PDFLATEX = pdflatex +DVIPS = dvips +MAKEINDEX = makeindex +BIBTEX = bibtex +FIG2DEV = fig2dev +PNGTOPNM = pngtopnm +PNMTOPS = pnmtops + +######################################################################### +# +# You should not need to edit below this line +# +######################################################################### + +SUFFIXES = .tex .dvi .ps .pdf .fig .eps .png +.SUFFIXES: .tex .dvi .ps .pdf .fig .eps .png + +MAIN_DVI = $(MAIN_TEX:.tex=.dvi) +MAIN_PS = $(MAIN_TEX:.tex=.ps) +MAIN_PDF = $(MAIN_TEX:.tex=.pdf) +MAIN_BBL = $(MAIN_TEX:.tex=.bbl) +MAIN_BASENAME = $(MAIN_TEX:.tex=) +EPS_FILES = $(PNG_FILES:.png=.eps) +EPS_FIG_FILES = $(FIG_FILES:.fig=.eps) +PDF_FIG_FILES = $(FIG_FILES:.fig=.pdf) + +# +# Some common target names +# Note that the default target is "ps" +# + +ps: $(MAIN_PS) +pdf: $(MAIN_PDF) + +# +# Make the dependencies so that things build when they need to +# + +$(MAIN_PS): $(MAIN_DVI) +$(MAIN_DVI): $(MAIN_TEX) $(CITE_TEX) $(OTHER_SRC_FILES) $(EPS_FIG_FILES) $(EPS_FILES) $(MAIN_BBL) +$(MAIN_PDF): $(MAIN_TEX) $(CITE_TEX) $(OTHER_SRC_FILES) $(PDF_FIG_FILES) $(PNG_FILES) $(MAIN_BBL) + +# +# Search Strings +# + +REFERENCES = "(There were undefined references|Rerun to get (cross-references|the bars) right)" +NEEDINDEX = "Writing index file" +RERUNBIB = "No file.*\.bbl|Citation.*undefined|LaTeX Warning: Label\(s\) may" + +# +# General rules +# + +.fig.eps: + $(FIG2DEV) -L eps $< $@ + +.fig.pdf: + $(FIG2DEV) -L pdf $< $@ + +.png.eps: + $(PNGTOPNM) $< | $(PNMTOPS) -noturn > $*.eps + +# Only run bibtex if latex has already been run (i.e., if there is +# already a .aux file). If .aux file does not exist, then bibtex will +# be run during the .tex.dvi / .tex.pdf rules. We don't run latex +# here to generate the .aux file because a) we don't know whether to +# run latex or pdflatex, and b) the dependencies are wrong for +# pdflatex because we may need to generate some pdf images first. + +$(MAIN_BBL): $(BIBTEX_SOURCES) + @if (test -f $(MAIN_BASENAME).aux); then \ + echo "### Running BibTex"; \ + $(BIBTEX) $(MAIN_BASENAME); \ + fi + +# Main workhorse for .tex -> .dvi. Run latex, makeindex, and bibtex +# as necessary. + +.tex.dvi: + echo "### Running LaTeX (1)" + $(LATEX) $* + @if (egrep $(REFERENCES) $*.log > /dev/null); then \ + echo "### Running LaTeX to fix references (2)"; \ + ($(LATEX) $*); \ + fi + @if (egrep $(NEEDINDEX) $*.log >/dev/null); then \ + echo "### Running makeindex to generate index"; \ + $(MAKEINDEX) $*; \ + echo "### Running LaTeX after generating index"; \ + $(LATEX) $*; \ + fi + @if (egrep $(RERUNBIB) $*.log >/dev/null); then \ + echo "### Running BibTex because references changed"; \ + $(BIBTEX) $(MAIN_BASENAME); \ + echo "### Running LaTeX after generating bibtex"; \ + $(LATEX) $*; \ + fi + @if (egrep $(REFERENCES) $*.log > /dev/null); then \ + echo "### Running LaTeX to fix references (3)"; \ + ($(LATEX) $*); \ + fi + @if (egrep $(REFERENCES) $*.log > /dev/null); then \ + echo "### Running LaTeX to fix references (4)"; \ + ($(LATEX) $*); \ + fi + +.dvi.ps: + $(DVIPS) -o $*.ps $* + +# Main workhorse for .tex -> .pdf. Run latex, makeindex, and bibtex +# as necessary. Essentially the same as .tex.dvi, except +# s/latex/pdflatex/g. + +.tex.pdf: + echo "### Running pdfLaTeX (1)" + $(PDFLATEX) $* + @if (egrep $(REFERENCES) $*.log > /dev/null); then \ + echo "### Running pdfLaTeX to fix references (2)"; \ + ($(PDFLATEX) $*); \ + fi + @if (egrep $(NEEDINDEX) $*.log >/dev/null); then \ + echo "### Running makeindex to generate index"; \ + $(MAKEINDEX) $*; \ + echo "### Running pdfLaTeX after generating index"; \ + $(PDFLATEX) $*; \ + fi + @if (egrep $(RERUNBIB) $*.log >/dev/null); then \ + echo "### Running BibTex because references changed"; \ + $(BIBTEX) $(MAIN_BASENAME); \ + echo "### Running pdfLaTeX after generating bibtex"; \ + $(PDFLATEX) $*; \ + fi + @if (egrep $(REFERENCES) $*.log > /dev/null); then \ + echo "### Running pdfLaTeX to fix references (3)"; \ + ($(PDFLATEX) $*); \ + fi + @if (egrep $(REFERENCES) $*.log > /dev/null); then \ + echo "### Running pdfLaTeX to fix references (4)"; \ + ($(PDFLATEX) $*); \ + fi + +# +# Standard targets +# + +clean: + /bin/rm -f *~ *.bak *% + /bin/rm -f *.log *.aux *.dvi *.blg *.toc *.bbl *.lof *.lot \ + *.ind *.idx *.ilg *.int *.out \ + $(MAIN_PS) $(MAIN_DVI) $(MAIN_PDF) \ + $(EPS_FILES) $(EPS_FIG_FILES) $(PDF_FIG_FILES) diff --git a/doc/user/audience.tex b/doc/user/audience.tex new file mode 100644 index 0000000000..7f00bc4bad --- /dev/null +++ b/doc/user/audience.tex @@ -0,0 +1,87 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Don't Panic! (Who Should Read This Document?)} + +{\Huge JMS needs overhauling -- no such thing as a previous OMPI user} + +This document probably looks huge to new users. But don't panic! It +is divided up into multiple, relatively independent sections that can +be read and digested separately. Although this manual covers a lot of +relevant material for all users, the following guidelines are +suggested for various types of users. If you are: + +\begin{itemize} +\item {\bf New to MPI}: First, read Chapter~\ref{sec:introduction} for + an introduction to MPI and Open MPI. A good reference on MPI + programming is also strongly recommended; there are several books + available as well as excellent on-line tutorials + (e.g.,~\cite{gropp98:_mpi2,gropp94:_using_mpi,gropp99:_using_mpi_2,snir96:_mpi_the_compl_refer}). + + When you're comfortable with the concepts of MPI, move on to {\bf + New to Open MPI}. + + \vspace{-3pt} + +\item {\bf New to Open MPI}: If you're familiar with MPI but unfamiliar + with Open MPI, first read Chapter~\ref{sec:getting-started} for a + mini-tutorial on getting started with Open MPI. You'll probably be + familiar with many of the concepts described, and simply learn the + Open MPI terminology and commands. Glance over and use as a reference + Chapter~\ref{sec:commands} for the rest of the Open MPI commands. + Chapter~\ref{sec:troubleshooting} contains some quick tips on common + problems with Open MPI. + + Assuming that you've already got MPI codes that you want to run + under LAM/MPI, read Chapter~\ref{sec:mpi-functionality} to see + exactly what MPI-2 features LAM/MPI supports. + + When you're comfortable with all this, move on to {\bf Previous Open + MPI user}. + + \vspace{-3pt} + +\item {\bf Previous Open MPI user}: As a previous Open MPI user, + you're probably already fairly familiar with all the Open MPI + commands -- their basic functionality hasn't changed much. However, + many of them have grown new options and capabilities, particularly + in the area of run-time tunable parameters. So be sure to read + Chapters~\ref{sec:ssi} to learn about Open MPI's Modular Component + Architecture (MCA), Chapters~\ref{sec:mca-orte} + and~\ref{sec:mca-ompi} (run-time environment and MPI MCA modules), + and finally Chapter~\ref{sec:misc} (miscellaneous Open MPI + information, features, etc.). + + If you're curious to see a brief listing of new features in this + release, see the release notes in Chapter~\ref{sec:release-notes}. + This isn't really necessary, but when you're kicking the tires of + this version, it's a good way to ensure that you are aware of all + the new features. + + Finally, even for the seasoned MPI and Open MPI veteran, be sure to + check out Chapter~\ref{sec:debug} for information about debugging + MPI programs in parallel. + + \vspace{-3pt} + +\item {\bf System administrator}: Unless you're also a parallel + programmer, you're reading the wrong document. You should be + reading the Open MPI Installation + Guide~\cite{open_mpi_install_guide} for detailed + information on how to configure, compile, and install Open MPI. +\end{itemize} + diff --git a/doc/user/bibliography.tex b/doc/user/bibliography.tex new file mode 100644 index 0000000000..48455a17f7 --- /dev/null +++ b/doc/user/bibliography.tex @@ -0,0 +1,20 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\bibliography{refs} +\bibliographystyle{plain} + diff --git a/doc/user/commands.tex b/doc/user/commands.tex new file mode 100644 index 0000000000..617568a24f --- /dev/null +++ b/doc/user/commands.tex @@ -0,0 +1,1281 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Open MPI Command Quick Reference} +\label{sec:commands} + +This section is intended to provide a quick reference of the major +Open MPI commands. Each command also has its own manual page which +typically provides more detail than this document. + +{\Huge JMS needs total overhaul} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamboot} Command} +\label{sec:commands-lamboot} + +The \cmd{lamboot} command is used to start the Open MPI run-time +environment (RTE). \cmd{lamboot} is typically the first command used +before any other Open MPI command (notable exceptions are the wrapper +compilers, which do not require the Open MPI RTE, and \cmd{mpiexec} which +can launch its own Open MPI universe). \cmd{lamboot} can use any of the +available \kind{boot} SSI modules; Section~\ref{sec:lam-ssi-boot} +details the requirements and operations of each of the \kind{boot} SSI +modules that are included in the Open MPI distribution. + +Common arguments that are used with the \cmd{lamboot} command are: + +\begin{itemize} +\item \cmdarg{-b}: When used with the \boot{rsh} boot module, the + ``fast'' boot algorithm is used which can noticeably speed up the + execution time of \cmd{lamboot}. It can also be used where remote + shell agents cannot provide output from remote nodes (e.g., in a + Condor environment). Specifically, the ``fast'' algorithm assumes + that the user's shell on the remote node is the same as the shell on + the node where \cmd{lamboot} was invoked. + +\item \cmdarg{-d}: Print debugging output. This will print a {\em + lot} of output, and is typically only necessary if \cmd{lamboot} + fails for an unknown reason. The output is forwarded to standard + out as well as either \file{/tmp} or syslog facilities. The amount of + data produced can fill these filesystems, leading to general system + problems. + +\item \cmdarg{-l}: Use local hostname resolution instead of + centralized lookups. This is useful in environments where the same + hostname may resolve to different IP addresses on different nodes + (e.g., clusters based on Finite Neighborhood Networks\footnote{See + \url{http://www.aggregate.org/} for more details.}). + +\changebegin{7.1} + +\item \cmdarg{-prefix $<$lam/install/path$>$}: Use the Open MPI + installation specified in the $<$lam/install/path$>$ - where + $<$lam/install/path$>$ is the top level directory where Open MPI is + installed. This is typically used when a user has multiple Open MPI + installations and want to switch between them without changing the + dot files or PATH environment variable. + + This option is not compatible with Open MPI versions prior to 7.1. + +\changeend{7.1} + +\item \cmdarg{-s}: Close the \file{stdout} and \file{stderr} of the + locally-launched Open MPI daemon (they are normally left open). This is + necessary when invoking \cmd{lamboot} via a remote agent such as + \cmd{rsh} or \cmd{ssh}. + +\item \cmdarg{-v}: Print verbose output. This is useful to show + progress during \cmd{lamboot}'s progress. Unlike \cmdarg{-d}, + \cmdarg{-v} does not forward output to a file or syslog. + +\item \cmdarg{-x}: Run the Open MPI RTE in fault-tolerant mode. + +\item \cmdarg{$<$filename$>$}: The name of the boot schema file. Boot + schemas, while they can be as simple as a list of hostnames, can + contain additional information and are discussed in detail + in Sections~\ref{sec:getting-started-hostfile} and + ~\ref{sec:lam-ssi-boot-schema}, + pages~\pageref{sec:getting-started-hostfile} + and~\pageref{sec:lam-ssi-boot-schema}, respectively. +\end{itemize} + +Booting the Open MPI RTE is where most users (particularly first-time +users) encounter problems. Each \kind{boot} module has its own +specific requirements and prerequisites for success. Although +\cmd{lamboot} typically prints detailed messages when errors occur, +users are strongly encouraged to read Section~\ref{sec:lam-ssi-boot} +for the details of the \kind{boot} module that they will be using. +Additionally, the \cmdarg{-d} switch should be used to examine exactly +what is happening to determine the actual source of the problem -- +many problems with \cmd{lamboot} come from the operating system or the +user's shell setup; not from within Open MPI itself. + +The most common \cmd{lamboot} example simply uses a hostfile to launch +across an \cmd{rsh}/\cmd{ssh}-based cluster of nodes (the +``\cmdarg{-ssi boot rsh}'' is not technically necessary here, but it +is specified to make this example correct in all environments): + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot -v -ssi boot rsh hostfile + +Open MPI 7.0/MPI 2 C++/ROMIO - Indiana University + +n0<1234> ssi:boot:base:linear: booting n0 (node1.cluster.example.com) +n0<1234> ssi:boot:base:linear: booting n1 (node2.cluster.example.com) +n0<1234> ssi:boot:base:linear: booting n2 (node3.cluster.example.com) +n0<1234> ssi:boot:base:linear: booting n3 (node4.cluster.example.com) +n0<1234> ssi:boot:base:linear: finished +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Multiple Sessions on the Same Node} + +In some cases (such as in batch-regulated environments), it is +desirable to allow multiple universes owned by the same on the same +node. The \ienvvar{TMPDIR}, +\ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-PREFIX}, and +\ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-SUFFIX} environment variables can be +used to effect this behavior. The main issue is the location of Open MPI's +session directory; each node in a Open MPI universe has a session directory +in a well-known location in the filesystem that identifies how to +contact the Open MPI daemon on that node. Multiple Open MPI universes can +simultaneously co-exist on the same node as long as they have +different session directories. + +Open MPI recognizes several batch environments and automatically adapts the +session directory to be specific to a batch job. Hence, if the batch +scheduler allocates multiple jobs from the same user to the same node, +Open MPI will automatically do the ``right thing'' and ensure that the Open MPI +universes from each job will not collide. +% +Sections~\ref{sec:misc-batch} and~\ref{sec:misc-session-directory} +(starting on page~\pageref{sec:misc-batch}) discuss these issues in +detail. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Avoiding Running on Specific Nodes} +\label{sec:commands-lamboot-no-schedule} +\index{no-schedule boot schema attribute@\cmd{no-schedule} boot + schema attribute} + +Once the Open MPI universe is booted, processes can be launched on any +node. The \cmd{mpirun}, \cmd{mpiexec}, and \cmd{lamexec} commands are +most commonly used to launch jobs in the universe, and are typically +used with the \cmdarg{N} and \cmdarg{C} nomenclatures (see the description of +\cmd{mpirun} in Section~\ref{sec:commands-mpirun} for details on the +\cmdarg{N} and \cmdarg{C} nomenclature) which launch jobs on all schedulable +nodes and CPUs in the Open MPI universe, respectively. While finer-grained +controls are available through \cmd{mpirun} (etc.), it can be +convenient to simply mark some nodes as ``non-schedulable,'' and +therefore avoid having \cmd{mpirun} (etc.) launch executables on those +nodes when using \cmdarg{N} and \cmdarg{C} nomenclature. + +For example, it may be convenient to boot a Open MPI universe that includes +a controller node (e.g., a desktop workstation) and a set of worker +nodes. In this case, it is desirable to mark the desktop workstation +as ``non-scheduable'' so that Open MPI will not launch executables there +(by default). Consider the following boot schema: + +\lstset{style=lam-shell} +\begin{lstlisting} +# Mark my_workstation as ``non-schedulable'' +my_workstation.office.example.com schedule=no +# All the other nodes are, by default, schedulable +node1.cluster.example.com +node2.cluster.example.com +node3.cluster.example.com +node4.cluster.example.com +\end{lstlisting} + +Booting with this schema allows the convenienve of: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +\noindent which will only run \cmd{my\_\-mpi\_\-program} on the four +cluster nodes (i.e., not the workstation). +% +Note that this behavior {\em only} applies to the \cmdarg{C} and \cmdarg{N} +designations; Open MPI will always allow execution on any node when using +the \cmdarg{nX} or \cmdarg{cX} notation: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun c0 C my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +\noindent which will run \cmd{my\_\-mpi\_\-program} on all five nodes +in the Open MPI universe. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamcheckpoint} Command} +\label{sec:commands-lamcheckpoint} + +\changebegin{7.1} + +The \cmd{lamcheckpoint} command is provided to checkpoint a MPI +application. One of the arguments to \cmd{lamcheckpoint} is the name +of the checkpoint/restart module (which can be either one of +\crssi{blcr} and \crssi{self}). Additional arguments to +\cmd{lamcheckpoint} depend of the selected checkpoint/restart module. +The name of the module can be specified by passing the \crssi{cr} SSI +parameter. + +Common arguments that are used with the \cmd{lamcheckpoint} command +are: + +\begin{itemize} +\item \cmdarg{-ssi}: Just like with \cmd{mpirun}, the \cmdarg{-ssi} + flag can be used to pass key=value pairs to Open MPI. Indeed, it is + required to pass at least one SSI parameter: \ssiparam{cr}, + indicating which \kind{cr} module to use for checkpointing. + +\item \cmdarg{-pid}: Indicate the PID of \cmd{mpirun} to checkpoint. +\end{itemize} + +\noindent Notes: + +\begin{itemize} +\item If the \crssi{blcr} \kind{cr} module is selected, the name of + the directory for storing the checkpoint files and the PID of + \cmd{mpirun} should be passed as SSI parameters to + \cmd{lamcheckpoint}. + +\item If the \crssi{self} \kind{cr} module is selected, the PID of + \cmd{mpirun} should be passed via the \cmdarg{-pid} parameter. +\end{itemize} + +\changeend{7.1} + +See Section~\ref{sec:mpi-ssi-cr} for more detail about the +checkpoint/restart capabilities of Open MPI, including details about +the \crssi{blcr} and \crssi{self} \kind{cr} modules. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamclean} Command} +\label{sec:commands-lamclean} + +The \cmd{lamclean} command is provided to clean up the Open MPI universe. +It is typically only necessary when MPI processes terminate ``badly,'' +and potentially leave resources allocated in the Open MPI universe (such as +MPI-2 published names, processes, or shared memory). The +\cmd{lamclean} command will kill {\em all} processes running in the +Open MPI universe, and free {\em all} resources that were associated with +them (including unpublishing MPI-2 dynamicly published names). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamexec} Command} +\label{sec:commands-lamexec} + +The \cmd{lamexec} command is similar to \cmd{mpirun} but is used for +non-MPI programs. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamexec N uptime + 5:37pm up 21 days, 23:49, 5 users, load average: 0.31, 0.26, 0.25 + 5:37pm up 21 days, 23:49, 2 users, load average: 0.01, 0.00, 0.00 + 5:37pm up 21 days, 23:50, 3 users, load average: 0.01, 0.00, 0.00 + 5:37pm up 21 days, 23:50, 2 users, load average: 0.87, 0.81, 0.80 +\end{lstlisting} +% Stupid emacs: $ + +Most of the parameters and options that are available to \cmd{mpirun} +are also available to \cmd{lamexec}. See the \cmd{mpirun} description +in Section~\ref{sec:commands-mpirun} for more details. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamgrow} Command} +\label{sec:commands-lamgrow} + +The \cmd{lamgrow} command adds a single node to the Open MPI universe. It +must use the same \kind{boot} module that was used to initially boot +the Open MPI universe. \cmd{lamgrow} must be run from a node already in +the Open MPI universe. Common parameters include: + +\begin{itemize} +\item \cmdarg{-v}: Verbose mode. + +\item \cmdarg{-d}: Debug mode; enables a {\em lot} of diagnostic + output. + +\item \cmdarg{-n $<$nodeid$>$}: Assign the new host the node ID + \cmdarg{nodeid}. \cmdarg{nodeid} must be an unused node ID. If + \cmdarg{-n} is not specified, Open MPI will find the lowest node ID that + is not being used. + +\item \cmdarg{-no-schedule}: Has the same effect as putting ``{\tt + no\_\-schedule=yes}'' in the boot schema. This means that the + \cmdarg{C} and \cmdarg{N} expansion used in \cmd{mpirun} and \cmd{lamexec} + will not include this node. + +\item \cmdarg{-ssi $<$key$>$ $<$value$>$}: Pass in SSI parameter + \cmdarg{key} with the value \cmdarg{value}. + +\item \cmdarg{$<$hostname$>$}: The name of the host to expand the + universe to. +\end{itemize} + +For example, the following adds the node \host{blinky} to the existing +Open MPI universe using the \boot{rsh} boot module: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamgrow -ssi boot rsh blinky.cluster.example.com +\end{lstlisting} +% Stupid emacs: $ + +Note that \cmd{lamgrow} cannot grow a Open MPI universe that only contains +one node that has an IP address of 127.0.0.1 (e.g., if \cmd{lamboot} +was run with the default boot schema that only contains the name +\host{localhost}). In this case, \cmd{lamgrow} will print an error +and abort without adding the new node. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamhalt} Command} +\label{sec:commands-lamhalt} + +The \cmd{lamhalt} command is used to shut down the Open MPI RTE. +Typically, \cmd{lamhalt} can simply be run with no command line +parameters and it will shut down the Open MPI RTE. Optionally, the +\cmdarg{-v} or \cmdarg{-d} arguments can be used to make \cmd{lamhalt} +be verbose or extremely verbose, respectively. + +There are a small number of cases where \cmd{lamhalt} will fail. For +example, if a Open MPI daemon becomes unresponsive (e.g., the daemon was +killed), \cmd{lamhalt} may fail to shut down the entire Open MPI universe. +It will eventually timeout and therefore complete in finite time, but +you may want to use the last-resort \cmd{lamwipe} command (see +Section~\ref{sec:commands-lamwipe}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{laminfo} Command} +\label{sec:commands-laminfo} + +The \cmd{laminfo} command can be used to query the capabilities of the +Open MPI installation. Running \cmd{laminfo} with no parameters shows +a prettyprint summary of information. Using the \cmdarg{-parsable} +command line switch shows the same summary information, but in a +format that should be relatively easy to parse with common unix tools +such as \cmd{grep}, \cmd{cut}, \cmd{awk}, etc. + +\cmd{laminfo} supports a variety of command line options to query for +specific information. The \cmdarg{-h} option shows a complete listing +of all options. Some of the most common options include: + +\begin{itemize} +\item \cmdarg{-arch}: Show the architecture that Open MPI was configured + for. + +\item \cmdarg{-path}: Paired with a second argument, display various + paths relevant to the Open MPI installation. Valid second arguments + include: + + \begin{itemize} + \item \cmdarg{prefix}: Main installation prefix + \item \cmdarg{bindir}: Where the Open MPI executables are located + \item \cmdarg{libdir}: Where the Open MPI libraries are located + \item \cmdarg{incdir}: Where the Open MPI include files are located + \item \cmdarg{pkglibdir}: Where dynamic SSI modules are + installed\footnote{Dynamic SSI modules are not supported in + Open MPI 7.0, but will be supported in future versions.} + \item \cmdarg{sysconfdir}: Where the Open MPI help files are located + \end{itemize} + +\item \cmdarg{-version}: Paired with two addition options, display the + version of either Open MPI or one or more SSI modules. The first + argument identifies what to report the version of, and can be any of + the following: + + \begin{itemize} + \item \cmdarg{lam}: Version of Open MPI + \item \cmdarg{boot}: Version of all boot modules + \item \cmdarg{boot:module}: Version of a specific boot module + \item \cmdarg{coll}: Version of all coll modules + \item \cmdarg{coll:module}: Version of a specific coll module + \item \cmdarg{cr}: Version of all cr modules + \item \cmdarg{cr:module}: Version of a specific cr module + \item \cmdarg{rpi}: Version of all rpi modules + \item \cmdarg{rpi:module}: Version of a specific rpi module + \end{itemize} + + The second argument specifies the scope of the version number to + display -- whether to show the entire version number string, or just + one component of it: + + \begin{itemize} + \item \cmdarg{full}: Display the entire version number string + \item \cmdarg{major}: Display the major version number + \item \cmdarg{minor}: Display the minor version number + \item \cmdarg{release}: Display the release version number + \item \cmdarg{alpha}: Display the alpha version number + \item \cmdarg{beta}: Display the beta version number + \item \cmdarg{svn}: Display the SVN version number\footnote{The + value will either be 0 (not built from SVN), 1 (built from a + Subverstion checkout) or a date encoded in the form YYYYMMDD + (built from a nightly tarball on the given date)} + + \end{itemize} + +\changebegin{7.1} + +\item \cmdarg{-param}: Paired with two additional arguments, display + the SSI parameters for a given type and/or module. The first + argument can be any of the valid SSI types or the special name + ``base,'' indicating the SSI framework itself. The second argument + can be any valid module name. + + Additionally, either argument can be the wildcard ``any'' which + will match any valid SSI type and/or module. + +\changeend{7.1} +\end{itemize} + +Multiple options can be combined to query several attributes at once: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ laminfo -parsable -arch -version lam major -version rpi:tcp full -param rpi tcp +version:lam:7 +ssi:boot:rsh:version:ssi:1.0 +ssi:boot:rsh:version:api:1.0 +ssi:boot:rsh:version:module:7.0 +arch:i686-pc-linux-gnu +ssi:rpi:tcp:param:rpi_tcp_short:65536 +ssi:rpi:tcp:param:rpi_tcp_sockbuf:-1 +ssi:rpi:tcp:param:rpi_tcp_priority:20 +\end{lstlisting} +% Stupid emacs: $ + +Note that three version numbers are returned for the \rpi{tcp} module. +The first (\cmdarg{ssi}) indicates the overall SSI version that the +module conforms to, the second (\cmdarg{api}) indicates what version +of the \kind{rpi} API the module conforms to, and the last +(\cmdarg{module}) indicates the version of the module itself. + +Running \cmd{laminfo} with no arguments provides a wealth of +information about your Open MPI installation (we ask for this output +when reporting problems to the Open MPI general user's mailing list -- +see Section \ref{troubleshooting:mailing-lists} on page +\pageref{troubleshooting:mailing-lists}). Most of the output fields +are self-explanitory; two that are worth explaining are: + +\begin{itemize} +\item Debug support: This indicates whether your Open MPI installation was + configured with the \confflag{with-debug} option. It is generally + only used by the Open MPI Team for development and maintenance of Open MPI + itself; it does {\em not} indicate whether user's MPI applications + can be debugged (specifically: user's MPI applications can {\em + always} be debugged, regardless of this setting). This option + defaults to ``no''; users are discouraged from using this option. + See the Install Guide for more information about + \confflag{with-debug}. + +\item Purify clean: This indicates whether your Open MPI installation was + configured with the \confflag{with-purify} option. This option is + necessary to prevent a number of false positives when using + memory-checking debuggers such as Purify, Valgrind, and bcheck. It + is off by default because it can cause slight performance + degredation in MPI applications. See the Install Guide for more + information about \confflag{with-purify}. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamnodes} Command} +\label{sec:commands-lamnodes} + +Open MPI was specifically designed to abstract away hostnames once +\cmd{lamboot} has completed successfully. However, for various +reasons (usually related to system-administration concerns, and/or for +creating human-readable reports), it can be desirable to retrieve the +hostnames of Open MPI nodes long after \icmd{lamboot}. + +The command \cmd{lamnodes} can be used for this purpose. It accepts +both the \cmdarg{N} and \cmdarg{C} syntax from \cmd{mpirun}, and will return the +corresponding names of the specified nodes. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamnodes N +\end{lstlisting} +% Stupid emacs: $ + +\noindent will return the node that each CPU is located on, the +hostname of that node, the total number of CPUs on each, and any flags +that are set on that node. Specific nodes can also be queried: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamnodes n0,3 +\end{lstlisting} +% Stupid emacs: $ + +\noindent will return the node, hostname, number of CPUs, and flags on +n0 and n3. + +Command line arguments can be used to customize the output of +\cmd{lamnodes}. These include: + +\begin{itemize} +\item \cmdarg{-c}: Suppress printing CPU counts +\item \cmdarg{-i}: Print IP addresses instead of IP names +\item \cmdarg{-n}: Suppress printing Open MPI node IDs +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamrestart} Command} + +The \cmd{lamrestart} can be used to restart a previously-checkpointed +MPI application. The arguments to \cmd{lamrestart} depend on the +selected checkpoint/restart module. Regardless of the +checkpoint/restart module used, invoking \cmd{lamrestart} results in a +new \cmd{mpirun} being launched. + +The SSI parameter \ssiparam{cr} must be used to specify which +checkpoint/restart module should be used to restart the application. +Currently, only two values are possible: \ssiparam{blcr} and +\ssiparam{self}. + +\begin{itemize} +\item If the \crssi{blcr} module is selected, the SSI parameter + \issiparam{cr\_\-blcr\_\-context\_\-file} should be used to pass in + the filename of the context file that was created during a pevious + successful checkpoint. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamrestart -ssi cr blcr -ssi cr_blcr_context_file filename +\end{lstlisting} +% Stupid emacs: $ + +\item If the \crssi{self} module is selected, the SSI parameter + \issiparam{cr\_\-restart\_\-args} must be passed with the arguments + to be passed to \cmd{mpirun} to restart the application. For + example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamrestart -ssi cr self -ssi cr_restart_args "args to mpirun" +\end{lstlisting} +% Stupid emacs: $ +\end{itemize} + +See Section~\ref{sec:mpi-ssi-cr} for more detail about the +checkpoint/restart capabilities of Open MPI, including details about +the \crssi{blcr} and \crssi{self} \kind{cr} modules. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{The \icmd{lamshrink} Command} +\label{sec:commands-lamshrink} + +The \cmd{lamshrink} command is used to remove a node from a Open MPI +universe: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamshrink n3 +\end{lstlisting} +% Stupid emacs: $ + +\noindent removes node n3 from the Open MPI universe. Note that all nodes +with ID's greater than 3 will not have their ID's reduced by one -- n3 +simply becomes an empty slot in the Open MPI universe. \cmd{mpirun} and +\cmd{lamexec} will still function correctly, even when used with \cmdarg{C} +and \cmdarg{N} notation -- they will simply skip the n3 since there is no +longer an operational node in that slot. + +Note that the \cmd{lamgrow} command can optionally be used to fill the +empty slot with a new node. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{mpicc}, \icmd{mpiCC} / \icmd{mpic++}, and + \icmd{mpif77} Commands} +\label{sec:commands-wrappers} +\index{wrapper compilers} + +Compiling MPI applications can be a complicated process because the +list of compiler and linker flags required to successfully compile and +link a Open MPI application not only can be quite long, it can change +depending on the particular configuration that Open MPI was installed with. +For example, if Open MPI includes native support for Myrinet hardware, the +\cmdarg{-lgm} flag needs to be used when linking MPI executables. + +To hide all this complexity, ``wrapper'' compilers are provided that +handle all of this automatically. They are called ``wrapper'' +compilers because all they do is add relevant compiler and linker +flags to the command line before invoking the real back-end compiler +to actually perform the compile/link. Most command line arugments are +passed straight through to the back-end compiler without modification. + +Therefore, to compile an MPI application, use the wrapper compilers +exactly as you would use the real compiler. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpicc -O -c main.c +shell$ mpicc -O -c foo.c +shell$ mpicc -O -c bar.c +shell$ mpicc -O -o main main.o foo.o bar.o +\end{lstlisting} + +This compiles three C source code files and links them together into a +single executable. No additional \cmdarg{-I}, \cmdarg{-L}, or +\cmdarg{-l} arguments are required. + +The main exceptions to what flags are not passed through to the +back-end compiler are: + +\begin{itemize} +\item \cmdarg{-showme}: Used to show what the wrapper compiler would + have executed. This is useful to see the full compile/link line + would have been executed. For example (your output may differ from + what is shown below, depending on your installed Open MPI + configuration): + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpicc -O -c main.c -showme +gcc -I/usr/local/lam/include -pthread -O -c foo.c + \end{lstlisting} +% Stupid emacs mode: $ + \lstset{style=lam-cmdline} + \begin{lstlisting} +# The output line shown below is word wrapped in order to fit nicely in the document margins +shell$ mpicc -O -o main main.o foo.o bar.o -showme +gcc -I/usr/local/lam/include -pthread -O -o main main.o foo.o bar.o \ +-L/usr/local/lam/lib -llammpio -lpmpi -llamf77mpi -lmpi -llam -lutil \ +-pthread + \end{lstlisting} +% Stupid emacs mode: $ + + \changebegin{7.1} + + Two notable sub-flags are: + + \begin{itemize} + \item \cmdarg{-showme:compile}: Show only the compile flags, + suitable for substitution into \envvar{CFLAGS}. + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpicc -O -c main.c -showme:compile +-I/usr/local/lam/include -pthread + \end{lstlisting} +% Stupid emacs mode: $ + + \item \cmdarg{-showme:link}: Show only the linker flags (which are + actually \envvar{LDFLAGS} and \envvar{LIBS} mixed together), + suitable for substitution into \envvar{LIBS}. + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpicc -O -o main main.o foo.o bar.o -showme:link +-L/usr/local/lam/lib -llammpio -lpmpi -llamf77mpi -lmpi -llam -lutil -pthread + \end{lstlisting} +% Stupid emacs mode: $ + + \end{itemize} + + \changeend{7.1} + +\item \cmdarg{-lpmpi}: When compiling a user MPI application, the + \cmdarg{-lpmpi} argument is used to indicate that MPI profiling + support should be included. The wrapper compiler may alter the + exact placement of this argument to ensure that proper linker + dependency semantics are preserved. +\end{itemize} + +\changebegin{7.1} +Neither the compiler nor linker flags can be overridden at run-time. +The back-end compiler, however, can be. Environment variables can be +used for this purpose: + +\begin{itemize} +\item \ienvvar{Open MPIMPICC} (deprecated name: \idepenvvar{Open MPIHCC}): + Overrides the default C compiler in the \cmd{mpicc} wrapper + compiler. + +\item \ienvvar{Open MPIMPICXX} (deprecated name: \idepenvvar{Open MPIHCP}): + Overrides the default C compiler in the \cmd{mpicc} wrapper + compiler. + +\item \ienvvar{Open MPIMPIF77} (deprecated name: \idepenvvar{Open MPIHF77}): + Overrides the default C compiler in the \cmd{mpicc} wrapper + compiler. +\end{itemize} + +For example (for Bourne-like shells): + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ Open MPIPICC=cc +shell$ export Open MPIMPICC +shell$ mpicc my_application.c -o my_application +\end{lstlisting} +% Stupid emacs mode: $ + +For csh-like shells: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell% setenv Open MPIPICC cc +shell% mpicc my_application.c -o my_application +\end{lstlisting} + +All this being said, it is {\em strongly} recommended to use the +wrapper compilers -- and their default underlying compilers -- for all +compiling and linking of MPI applications. Strange behavior can occur +in MPI applications if Open MPI was configured and compiled with one +compiler and then user applications were compiled with a different +underlying compiler, to include: failure to compile, failure to link, +seg faults and other random bad behavior at run-time. + +Finally, note that the wrapper compilers only add all the +Open MPI-specific flags when a command-line argument that does not +begin with a dash (``-'') is present. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpicc +gcc: no input files +shell$ mpicc --version +gcc (GCC) 3.2.2 (Mandrake Linux 9.1 3.2.2-3mdk) +Copyright (C) 2002 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +\end{lstlisting} + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Deprecated Names} + +Previous versions of Open MPI used the names \idepcmd{hcc}, +\idepcmd{hcp}, and \idepcmd{hf77} for the wrapper compilers. While +these command names still work (they are simply symbolic links to the +real wrapper compilers \cmd{mpicc}, \cmd{mpiCC}/\cmd{mpic++}, and +\cmd{mpif77}, respectively), their use is deprecated. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{mpiexec} Command} +\label{sec:commands-mpiexec} + +The \cmd{mpiexec} command is used to launch MPI programs. It is +similar to, but slightly different than, \cmd{mpirun}.\footnote{The + reason that there are two methods to launch MPI executables is + because the MPI-2 standard suggests the use of \cmd{mpiexec} and + provides standardized command line arguments. Hence, even though + Open MPI already had an \cmd{mpirun} command to launch MPI executables, + \cmd{mpiexec} was added to comply with the standard.} Although +\cmd{mpiexec} is simply a wrapper around other Open MPI commands (including +\cmd{lamboot}, \cmd{mpirun}, and \cmd{lamhalt}), it ties their +functionality together and provides a unified interface for launching +MPI processes. +% +Specifically, \cmd{mpiexec} offers two features from command line +flags that require multiple steps when using other Open MPI commands: +launching MPMD MPI processes and launching MPI processes when there is +no existing Open MPI universe. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{General Syntax} + +The general form of \cmd{mpiexec} commands is: + +\lstset{style=lam-cmdline} +\begin{lstlisting} + mpiexec [global_args] local_args1 [: local_args2 [...]] +\end{lstlisting} + +Global arguments are applied to all MPI processes that are launched. +They must be specified before any local arguments. Common global +arguments include: + +\begin{itemize} +\item \cmdarg{-boot}: Boot the Open MPI RTE before launching the MPI + processes. + +\item \cmdarg{-boot-args $<$args$>$}: Pass \cmdarg{$<$args$>$} to the + back-end \cmd{lamboot}. Implies \cmdarg{-boot}. + +\item \cmdarg{-machinefile $<$filename$>$}: Specify {\tt + $<$filename$>$} as the boot schema to use when invoking the + back-end \cmd{lamboot}. Implies \cmdarg{-boot}. + +\changebegin{7.1} +\item \cmdarg{-prefix $<$lam/install/path$>$}: Use the Open MPI + installation specified in the $<$lam/install/path$>$ - where + $<$lam/install/path$>$ is the top level directory where Open MPI is + ``installed''. This is typically used when a user has multiple + Open MPI installations and want to switch between them without + changing the dot files or PATH environment variable. This option is + not compatible with Open MPI versions prior to 7.1. +\changeend{7.1} + +\item \cmdarg{-ssi $<$key$>$ $<$value$>$}: Pass the SSI {\tt + $<$key$>$} and {\tt $<$value$>$} arguments to the back-end + \cmd{mpirun} command. +\end{itemize} + +Local arguments are specific to an individual MPI process that will be +launched. They are specified along with the executable that will be +launched. Common local arguments include: + +\begin{itemize} +\item \cmdarg{-n $<$numprocs$>$}: Launch {\tt $<$numprocs$>$} number + of copies of this executable. + +\item \cmdarg{-arch $<$architecture$>$}: Launch the executable on + nodes in the Open MPI universe that match this architecture. An + architecture is determined to be a match if the {\tt + $<$architecture$>$} matches any subset of the GNU Autoconf + architecture string on each of the target nodes (the \cmd{laminfo} + command shows the GNU Autoconf configure string). + +\item \cmdarg{$<$other arguments$>$}: When \cmd{mpiexec} first + encounters an argument that it doesn't recognize, the remainder of + the arguments will be passed back to \cmd{mpirun} to actually start + the process. +\end{itemize} + +The following example launches four copies of the +\cmd{my\_\-mpi\_\-program} executable in the Open MPI universe, using +default scheduling patterns: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -n 4 my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Launching MPMD Processes} + +The ``\cmdarg{:}'' separator can be used to launch multiple +executables in the same MPI job. Specifically, each process will +share a common \mpiconst{MPI\_\-COMM\_\-WORLD}. For example, the +following launches a single \cmd{manager} process as well as a +\cmd{worker} process for every CPU in the Open MPI universe: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -n 1 manager : C worker +\end{lstlisting} +% Stupid emacs mode: $ + +Paired with the \cmd{-arch} flag, this can be especially helpful in +heterogeneous environments: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -arch solaris sol_program : -arch linux linux_program +\end{lstlisting} +% Stupid emacs mode: $ + +Even only ``slightly heterogeneous'' environments can run into +problems with shared libraries, different compilers, etc. The +\cmd{-arch} flag can be used to differentiate between different +versions of the same operating system: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -arch solaris2.8 sol2.8_program : -arch solaris2.9 sol2.9_program +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Launching MPI Processes with No Established Open MPI Universe} + +The \cmd{-boot}, \cmd{-boot-args}, and \cmd{-machinefile} global +arguments can be used to launch the Open MPI RTE, run the MPI process(es), +and then take down the Open MPI RTE. This conveniently wraps up several +Open MPI commands and provides ``one-shot'' execution of MPI processes. +For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -machinefile hostfile C my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +Some boot SSI modules do not require a hostfile; specifying the +\cmdarg{-boot} argument is sufficient in these cases: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -boot C my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +When \cmd{mpiexec} is used to boot the Open MPI RTE, it will do its best to +take down the Open MPI RTE even if errors occur, either during the boot +itself, or if an MPI process aborts (or the user hits Control-C). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{mpimsg} Command (Deprecated)} +\label{sec:commands-mpimsg} + +The \cmd{mpimsg} command is deprecated. It is only useful in a small +number of cases (specifically, when the \rpi{lamd} RPI module is +used), and may disappear in future Open MPI releases. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{mpirun} Command} +\label{sec:commands-mpirun} + +The \cmd{mpirun} command is the main mechanism to launch MPI processes +in parallel. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Simple Examples} + +Although \cmd{mpirun} supports many different modes of execution, most +users will likely only need to use a few of its capabilities. It is +common to launch either one process per node or one process per CPU in +the Open MPI universe (CPU counts are established in the boot schema). The +following two examples show these two cases: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# Launch one copy of my_mpi_program on every schedulable node in the Open MPI universe +shell$ mpirun N my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# Launch one copy of my_mpi_program on every schedulable CPU in the Open MPI universe +shell$ mpirun C my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +The specific number of processes that are launched can be controlled +with the \cmdarg{-np} switch: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# Launch four my_mpi_program processes +shell$ mpirun -np 4 my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +The \cmdarg{-ssi} switch can be used to specify tunable parameters to +MPI processes. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# Specify to use the usysv RPI module +shell$ mpirun -ssi rpi usysv C my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +The available modules and their associated parameters are discussed in +detail in Chapter~\ref{sec:mpi-ssi}. + +Arbitrary user arguments can also be passed to the user program. +\cmd{mpirun} will attempt to parse all options (looking for Open MPI +options) until it finds a \cmdarg{--}. All arguments following +\cmdarg{--} are directly passed to the MPI application. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# Pass three command line arguments to every instance of my_mpi_program +shell$ mpirun -ssi rpi usysv C my_mpi_program arg1 arg2 arg3 +# Pass three command line arguments, escaped from parsing +shell$ mpirun -ssi rpi usysv C my_mpi_program -- arg1 arg2 arg3 +\end{lstlisting} +% stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Controlling Where Processes Are Launched} + +\cmd{mpirun} allows for fine-grained control of where to schedule +launched processes. Note Open MPI uses the term ``schedule'' extensively +to indicate which nodes processes are launched on. Open MPI does {\em not} +influence operating system semantics for prioritizing processes or +binding processes to specific CPUs. The boot schema file can be used +to indicate how many CPUs are on a node, but this is only used for +scheduling purposes. For a fuller description of CPU counts in boot +schemas, see Sections~\ref{sec:getting-started-hostfile} +and~\ref{sec:lam-ssi-boot-schema} on +pages~\pageref{sec:getting-started-hostfile} +and~\pageref{sec:lam-ssi-boot-schema}, respectively. + +Open MPI offers two main scheduling nomenclatures: by node and by CPU. For +example \cmdarg{N} means ``all schedulable nodes in the universe'' +(``schedulable'' is defined in +Section~\ref{sec:commands-lamboot-no-schedule}). Similarly, +\cmdarg{C} means ``all schedulable CPUs in the universe.'' + +More fine-grained control is also possible -- nodes and CPUs can be +individually identified, or identified by ranges. The syntax for +these concepts is \cmdarg{n$<$range$>$} and \cmdarg{c$<$range$>$}, +respectively. \cmdarg{$<$range$>$} can specify one or more elements +by listing integers separated by commas and dashes. For example: + +\begin{itemize} +\item \cmdarg{n3}: The node with an ID of 3. + +\item \cmdarg{c2}: The CPU with an ID of 2. + +\item \cmdarg{n2,4}: The nodes with IDs of 2 and 4. + +\item \cmdarg{c2,4-7}: The CPUs with IDs of 2, 4, 5, 6, and 7. Note + that some of these CPUs may be on the same node(s). +\end{itemize} + +Integers can range from 0 to the highest numbered node/CPU. Note that +these nomenclatures can be mixed and matched on the \cmd{mpirun} +command line: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun n0 C manager-worker +\end{lstlisting} +% Stupid emacs mode: $ + +\noindent will launch the \cmd{manager-worker} program on \cmdarg{n0} +as well as on every schedulable CPU in the universe (yes, this means +that \cmdarg{n0} will likely be over-subscribed). + +When running on SMP nodes, it is preferable to use the +\cmdarg{C}/\cmdarg{c$<$range$>$} nomenclature (with appropriate CPU +counts in the boot schema) to the \cmdarg{N}/\cmdarg{n$<$range$>$} +nomenclature because of how Open MPI will order ranks in \mcw. For +example, consider a Open MPI universe of two four-way SMPs -- \cmdarg{n0} +and \cmdarg{n1} both have a CPU count of 4. Using the following: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +\noindent will launch eight copies of \cmd{my\_\-mpi\_\-program}, four +on each node. Open MPI will place as many adjoining \mcw\ ranks on the +same node as possible: \mcw\ ranks 0-3 will be scheduled on +\cmdarg{n0} and \mcw\ ranks 4-7 will be scheduled on \cmdarg{n1}. +Specifically, \cmdarg{C} schedules processes starting with \cmd{c0} +and incrementing the CPU index number. + +Note that unless otherwise specified, Open MPI schedules processes by CPU +(vs.\ scheduling by node). For example, using \cmd{mpirun}'s +\cmdarg{-np} switch to specify an absolute number of processes +schedules on a per-CPU basis. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Per-Process Controls} + +\cmd{mpirun} allows for arbitrary, per-process controls such as +launching MPMD jobs, passing different command line arguments to +different \mcw\ ranks, etc. This is accomplished by creating a text +file called an application schema that lists, one per line, the +location, relevant flags, user executable, and command line arguments +for each process. For example (lines beginning with ``\#'' are +comments): + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# Start the manager on c0 with a specific set of command line options +c0 manager manager_arg1 manager_arg2 manager_arg3 +# Start the workers on all available CPUs with different arguments +C worker worker_arg1 worker_arg2 worker_arg3 +\end{lstlisting} + +Note that the \cmdarg{-ssi} switch is {\em not} permissible in +application schema files; \cmdarg{-ssi} flags are considered to be +global to the entire MPI job, not specified per-process. Application +schemas are described in more detail in the \file{appschema(5)} manual +page. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Ability to Pass Environment Variables} + +All environment variables with names that begin with +\envvar{Open MPI\_\-MPI\_} are automatically passed to remote notes (unless +disabled via the \cmdarg{-nx} option to \cmd{mpirun}). Additionally, +the \cmdarg{-x} option enables exporting of specific environment +variables to the remote nodes: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ Open MPI_MPI_FOO=``green eggs and ham'' +shell$ export Open MPI_MPI_FOO +shell$ mpirun C -x DISPLAY,SEUSS=author samIam +\end{lstlisting} +% Stupid emacs mode: $ + +This will launch the \cmd{samIam} application on all available CPUs. +The \envvar{Open MPI\_\-MPI\_\-FOO}, \envvar{DISPLAY}, and \envvar{SEUSS} +environment variables will be created each the process environment +before the \cmd{smaIam} program is invoked. + +Note that the parser for the \cmd{-x} option is currently not very +sophisticated -- it cannot even handle quoted values when defining new +environment variables. Users are advised to set variables in the +environment prior to invoking \cmd{mpirun}, and only use \cmd{-x} to +export the variables to the remote nodes (not to define new +variables), if possible. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Current Working Directory Behavior} + +Using the \cmd{-wd} option to \cmd{mpirun} allows specifying an +arbitrary working directory for the launched processes. It can also +be used in application schema files to specify working directories on +specific nodes and/or for specific applications. + +If the \cmdarg{-wd} option appears both in an application schema file +and on the command line, the schema file directory will override the +command line value. \cmd{-wd} is mutually exclusive with \cmdarg{-D}. + +If neither \cmdarg{-wd} nor \cmdarg{-D} are specified, the local node +will send the present working directory name from the \cmd{mpirun} +process to each of the remote nodes. The remote nodes will then try +to change to that directory. If they fail (e.g., if the directory +does not exist on that node), they will start from the user's home +directory. + +All directory changing occurs before the user's program is invoked; it +does not wait until \mpifunc{MPI\_\-INIT} is called. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{mpitask} Command} +\label{sec:commands-mpitask} + +The \cmd{mpitask} command shows a list of the processes running in the +Open MPI universe and a snapshot of their current MPI activity. It is +usually invoked with no command line parameters, thereby showing +summary details of all processes currently running. +% +Since \cmd{mpitask} only provides a snapshot view, it is not advisable +to use \cmd{mpitask} as a high-resolution debugger (see +Chapter~\ref{sec:debugging}, page~\pageref{sec:debugging}, for more +details on debugging MPI programs). Instead, \cmd{mpitask} can be +used to provide answers to high-level questions such as ``Where is my +program hung?'' and ``Is my program making progress?'' + +The following example shows an MPI program running on four nodes, +sending a message of 524,288 integers around in a ring pattern. +Process 0 is running (i.e., not in an MPI function), while the other +three are blocked in \mpifunc{MPI\_\-RECV}. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpitask +TASK (G/L) FUNCTION PEER|ROOT TAG COMM COUNT DATATYPE +0 ring +1/1 ring Recv 0/0 201 WORLD 524288 INT +2/2 ring Recv 1/1 201 WORLD 524288 INT +3/3 ring Recv 2/2 201 WORLD 524288 INT +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{recon} Command} +\label{sec:commands-recon} + +The \cmd{recon} command is a quick test to see if the user's +environment is setup properly to boot the Open MPI RTE. It takes most of +the same parameters as the \cmd{lamboot} command. + +Although it does not boot the RTE, and does not definitively guarantee +that \cmd{lamboot} will succeed, it is a good tool for testing while +setting up first-time Open MPI users. \cmd{recon} will display a +message when it has completed indicating whether it succeeded or +failed. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{tping} Command} +\label{sec:commands-tping} + +The \cmd{tping} command can be used to verify the functionality of a +Open MPI universe. It is used to send a ping message between the Open MPI +daemons that constitute the Open MPI RTE. + +It commonly takes two arguments: the set of nodes to ping (expressed +in \cmdarg{N} notation) and how many times to ping them. Similar to the +Unix \cmd{ping} command, if the number of times to ping is not +specified, \cmd{tping} will continue until it is stopped (usually by +the user hitting Control-C). The following example pings all nodes in +the Open MPI universe three times: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ tping N -c 3 + 1 byte from 3 remote nodes and 1 local node: 0.002 secs + 1 byte from 3 remote nodes and 1 local node: 0.001 secs + 1 byte from 3 remote nodes and 1 local node: 0.001 secs + +3 messages, 3 bytes (0.003K), 0.005 secs (1.250K/sec) +roundtrip min/avg/max: 0.001/0.002/0.002 +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The \icmd{lamwipe} Command} +\label{sec:commands-lamwipe} + +\changebegin{7.1} +The \cmd{lamwipe} command used to be called \idepcmd{wipe}. The name +\idepcmd{wipe} has now been deprecated and although it still works in +this version of Open MPI, will be removed in future versions. All +users are encouraged to start using \cmd{lamwipe} instead. +\changeend{7.1} + +The \cmd{lamwipe} command is used as a ``last resort'' command, and is +typically only necessary if \cmd{lamhalt} fails. This usually only +occurs in error conditions, such as if a node fails. The +\cmd{lamwipe} command takes most of the same parameters as the +\cmd{lamboot} command -- it launches a process on each node in the +boot schema to kill the Open MPI RTE on that node. Hence, it should be +used with the same (or an equivalent) boot schema file as was used +with \cmd{lamboot}. + diff --git a/doc/user/debuggers.tex b/doc/user/debuggers.tex new file mode 100644 index 0000000000..f72121ecb4 --- /dev/null +++ b/doc/user/debuggers.tex @@ -0,0 +1,496 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Debugging Parallel Programs} +\label{sec:debug} +\label{sec:debugging} +\index{debuggers|(} + +{\Huge JMS this section is not bad, but needs a little revising (see + notes below} + +Open MPI supports multiple methods of debugging parallel programs. +The following notes and observations generally apply to debugging in +parallel: + +\begin{itemize} +\item Note that most debuggers require that MPI applications were + compiled with debugging support enabled. This typically entails + adding \cmdarg{-g} to the compile and link lines when building + your MPI application. + +\item Unless you specifically need it, it is not recommended to + compile Open MPI with \cmdarg{-g}. This will allow you to treat MPI + function calls as atomic instructions. + +\item Even when debugging in parallel, it is possible that not all MPI + processes will execute exactly the same code. For example, ``if'' + statements that are based upon a communicator's rank of the calling + process, or other location-specific information may cause different + execution paths in each MPI process. +\end{itemize} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Naming MPI Objects} + +Open MPI supports the MPI-2 functions {\sf + MPI\_\-$<$type$>$\_\-SET\_\-NAME} and {\sf + MPI\_\-$<$type$>$\_\-GET\_\-NAME}, where {\sf $<$type$>$} can be: +{\sf COMM}, {\sf WIN}, or {\sf TYPE}. Hence, you can associate +relevant text names with communicators, windows, and datatypes (e.g., +``6x13x12 molecule datatype'', ``Local group reduction +intracommunicator'', ``Spawned worker intercommunicator''). The use +of these functions is strongly encouraged while debugging MPI +applications. Since they are constant-time, one-time setup functions, +using these functions likely does not impact performance, and may be +safe to use in production environments, too. + +The rationale for using these functions is to allow Open MPI (and +supported debuggers, profilers, and other MPI diagnostic tools) to +display accurate information about MPI communicators, windows, and +datatypes. For example, whenever a communicator name is available, +Open MPI will use it in relevant error messages; when names are not +available, communicators (and windows and types) are identified by +index number, which -- depending on the application -- may vary +between successive runs. The TotalView parallel debugger will also +show communicator names (if available) when displaying the message +queues. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{TotalView Parallel Debugger} +\label{sec:debug-totalview} + +TotalView is a commercial debugger from Etnus that supports debugging +MPI programs in parallel. That is, with supported MPI +implementations, the TotalView debugger can automatically attach to +one or more MPI processes in a parallel application. + +Open MPI now supports basic debugging functionality with the TotalView +debugger. Specifically, Open MPI supports TotalView attaching to one +or more MPI processes, as well as viewing the MPI message queues in +supported RPI modules. + +This section provides some general tips and suggested use of TotalView +with Open MPI. It is {\em not} intended to replace the TotalView +documentation in any way. {\bf Be sure to consult the TotalView + documentation for more information and details than are provided + here.} + +Note: TotalView is licensed product provided by Etnus. You need to +have TotalView installed properly before you can use it with Open +MPI.\footnote{Refer to \url{http://www.etnus.com/} for more + information about TotalView.} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Attaching TotalView to MPI Processes} +\index{TotalView parallel debugger} +\index{debuggers!TotalView} + +Open MPI does not need to be configured or compiled in any special way +to allow TotalView to attach to MPI processes. + +You can attach TotalView to MPI processes started by \icmd{mpirun} / +\icmd{mpiexec} in following ways: + +\begin{enumerate} +\item Use the \cmdarg{-tv} convenience argument when running + \cmd{mpirun} or \cmd{mpiexec} (this is the preferred method): + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpirun -tv [...other mpirun arguments...] + \end{lstlisting} + % Stupid emacs mode: $ + + For example: + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpirun -tv C my_mpi_program arg1 arg2 arg3 + \end{lstlisting} + % Stupid emacs mode: $ + +\item Directly launch \cmd{mpirun} in TotalView (you {\em cannot} + launch \cmd{mpiexec} in TotalView): + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ totalview mpirun -a [...mpirun arguments...] + \end{lstlisting} + % Stupid emacs mode: $ + + For example: + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ totalview mpirun -a C my_mpi_program arg1 arg2 arg3 + \end{lstlisting} + % Stupid emacs mode: $ + + Note the \cmdarg{-a} argument after \cmd{mpirun}. This is necessary + to tell TotalView that arguments following ``\cmdarg{-a}'' belong to + \cmd{mpirun} and not TotalView. + + Also note that the \cmdarg{-tv} convenience argument to \cmd{mpirun} + simply executes ``\cmd{totalview mpirun -a ...}''; so both methods + are essentially identical. +\end{enumerate} + +TotalView can either attach to all MPI processes in +\mpiconst{MPI\_\-COMM\_\-WORLD} or a subset of them. The controls for +``partial attach'' are in TotalView, not Open MPI. In TotalView 6.0.0 +(analogous methods may work for earlier versions of TotalView -- see +the TotalView documentation for more details), you need to set the +parallel launch preference to ``ask.'' In the root window menu: + +\begin{enumerate} +\item Select File $\rightarrow$ Preferences +\item Select the Parallel tab +\item In the ``When a job goes parallel'' box, select ``Ask what to do'' +\item Click on OK +\end{enumerate} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Suggested Use} + +Since TotalView support is started with the \cmd{mpirun} command, +TotalView will, by default, start by debugging \cmd{mpirun} itself. +While this may seem to be an annoying drawback, there are actually +good reasons for this: + +\begin{itemize} +\item While debugging the parallel program, if you need to re-run the + program, you can simply re-run the application from within TotalView + itself. There is no need to exit the debugger to run your parallel + application again. + +\item TotalView can be configured to automatically skip displaying the + \cmd{mpirun} code. Specifically, instead of displaying the + \cmd{mpirun} code and enabling it for debugging, TotalView will + recognize the command named \cmd{mpirun} and start executing it + immediately upon load. See below for details. +\end{itemize} + +\noindent There are two ways to start debugging the MPI application: + +\begin{enumerate} +\item The preferred method is to have a \ifile{\$HOME/.tvdrc} file + that tells TotalView to skip past the \cmd{mpirun} code and + automatically start the parallel program. Create or edit your + \ifile{\$HOME/.tvdrc} file to include the following: + +\lstset{style=lam-shell} +\begin{lstlisting} +# Set a variable to say what the MPI ``starter'' program is +set starter_program mpirun + +# Check if the newly loaded image is the starter program +# and start it immediately if it is. +proc auto_run_starter {loaded_id} { + global starter_program + set executable_name [TV::symbol get $loaded_id full_pathname] + set file_component [file tail $executable_name] + + if {[string compare $file_component $starter_program] == 0} { + puts ``Automatically starting $file_component'' + dgo + } +} + +# Append this function to TotalView's image load callbacks so that +# TotalView run this program automatically. +dlappend TV::image_load_callbacks auto_run_starter +\end{lstlisting} +% Stupid emacs mode: $ + +Note that when using this method, \cmd{mpirun} is actually running in +the debugger while you are debugging your parallel application, even +though it may not be obvious. Hence, when the MPI job completes, +you'll be returned to viewing \cmd{mpirun} in the debugger. {\em This + is normal} -- all MPI processes have exited; the only process that +remains is \cmd{mpirun}. If you click ``Go'' again, \cmd{mpirun} will +launch the MPI job again. + +\item Do not create the \file{\$HOME/.tvdrc} file with the ``auto + run'' functionality described in the previous item, but instead + simply click the ``go'' button when TotalView launches. This runs + the \cmd{mpirun} command with the command line arguments, which will + eventually launch the MPI programs and allow attachment to the MPI + processes. + +\end{enumerate} + +When TotalView initially attaches to an MPI process, you will see the +code for \mpifunc{MPI\_\-INIT} or one of its sub-functions (which will +likely be assembly code, unless Open MPI itself was compiled with debugging +information). +% +You probably want to skip past the rest of \mpifunc{MPI\_\-INIT}. In +the Stack Trace window, click on function which called +\mpifunc{MPI\_\-INIT} (e.g., \func{main}) and set a breakpoint to line +following call to \mpifunc{MPI\_\-INIT}. Then click ``Go''. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Limitations} + +The following limitations are currently imposed when debugging Open MPI +jobs in TotalView: + +\begin{enumerate} +\item Cannot attach to scripts: You cannot attach TotalView to MPI + processes if they were launched by scripts instead of \cmd{mpirun}. + Specifically, the following won't work: + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpirun -tv C script_to_launch_foo + \end{lstlisting} + % Stupid emacs mode: $ + + But this will: + + \lstset{style=lam-cmdline} + \begin{lstlisting} +shell$ mpirun -tv C foo + \end{lstlisting} + % Stupid emacs mode: $ + + For that reason, since \cmd{mpiexec} is a script, although the + \cmdarg{-tv} switch works with \cmd{mpiexec} (because it will + eventually invoke \cmd{mpirun}), you cannot launch \cmd{mpiexec} + with TotalView. + +\item TotalView needs to launch the TotalView server on all remote + nodes in order to attach to remote processes. + + The command that TotalView uses to launch remote executables might + be different than what Open MPI uses. You may have to set this + command explicitly and independently of Open MPI. +% + For example, if your local environment has \cmd{rsh} disabled and + only allows \cmd{ssh}, then you likely need to set the TotalView + remote server launch command to ``\cmd{ssh}''. You can set this + internally in TotalView or with the \ienvvar{TVDSVRLAUNCHCMD} + environment variable (see the TotalView documentation for more + information on this). + +\item The TotalView license must be able to be found on all nodes + where you expect to attach the debugger. + + Consult with your system administrator to ensure that this is set up + properly. You may need to edit your ``dot'' files (e.g., + \file{.profile}, \file{.bashrc}, \file{.cshrc}, etc.) to ensure that + relevant environment variable settings exist on all nodes when you + \cmd{lamboot}. + +\item It is always a good idea to let \cmd{mpirun} finish before you + rerun or exit TotalView. + +\item TotalView will not be able to attach to MPI programs when you + execute \cmd{mpirun} with \cmdarg{-s} option. + + This is because TotalView will not get the source code of your + program on nodes other than the source node. We advise you to + either use a common filesystem or copy the source code and + executable on all nodes when using TotalView with Open MPI so that you + can avoid the use of \cmd{mpirun}'s \cmdarg{-s} flag. +\end{enumerate} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Message Queue Debugging} + +The TotalView debugger can show the sending, receiving, and +unexepected message queues for many parallel applications. Note the +following: + +\begin{itemize} +\item The MPI-2 function for naming communicators + (\mpifunc{MPI\_\-COMM\_\-SET\_\-NAME}) is strongly recommended when + using the message queue debugging functionality. For example, + \mpiconst{MPI\_\-COMM\_\-WORLD} and \mpiconst{MPI\_\-COMM\_\-SELF} + are automatically named by Open MPI. Naming communicators makes it + significantly easier to identify communicators of interest in the + debugger. + + {\Huge JMS is this true?} + Any communicator that is not named will be displayed as ``{\tt + --unnamed--}''. + +\item Message queue debugging of applications is not currently + supported for 64 bit executables. If you attempt to use the message + queue debugging functionality on a 64 bit executable, TotalView will + display a warning before disabling the message queue options. + +\item Open MPI does not currently provide debugging support for + dynamic processes (e.g., \mpifunc{MPI\_\-COMM\_\-SPAWN}). +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Serial Debuggers} +\label{sec:debug-serial} +\index{serial debuggers} +\index{debuggers!serial} + +Open MPI also allows the use of one or more serial debuggers when debugging +a parallel program. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Lauching Debuggers} +\index{debuggers!launching} + +Open MPI allows the arbitrary execution of any executable in an MPI +context as long as an MPI executable is eventually launched. For +example, it is common to \icmd{mpirun} a debugger (or a script that +launches a debugger on some nodes, and directly runs the application +on other nodes) since the debugger will eventually launch the MPI +process. + +{\Huge JMS may need some minor revamping} + +However, one must be careful when running programs on remote nodes +that expect the use of \file{stdin} -- \file{stdin} on remote nodes is +redirected to \file{/dev/null}. For example, it is advantageous to +export the \ienvvar{DISPLAY} environment variable, and run a shell +script that invokes an \cmd{xterm} with ``\cmd{gdb}'' (for example) +running in it on each node. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -x DISPLAY xterm-gdb.csh +\end{lstlisting} +% Stupid emacs mode: $ + +Additionally, it may be desirable to only run the debugger on certain +ranks in \mcw. For example, with parallel jobs that include tens or +hundreds of MPI processes, it is really only feasible to attach +debuggers to a small number of processes. In this case, a script may +be helpful to launch debuggers for some ranks in \mcw and directly +launch the application in others. + +{\Huge JMS needs revising} + +The Open MPI environment variable \ienvvar{Open MPIRANK} can be +helpful in this situation. This variable is placed in the environment +before the target application is executed. Hence, it is visible to +shell scripts as well as the target MPI application. It is erroneous +to alter the value of this variable. + +Consider the following script: + +\lstset{style=lam-shell} +\begin{lstlisting} +#!/bin/csh -f + +# Which debugger to run +set debugger=gdb + +# On MPI_COMM_WORLD rank 0, launch the process in the debugger. +# Elsewhere, just launch the process directly. +if (``$Open MPIRANK'' == ``0'') then + echo Launching $debugger on MPI_COMM_WORLD rank $Open MPIRANK + $debugger $* +else + echo Launching MPI executable on MPI_COMM_WORLD rank $Open MPIRANK + $* +endif + +# All done +exit 0 +\end{lstlisting} +% Stupid emacs mode: $ + +This script can be executed via \cmd{mpirun} to launch a debugger on +\mpiconst{MPI\_\-COMM\_\-WORLD} rank 0, and directly launch the MPI +process in all other cases. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Attaching Debuggers} +\index{debuggers!attaching} + +In some cases, it is not possible or desirable to start debugging a +parallel application immediately. For example, it may only be +desirable to attach to certain MPI processes whose identity may not be +known until run-time. + +In this case, the technique of attaching to a running process can be +used (this functionality is supported by many serial debuggers). +Specifically, determine which MPI process you want to attach to. Then +login to the node where it is running, and use the debugger's +``attach'' functionality to latch on to the running process. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Memory-Checking Debuggers} +\label{sec:debug-mem} +\index{debuggers!memory-checking} + +Memory-checking debuggers are an invaluable tool when debugging +software (even parallel software). They can provide detailed reports +about memory leaks, bad memory accesses, duplicate/bad memory +management calls, etc. Some memory-checking debuggers include (but +are not limited to): the Solaris Forte debugger (including the +\cmd{bcheck} command-line memory checker), the Purify software +package, and the Valgrind software package. + +Open MPI can be used with memory-checking debuggers. However, Open +MPI should be compiled with special support for such debuggers. This +is because in an attempt to optimize performance, there are many +structures used internally to Open MPI that do not always have all +memory positions initialized. For example, Open MPI's internal +\type{struct nmsg} is one of the underlying message constructs used to +pass data between Open MPI processes. But since the \type{struct + nmsg} is used in so many places, it is a generalized structure and +contains fields that are not used in every situation. + +By default, Open MPI only initializes relevant struct members before +using a structure. Using a structure may involve sending the entire +structure (including uninitialized members) to a remote host. This is +not a problem for Open MPI; the remote host will also ignore the +irrelevant struct members (depending on the specific function being +invoked). More to the point -- Open MPI was designed this way to +avoid setting variables that will not be used; this is a slight +optimization in run-time performance. Memory-checking debuggers, +however, will flag this behavior with ``read from uninitialized'' +warnings. + +The \confflag{enable-mem-debug} option can be used with Open MPI's +\cmd{configure} script that will force Open MPI to zero out {\em all} +memory before it is used. This will eliminate the ``read from +uninitialized'' types of warnings that memory-checking debuggers will +identify deep inside Open MPI. This option can only be specified when +Open MPI is configured; it is not possible to enable or disable this +behavior at run-time. Since this option invokes a slight overhead +penalty in the run-time performance of Open MPI, it is not the +default. + +% Close out the debuggers index entry + +\index{debuggers|)} diff --git a/doc/user/defs.tex b/doc/user/defs.tex new file mode 100644 index 0000000000..4fa784960b --- /dev/null +++ b/doc/user/defs.tex @@ -0,0 +1,206 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\usepackage{times} +\usepackage[final]{graphicx} +\usepackage{fullpage} +\usepackage{url} +\usepackage{makeidx} +\usepackage[final]{listings} + +% Make the index + +\makeindex + +% Version (gets substituted in by ``make dist'') + +\include{version} + +% PDF stuff + +\ifx\pdfoutput\undefined + \usepackage[colorlinks=true, + linkcolor=blue,filecolor=blue,pagecolor=blue,urlcolor=blue + ]{hyperref} +\else + \usepackage[pdftex, + colorlinks=true, + linkcolor=blue,filecolor=blue,pagecolor=blue,urlcolor=blue + ]{hyperref} +\fi + +% Some custom commands. Can't put spaces in these, or they'll show up +% with extra spaces in the text. :-( + +\newcommand{\cmd}[1]{\texttt{#1}} +\newcommand{\icmd}[1]{\cmd{#1}\index{#1 command@\cmd{#1} command}\index{commands!#1@\cmd{#1}}} +\newcommand{\idepcmd}[1]{\cmd{#1}\index{#1 command (deprecated)@\cmd{#1} command (deprecated)}\index{commands!#1 (deprecated)@\cmd{#1} (deprecated)}} +\newcommand{\cmdindex}[2]{\index{#1 command@\cmd{#1} command!#2}\index{commands!#1@\cmd{#1}}} +\newcommand{\cmdarg}[1]{\texttt{#1}} + +\newcommand{\func}[1]{\texttt{#1}} +\newcommand{\ifunc}[1]{\func{#1}\index{#1@\func{#1}}} +\newcommand{\mpifunc}[1]{\textsf{#1}\index{MPI functions!#1@\textsf{#1}}} + +\newcommand{\mpidatatype}[1]{\textsf{#1}\index{MPI datatypes!#1@\textsf{#1}}} +\newcommand{\mpitype}[1]{\textsf{#1}\index{MPI types!#1@\textsf{#1}}} +\newcommand{\type}[1]{\texttt{#1}} + +\newcommand{\mpiattr}[1]{\textsf{#1}\index{MPI attribute keyvals!#1@\textsf{#1}}} + +\newcommand{\mpiconst}[1]{\textsf{#1}\index{MPI constants!#1@\textsf{#1}}} +\newcommand{\iconst}[1]{\const{#1}\index{#1@\const{#1}}} +\newcommand{\const}[1]{\textsf{#1}} + +\def\mcw{\mpiconst{MPI\_\-COMM\_\-WORLD}} +\def\mcs{\mpiconst{MPI\_\-COMM\_\-SELF}} + +\newcommand{\confflag}[1]{\texttt{--#1}\index{#1@\texttt{--#1} configure flag}\index{configure flags!--#1@\texttt{--#1}}} +\newcommand{\confflagtwo}[2]{\texttt{--#1=#2}\index{#1@\texttt{--#1} configure flag}\index{configure flags!--#1@\texttt{--#1}}} +\newcommand{\depconfflag}[1]{\texttt{--#1}\index{#1@\texttt{--#1} +deprecated configure flag}} +\newcommand{\depconfflagtwo}[2]{\texttt{--#1=#2}\index{#1@\texttt{--#1} +deprecated configure flag}} +\newcommand{\confarg}[1]{\textsf{#1}} + +\newcommand{\manpage}[1]{\texttt{#1}\index{#1@\texttt{#1} manual page}\index{manual pages!#1@\texttt{#1}}} + +\newcommand{\maketarget}[1]{\texttt{#1}\index{#1@\texttt{#1} make target}\index{make targets!#1@\texttt{#1}}} + +\newcommand{\file}[1]{\texttt{#1}} +\newcommand{\ifile}[1]{\file{#1}\index{#1@\file{#1} file}\index{files!#1@\file{#1}} } + +\newcommand{\envvar}[1]{\texttt{#1}} +\newcommand{\ienvvar}[1]{\envvar{#1}\index{#1 environment variable@\envvar{#1} environment variable}\index{environment variables!#1@\envvar{#1}}} +\newcommand{\idepenvvar}[1]{\envvar{#1}\index{#1 environment variable@\envvar{#1} environment variable (deprecated)}\index{environment variables!#1 (deprecated)@\envvar{#1} (deprecated)}} + +\newcommand{\mcafw}[1]{\textsf{#1}} +\newcommand{\mcacomp}[1]{\textsf{#1}} + +\newcommand{\mcaparam}[1]{\texttt{#1}} +\newcommand{\imcaparam}[1]{\mcaparam{#1}\index{#1 MCA parameter@\mcaparam{#1} MCA parameter}\index{MCA parameters!#1@\mcaparam{#1}}} + +\newcommand{\mcavalue}[1]{\texttt{#1}} +\newcommand{\imcavalue}[2]{\mcavalue{#2}\index{MCA parameters!#1@\mcaparam{#1}!#2 value@\mcavalue{#2} value}} + +\newcommand{\host}[1]{\texttt{#1}} +\newcommand{\user}[1]{\texttt{#1}} +\newcommand{\funcarg}[1]{\texttt{#1}} +\newcommand{\var}[1]{\texttt{#1}} + +\newcommand{\signal}[1]{\textsf{#1}} + +% +% Tables for MCA Parameters +% +\newenvironment{mcaparamtb} +{\noindent +\begin{center} +\begin{tabular}{| p{2.1in} | p{.9in} | p{3in} |} \hline + \multicolumn{1}{|c|}{MCA parameter name} & + \multicolumn{1}{|c|}{Default value} & + \multicolumn{1}{|c|}{Description} \\ \hline \hline} +{\end{tabular}\end{center}} + +\newcommand{\mcaparamentry}[3]{\imcaparam{#1} & \multicolumn{1}{|c|}{#2} & #3 \\ \hline} + +% Some defines + +\def\trademark{$^{\sf (TM)}$} +\def\supportyes{yes} +\def\supportno{no} + +% Define some lstlistings styles for convenience + +\lstdefinestyle{ompi-c}{ + language=C, + showspaces=false, + columns=fullflexible, + frame=single, + frameround=tttt +} +\lstdefinestyle{ompi-cxx}{ + language=C++, + showspaces=false, + columns=fullflexible, + frameround=tttt +} +\lstdefinestyle{ompi-perl}{ + language=Perl, + showspaces=false, + columns=fullflexible, + frameround=tttt +} +\lstdefinestyle{ompi-fortran}{ + language=Fortran, + showspaces=false, + columns=fullflexible, + frame=single, + frameround=tttt +} +\lstdefinestyle{ompi-bourne}{ + language=ksh, + showspaces=false, + frame=single, + frameround=tttt, + columns=fullflexible, +} +\lstdefinestyle{ompi-shell}{ + language=csh, + showspaces=false, + frame=single, + frameround=tttt, + columns=fullflexible, +} +\lstdefinestyle{ompi-cmdline}{ + language=csh, + showspaces=false, + columns=fullflexible, + frame=single, + frameround=tttt, + emph={shell$}, + emphstyle=\bf +} +% Stupid emacs mode: $ +\lstdefinestyle{ompi-ompiinfo}{ + language=csh, + showspaces=false, + columns=fixed, + frame=single, + frameround=tttt, + emph={shell$}, + emphstyle=\bf +} +% Stupid emacs mode: $ + +% Stoopid European-based Linux distributions... +% Gotta force letter size paper, not A4 + +\ExecuteOptions{letterpaper} + +% Discussion item; stolen from the MPI standard + +\newenvironment{discuss}{\begin{list}{}{}\item[]{\it Discussion item:} +\addcontentsline{toc}{subsection}{Discussion Item} +}{{\rm ({\it End of discussion item.})} \end{list}} + +% Change bars + +\newcommand{\changebegin}[1]{\marginpar[\hspace*{75pt}\mbox{\hspace*{10pt} + $\top$ \tiny (#1)}]{\mbox{$\top$ \tiny (#1)}}} +\newcommand{\changeend}[1]{\marginpar[\hspace*{75pt}\mbox{\hspace*{10pt} + $\bot$ \tiny (#1)}]{\mbox{$\bot$ \tiny (#1)}}} diff --git a/doc/user/getting-started.tex b/doc/user/getting-started.tex new file mode 100644 index 0000000000..eadfb500ed --- /dev/null +++ b/doc/user/getting-started.tex @@ -0,0 +1,946 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Getting Started with Open MPI} +\label{sec:getting-started} + +This chapter provides a summary tutorial describing some of the high +points of using Open MPI. It is not intended as a comprehensive +guide; the finer details of some situations will not be explained. +However, it is a good step-by-step guide for users who are new to MPI +and/or Open MPI. + +Using Open MPI is conceptually simple: + +\begin{itemize} +\item Optionally launch the Open MPI run-time environment, as known as + the Open Run-Time Environment (ORTE) +\item Repeat as necessary: + \begin{itemize} + \item Compile MPI program(s) + \item Run MPI program(s) + \end{itemize} +\item If ORTE was started, shut it down. +\end{itemize} + +The tutorial below will describe each of these steps. + +{\Huge JMS Needs massive overhauling} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{One-Time Setup} + +This section describes actions that usually only need to be performed +once per user in order to setup LAM to function properly. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Setting the Path} +\label{sec:getting-started-path} + +One of the main requirements for Open MPI to function properly is for +the LAM executables to be in your path. This step may vary from site +to site; for example, the LAM executables may already be in your path +-- consult your local administrator to see if this is the case. + +{\bf NOTE:} If the LAM executables are already in your path, you can +skip this step and proceed to +Section~\ref{sec:getting-started-ssi}. + +In many cases, if your system does not already provide the LAM +executables in your path, you can add them by editing your ``dot'' +files that are executed automatically by the shell upon login (both +interactive and non-interactive logins). Each shell has a different +file to edit and corresponding syntax, so you'll need to know which +shell you are using. +Tables~\ref{tbl:getting-started-shells-interactive} +and~\ref{tbl:getting-started-shells-noninteractive} list several +common shells and the associated files that are typically used. +Consult the documentation for your shell for more information. + +\begin{table}[htbp] + \centering + \begin{tabular}{|p{1in}|p{4in}|} + \hline + \multicolumn{1}{|c|}{Shell name} & + \multicolumn{1}{|c|}{Interactive login startup file} \\ +% + \hline + \cmd{sh} (or Bash named ``\cmd{sh}'') & \ifile{.profile} \\ +% + \hline + \cmd{csh} & \ifile{.cshrc} followed by \ifile{.login} \\ +% + \hline + \cmd{tcsh} & \ifile{.tcshrc} if it exists, \ifile{.cshrc} if it + does not, followed by \ifile{.login} \\ +% + \hline + \cmd{bash} & \ifile{.bash\_\-profile} if it exists, or + \ifile{.bash\_\-login} if it exists, or \ifile{.profile} if it + exists (in that order). Note that some Linux distributions + automatically come with \ifile{.bash\_\-profile} scripts for users + that automatically execute \ifile{.bashrc} as well. Consult the + \cmd{bash} manual page for more information. \\ + \hline + \end{tabular} + \caption[List of common shells and the corresponding environment + setup files for interactive shells.]{List of common shells and + the corresponding environmental setup files commonly used with + each for interactive startups (e.g., normal login). All files + listed are assumed to be in the \file{\$HOME} directory.} + \label{tbl:getting-started-shells-interactive} +\end{table} + +\begin{table}[htbp] + \centering + \begin{tabular}{|p{1in}|p{4in}|} + \hline + \multicolumn{1}{|c|}{Shell name} & + \multicolumn{1}{|c|}{Non-interactive login startup file} \\ +% + \hline + \cmd{sh} (or Bash named ``\cmd{sh}'') & This shell does not + execute any file automatically, so LAM will execute the + \file{.profile} script before invoking LAM executables on remote + nodes \\ +% + \hline + \cmd{csh} & \ifile{.cshrc} \\ +% + \hline + \cmd{tcsh} & \ifile{.tcshrc} if it exists, \ifile{.cshrc} if it + does not \\ +% + \hline + \cmd{bash} & \ifile{.bashrc} if it exists \\ + \hline + \end{tabular} + \caption[List of common shells and the corresponding environment + setup files for non-interactive shells.]{List of common shells and + the corresponding environmental setup files commonly used with + each for non-interactive startups (e.g., normal login). All files + listed are assumed to be in the \file{\$HOME} directory.} + \label{tbl:getting-started-shells-noninteractive} +\end{table} + +You'll also need to know the directory where LAM was installed. For +the purposes of this tutorial, we'll assume that LAM is installed in +\file{/usr/local/lam}. And to re-emphasize a critical point: these +are only guidelines -- the specifics may vary depending on your local +setup. Consult your local system or network administrator for more +details. + +Once you have determined all three pieces of information (what shell +you are using, what directory LAM was installed to, and what the +appropriate ``dot'' file to edit), open the ``dot'' file in a text +editor and follow the general directions listed below: + +\begin{itemize} +\index{shell setup!Bash/Bourne shells} +\item For the Bash, Bourne, and Bourne-related shells, add the + following lines: + + \lstset{style=lam-bourne} + \begin{lstlisting} +PATH=/usr/local/lam/bin:$PATH +export PATH + \end{lstlisting} +% Stupid emacs mode: $ + +\index{shell setup!C shell (and related)} +\item For the C shell and related shells (such as \cmd{tcsh}), add the + following line: + + \lstset{style=lam-shell} + \begin{lstlisting} +set path = (/usr/local/lam/bin $path) + \end{lstlisting} +% Stupid emacs mode: $ + +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Finding the LAM Manual Pages} +\index{manual pages} + +LAM includes manual pages for all supported MPI functions as well as +all of the LAM executables. While this step {\em is not necessary} +for correct MPI functionality, it can be helpful when looking for MPI +or LAM-specific information. + +Using Tables~\ref{tbl:getting-started-shells-interactive} +and~\ref{tbl:getting-started-shells-noninteractive}, find the right +``dot'' file to edit. Assuming again that LAM was installed to +\file{/usr/local/lam}, open the appropriate ``dot'' file in a text +editor and follow the general directions listed below: + +\begin{itemize} +\index{shell setup!Bash/Bourne shells} +\item For the Bash, Bourne, and Bourne-related shells, add the + following lines: + + \lstset{style=lam-bourne} + \begin{lstlisting} +MANPATH=/usr/local/lam/man:$MANPATH +export MANPATH + \end{lstlisting} +% Stupid emacs mode: $ + +\index{shell setup!C shell (and related)} +\item For the C shell and related shells (such as \cmd{tcsh}), add the + following lines: + + \lstset{style=lam-shell} + \begin{lstlisting} +if ($?MANPATH == 0) then + setenv MANPATH /usr/local/lam/man +else + setenv MANPATH /usr/local/lam/man:$MANPATH +endif + \end{lstlisting} +% Stupid emacs mode: $ + +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{System Services Interface (SSI)} +\label{sec:getting-started-ssi} + +Open MPI is built around a core of System Services Interface (SSI) +plugin modules. SSI allows run-time selection of different underlying +services within the Open MPI run-time environment, including tunable +parameters that can affect the performance of MPI programs. + +While this tutorial won't go into much detail about SSI, just be aware +that you'll see mention of ``SSI'' in the text below. In a few +places, the tutorial passes parameters to various SSI modules through +either environment variables and/or the \cmdarg{-ssi} command line +parameter to several LAM commands. + +See other sections in this manual for a more complete description of +SSI (Chapter~\ref{sec:ssi}, page~\pageref{sec:ssi}), how it works, and +what run-time parameters are available (Chapters~\ref{sec:lam-ssi} +and~\ref{sec:mpi-ssi}, pages~\pageref{sec:lam-ssi} +and~\pageref{sec:mpi-ssi}, respectively). Also, the +\manpage{lamssi(7)}, \manpage{lamssi\_\-boot(7)}, +\manpage{lamssi\_\-coll(7)}, \manpage{lamssi\_\-cr(7)}, and +\manpage{lamssi\_\-rpi(7)} manual pages each provide additional +information on LAM's SSI mechanisms. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{What Does Your Open MPI Installation Support?} + +Open MPI can be installed with a large number of configuration options. +It depends on what choices your system/network administrator made when +configuring and installing Open MPI. The \icmd{laminfo} command is +provided to show the end-user with information about what the +installed Open MPI supports. Running ``\cmd{laminfo}'' (with no +arguments) prints a list of LAM's capabilities, including all of its +SSI modules. + +Among other things, this shows what language bindings the installed +Open MPI supports, what underlying network transports it supports, and +what directory LAM was installed to. The \cmdarg{-parsable} option +prints out all the same information, but in a conveniently +machine-parsable format (suitable for using with scripts). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Booting the LAM Run-Time Environment} +\label{sec:getting-started-booting} +\index{booting the LAM run-time environment} + +Before any MPI programs can be executed, the LAM run-time environment +must be launched. This is typically called ``booting LAM.'' A +successfully boot process creates an instance of the LAM run-time +environment commonly referred to as the ``LAM universe.'' + +LAM's run-time environment can be executed in many different +environments. For example, it can be run interactively on a cluster +of workstations (even on a single workstation, perhaps to simulate +parallel execution for debugging and/or development). Or LAM can be +run in production batch scheduled systems. + +This example will focus on a traditional \cmd{rsh} / \cmd{ssh}-style +workstation cluster (i.e., not under batch systems), where \cmd{rsh} +or \cmd{ssh} is used to launch executables on remote workstations. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The Boot Schema File (a.k.a, ``Hostfile'', ``Machinefile'')} +\label{sec:getting-started-hostfile} + +When using \cmd{rsh} or \cmd{ssh} to boot LAM, you will need a text +file listing the hosts on which to launch the LAM run-time +environment. This file is typically referred to as a ``boot schema'', +``hostfile'', or ``machinefile.'' For example: + +\lstset{style=lam-shell} +\begin{lstlisting} +# My boot schema +node1.cluster.example.com +node2.cluster.example.com +node3.cluster.example.com cpu=2 +node4.cluster.example.com cpu=2 +\end{lstlisting} + +Four nodes are specified in the above example by listing their IP +hostnames. Note also the ``{\tt cpu=2}'' that follows the last two +entries. This tells LAM that these machines each have two CPUs +available for running MPI programs (e.g., \host{node3} and +\host{node4} are two-way SMPs). It is important to note that the +number of CPUs specified here has {\em no} correlation to the +physicial number of CPUs in the machine. It is simply a convenience +mechanism telling LAM how many MPI processes we will typically launch +on that node. The ramifications of the {\tt cpu} key will be discussed +later. + +The location of this text file is irrelevant; for the purposes of this +example, we'll assume that it is named \file{hostfile} and is located +in the current working directory. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \icmd{lamboot} Command} +\label{sec:getting-started-lamboot} + +The \cmd{lamboot} command is used to launch the LAM run-time +environment. For each machine listed in the boot schema, the +following conditions must be met for LAM's run-time environment to be +booted correctly: + +\cmdindex{lamboot}{conditions for success} +\begin{itemize} +\item The machine must be reachable and operational. + +\item The user must be able to non-interactively execute arbitrary + commands on the machine (e.g., without being prompted for a + password). + +\item The LAM executables must be locatable on that machine, using the + user's shell search path. + +\item The user must be able to write to the LAM session directory + (usually somewhere under \file{/tmp}). + +\item The shell's start-up scripts must not print anything on standard + error. + +\item All machines must be able to resolve the fully-qualified domain + name (FQDN) of all the machines being booted (including itself). +\end{itemize} + +Once all of these conditions are met, the \cmd{lamboot} command is +used to launch the LAM run-time environment. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot -v -ssi boot rsh hostfile + +LAM 7.0/MPI 2 C++/ROMIO - Indiana University + +n0<1234> ssi:boot:base:linear: booting n0 (node1.cluster.example.com) +n0<1234> ssi:boot:base:linear: booting n1 (node2.cluster.example.com) +n0<1234> ssi:boot:base:linear: booting n2 (node3.cluster.example.com) +n0<1234> ssi:boot:base:linear: booting n3 (node4.cluster.example.com) +n0<1234> ssi:boot:base:linear: finished +\end{lstlisting} +% Stupid emacs mode: $ + +The parameters passed to \cmd{lamboot} in the example above are as +follows: + +\begin{itemize} +\item \cmdarg{-v}: Make \cmd{lamboot} be slightly verbose. + +\item \cmdarg{-ssi boot rsh}: Ensure that LAM uses the + \cmd{rsh}/\cmd{ssh} boot module to boot the LAM universe. + Typically, LAM chooses the right boot module automatically (and + therefore this parameter is not typically necessary), but to ensure + that this tutorial does exactly what we want it to do, we use this + parameter to absolutely ensure that LAM uses \cmd{rsh} or \cmd{ssh} + to boot the universe. + +\item \file{hostfile}: Name of the boot schema file. +\end{itemize} + +Common causes of failure with the \cmd{lamboot} command include (but +are not limited to): + +\cmdindex{lamboot}{common problems and solutions} +\begin{itemize} +\item User does not have permission to execute on the remote node. + This typically involves setting up a \file{\$HOME/.rhosts} file (if + using \cmd{rsh}), or properly configured SSH keys (using using + \cmd{ssh}). + + Setting up \file{.rhosts} and/or SSH keys for password-less remote + logins are beyond the scope of this tutorial; consult local + documentation for \cmd{rsh} and \cmd{ssh}, and/or internet tutorials + on setting up SSH keys.\footnote{As of this writing, a Google search + for ``ssh keys'' turned up several decent tutorials; including any + one of them here would significantly increase the length of this + already-tremendously-long manual.} + +\item The first time a user uses \cmd{ssh} to execute on a remote + node, \cmd{ssh} typically prints a warning to the standard error. + LAM will interpret this as a failure. If this happens, + \cmd{lamboot} will complain that something unexpectedly appeared on + \file{stderr}, and abort. +% + \changebegin{7.1} +% + One solution is to manually \cmd{ssh} to each node in the boot + schema once in order to eliminate the \file{stderr} warning, and + then try \cmd{lamboot} again. Another is to use the + \ssiparam{boot\_\-rsh\_\-ignore\_\-stderr} SSI parameter. We + haven't discussed SSI parameters yet, so it is probably easiest at + this point to manually \cmd{ssh} to a small number of nodes to get + the warning out of the way. +% + \changeend{7.1} +\end{itemize} + +If you have having problems with \cmd{lamboot}, try using the +\cmdarg{-d} option to \cmd{lamboot}, which will print enormous amounts +of debugging output which can be helpful for determining what the +problem is. Additionally, check the \file{lamboot(1)} man page as +well as the LAM FAQ on the main LAM web +site\footnote{\url{http://www.lam-mpi.org/faq/}} under the section +``Booting LAM'' for more information. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \icmd{lamnodes} Command} + +An easy way to see how many nodes and CPUs are in the current LAM +universe is with the \cmd{lamnodes} command. For example, with the +LAM universe that was created from the boot schema in +Section~\ref{sec:getting-started-hostfile}, running the \cmd{lamnodes} +command would result in the following output: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamnodes +n0 node1.cluster.example.com:1:origin,this_node +n1 node2.cluster.example.com:1: +n2 node3.cluster.example.com:2: +n3 node4.cluster.example.com:2: +\end{lstlisting} +% Stupid emacs mode: $ + +The ``{\tt n}'' number on the far left is the LAM node number. For +example, ``{\tt n3}'' uniquely refers to \host{node4}. Also note the +third column, which indicates how many CPUs are available for running +processes on that node. In this example, there are a total of 6 CPUs +available for running processes. This information is from the ``{\tt + cpu}'' key that was used in the hostfile, and is helpful for running +parallel processes (see below). + +Finally, the ``{\tt origin}'' notation indicates which node +\cmd{lamboot} was executed from. ``{\tt this\_\-node}'' obviously +indicates which node \cmd{lamnodes} is running on. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Compiling MPI Programs} +\label{sec:getting-started-compiling} +\index{compiling MPI programs} + +Note that it is {\em not} necessary to have LAM booted to compile MPI +programs. + +Compiling MPI programs can be a complicated process: + +\begin{itemize} +\item The same compilers should be used to compile/link user MPI + programs as were used to compile LAM itself. + +\item Depending on the specific installation configuration of LAM, a + variety of \cmdarg{-I}, \cmdarg{-L}, and \cmdarg{-l} flags (and + possibly others) may be necessary to compile and/or link a user MPI + program. +\end{itemize} + +Open MPI provides ``wrapper'' compilers to hide all of this complexity. +These wrapper compilers simply add the correct compiler/linker flags +and then invoke the underlying compiler to actually perform the +compilation/link. As such, LAM's wrapper compilers can be used just +like ``real'' compilers. + +The wrapper compilers are named \icmd{mpicc} (for C programs), +\icmd{mpiCC} and \icmd{mpic++} (for C++ programs), and \icmd{mpif77} +(for Fortran programs). For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpicc -g -c foo.c +shell$ mpicc -g -c bar.c +shell$ mpicc -g foo.o bar.o -o my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +Note that no additional compiler and linker flags are required for +correct MPI compilation or linking. The resulting +\cmd{my\_\-mpi\_\-program} is ready to run in the LAM run-time +environment. Similarly, the other two wrapper compilers can be used +to compile MPI programs for their respective languages: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiCC -O c++_program.cc -o my_c++_mpi_program +shell$ mpif77 -O f77_program.f -o my_f77_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +Note, too, that any other compiler/linker flags can be passed through +the wrapper compilers (such as \cmdarg{-g} and \cmdarg{-O}); they will +simply be passed to the back-end compiler. + +Finally, note that giving the \cmdarg{-showme} option to any of the +wrapper compilers will show both the name of the back-end compiler +that will be invoked, and also all the command line options that would +have been passed for a given compile command. For example (line +breaks added to fit in the documentation): + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiCC -O c++_program.cc -o my_c++_program -showme +g++ -I/usr/local/lam/include -pthread -O c++_program.cc -o \ +my_c++_program -L/usr/local/lam/lib -llammpio -llammpi++ -lpmpi \ +-llamf77mpi -lmpi -llam -lutil -pthread +\end{lstlisting} +% Stupid emacs mode: $ + +\changebegin{7.1} + +Note that the wrapper compilers only add all the Open MPI-specific +flags when a command-line argument that does not begin with a dash +(``-'') is present. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpicc +gcc: no input files +shell$ mpicc --version +gcc (GCC) 3.2.2 (Mandrake Linux 9.1 3.2.2-3mdk) +Copyright (C) 2002 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +\end{lstlisting} + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Sample MPI Program in C} +\index{sample MPI program!C} + +The following is a simple ``hello world'' C program. + +\lstset{style=lam-c} + +\begin{lstlisting} +#include +#include + +int main(int argc, char *argv[]) { + int rank, size; + + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + printf(``Hello, world! I am %d of %d\n'', rank, size); + + MPI_Finalize(); + return 0; +} +\end{lstlisting} + +This program can be saved in a text file and compiled with the +\icmd{mpicc} wrapper compiler. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpicc hello.c -o hello +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Sample MPI Program in C++} +\index{sample MPI program!C++} + +The following is a simple ``hello world'' C++ program. + +\lstset{style=lam-cxx} + +\begin{lstlisting} +#include +#include + +using namespace std; + +int main(int argc, char *argv[]) { + int rank, size; + + MPI::Init(argc, argv); + rank = MPI::COMM_WORLD.Get_rank(); + size = MPI::COMM_WORLD.Get_size(); + + cout << ``Hello, world! I am '' << rank << `` of '' << size << endl; + + MPI::Finalize(); + return 0; +} +\end{lstlisting} + +This program can be saved in a text file and compiled with the +\icmd{mpiCC} wrapper compiler (or \cmd{mpic++} if on case-insensitive +filesystems, such as Mac OS X's HFS+). + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiCC hello.cc -o hello +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Sample MPI Program in Fortran} +\index{sample MPI program!Fortran} + +The following is a simple ``hello world'' Fortran program. + +\lstset{style=lam-fortran} + +\begin{lstlisting} +program hello +include 'mpif.h' +integer rank, size, ierr + +call MPI_INIT(ierr) +call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) +call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) + +print *, "Hello, world! I am ", rank, " of ", size + +call MPI_FINALIZE(ierr) +stop +end +\end{lstlisting} + +This program can be saved in a text file and compiled with the +\icmd{mpif77} wrapper compiler. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpif77 hello.f -o hello +\end{lstlisting} +% Stupid emacs mode: $ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Running MPI Programs} +\index{running MPI programs} + +Once you have successfully established a LAM universe and compiled an +MPI program, you can run MPI programs in parallel. + +In this section, we will show how to run a Single Program, Multiple +Data (SPMD) program. Specifically, we will run the \cmd{hello} +program (from the previous section) in parallel. The \cmd{mpirun} and +\cmd{mpiexec} commands are used for launching parallel MPI programs, +and the \cmd{mpitask} commands can be used to provide crude debugging +support. The \cmd{lamclean} command can be used to completely clean +up a failed MPI program (e.g., if an error occurs). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \icmd{mpirun} Command} + +The \cmd{mpirun} command has many different options that can be used +to control the execution of a program in parallel. We'll explain only +a few of them here. + +The simplest way to launch the \cmd{hello} program across all CPUs +listed in the boot schema is: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C hello +\end{lstlisting} +% stupid emacs mode: $ + +The \cmdarg{C} option means ``launch one copy of \cmd{hello} on +every CPU that was listed in the boot schema.'' The \cmdarg{C} +notation is therefore convenient shorthand notation for launching a +set of processes across a group of SMPs. + +Another method for running in parallel is: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun N hello +\end{lstlisting} +% stupid emacs mode: $ + +The \cmdarg{N} option has a different meaning than \cmdarg{C} -- it +means ``launch one copy of \cmd{hello} on every node in the LAM +universe.'' Hence, \cmdarg{N} disregards the CPU count. This can be +useful for multi-threaded MPI programs. + +Finally, to run an absolute number of processes (regardless of how +many CPUs or nodes are in the LAM universe): + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun -np 4 hello +\end{lstlisting} +% stupid emacs mode: $ + +This runs 4 copies of \cmd{hello}. LAM will ``schedule'' how many +copies of \cmd{hello} will be run in a round-robin fashion on each +node by how many CPUs were listed in the boot schema +file.\footnote{Note that the use of the word ``schedule'' does not + imply that LAM has ties with the operating system for scheduling + purposes (it doesn't). LAM ``scheduled'' on a per-node basis; so + selecting a process to run means that it has been assigned and + launched on that node. The operating system is solely responsible + for all process and kernel scheduling.} For example, on the LAM +universe that we have previously shown in this tutorial, the following +would be launched: + +\begin{itemize} +\item 1 \cmd{hello} would be launched on {\tt n0} (named + \host{node1}) +\item 1 \cmd{hello} would be launched on {\tt n1} (named + \host{node2}) +\item 2 \cmd{hello}s would be launched on {\tt n2} (named + \host{node3}) +\end{itemize} + +Note that any number can be used -- if a number is used that is +greater than how many CPUs are in the LAM universe, LAM will ``wrap +around'' and start scheduling starting with the first node again. For +example, using \cmdarg{-np 10} would result in the following +schedule: + +\begin{itemize} +\item 2 \cmd{hello}s on {\tt n0} (1 from the first pass, and then a + second from the ``wrap around'') +\item 2 \cmd{hello}s on {\tt n1} (1 from the first pass, and then a + second from the ``wrap around'') +\item 4 \cmd{hello}s on {\tt n2} (2 from the first pass, and then 2 + more from the ``wrap around'') +\item 2 \cmd{hello}s on {\tt n3} +\end{itemize} + +The \file{mpirun(1)} man page contains much more information and +\cmd{mpirun} and the options available. For example, \cmd{mpirun} +also supports Multiple Program, Multiple Data (MPMD) programs, +although it is not discussed here. Also see +Section~\ref{sec:commands-mpirun} (page~\pageref{sec:commands-mpirun}) +in this document. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \icmd{mpiexec} Command} + +The MPI-2 standard recommends the use of \cmd{mpiexec} for portable +MPI process startup. In Open MPI, \cmd{mpiexec} is functionaly similar +to \cmd{mpirun}. Some options that are available to \cmd{mpirun} are +not available to \cmd{mpiexec}, and vice-versa. The end result is +typically the same, however -- both will launch parallel MPI programs; +which you should use is likely simply a personal choice. + +That being said, \cmd{mpiexec} offers more convenient access in three +cases: + +\begin{itemize} +\item Running MPMD programs +\item Running heterogeneous programs +\item Running ``one-shot'' MPI programs (i.e., boot LAM, run the + program, then halt LAM) +\end{itemize} + +The general syntax for \cmd{mpiexec} is: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec : : ... +\end{lstlisting} +% stupid emacs mode: $ + +%%%%% + +\subsubsection{Running MPMD Programs} + +For example, to run a manager/worker parallel program, where two +different executables need to be launched (i.e., \cmd{manager} and +\cmd{worker}, the following can be used: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -n 1 manager : worker +\end{lstlisting} +% stupid emacs mode: $ + +This runs one copy of \cmd{manager} and one copy of \cmd{worker} for +every CPU in the LAM universe. + +%%%%% + +\subsubsection{Running Heterogeneous Programs} + +Since LAM is a heterogeneous MPI implementation, it supports running +heterogeneous MPI programs. For example, this allows running a +parallel job that spans a Sun SPARC machine and an IA-32 Linux machine +(even though they are opposite endian machines). Although this can be +somewhat complicated to setup (remember that you will first need to +\cmd{lamboot} successfully, which essentially means that LAM must be +correctly installed on both architectures), the \cmd{mpiexec} command +can be helpful in actually running the resulting MPI job. + +Note that you will need to have two MPI executables -- one compiled +for Solaris (e.g., \cmd{hello.solaris}) and one compiled for Linux +(e.g., \cmd{hello.linux}). Assuming that these executables both +reside in the same directory, and that directory is available on both +nodes (or the executables can be found in the \envvar{PATH} on their +respective machines), the following command can be used: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -arch solaris hello.solaris : -arch linux hello.linux +\end{lstlisting} +% stupid emacs mode: $ + +This runs the \cmd{hello.solaris} command on all nodes in the LAM +universe that have the string ``solaris'' anywhere in their +architecture string, and \cmd{hello.linux} on all nodes that have +``linux'' in their architecture string. The architecture string of a +given LAM installation can be found by running the \cmd{laminfo} +command. + +%%%%% + +\subsubsection{``One-Shot'' MPI Programs} + +In some cases, it seems like extra work to boot a LAM universe, run +a single MPI job, and then shut down the universe. Batch jobs are +good examples of this -- since only one job is going to be run, why +does it take three commands? \cmd{mpiexec} provides a convenient way +to run ``one-shot'' MPI jobs. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpiexec -machinefile hostfile hello +\end{lstlisting} +% stupid emacs mode: $ + +This will invoke \cmd{lamboot} with the boot schema named +``\file{hostfile}'', run the MPI program \cmd{hello} on all available +CPUs in the resulting universe, and then shut down the universe with +the \cmd{lamhalt} command (which we'll discuss in +Section~\ref{sec:getting-started-lamhalt}, below). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \icmd{mpitask} Command} + +The \cmd{mpitask} command is analogous to the sequential Unix command +\cmd{ps}. It shows the current status of the MPI program(s) being +executed in the LAM universe, and displays primitive information about +what MPI function each process is currently executing (if any). Note +that in normal practice, the \cmd{mpimsg} command only gives a +snapshot of what messages are flowing between MPI processes, and +therefore is usually only accurate at that single point in time. To +really debug message passing traffic, use a tool such as message +passing analyzer (e.g., XMPI), or a parallel debugger (e.g., +TotalView). + +\cmd{mpitask} can be run from any node in the LAM universe. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \icmd{lamclean} Command} + +The \cmd{lamclean} command completely removed all running programs +from the LAM universe. This can be useful if a parallel job crashes +and/or leaves state in the LAM run-time environment (e.g., MPI-2 +published names). It is usually run with no parameters: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamclean +\end{lstlisting} +% stupid emacs mode: $ + +\cmd{lamclean} is typically only necessary when developing / debugging +MPI applications -- i.e., programs that hang, messages that are left +around, etc. Correct MPI programs should terminate properly, clean up +all their messages, unpublish MPI-2 names, etc. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Shutting Down the LAM Universe} +\label{sec:getting-started-lamhalt} + +When finished with the LAM universe, it should be shut down with the +\icmd{lamhalt} command: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamhalt +\end{lstlisting} +% Stupid emacs mode: $ + +In most cases, this is sufficient to kill all running MPI processes +and shut down the LAM universe. + +However, in some rare conditions, \cmd{lamhalt} may fail. For +example, if any of the nodes in the LAM universe crashed before +running \cmd{lamhalt}, \cmd{lamhalt} will likely timeout and +potentially not kill the entire LAM universe. In this case, you will +need to use the \icmd{lamwipe} command to guarantee that the LAM +universe has shut down properly: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamwipe -v hostfile +\end{lstlisting} +% Stupid emacs mode: $ + +\noindent where \file{hostfile} is the same boot schema that was used to +boot LAM (i.e., all the same nodes are listed). \cmd{lamwipe} will +forcibly kill all Open MPI processes and terminate the LAM universe. +This is a slower process than \cmd{lamhalt}, and is typically not +necessary. + diff --git a/doc/user/introduction.tex b/doc/user/introduction.tex new file mode 100644 index 0000000000..cacd75115a --- /dev/null +++ b/doc/user/introduction.tex @@ -0,0 +1,94 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Introduction to Open MPI} +\label{sec:introduction} + +This chapter provides a summary of the MPI standard and the +Open MPI implementation of that standard. + +\section{About MPI} + +The Message Passing Interface +(MPI)~\cite{geist96:_mpi2_lyon,mpi_forum93:_mpi}, is a set of API +functions enabling programmers to write high-performance parallel +programs that pass messages between processes to make up an +overall parallel job. MPI is the culmination of decades of research +in parallel computing, and was created by the MPI Forum~-- an open +group representing a wide cross-section of industry and academic +interests. More information, including the both volumes of the +official MPI standard, can be found at the MPI Forum web +site.\footnote{\url{http://www.mpi-forum.org/}} + +MPI is suitable for ``big iron'' parallel machines such as the IBM SP, +SGI Origin, etc., but it also works in smaller environments such as a +group of workstations. Since clusters of workstations are readily +available at many institutions, it has become common to use them as a +single parallel computing resource running MPI programs. +% +The MPI standard was designed to support portability and platform +independence. As a result, users can enjoy cross-platform development +capability as well as transparent heterogenous communication. For +example, MPI codes which have been written on the RS-6000 architecture +running AIX can be ported to a SPARC architecture running Solaris with +little or no modifications. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{About Open MPI} + +Open MPI is a project combining technologies and resources from +several other projects (FT-MPI, LA-MPI, LAM/MPI, and PACX-MPI) in +order to build the best MPI library available. A completely new MPI-2 +compliant implementation, Open MPI offers advantages for system and +software vendors, application developers, and computer science +researchers. + +Features implemented or in short-term development for Open MPI +include: + +\begin{itemize} +\item Full MPI-2 standards conformance +\item Thread safety and concurrency +\item Dynamic process spawning +\item High performance on all platforms +\item Reliable and fast job management +\item Network and process fault tolerance +\item Support data and network heterogeneity +\item Single library supports all networks +\item Run-time instrumentation +\item Many job schedulers supported +\item Many OS's supported (32 and 64 bit) +\item Production quality software +\item Portable and maintainable +\item Tunable by installers and end-users +\item Extensive user and installer guides +\item Internationalized error messages +\item Component-based design, documented APIs +\item CPAN-like tool for component management +\item Active, responsive mailing list +\item Open source license based on the BSD license +\end{itemize} + +The organizations (and newly-combined projects) contributing to Open +MPI are Indiana University (LAM/MPI), the University of Tennessee +(FT-MPI), and Los Alamos National Laboratory (LA-MPI). Additional +collaborators are at Sandia National Laboratories and the University +of Stuttgart. These developers bring many years of combined experience +to the project. + diff --git a/doc/user/listings.cfg b/doc/user/listings.cfg new file mode 100644 index 0000000000..c416dd9035 --- /dev/null +++ b/doc/user/listings.cfg @@ -0,0 +1,41 @@ +%% +%% This is file `listings.cfg', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% lstdrvrs.dtx (with options: `config') +%% +%% (w)(c) 1996/1997/1998/1999/2000/2001/2002 Carsten Heinz and/or any +%% other author listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\ProvidesFile{listings.cfg}[2002/04/01 v1.0 listings configuration] +\def\lstlanguagefiles + {lstlang0.sty,lstlang1.sty,lstlang2.sty,lstlang3.sty} +\lstset{defaultdialect=[R/3 6.10]ABAP, + defaultdialect=[95]Ada, + defaultdialect=[68]Algol, + defaultdialect=[ANSI]C, + defaultdialect=[light]Caml, + defaultdialect=[1985]Cobol, + defaultdialect=[ISO]C++, + defaultdialect=[95]Fortran, + defaultdialect=[3.0]Mathematica, + defaultdialect=[OMG]OCL, + defaultdialect=[Standard]Pascal, + defaultdialect=[67]Simula, + defaultdialect=[plain]TeX, + defaultdialect=[97]VRML} +\lstalias[]{TclTk}[tk]{tcl} +\endinput +%% +%% End of file `listings.cfg'. diff --git a/doc/user/listings.sty b/doc/user/listings.sty new file mode 100644 index 0000000000..fe13bedc36 --- /dev/null +++ b/doc/user/listings.sty @@ -0,0 +1,1828 @@ +%% +%% This is file `listings.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% listings.dtx (with options: `kernel') +%% +%% Please read the software license in listings.dtx or listings.dvi. +%% +%% (w)(c) 1996 -- 2002 Carsten Heinz and/or any other author +%% listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% Permission is granted to modify the listings package as well as +%% lstdrvrs.dtx. You are not allowed to distribute a modified version +%% of the package or lstdrvrs.dtx unless you change the file names and +%% provide the original files. In any case it is better to contact the +%% address below; other users will welcome removed bugs, new features, +%% and additional programming languages. +%% +%% The listings package is free software. +%% +%% However, if you distribute the package as part of a commercial +%% product or if you use the package to prepare a commercial document +%% (books, journals, and so on), I'd like to encourage you to make a +%% donation to the LaTeX3 fund. The size of this `license fee' should +%% depend on the value of the package for your product. For more +%% information about LaTeX see http://www.latex-project.org +%% +%% No matter whether you use the package for a commercial or +%% non-commercial document, please send me a copy of the document (.dvi, +%% .ps, .pdf, hardcopy, etc.) to support further development---it is +%% easier to introduce new features or simplify things if I see how the +%% package is used by other people. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\def\filedate{2002/04/01} +\def\fileversion{1.0} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{listings} + [\filedate\space\fileversion\space(Carsten Heinz)] +\def\lst@CheckVersion#1{\edef\reserved@a{#1}% + \ifx\lst@version\reserved@a \expandafter\@gobble + \else \expandafter\@firstofone \fi} +\let\lst@version\fileversion +\def\lst@InputCatcodes{% + \makeatletter \catcode`\"12% + \catcode`\^^@\active + \catcode`\^^I9% + \catcode`\^^L9% + \catcode`\^^M9% + \catcode`\%14% + \catcode`\~\active} +\def\lst@RestoreCatcodes#1{% + \ifx\relax#1\else + \noexpand\catcode`\noexpand#1\the\catcode`#1\relax + \expandafter\lst@RestoreCatcodes + \fi} +\edef\lst@RestoreCatcodes{% + \noexpand\lccode`\noexpand\/`\noexpand\/% + \lst@RestoreCatcodes\"\^^I\^^M\~\^^@\relax} +\lst@InputCatcodes +\AtEndOfPackage{\lst@RestoreCatcodes} +\def\@lst{lst} +\def\lst@IfSubstring#1#2{% + \def\lst@temp##1#1##2##3\relax{% + \ifx \@empty##2\expandafter\@secondoftwo + \else \expandafter\@firstoftwo \fi}% + \expandafter\lst@temp#2#1\@empty\relax} +\def\lst@IfOneOf#1\relax#2{% + \def\lst@temp##1,#1,##2##3\relax{% + \ifx \@empty##2\expandafter\@secondoftwo + \else \expandafter\@firstoftwo \fi}% + \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax} +\def\lst@DeleteKeysIn#1#2{% + \expandafter\lst@DeleteKeysIn@\expandafter#1#2,\relax,} +\def\lst@DeleteKeysIn@#1#2,{% + \ifx\relax#2\@empty + \expandafter\@firstoftwo\expandafter\lst@RemoveCommas + \else + \ifx\@empty#2\@empty\else + \def\lst@temp##1,#2,##2{% + ##1% + \ifx\@empty##2\@empty\else + \expandafter\lst@temp\expandafter,% + \fi ##2}% + \edef#1{\expandafter\lst@temp\expandafter,#1,#2,\@empty}% + \fi + \fi + \lst@DeleteKeysIn@#1} +\def\lst@RemoveCommas#1{\edef#1{\expandafter\lst@RC@#1\@empty}} +\def\lst@RC@#1{\ifx,#1\expandafter\lst@RC@ \else #1\fi} +\def\lst@ReplaceIn#1#2{% + \expandafter\lst@ReplaceIn@\expandafter#1#2\@empty\@empty} +\def\lst@ReplaceInArg#1#2{\lst@ReplaceIn@#1#2\@empty\@empty} +\def\lst@ReplaceIn@#1#2#3{% + \ifx\@empty#3\relax\else + \def\lst@temp##1#2##2{% + \ifx\@empty##2% + \lst@lAddTo#1{##1}% + \else + \lst@lAddTo#1{##1#3}\expandafter\lst@temp + \fi ##2}% + \let\@tempa#1\let#1\@empty + \expandafter\lst@temp\@tempa#2\@empty + \expandafter\lst@ReplaceIn@\expandafter#1% + \fi} +\providecommand*\@gobblethree[3]{} +\def\lst@GobbleNil#1\@nil{} +\def\lst@Swap#1#2{#2#1} +\def\lst@true{\let\lst@if\iftrue} +\def\lst@false{\let\lst@if\iffalse} +\lst@false +\def\lst@IfNextCharsArg#1{% + \def\lst@tofind{#1}\lst@IfNextChars\lst@tofind} +\def\lst@IfNextChars#1#2#3{% + \let\lst@tofind#1\def\@tempa{#2}\def\@tempb{#3}% + \let\lst@eaten\@empty \lst@IfNextChars@} +\def\lst@IfNextChars@{\expandafter\lst@IfNextChars@@\lst@tofind\relax} +\def\lst@IfNextChars@@#1#2\relax#3{% + \def\lst@tofind{#2}\lst@lAddTo\lst@eaten{#3}% + \ifx#1#3% + \ifx\lst@tofind\@empty + \let\lst@next\@tempa + \else + \let\lst@next\lst@IfNextChars@ + \fi + \expandafter\lst@next + \else + \expandafter\@tempb + \fi} +\def\lst@IfNextCharActive#1#2#3{% + \begingroup \lccode`\~=`#3\lowercase{\endgroup + \ifx~}#3% + \def\lst@next{#1}% + \else + \def\lst@next{#2}% + \fi \lst@next #3} +\def\lst@for#1\do#2{% + \def\lst@forbody##1{#2}% + \@for\lst@forvar:=#1\do + {\expandafter\lst@forbody\expandafter{\lst@forvar}}} +\def\lst@MakeActive#1{% + \let\lst@temp\@empty \lst@MakeActive@#1% + \relax\relax\relax\relax\relax\relax\relax\relax\relax} +\begingroup +\catcode`\^^@=\active \catcode`\^^A=\active \catcode`\^^B=\active +\catcode`\^^C=\active \catcode`\^^D=\active \catcode`\^^E=\active +\catcode`\^^F=\active \catcode`\^^G=\active \catcode`\^^H=\active +\gdef\lst@MakeActive@#1#2#3#4#5#6#7#8#9{\let\lst@next\relax + \ifx#1\relax + \else \lccode`\^^@=`#1% + \ifx#2\relax + \lowercase{\lst@lAddTo\lst@temp{^^@}}% + \else \lccode`\^^A=`#2% + \ifx#3\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A}}% + \else \lccode`\^^B=`#3% + \ifx#4\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B}}% + \else \lccode`\^^C=`#4% + \ifx#5\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C}}% + \else \lccode`\^^D=`#5% + \ifx#6\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D}}% + \else \lccode`\^^E=`#6% + \ifx#7\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E}}% + \else \lccode`\^^F=`#7% + \ifx#8\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F}}% + \else \lccode`\^^G=`#8% + \ifx#9\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F^^G}}% + \else \lccode`\^^H=`#9% + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F^^G^^H}}% + \let\lst@next\lst@MakeActive@ + \fi \fi \fi \fi \fi \fi \fi \fi \fi + \lst@next} +\endgroup +\def\lst@DefActive#1#2{\lst@MakeActive{#2}\let#1\lst@temp} +\def\lst@DefOther#1#2{% + \begingroup \def#1{#2}\escapechar\m@ne \expandafter\endgroup + \expandafter\lst@DefOther@\meaning#1\relax#1} +\def\lst@DefOther@#1>#2\relax#3{\edef#3{\zap@space#2 \@empty}} +\def\lst@InsideConvert#1{\lst@InsideConvert@#1 \@empty} +\begingroup \lccode`\~=`\ \relax \lowercase{% +\gdef\lst@InsideConvert@#1 #2{% + \lst@MakeActive{#1}% + \ifx\@empty#2% + \lst@lExtend\lst@arg{\lst@temp}% + \else + \lst@lExtend\lst@arg{\lst@temp~}% + \expandafter\lst@InsideConvert@ + \fi #2} +}\endgroup +\def\lst@XConvert{\@ifnextchar\bgroup \lst@XConvertArg\lst@XConvert@} +\def\lst@XConvertArg#1{% + {\lst@false \let\lst@arg\@empty + \lst@XConvert#1\@nil + \global\let\@gtempa\lst@arg}% + \lst@lExtend\lst@arg{\expandafter{\@gtempa}}% + \lst@XConvertNext} +\def\lst@XConvert@#1{% + \ifx\@nil#1\else + \begingroup\lccode`\~=`#1\lowercase{\endgroup + \lst@lAddTo\lst@arg~}% + \expandafter\lst@XConvertNext + \fi} +\def\lst@XConvertNext{% + \lst@if \expandafter\lst@XConvertX + \else \expandafter\lst@XConvert \fi} +\def\lst@XConvertX#1{% + \ifx\@nil#1\else + \lst@XConvertX@#1\relax + \expandafter\lst@XConvert + \fi} +\def\lst@XConvertX@#1#2\relax{% + \begingroup\lccode`\~=`#1\lowercase{\endgroup + \lst@XCConvertX@@~}{#2}} +\def\lst@XCConvertX@@#1#2{\lst@lAddTo\lst@arg{{#1#2}}} +\def\lst@Require#1#2#3#4#5{% + \begingroup + \aftergroup\lst@true + \ifx\@empty#3\@empty\else + \def\lst@prefix{#2}\let\lst@require\@empty + \edef\lst@temp{\expandafter\zap@space#3 \@empty}% + \lst@for\lst@temp\do{% + \ifx\@empty##1\@empty\else \lstKV@OptArg[]{##1}{% + #4[####1]{####2}% + \@ifundefined{\@lst\lst@prefix @\lst@malias $\lst@oalias}% + {\edef\lst@require{\lst@require,\lst@malias $\lst@oalias}}% + {}}% + \fi}% + \global\let\lst@loadaspects\@empty + \lst@InputCatcodes + \ifx\lst@require\@empty\else + \lst@for{#5}\do{% + \ifx\lst@require\@empty\else + \InputIfFileExists{##1}{}{}% + \fi}% + \fi + \ifx\lst@require\@empty\else + \PackageError{Listings}{Couldn't load requested #1}% + {The following #1s weren't loadable:^^J\@spaces + \lst@require^^JThis may cause errors in the sequel.}% + \aftergroup\lst@false + \fi + \ifx\lst@loadaspects\@empty\else + \lst@RequireAspects\lst@loadaspects + \fi + \fi + \endgroup} +\def\lst@IfRequired[#1]#2{% + \lst@NormedDef\lst@temp{[#1]#2}% + \expandafter\lst@IfRequired@\lst@temp\relax} +\def\lst@IfRequired@[#1]#2\relax#3{% + \lst@IfOneOf #2$#1\relax\lst@require + {\lst@DeleteKeysIn@\lst@require#2$#1,\relax,% + \global\expandafter\let + \csname\@lst\lst@prefix @#2$#1\endcsname\@empty + #3}} +\let\lst@require\@empty +\def\lst@NoAlias[#1]#2{% + \lst@NormedDef\lst@oalias{#1}\lst@NormedDef\lst@malias{#2}} +\gdef\lst@LAS#1#2#3#4#5#6#7{% + \lst@Require{#1}{#2}{#3}#4#5% + #4#3% + \@ifundefined{lst#2@\lst@malias$\lst@oalias}% + {\PackageError{Listings}% + {#1 \ifx\@empty\lst@oalias\else \lst@oalias\space of \fi + \lst@malias\space undefined}% + {The #1 is not loadable. \@ehc}}% + {#6\csname\@lst#2@\lst@malias $\lst@oalias\endcsname #7}} +\def\lst@RequireAspects#1{% + \lst@Require{aspect}{asp}{#1}\lst@NoAlias\lstaspectfiles} +\let\lstloadaspects\lst@RequireAspects +\@ifundefined{lstaspectfiles} + {\newcommand\lstaspectfiles{lstmisc0.sty,lstmisc.sty}}{} +\gdef\lst@DefDriver#1#2#3#4{% + \@ifnextchar[{\lst@DefDriver@{#1}{#2}#3#4}% + {\lst@DefDriver@{#1}{#2}#3#4[]}} +\gdef\lst@DefDriver@#1#2#3#4[#5]#6{% + \def\lst@name{#1}\let\lst@if#4% + \lst@NormedDef\lst@driver{\@lst#2@#6$#5}% + \lst@IfRequired[#5]{#6}{\begingroup \lst@true}% + {\begingroup}% + \lst@setcatcodes + \@ifnextchar[{\lst@XDefDriver{#1}#3}{\lst@DefDriver@@#3}} +\gdef\lst@DefDriver@@#1#2{% + \lst@if + \global\@namedef{\lst@driver}{#1{#2}}% + \fi + \endgroup + \@ifnextchar[\lst@XXDefDriver\@empty} +\gdef\lst@XXDefDriver[#1]{% + \ifx\@empty#1\@empty\else + \lst@if + \lstloadaspects{#1}% + \else + \@ifundefined{\lst@driver}{}% + {\xdef\lst@loadaspects{\lst@loadaspects,#1}}% + \fi + \fi} +\gdef\lst@XDefDriver#1#2[#3]#4#5{\lst@DefDriver@@#2{also#1=[#3]#4,#5}} +\let\lst@UserCommand\gdef +\newcommand*\lst@BeginAspect[2][]{% + \def\lst@curraspect{#2}% + \ifx \lst@curraspect\@empty + \expandafter\lst@GobbleAspect + \else + \let\lst@next\@empty + \lst@IfRequired[]{#2}% + {\lst@RequireAspects{#1}% + \lst@if\else \let\lst@next\lst@GobbleAspect \fi}% + {\let\lst@next\lst@GobbleAspect}% + \expandafter\lst@next + \fi} +\def\lst@EndAspect{% + \csname\@lst patch@\lst@curraspect\endcsname + \let\lst@curraspect\@empty} +\long\def\lst@GobbleAspect#1\lst@EndAspect{\let\lst@curraspect\@empty} +\def\lst@Key#1#2{% + \@ifnextchar[{\lstKV@def{#1}{#2}}% + {\def\lst@temp{\lst@Key@{#1}{#2}} + \afterassignment\lst@temp + \global\@namedef{KV@\@lst @#1}####1}} +\def\lstKV@def#1#2[#3]{% + \global\@namedef{KV@\@lst @#1@default\expandafter}\expandafter + {\csname KV@\@lst @#1\endcsname{#3}}% + \def\lst@temp{\lst@Key@{#1}{#2}}\afterassignment\lst@temp + \global\@namedef{KV@\@lst @#1}##1} +\def\lst@Key@#1#2{% + \ifx\relax#2\@empty\else + \begingroup \globaldefs\@ne + \csname KV@\@lst @#1\endcsname{#2}% + \endgroup + \fi} +\def\lst@UseHook#1{\csname\@lst hk@#1\endcsname} +\def\lst@AddToHook{\lst@ATH@\iffalse\lst@AddTo} +\def\lst@AddToHookExe{\lst@ATH@\iftrue\lst@AddTo} +\def\lst@AddToHookAtTop{\lst@ATH@\iffalse\lst@AddToAtTop} +\long\def\lst@ATH@#1#2#3#4{% + \@ifundefined{\@lst hk@#3}{% + \expandafter\gdef\csname\@lst hk@#3\endcsname{}}{}% + \expandafter#2\csname\@lst hk@#3\endcsname{#4}% + \def\lst@temp{#4}% + #1% \iftrue|false + \begingroup \globaldefs\@ne \lst@temp \endgroup + \fi} +\long\def\lst@AddTo#1#2{% + \expandafter\gdef\expandafter#1\expandafter{#1#2}} +\def\lst@AddToAtTop#1#2{\def\lst@temp{#2}% + \expandafter\expandafter\expandafter\gdef + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\lst@temp#1}} +\def\lst@lAddTo#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} +\def\lst@Extend#1#2{% + \expandafter\lst@AddTo\expandafter#1\expandafter{#2}} +\def\lst@lExtend#1#2{% + \expandafter\lst@lAddTo\expandafter#1\expandafter{#2}} +\RequirePackage{keyval}[1997/11/10] +\def\lstKV@TwoArg#1#2{\gdef\@gtempa##1##2{#2}\@gtempa#1{}{}} +\def\lstKV@ThreeArg#1#2{\gdef\@gtempa##1##2##3{#2}\@gtempa#1{}{}{}} +\def\lstKV@FourArg#1#2{\gdef\@gtempa##1##2##3##4{#2}\@gtempa#1{}{}{}{}} +\def\lstKV@OptArg[#1]#2#3{% + \gdef\@gtempa[##1]##2{#3}\lstKV@OptArg@{#1}#2\@} +\def\lstKV@OptArg@#1{\@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[#1]}} +\def\lstKV@OptArg@@[#1]#2\@{\@gtempa[#1]{#2}} +\def\lstKV@XOptArg[#1]#2#3{% + \global\let\@gtempa#3\lstKV@OptArg@{#1}#2\@} +\def\lstKV@CSTwoArg#1#2{% + \gdef\@gtempa##1,##2,##3\relax{#2}% + \@gtempa#1,,\relax} +\def\lstKV@SetIf#1{\lstKV@SetIf@#1\relax} +\def\lstKV@SetIf@#1#2\relax#3{\lowercase{% + \expandafter\let\expandafter#3% + \csname if\ifx #1t}true\else false\fi\endcsname} +\def\lstKV@SwitchCases#1#2#3{% + \def\lst@temp##1\\#1&##2\\##3##4\@nil{% + \ifx\@empty##3% + #3% + \else + ##2% + \fi + }% + \lst@temp\\#2\\#1&\\\@empty\@nil} +\lst@UserCommand\lstset{\begingroup \lst@setcatcodes \lstset@} +\def\lstset@#1{\endgroup \ifx\@empty#1\@empty\else\setkeys{lst}{#1}\fi} +\def\lst@setcatcodes{\makeatletter \catcode`\"=12\relax} +\def\lst@NewMode#1{% + \ifx\@undefined#1% + \lst@mode\lst@newmode\relax \advance\lst@mode\@ne + \xdef\lst@newmode{\the\lst@mode}% + \global\chardef#1=\lst@mode + \lst@mode\lst@nomode + \fi} +\newcount\lst@mode +\def\lst@newmode{\m@ne}% init +\lst@NewMode\lst@nomode % init (of \lst@mode :-) +\def\lst@UseDynamicMode{% + \@tempcnta\lst@dynamicmode\relax \advance\@tempcnta\@ne + \edef\lst@dynamicmode{\the\@tempcnta}% + \expandafter\lst@Swap\expandafter{\expandafter{\lst@dynamicmode}}} +\lst@AddToHook{InitVars}{\let\lst@dynamicmode\lst@newmode} +\def\lst@EnterMode#1#2{% + \bgroup \lst@mode=#1\relax #2% + \lst@FontAdjust + \lst@lAddTo\lst@entermodes{\lst@EnterMode{#1}{#2}}} +\lst@AddToHook{InitVars}{\let\lst@entermodes\@empty} +\def\lst@LeaveMode{% + \ifnum\lst@mode=\lst@nomode\else + \egroup \expandafter\lsthk@EndGroup + \fi} +\lst@AddToHook{EndGroup}{}% init +\def\lst@InterruptModes{% + \lst@Extend\lst@modestack{\expandafter{\lst@entermodes}}% + \lst@LeaveAllModes} +\lst@AddToHook{InitVars}{\global\let\lst@modestack\@empty} +\def\lst@ReenterModes{% + \ifx\lst@modestack\@empty\else + \lst@LeaveAllModes + \global\let\@gtempa\lst@modestack + \global\let\lst@modestack\@empty + \expandafter\lst@ReenterModes@\@gtempa\relax + \fi} +\def\lst@ReenterModes@#1#2{% + \ifx\relax#2\@empty + \gdef\@gtempa##1{#1}% + \expandafter\@gtempa + \else + \lst@AddTo\lst@modestack{{#1}}% + \expandafter\lst@ReenterModes@ + \fi + {#2}} +\def\lst@LeaveAllModes{% + \ifnum\lst@mode=\lst@nomode + \expandafter\lsthk@EndGroup + \else + \expandafter\egroup\expandafter\lst@LeaveAllModes + \fi} +\lst@AddToHook{ExitVars}{\lst@LeaveAllModes} +\lst@NewMode\lst@Pmode +\lst@NewMode\lst@GPmode +\def\lst@modetrue{\let\lst@ifmode\iftrue \lsthk@ModeTrue} +\let\lst@ifmode\iffalse % init +\lst@AddToHook{ModeTrue}{}% init +\def\lst@Lmodetrue{\let\lst@ifLmode\iftrue} +\let\lst@ifLmode\iffalse % init +\lst@AddToHook{EOL}{\@whilesw \lst@ifLmode\fi \lst@LeaveMode} +\def\lst@NormedDef#1#2{\lowercase{\edef#1{\zap@space#2 \@empty}}} +\def\lst@NormedNameDef#1#2{% + \lowercase{\edef\lst@temp{\zap@space#1 \@empty}% + \expandafter\xdef\csname\lst@temp\endcsname{\zap@space#2 \@empty}}} +\def\lst@GetFreeMacro#1{% + \@tempcnta\z@ \def\lst@freemacro{#1\the\@tempcnta}% + \lst@GFM@} +\def\lst@GFM@{% + \expandafter\ifx \csname\lst@freemacro\endcsname \relax + \edef\lst@freemacro{\csname\lst@freemacro\endcsname}% + \else + \advance\@tempcnta\@ne + \expandafter\lst@GFM@ + \fi} +\newbox\lst@gtempboxa +\newtoks\lst@token \newcount\lst@length +\def\lst@ResetToken{\lst@token{}\lst@length\z@} +\lst@AddToHook{InitVarsBOL}{\lst@ResetToken \let\lst@lastother\@empty} +\lst@AddToHook{EndGroup}{\lst@ResetToken \let\lst@lastother\@empty} +\def\lst@lettertrue{\let\lst@ifletter\iftrue} +\def\lst@letterfalse{\let\lst@ifletter\iffalse} +\lst@AddToHook{InitVars}{\lst@letterfalse} +\def\lst@Append#1{\advance\lst@length\@ne + \lst@token=\expandafter{\the\lst@token#1}} +\def\lst@AppendOther{% + \lst@ifletter \lst@Output\lst@letterfalse \fi + \futurelet\lst@lastother\lst@Append} +\def\lst@AppendLetter{% + \lst@ifletter\else \lst@OutputOther\lst@lettertrue \fi + \lst@Append} +\def\lst@SaveToken{% + \global\let\lst@gthestyle\lst@thestyle + \xdef\lst@RestoreToken{\noexpand\lst@token{\the\lst@token}% + \noexpand\lst@length\the\lst@length\relax + \noexpand\let\noexpand\lst@thestyle + \noexpand\lst@gthestyle}} +\newdimen\lst@currlwidth % \global +\newcount\lst@column \newcount\lst@pos % \global +\lst@AddToHook{InitVarsBOL} + {\global\lst@currlwidth\z@ \global\lst@pos\z@ \global\lst@column\z@} +\def\lst@CalcColumn{% + \@tempcnta\lst@column + \advance\@tempcnta\lst@length + \advance\@tempcnta-\lst@pos} +\newdimen\lst@lostspace % \global +\lst@AddToHook{InitVarsBOL}{\global\lst@lostspace\z@} +\def\lst@UseLostSpace{\ifdim\lst@lostspace>\z@ \lst@InsertLostSpace \fi} +\def\lst@InsertLostSpace{% + \lst@Kern\lst@lostspace \global\lst@lostspace\z@} +\def\lst@InsertHalfLostSpace{% + \global\lst@lostspace.5\lst@lostspace \lst@Kern\lst@lostspace} +\newdimen\lst@width +\lst@Key{basewidth}{0.6em,0.45em}{\lstKV@CSTwoArg{#1}% + {\def\lst@widthfixed{##1}\def\lst@widthflexible{##2}% + \ifx\lst@widthflexible\@empty + \let\lst@widthflexible\lst@widthfixed + \fi + \def\lst@temp{\PackageError{Listings}% + {Negative value(s) treated as zero}% + \@ehc}% + \let\lst@error\@empty + \ifdim \lst@widthfixed<\z@ + \let\lst@error\lst@temp \let\lst@widthfixed\z@ + \fi + \ifdim \lst@widthflexible<\z@ + \let\lst@error\lst@temp \let\lst@widthflexible\z@ + \fi + \lst@error}} +\lst@AddToHook{FontAdjust} + {\lst@width=\lst@ifflexible\lst@widthflexible + \else\lst@widthfixed\fi \relax} +\lst@Key{fontadjust}{false}[t]{\lstKV@SetIf{#1}\lst@iffontadjust} +\def\lst@FontAdjust{\lst@iffontadjust \lsthk@FontAdjust \fi} +\lst@AddToHook{InitVars}{\lsthk@FontAdjust} +\def\lst@OutputBox#1{\lst@alloverstyle{\box#1}} +\def\lst@alloverstyle#1{#1}% init +\def\lst@Kern#1{% + \setbox\z@\hbox{{\lst@currstyle{\kern#1}}}% + \global\advance\lst@currlwidth \wd\z@ + \lst@OutputBox\z@} +\def\lst@CalcLostSpaceAndOutput{% + \global\advance\lst@lostspace \lst@length\lst@width + \global\advance\lst@lostspace-\wd\@tempboxa + \global\advance\lst@currlwidth \wd\@tempboxa + \global\advance\lst@pos -\lst@length + \setbox\@tempboxa\hbox{\let\lst@OutputBox\box + \ifdim\lst@lostspace>\z@ \lst@leftinsert \fi + \box\@tempboxa + \ifdim\lst@lostspace>\z@ \lst@rightinsert \fi}% + \lst@OutputBox\@tempboxa \lsthk@PostOutput} +\lst@AddToHook{PostOutput}{}% init +\def\lst@OutputToken{% + \lst@TrackNewLines \lst@OutputLostSpace + \lst@CheckMerge + {\lst@thestyle{\lst@FontAdjust + \setbox\@tempboxa\lst@hbox + {\lsthk@OutputBox + \lst@lefthss + \expandafter\lst@FillOutputBox\the\lst@token\@empty + \lst@righthss}% + \lst@CalcLostSpaceAndOutput}}% + \lst@ResetToken} +\lst@AddToHook{OutputBox}{}% init +\def\lst@Delay#1{% + \lst@CheckDelay + #1% + \lst@GetOutputMacro\lst@delayedoutput + \edef\lst@delayed{\the\lst@token}% + \edef\lst@delayedlength{\the\lst@length}% + \lst@ResetToken} +\def\lst@Merge#1{% + \lst@CheckMerge + #1% + \edef\lst@merged{\the\lst@token}% + \edef\lst@mergedlength{\the\lst@length}% + \lst@ResetToken} +\def\lst@MergeToken#1#2{% + \advance\lst@length#2% + \lst@lExtend#1{\the\lst@token}% + \expandafter\lst@token\expandafter{#1}% + \let#1\@empty} +\def\lst@CheckDelay{% + \ifx\lst@delayed\@empty\else + \lst@GetOutputMacro\@gtempa + \ifx\lst@delayedoutput\@gtempa + \lst@MergeToken\lst@delayed\lst@delayedlength + \else + {\lst@ResetToken + \lst@MergeToken\lst@delayed\lst@delayedlength + \lst@delayedoutput}% + \let\lst@delayed\@empty + \fi + \fi} +\def\lst@CheckMerge{% + \ifx\lst@merged\@empty\else + \lst@MergeToken\lst@merged\lst@mergedlength + \fi} +\let\lst@delayed\@empty % init +\let\lst@merged\@empty % init +\def\lst@column@fixed{% + \lst@flexiblefalse + \lst@width\lst@widthfixed\relax + \let\lst@OutputLostSpace\lst@UseLostSpace + \let\lst@FillOutputBox\lst@FillFixed + \let\lst@hss\hss + \def\lst@hbox{\hbox to\lst@length\lst@width}} +\def\lst@FillFixed#1{#1\lst@FillFixed@} +\def\lst@FillFixed@#1{% + \ifx\@empty#1\else \lst@hss#1\expandafter\lst@FillFixed@ \fi} +\def\lst@column@flexible{% + \lst@flexibletrue + \lst@width\lst@widthflexible\relax + \let\lst@OutputLostSpace\lst@UseLostSpace + \let\lst@FillOutputBox\@empty + \let\lst@hss\@empty + \let\lst@hbox\hbox} +\def\lst@column@fullflexible{% + \lst@column@flexible + \def\lst@OutputLostSpace{\lst@ifnewline \lst@UseLostSpace\fi}% + \let\lst@leftinsert\@empty + \let\lst@rightinsert\@empty} +\def\lst@outputpos#1#2\relax{% + \def\lst@lefthss{\lst@hss}\let\lst@righthss\lst@lefthss + \let\lst@rightinsert\lst@InsertLostSpace + \ifx #1c% + \let\lst@leftinsert\lst@InsertHalfLostSpace + \else\ifx #1r% + \let\lst@righthss\@empty + \let\lst@leftinsert\lst@InsertLostSpace + \let\lst@rightinsert\@empty + \else + \let\lst@lefthss\@empty + \let\lst@leftinsert\@empty + \ifx #1l\else \PackageWarning{Listings}% + {Unknown positioning for output boxes}% + \fi + \fi\fi} +\def\lst@flexibletrue{\let\lst@ifflexible\iftrue} +\def\lst@flexiblefalse{\let\lst@ifflexible\iffalse} +\lst@Key{columns}{[c]fixed}{\lstKV@OptArg[]{#1}{% + \ifx\@empty##1\@empty\else \lst@outputpos##1\relax\relax \fi + \expandafter\let\expandafter\lst@arg + \csname\@lst @column@##2\endcsname + \lst@arg + \ifx\lst@arg\relax + \PackageWarning{Listings}{Unknown column format `##2'}% + \else + \lst@ifflexible + \let\lst@columnsflexible\lst@arg + \else + \let\lst@columnsfixed\lst@arg + \fi + \fi}} +\let\lst@columnsfixed\lst@column@fixed % init +\let\lst@columnsflexible\lst@column@flexible % init +\lst@Key{flexiblecolumns}\relax[t]{% + \lstKV@SetIf{#1}\lst@ifflexible + \lst@ifflexible \lst@columnsflexible + \else \lst@columnsfixed \fi} +\newcount\lst@newlines +\lst@AddToHook{InitVars}{\global\lst@newlines\z@} +\lst@AddToHook{InitVarsBOL}{\global\advance\lst@newlines\@ne} +\def\lst@NewLine{% + \ifx\lst@OutputBox\@gobble\else + \par\noindent \hbox{}% + \fi + \global\advance\lst@newlines\m@ne + \lst@newlinetrue} +\def\lst@newlinetrue{\global\let\lst@ifnewline\iftrue} +\lst@AddToHookExe{PostOutput}{\global\let\lst@ifnewline\iffalse}% init +\def\lst@TrackNewLines{% + \ifnum\lst@newlines>\z@ + \lsthk@OnNewLine + \lst@DoNewLines + \fi} +\lst@AddToHook{OnNewLine}{}% init +\lst@Key{emptylines}\maxdimen{% + \@ifstar{\lst@true\@tempcnta\@gobble#1\relax\lst@GobbleNil}% + {\lst@false\@tempcnta#1\relax\lst@GobbleNil}#1\@nil + \advance\@tempcnta\@ne + \edef\lst@maxempty{\the\@tempcnta\relax}% + \let\lst@ifpreservenumber\lst@if} +\def\lst@DoNewLines{ + \@whilenum\lst@newlines>\lst@maxempty \do + {\lst@ifpreservenumber + \lsthk@OnEmptyLine + \global\advance\c@lstnumber\lst@advancelstnum + \fi + \global\advance\lst@newlines\m@ne}% + \@whilenum \lst@newlines>\@ne \do + {\lsthk@OnEmptyLine \lst@NewLine}% + \ifnum\lst@newlines>\z@ \lst@NewLine \fi} +\lst@AddToHook{OnEmptyLine}{}% init +\lst@Key{identifierstyle}{}{\def\lst@identifierstyle{#1}} +\lst@AddToHook{EmptyStyle}{\let\lst@identifierstyle\@empty} +\def\lst@GotoTabStop{% + \ifnum\lst@newlines=\z@ + \setbox\@tempboxa\hbox{\lst@outputspace}% + \setbox\@tempboxa\hbox to\wd\@tempboxa{{\lst@currstyle{\hss}}}% + \lst@CalcLostSpaceAndOutput + \else + \global\advance\lst@lostspace \lst@length\lst@width + \global\advance\lst@column\lst@length \lst@length\z@ + \fi} +\def\lst@OutputOther{% + \lst@CheckDelay + \ifnum\lst@length=\z@\else + \let\lst@thestyle\lst@currstyle + \lsthk@OutputOther + \lst@OutputToken + \fi} +\lst@AddToHook{OutputOther}{}% init +\let\lst@currstyle\relax % init +\def\lst@Output{% + \lst@CheckDelay + \ifnum\lst@length=\z@\else + \ifx\lst@currstyle\relax + \let\lst@thestyle\lst@identifierstyle + \else + \let\lst@thestyle\lst@currstyle + \fi + \lsthk@Output + \lst@OutputToken + \fi + \let\lst@lastother\relax} +\lst@AddToHook{Output}{}% init +\def\lst@GetOutputMacro#1{% + \lst@ifletter \global\let#1\lst@Output + \else \global\let#1\lst@OutputOther\fi} +\def\lst@PrintToken{% + \lst@ifletter \lst@Output \lst@letterfalse + \else \lst@OutputOther \let\lst@lastother\@empty \fi} +\def\lst@XPrintToken{% + \lst@PrintToken \lst@CheckMerge + \ifnum\lst@length=\z@\else \lst@PrintToken \fi} +\def\lst@BeginDropOutput#1{% + \xdef\lst@BDOnewlines{\the\lst@newlines}% + \global\let\lst@BDOifnewline\lst@ifnewline + \lst@EnterMode{#1}% + {\lst@modetrue + \let\lst@OutputBox\@gobble + \aftergroup\lst@BDORestore}} +\def\lst@BDORestore{% + \global\lst@newlines\lst@BDOnewlines + \global\let\lst@ifnewline\lst@BDOifnewline} +\let\lst@EndDropOutput\lst@LeaveMode +\def\lst@ProcessLetter{\lst@whitespacefalse \lst@AppendLetter} +\def\lst@ProcessOther{\lst@whitespacefalse \lst@AppendOther} +\def\lst@ProcessDigit{% + \lst@whitespacefalse + \lst@ifletter \expandafter\lst@AppendLetter + \else \expandafter\lst@AppendOther\fi} +\def\lst@whitespacetrue{\global\let\lst@ifwhitespace\iftrue} +\def\lst@whitespacefalse{\global\let\lst@ifwhitespace\iffalse} +\lst@AddToHook{InitVarsBOL}{\lst@whitespacetrue} +\lst@Key{tabsize}{8} + {\ifnum#1>\z@ \def\lst@tabsize{#1}\else + \PackageError{Listings}{Strict positive integer expected}% + {You can't use `#1' as tabsize. \@ehc}% + \fi} +\lst@Key{showtabs}f[t]{\lstKV@SetIf{#1}\lst@ifshowtabs} +\lst@Key{tab}{\kern.06em\hbox{\vrule\@height.3ex}% + \hrulefill\hbox{\vrule\@height.3ex}} + {\def\lst@tab{#1}} +\def\lst@ProcessTabulator{% + \lst@XPrintToken \lst@whitespacetrue + \global\advance\lst@column -\lst@pos + \@whilenum \lst@pos<\@ne \do + {\global\advance\lst@pos\lst@tabsize}% + \lst@length\lst@pos + \lst@PreGotoTabStop} +\def\lst@PreGotoTabStop{% + \lst@ifshowtabs + \lst@TrackNewLines + \setbox\@tempboxa\hbox to\lst@length\lst@width + {{\lst@currstyle{\hss\lst@tab}}}% + \lst@CalcLostSpaceAndOutput + \else + \lst@ifkeepspaces + \@tempcnta\lst@length \lst@length\z@ + \@whilenum \@tempcnta>\z@ \do + {\lst@AppendOther\lst@outputspace + \advance\@tempcnta\m@ne}% + \lst@OutputOther + \else + \lst@GotoTabStop + \fi + \fi + \lst@length\z@ \global\lst@pos\z@} +\def\lst@outputspace{\ } +\def\lst@visiblespace{\lst@ttfamily{\char32}\textvisiblespace} +\lst@Key{showspaces}{false}[t]{\lstKV@SetIf{#1}\lst@ifshowspaces} +\lst@Key{keepspaces}{false}[t]{\lstKV@SetIf{#1}\lst@ifkeepspaces} +\lst@AddToHook{Init} + {\lst@ifshowspaces + \let\lst@outputspace\lst@visiblespace + \lst@keepspacestrue + \fi} +\def\lst@keepspacestrue{\let\lst@ifkeepspaces\iftrue} +\def\lst@ProcessSpace{% + \lst@ifkeepspaces + \lst@AppendOther\lst@outputspace + \else \ifnum\lst@newlines=\z@ + \lst@AppendSpecialSpace + \else \ifnum\lst@length=\z@ + \global\advance\lst@lostspace\lst@width + \global\advance\lst@pos\m@ne + \else + \lst@AppendSpecialSpace + \fi + \fi \fi + \lst@whitespacetrue} +\def\lst@AppendSpecialSpace{% + \lst@ifwhitespace + \lst@PrintToken + \global\advance\lst@lostspace\lst@width + \global\advance\lst@pos\m@ne + \else + \lst@AppendOther\lst@outputspace + \fi} +\lst@Key{formfeed}{\bigbreak}{\def\lst@formfeed{#1}} +\def\lst@ProcessFormFeed{% + \lst@XPrintToken + \ifnum\lst@newlines=\z@ + \lst@EOLUpdate \lsthk@InitVarsBOL + \fi + \lst@formfeed + \lst@whitespacetrue} +\def\lst@Def#1{\lccode`\~=#1\lowercase{\def~}} +\def\lst@Let#1{\lccode`\~=#1\lowercase{\let~}} +\lst@AddToAtTop{\try@load@fontshape}{\def\space{ }} +\def\lst@SelectStdCharTable{% + \lst@Def{9}{\lst@ProcessTabulator}% + \lst@Def{12}{\lst@ProcessFormFeed}% + \lst@Def{32}{\lst@ProcessSpace}} +\def\lst@CCPut#1#2{% + \ifnum#2=\z@ + \expandafter\@gobbletwo + \else + \lccode`\~=#2\lccode`\/=#2\lowercase{\lst@CCPut@~{#1/}}% + \fi + \lst@CCPut#1} +\def\lst@CCPut@#1#2{\lst@lAddTo\lst@SelectStdCharTable{\def#1{#2}}} +\lst@CCPut \lst@ProcessOther + {"21}{"22}{"27}{"28}{"29}{"2B}{"2C}{"2E}{"2F} + {"3A}{"3B}{"3D}{"3F}{"5B}{"5D}{"60} + \z@ +\lst@CCPut \lst@ProcessDigit + {"30}{"31}{"32}{"33}{"34}{"35}{"36}{"37}{"38}{"39} + \z@ +\lst@CCPut \lst@ProcessLetter + {"40}{"41}{"42}{"43}{"44}{"45}{"46}{"47} + {"48}{"49}{"4A}{"4B}{"4C}{"4D}{"4E}{"4F} + {"50}{"51}{"52}{"53}{"54}{"55}{"56}{"57} + {"58}{"59}{"5A} + {"61}{"62}{"63}{"64}{"65}{"66}{"67} + {"68}{"69}{"6A}{"6B}{"6C}{"6D}{"6E}{"6F} + {"70}{"71}{"72}{"73}{"74}{"75}{"76}{"77} + {"78}{"79}{"7A} + \z@ +\def\lst@CCPutMacro#1#2#3{% + \ifnum#2=\z@ \else + \begingroup\lccode`\~=#2\relax \lccode`\/=#2\relax + \lowercase{\endgroup\expandafter\lst@CCPutMacro@ + \csname\@lst @um/\expandafter\endcsname + \csname\@lst @um/@\endcsname /~}#1{#3}% + \expandafter\lst@CCPutMacro + \fi} +\def\lst@CCPutMacro@#1#2#3#4#5#6{% + \lst@lAddTo\lst@SelectStdCharTable{\def#4{#5#1}}% + \def#1{\lst@UM#3}% + \def#2{#6}} +\def\lst@UM#1{\csname\@lst @um#1@\endcsname} +\lst@CCPutMacro + \lst@ProcessOther {"23}\# + \lst@ProcessLetter{"24}\textdollar + \lst@ProcessOther {"25}\% + \lst@ProcessOther {"26}\& + \lst@ProcessOther {"2A}{\lst@ttfamily*\textasteriskcentered} + \lst@ProcessOther {"2D}{\lst@ttfamily{-{}}{$-$}} + \lst@ProcessOther {"3C}{\lst@ttfamily<\textless} + \lst@ProcessOther {"3E}{\lst@ttfamily>\textgreater} + \lst@ProcessOther {"5C}{\lst@ttfamily{\char92}\textbackslash} + \lst@ProcessOther {"5E}\textasciicircum + \lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}\textunderscore} + \lst@ProcessOther {"7B}{\lst@ttfamily{\char123}\textbraceleft} + \lst@ProcessOther {"7C}{\lst@ttfamily|\textbar} + \lst@ProcessOther {"7D}{\lst@ttfamily{\char125}\textbraceright} + \lst@ProcessOther {"7E}\textasciitilde + \lst@ProcessOther {"7F}- + \@empty\z@\@empty +\def\lst@ttfamily#1#2{\ifx\f@family\ttdefault#1\relax\else#2\fi} +\lst@AddToHook{Init}{\edef\ttdefault{\ttdefault}} +\def\lst@activecharstrue{\let\lst@ifactivechars\iftrue} +\def\lst@activecharsfalse{\let\lst@ifactivechars\iffalse} +\lst@activecharstrue +\def\lst@SelectCharTable{% + \lst@SelectStdCharTable + \lst@ifactivechars + \catcode9\active \catcode12\active \catcode13\active + \@tempcnta=32\relax + \@whilenum\@tempcnta<128\do + {\catcode\@tempcnta\active\advance\@tempcnta\@ne}% + \fi + \lst@ifec \lst@DefEC \fi + \let\do@noligs\lst@do@noligs \verbatim@nolig@list + \lsthk@SelectCharTable + \lst@DeveloperSCT + \ifx\lst@Backslash\relax\else + \lst@LetSaveDef{"5C}\lsts@backslash\lst@Backslash + \fi} +\lst@Key{SelectCharTable}{}{\def\lst@DeveloperSCT{#1}} +\lst@Key{MoreSelectCharTable}\relax{\lst@lAddTo\lst@DeveloperSCT{#1}} +\lst@AddToHook{SetLanguage}{\let\lst@DeveloperSCT\@empty} +\def\lst@do@noligs#1{% + \begingroup \lccode`\~=`#1\lowercase{\endgroup + \lst@do@noligs@~}} +\def\lst@do@noligs#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\lst@NoLig#1}} +\def\lst@NoLig{\advance\lst@length\m@ne \lst@Append\lst@nolig} +\def\lst@nolig{\lst@UM\@empty}% +\@namedef{\@lst @um@}{\leavevmode\kern\z@} +\def\lst@SaveOutputDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup + \def\lst@temp##1\def~##2##3\relax}{% + \global\expandafter\let\expandafter#2\@gobble##2\relax}% + \expandafter\lst@temp\lst@SelectStdCharTable\relax} +\lst@SaveOutputDef{"5C}\lstum@backslash +\lst@Key{extendedchars}{false}[t]{\lstKV@SetIf{#1}\lst@ifec} +\def\lst@DefEC{% + \lst@CCECUse \lst@ProcessLetter + ^^80^^81^^82^^83^^84^^85^^86^^87^^88^^89^^8a^^8b^^8c^^8d^^8e^^8f% + ^^90^^91^^92^^93^^94^^95^^96^^97^^98^^99^^9a^^9b^^9c^^9d^^9e^^9f% + ^^a0^^a1^^a2^^a3^^a4^^a5^^a6^^a7^^a8^^a9^^aa^^ab^^ac^^ad^^ae^^af% + ^^b0^^b1^^b2^^b3^^b4^^b5^^b6^^b7^^b8^^b9^^ba^^bb^^bc^^bd^^be^^bf% + ^^c0^^c1^^c2^^c3^^c4^^c5^^c6^^c7^^c8^^c9^^ca^^cb^^cc^^cd^^ce^^cf% + ^^d0^^d1^^d2^^d3^^d4^^d5^^d6^^d7^^d8^^d9^^da^^db^^dc^^dd^^de^^df% + ^^e0^^e1^^e2^^e3^^e4^^e5^^e6^^e7^^e8^^e9^^ea^^eb^^ec^^ed^^ee^^ef% + ^^f0^^f1^^f2^^f3^^f4^^f5^^f6^^f7^^f8^^f9^^fa^^fb^^fc^^fd^^fe^^ff% + ^^00} +\def\lst@CCECUse#1#2{% + \ifnum`#2=\z@ + \expandafter\@gobbletwo + \else + \ifnum\catcode`#2=\active + \lccode`\~=`#2\lccode`\/=`#2\lowercase{\lst@CCECUse@#1~/}% + \else + \lst@ifactivechars \catcode`#2=\active \fi + \lccode`\~=`#2\lccode`\/=`#2\lowercase{\def~{#1/}}% + \fi + \fi + \lst@CCECUse#1} +\def\lst@CCECUse@#1#2#3{% + \expandafter\def\csname\@lst @EC#3\endcsname{\lst@UM#3}% + \expandafter\let\csname\@lst @um#3@\endcsname #2% + \edef#2{\noexpand#1% + \expandafter\noexpand\csname\@lst @EC#3\endcsname}} +\lst@AddToHook{Init} + {\let\lsts@nfss@catcodes\nfss@catcodes + \let\nfss@catcodes\lst@nfss@catcodes} +\def\lst@nfss@catcodes{% + \lst@makeletter + ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\relax + \@makeother 0\@makeother 1\@makeother 2\@makeother 3\@makeother 4% + \@makeother 5\@makeother 6\@makeother 7\@makeother 8\@makeother 9% + \@makeother =\lsts@nfss@catcodes} +\def\lst@makeletter#1{% + \ifx\relax#1\else\catcode`#111\relax \expandafter\lst@makeletter\fi} +\lst@AddToHook{Init} +{\edef\lst@OrgOutput{\the\output}% + \output{\global\setbox\lst@gtempboxa\box\@cclv + \expandafter\egroup + \lst@SaveToken + \lst@InterruptModes + \setbox\@cclv\box\lst@gtempboxa + \bgroup\lst@OrgOutput\egroup + \bgroup + \aftergroup\pagegoal\aftergroup\vsize + \aftergroup\lst@ReenterModes\aftergroup\lst@RestoreToken}} +\lst@Key{alsoletter}\relax{% + \lst@DoAlso{#1}\lst@alsoletter\lst@ProcessLetter} +\lst@Key{alsodigit}\relax{% + \lst@DoAlso{#1}\lst@alsodigit\lst@ProcessDigit} +\lst@Key{alsoother}\relax{% + \lst@DoAlso{#1}\lst@alsoother\lst@ProcessOther} +\lst@AddToHook{SelectCharTable} + {\lst@alsoother \lst@alsodigit \lst@alsoletter} +\lst@AddToHookExe{SetLanguage}% init + {\let\lst@alsoletter\@empty + \let\lst@alsodigit\@empty + \let\lst@alsoother\@empty} +\def\lst@DoAlso#1#2#3{% + \lst@DefOther\lst@arg{#1}\let#2\@empty + \expandafter\lst@DoAlso@\expandafter#2\expandafter#3\lst@arg\relax} +\def\lst@DoAlso@#1#2#3{% + \ifx\relax#3\expandafter\@gobblethree \else + \begingroup \lccode`\~=`#3\relax \lowercase{\endgroup + \def\lst@temp##1\def~##2##3\relax{% + \edef\lst@arg{\def\noexpand~{\noexpand#2\expandafter + \noexpand\@gobble##2}}}}% + \expandafter\lst@temp\lst@SelectStdCharTable\relax + \lst@lExtend#1{\lst@arg}% + \fi + \lst@DoAlso@#1#2} +\def\lst@SaveDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~}} +\def\lst@DefSaveDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~\def~}} +\def\lst@LetSaveDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~\let~}} +\def\lst@CDef#1{\lst@CDef@#1} +\def\lst@CDef@#1#2#3#4{\lst@CDefIt#1{#2}{#3}{#4#2#3}#4} +\def\lst@CDefX#1{\lst@CDefX@#1} +\def\lst@CDefX@#1#2#3{\lst@CDefIt#1{#2}{#3}{}} +\def\lst@CDefIt#1#2#3#4#5#6#7#8{% + \ifx\@empty#2\@empty + \def#1{#6\def\lst@next{#7#4#8}\lst@next}% + \else \ifx\@empty#3\@empty + \def#1##1{% + #6% + \ifx##1#2\def\lst@next{#7#4#8}\else + \def\lst@next{#5##1}\fi + \lst@next}% + \else + \def#1{% + #6% + \lst@IfNextCharsArg{#2#3}{#7#4#8}% + {\expandafter#5\lst@eaten}}% + \fi \fi} +\def\lst@CArgX#1#2\relax{% + \lst@DefActive\lst@arg{#1#2}% + \expandafter\lst@CArg\lst@arg\relax} +\def\lst@CArg#1#2\relax{% + \lccode`\/=`#1\lowercase{\def\lst@temp{/}}% + \lst@GetFreeMacro{lst@c\lst@temp}% + \expandafter\lst@CArg@\lst@freemacro#1#2\@empty\@empty\relax} +\def\lst@CArg@#1#2#3#4\@empty#5\relax#6{% + \let#1#2% + \ifx\@empty#3\@empty + \def\lst@next{#6{#2{}{}}}% + \else + \def\lst@next{#6{#2#3{#4}}}% + \fi + \lst@next #1} +\def\lst@CArgEmpty#1\@empty{#1} +\lst@Key{excludedelims}\relax + {\lsthk@ExcludeDelims \lst@NormedDef\lst@temp{#1}% + \expandafter\lst@for\lst@temp\do + {\expandafter\let\csname\@lst @ifex##1\endcsname\iftrue}} +\def\lst@DelimPrint#1#2{% + #1% + \begingroup + \lst@mode\lst@nomode \lst@modetrue + #2\lst@XPrintToken + \endgroup + \lst@ResetToken + \fi} +\def\lst@DelimOpen#1#2#3#4#5#6\@empty{% + \lst@TrackNewLines \lst@XPrintToken + \lst@DelimPrint#1{#6}% + \lst@EnterMode{#4}{\def\lst@currstyle#5}% + \lst@DelimPrint{#1#2}{#6}% + #3} +\def\lst@DelimClose#1#2#3\@empty{% + \lst@TrackNewLines \lst@XPrintToken + \lst@DelimPrint{#1#2}{#3}% + \lst@LeaveMode + \lst@DelimPrint{#1}{#3}} +\def\lst@BeginDelim{\lst@DelimOpen\iffalse\else{}} +\def\lst@EndDelim{\lst@DelimClose\iffalse\else} +\def\lst@BeginIDelim{\lst@DelimOpen\iffalse{}{}} +\def\lst@EndIDelim{\lst@DelimClose\iffalse{}} +\lst@AddToHook{SelectCharTable}{\lst@DefDelims} +\lst@AddToHookExe{SetLanguage}{\let\lst@DefDelims\@empty} +\def\lst@Delim#1{% + \lst@false \let\lst@cumulative\@empty \let\lst@arg\@empty + \@ifstar{\@ifstar{\lst@Delim@{#1}}% + {\let\lst@cumulative\relax + \lst@Delim@{#1}}}% + {\lst@true\lst@Delim@{#1}}} +\def\lst@Delim@#1[#2]{% + \gdef\lst@delimtype{#2}% + \@ifnextchar[\lst@Delim@sty + {\lst@Delim@sty[#1]}} +\def\lst@Delim@sty[#1]{% + \def\lst@delimstyle{#1}% + \ifx\@empty#1\@empty\else + \lst@Delim@sty@ #1\@nil + \fi + \@ifnextchar[\lst@Delim@option + \lst@Delim@delim} +\def\lst@Delim@option[#1]{\def\lst@arg{#1}\lst@Delim@delim} +\def\lst@Delim@sty@#1#2\@nil{% + \if\relax\noexpand#1\else + \edef\lst@delimstyle{\expandafter\noexpand + \csname\@lst @\lst@delimstyle\endcsname}% + \fi} +\def\lst@Delim@delim#1\relax#2#3#4#5#6#7#8{% + \ifx #4\@empty \lst@Delim@delall{#2}\fi + \ifx\@empty#1\@empty + \ifx #4\@nil + \@ifundefined{\@lst @#2DM@\lst@delimtype}% + {\lst@Delim@delall{#2@\lst@delimtype}}% + {\lst@Delim@delall{#2DM@\lst@delimtype}}% + \fi + \else + \expandafter\lst@Delim@args\expandafter + {\lst@delimtype}{#1}{#5}#6{#7}{#8}#4% + \let\lst@delim\@empty + \expandafter\lst@IfOneOf\lst@delimtype\relax#3% + {\@ifundefined{\@lst @#2DM@\lst@delimtype}% + {\lst@lExtend\lst@delim{\csname\@lst @#2@\lst@delimtype + \expandafter\endcsname\lst@arg}}% + {\lst@lExtend\lst@delim{\expandafter\lst@UseDynamicMode + \csname\@lst @#2DM@\lst@delimtype + \expandafter\endcsname\lst@arg}}% + \ifx #4\@nil + \let\lst@temp\lst@DefDelims \let\lst@DefDelims\@empty + \expandafter\lst@Delim@del\lst@temp\@empty\@nil\@nil\@nil + \else + \lst@lExtend\lst@DefDelims\lst@delim + \fi}% + {\PackageError{Listings}{Illegal type `\lst@delimtype'}% + {#2 types are #3.}}% + \fi} +\def\lst@Delim@args#1#2#3#4#5#6#7{% + \begingroup + \lst@false \let\lst@next\lst@XConvert + \@ifnextchar #4{\xdef\lst@delimtype{\expandafter\@gobble + \lst@delimtype}% + #5\lst@next#2\@nil + \lst@lAddTo\lst@arg{\@empty#6}% + \lst@GobbleNil}% + {\lst@next#2\@nil + \lst@lAddTo\lst@arg{\@empty#3}% + \lst@GobbleNil}% + #1\@nil + \global\let\@gtempa\lst@arg + \endgroup + \let\lst@arg\@gtempa + \ifx #7\@nil\else + \expandafter\lst@Delim@args@\expandafter{\lst@delimstyle}% + \fi} +\def\lst@Delim@args@#1{% + \lst@if + \lst@lAddTo\lst@arg{{{#1}\lst@modetrue}}% + \else + \ifx\lst@cumulative\@empty + \lst@lAddTo\lst@arg{{{}#1}}% + \else + \lst@lAddTo\lst@arg{{{#1}}}% + \fi + \fi} +\def\lst@Delim@del#1\@empty#2#3#4{% + \ifx #2\@nil\else + \def\lst@temp{#1\@empty#2#3}% + \ifx\lst@temp\lst@delim\else + \lst@lAddTo\lst@DefDelims{#1\@empty#2#3{#4}}% + \fi + \expandafter\lst@Delim@del + \fi} +\def\lst@Delim@delall#1{% + \begingroup + \edef\lst@delim{\expandafter\string\csname\@lst @#1\endcsname}% + \lst@false \global\let\@gtempa\@empty + \expandafter\lst@Delim@delall@\lst@DefDelims\@empty + \endgroup + \let\lst@DefDelims\@gtempa} +\def\lst@Delim@delall@#1{% + \ifx #1\@empty\else + \ifx #1\lst@UseDynamicMode + \lst@true + \let\lst@next\lst@Delim@delall@do + \else + \def\lst@next{\lst@Delim@delall@do#1}% + \fi + \expandafter\lst@next + \fi} +\def\lst@Delim@delall@do#1#2\@empty#3#4#5{% + \expandafter\lst@IfSubstring\expandafter{\lst@delim}{\string#1}% + {}% + {\lst@if \lst@AddTo\@gtempa\lst@UseDynamicMode \fi + \lst@AddTo\@gtempa{#1#2\@empty#3#4{#5}}}% + \lst@false \lst@Delim@delall@} +\gdef\lst@DefDelimB#1#2#3#4#5#6#7#8{% + \lst@CDef{#1}#2% + {#3}% + {\let\lst@bnext\lst@CArgEmpty + \lst@ifmode #4\else + #5% + \def\lst@bnext{#6{#7}{#8}}% + \fi + \lst@bnext}% + \@empty} +\gdef\lst@DefDelimE#1#2#3#4#5#6#7{% + \lst@CDef{#1}#2% + {#3}% + {\let\lst@enext\lst@CArgEmpty + \ifnum #7=\lst@mode% + #4% + \let\lst@enext#6% + \else + #5% + \fi + \lst@enext}% + \@empty} +\lst@AddToHook{Init}{\let\lst@bnext\relax \let\lst@enext\relax} +\gdef\lst@DefDelimBE#1#2#3#4#5#6#7#8#9{% + \lst@CDef{#1}#2% + {#3}% + {\let\lst@bnext\lst@CArgEmpty + \ifnum #7=\lst@mode + #4% + \let\lst@bnext#9% + \else + \lst@ifmode\else + #5% + \def\lst@bnext{#6{#7}{#8}}% + \fi + \fi + \lst@bnext}% + \@empty} +\gdef\lst@delimtypes{s,l} +\gdef\lst@DelimKey#1#2{% + \lst@Delim{}#2\relax + {Delim}\lst@delimtypes #1% + {\lst@BeginDelim\lst@EndDelim} + i\@empty{\lst@BeginIDelim\lst@EndIDelim}} +\lst@Key{delim}\relax{\lst@DelimKey\@empty{#1}} +\lst@Key{moredelim}\relax{\lst@DelimKey\relax{#1}} +\lst@Key{deletedelim}\relax{\lst@DelimKey\@nil{#1}} +\gdef\lst@DelimDM@l#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} +\gdef\lst@DelimDM@s#1#2#3\@empty#4#5#6{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% + \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}} +\def\lst@ReplaceInput#1{\lst@CArgX #1\relax\lst@CDefX{}{}} +\lst@Key{literate}{}{\def\lst@literate{#1}} +\lst@AddToHook{SelectCharTable} + {\ifx\lst@literate\@empty\else + \expandafter\lst@Literate\lst@literate{}\relax\z@ + \fi} +\def\lst@Literate#1#2#3{% + \ifx\relax#2\@empty\else + \lst@ReplaceInput{#1}% + {\lst@XPrintToken \lst@letterfalse + \lst@token{#2}\lst@length#3\relax + \lst@XPrintToken}% + \expandafter\lst@Literate + \fi} +\def\lst@BeginDropInput#1{% + \lst@EnterMode{#1}% + {\lst@modetrue + \let\lst@ifdropinput\iftrue + \let\lst@ProcessLetter\@gobble + \let\lst@ProcessDigit\@gobble + \let\lst@ProcessOther\@gobble + \let\lst@ProcessSpace\@empty + \let\lst@ProcessTabulator\@empty + \let\lst@ProcessFormFeed\@empty}} +\let\lst@ifdropinput\iffalse % init +\lst@Key{basicstyle}\relax{\def\lst@basicstyle{#1}} +\lst@Key{inputencoding}\relax{\def\lst@inputenc{#1}} +\lst@AddToHook{Init} + {\lst@basicstyle + \ifx\lst@inputenc\@empty\else + \@ifundefined{inputencoding}{}% + {\inputencoding\lst@inputenc}% + \fi} +\lst@AddToHookExe{EmptyStyle} + {\let\lst@basicstyle\@empty + \let\lst@inputenc\@empty} +\def\lst@parshape{\parshape\@ne \z@ \linewidth} +\lst@AddToHookAtTop{EveryLine}{\lst@parshape} +\lst@AddToHookAtTop{EndGroup}{\lst@parshape} +\newcount\lst@lineno % \global +\lst@AddToHook{InitVars}{\global\lst@lineno\@ne} +\lst@Key{print}{true}[t]{\lstKV@SetIf{#1}\lst@ifprint} +\lst@Key{firstline}\relax{\def\lst@firstline{#1\relax}} +\lst@Key{lastline}\relax{\def\lst@lastline{#1\relax}} +\lst@AddToHook{PreSet} + {\let\lst@firstline\@ne \def\lst@lastline{9999999\relax}} +\lst@Key{nolol}{false}[t]{\lstKV@SetIf{#1}\lst@ifnolol} +\def\lst@nololtrue{\let\lst@ifnolol\iftrue} +\let\lst@ifnolol\iffalse % init +\lst@Key{captionpos}{t}{\def\lst@captionpos{#1}} +\lst@Key{abovecaptionskip}\smallskipamount{\def\lst@abovecaption{#1}} +\lst@Key{belowcaptionskip}\smallskipamount{\def\lst@belowcaption{#1}} +\lst@Key{label}\relax{\def\lst@label{#1}} +\lst@Key{title}\relax{\def\lst@title{#1}\let\lst@caption\relax} +\lst@Key{caption}\relax{\lstKV@OptArg[{#1}]{#1}% + {\def\lst@caption{##2}\def\lst@@caption{##1}}% + \let\lst@title\@empty} +\lst@AddToHookExe{TextStyle} + {\let\lst@caption\@empty \let\lst@@caption\@empty + \let\lst@title\@empty \let\lst@label\@empty} +\@ifundefined{thechapter} + {\newcounter{lstlisting} + \renewcommand\thelstlisting{\@arabic\c@lstlisting}} + {\newcounter{lstlisting}[chapter] + \renewcommand\thelstlisting + {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@lstlisting}} +\lst@UserCommand\lstlistingname{Listing} +\@ifundefined{abovecaptionskip} +{\newskip\abovecaptionskip + \newskip\belowcaptionskip + \long\def\@makecaption#1#2{% + \vskip\abovecaptionskip + \sbox\@tempboxa{#1: #2}% + \ifdim \wd\@tempboxa >\hsize + #1: #2\par + \else + \global \@minipagefalse + \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}% + \fi + \vskip\belowcaptionskip}% +}{} +\def\lst@MakeCaption#1{% + \ifx #1t% + \ifx\lst@@caption\@empty\expandafter\lst@HRefStepCounter \else + \expandafter\refstepcounter + \fi {lstlisting}% + \ifx\lst@label\@empty\else \label{\lst@label}\fi + \fi + \ifx\lst@caption\@empty\else + \lst@IfSubstring #1\lst@captionpos + {\begingroup \let\@@vskip\vskip + \def\vskip{\afterassignment\lst@vskip \@tempskipa}% + \def\lst@vskip{\nobreak\@@vskip\@tempskipa\nobreak}% + \par\normalsize\normalfont + \ifx #1t\allowbreak \fi + \ifx\lst@title\@empty + \expandafter\@makecaption + \else + \expandafter\lst@maketitle + \fi + {\noindent\lstlistingname + \ifx\lst@@caption\@empty\else~\thelstlisting\fi}% + \lst@caption + \ifx #1b\allowbreak \fi + \endgroup}{}% + \fi} +\def\lst@maketitle#1#2{\@makecaption\lst@title@dropdelim\lst@title} +\def\lst@title@dropdelim#1{\ignorespaces} +\AtBeginDocument{% +\@ifundefined{caption@make}{}{% +\def\lst@maketitle#1#2{% + \begingroup + \captionstyle{lsttitle}\@makecaption{}\lst@title + \endgroup} +\newcaptionstyle{lsttitle}{\caption@make{lsttitle}}% +\def\caption@@@lsttitle{\captiontext\par}% +}} +\def\lst@HRefStepCounter#1{% + \begingroup + \c@lstlisting\lst@neglisting + \advance\c@lstlisting\m@ne \xdef\lst@neglisting{\the\c@lstlisting}% + \ifx\hyper@refstepcounter\@undefined\else + \hyper@refstepcounter{#1}% + \fi + \endgroup} +\gdef\lst@neglisting{\z@}% init +\lst@Key{boxpos}{c}{\def\lst@boxpos{#1}} +\def\lst@boxtrue{\let\lst@ifbox\iftrue} +\let\lst@ifbox\iffalse +\lst@Key{float}\relax[\lst@floatplacement]{% + \def\lst@next{\@ifstar{\let\lst@beginfloat\@dblfloat + \let\lst@endfloat\end@dblfloat + \lst@KFloat}% + {\let\lst@beginfloat\@float + \let\lst@endfloat\end@float + \lst@KFloat}} + \edef\lst@float{#1}% + \expandafter\lst@next\lst@float\relax} +\def\lst@KFloat#1\relax{% + \ifx\@empty#1\@empty + \let\lst@float\lst@floatplacement + \else + \def\lst@float{#1}% + \fi} +\lst@Key{floatplacement}{tbp}{\def\lst@floatplacement{#1}} +\lst@AddToHook{PreSet}{\let\lst@float\relax} +\lst@AddToHook{TextStyle}{\let\lst@float\relax} +\AtBeginDocument{% +\@ifundefined{c@float@type}% + {\edef\ftype@lstlisting{\ifx\c@figure\@undefined 1\else 4\fi}} + {\edef\ftype@lstlisting{\the\c@float@type}% + \addtocounter{float@type}{\value{float@type}}}% +} +\lst@Key{aboveskip}\medskipamount{\def\lst@aboveskip{#1}} +\lst@Key{belowskip}\medskipamount{\def\lst@belowskip{#1}} +\lst@AddToHook{TextStyle} + {\let\lst@aboveskip\z@ \let\lst@belowskip\z@} +\lst@Key{everydisplay}{}{\def\lst@EveryDisplay{#1}} +\lst@AddToHook{TextStyle}{\let\lst@ifdisplaystyle\iffalse} +\lst@AddToHook{DisplayStyle}{\let\lst@ifdisplaystyle\iftrue} +\let\lst@ifdisplaystyle\iffalse +\def\lst@Init#1{% + \begingroup + \ifx\lst@float\relax\else + \edef\@tempa{\noexpand\lst@beginfloat{lstlisting}[\lst@float]}% + \expandafter\@tempa + \fi + \ifhmode\ifinner \lst@boxtrue \fi\fi + \lst@ifbox + \lsthk@BoxUnsafe + \hbox to\z@\bgroup + $\if t\lst@boxpos \vtop + \else \if b\lst@boxpos \vbox + \else \vcenter \fi\fi + \bgroup \par\noindent + \else + \lst@ifdisplaystyle + \lst@EveryDisplay + \par\penalty-50\relax + \vspace\lst@aboveskip + \fi + \fi + \normalbaselines + \abovecaptionskip\lst@abovecaption\relax + \belowcaptionskip\lst@belowcaption\relax + \lst@MakeCaption t% + \lsthk@PreInit \lsthk@Init + \lst@ifdisplaystyle + \global\let\lst@ltxlabel\@empty + \if@inlabel + \lst@ifresetmargins + \leavevmode + \else + \xdef\lst@ltxlabel{\the\everypar}% + \lst@AddTo\lst@ltxlabel{% + \global\let\lst@ltxlabel\@empty + \everypar{\lsthk@EveryLine\lsthk@EveryPar}}% + \fi + \fi + \everypar\expandafter{\lst@ltxlabel + \lsthk@EveryLine\lsthk@EveryPar}% + \else + \everypar{}\let\lst@NewLine\@empty + \fi + \lsthk@InitVars \lsthk@InitVarsBOL + \lst@Let{13}\lst@MProcessListing + \let\lst@Backslash#1% + \lst@EnterMode{\lst@Pmode}{\lst@SelectCharTable}} +\lst@AddToHook{InitVars} + {\rightskip\z@ \leftskip\z@ \parfillskip=\z@ plus 1fil + \let\par\@@par} +\lst@AddToHook{EveryLine}{}% init +\lst@AddToHook{EveryPar}{}% init +\lst@Key{showlines}f[t]{\lstKV@SetIf{#1}\lst@ifshowlines} +\def\lst@DeInit{% + \lst@XPrintToken \lst@EOLUpdate + \global\advance\lst@newlines\m@ne + \lst@ifshowlines + \lst@DoNewLines + \else + \setbox\@tempboxa\vbox{\lst@DoNewLines}% + \fi + \lst@ifdisplaystyle \par\removelastskip \fi + \everypar{}\lsthk@ExitVars \lsthk@DeInit + \lst@MakeCaption b% + \lst@ifbox + \egroup $\hss \egroup + \vrule\@width\lst@maxwidth\@height\z@\@depth\z@ + \else + \lst@ifdisplaystyle + \par\penalty-50\vspace\lst@belowskip + \fi + \fi + \ifx\lst@float\relax\else + \expandafter\lst@endfloat + \fi + \endgroup} +\newdimen\lst@maxwidth % \global +\lst@AddToHook{InitVars}{\global\lst@maxwidth\z@} +\lst@AddToHook{InitVarsEOL} + {\ifdim\lst@currlwidth>\lst@maxwidth + \global\lst@maxwidth\lst@currlwidth + \fi} +\def\lst@EOLUpdate{\lsthk@EOL \lsthk@InitVarsEOL} +\def\lst@MProcessListing{% + \lst@XPrintToken \lst@EOLUpdate \lsthk@InitVarsBOL + \global\advance\lst@lineno\@ne + \ifnum \lst@lineno>\lst@lastline + \expandafter\lst@EndProcessListing + \else + \expandafter\lst@BOLGobble + \fi} +\let\lst@EndProcessListing\endinput +\lst@Key{gobble}{0}{\def\lst@gobble{#1}} +\def\lst@BOLGobble{% + \ifnum\lst@gobble>\z@ + \@tempcnta\lst@gobble\relax + \expandafter\lst@BOLGobble@ +\fi} +\def\lst@BOLGobble@@{% + \ifnum\@tempcnta>\z@ + \expandafter\lst@BOLGobble@ + \fi} +\def\lstenv@BOLGobble@@{% + \lst@IfNextChars\lstenv@endstring{\lstenv@End}% + {\advance\@tempcnta\m@ne \expandafter\lst@BOLGobble@@\lst@eaten}} +\def\lst@BOLGobble@#1{% + \let\lst@next#1% + \ifx \lst@next\relax\else + \ifx \lst@next\lst@MProcessListing\else + \ifx \lst@next\lst@ProcessFormFeed\else + \ifx \lst@next\lstenv@backslash + \let\lst@next\lstenv@BOLGobble@@ + \else + \let\lst@next\lst@BOLGobble@@ + \ifx #1\lst@ProcessTabulator + \advance\@tempcnta-\lst@tabsize\relax + \ifnum\@tempcnta<\z@ + \lst@length-\@tempcnta \lst@PreGotoTabStop + \fi + \else + \advance\@tempcnta\m@ne + \fi + \fi \fi \fi \fi + \lst@next} +\lst@Key{name}\relax{\def\lst@intname{#1}} +\lst@AddToHookExe{PreSet}{\global\let\lst@intname\@empty} +\lst@AddToHook{PreInit}{% + \let\lst@arg\lst@intname \lst@ReplaceIn\lst@arg\lst@filenamerpl + \global\let\lst@name\lst@arg \global\let\lstname\lst@name} +\def\lst@filenamerpl{_\textunderscore $\textdollar -\textendash} +\def\l@lstlisting#1#2{\@dottedtocline{1}{1.5em}{2.3em}{#1}{#2}} +\lst@AddToHook{Init} + {\lst@ifnolol\else + \ifx\lst@@caption\@empty + \ifx\lst@caption\@empty + \ifx\lst@intname\@empty \else \def\lst@temp{ }% + \ifx\lst@intname\lst@temp \else + \addcontentsline{lol}{lstlisting}\lst@name + \fi\fi + \fi + \else + \addcontentsline{lol}{lstlisting}% + {\protect\numberline{\thelstlisting}\lst@@caption}% + \fi + \fi} +\lst@UserCommand\lstlistlistingname{Listings} +\lst@UserCommand\lstlistoflistings{\bgroup + \let\contentsname\lstlistlistingname + \let\lst@temp\@starttoc \def\@starttoc##1{\lst@temp{lol}}% + \tableofcontents \egroup} +\newcommand\lstinline[1][]{% + \leavevmode\bgroup % \hbox\bgroup --> \bgroup + \def\lst@boxpos{b}% + \lsthk@PreSet\lstset{flexiblecolumns,#1}% + \lsthk@TextStyle + \@ifnextchar\bgroup{\afterassignment\lst@InlineG \let\@let@token}% + \lstinline@} +\def\lstinline@#1{% + \lst@Init\relax + \lst@IfNextCharActive{\lst@InlineM#1}{\lst@InlineJ#1}} +\lst@AddToHook{TextStyle}{}% init +\lst@AddToHook{SelectCharTable}{\lst@inlinechars} +\global\let\lst@inlinechars\@empty +\def\lst@InlineM#1{\gdef\lst@inlinechars{% + \lst@Def{`#1}{\lst@DeInit\egroup\global\let\lst@inlinechars\@empty}% + \lst@Def{13}{\lst@DeInit\egroup \global\let\lst@inlinechars\@empty + \PackageError{Listings}{lstinline ended by EOL}\@ehc}}% + \lst@inlinechars} +\def\lst@InlineJ#1{% + \def\lst@temp##1#1{% + \let\lst@arg\@empty \lst@InsideConvert{##1}\lst@arg + \lst@DeInit\egroup}% + \lst@temp} +\def\lst@InlineG{% + \lst@Init\relax + \lst@IfNextCharActive{\lst@InlineM\}}% + {\let\lst@arg\@empty \lst@InlineGJ}} +\def\lst@InlineGJ{\futurelet\@let@token\lst@InlineGJTest} +\def\lst@InlineGJTest{% + \ifx\@let@token\egroup + \afterassignment\lst@InlineGJEnd + \expandafter\let\expandafter\@let@token + \else + \ifx\@let@token\@sptoken + \let\lst@next\lst@InlineGJReadSp + \else + \let\lst@next\lst@InlineGJRead + \fi + \expandafter\lst@next + \fi} +\def\lst@InlineGJEnd{\lst@arg\lst@DeInit\egroup} +\def\lst@InlineGJRead#1{% + \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% + \lst@InlineGJ} +\def\lst@InlineGJReadSp#1{% + \lccode`\~=`\ \lowercase{\lst@lAddTo\lst@arg~}% + \lst@InlineGJ#1} +\newcommand\lstinputlisting[2][]{% + \def\lst@set{#1}% + \IfFileExists{#2}% + {\lst@InputListing{#2}}% + {\filename@parse{#2}% + \edef\reserved@a{\noexpand\lst@MissingFileError + {\filename@area\filename@base}% + {\ifx\filename@ext\relax tex\else\filename@ext\fi}}% + \reserved@a}% + \@doendpe \@newlistfalse \ignorespaces} +\def\lst@MissingFileError#1#2{% + \typeout{^^J! Package Listings Error: File `#1.#2' not found.^^J^^J% + Type X to quit or to proceed,^^J% + or enter new name. (Default extension: #2)^^J}% + \message{Enter file name: }% + {\endlinechar\m@ne \global\read\m@ne to\@gtempa}% + \ifx\@gtempa\@empty \else + \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi + \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi + \filename@parse\@gtempa + \edef\filename@ext{% + \ifx\filename@ext\relax#2\else\filename@ext\fi}% + \edef\reserved@a{\noexpand\IfFileExists % + {\filename@area\filename@base.\filename@ext}% + {\noexpand\lst@InputListing % + {\filename@area\filename@base.\filename@ext}}% + {\noexpand\lst@MissingFileError + {\filename@area\filename@base}{\filename@ext}}}% + \expandafter\reserved@a % + \fi} +\let\lst@ifdraft\iffalse +\DeclareOption{draft}{\let\lst@ifdraft\iftrue} +\lst@AddToHook{PreSet} + {\lst@ifdraft + \let\lst@ifprint\iffalse + \@gobbletwo\fi\fi + \fi} +\def\lst@InputListing#1{% + \begingroup + \lsthk@PreSet \gdef\lst@intname{#1}% + \expandafter\lstset\expandafter{\lst@set}% + \lsthk@DisplayStyle + \lst@Init\relax \let\lst@gobble\z@ + \lst@SkipToFirst + \lst@ifprint \def\lst@next{\input{#1}}% + \else \let\lst@next\@empty \fi + \lst@next + \lst@DeInit + \endgroup} +\def\lst@SkipToFirst{% + \ifnum \lst@lineno<\lst@firstline + \lst@BeginDropInput\lst@Pmode + \lst@Let{13}\lst@MSkipToFirst + \lst@Let{10}\lst@MSkipToFirst + \else + \expandafter\lst@BOLGobble + \fi} +\def\lst@MSkipToFirst{% + \global\advance\lst@lineno\@ne + \ifnum \lst@lineno=\lst@firstline + \lst@LeaveMode \global\lst@newlines\z@ + \lsthk@InitVarsBOL + \expandafter\lst@BOLGobble + \fi} +\def\lstenv@DroppedWarning{% + \ifx\lst@dropped\@undefined\else + \PackageWarning{Listings}{Text dropped after begin of listing}% + \fi} +\let\lst@dropped\@undefined % init +\begingroup \lccode`\~=`\^^M\lowercase{% +\gdef\lstenv@Process#1{% + \ifx~#1% + \lstenv@DroppedWarning \let\lst@next\lst@SkipToFirst + \else\ifx^^J#1% + \lstenv@DroppedWarning \let\lst@next\lstenv@ProcessJ + \else + \let\lst@dropped#1\let\lst@next\lstenv@Process + \fi \fi + \lst@next} +}\endgroup +\def\lstenv@ProcessJ{% + \let\lst@arg\@empty + \ifx\@currenvir\lstenv@name + \expandafter\lstenv@ProcessJEnv + \else + \expandafter\def\expandafter\lst@temp\expandafter##1% + \csname end\lstenv@name\endcsname + {\lst@InsideConvert{##1}\lstenv@ProcessJ@}% + \expandafter\lst@temp + \fi} +\begingroup \lccode`\~=`\\\lowercase{% +\gdef\lstenv@ProcessJ@{% + \lst@lExtend\lst@arg + {\expandafter\ \expandafter~\lstenv@endstring}% + \catcode10=\active \lst@Let{10}\lst@MProcessListing + \lst@SkipToFirst \lst@arg} +}\endgroup +\def\lstenv@ProcessJEnv#1\end#2{\def\lst@temp{#2}% + \ifx\lstenv@name\lst@temp + \lst@InsideConvert{#1}% + \expandafter\lstenv@ProcessJ@ + \else + \lst@InsideConvert{#1\\end\{#2\}}% + \expandafter\lstenv@ProcessJEnv + \fi} +\def\lstenv@backslash{% + \lst@IfNextChars\lstenv@endstring + {\lstenv@End}% + {\expandafter\lsts@backslash \lst@eaten}}% +\def\lstenv@End{% + \ifx\@currenvir\lstenv@name + \edef\lst@next{\noexpand\end{\lstenv@name}}% + \else + \def\lst@next{\csname end\lstenv@name\endcsname}% + \fi + \lst@next} +\lst@UserCommand\lstnewenvironment#1#2#{% + \@ifundefined{#1}% + {\let\lst@arg\@empty + \lst@XConvert{#1}\@nil + \expandafter\lstnewenvironment@\lst@arg{#1}{#2}}% + {\PackageError{Listings}{Environment `#1' already defined}\@eha + \@gobbletwo}} +\def\@tempa#1#2#3{% +\gdef\lstnewenvironment@##1##2##3##4##5{% + \begingroup + \global\@namedef{end##2}{\lstenv@Error{##2}}% + \global\@namedef{##2}{\def\lstenv@name{##2}% + \begingroup \catcode\active=\active \csname##2@\endcsname}% + \let\l@ngrel@x\global + \let\@xargdef\lstenv@xargdef + \expandafter\new@command\csname##2@\endcsname##3% + {\lsthk@PreSet ##4% + \ifx\@currenvir\lstenv@name + \def\lstenv@endstring{#1#2##1#3}% + \else + \def\lstenv@endstring{#1##1}% + \fi + \@namedef{end##2}{\lst@DeInit ##5\endgroup + \@doendpe \@ignoretrue}% + \lsthk@DisplayStyle + \lst@Init\lstenv@backslash + \let\lst@EndProcessListing\lstenv@SkipToEnd + \lst@ifprint + \expandafter\expandafter\expandafter\lstenv@Process + \else + \expandafter\lstenv@SkipToEnd + \fi + \lst@insertargs}% + \endgroup}% +} +\let\lst@arg\@empty \lst@XConvert{end}\{\}\@nil +\expandafter\@tempa\lst@arg +\let\lst@insertargs\@empty +\def\lstenv@xargdef#1{ + \expandafter\lstenv@xargdef@\csname\string#1\endcsname#1} +\def\lstenv@xargdef@#1#2[#3][#4]#5{% + \@ifdefinable#2{% + \gdef#2{% + \ifx\protect\@typeset@protect + \expandafter\lstenv@testopt + \else + \@x@protect#2% + \fi + #1% + {#4}}% + \@yargdef + #1% + \tw@ + {#3}% + {#5}}} +\long\def\lstenv@testopt#1#2{% + \@ifnextchar[{\catcode\active5\relax \lstenv@testopt@#1}% + {#1[{#2}]}} +\def\lstenv@testopt@#1[#2]{% + \catcode\active\active + #1[#2]} +\begingroup \lccode`\~=`\\\lowercase{% +\gdef\lstenv@SkipToEnd{% + \long\expandafter\def\expandafter\lst@temp\expandafter##\expandafter + 1\expandafter~\lstenv@endstring{\lstenv@End}% + \lst@temp} +}\endgroup +\def\lstenv@Error#1{\PackageError{Listings}{Extra \string\end#1}% + {I'm ignoring this, since I wasn't doing a \csname#1\endcsname.}} +\begingroup \lccode`\~=`\^^M\lowercase{% +\gdef\lst@TestEOLChar#1{% + \def\lst@insertargs{#1}% + \ifx ~#1\@empty \else + \ifx^^J#1\@empty \else + \global\let\lst@intname\lst@insertargs + \let\lst@insertargs\@empty + \fi \fi} +}\endgroup +\lstnewenvironment{lstlisting}[2][] + {\lst@TestEOLChar{#2}% + \lstset{#1}% + \csname\@lst @SetFirstNumber\endcsname} + {\csname\@lst @SaveFirstNumber\endcsname} +\lst@Key{fancyvrb}\relax[t]{% + \lstKV@SetIf{#1}\lst@iffancyvrb + \lstFV@fancyvrb} +\ifx\lstFV@fancyvrb\@undefined + \gdef\lstFV@fancyvrb{\lst@RequireAspects{fancyvrb}\lstFV@fancyvrb} +\fi +\@ifundefined{ocp}{} + {\lst@AddToHook{OutputBox}% + {\let\lst@ProcessLetter\@firstofone + \let\lst@ProcessDigit\@firstofone + \let\lst@ProcessOther\@firstofone}} +\DeclareOption*{\expandafter\lst@ProcessOption\CurrentOption\relax} +\def\lst@ProcessOption#1#2\relax{% + \ifx #1!% + \lst@DeleteKeysIn\lst@loadaspects{#2}% + \else + \lst@lAddTo\lst@loadaspects{,#1#2}% + \fi} +\@ifundefined{lst@loadaspects} + {\def\lst@loadaspects{strings,comments,escape,style,language,% + keywords,labels,lineshape,frames,emph,index}% + }{} +\InputIfFileExists{lstpatch.sty}{}{} +\let\lst@ifsavemem\iffalse +\DeclareOption{savemem}{\let\lst@ifsavemem\iftrue} +\DeclareOption{noaspects}{\let\lst@loadaspects\@empty} +\ProcessOptions +\lst@RequireAspects\lst@loadaspects +\let\lst@loadaspects\@empty +\lst@UseHook{SetStyle}\lst@UseHook{EmptyStyle} +\lst@UseHook{SetLanguage}\lst@UseHook{EmptyLanguage} +\InputIfFileExists{listings.cfg}{}{} +\InputIfFileExists{lstlocal.cfg}{}{} +\endinput +%% +%% End of file `listings.sty'. diff --git a/doc/user/lstdoc.sty b/doc/user/lstdoc.sty new file mode 100644 index 0000000000..82f7b4728a --- /dev/null +++ b/doc/user/lstdoc.sty @@ -0,0 +1,466 @@ +%% +%% This is file `lstdoc.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% listings.dtx (with options: `doc') +%% +%% Please read the software license in listings.dtx or listings.dvi. +%% +%% (w)(c) 1996 -- 2002 Carsten Heinz and/or any other author +%% listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% Permission is granted to modify the listings package as well as +%% lstdrvrs.dtx. You are not allowed to distribute a modified version +%% of the package or lstdrvrs.dtx unless you change the file names and +%% provide the original files. In any case it is better to contact the +%% address below; other users will welcome removed bugs, new features, +%% and additional programming languages. +%% +%% The listings package is free software. +%% +%% However, if you distribute the package as part of a commercial +%% product or if you use the package to prepare a commercial document +%% (books, journals, and so on), I'd like to encourage you to make a +%% donation to the LaTeX3 fund. The size of this `license fee' should +%% depend on the value of the package for your product. For more +%% information about LaTeX see http://www.latex-project.org +%% +%% No matter whether you use the package for a commercial or +%% non-commercial document, please send me a copy of the document (.dvi, +%% .ps, .pdf, hardcopy, etc.) to support further development---it is +%% easier to introduce new features or simplify things if I see how the +%% package is used by other people. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\def\filedate{2002/04/01} +\def\fileversion{1.0} +\ProvidesPackage{lstdoc} + [\filedate\space\fileversion\space(Carsten Heinz)] +\let\lstdoc@currversion\fileversion +\RequirePackage[writefile]{listings}[2002/04/01] +\newif\iffancyvrb \IfFileExists{fancyvrb.sty}{\fancyvrbtrue}{} +\newif\ifcolor \IfFileExists{color.sty}{\colortrue}{} +\newif\ifhyper \@ifundefined{pdfoutput}{} + {\IfFileExists{hyperref.sty}{\hypertrue}{}} +\newif\ifalgorithmic \IfFileExists{algorithmic.sty}{\algorithmictrue}{} +\iffancyvrb \RequirePackage{fancyvrb}\fi +\ifhyper \RequirePackage[colorlinks]{hyperref}\else + \def\href#1{\texttt}\fi +\ifcolor \RequirePackage{color}\fi +\ifalgorithmic \RequirePackage{algorithmic}\fi +\RequirePackage{nameref} +\renewcommand\ref{\protect\T@ref} +\renewcommand\pageref{\protect\T@pageref} +\def\lst@BeginRemark#1{% + \begin{quote}\topsep0pt\let\small\footnotesize\small#1:} +\def\lst@EndRemark{\end{quote}} +\newenvironment{TODO} + {\lst@BeginRemark{To do}}{\lst@EndRemark} +\newenvironment{ALTERNATIVE} + {\lst@BeginRemark{Alternative}}{\lst@EndRemark} +\newenvironment{REMOVED} + {\lst@BeginRemark{Removed}}{\lst@EndRemark} +\newenvironment{OLDDEF} + {\lst@BeginRemark{Old definition}}{\lst@EndRemark} +\def\advise{\par\list\labeladvise + {\advance\linewidth\@totalleftmargin + \@totalleftmargin\z@ + \@listi + \let\small\footnotesize \small\sffamily + \parsep \z@ \@plus\z@ \@minus\z@ + \topsep6\p@ \@plus1\p@\@minus2\p@ + \def\makelabel##1{\hss\llap{##1}}}} +\let\endadvise\endlist +\def\advisespace{\hbox{}\qquad} +\def\labeladvise{$\to$} +\newenvironment{syntax} + {\list{}{\itemindent-\leftmargin + \def\makelabel##1{\hss\lst@syntaxlabel##1,,,,\relax}}} + {\endlist} +\def\lst@syntaxlabel#1,#2,#3,#4\relax{% + \llap{\scriptsize\itshape#3}% + \def\lst@temp{#2}% + \expandafter\lst@syntaxlabel@\meaning\lst@temp\relax + \rlap{\hskip-\itemindent\hskip\itemsep\hskip\linewidth + \llap{\ttfamily\lst@temp}\hskip\labelwidth + \def\lst@temp{#1}% + \ifx\lst@temp\lstdoc@currversion#1\fi}} +\def\lst@syntaxlabel@#1>#2\relax + {\edef\lst@temp{\zap@space#2 \@empty}} +\newcommand*\syntaxnewline{\newline\hbox{}\kern\labelwidth} +\newcommand*\syntaxor{\qquad or\qquad} +\newcommand*\syntaxbreak + {\hfill\kern0pt\discretionary{}{\kern\labelwidth}{}} +\let\syntaxfill\hfill +\def\alternative#1{\lst@true \alternative@#1,\relax,} +\def\alternative@#1,{% + \ifx\relax#1\@empty + \expandafter\@gobble + \else + \ifx\@empty#1\@empty\else + \lst@if \lst@false \else $\vert$\fi + \textup{\texttt{#1}}% + \fi + \fi + \alternative@} +\long\def\m@cro@#1#2#3{\endgroup \topsep\MacroTopsep \trivlist + \edef\saved@macroname{\string#3}% + \def\makelabel##1{\llap{##1}}% + \if@inlabel + \let\@tempa\@empty \count@\macro@cnt + \loop \ifnum\count@>\z@ + \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat + \edef\makelabel##1{\llap{\vtop to\baselineskip + {\@tempa\hbox{##1}\vss}}}% + \advance \macro@cnt \@ne + \else \macro@cnt\@ne \fi + \edef\@tempa{\noexpand\item[% + #1% + \noexpand\PrintMacroName + \else + \expandafter\noexpand\csname Print#2Name\endcsname % MODIFIED + \fi + {\string#3}]}% + \@tempa + \global\advance\c@CodelineNo\@ne + #1% + \SpecialMainIndex{#3}\nobreak + \DoNotIndex{#3}% + \else + \csname SpecialMain#2Index\endcsname{#3}\nobreak % MODIFIED + \fi + \global\advance\c@CodelineNo\m@ne + \ignorespaces} +\def\macro{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \iftrue {Macro}}% MODIFIED +\def\environment{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \iffalse {Env}}% MODIFIED +\def\newdocenvironment#1#2#3#4{% + \@namedef{#1}{#3\begingroup \catcode`\\12\relax + \MakePrivateLetters \m@cro@ \iffalse {#2}}% + \@namedef{end#1}{#4\endmacro}% + \@ifundefined{Print#2Name}{\expandafter + \let\csname Print#2Name\endcsname\PrintMacroName}{}% + \@ifundefined{SpecialMain#2Index}{\expandafter + \let\csname SpecialMain#2Index\endcsname\SpecialMainIndex}{}} +\newdocenvironment{aspect}{Aspect}{}{} +\def\PrintAspectName#1{} +\def\SpecialMainAspectIndex#1{% + \@bsphack + \index{aspects:\levelchar\protect\aspectname{#1}\encapchar main}% + \@esphack} +\newdocenvironment{lstkey}{Key}{}{} +\def\PrintKeyName#1{\strut\keyname{#1}\ } +\def\SpecialMainKeyIndex#1{% + \@bsphack + \index{keys\levelchar\protect\keyname{#1}\encapchar main}% + \@esphack} +\newcounter{argcount} +\def\labelargcount{\texttt{\#\arabic{argcount}}\hskip\labelsep$=$} +\def\macroargs{\list\labelargcount + {\usecounter{argcount}\leftmargin=2\leftmargin + \parsep \z@ \@plus\z@ \@minus\z@ + \topsep4\p@ \@plus\p@ \@minus2\p@ + \itemsep\z@ \@plus\z@ \@minus\z@ + \def\makelabel##1{\hss\llap{##1}}}} +\def\endmacroargs{\endlist\@endparenv} +\lst@RequireAspects{writefile} +\newbox\lst@samplebox +\lstnewenvironment{lstsample}[3][] + {\global\let\lst@intname\@empty + \gdef\lst@sample{#2}% + \setbox\lst@samplebox=\hbox\bgroup + \setkeys{lst}{language={},style={},tabsize=4,gobble=5,% + basicstyle=\small\ttfamily,basewidth=0.51em,point={#1}} + #3% + \lst@BeginAlsoWriteFile{\jobname.tmp}} + {\lst@EndWriteFile\egroup + \ifdim \wd\lst@samplebox>.5\linewidth + \begin{center}% + \hbox to\linewidth{\box\lst@samplebox\hss}% + \end{center}% + \lst@sampleInput + \else + \begin{center}% + \begin{minipage}{0.45\linewidth}\lst@sampleInput\end{minipage}% + \qquad + \begin{minipage}{0.45\linewidth}% + \hbox to\linewidth{\box\lst@samplebox\hss}% + \end{minipage}% + \end{center}% + \fi} +\lst@InstallKeywords{p}{point}{pointstyle}\relax{keywordstyle}{}ld +\lstnewenvironment{lstxsample}[1][] + {\begingroup + \setkeys{lst}{belowskip=-\medskipamount,language={},style={},% + tabsize=4,gobble=5,basicstyle=\small\ttfamily,% + basewidth=0.51em,point={#1}} + \lst@BeginAlsoWriteFile{\jobname.tmp}} + {\endgroup + \endgroup} +\def\lst@sampleInput{% + \MakePercentComment\catcode`\^^M=10\relax + \small\lst@sample + {\setkeys{lst}{SelectCharTable=\lst@ReplaceInput{\^\^I}% + {\lst@ProcessTabulator}}% + \leavevmode \input{\jobname.tmp}}\MakePercentIgnore} +\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}% + {1.25ex \@plus1ex \@minus.2ex}% + {-1em}% + {\normalfont\normalsize\bfseries}} +\def\lstref#1{\emph{\ref{#1} \nameref{#1}}} +\def\@part[#1]#2{\addcontentsline{toc}{part}{#1}% + {\parindent\z@ \raggedright \interlinepenalty\@M + \normalfont \huge \bfseries #2\markboth{}{}\par}% + \nobreak\vskip 3ex\@afterheading} +\renewcommand*\l@section[2]{% + \addpenalty\@secpenalty + \addvspace{.25em \@plus\p@}% + \setlength\@tempdima{1.5em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \endgroup} +\renewcommand*\l@subsection{\@dottedtocline{2}{0pt}{2.3em}} +\renewcommand*\l@subsubsection{\@dottedtocline{3}{0pt}{3.2em}} +\newcommand\ikeyname[1]{% + \lstkeyindex{#1}{}% + \lstaspectindex{#1}{}% + \keyname{#1}} +\newcommand\ekeyname[1]{% + \@bsphack + \lstkeyindex{#1}{\encapchar usage}% + \lstaspectindex{#1}{\encapchar usage}% + \@esphack} +\newcommand\rkeyname[1]{% + \@bsphack + \lstkeyindex{#1}{\encapchar main}% + \lstaspectindex{#1}{\encapchar main}% + \@esphack{\rstyle\keyname{#1}}} +\newcommand\icmdname[1]{% + \@bsphack + \lstaspectindex{#1}{}% + \@esphack\texttt{\string#1}} +\newcommand\rcmdname[1]{% + \@bsphack + \lstaspectindex{#1}{\encapchar main}% + \@esphack\texttt{\rstyle\string#1}} +\def\lstaspectindex#1#2{% + \global\@namedef{lstkandc@\string#1}{}% + \@ifundefined{lstisaspect@\string#1} + {\index{unknown\levelchar + \protect\texttt{\protect\string\string#1}#2}}% + {\index{\@nameuse{lstisaspect@\string#1}\levelchar + \protect\texttt{\protect\string\string#1}#2}}% +} +\def\lstkeyindex#1#2{% +} +\def\lstisaspect[#1]#2{% + \global\@namedef{lstaspect@#1}{#2}% + \lst@AddTo\lst@allkeysandcmds{,#2}% + \@for\lst@temp:=#2\do + {\ifx\@empty\lst@temp\else + \global\@namedef{lstisaspect@\lst@temp}{#1}% + \fi}} +\gdef\lst@allkeysandcmds{} +\def\lstprintaspectkeysandcmds#1{% + \lst@true + \expandafter\@for\expandafter\lst@temp + \expandafter:\expandafter=\csname lstaspect@#1\endcsname\do + {\lst@if\lst@false\else, \fi \texttt{\lst@temp}}} +\def\lstcheckreference{% + \@for\lst@temp:=\lst@allkeysandcmds\do + {\ifx\lst@temp\@empty\else + \@ifundefined{lstkandc@\lst@temp} + {\typeout{\lst@temp\space not in reference guide?}}{}% + \fi}} +\newcommand*\lst{\texttt{lst}} +\newcommand*\Cpp{C\texttt{++}} +\let\keyname\texttt +\let\keyvalue\texttt +\let\hookname\texttt +\newcommand*\aspectname[1]{{\normalfont\sffamily#1}} +\DeclareRobustCommand\packagename[1]{% + {\leavevmode\text@command{#1}% + \switchfontfamily\sfdefault\rmdefault + \check@icl #1\check@icr + \expandafter}}% +\def\switchfontfamily#1#2{% + \begingroup\xdef\@gtempa{#1}\endgroup + \ifx\f@family\@gtempa\fontfamily#2% + \else\fontfamily#1\fi + \selectfont} +\ifcolor + \definecolor{darkgreen}{rgb}{0,0.6,0} + \def\rstyle{\color{darkgreen}} +\else + \let\rstyle\empty +\fi +\gdef\lst@emails{} +\newcommand*\lstthanks[2] + {#1\lst@AddTo\lst@emails{,#1,<#2>}% + \ifx\@empty#2\@empty\typeout{Missing email for #1}\fi} +\newcommand*\lsthelper[3] + {{\let~\ #1}% + \lst@IfOneOf#1\relax\lst@emails + {}{\typeout{^^JWarning: Unknown helper #1.^^J}}} +\lstdefinelanguage[doc]{Pascal}{% + morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,% + do,downto,else,end,false,file,for,function,get,goto,if,in,% + integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% + procedure,put,read,readln,real,record,repeat,reset,rewrite,set,% + text,then,to,true,type,unpack,until,var,while,with,write,writeln},% + sensitive=false,% + morecomment=[s]{(*}{*)},% + morecomment=[s]{\{}{\}},% + morestring=[d]{'}} +\lstdefinestyle{} + {basicstyle={},% + keywordstyle=\bfseries,identifierstyle={},% + commentstyle=\itshape,stringstyle={},% + numberstyle={},stepnumber=1,% + pointstyle=\pointstyle} +\def\pointstyle{% + {\let\lst@um\@empty \xdef\@gtempa{\the\lst@token}}% + \expandafter\lstkeyindex\expandafter{\@gtempa}{}% + \expandafter\lstaspectindex\expandafter{\@gtempa}{}% + \rstyle} +\lstset{defaultdialect=[doc]Pascal,language=Pascal,style={}} +\def\lstscanlanguages#1#2#3{% + \begingroup + \def\lst@DefDriver@##1##2##3##4[##5]##6{% + \lst@false + \lst@lAddTo\lst@scan{##6(##5),}% + \begingroup + \@ifnextchar[{\lst@XDefDriver{##1}##3}{\lst@DefDriver@@##3}}% + \def\lst@XXDefDriver[##1]{}% + \lst@InputCatcodes + \def\lst@dontinput{#3}% + \let\lst@scan\@empty + \lst@for{#2}\do{% + \lst@IfOneOf##1\relax\lst@dontinput + {}% + {\InputIfFileExists{##1}{}{}}}% + \global\let\@gtempa\lst@scan + \endgroup + \let#1\@gtempa} +\def\lstprintlanguages#1{% + \def\do##1{\setbox\@tempboxa\hbox{##1\space\space}% + \ifdim\wd\@tempboxa<.5\linewidth \wd\@tempboxa.5\linewidth + \else \wd\@tempboxa\linewidth \fi + \box\@tempboxa\allowbreak}% + \begin{quote} + \par\noindent + \hyphenpenalty=\@M \rightskip=\z@\@plus\linewidth\relax + \lst@BubbleSort#1% + \expandafter\lst@NextLanguage#1\relax(\relax),% + \end{quote}} +\def\lst@NextLanguage#1(#2),{% + \ifx\relax#1\else + \def\lst@language{#1}\def\lst@dialects{(#2),}% + \expandafter\lst@NextLanguage@ + \fi} +\def\lst@NextLanguage@#1(#2),{% + \def\lst@temp{#1}% + \ifx\lst@temp\lst@language + \lst@lAddTo\lst@dialects{(#2),}% + \expandafter\lst@NextLanguage@ + \else + \do{\lst@language + \ifx\lst@dialects\lst@emptydialect\else + \expandafter\lst@NormedDef\expandafter\lst@language + \expandafter{\lst@language}% + \space(% + \lst@BubbleSort\lst@dialects + \expandafter\lst@PrintDialects\lst@dialects(\relax),% + )% + \fi}% + \def\lst@next{\lst@NextLanguage#1(#2),}% + \expandafter\lst@next + \fi} +\def\lst@emptydialect{(),} +\def\lst@PrintDialects(#1),{% + \ifx\@empty#1\@empty empty\else + \lst@PrintDialect{#1}% + \fi + \lst@PrintDialects@} +\def\lst@PrintDialects@(#1),{% + \ifx\relax#1\else + , \lst@PrintDialect{#1}% + \expandafter\lst@PrintDialects@ + \fi} +\def\lst@PrintDialect#1{% + \lst@NormedDef\lst@temp{#1}% + \expandafter\ifx\csname\@lst dd@\lst@language\endcsname\lst@temp + \texttt{\underbar{#1}}% + \else + \texttt{#1}% + \fi} +\def\lst@IfLE#1#2\@empty#3#4\@empty{% + \ifx #1\relax + \let\lst@next\@firstoftwo + \else \ifx #3\relax + \let\lst@next\@secondoftwo + \else + \lowercase{\ifx#1#3}% + \def\lst@next{\lst@IfLE#2\@empty#4\@empty}% + \else + \lowercase{\ifnum`#1<`#3}\relax + \let\lst@next\@firstoftwo + \else + \let\lst@next\@secondoftwo + \fi + \fi + \fi \fi + \lst@next} +\def\lst@BubbleSort#1{% + \ifx\@empty#1\else + \lst@false + \expandafter\lst@BubbleSort@#1\relax,\relax,% + \expandafter\lst@BubbleSort@\expandafter,\lst@sorted + \relax,\relax,% + \let#1\lst@sorted + \lst@if + \def\lst@next{\lst@BubbleSort#1}% + \expandafter\expandafter\expandafter\lst@next + \fi + \fi} +\def\lst@BubbleSort@#1,#2,{% + \ifx\@empty#1\@empty + \def\lst@sorted{#2,}% + \def\lst@next{\lst@BubbleSort@@}% + \else + \let\lst@sorted\@empty + \def\lst@next{\lst@BubbleSort@@#1,#2,}% + \fi + \lst@next} +\def\lst@BubbleSort@@#1,#2,{% + \ifx\relax#1\else + \ifx\relax#2% + \lst@lAddTo\lst@sorted{#1,}% + \expandafter\expandafter\expandafter\lst@BubbleSort@@@ + \else + \lst@IfLE #1\relax\@empty #2\relax\@empty + {\lst@lAddTo\lst@sorted{#1,#2,}}% + {\lst@true \lst@lAddTo\lst@sorted{#2,#1,}}% + \expandafter\expandafter\expandafter\lst@BubbleSort@@ + \fi + \fi} +\def\lst@BubbleSort@@@#1\relax,{} +\endinput +%% +%% End of file `lstdoc.sty'. diff --git a/doc/user/lstlang1.sty b/doc/user/lstlang1.sty new file mode 100644 index 0000000000..082e87c6d8 --- /dev/null +++ b/doc/user/lstlang1.sty @@ -0,0 +1,882 @@ +%% +%% This is file `lstlang1.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% lstdrvrs.dtx (with options: `lang1') +%% +%% (w)(c) 1996/1997/1998/1999/2000/2001/2002 Carsten Heinz and/or any +%% other author listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\ProvidesFile{lstlang1} + [2002/07/31 v1.0d listings language file] +%% +%% ACSL definition (c) 2000 by Andreas Matthias +%% +\lst@definelanguage{ACSL}[90]{Fortran}% + {morekeywords={algorithm,cinterval,constant,derivative,discrete,% + dynamic,errtag,initial,interval,maxterval,minterval,% + merror,xerror,nsteps,procedural,save,schedule,sort,% + table,terminal,termt,variable},% + sensitive=false,% + morecomment=[l]!% + }[keywords, comments]% +%% +%% Ada 95 definition (c) Torsten Neuer +%% +\lst@definelanguage[95]{Ada}[83]{Ada}% + {morekeywords={abstract,aliased,protected,requeue,tagged,until}}% +\lst@definelanguage[83]{Ada}% + {morekeywords={abort,abs,accept,access,all,and,array,at,begin,body,% + case,constant,declare,delay,delta,digits,do,else,elsif,end,entry,% + exception,exit,for,function,generic,goto,if,in,is,limited,loop,% + mod,new,not,null,of,or,others,out,package,pragma,private,% + procedure,raise,range,record,rem,renames,return,reverse,select,% + separate,subtype,task,terminate,then,type,use,when,while,with,% + xor},% + sensitive=f,% + morecomment=[l]--,% + morestring=[m]",% percent not defined as stringizer so far + morestring=[m]'% + }[keywords,comments,strings]% +%% +%% Visual Basic definition (c) 2002 Robert Frank +%% +\lst@definelanguage[Visual]{Basic} + {morekeywords={Abs,Array,Asc,AscB,AscW,Atn,Avg,CBool,CByte,CCur,% + CDate,CDbl,Cdec,Choose,Chr,ChrB,ChrW,CInt,CLng,Command,Cos,% + Count,CreateObject,CSng,CStr,CurDir,CVar,CVDate,CVErr,Date,% + DateAdd,DateDiff,DatePart,DateSerial,DateValue,Day,DDB,Dir,% + DoEvents,Environ,EOF,Error,Exp,FileAttr,FileDateTime,FileLen,% + Fix,Format,FreeFile,FV,GetAllStrings,GetAttr,% + GetAutoServerSettings,GetObject,GetSetting,Hex,Hour,IIf,% + IMEStatus,Input,InputB,InputBox,InStr,InstB,Int,Integer,IPmt,% + IsArray,IsDate,IsEmpty,IsError,IsMissing,IsNull,IsNumeric,% + IsObject,LBound,LCase,Left,LeftB,Len,LenB,LoadPicture,Loc,LOF,% + Log,Ltrim,Max,Mid,MidB,Min,Minute,MIRR,Month,MsgBox,Now,NPer,% + NPV,Oct,Partition,Pmt,PPmt,PV,QBColor,Rate,RGB,Right,RightB,Rnd,% + Rtrim,Second,Seek,Sgn,Shell,Sin,SLN,Space,Spc,Sqr,StDev,StDevP,% + Str,StrComp,StrConv,String,Switch,Sum,SYD,Tab,Tan,Time,Timer,% + TimeSerial,TimeValue,Trim,TypeName,UBound,Ucase,Val,Var,VarP,% + VarType,Weekday,Year},% functions + morekeywords=[2]{Accept,Activate,Add,AddCustom,AddFile,AddFromFile,% + AddFromTemplate,AddItem,AddNew,AddToAddInToolbar,% + AddToolboxProgID,Append,AppendChunk,Arrange,Assert,AsyncRead,% + BatchUpdate,BeginTrans,Bind,Cancel,CancelAsyncRead,CancelBatch,% + CancelUpdate,CanPropertyChange,CaptureImage,CellText,CellValue,% + Circle,Clear,ClearFields,ClearSel,ClearSelCols,Clone,Close,Cls,% + ColContaining,ColumnSize,CommitTrans,CompactDatabase,Compose,% + Connect,Copy,CopyQueryDef,CreateDatabase,CreateDragImage,% + CreateEmbed,CreateField,CreateGroup,CreateIndex,CreateLink,% + CreatePreparedStatement,CreatePropery,CreateQuery,% + CreateQueryDef,CreateRelation,CreateTableDef,CreateUser,% + CreateWorkspace,Customize,Delete,DeleteColumnLabels,% + DeleteColumns,DeleteRowLabels,DeleteRows,DoVerb,Drag,Draw,Edit,% + EditCopy,EditPaste,EndDoc,EnsureVisible,EstablishConnection,% + Execute,ExtractIcon,Fetch,FetchVerbs,Files,FillCache,Find,% + FindFirst,FindItem,FindLast,FindNext,FindPrevious,Forward,% + GetBookmark,GetChunk,GetClipString,GetData,GetFirstVisible,% + GetFormat,GetHeader,GetLineFromChar,GetNumTicks,GetRows,% + GetSelectedPart,GetText,GetVisibleCount,GoBack,GoForward,Hide,% + HitTest,HoldFields,Idle,InitializeLabels,InsertColumnLabels,% + InsertColumns,InsertObjDlg,InsertRowLabels,InsertRows,Item,% + KillDoc,Layout,Line,LinkExecute,LinkPoke,LinkRequest,LinkSend,% + Listen,LoadFile,LoadResData,LoadResPicture,LoadResString,% + LogEvent,MakeCompileFile,MakeReplica,MoreResults,Move,MoveData,% + MoveFirst,MoveLast,MoveNext,MovePrevious,NavigateTo,NewPage,% + NewPassword,NextRecordset,OLEDrag,OnAddinsUpdate,OnConnection,% + OnDisconnection,OnStartupComplete,Open,OpenConnection,% + OpenDatabase,OpenQueryDef,OpenRecordset,OpenResultset,OpenURL,% + Overlay,PaintPicture,Paste,PastSpecialDlg,PeekData,Play,Point,% + PopulatePartial,PopupMenu,Print,PrintForm,PropertyChanged,Pset,% + Quit,Raise,RandomDataFill,RandomFillColumns,RandomFillRows,% + rdoCreateEnvironment,rdoRegisterDataSource,ReadFromFile,% + ReadProperty,Rebind,ReFill,Refresh,RefreshLink,RegisterDatabase,% + Reload,Remove,RemoveAddInFromToolbar,RemoveItem,Render,% + RepairDatabase,Reply,ReplyAll,Requery,ResetCustom,% + ResetCustomLabel,ResolveName,RestoreToolbar,Resync,Rollback,% + RollbackTrans,RowBookmark,RowContaining,RowTop,Save,SaveAs,% + SaveFile,SaveToFile,SaveToolbar,SaveToOle1File,Scale,ScaleX,% + ScaleY,Scroll,Select,SelectAll,SelectPart,SelPrint,Send,% + SendData,Set,SetAutoServerSettings,SetData,SetFocus,SetOption,% + SetSize,SetText,SetViewport,Show,ShowColor,ShowFont,ShowHelp,% + ShowOpen,ShowPrinter,ShowSave,ShowWhatsThis,SignOff,SignOn,Size,% + Span,SplitContaining,StartLabelEdit,StartLogging,Stop,% + Synchronize,TextHeight,TextWidth,ToDefaults,TwipsToChartPart,% + TypeByChartType,Update,UpdateControls,UpdateRecord,UpdateRow,% + Upto,WhatsThisMode,WriteProperty,ZOrder},% methods + morekeywords=[3]{AccessKeyPress,AfterAddFile,AfterChangeFileName,% + AfterCloseFile,AfterColEdit,AfterColUpdate,AfterDelete,% + AfterInsert,AfterLabelEdit,AfterRemoveFile,AfterUpdate,% + AfterWriteFile,AmbienChanged,ApplyChanges,Associate,% + AsyncReadComplete,AxisActivated,AxisLabelActivated,% + AxisLabelSelected,AxisLabelUpdated,AxisSelected,% + AxisTitleActivated,AxisTitleSelected,AxisTitleUpdated,% + AxisUpdated,BeforeClick,BeforeColEdit,BeforeColUpdate,% + BeforeConnect,BeforeDelete,BeforeInsert,BeforeLabelEdit,% + BeforeLoadFile,BeforeUpdate,ButtonClick,ButtonCompleted,% + ButtonGotFocus,ButtonLostFocus,Change,ChartActivated,% + ChartSelected,ChartUpdated,Click,ColEdit,Collapse,ColResize,% + ColumnClick,Compare,ConfigChageCancelled,ConfigChanged,% + ConnectionRequest,DataArrival,DataChanged,DataUpdated,DblClick,% + Deactivate,DeviceArrival,DeviceOtherEvent,DeviceQueryRemove,% + DeviceQueryRemoveFailed,DeviceRemoveComplete,DeviceRemovePending,% + DevModeChange,Disconnect,DisplayChanged,Dissociate,% + DoGetNewFileName,Done,DonePainting,DownClick,DragDrop,DragOver,% + DropDown,EditProperty,EnterCell,EnterFocus,Event,ExitFocus,% + Expand,FootnoteActivated,FootnoteSelected,FootnoteUpdated,% + GotFocus,HeadClick,InfoMessage,Initialize,IniProperties,% + ItemActivated,ItemAdded,ItemCheck,ItemClick,ItemReloaded,% + ItemRemoved,ItemRenamed,ItemSeletected,KeyDown,KeyPress,KeyUp,% + LeaveCell,LegendActivated,LegendSelected,LegendUpdated,% + LinkClose,LinkError,LinkNotify,LinkOpen,Load,LostFocus,% + MouseDown,MouseMove,MouseUp,NodeClick,ObjectMove,% + OLECompleteDrag,OLEDragDrop,OLEDragOver,OLEGiveFeedback,% + OLESetData,OLEStartDrag,OnAddNew,OnComm,Paint,PanelClick,% + PanelDblClick,PathChange,PatternChange,PlotActivated,% + PlotSelected,PlotUpdated,PointActivated,PointLabelActivated,% + PointLabelSelected,PointLabelUpdated,PointSelected,% + PointUpdated,PowerQuerySuspend,PowerResume,PowerStatusChanged,% + PowerSuspend,QueryChangeConfig,QueryComplete,QueryCompleted,% + QueryTimeout,QueryUnload,ReadProperties,Reposition,% + RequestChangeFileName,RequestWriteFile,Resize,ResultsChanged,% + RowColChange,RowCurrencyChange,RowResize,RowStatusChanged,% + SelChange,SelectionChanged,SendComplete,SendProgress,% + SeriesActivated,SeriesSelected,SeriesUpdated,SettingChanged,% + SplitChange,StateChanged,StatusUpdate,SysColorsChanged,% + Terminate,TimeChanged,TitleActivated,TitleSelected,% + TitleActivated,UnboundAddData,UnboundDeleteRow,% + UnboundGetRelativeBookmark,UnboundReadData,UnboundWriteData,% + Unload,UpClick,Updated,Validate,ValidationError,WillAssociate,% + WillChangeData,WillDissociate,WillExecute,WillUpdateRows,% + WithEvents,WriteProperties},% VB-events + morekeywords=[4]{AppActivate,Base,Beep,Call,Case,ChDir,ChDrive,% + Const,Declare,DefBool,DefByte,DefCur,DefDate,DefDbl,DefDec,% + DefInt,DefLng,DefObj,DefSng,DefStr,Deftype,DefVar,DeleteSetting,% + Dim,Do,Else,ElseIf,End,Enum,Erase,Event,Exit,Explicit,FileCopy,% + For,ForEach,Friend,Function,Get,GoSub,GoTo,If,Implements,Kill,% + Let,LineInput,Lock,Lset,MkDir,Name,Next,OnError,On,Option,% + Private,Property,Public,Put,RaiseEvent,Randomize,ReDim,Rem,% + Reset,Resume,Return,RmDir,Rset,SavePicture,SaveSetting,% + SendKeys,SetAttr,Static,Sub,Then,Type,Unlock,Wend,While,Width,% + With,Write},% statements + sensitive=false, + keywordcomment=rem,% + MoreSelectCharTable=\def\lst@BeginKC@{% chmod + \lst@ResetToken + \lst@BeginComment\lst@GPmode{{\lst@commentstyle}% + \lst@Lmodetrue\lst@modetrue}\@empty}% + morecomment=[l]{'}, + morecomment=[s]{/*}{*/}, + morestring=[b]", + }[keywords,comments,strings,keywordcomments] +\lst@definelanguage[ANSI]{C++}[ISO]{C++}{}% +\lst@definelanguage[GNU]{C++}[ISO]{C++}% + {morekeywords={__attribute__,__extension__,__restrict,__restrict__,% + typeof,__typeof__},% + }% +\lst@definelanguage[Visual]{C++}[ISO]{C++}% + {morekeywords={__asm,__based,__cdecl,__declspec,dllexport,% + dllimport,__except,__fastcall,__finally,__inline,__int8,__int16,% + __int32,__int64,naked,__stdcall,thread,__try,__leave},% + }% +\lst@definelanguage[ISO]{C++}[ANSI]{C}% + {morekeywords={and,and_eq,asm,bad_cast,bad_typeid,bitand,bitor,bool,% + catch,class,compl,const_cast,delete,dynamic_cast,explicit,export,% + false,friend,inline,mutable,namespace,new,not,not_eq,operator,or,% + or_eq,private,protected,public,reinterpret_cast,static_cast,% + template,this,throw,true,try,typeid,type_info,typename,using,% + virtual,wchar_t,xor,xor_eq},% + }% +%% +%% Objective-C definition (c) 1997 Detlev Droege +%% +%% +\lst@definelanguage[Objective]{C}[ANSI]{C} + {morekeywords={bycopy,id,in,inout,oneway,out,self,super,% + @class,@defs,@encode,@end,@implementation,@interface,@private,% + @protected,@protocol,@public,@selector},% + moredirectives={import}% + }% +\lst@definelanguage[ANSI]{C}% + {morekeywords={auto,break,case,char,const,continue,default,do,double,% + else,enum,extern,float,for,goto,if,int,long,register,return,% + short,signed,sizeof,static,struct,switch,typedef,union,unsigned,% + void,volatile,while},% + sensitive,% + morecomment=[s]{/*}{*/},% + morecomment=[l]//,% nonstandard + morestring=[b]",% + morestring=[b]',% + moredirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% + include,pragma,undef,warning}% + }[keywords,comments,strings,directives]% +%% +%% C-Sharp definition (c) 2002 Martin Brodbeck +%% +\lst@definelanguage[Sharp]{C}% + {morekeywords={abstract,base,bool,break,byte,case,catch,char,checked,% + class,const,continue,decimal,default,delegate,do,double,else,% + enum,event,explicit,extern,false,finally,fixed,float,for,foreach,% + goto,if,implicit,in,int,interface,internal,is,lock,long,% + namespace,new,null,object,operator,out,override,params,private,% + protected,public,readonly,ref,return,sbyte,sealed,short,sizeof,% + static,string,struct,switch,this,throw,true,try,typeof,uint,% + ulong,unchecked,unsafe,ushort,using,virtual,void,while},% + sensitive,% + morecomment=[s]{/*}{*/},% + morecomment=[l]//,% + morestring=[b]" + }[keywords,comments,strings]% +%% +%% csh definition (c) 1998 Kai Below +%% +\lst@definelanguage{csh} + {morekeywords={alias,awk,cat,echo,else,end,endif,endsw,exec,exit,% + foreach,glob,goto,history,if,logout,nice,nohup,onintr,repeat,sed,% + set,setenv,shift,source,switch,then,time,while,umask,unalias,% + unset,wait,while,@,env,argv,child,home,ignoreeof,noclobber,% + noglob,nomatch,path,prompt,shell,status,verbose,print,printf,% + sqrt,BEGIN,END},% + morecomment=[l]\#,% + morestring=[d]"% + }[keywords,comments,strings]% +\lst@definelanguage[90]{Fortran}[95]{Fortran}{} +\lst@definelanguage[95]{Fortran}[77]{Fortran}% + {deletekeywords=SAVE,% + morekeywords={ACTION,ADVANCE,ALLOCATE,ALLOCATABLE,ASSIGNMENT,CASE,% + CONTAINS,CYCLE,DEALLOCATE,DEFAULT,DELIM,EXIT,INCLUDE,IN,NONE,IN,% + OUT,INTENT,INTERFACE,IOLENGTH,KIND,LEN,MODULE,NAME,NAMELIST,NMT,% + NULLIFY,ONLY,OPERATOR,OPTIONAL,OUT,PAD,POINTER,POSITION,PRIVATE,% + PUBLIC,READWRITE,RECURSIVE,RESULT,SELECT,SEQUENCE,SIZE,STAT,% + TARGET,USE,WHERE,WHILE,BLOCKDATA,DOUBLEPRECISION,ELSEIF,% + ENDBLOCKDATA,ENDDO,ENDFILE,ENDFUNCTION,ENDIF,ENDINTERFACE,% + ENDMODULE,ENDPROGRAM,ENDSELECT,ENDSUBROUTINE,ENDTYPE,ENDWHERE,% + GOTO,INOUT,SELECTCASE},% + deletecomment=[f],% no fixed comment line: 1998 Magne Rudshaug + morecomment=[l]!% + }% +\lst@definelanguage[77]{Fortran}% + {morekeywords={ACCESS,ASSIGN,BACKSPACE,BLANK,BLOCK,CALL,CHARACTER,% + CLOSE,COMMON,COMPLEX,CONTINUE,DATA,DIMENSION,DIRECT,DO,DOUBLE,% + ELSE,END,ENTRY,EOF,EQUIVALENCE,ERR,EXIST,EXTERNAL,FILE,FMT,FORM,% + FORMAT,FORMATTED,FUNCTION,GO,TO,IF,IMPLICIT,INQUIRE,INTEGER,% + INTRINSIC,IOSTAT,LOGICAL,NAMED,NEXTREC,NUMBER,OPEN,OPENED,% + PARAMETER,PAUSE,PRECISION,PRINT,PROGRAM,READ,REAL,REC,RECL,% + RETURN,REWIND,SEQUENTIAL,STATUS,STOP,SUBROUTINE,THEN,TYPE,% + UNFORMATTED,UNIT,WRITE,SAVE},% + sensitive=f,%% not Fortran standard %% + morecomment=[f]*,% + morecomment=[f]C,% + morecomment=[f]c,% + morestring=[d]"% + }[keywords,comments,strings]% +\lst@definelanguage{HTML}% + {morekeywords={A,ADDRESS,APPLET,B,BASE,BASEFONT,BIG,BLOCKQUOTE,BODY,% + BR,CENTER,CITE,CODE,DFN,DIR,DIV,DOCTYPE,EM,FONT,FORM,HEAD,HR,% + H1,H2,H3,H4,H5,H6,HTML,I,IMG,INPUT,ISINDEX,KBD,LI,LINK,LISTING,% + MAP,META,MENU,P,PLAINTEXT,PRE,OL,SAMP,SCRIPT,SELECT,SMALL,STRIKE,% + STRING,SUB,SUP,STYLE,TABLE,TEXTAREA,TITLE,TT,U,UL,VAR,XMP,% + action,align,alink,alt,background,bgcolor,border,cellpadding,% + cellspacing,checked,code,codebase,color,cols,colspan,entype,% + height,href,hspace,ismap,link,maxlength,method,multiple,name,% + noshade,nowrap,rel,rev,rows,rowspan,selected,shape,size,src,text,% + title,type,usemap,valign,value,vlink,vspace,width},% + keywordsinside=<>, + sensitive=f,% + morestring=[d]",% ??? doubled + MoreSelectCharTable=% + \lst@CArgX--\relax\lst@DefDelimB{}{}% + {\ifnum\lst@mode=\lst@insidemode\else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@commentmode{{\lst@commentstyle}}% + \lst@CArgX--\relax\lst@DefDelimE{}{}{}% + \lst@EndComment\lst@commentmode + }[keywords,comments,strings,html]% +\lst@definelanguage{Java}% + {morekeywords={abstract,boolean,break,byte,case,catch,char,class,% + const,continue,default,do,double,else,extends,false,final,% + finally,float,for,goto,if,implements,import,instanceof,int,% + interface,label,long,native,new,null,package,private,protected,% + public,return,short,static,super,switch,synchronized,this,throw,% + throws,transient,true,try,void,volatile,while},% + sensitive,% + morecomment=[l]//,% + morecomment=[s]{/*}{*/},% + morestring=[b]",% + morestring=[b]',% + }[keywords,comments,strings]% +\lst@definelanguage{Matlab}% + {morekeywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% + all,angle,ans,any,asec,asech,asin,asinh,atan,atan2,atanh,auread,% + auwrite,axes,axis,balance,bar,bessel,besselk,bessely,beta,% + betainc,betaln,blanks,bone,break,brighten,capture,cart2pol,% + cart2sph,caxis,cd,cdf2rdf,cedit,ceil,chol,cla,clabel,clc,clear,% + clf,clock,close,colmmd,Colon,colorbar,colormap,ColorSpec,colperm,% + comet,comet3,compan,compass,computer,cond,condest,conj,contour,% + contour3,contourc,contrast,conv,conv2,cool,copper,corrcoef,cos,% + cosh,cot,coth,cov,cplxpair,cputime,cross,csc,csch,csvread,% + csvwrite,cumprod,cumsum,cylinder,date,dbclear,dbcont,dbdown,% + dbquit,dbstack,dbstatus,dbstep,dbstop,dbtype,dbup,ddeadv,ddeexec,% + ddeinit,ddepoke,ddereq,ddeterm,ddeunadv,deblank,dec2hex,deconv,% + del2,delete,demo,det,diag,diary,diff,diffuse,dir,disp,dlmread,% + dlmwrite,dmperm,dot,drawnow,echo,eig,ellipj,ellipke,else,elseif,% + end,engClose,engEvalString,engGetFull,engGetMatrix,engOpen,% + engOutputBuffer,engPutFull,engPutMatrix,engSetEvalCallback,% + engSetEvalTimeout,engWinInit,eps,erf,erfc,erfcx,erfinv,error,% + errorbar,etime,etree,eval,exist,exp,expint,expm,expo,eye,fclose,% + feather,feof,ferror,feval,fft,fft2,fftshift,fgetl,fgets,figure,% + fill,fill3,filter,filter2,find,findstr,finite,fix,flag,fliplr,% + flipud,floor,flops,fmin,fmins,fopen,for,format,fplot,fprintf,% + fread,frewind,fscanf,fseek,ftell,full,function,funm,fwrite,fzero,% + gallery,gamma,gammainc,gammaln,gca,gcd,gcf,gco,get,getenv,% + getframe,ginput,global,gplot,gradient,gray,graymon,grid,griddata,% + gtext,hadamard,hankel,help,hess,hex2dec,hex2num,hidden,hilb,hist,% + hold,home,hostid,hot,hsv,hsv2rgb,if,ifft,ifft2,imag,image,% + imagesc,Inf,info,input,int2str,interp1,interp2,interpft,inv,% + invhilb,isempty,isglobal,ishold,isieee,isinf,isletter,isnan,% + isreal,isspace,issparse,isstr,jet,keyboard,kron,lasterr,lcm,% + legend,legendre,length,lin2mu,line,linspace,load,log,log10,log2,% + loglog,logm,logspace,lookfor,lower,ls,lscov,lu,magic,matClose,% + matDeleteMatrix,matGetDir,matGetFp,matGetFull,matGetMatrix,% + matGetNextMatrix,matGetString,matlabrc,matlabroot,matOpen,% + matPutFull,matPutMatrix,matPutString,max,mean,median,menu,mesh,% + meshc,meshgrid,meshz,mexAtExit,mexCallMATLAB,mexdebug,% + mexErrMsgTxt,mexEvalString,mexFunction,mexGetFull,mexGetMatrix,% + mexGetMatrixPtr,mexPrintf,mexPutFull,mexPutMatrix,mexSetTrapFlag,% + min,more,movie,moviein,mu2lin,mxCalloc,mxCopyCharacterToPtr,% + mxCopyComplex16ToPtr,mxCopyInteger4ToPtr,mxCopyPtrToCharacter,% + mxCopyPtrToComplex16,mxCopyPtrToInteger4,mxCopyPtrToReal8,% + mxCopyReal8ToPtr,mxCreateFull,mxCreateSparse,mxCreateString,% + mxFree,mxFreeMatrix,mxGetIr,mxGetJc,mxGetM,mxGetN,mxGetName,% + mxGetNzmax,mxGetPi,mxGetPr,mxGetScalar,mxGetString,mxIsComplex,% + mxIsFull,mxIsNumeric,mxIsSparse,mxIsString,mxIsTypeDouble,% + mxSetIr,mxSetJc,mxSetM,mxSetN,mxSetName,mxSetNzmax,mxSetPi,% + mxSetPr,NaN,nargchk,nargin,nargout,newplot,nextpow2,nnls,nnz,% + nonzeros,norm,normest,null,num2str,nzmax,ode23,ode45,orient,orth,% + pack,pascal,patch,path,pause,pcolor,pi,pink,pinv,plot,plot3,% + pol2cart,polar,poly,polyder,polyeig,polyfit,polyval,polyvalm,% + pow2,print,printopt,prism,prod,pwd,qr,qrdelete,qrinsert,quad,% + quad8,quit,quiver,qz,rand,randn,randperm,rank,rat,rats,rbbox,% + rcond,real,realmax,realmin,refresh,rem,reset,reshape,residue,% + return,rgb2hsv,rgbplot,rootobject,roots,rose,rosser,rot90,rotate,% + round,rref,rrefmovie,rsf2csf,save,saxis,schur,sec,sech,semilogx,% + semilogy,set,setstr,shading,sign,sin,sinh,size,slice,sort,sound,% + spalloc,sparse,spaugment,spconvert,spdiags,specular,speye,spfun,% + sph2cart,sphere,spinmap,spline,spones,spparms,sprandn,sprandsym,% + sprank,sprintf,spy,sqrt,sqrtm,sscanf,stairs,startup,std,stem,% + str2mat,str2num,strcmp,strings,strrep,strtok,subplot,subscribe,% + subspace,sum,surf,surface,surfc,surfl,surfnorm,svd,symbfact,% + symmmd,symrcm,tan,tanh,tempdir,tempname,terminal,text,tic,title,% + toc,toeplitz,trace,trapz,tril,triu,type,uicontrol,uigetfile,% + uimenu,uiputfile,unix,unwrap,upper,vander,ver,version,view,% + viewmtx,waitforbuttonpress,waterfall,wavread,wavwrite,what,% + whatsnew,which,while,white,whitebg,who,whos,wilkinson,wk1read,% + wk1write,xlabel,xor,ylabel,zeros,zlabel,zoom},% + sensitive,% + morecomment=[l]\%,% + morestring=[m]'% + }[keywords,comments,strings]% +%% +%% Mathematica definitions (c) 1999 Michael Wiese +%% +\lst@definelanguage[3.0]{Mathematica}[1.0]{Mathematica}% + {morekeywords={Abort,AbortProtect,AbsoluteDashing,AbsolutePointSize,% + AbsoluteThickness,AbsoluteTime,AccountingFormAiry,AiPrime,AiryBi,% + AiryBiPrime,Alternatives,AnchoredSearch,AxesEdge,AxesOrigin,% + AxesStyle,Background,BetaRegularized,BoxStyle,C,CheckAbort,% + Circle,ClebschGordan,CMYKColor,ColorFunction,ColorOutput,Compile,% + Compiled,CompiledFunction,ComplexExpand,ComposeList,Composition,% + ConstrainedMax,ConstrainedMin,Contexts,ContextToFilename,% + ContourLines,Contours,ContourShading,ContourSmoothing,% + ContourStyle,CopyDirectory,CopyFile,CosIntegral,CreateDirectory,% + Cuboid,Date,DeclarePackage,DefaultColor,DefaultFont,Delete,% + DeleteCases,DeleteDirectory,DeleteFile,Dialog,DialogIndent,% + DialogProlog,DialogSymbols,DigitQ,Directory,DirectoryStack,Disk,% + Dispatch,DownValues,DSolve,Encode,Epilog,Erfc,Evaluate,% + ExponentFunction,FaceGrids,FileByteCount,FileDate,FileNames,% + FileType,Find,FindList,FixedPointList,FlattenAt,Fold,FoldList,% + Frame,FrameLabel,FrameStyle,FrameTicks,FromCharacterCode,% + FromDate,FullGraphics,FullOptions,GammaRegularized,% + GaussianIntegers,GraphicsArray,GraphicsSpacing,GridLines,% + GroebnerBasis,Heads,HeldPart,HomeDirectory,Hue,IgnoreCases,% + InputStream,Install,InString,IntegerDigits,InterpolatingFunction,% + InterpolatingPolynomial,Interpolation,Interrupt,InverseFunction,% + InverseFunctions,JacobiZeta,LetterQ,LinearProgramming,ListPlay,% + LogGamma,LowerCaseQ,MachineNumberQ,MantissaExponent,MapIndexed,% + MapThread,MatchLocalNames,MatrixExp,MatrixPower,MeshRange,% + MeshStyle,MessageList,Module,NDSolve,NSolve,NullRecords,% + NullWords,NumberFormat,NumberPadding,NumberSigns,OutputStream,% + PaddedForm,ParentDirectory,Pause,Play,PlayRange,PlotRegion,% + PolygonIntersections,PolynomialGCD,PolynomialLCM,PolynomialMod,% + PostScript,PowerExpand,PrecisionGoal,PrimePi,Prolog,% + QRDecomposition,Raster,RasterArray,RealDigits,Record,RecordLists,% + RecordSeparators,ReleaseHold,RenameDirectory,RenameFile,% + ReplaceHeldPart,ReplacePart,ResetDirectory,Residue,% + RiemannSiegelTheta,RiemannSiegelZ,RotateLabel,SameTest,% + SampleDepth,SampledSoundFunction,SampledSoundList,SampleRate,% + SchurDecomposition,SessionTime,SetAccuracy,SetDirectory,% + SetFileDate,SetPrecision,SetStreamPosition,Shallow,SignPadding,% + SinIntegral,SixJSymbol,Skip,Sound,SpellingCorrection,% + SphericalRegion,Stack,StackBegin,StackComplete,StackInhibit,% + StreamPosition,Streams,StringByteCount,StringConversion,% + StringDrop,StringInsert,StringPosition,StringReplace,% + StringReverse,StringTake,StringToStream,SurfaceColor,% + SyntaxLength,SyntaxQ,TableAlignments,TableDepth,% + TableDirections,TableHeadings,TableSpacing,ThreeJSymbol,TimeUsed,% + TimeZone,ToCharacterCode,ToDate,ToHeldExpression,TokenWords,% + ToLowerCase,ToUpperCase,Trace,TraceAbove,TraceBackward,% + TraceDepth,TraceDialog,TraceForward,TraceOff,TraceOn,% + TraceOriginal,TracePrint,TraceScan,Trig,Unevaluated,Uninstall,% + UnsameQ,UpperCaseQ,UpValues,ViewCenter,ViewVertical,With,Word,% + WordSearch,WordSeparators},% + morendkeywords={Stub,Temporary,$Aborted,$BatchInput,$BatchOutput,% + $CreationDate,$DefaultFont,$DumpDates,$DumpSupported,$Failed,% + $Input,$Inspector,$IterationLimit,$Language,$Letters,$Linked,% + $LinkSupported,$MachineEpsilon,$MachineID,$MachineName,% + $MachinePrecision,$MachineType,$MaxMachineNumber,$MessageList,% + $MessagePrePrint,$MinMachineNumber,$ModuleNumber,$NewMessage,% + $NewSymbol,$Notebooks,$OperatingSystem,$Packages,$PipeSupported,% + $PreRead,$ReleaseNumber,$SessionID,$SoundDisplayFunction,% + $StringConversion,$StringOrder,$SyntaxHandler,$TimeUnit,% + $VersionNumber}% + }% +\lst@definelanguage[1.0]{Mathematica}% + {morekeywords={Abs,Accuracy,AccurayGoal,AddTo,AiryAi,AlgebraicRules,% + AmbientLight,And,Apart,Append,AppendTo,Apply,ArcCos,ArcCosh,% + ArcCot,ArcCoth,ArcCsc,ArcCsch,ArcSec,ArcSech,ArcSin,ArcSinh,% + ArcTan,ArcTanh,Arg,ArithmeticGeometricMean,Array,AspectRatio,% + AtomQ,Attributes,Axes,AxesLabel,BaseForm,Begin,BeginPackage,% + BernoulliB,BesselI,BesselJ,BesselK,BesselY,Beta,Binomial,Blank,% + BlankNullSequence,BlankSequence,Block,Boxed,BoxRatios,Break,Byte,% + ByteCount,Cancel,Cases,Catch,Ceiling,CForm,Character,Characters,% + ChebyshevT,ChebyshevU,Check,Chop,Clear,ClearAll,ClearAttributes,% + ClipFill,Close,Coefficient,CoefficientList,Collect,ColumnForm,% + Complement,Complex,CompoundExpression,Condition,Conjugate,% + Constants,Context,Continuation,Continue,ContourGraphics,% + ContourPlot,Cos,Cosh,Cot,Coth,Count,Csc,Csch,Cubics,Cyclotomic,% + D,Dashing,Decompose,Decrement,Default,Definition,Denominator,% + DensityGraphics,DensityPlot,Depth,Derivative,Det,DiagonalMatrix,% + DigitBlock,Dimensions,DirectedInfinity,Display,DisplayFunction,% + Distribute,Divide,DivideBy,Divisors,DivisorSigma,Do,Dot,Drop,Dt,% + Dump,EdgeForm,Eigensystem,Eigenvalues,Eigenvectors,Eliminate,% + EllipticE,EllipticExp,EllipticF,EllipticK,EllipticLog,EllipticPi,% + EllipticTheta,End,EndPackage,EngineeringForm,Environment,Equal,% + Erf,EulerE,EulerPhi,EvenQ,Exit,Exp,Expand,ExpandAll,% + ExpandDenominator,ExpandNumerator,ExpIntegralE,ExpIntegralEi,% + Exponent,Expression,ExtendedGCD,FaceForm,Factor,FactorComplete,% + Factorial,Factorial2,FactorInteger,FactorList,FactorSquareFree,% + FactorSquareFreeList,FactorTerms,FactorTermsList,FindMinimum,% + FindRoot,First,Fit,FixedPoint,Flatten,Floor,FontForm,For,Format,% + FormatType,FortranForm,Fourier,FreeQ,FullDefinition,FullForm,% + Function,Gamma,GCD,GegenbauerC,General,Get,Goto,Graphics,% + Graphics3D,GrayLevel,Greater,GreaterEqual,Head,HermiteH,% + HiddenSurface,Hold,HoldForm,Hypergeometric0F1, Hypergeometric1F1,% + Hypergeometric2F1,HypergeometricU,Identity,IdentityMatrix,If,Im,% + Implies,In,Increment,Indent,Infix,Information,Inner,Input,% + InputForm,InputString,Insert,Integer,IntegerQ,Integrate,% + Intersection,Inverse,InverseFourier,InverseJacobiSN,% + InverseSeries,JacobiAmplitude,JacobiP,JacobiSN,JacobiSymbol,Join,% + Label,LaguerreL,Last,LatticeReduce,LCM,LeafCount,LegendreP,% + LegendreQ,LegendreType,Length,LerchPhi,Less,LessEqual,Level,% + Lighting,LightSources,Limit,Line,LinearSolve,LineBreak,List,% + ListContourPlot,ListDensityPlot,ListPlot,ListPlot3D,Literal,Log,% + LogicalExpand,LogIntegral,MainSolve,Map,MapAll,MapAt,MatchQ,% + MatrixForm,MatrixQ,Max,MaxBend,MaxMemoryUsed,MemberQ,% + MemoryConstrained,MemoryInUse,Mesh,Message,MessageName,Messages,% + Min,Minors,Minus,Mod,Modulus,MoebiusMu,Multinomial,N,NameQ,Names,% + NBernoulliB,Needs,Negative,Nest,NestList,NIntegrate,% + NonCommutativeMultiply,NonConstants,NonNegative,Normal,Not,% + NProduct,NSum,NullSpace,Number,NumberForm,NumberPoint,NumberQ,% + NumberSeparator,Numerator,O,OddQ,Off,On,OpenAppend,OpenRead,% + OpenTemporary,OpenWrite,Operate,Optional,Options,Or,Order,% + OrderedQ,Out,Outer,OutputForm,PageHeight,PageWidth,% + ParametricPlot,ParametricPlot3D,Part,Partition,PartitionsP,% + PartitionsQ,Pattern,Permutations,Plot,Plot3D,PlotDivision,% + PlotJoined,PlotLabel,PlotPoints,PlotRange,PlotStyle,Pochhammer,% + Plus,Point,PointSize,PolyGamma,Polygon,PolyLog,PolynomialQ,% + PolynomialQuotient,PolynomialRemainder,Position,Positive,Postfix,% + Power,PowerMod,PrecedenceForm,Precision,PreDecrement,Prefix,% + PreIncrement,Prepend,PrependTo,Prime,PrimeQ,Print,PrintForm,% + Product,Protect,PseudoInverse,Put,PutAppend,Quartics,Quit,% + Quotient,Random,Range,Rational,Rationalize,Raw,Re,Read,ReadList,% + Real,Rectangle,Reduce,Remove,RenderAll,Repeated,RepeatedNull,% + Replace,ReplaceAll,ReplaceRepeated,Rest,Resultant,Return,Reverse,% + RGBColor,Roots,RotateLeft,RotateRight,Round,RowReduce,Rule,% + RuleDelayed,Run,RunThrough,SameQ,Save,Scaled,Scan,ScientificForm,% + Sec,Sech,SeedRandom,Select,Sequence,SequenceForm,Series,% + SeriesData,Set,SetAttributes,SetDelayed,SetOptions,Shading,Share,% + Short,Show,Sign,Signature,Simplify,Sin,SingularValues,Sinh,% + Skeleton,Slot,SlotSequence,Solve,SolveAlways,Sort,% + SphericalHarmonicY,Splice,Sqrt,StirlingS1,StirlingS2,String,% + StringBreak,StringForm,StringJoin,StringLength,StringMatchQ,% + StringSkeleton,Subscript,Subscripted,Subtract,SubtractForm,Sum,% + Superscript,SurfaceGraphics,Switch,Symbol,Table,TableForm,TagSet,% + TagSetDelayed,TagUnset,Take,Tan,Tanh,ToString,TensorRank,TeXForm,% + Text,TextForm,Thickness,Thread,Through,Throw,Ticks,% + TimeConstrained,Times,TimesBy,Timing,ToExpression,Together,% + ToRules,ToString,TotalHeight,TotalWidth,Transpose,TreeForm,TrueQ,% + Unequal,Union,Unique,Unprotect,Unset,Update,UpSet,UpSetDelayed,% + ValueQ,Variables,VectorQ,ViewPoint,WeierstrassP,% + WeierstrassPPrime,Which,While,WorkingPrecision,Write,WriteString,% + Xor,ZeroTest,Zeta},% + morendkeywords={All,Automatic,Catalan,ComplexInfinity,Constant,% + Degree,E,EndOfFile,EulerGamma,False,Flat,GoldenRatio,HoldAll,% + HoldFirst,HoldRest,I,Indeterminate,Infinity,Listable,Locked,% + Modular,None,Null,OneIdentity,Orderless,Pi,Protected,% + ReadProtected,True,$CommandLine,$Context,$ContextPath,$Display,% + $DisplayFunction,$Echo,$Epilog,$IgnoreEOF,$Line,$Messages,% + $Output,$Path,$Post,$Pre,$PrePrint,$RecursionLimit,$System,% + $Urgent,$Version},% + sensitive,% + morecomment=[s]{(*}{*)},% + morestring=[d]"% + }[keywords,comments,strings]% +%% +%% Octave definition (c) 2001,2002 Ulrich G. Wortmann +%% +%% +\lst@definelanguage{Octave}% + {morekeywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% + all,angle,ans,any,asec,asech,asin,asinh,atan,atan2,atanh,auread,% + auwrite,axes,axis,balance,bar,bessel,besselk,bessely,beta,% + betainc,betaln,blanks,bone,break,brighten,capture,cart2pol,% + cart2sph,caxis,cd,cdf2rdf,cedit,ceil,chol,cla,clabel,clc,clear,% + clf,clock,close,colmmd,Colon,colorbar,colormap,ColorSpec,colperm,% + comet,comet3,compan,compass,computer,cond,condest,conj,contour,% + contour3,contourc,contrast,conv,conv2,cool,copper,corrcoef,cos,% + cosh,cot,coth,cov,cplxpair,cputime,cross,csc,csch,csvread,% + csvwrite,cumprod,cumsum,cylinder,date,dbclear,dbcont,dbdown,% + dbquit,dbstack,dbstatus,dbstep,dbstop,dbtype,dbup,ddeadv,ddeexec,% + ddeinit,ddepoke,ddereq,ddeterm,ddeunadv,deblank,dec2hex,deconv,% + del2,delete,demo,det,diag,diary,diff,diffuse,dir,disp,dlmread,% + dlmwrite,dmperm,dot,drawnow,echo,eig,ellipj,ellipke,else,elseif,% + end,engClose,engEvalString,engGetFull,engGetMatrix,engOpen,% + engOutputBuffer,engPutFull,engPutMatrix,engSetEvalCallback,% + engSetEvalTimeout,engWinInit,eps,erf,erfc,erfcx,erfinv,% + errorbar,etime,etree,eval,exist,exp,expint,expm,expo,eye,fclose,% + feather,feof,ferror,feval,fft,fft2,fftshift,fgetl,fgets,figure,% + fill,fill3,filter,filter2,find,findstr,finite,fix,flag,fliplr,% + flipud,floor,flops,fmin,fmins,fopen,for,format,fplot,fprintf,% + fread,frewind,fscanf,fseek,ftell,full,function,funm,fwrite,fzero,% + gallery,gamma,gammainc,gammaln,gca,gcd,gcf,gco,get,getenv,% + getframe,ginput,global,gplot,gradient,gray,graymon,grid,griddata,% + gtext,hadamard,hankel,help,hess,hex2dec,hex2num,hidden,hilb,hist,% + hold,home,hostid,hot,hsv,hsv2rgb,if,ifft,ifft2,imag,image,% + imagesc,Inf,info,input,int2str,interp1,interp2,interpft,inv,% + invhilb,isempty,isglobal,ishold,isieee,isinf,isletter,isnan,% + isreal,isspace,issparse,isstr,jet,keyboard,kron,lasterr,lcm,% + legend,legendre,length,lin2mu,line,linspace,load,log,log10,log2,% + loglog,logm,logspace,lookfor,lower,ls,lscov,lu,magic,matClose,% + matDeleteMatrix,matGetDir,matGetFp,matGetFull,matGetMatrix,% + matGetNextMatrix,matGetString,matlabrc,matlabroot,matOpen,% + matPutFull,matPutMatrix,matPutString,max,mean,median,menu,mesh,% + meshc,meshgrid,meshz,mexAtExit,mexCallMATLAB,mexdebug,% + mexErrMsgTxt,mexEvalString,mexFunction,mexGetFull,mexGetMatrix,% + mexGetMatrixPtr,mexPrintf,mexPutFull,mexPutMatrix,mexSetTrapFlag,% + min,more,movie,moviein,mu2lin,mxCalloc,mxCopyCharacterToPtr,% + mxCopyComplex16ToPtr,mxCopyInteger4ToPtr,mxCopyPtrToCharacter,% + mxCopyPtrToComplex16,mxCopyPtrToInteger4,mxCopyPtrToReal8,% + mxCopyReal8ToPtr,mxCreateFull,mxCreateSparse,mxCreateString,% + mxFree,mxFreeMatrix,mxGetIr,mxGetJc,mxGetM,mxGetN,mxGetName,% + mxGetNzmax,mxGetPi,mxGetPr,mxGetScalar,mxGetString,mxIsComplex,% + mxIsFull,mxIsNumeric,mxIsSparse,mxIsString,mxIsTypeDouble,% + mxSetIr,mxSetJc,mxSetM,mxSetN,mxSetName,mxSetNzmax,mxSetPi,% + mxSetPr,NaN,nargchk,nargin,nargout,newplot,nextpow2,nnls,nnz,% + nonzeros,norm,normest,null,num2str,nzmax,ode23,ode45,orient,orth,% + pack,pascal,patch,path,pause,pcolor,pi,pink,pinv,plot,plot3,% + pol2cart,polar,poly,polyder,polyeig,polyfit,polyval,polyvalm,% + pow2,print,printopt,prism,prod,pwd,qr,qrdelete,qrinsert,quad,% + quad8,quit,quiver,qz,rand,randn,randperm,rank,rat,rats,rbbox,% + rcond,real,realmax,realmin,refresh,rem,reset,reshape,residue,% + return,rgb2hsv,rgbplot,rootobject,roots,rose,rosser,rot90,rotate,% + round,rref,rrefmovie,rsf2csf,save,saxis,schur,sec,sech,semilogx,% + semilogy,set,setstr,shading,sign,sin,sinh,size,slice,sort,sound,% + spalloc,sparse,spaugment,spconvert,spdiags,specular,speye,spfun,% + sph2cart,sphere,spinmap,spline,spones,spparms,sprandn,sprandsym,% + sprank,sprintf,spy,sqrt,sqrtm,sscanf,stairs,startup,std,stem,% + str2mat,str2num,strcmp,strings,strrep,strtok,subplot,subscribe,% + subspace,sum,surf,surface,surfc,surfl,surfnorm,svd,symbfact,% + symmmd,symrcm,tan,tanh,tempdir,tempname,terminal,text,tic,title,% + toc,toeplitz,trace,trapz,tril,triu,type,uicontrol,uigetfile,% + uimenu,uiputfile,unix,unwrap,upper,vander,ver,version,view,% + viewmtx,waitforbuttonpress,waterfall,wavread,wavwrite,what,% + whatsnew,which,while,white,whitebg,who,whos,wilkinson,wk1read,% + stderr,stdout,plot,set,endif,wk1write,xlabel,xor,ylabel,zeros,% + zlabel,zoom,endwhile,endfunction},% + sensitive=f,% + morecomment=[l]\#,% + morecomment=[l]\#\#,% + morestring=[m]',% + morestring=[m]"% + }[keywords,comments,strings]% +\lst@definelanguage[XSC]{Pascal}[Standard]{Pascal} + {deletekeywords={alfa,byte,pack,unpack},% 1998 Andreas Stephan + morekeywords={dynamic,external,forward,global,module,nil,operator,% + priority,sum,type,use,dispose,mark,page,release,cimatrix,% + cinterval,civector,cmatrix,complex,cvector,dotprecision,imatrix,% + interval,ivector,rmatrix,rvector,string,im,inf,re,sup,chr,comp,% + eof,eoln,expo,image,ival,lb,lbound,length,loc,mant,maxlength,odd,% + ord,pos,pred,round,rval,sign,substring,succ,trunc,ub,ubound}% + }% +\lst@definelanguage[Borland6]{Pascal}[Standard]{Pascal} + {morekeywords={asm,constructor,destructor,implementation,inline,% + interface,nil,object,shl,shr,string,unit,uses,xor},% + morendkeywords={Abs,Addr,ArcTan,Chr,Concat,Copy,Cos,CSeg,DiskFree,% + DiskSize,DosExitCode,DosVersion,DSeg,EnvCount,EnvStr,Eof,Eoln,% + Exp,FExpand,FilePos,FileSize,Frac,FSearch,GetBkColor,GetColor,% + GetDefaultPalette,GetDriverName,GetEnv,GetGraphMode,GetMaxMode,% + GetMaxX,GetMaxY,GetModeName,GetPaletteSize,GetPixel,GetX,GetY,% + GraphErrorMsg,GraphResult,Hi,ImageSize,InstallUserDriver,% + InstallUserFont,Int,IOResult,KeyPressed,Length,Lo,MaxAvail,% + MemAvail,MsDos,Odd,Ofs,Ord,OvrGetBuf,OvrGetRetry,ParamCount,% + ParamStr,Pi,Pos,Pred,Ptr,Random,ReadKey,Round,SeekEof,SeekEoln,% + Seg,SetAspectRatio,Sin,SizeOf,Sound,SPtr,Sqr,Sqrt,SSeg,Succ,% + Swap,TextHeight,TextWidth,Trunc,TypeOf,UpCase,WhereX,WhereY,% + Append,Arc,Assign,AssignCrt,Bar,Bar3D,BlockRead,BlockWrite,ChDir,% + Circle,ClearDevice,ClearViewPort,Close,CloseGraph,ClrEol,ClrScr,% + Dec,Delay,Delete,DelLine,DetectGraph,Dispose,DrawPoly,Ellipse,% + Erase,Exec,Exit,FillChar,FillEllipse,FillPoly,FindFirst,FindNext,% + FloodFill,Flush,FreeMem,FSplit,GetArcCoords,GetAspectRatio,% + GetDate,GetDefaultPalette,GetDir,GetCBreak,GetFAttr,% + GetFillSettings,GetFTime,GetImage,GetIntVec,GetLineSettings,% + GetMem,GetPalette,GetTextSettings,GetTime,GetVerify,% + GetViewSettings,GoToXY,Halt,HighVideo,Inc,InitGraph,Insert,% + InsLine,Intr,Keep,Line,LineRel,LineTo,LowVideo,Mark,MkDir,Move,% + MoveRel,MoveTo,MsDos,New,NormVideo,NoSound,OutText,OutTextXY,% + OvrClearBuf,OvrInit,OvrInitEMS,OvrSetBuf,PackTime,PieSlice,% + PutImage,PutPixel,Randomize,Rectangle,Release,Rename,% + RestoreCrtMode,RmDir,RunError,Sector,Seek,SetActivePage,% + SetAllPalette,SetBkColor,SetCBreak,SetColor,SetDate,SetFAttr,% + SetFillPattern,SetFillStyle,SetFTime,SetGraphBufSize,% + SetGraphMode,SetIntVec,SetLineStyle,SetPalette,SetRGBPalette,% + SetTextBuf,SetTextJustify,SetTextStyle,SetTime,SetUserCharSize,% + SetVerify,SetViewPort,SetVisualPage,SetWriteMode,Sound,Str,% + SwapVectors,TextBackground,TextColor,TextMode,Truncate,% + UnpackTime,Val,Window}% + }% +\lst@definelanguage[Standard]{Pascal}% + {morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,% + do,downto,else,end,false,file,for,function,get,goto,if,in,% + integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% + put,procedure,read,readln,real,record,repeat,reset,rewrite,set,% + text,then,to,true,type,unpack,until,var,while,with,write,% + writeln},% + sensitive=f,% + morecomment=[s]{(*}{*)},% + morecomment=[s]{\{}{\}},% + morestring=[d]'% + }[keywords,comments,strings]% +\lst@definelanguage{Perl}% + {morekeywords={abs,accept,alarm,atan2,bind,binmode,bless,caller,% + chdir,chmod,chomp,chop,chown,chr,chroot,close,closedir,connect,% + continue,cos,crypt,dbmclose,dbmopen,defined,delete,die,do,dump,% + each,else,elsif,endgrent,endhostent,endnetent,endprotoent,% + endpwent,endservent,eof,eval,exec,exists,exit,exp,fcntl,fileno,% + flock,for,foreach,fork,format,formline,getc,getgrent,getgrgid,% + getgrnam,gethostbyaddr,gethostbyname,gethostent,getlogin,% + getnetbyaddr,getnetbyname,getnetent,getpeername,getpgrp,% + getppid,getpriority,getprotobyname,getprotobynumber,getprotoent,% + getpwent,getpwnam,getpwuid,getservbyname,getservbyport,% + getservent,getsockname,getsockopt,glob,gmtime,goto,grep,hex,if,% + import,index,int,ioctl,join,keys,kill,last,lc,lcfirst,length,% + link,listen,local,localtime,log,lstat,m,map,mkdir,msgctl,msgget,% + msgrcv,msgsnd,my,next,no,oct,open,opendir,ord,pack,package,pipe,% + pop,pos,print,printf,prototype,push,q,qq,quotemeta,qw,qx,rand,% + read,readdir,readlink,recv,redo,ref,rename,require,reset,return,% + reverse,rewinddir,rindex,rmdir,s,scalar,seek,seekdir,select,% + semctl,semget,semop,send,setgrent,sethostent,setnetent,setpgrp,% + setpriority,setprotoent,setpwent,setservent,setsockopt,shift,% + shmctl,shmget,shmread,shmwrite,shutdown,sin,sleep,socket,% + socketpair,sort,splice,split,sprintf,sqrt,srand,stat,study,sub,% + substr,symlink,syscall,sysopen,sysread,system,syswrite,tell,% + telldir,tie,tied,time,times,tr,truncate,uc,ucfirst,umask,undef,% + unless,unlink,unpack,unshift,untie,until,use,utime,values,vec,% + wait,waitpid,wantarray,warn,while,write,y},% + sensitive,% + morecomment=[l]\#,% + morestring=[b]",% + morestring=[b]',% + MoreSelectCharTable=% + \lst@ReplaceInput{\$\#}{\lst@ProcessOther\$\lst@ProcessOther\#}% + }[keywords,comments,strings]% +%% +%% POV definition (c) 1999 Berthold H\"ollmann +%% +%% +\lst@definelanguage{POV}% + {morekeywords={abs,absorption,acos,acosh,adaptive,adc_bailout,agate,% + agate_turb,all,alpha,ambient,ambient_light,angle,aperture,append,% + arc_angle,area_light,array,asc,asin,asinh,assumed_gamma,atan,% + atan2,atanh,average,background,bezier_spline,bicubic_patch,% + black_hole,blob,blue,blur_samples,bounded_by,box,boxed,bozo,% + break,brick,brick_size,brightness,brilliance,bumps,bump_map,% + bump_size,camera,case,caustics,ceil,checker,chr,clipped_by,clock,% + clock_delta,color,color_map,colour,colour_map,component,% + composite,concat,cone,confidence,conic_sweep,control0,control1,% + cos,cosh,count,crackle,crand,cube,cubic,cubic_spline,cubic_wave,% + cylinder,cylindrical,debug,declare,default,defined,degrees,% + density,density_file,density_map,dents,difference,diffuse,% + dimensions,dimension_size,direction,disc,distance,% + distance_maximum,div,eccentricity,else,emission,end,error,% + error_bound,exp,extinction,fade_distance,fade_power,falloff,% + falloff_angle,false,fclose,file_exists,filter,finish,fisheye,% + flatness,flip,floor,focal_point,fog,fog_alt,fog_offset,fog_type,% + fopen,frequency,gif,global_settings,gradient,granite,% + gray_threshold,green,height_field,hexagon,hf_gray_16,hierarchy,% + hollow,hypercomplex,if,ifdef,iff,ifndef,image_map,include,int,% + interior,interpolate,intersection,intervals,inverse,ior,irid,% + irid_wavelength,jitter,julia_fractal,lambda,lathe,leopard,% + light_source,linear_spline,linear_sweep,local,location,log,% + looks_like,look_at,low_error_factor,macro,mandel,map_type,marble,% + material,material_map,matrix,max,max_intersections,max_iteration,% + max_trace_level,media,media_attenuation,media_interaction,merge,% + mesh,metallic,min,minimum_reuse,mod,mortar,nearest_count,no,% + normal,normal_map,no_shadow,number_of_waves,object,octaves,off,% + offset,omega,omnimax,on,once,onion,open,orthographic,panoramic,% + perspective,pgm,phase,phong,phong_size,pi,pigment,pigment_map,% + planar,plane,png,point_at,poly,polygon,poly_wave,pot,pow,ppm,% + precision,prism,pwr,quadratic_spline,quadric,quartic,quaternion,% + quick_color,quick_colour,quilted,radial,radians,radiosity,radius,% + rainbow,ramp_wave,rand,range,ratio,read,reciprocal,% + recursion_limit,red,reflection,reflection_exponent,refraction,% + render,repeat,rgb,rgbf,rgbft,rgbt,right,ripples,rotate,roughness,% + samples,scale,scallop_wave,scattering,seed,shadowless,sin,% + sine_wave,sinh,sky,sky_sphere,slice,slope_map,smooth,% + smooth_triangle,sor,specular,sphere,spherical,spiral1,spiral2,% + spotlight,spotted,sqr,sqrt,statistics,str,strcmp,strength,strlen,% + strlwr,strupr,sturm,substr,superellipsoid,switch,sys,t,tan,tanh,% + text,texture,texture_map,tga,thickness,threshold,tightness,tile2,% + tiles,torus,track,transform,translate,transmit,triangle,% + triangle_wave,true,ttf,turbulence,turb_depth,type,u,% + ultra_wide_angle,undef,union,up,use_color,use_colour,use_index,% + u_steps,v,val,variance,vaxis_rotate,vcross,vdot,version,vlength,% + vnormalize,vrotate,v_steps,warning,warp,water_level,waves,while,% + width,wood,wrinkles,write,x,y,yes,z},% + moredirectives={break,case,debug,declare,default,else,end,fclose,% + fopen,local,macro,read,render,statistics,switch,undef,version,% + warning,write},% + sensitive,% + morecomment=[l]//,% + morecomment=[s]{/*}{*/},% + morestring=[d]",% + }[keywords,directives,comments,strings]% +%% +%% Python definition (c) 1998 Michael Weber +%% +%% +\lst@definelanguage{Python}% + {morekeywords={access,and,break,class,continue,def,del,elif,else,% + except,exec,finally,for,from,global,if,import,in,is,lambda,not,% + or,pass,print,raise,return,try,while},% + sensitive=true,% + morecomment=[l]\#,% + morecomment=[s]{'''}{'''},% used for documentation text + morecomment=[s]{"""}{"""},% added by Philipp Matthias Hahn + morestring=[b]',% + morestring=[b]"% + }% +%% +%% SQL definition (c) 1998 Christian Haul +%% +%% and (c) 2002 Neil Conway +%% +\lst@definelanguage{SQL}% + {morekeywords={ABSOLUTE,ACTION,ADD,ALLOCATE,ALTER,ARE,AS,ASSERTION,% + AT,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,% + CATALOG,CHAR,CHAR_LENGTH,CHARACTER_LENGTH,CLUSTER,COALESCE,% + COLLATE,COLLATION,COLUMN,CONNECT,CONNECTION,CONSTRAINT,% + CONSTRAINTS,CONVERT,CORRESPONDING,CREATE,CROSS,CURRENT_DATE,% + CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,DATE,DAY,DEALLOCATE,% + DEC,DECIMAL,DEFERRABLE,DEFERED,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,% + DISCONNECT,DOMAIN,DROP,ELSE,END,EXEC,EXCEPT,EXCEPTION,EXECUTE,% + EXTERNAL,EXTRACT,FALSE,FIRST,FLOAT,FOREIGN,FROM,FULL,GET,GLOBAL,% + GRAPHIC,HAVING,HOUR,IDENTITY,IMMEDIATE,INDEX,INITIALLY,INNER,% + INPUT,INSENSITIVE,INSERT,INT,INTO,INTEGER,INTERSECT,INTERVAL,% + ISOLATION,JOIN,KEY,LAST,LEADING,LEFT,LEVEL,LIMIT,LOCAL,LOWER,% + MATCH,MINUTE,MONTH,NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NOT,NULL,% + NULLIF,OCTET_LENGTH,ON,ONLY,ORDER,ORDERED,OUTER,OUTPUT,OVERLAPS,% + PAD,PARTIAL,POSITION,PREPARE,PRESERVE,PRIMARY,PRIOR,READ,% + RELATIVE,RESTRICT,REVOKE,RIGHT,ROWS,SCROLL,SECOND,SELECT,SESSION,% + SESSION_USER,SIZE,SMALLINT,SPACE,SQLSTATE,SUBSTRING,SYSTEM_USER,% + TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,% + TIMEZONE_MINUTE,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,% + TRUE,UNIQUE,UNKNOWN,UPPER,USAGE,USING,VALUE,VALUES,VARCHAR,% + VARGRAPHIC,VARYING,WHEN,WHERE,WRITE,YEAR,ZONE},% + sensitive,% + morecomment=[l]--,% + morecomment=[s]{/*}{*/},% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% +%% +%% VHDL definition (c) 1997 Kai Wollenweber +%% +\lst@definelanguage{VHDL}% + {morekeywords={ALL,ARCHITECTURE,ABS,AND,ASSERT,ARRAY,AFTER,ALIAS,% + ACCESS,ATTRIBUTE,BEGIN,BODY,BUS,BLOCK,BUFFER,CONSTANT,CASE,% + COMPONENT,CONFIGURATION,DOWNTO,ELSE,ELSIF,END,ENTITY,EXIT,% + FUNCTION,FOR,FILE,GENERIC,GENERATE,GUARDED,GROUP,IF,IN,INOUT,IS,% + INERTIAL,IMPURE,LIBRARY,LOOP,LABEL,LITERAL,LINKAGE,MAP,MOD,NOT,% + NOR,NAND,NULL,NEXT,NEW,OUT,OF,OR,OTHERS,ON,OPEN,PROCESS,PORT,% + PACKAGE,PURE,PROCEDURE,POSTPONED,RANGE,REM,ROL,ROR,REPORT,RECORD,% + RETURN,REGISTER,REJECT,SIGNAL,SUBTYPE,SLL,SRL,SLA,SRA,SEVERITY,% + SELECT,THEN,TYPE,TRANSPORT,TO,USE,UNITS,UNTIL,VARIABLE,WHEN,WAIT,% + WHILE,XOR,XNOR},% + sensitive=f,% 1998 Gaurav Aggarwal + morecomment=[l]--,% + morestring=[d]{"}% + }[keywords,comments,strings]% +%% +%% VHDL-AMS definition (c) Steffen Klupsch +%% +\lst@definelanguage[AMS]{VHDL}[]{VHDL}% + {morekeywords={ACROSS,ARRAY,BREAK,DISCONNECT,NATURE,NOISE,PORT,% + PROCEDURAL,QUANTITY,SHARED,SPECTRUM,SUBNATURE,TERMINAL,THROUGH,% + TOLERANCE,UNAFFACTED,UNITS}} +\lst@definelanguage{XML}% + {keywords={,CDATA,DOCTYPE,ATTLIST,termdef,ELEMENT,EMPTY,ANY,ID,% + IDREF,IDREFS,ENTITY,ENTITIES,NMTOKEN,NMTOKENS,NOTATION,% + INCLUDE,IGNORE,SYSTEM,PUBLIC,NDATA,PUBLIC,% + PCDATA,REQUIRED,IMPLIED,FIXED,%%% preceded by # + xml,xml:space,xml:lang,version,standalone,default,preserve},% + alsoother=$,% + alsoletter=:,% + keywordsinside=<>,% + morestring=[d]",% ??? doubled + morestring=[d]',% ??? doubled + MoreSelectCharTable=% + \lst@CArgX--\relax\lst@DefDelimB{}{}% + {\ifnum\lst@mode=\lst@insidemode\else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@commentmode{{\lst@commentstyle}}% + \lst@CArgX--\relax\lst@DefDelimE{}{}{}% + \lst@EndComment\lst@commentmode + \lst@CArgX[CDATA[\relax\lst@CDef{}% + {\ifnum\lst@mode=\lst@insidemode + \expandafter\lst@BeginCDATA + \else \expandafter\lst@CArgEmpty + \fi}% + \@empty + \lst@CArgX]]\relax\lst@CDef{}% + {\ifnum\lst@mode=\lst@GPmode + \expandafter\lst@EndComment + \else \expandafter\lst@CArgEmpty + \fi}% + \@empty + }[keywords,comments,strings,html]% +\endinput +%% +%% End of file `lstlang1.sty'. diff --git a/doc/user/lstlang2.sty b/doc/user/lstlang2.sty new file mode 100644 index 0000000000..6aed9ba8f6 --- /dev/null +++ b/doc/user/lstlang2.sty @@ -0,0 +1,1273 @@ +%% +%% This is file `lstlang2.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% lstdrvrs.dtx (with options: `lang2') +%% +%% (w)(c) 1996/1997/1998/1999/2000/2001/2002 Carsten Heinz and/or any +%% other author listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\ProvidesFile{lstlang2} + [2002/07/31 v1.0d listings language file] +%% +%% Abap definition by Knut Lickert +%% +%%%%knut>>>>>new +\lst@definelanguage[R/3 6.10]{ABAP}[R/3 4.6C]{ABAP}% + {morekeywords={try,endtry},% + }[keywords,comments,strings] +%%%%knut<<<<}{{$\rightarrow$}}1{=>}{{$\Rightarrow$}}1,%knut + }[keywords,comments,strings] +\lst@definelanguage[R/3 3.1]{ABAP}[R/2 5.0]{ABAP}{}% +\lst@definelanguage[R/2 5.0]{ABAP}% + {sensitive=f,% + procnamekeys={report,program,form,function},% + morekeywords={*,add,after,alias,analyzer,and,append,area,assign,at,% + authority-check,before,binary,blank,break-point,calendar,call,% + case,change,changing,check,clear,cnt,co,collect,commit,common,% + component,compute,condense,cos,cp,cs,currency-conversion,% + cursor,data,database,dataset,decimals,define,delete,dequeue,% + describe,detail,dialog,directory,div,divide,do,documentation,% + during,dynpro,else,end-of-page,end-of-selection,endat,endcase,% + enddo,endfor,endform,endif,endloop,endmodule,endselect,% + endwhile,enqueue,exceptions,exit,exp,export,exporting,extract,% + field,field-groups,field-symbols,find,for,form,format,free,% + from,function,generating,get,giving,hide,id,if,import,% + importing,in,incl,include,initial,initialization,input,insert,% + interrupt,into,is,language,leave,like,line,lines,line-count, + line-selection,list-processing,load,local,log,logfile,loop,% + margin,mark,mask,memory,menue,message,mod,modify,module,move,% + move-text,multiply,na,new,new-line,new-page,no-gaps,np,ns,% + number,obligatory,occurs,of,on,or,others,output,parameter,% + parameters,parts,perform,pf-status,places,position,process,% + raise,raising,ranges,read,refresh,refresh-dynpro,reject,remote,% + replace,report,reserve,reset,restart,run,screen,scroll,search,% + segments,select,select-options,selection-screen,set,shift,sin,% + single,sqrt,start-of-selection,statement,structure,submit,% + subtract,summary,summing,suppress,system,table,tables,task,% + text,time,to,top-of-page,trace,transaction,transfer,% + transfer-dynpro,translate,type,unpack,update,user-command,% + using,value,when,where,while,window,with,workfile,write,},% + morecomment=[l]",% + morecomment=[f][0]*,% + morestring=[d]'% + }[keywords,comments,strings,procnames] +\lst@definelanguage[R/2 4.3]{ABAP}[R/2 5.0]{ABAP}% + {deletekeywords={function,importing,exporting,changing,exceptions,% + raise,raising}% + }[keywords,comments,strings] +%% +%% Corba IDL definition (c) 1999 Jens T. Berger Thielemann +%% +%% +\lst@definelanguage[CORBA]{IDL}% + {morekeywords={any,attribute,boolean,case,char,const,context,default,% + double,enum,exception,fixed,float,in,inout,interface,long,module,% + native,Object,octet,oneway,out,raises,readonly,sequence,short,% + string,struct,switch,typedef,union,unsigned,void,wchar,wstring,% + FALSE,TRUE},% + sensitive,% + moredirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% + include,pragma,undef,warning},% + morecomment=[l]//,% + morecomment=[s]{/*}{*/},% + morestring=[b]"% + }[keywords,comments,strings]% +%% +%% (Objective) Caml definition (c) 1999 Patrick Cousot +%% +%% +%% Objective CAML and Caml light are freely available, together with a +%% reference manual, at URL ftp.inria.fr/lang/caml-light for the Unix, +%% Windows and Macintosh OS operating systems. +%% +\lst@definelanguage[Objective]{Caml}[light]{Caml} + {deletekeywords={not,prefix,value,where},% + morekeywords={assert,asr,class,closed,constraint,external,false,% + functor,include,inherit,land,lazy,lor,lsl,lsr,lxor,method,mod,% + module,new,open,parser,private,sig,struct,true,val,virtual,when},% + }% +\lst@definelanguage[light]{Caml} + {morekeywords={and,as,begin,do,done,downto,else,end,exception,for,% + fun,function,if,in,let,match,mutable,not,of,or,prefix,rec,then,% + to,try,type,value,where,while,with},% + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[b]",% + moredirectives={open,close,include}% + }[keywords,comments,strings,directives]% +\lst@definelanguage[ibm]{Cobol}[1985]{Cobol}% + {morekeywords={ADDRESS,BEGINNING,COMP-3,COMP-4,COMPUTATIONAL,% + COMPUTATIONAL-3,COMPUTATIONAL-4,DISPLAY-1,EGCS,EJECT,ENDING,% + ENTRY,GOBACK,ID,MORE-LABELS,NULL,NULLS,PASSWORD,RECORDING,% + RETURN-CODE,SERVICE,SKIP1,SKIP2,SKIP3,SORT-CONTROL,SORT-RETURN,% + SUPPRESS,TITLE,WHEN-COMPILED},% + }% +\lst@definelanguage[1985]{Cobol}[1974]{Cobol}% + {morekeywords={ALPHABET,ALPHABETIC-LOWER,ALPHABETIC-UPPER,% + ALPHANUMERIC,ALPHANUMERIC-EDITED,ANY,CLASS,COMMON,CONTENT,% + CONTINUE,DAY-OF-WEEK,END-ADD,END-CALL,END-COMPUTE,END-DELETE,% + END-DIVIDE,END-EVALUATE,END-IF,END-MULTIPLY,END-PERFORM,END-READ,% + END-RECEIVE,END-RETURN,END-REWRITE,END-SEARCH,END-START,% + END-STRING,END-SUBTRACT,END-UNSTRING,END-WRITE,EVALUATE,EXTERNAL,% + FALSE,GLOBAL,INITIALIZE,NUMERIC-EDITED,ORDER,OTHER,% + PACKED-DECIMAL,PADDING,PURGE,REFERENCE,RELOAD,REPLACE,STANDARD-1,% + STANDARD-2,TEST,THEN,TRUE},% + }% +\lst@definelanguage[1974]{Cobol}% + {morekeywords={ACCEPT,ACCESS,ADD,ADVANCING,AFTER,ALL,ALPHABETIC,ALSO,% + ALTER,ALTERNATE,AND,ARE,AREA,AREAS,ASCENDING,ASSIGN,AT,AUTHOR,% + BEFORE,BINARY,BLANK,BLOCK,BOTTOM,BY,CALL,CANCEL,CD,CF,CH,% + CHARACTER,CHARACTERS,CLOCK-UNITS,CLOSE,COBOL,CODE,CODE-SET,% + COLLATING,COLUMN,COMMA,COMMUNICATION,COMP,COMPUTE,CONFIGURATION,% + CONTAINS,CONTROL,CONTROLS,CONVERTING,COPY,CORR,CORRESPONDING,% + COUNT,CURRENCY,DATA,DATE,DATE-COMPILED,DATE-WRITTEN,DAY,DE,% + DEBUG-CONTENTS,DEGUB-ITEM,DEBUG-LINE,DEBUG-NAME,DEBUG-SUB1,% + DEBUG-SUB2,DEBUG-SUB3,DEBUGGING,DECIMAL-POINT,DECLARATIVES,% + DELETE,DELIMITED,DELIMITER,DEPENDING,DESCENDING,DESTINATION,% + DETAIL,DISABLE,DISPLAY,DIVIDE,DIVISION,DOWN,DUPLICATES,DYNAMIC,% + EGI,ELSE,EMI,ENABLE,END,END-OF-PAGE,ENTER,ENVIRONMENT,EOP,EQUAL,% + ERROR,ESI,EVERY,EXCEPTION,EXIT,EXTEND,FD,FILE,FILE-CONTROL,% + FILLER,FINAL,FIRST,FOOTING,FOR,FROM,GENERATE,GIVING,GO,GREATER,% + GROUP,HEADING,HIGH-VALUE,HIGH-VALUES,I-O,I-O-CONTROL,% + IDENTIFICATION,IF,IN,INDEX,INDEXED,INDICATE,INITIAL,INITIATE,% + INPUT,INPUT-OUTPUT,INSPECT,INSTALLATION,INTO,INVALID,IS,JUST,% + JUSTIFIED,KEY,LABEL,LAST,LEADING,LEFT,LENGTH,LESS,LIMIT,LIMITS,% + LINAGE,LINAGE-COUNTER,LINE,LINE-COUNTER,LINES,LINKAGE,LOCK,% + LOW-VALUE,LOW-VALUES,MEMORY,MERGE,MESSAGE,MODE,MODULES,MOVE,% + MULTIPLE,MULTIPLY,NATIVE,NEGATIVE,NEXT,NO,NOT,NUMBER,NUMERIC,% + OBJECT-COMPUTER,OCCURS,OF,OFF,OMITTED,ON,OPEN,OPTIONAL,OR,% + ORGANIZATION,OUTPUT,OVERFLOW,PAGE,PAGE-COUNTER,PERFORM,PF,PH,PIC,% + PICTURE,PLUS,POINTER,POSITION,PRINTING,POSITIVE,PRINTING,% + PROCEDURE,PROCEDURES,PROCEED,PROGRAM,PROGRAM-ID,QUEUE,QUOTE,% + QUOTES,RANDOM,RD,READ,RECEIVE,RECORD,RECORDING,RECORDS,REDEFINES,% + REEL,REFERENCES,RELATIVE,RELEASE,REMAINDER,REMOVAL,RENAMES,% + REPLACING,REPORT,REPORTING,REPORTS,RERUN,RESERVE,RESET,RETURN,% + REVERSED,REWIND,REWRITE,RF,RH,RIGHT,ROUNDED,RUN,SAME,SD,SEARCH,% + SECTION,SECURITY,SEGMENT,SEGMENT-LIMIT,SELECT,SEND,SENTENCE,% + SEPARATE,SEQUENCE,SEQUENTIAL,SET,SIGN,SIZE,SORT,SORT-MERGE,% + SOURCE,SOURCE-COMPUTER,SPACE,SPACES,SPECIAL-NAMES,STANDARD,START,% + STATUS,STOP,STRING,SUB-QUEUE-1,SUB-QUEUE-2,SUB-QUEUE-3,SUBTRACT,% + SUM,SYMBOLIC,SYNC,SYNCHRONIZED,TABLE,TALLYING,TAPE,TERMINAL,% + TERMINATE,TEXT,THAN,THROUGH,THRU,TIME,TIMES,TO,TOP,TRAILING,TYPE,% + UNIT,UNSTRING,UNTIL,UP,UPON,USAGE,USE,USING,VALUE,VALUES,VARYING,% + WHEN,WITH,WORDS,WORKING-STORAGE,WRITE,ZERO,ZEROES,ZEROS},% + alsodigit=-%, + sensitive=f,% ??? + morecomment=[f][commentstyle][6]*,% + morestring=[d]"% ??? doubled + }[keywords,comments,strings]% +\lst@definelanguage{Delphi}% + {morekeywords={and,as,asm,array,begin,case,class,const,constructor,% + destructor,div,do,downto,else,end,except,exports,file,finally,% + for,function,goto,if,implementation,in,inherited,inline,% + initialization,interface,is,label,library,mod,nil,not,object,of,% + or,packed,procedure,program,property,raise,record,repeat,set,% + shl,shr,string,then,to,try,type,unit,until,uses,var,while,with,% + xor,% + absolute,abstract,assembler,at,cdecl,default,dynamic,export,% + external,far,forward,index,name,near,nodefault,on,override,% + private,protected,public,published,read,resident,storedDir,% + virtual,write},% + morendkeywords={Abs,AddExitProc,Addr,AllocMem,AnsiCompareStr,% + AnsiCompareText,AnsiLowerCase,AnsiUpperCase,Append,AppendStr,% + ArcTan,AssignCrt,Assigned,AssignFile,BlockRead,BlockWrite,Break,% + ChangeFileExt,ChDir,Chr,CloseFile,ClrEol,ClrScr,Concat,Continue,% + Copy,Cos,CSeg,CursorTo,Date,DateTimeToFileDate,DateTimeToStr,% + DateTimeToString,DateToStr,DayOfWeek,Dec,DecodeDate,DecodeTime,% + Delete,DeleteFile,DiskFree,DiskSize,Dispose,DisposeStr,% + DoneWinCrt,DSeg,EncodeDate,EncodeTime,Eof,Eoln,Erase,Exclude,% + Exit,Exp,ExpandFileName,ExtractFileExt,ExtractFileName,% + ExtractFilePath,FileAge,FileClose,FileDateToDateTime,FileExists,% + FileGetAttr,FileGetDate,FileOpen,FilePos,FileRead,FileSearch,% + FileSeek,FileSetAttr,FileSetDate,FileSize,FillChar,FindClose,% + FindFirst,FindNext,FloatToDecimal,FloatToStrF,FloatToStr,% + FloatToText,FloatToTextFmt,Flush,FmtLoadStr,FmtStr,Format,% + FormatBuf,FormatDateTime,FormatFloat,Frac,Free,FreeMem,GetDir,% + GetMem,GotoXY,Halt,Hi,High,Inc,Include,InitWinCrt,Insert,Int,% + IntToHex,IntToStr,IOResult,IsValidIdent,KeyPressed,Length,Ln,Lo,% + LoadStr,Low,LowerCase,MaxAvail,MemAvail,MkDir,Move,New,NewStr,% + Now,Odd,Ofs,Ord,ParamCount,ParamStr,Pi,Pos,Pred,Ptr,Random,% + Randomize,Read,ReadBuf,ReadKey,Readln,ReAllocMem,Rename,% + RenameFile,Reset,Rewrite,RmDir,Round,RunError,ScrollTo,Seek,% + SeekEof,SeekEoln,Seg,SetTextBuf,Sin,SizeOf,SPtr,Sqr,Sqrt,SSeg,% + Str,StrCat,StrComp,StrCopy,StrDispose,StrECopy,StrEnd,StrFmt,% + StrLCat,StrIComp,StrLComp,StrLCopy,StrLen,StrLFmt,StrLIComp,% + StrLower,StrMove,StrNew,StrPas,StrPCopy,StrPos,StrScan,StrRScan,% + StrToDate,StrToDateTime,StrToFloat,StrToInt,StrToIntDef,% + StrToTime,StrUpper,Succ,Swap,TextToFloat,Time,TimeToStr,% + TrackCursor,Trunc,Truncate,TypeOf,UpCase,UpperCase,Val,WhereX,% + WhereY,Write,WriteBuf,WriteChar,Writeln},% + sensitive=f,% + morecomment=[s]{(*}{*)},% + morecomment=[s]{\{}{\}},% + morecomment=[l]{//},% 2001 Christian Gudrian + morestring=[d]'% + }[keywords,comments,strings]% +\lst@definelanguage{Eiffel}% + {morekeywords={alias,all,and,as,BIT,BOOLEAN,CHARACTER,check,class,% + creation,Current,debug,deferred,do,DOUBLE,else,elseif,end,% + ensure,expanded,export,external,false,feature,from,frozen,if,% + implies,indexing,infix,inherit,inspect,INTEGER,invariant,is,% + like,local,loop,NONE,not,obsolete,old,once,or,POINTER,prefix,% + REAL,redefine,rename,require,rescue,Result,retry,select,% + separate,STRING,strip,then,true,undefine,unique,until,variant,% + when,xor},% + sensitive,% + morecomment=[l]--,% + morestring=[d]",% + }[keywords,comments,strings]% +%% +%% Euphoria definition (c) 1998 Detlef Reimers +%% +\lst@definelanguage{Euphoria}% + {morekeywords={abort,and,and_bits,append,arctan,atom,by,call,% + call_proc,call_func,c_proc,c_func,clear_screen,close,% + command_line,compare,constant,cos,do,date,else,elsif,end,exit,% + find,floor,for,function,getc,getenv,get_key,gets,global,% + get_pixel,if,include,integer,length,log,match,machine_func,% + machine_proc,mem_copy,mem_set,not,not_bits,or,object,open,% + or_bits,procedure,puts,position,prepend,print,printf,power,peek,% + poke,pixel,poke4,peek4s,peek4u,return,rand,repeat,remainder,% + routine_id,sequence,sqrt,sin,system,sprintf,then,type,to,time,% + trace,tan,while,with,without,xor,xor_bits},% + sensitive,% + morecomment=[l]--,% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% +%% +%% Haskell98 as implemented in Hugs98. See http://www.haskell.org +%% All keywords from Prelude and Standard Libraries +%% (c) 1999 Peter Bartke +%% +\lst@definelanguage{Haskell}% + {otherkeywords={=>},% + morekeywords={abstype,if,then,else,case,class,data,default,deriving,% + hiding,if,in,infix,infixl,infixr,import,instance,let,module,% + newtype,of,qualified,type,where,do,AbsoluteSeek,AppendMode,% + Array,BlockBuffering,Bool,BufferMode,Char,Complex,Double,Either,% + FilePath,Float,Int,Integer,IO,IOError,Ix,LineBuffering,Maybe,% + Ordering,NoBuffering,ReadMode,ReadWriteMode,ReadS,RelativeSeek,% + SeekFromEnd,SeekMode,ShowS,StdGen,String,Void,Bounded,Enum,Eq,% + Eval,ExitCode,exitFailure,exitSuccess,Floating,Fractional,% + Functor,Handle,HandlePosn,IOMode,Integral,List,Monad,MonadPlus,% + MonadZero,Num,Numeric,Ord,Random,RandomGen,Ratio,Rational,Read,% + Real,RealFloat,RealFrac,Show,System,Prelude,EQ,False,GT,Just,% + Left,LT,Nothing,Right,WriteMode,True,abs,accum,accumArray,% + accumulate,acos,acosh,all,and,any,ap,appendFile,applyM,% + approxRational,array,asTypeOf,asin,asinh,assocs,atan,atan2,atanh,% + bounds,bracket,bracket_,break,catch,catMaybes,ceiling,chr,cis,% + compare,concat,concatMap,conjugate,const,cos,cosh,curry,cycle,% + decodeFloat,delete,deleteBy,deleteFirstsBy,denominator,% + digitToInt,div,divMod,drop,dropWhile,either,elem,elems,elemIndex,% + elemIndices,encodeFloat,enumFrom,enumFromThen,enumFromThenTo,% + enumFromTo,error,even,exitFailure,exitWith,exp,exponent,fail,% + filter,filterM,find,findIndex,findIndices,flip,floatDigits,% + floatRadix,floatRange,floatToDigits,floor,foldl,foldM,foldl1,% + foldr,foldr1,fromDouble,fromEnum,fromInt,fromInteger,% + fromIntegral,fromJust,fromMaybe,fromRat,fromRational,% + fromRealFrac,fst,gcd,genericLength,genericTake,genericDrop,% + genericSplitAt,genericIndex,genericReplicate,getArgs,getChar,% + getContents,getEnv,getLine,getProgName,getStdGen,getStdRandom,% + group,groupBy,guard,hClose,hFileSize,hFlush,hGetBuffering,% + hGetChar,hGetContents,hGetLine,hGetPosn,hIsClosed,hIsEOF,hIsOpen,% + hIsReadable,hIsSeekable,hIsWritable,hLookAhead,hPutChar,hPutStr,% + hPutStrLn,hPrint,hReady,hSeek,hSetBuffering,hSetPosn,head,% + hugsIsEOF,hugsHIsEOF,hugsIsSearchErr,hugsIsNameErr,% + hugsIsWriteErr,id,ioError,imagPart,index,indices,init,inits,% + inRange,insert,insertBy,interact,intersect,intersectBy,% + intersperse,intToDigit,ioeGetErrorString,ioeGetFileName,% + ioeGetHandle,isAlreadyExistsError,isAlreadyInUseError,isAlpha,% + isAlphaNum,isAscii,isControl,isDenormalized,isDoesNotExistError,% + isDigit,isEOF,isEOFError,isFullError,isHexDigit,isIEEE,% + isIllegalOperation,isInfinite,isJust,isLower,isNaN,% + isNegativeZero,isNothing,isOctDigit,isPermissionError,isPrefixOf,% + isPrint,isSpace,isSuffixOf,isUpper,isUserError,iterate,ixmap,% + join,last,lcm,length,lex,lexDigits,lexLitChar,liftM,liftM2,% + liftM3,liftM4,liftM5,lines,listArray,listToMaybe,log,logBase,% + lookup,magnitude,makePolar,map,mapAccumL,mapAccumR,mapAndUnzipM,% + mapM,mapM_,mapMaybe,max,maxBound,maximum,maximumBy,maybe,% + maybeToList,min,minBound,minimum,minimumBy,mkPolar,mkStdGen,% + mplus,mod,msum,mzero,negate,next,newStdGen,not,notElem,nub,nubBy,% + null,numerator,odd,openFile,or,ord,otherwise,partition,phase,pi,% + polar,pred,print,product,properFraction,putChar,putStr,putStrLn,% + quot,quotRem,random,randomIO,randomR,randomRIO,randomRs,randoms,% + rangeSize,read,readDec,readFile,readFloat,readHex,readInt,readIO,% + readList,readLitChar,readLn,readParen,readOct,readSigned,reads,% + readsPrec,realPart,realToFrac,recip,rem,repeat,replicate,return,% + reverse,round,scaleFloat,scanl,scanl1,scanr,scanr1,seq,sequence,% + sequence_,setStdGen,show,showChar,showEFloat,showFFloat,% + showFloat,showGFloat,showInt,showList,showLitChar,showParen,% + showSigned,showString,shows,showsPrec,significand,signum,sin,% + sinh,snd,sort,sortBy,span,split,splitAt,sqrt,stderr,stdin,stdout,% + strict,subtract,succ,sum,system,tail,tails,take,takeWhile,tan,% + tanh,toEnum,toInt,toInteger,toLower,toRational,toUpper,transpose,% + truncate,try,uncurry,undefined,unfoldr,union,unionBy,unless,% + unlines,until,unwords,unzip,unzip3,unzip4,unzip5,unzip6,unzip7,% + userError,when,words,writeFile,zero,zip,zip3,zip4,zip5,zip6,zip7,% + zipWith,zipWithM,zipWithM_,zipWith3,zipWith4,zipWith5,zipWith6,% + zipWith7},% + sensitive,% + morecomment=[l]--,% + morecomment=[n]{\{-}{-\}},% + morestring=[b]"% + }[keywords,comments,strings]% +%% +%% IDL definition (c) 1998 Juergen Heim +%% +\lst@definelanguage{IDL}% + {morekeywords={and,begin,case,common,do,else,end,endcase,endelse,% + endfor,endif,endrep,endwhile,eq,for,function,ge,goto,gt,if,le,lt,% + mod,ne,not,of,on_ioerror,or,pro,repeat,return,then,until,while,% + xor,on_error,openw,openr,openu,print,printf,printu,plot,read,% + readf,readu,writeu,stop},% + sensitive=f,% + morecomment=[l];,% + morestring=[d]'% + }[keywords,comments,strings]% +\lst@definelanguage{Lisp}% + {morekeywords={abort,abs,acons,acos,acosh,adjoin,alphanumericp,alter,% + append,apply,apropos,aref,arrayp,ash,asin,asinh,assoc,atan,atanh,% + atom,bit,boole,boundp,break,butlast,byte,catenate,ceiling,cerror,% + char,character,characterp,choose,chunk,cis,close,clrhash,coerce,% + collect,commonp,compile,complement,complex,complexp,concatenate,% + conjugate,cons,consp,constantp,continue,cos,cosh,cotruncate,% + count,delete,denominator,describe,directory,disassemble,% + documentation,dpb,dribble,ed,eighth,elt,enclose,endp,eq,eql,% + equal,equalp,error,eval,evalhook,evenp,every,exp,expand,export,% + expt,fboundp,fceiling,fdefinition,ffloor,fifth,fill,find,first,% + float,floatp,floor,fmakunbound,format,fourth,fround,ftruncate,% + funcall,functionp,gatherer,gcd,generator,gensym,gentemp,get,getf,% + gethash,identity,imagpart,import,inspect,integerp,intern,% + intersection,tively,isqrt,keywordp,last,latch,lcm,ldb,ldiff,% + length,list,listen,listp,load,log,logand,logbitp,logcount,logeqv,% + logior,lognand,lognor,lognot,logtest,logxor,macroexpand,% + makunbound,map,mapc,mapcan,mapcar,mapcon,maphash,mapl,maplist,% + mask,max,member,merge,min,mingle,minusp,mismatch,mod,namestring,% + nbutlast,nconc,nintersection,ninth,not,notany,notevery,nreconc,% + nreverse,nsublis,nsubst,nth,nthcdr,null,numberp,numerator,nunion,% + oddp,open,packagep,pairlis,pathname,pathnamep,phase,plusp,% + position,positions,pprint,previous,princ,print,proclaim,provide,% + random,rassoc,rational,rationalize,rationalp,read,readtablep,% + realp,realpart,reduce,rem,remhash,remove,remprop,replace,require,% + rest,revappend,reverse,room,round,rplaca,rplacd,sbit,scan,schar,% + search,second,series,set,seventh,shadow,signal,signum,sin,sinh,% + sixth,sleep,some,sort,split,sqrt,streamp,string,stringp,sublis,% + subseq,subseries,subsetp,subst,substitute,subtypep,svref,sxhash,% + symbolp,tailp,tan,tanh,tenth,terpri,third,truename,truncate,% + typep,unexport,unintern,union,until,values,vector,vectorp,warn,% + write,zerop,and,assert,case,ccase,cond,ctypecase,decf,declaim,% + defclass,defconstant,defgeneric,defmacro,defmethod,defpackage,% + defparameter,defsetf,defstruct,deftype,defun,defvar,do,dolist,% + dotimes,ecase,encapsulated,etypecase,flet,formatter,gathering,% + incf,iterate,labels,let,locally,loop,macrolet,mapping,or,pop,% + producing,prog,psetf,psetq,push,pushnew,remf,return,rotatef,% + setf,shiftf,step,time,trace,typecase,unless,untrace,when},% + sensitive,% ??? + alsodigit=-,% + morecomment=[l];,% + morecomment=[s]{\#|}{|\#},% 1997 Aslak Raanes + morestring=[b]"% + }[keywords,comments,strings]% +%% +%% AutoLISP/VisualLISP - Stefan Lagotzki, info@lagotzki.de +%% +\lst@definelanguage[Auto]{Lisp}% + {morekeywords={abs,acad_colordlg,acad_helpdlg,acad_strlsort,% + action_tile,add_list,alert,alloc,and,angle,angtof,angtos,append,% + apply,arx,arxload,arxunload,ascii,assoc,atan,atof,atoi,atom,% + atoms-family,autoarxload,autoload,Boole,boundp,caddr,cadr,car,% + cdr,chr,client_data_tile,close,command,cond,cons,cos,cvunit,% + defun,defun-q,defun-q-list-ref,defun-q-list-set,dictadd,dictnext,% + dictremove,dictrename,dictsearch,dimx_tile,dimy_tile,distance,% + distof,done_dialog,end_image,end_list,entdel,entget,entlast,% + entmake,entmakex,entmod,entnext,entsel,entupd,eq,equal,*error*,% + eval,exit,exp,expand,expt,fill_image,findfile,fix,float,foreach,% + function,gc,gcd,get_attr,get_tile,getangle,getcfg,getcname,% + getcorner,getdist,getenv,getfiled,getint,getkword,getorient,% + getpoint,getreal,getstring,getvar,graphscr,grclear,grdraw,grread,% + grtext,grvecs,handent,help,if,initdia,initget,inters,itoa,lambda,% + last,layoutlist,length,list,listp,load,load_dialog,log,logand,% + logior,lsh,mapcar,max,mem,member,menucmd,menugroup,min,minusp,% + mode_tile,namedobjdict,nentsel,nentselp,new_dialog,not,nth,% + null,numberp,open,or,osnap,polar,prin1,princ,print,progn,prompt,% + quit,quote,read,read-char,read-line,redraw,regapp,rem,repeat,% + reverse,rtos,set,set_tile,setcfg,setenv,setfunhelp,setq,% + setvar,setview,sin,slide_image,snvalid,sqrt,ssadd,ssdel,ssget,% + ssgetfirst,sslength,ssmemb,ssname,ssnamex,sssetfirst,startapp,% + start_dialog,start_image,start_list,strcase,strcat,strlen,subst,% + substr,tablet,tblnext,tblobjname,tblsearch,term_dialog,terpri,% + textbox,textpage,textscr,trace,trans,type,unload_dialog,untrace,% + vector_image,ver,vl-acad-defun,vl-acad-undefun,vl-arx-import,% + vl-bb-ref,vl-bb-set,vl-catch-all-apply,% + vl-catch-all-error-message,vl-catch-all-error-p,vl-cmdf,vl-consp,% + vl-directory-files,vl-doc-export,vl-doc-import,vl-doc-ref,% + vl-doc-set,vl-every,vl-exit-with-error,vl-exit-with-value,% + vl-file-copy,vl-file-delete,vl-file-directory-p,vl-file-rename,% + vl-file-size,vl-file-systime,vl-filename-base,% + vl-filename-directory,vl-filename-extension,vl-filename-mktemp,% + vl-get-resource,vl-list*,vl-list->string,% + vl-list-exported-functions,vl-list-length,vl-list-loaded-vlx,% + vl-load-all,vl-load-com,vl-load-reactors,vl-member-if,% + vl-member-if-not,vl-position,vl-prin1-to-string,% + vl-princ-to-string,vl-propagate,vl-registry-delete,% + vl-registry-descendents,vl-registry-read,vl-registry-write,% + vl-remove,vl-remove-if,vl-remove-if-not,vl-some,vl-sort,% + vl-sort-i,vl-string->list,vl-string-elt,vl-string-left-trim,% + vl-string-mismatch,vl-string-position,vl-string-right-trim,% + vl-string-search,vl-string-subst,vl-string-translate,% + vl-string-trim,vl-symbol-name,vl-symbol-value,vl-symbolp,% + vl-unload-vlx,vl-vbaload,vl-vbarun,vl-vlx-loaded-p,vlax-3D-point,% + vlax-add-cmd,vlax-create-object,vlax-curve-getArea,% + vlax-curve-getDistAtParam,vlax-curve-getDistAtPoint,% + vlax-curve-getEndParam,vlax-curve-getEndPoint,% + vlax-curve-getParamAtDist,vlax-curve-getParamAtPoint,% + vlax-curve-getPointAtDist,vlax-curve-getPointAtParam,% + vlax-curve-getStartParam,vlax-curve-getStartPoint,% + vlax-curve-isClosed,vlax-curve-isPeriodic,vlax-curve-isPlanar,% + vlax-curve-getClosestPointTo,% + vlax-curve-getClosestPointToProjection,vlax-curve-getFirstDeriv,% + vlax-curve-getSecondDeriv,vlax-dump-object,% + vlax-ename->vla-object,vlax-erased-p,vlax-for,% + vlax-get-acad-object,vlax-get-object,vlax-get-or-create-object,% + vlax-get-property,vlax-import-type-library,vlax-invoke-method,% + vlax-ldata-delete,vlax-ldata-get,vlax-ldata-list,vlax-ldata-put,% + vlax-ldata-test,vlax-make-safearray,vlax-make-variant,% + vlax-map-collection,vlax-method-applicable-p,% + vlax-object-released-p,vlax-product-key,% + vlax-property-available-p,vlax-put-property,vlax-read-enabled-p,% + vlax-release-object,vlax-remove-cmd,vlax-safearray-fill,% + vlax-safearray-get-dim,vlax-safearray-get-element,% + vlax-safearray-get-l-bound,vlax-safearray-get-u-bound,% + vlax-safearray-put-element,vlax-safearray-type,% + vlax-safearray->list,vlax-tmatrix,vlax-typeinfo-available-p,% + vlax-variant-change-type,vlax-variant-type,vlax-variant-value,% + vlax-vla-object->ename,vlax-write-enabled-p,vlisp-compile,% + vlr-acdb-reactor,vlr-add,vlr-added-p,vlr-beep-reaction,% + vlr-command-reactor,vlr-current-reaction-name,vlr-data,% + vlr-data-set,vlr-deepclone-reactor,vlr-docmanager-reactor,% + vlr-dwg-reactor,vlr-dxf-reactor,vlr-editor-reactor,% + vlr-insert-reactor,vlr-linker-reactor,vlr-lisp-reactor,% + vlr-miscellaneous-reactor,vlr-mouse-reactor,vlr-notification,% + vlr-object-reactor,vlr-owner-add,vlr-owner-remove,vlr-owners,% + vlr-pers,vlr-pers-list,vlr-pers-p,vlr-pers-release,% + vlr-reaction-names,vlr-reaction-set,vlr-reactions,vlr-reactors,% + vlr-remove,vlr-remove-all,vlr-set-notification,% + vlr-sysvar-reactor,vlr-toolbar-reactor,vlr-trace-reaction,% + vlr-type,vlr-types,vlr-undo-reactor,vlr-wblock-reactor,% + vlr-window-reactor,vlr-xref-reactor,vports,wcmatch,while,% + write-char,write-line,xdroom,xdsize,zerop},% + alsodigit=->,% + otherkeywords={1+,1-},% + sensitive=false,% + morecomment=[l];,% + morecomment=[l];;,% + morestring=[b]"% + }[keywords,comments,strings]% +%% +%% Make definitions (c) 2000 Rolf Niepraschk +%% +\lst@definelanguage[gnu]{make}% + {morekeywords={SHELL,MAKE,MAKEFLAGS,$@,$\%,$<,$?,$^,$+,$*,% + @,^,<,\%,+,?,*,% Markus Pahlow + export,unexport,include,override,define,ifdef,ifneq,ifeq,else,% + endif,vpath,subst,patsubst,strip,findstring,filter,filter-out,% + sort,dir,notdir,suffix,basename,addsuffix,addprefix,join,word,% + words,firstword,wildcard,shell,origin,foreach,% + @D,@F,*D,*F,\%D,\%F, +%% Extended (c) 2001 Ralph Becket +%% +\lst@definelanguage{Mercury}% + {otherkeywords={::,->,-->,--->,:-,==,=>,<=,<=>},% + morekeywords={module,include_module,import_module,interface,% + end_module,implementation,mode,is,failure,semidet,nondet,det,% + multi,erroneous,inst,in,out,di,uo,ui,type,typeclass,instance,% + where,with_type,pred,func,lambda,impure,semipure,if,then,else,% + some,all,not,true,fail,pragma,memo,no_inline,inline,loop_check,% + minimal_model,fact_table,type_spec,terminates,does_not_terminate,% + check_termination,promise_only_solution,unsafe_promise_unique,% + source_file,obsolete,import,export,c_header_code,c_code,% + foreign_code,foreign_proc,may_call_mercury,will_not_call_mercury,% + thread_safe,not_thread_safe},% + sensitive=t,% + morecomment=[l]\%,% + morecomment=[s]{/*}{*/},% + morestring=[bd]",% + morestring=[bd]'% + }[keywords,comments,strings]% +%% +%% Miranda definition (c) 1998 Peter Bartke +%% +%% Miranda: pure lazy functional language with polymorphic type system, +%% garbage collection and functions as first class citizens +%% +\lst@definelanguage{Miranda}% + {morekeywords={abstype,div,if,mod,otherwise,readvals,show,type,where,% + with,bool,char,num,sys_message,False,True,Appendfile,Closefile,% + Exit,Stderr,Stdout,System,Tofile,\%include,\%export,\%free,% + \%insert,abs,and,arctan,cjustify,code,concat,const,converse,cos,% + decode,digit,drop,dropwhile,entier,error,exp,filemode,filter,% + foldl,foldl1,foldr,foldr1,force,fst,getenv,hd,hugenum,id,index,% + init,integer,iterate,last,lay,layn,letter,limit,lines,ljustify,% + log,log10,map,map2,max,max2,member,merge,min,min2,mkset,neg,% + numval,or,pi,postfix,product,read,rep,repeat,reverse,rjustify,% + scan,seq,showfloat,shownum,showscaled,sin,snd,sort,spaces,sqrt,% + subtract,sum,system,take,takewhile,tinynum,tl,transpose,undef,% + until,zip2,zip3,zip4,zip5,zip6,zip},% + sensitive,% + morecomment=[l]||,% + morestring=[b]"% + }[keywords,comments,strings]% +%% +%% ML definition (c) 1999 Torben Hoffmann +%% +\lst@definelanguage{ML}% + {morekeywords={abstype,and,andalso,as,case,do,datatype,else,end,% + eqtype,exception,fn,fun,functor,handle,if,in,include,infix,% + infixr,let,local,nonfix,of,op,open,orelse,raise,rec,sharing,sig,% + signature,struct,structure,then,type,val,with,withtype,while},% + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[d]"% + }[keywords,comments,strings]% +%% +%% PHP definition by Luca Balzerani, +%% +\lst@definelanguage{PHP}% + {morekeywords={% + abs,acos,acosh,addcslashes,addslashes,apache_child_terminate,% + apache_note,apache_setenv,array_change_key_case,array_chunk,% + array_diff,array_fill,array_filter,array_flip,array_intersect,% + array_keys,array_map,array_merge_recursive,array_merge,% + array_pad,array_pop,array_push,array_rand,array_reduce,% + array_search,array_shift,array_slice,array_splice,array_sum,% + array_unshift,array_values,array_walk,array,arsort,ascii2ebcdic,% + asinh,asort,aspell_check_raw,aspell_check,aspell_new,% + assert_options,assert,atan,atan2,atanh,base_convert,% + base64_encode,basename,bcadd,bccomp,bcdiv,bcmod,bcmul,bcpow,% + bcsqrt,bcsub,bin2hex,bind_textdomain_codeset,bindec,% + bzclose,bzcompress,bzdecompress,bzerrno,bzerror,bzerrstr,% + bzopen,bzread,bzwrite,cal_days_in_month,cal_from_jd,cal_info,% + call_user_func_array,call_user_func,call_user_method_array,% + ccvs_add,ccvs_auth,ccvs_command,ccvs_count,ccvs_delete,% + ccvs_init,ccvs_lookup,ccvs_new,ccvs_report,ccvs_return,% + ccvs_sale,ccvs_status,ccvs_textvalue,ccvs_void,ceil,chdir,% + checkdnsrr,chgrp,chmod,chop,chown,chr,chroot,chunk_split,% + clearstatcache,closedir,closelog,com_addref,com_get,com_invoke,% + com_load_typelib,com_load,com_propget,com_propput,com_propset,% + com_set,compact,connection_aborted,connection_status,% + constant,convert_cyr_string,copy,cos,cosh,count_chars,count,% + cpdf_add_outline,cpdf_arc,cpdf_begin_text,cpdf_circle,cpdf_clip,% + cpdf_closepath_fill_stroke,cpdf_closepath_stroke,cpdf_closepath,% + cpdf_curveto,cpdf_end_text,cpdf_fill_stroke,cpdf_fill,% + cpdf_finalize,cpdf_global_set_document_limits,cpdf_import_jpeg,% + cpdf_moveto,cpdf_newpath,cpdf_open,cpdf_output_buffer,% + cpdf_place_inline_image,cpdf_rect,cpdf_restore,cpdf_rlineto,% + cpdf_rotate_text,cpdf_rotate,cpdf_save_to_file,cpdf_save,% + cpdf_set_action_url,cpdf_set_char_spacing,cpdf_set_creator,% + cpdf_set_font_directories,cpdf_set_font_map_file,cpdf_set_font,% + cpdf_set_keywords,cpdf_set_leading,cpdf_set_page_animation,% + cpdf_set_text_matrix,cpdf_set_text_pos,cpdf_set_text_rendering,% + cpdf_set_title,cpdf_set_viewer_preferences,% + cpdf_setdash,cpdf_setflat,cpdf_setgray_fill,cpdf_setgray_stroke,% + cpdf_setlinecap,cpdf_setlinejoin,cpdf_setlinewidth,% + cpdf_setrgbcolor_fill,cpdf_setrgbcolor_stroke,cpdf_setrgbcolor,% + cpdf_show,cpdf_stringwidth,cpdf_stroke,cpdf_text,cpdf_translate,% + crack_closedict,crack_getlastmessage,crack_opendict,crc32,% + crypt,ctype_alnum,ctype_alpha,ctype_cntrl,ctype_digit,% + ctype_lower,ctype_print,ctype_punct,ctype_space,ctype_upper,% + curl_close,curl_errno,curl_error,curl_exec,curl_getinfo,% + curl_setopt,curl_version,current,cybercash_base64_decode,% + cybercash_decr,cybercash_encr,cybermut_creerformulairecm,% + cybermut_testmac,cyrus_authenticate,cyrus_bind,cyrus_close,% + cyrus_query,cyrus_unbind,date,dba_close,dba_delete,dba_exists,% + dba_firstkey,dba_insert,dba_nextkey,dba_open,dba_optimize,% + dba_replace,dba_sync,dbase_add_record,dbase_close,dbase_create,% + dbase_get_record_with_names,dbase_get_record,dbase_numfields,% + dbase_open,dbase_pack,dbase_replace_record,dblist,dbmclose,% + dbmexists,dbmfetch,dbmfirstkey,dbminsert,dbmnextkey,dbmopen,% + dbplus_add,dbplus_aql,dbplus_chdir,dbplus_close,dbplus_curr,% + dbplus_errno,dbplus_find,dbplus_first,dbplus_flush,% + dbplus_freelock,dbplus_freerlocks,dbplus_getlock,% + dbplus_info,dbplus_last,dbplus_lockrel,dbplus_next,dbplus_open,% + dbplus_rchperm,dbplus_rcreate,dbplus_rcrtexact,dbplus_rcrtlike,% + dbplus_restorepos,dbplus_rkeys,dbplus_ropen,dbplus_rquery,% + dbplus_rsecindex,dbplus_runlink,dbplus_rzap,dbplus_savepos,% + dbplus_setindexbynumber,dbplus_sql,dbplus_tcl,dbplus_tremove,% + dbplus_undoprepare,dbplus_unlockrel,dbplus_unselect,% + dbplus_xlockrel,dbplus_xunlockrel,dbx_close,dbx_compare,% + dbx_error,dbx_query,dbx_sort,dcgettext,dcngettext,debugger_off,% + decbin,dechex,decoct,define_syslog_variables,define,defined,% + delete,dgettext,die,dio_close,dio_fcntl,dio_open,dio_read,% + dio_stat,dio_truncate,dio_write,dirname,disk_free_space,% + diskfreespace,dl,dngettext,domxml_add_root,domxml_attributes,% + domxml_dumpmem,domxml_get_attribute,domxml_new_child,% + domxml_node_set_content,domxml_node_unlink_node,domxml_node,% + domxml_set_attribute,domxml_version,dotnet_load,doubleval,each,% + easter_days,ebcdic2ascii,echo,empty,end,ereg_replace,ereg,% + eregi,error_log,error_reporting,escapeshellarg,escapeshellcmd,% + exec,exit,exp,explode,expm1,extension_loaded,extract,ezmlm_hash,% + fbsql_autocommit,fbsql_change_user,fbsql_close,fbsql_commit,% + fbsql_create_blob,fbsql_create_clob,fbsql_create_db,% + fbsql_database_password,fbsql_database,fbsql_db_query,% + fbsql_drop_db,fbsql_errno,fbsql_error,fbsql_fetch_array,% + fbsql_fetch_field,fbsql_fetch_lengths,fbsql_fetch_object,% + fbsql_field_flags,fbsql_field_len,fbsql_field_name,% + fbsql_field_table,fbsql_field_type,fbsql_free_result,% + fbsql_hostname,fbsql_insert_id,fbsql_list_dbs,fbsql_list_fields,% + fbsql_next_result,fbsql_num_fields,fbsql_num_rows,% + fbsql_pconnect,fbsql_query,fbsql_read_blob,fbsql_read_clob,% + fbsql_rollback,fbsql_select_db,fbsql_set_lob_mode,% + fbsql_start_db,fbsql_stop_db,fbsql_tablename,fbsql_username,% + fclose,fdf_add_template,fdf_close,fdf_create,fdf_get_file,% + fdf_get_value,fdf_next_field_name,fdf_open,fdf_save,fdf_set_ap,% + fdf_set_file,fdf_set_flags,fdf_set_javascript_action,% + fdf_set_status,fdf_set_submit_form_action,fdf_set_value,feof,% + fgetc,fgetcsv,fgets,fgetss,file_exists,file,fileatime,filectime,% + fileinode,filemtime,fileowner,fileperms,filepro_fieldcount,% + filepro_fieldtype,filepro_fieldwidth,filepro_retrieve,% + filepro,filesize,filetype,floatval,flock,floor,flush,fopen,% + fputs,fread,frenchtojd,fribidi_log2vis,fscanf,fseek,fsockopen,% + ftell,ftok,ftp_cdup,ftp_chdir,ftp_connect,ftp_delete,ftp_exec,% + ftp_fput,ftp_get,ftp_login,ftp_mdtm,ftp_mkdir,ftp_nlist,% + ftp_put,ftp_pwd,ftp_quit,ftp_rawlist,ftp_rename,ftp_rmdir,% + ftp_size,ftp_systype,ftruncate,func_get_arg,func_get_args,% + function_exists,fwrite,get_browser,get_cfg_var,% + get_class_vars,get_class,get_current_user,get_declared_classes,% + get_defined_functions,get_defined_vars,get_extension_funcs,% + get_included_files,get_loaded_extensions,get_magic_quotes_gpc,% + get_meta_tags,get_object_vars,get_parent_class,% + get_resource_type,getallheaders,getcwd,getdate,getenv,% + gethostbyname,gethostbynamel,getimagesize,getlastmod,getmxrr,% + getmyinode,getmypid,getmyuid,getprotobyname,getprotobynumber,% + getrusage,getservbyname,getservbyport,gettext,gettimeofday,% + gmdate,gmmktime,gmp_abs,gmp_add,gmp_and,gmp_clrbit,gmp_cmp,% + gmp_div_q,gmp_div_qr,gmp_div_r,gmp_div,gmp_divexact,gmp_fact,% + gmp_gcdext,gmp_hamdist,gmp_init,gmp_intval,gmp_invert,% + gmp_legendre,gmp_mod,gmp_mul,gmp_neg,gmp_or,gmp_perfect_square,% + gmp_pow,gmp_powm,gmp_prob_prime,gmp_random,gmp_scan0,gmp_scan1,% + gmp_sign,gmp_sqrt,gmp_sqrtrem,gmp_strval,gmp_sub,gmp_xor,% + gregoriantojd,gzclose,gzcompress,gzdeflate,gzencode,gzeof,% + gzgetc,gzgets,gzgetss,gzinflate,gzopen,gzpassthru,gzputs,gzread,% + gzseek,gztell,gzuncompress,gzwrite,header,headers_sent,hebrev,% + hexdec,highlight_file,highlight_string,htmlentities,% + hw_array2objrec,hw_changeobject,hw_children,hw_childrenobj,% + hw_connect,hw_connection_info,hw_cp,hw_deleteobject,% + hw_docbyanchorobj,hw_document_attributes,hw_document_bodytag,% + hw_document_setcontent,hw_document_size,hw_dummy,hw_edittext,% + hw_errormsg,hw_free_document,hw_getanchors,hw_getanchorsobj,% + hw_getchildcoll,hw_getchildcollobj,hw_getchilddoccoll,% + hw_getobject,hw_getobjectbyquery,hw_getobjectbyquerycoll,% + hw_getobjectbyqueryobj,hw_getparents,hw_getparentsobj,% + hw_getremote,hw_getremotechildren,hw_getsrcbydestobj,hw_gettext,% + hw_identify,hw_incollections,hw_info,hw_inscoll,hw_insdoc,% + hw_insertdocument,hw_insertobject,hw_mapid,hw_modifyobject,% + hw_new_document,hw_objrec2array,hw_output_document,hw_pconnect,% + hw_root,hw_setlinkroot,hw_stat,hw_unlock,hw_who,hypot,% + ibase_blob_cancel,ibase_blob_close,ibase_blob_create,% + ibase_blob_get,ibase_blob_import,ibase_blob_info,% + ibase_close,ibase_commit,ibase_connect,ibase_errmsg,% + ibase_fetch_object,ibase_fetch_row,ibase_field_info,% + ibase_free_result,ibase_num_fields,ibase_pconnect,ibase_prepare,% + ibase_rollback,ibase_timefmt,ibase_trans,icap_close,% + icap_delete_calendar,icap_delete_event,icap_fetch_event,% + icap_list_events,icap_open,icap_rename_calendar,icap_reopen,% + icap_store_event,iconv_get_encoding,iconv_set_encoding,iconv,% + ifx_blobinfile_mode,ifx_byteasvarchar,ifx_close,ifx_connect,% + ifx_create_blob,ifx_create_char,ifx_do,ifx_error,ifx_errormsg,% + ifx_fieldproperties,ifx_fieldtypes,ifx_free_blob,ifx_free_char,% + ifx_get_blob,ifx_get_char,ifx_getsqlca,ifx_htmltbl_result,% + ifx_num_fields,ifx_num_rows,ifx_pconnect,ifx_prepare,ifx_query,% + ifx_update_blob,ifx_update_char,ifxus_close_slob,% + ifxus_free_slob,ifxus_open_slob,ifxus_read_slob,ifxus_seek_slob,% + ifxus_write_slob,ignore_user_abort,image2wbmp,% + imagearc,imagechar,imagecharup,imagecolorallocate,imagecolorat,% + imagecolorclosestalpha,imagecolorclosesthwb,% + imagecolorexact,imagecolorexactalpha,imagecolorresolve,% + imagecolorset,imagecolorsforindex,imagecolorstotal,% + imagecopy,imagecopymerge,imagecopymergegray,imagecopyresampled,% + imagecreate,imagecreatefromgd,imagecreatefromgd2,% + imagecreatefromgif,imagecreatefromjpeg,imagecreatefrompng,% + imagecreatefromwbmp,imagecreatefromxbm,imagecreatefromxpm,% + imagedashedline,imagedestroy,imageellipse,imagefill,% + imagefilledellipse,imagefilledpolygon,imagefilledrectangle,% + imagefontheight,imagefontwidth,imageftbbox,imagefttext,% + imagegd,imagegd2,imagegif,imageinterlace,imagejpeg,imageline,% + imagepalettecopy,imagepng,imagepolygon,imagepsbbox,% + imagepsextendfont,imagepsfreefont,imagepsloadfont,% + imagepstext,imagerectangle,imagesetbrush,imagesetpixel,% + imagesetthickness,imagesettile,imagestring,imagestringup,% + imagesy,imagetruecolortopalette,imagettfbbox,imagettftext,% + imagewbmp,imap_8bit,imap_alerts,imap_append,imap_base64,% + imap_body,imap_bodystruct,imap_check,imap_clearflag_full,% + imap_createmailbox,imap_delete,imap_deletemailbox,imap_errors,% + imap_fetch_overview,imap_fetchbody,imap_fetchheader,% + imap_get_quota,imap_getmailboxes,imap_getsubscribed,imap_header,% + imap_headers,imap_last_error,imap_listmailbox,% + imap_mail_compose,imap_mail_copy,imap_mail_move,imap_mail,% + imap_mime_header_decode,imap_msgno,imap_num_msg,imap_num_recent,% + imap_ping,imap_popen,imap_qprint,imap_renamemailbox,imap_reopen,% + imap_rfc822_parse_headers,imap_rfc822_write_address,% + imap_search,imap_set_quota,imap_setacl,imap_setflag_full,% + imap_status,imap_subscribe,imap_thread,imap_uid,imap_undelete,% + imap_utf7_decode,imap_utf7_encode,imap_utf8,implode,% + in_array,include_once,include,ingres_autocommit,ingres_close,% + ingres_connect,ingres_fetch_array,ingres_fetch_object,% + ingres_field_length,ingres_field_name,ingres_field_nullable,% + ingres_field_scale,ingres_field_type,ingres_num_fields,% + ingres_pconnect,ingres_query,ingres_rollback,ini_alter,% + ini_get,ini_restore,ini_set,intval,ip2long,iptcembed,iptcparse,% + ircg_disconnect,ircg_fetch_error_msg,ircg_get_username,% + ircg_ignore_add,ircg_ignore_del,ircg_is_conn_alive,ircg_join,% + ircg_lookup_format_messages,ircg_msg,ircg_nick,% + ircg_nickname_unescape,ircg_notice,ircg_part,ircg_pconnect,% + ircg_set_current,ircg_set_file,ircg_set_on_die,ircg_topic,% + is_array,is_bool,is_dir,is_double,is_executable,is_file,% + is_int,is_integer,is_link,is_long,is_null,is_numeric,is_object,% + is_real,is_resource,is_scalar,is_string,is_subclass_of,% + is_writable,is_writeable,isset,java_last_exception_clear,% + jddayofweek,jdmonthname,jdtofrench,jdtogregorian,jdtojewish,% + jdtounix,jewishtojd,join,jpeg2wbmp,juliantojd,key,krsort,ksort,% + ldap_8859_to_t61,ldap_add,ldap_bind,ldap_close,ldap_compare,% + ldap_count_entries,ldap_delete,ldap_dn2ufn,ldap_err2str,% + ldap_error,ldap_explode_dn,ldap_first_attribute,% + ldap_first_reference,ldap_free_result,ldap_get_attributes,% + ldap_get_entries,ldap_get_option,ldap_get_values_len,% + ldap_list,ldap_mod_add,ldap_mod_del,ldap_mod_replace,% + ldap_next_attribute,ldap_next_entry,ldap_next_reference,% + ldap_parse_result,ldap_read,ldap_rename,ldap_search,% + ldap_set_rebind_proc,ldap_sort,ldap_start_tls,ldap_t61_to_8859,% + leak,levenshtein,link,linkinfo,list,localeconv,localtime,log,% + log1p,long2ip,lstat,ltrim,mail,% + mailparse_msg_create,mailparse_msg_extract_part_file,% + mailparse_msg_free,mailparse_msg_get_part_data,% + mailparse_msg_get_structure,mailparse_msg_parse_file,% + mailparse_rfc822_parse_addresses,mailparse_stream_encode,% + max,mb_convert_encoding,mb_convert_kana,mb_convert_variables,% + mb_decode_numericentity,mb_detect_encoding,mb_detect_order,% + mb_encode_numericentity,mb_http_input,mb_http_output,% + mb_language,mb_output_handler,mb_parse_str,% + mb_send_mail,mb_strcut,mb_strimwidth,mb_strlen,mb_strpos,% + mb_strwidth,mb_substitute_character,mb_substr,mcal_append_event,% + mcal_create_calendar,mcal_date_compare,mcal_date_valid,% + mcal_day_of_year,mcal_days_in_month,mcal_delete_calendar,% + mcal_event_add_attribute,mcal_event_init,mcal_event_set_alarm,% + mcal_event_set_class,mcal_event_set_description,% + mcal_event_set_recur_daily,mcal_event_set_recur_monthly_mday,% + mcal_event_set_recur_none,mcal_event_set_recur_weekly,% + mcal_event_set_start,mcal_event_set_title,mcal_expunge,% + mcal_fetch_event,mcal_is_leap_year,mcal_list_alarms,% + mcal_next_recurrence,mcal_open,mcal_popen,mcal_rename_calendar,% + mcal_snooze,mcal_store_event,mcal_time_valid,mcal_week_of_year,% + mcrypt_cfb,mcrypt_create_iv,mcrypt_decrypt,mcrypt_ecb,% + mcrypt_enc_get_block_size,mcrypt_enc_get_iv_size,% + mcrypt_enc_get_modes_name,mcrypt_enc_get_supported_key_sizes,% + mcrypt_enc_is_block_algorithm,mcrypt_enc_is_block_mode,% + mcrypt_encrypt,mcrypt_generic_deinit,mcrypt_generic_end,% + mcrypt_generic,mcrypt_get_block_size,mcrypt_get_cipher_name,% + mcrypt_get_key_size,mcrypt_list_algorithms,mcrypt_list_modes,% + mcrypt_module_get_algo_block_size,% + mcrypt_module_get_supported_key_sizes,% + mcrypt_module_is_block_algorithm,mcrypt_module_is_block_mode,% + mcrypt_module_self_test,mcrypt_ofb,md5_file,md5,% + metaphone,method_exists,mhash_count,mhash_get_block_size,% + mhash_keygen_s2k,mhash,microtime,min,ming_setcubicthreshold,% + ming_useswfversion,mkdir,mktime,move_uploaded_file,% + msession_count,msession_create,msession_destroy,% + msession_find,msession_get_array,msession_get,msession_getdata,% + msession_list,msession_listvar,msession_lock,msession_plugin,% + msession_set_array,msession_set,msession_setdata,% + msession_uniq,msession_unlock,msql_affected_rows,msql_close,% + msql_create_db,msql_createdb,msql_data_seek,msql_dbname,% + msql_dropdb,msql_error,msql_fetch_array,msql_fetch_field,% + msql_fetch_row,msql_field_seek,msql_fieldflags,msql_fieldlen,% + msql_fieldtable,msql_fieldtype,msql_free_result,msql_freeresult,% + msql_list_fields,msql_list_tables,msql_listdbs,msql_listfields,% + msql_num_fields,msql_num_rows,msql_numfields,msql_numrows,% + msql_query,msql_regcase,msql_result,msql_select_db,% + msql_tablename,msql,mssql_bind,mssql_close,mssql_connect,% + mssql_execute,mssql_fetch_array,mssql_fetch_assoc,% + mssql_fetch_field,mssql_fetch_object,mssql_fetch_row,% + mssql_field_name,mssql_field_seek,mssql_field_type,% + mssql_get_last_message,mssql_guid_string,mssql_init,% + mssql_min_message_severity,mssql_next_result,mssql_num_fields,% + mssql_pconnect,mssql_query,mssql_result,mssql_rows_affected,% + mt_getrandmax,mt_rand,mt_srand,muscat_close,muscat_get,% + muscat_setup_net,muscat_setup,mysql_affected_rows,% + mysql_close,mysql_connect,mysql_create_db,mysql_data_seek,% + mysql_db_query,mysql_drop_db,mysql_errno,mysql_error,% + mysql_fetch_array,mysql_fetch_assoc,mysql_fetch_field,% + mysql_fetch_object,mysql_fetch_row,mysql_field_flags,% + mysql_field_name,mysql_field_seek,mysql_field_table,% + mysql_free_result,mysql_get_client_info,mysql_get_host_info,% + mysql_get_server_info,mysql_insert_id,mysql_list_dbs,% + mysql_list_tables,mysql_num_fields,mysql_num_rows,% + mysql_query,mysql_result,mysql_select_db,mysql_tablename,% + natcasesort,natsort,ncurses_addch,ncurses_addchnstr,% + ncurses_addnstr,ncurses_addstr,ncurses_assume_default_colors,% + ncurses_attron,ncurses_attrset,ncurses_baudrate,ncurses_beep,% + ncurses_bkgdset,ncurses_border,ncurses_can_change_color,% + ncurses_clear,ncurses_clrtobot,ncurses_clrtoeol,% + ncurses_curs_set,ncurses_def_prog_mode,ncurses_def_shell_mode,% + ncurses_delay_output,ncurses_delch,ncurses_deleteln,% + ncurses_doupdate,ncurses_echo,ncurses_echochar,ncurses_end,% + ncurses_erasechar,ncurses_filter,ncurses_flash,ncurses_flushinp,% + ncurses_halfdelay,ncurses_has_colors,ncurses_has_ic,% + ncurses_has_key,ncurses_hline,ncurses_inch,ncurses_init_color,% + ncurses_init,ncurses_insch,ncurses_insdelln,ncurses_insertln,% + ncurses_instr,ncurses_isendwin,ncurses_keyok,ncurses_killchar,% + ncurses_move,ncurses_mvaddch,ncurses_mvaddchnstr,% + ncurses_mvaddnstr,ncurses_mvaddstr,ncurses_mvcur,% + ncurses_mvgetch,ncurses_mvhline,ncurses_mvinch,ncurses_mvvline,% + ncurses_napms,ncurses_newwin,ncurses_nl,ncurses_nocbreak,% + ncurses_nonl,ncurses_noqiflush,ncurses_noraw,ncurses_putp,% + ncurses_raw,ncurses_refresh,ncurses_resetty,ncurses_savetty,% + ncurses_scr_init,ncurses_scr_restore,ncurses_scr_set,% + ncurses_slk_attr,ncurses_slk_attroff,ncurses_slk_attron,% + ncurses_slk_clear,ncurses_slk_color,ncurses_slk_init,% + ncurses_slk_refresh,ncurses_slk_restore,ncurses_slk_touch,% + ncurses_standout,ncurses_start_color,ncurses_termattrs,% + ncurses_typeahead,ncurses_ungetch,ncurses_use_default_colors,% + ncurses_use_extended_names,ncurses_vidattr,ncurses_vline,% + next,ngettext,nl_langinfo,nl2br,notes_body,notes_copy_db,% + notes_create_note,notes_drop_db,notes_find_note,% + notes_list_msgs,notes_mark_read,notes_mark_unread,% + notes_search,notes_unread,notes_version,number_format,ob_clean,% + ob_end_flush,ob_flush,ob_get_contents,ob_get_length,% + ob_gzhandler,ob_iconv_handler,ob_implicit_flush,ob_start,% + ocicancel,ocicollappend,ocicollassign,ocicollassignelem,% + ocicollmax,ocicollsize,ocicolltrim,ocicolumnisnull,% + ocicolumnprecision,ocicolumnscale,ocicolumnsize,ocicolumntype,% + ocicommit,ocidefinebyname,ocierror,ociexecute,ocifetch,% + ocifetchstatement,ocifreecollection,ocifreecursor,ocifreedesc,% + ociinternaldebug,ociloadlob,ocilogoff,ocilogon,ocinewcollection,% + ocinewdescriptor,ocinlogon,ocinumcols,ociparse,ociplogon,% + ocirollback,ocirowcount,ocisavelob,ocisavelobfile,% + ocisetprefetch,ocistatementtype,ociwritelobtofile,octdec,% + odbc_binmode,odbc_close_all,odbc_close,odbc_columnprivileges,% + odbc_commit,odbc_connect,odbc_cursor,odbc_do,odbc_error,% + odbc_exec,odbc_execute,odbc_fetch_array,odbc_fetch_into,% + odbc_fetch_row,odbc_field_len,odbc_field_name,odbc_field_num,% + odbc_field_scale,odbc_field_type,odbc_foreignkeys,% + odbc_gettypeinfo,odbc_longreadlen,odbc_next_result,% + odbc_num_rows,odbc_pconnect,odbc_prepare,odbc_primarykeys,% + odbc_procedures,odbc_result_all,odbc_result,odbc_rollback,% + odbc_specialcolumns,odbc_statistics,odbc_tableprivileges,% + opendir,openlog,openssl_csr_export_to_file,openssl_csr_export,% + openssl_csr_sign,openssl_error_string,openssl_free_key,% + openssl_get_publickey,openssl_open,openssl_pkcs7_decrypt,% + openssl_pkcs7_sign,openssl_pkcs7_verify,% + openssl_pkey_export,openssl_pkey_new,openssl_private_decrypt,% + openssl_public_decrypt,openssl_public_encrypt,openssl_seal,% + openssl_verify,openssl_x509_check_private_key,% + openssl_x509_export_to_file,openssl_x509_export,% + openssl_x509_parse,openssl_x509_read,ora_bind,ora_close,% + ora_columnsize,ora_columntype,ora_commit,ora_commitoff,% + ora_do,ora_error,ora_errorcode,ora_exec,ora_fetch_into,% + ora_getcolumn,ora_logoff,ora_logon,ora_numcols,ora_numrows,% + ora_parse,ora_plogon,ora_rollback,ord,overload,ovrimos_close,% + ovrimos_connect,ovrimos_cursor,ovrimos_exec,ovrimos_execute,% + ovrimos_fetch_row,ovrimos_field_len,ovrimos_field_name,% + ovrimos_field_type,ovrimos_free_result,ovrimos_longreadlen,% + ovrimos_num_rows,ovrimos_prepare,ovrimos_result_all,% + ovrimos_rollback,pack,parse_ini_file,parse_str,parse_url,% + pathinfo,pclose,pdf_add_annotation,pdf_add_bookmark,% + pdf_add_locallink,pdf_add_note,pdf_add_outline,pdf_add_pdflink,% + pdf_add_weblink,pdf_arc,pdf_arcn,pdf_attach_file,pdf_begin_page,% + pdf_begin_template,pdf_circle,pdf_clip,pdf_close_image,% + pdf_close_pdi,pdf_close,pdf_closepath_fill_stroke,% + pdf_closepath,pdf_concat,pdf_continue_text,pdf_curveto,% + pdf_end_page,pdf_end_pattern,pdf_end_template,pdf_endpath,% + pdf_fill,pdf_findfont,pdf_get_buffer,pdf_get_font,% + pdf_get_fontsize,pdf_get_image_height,pdf_get_image_width,% + pdf_get_minorversion,pdf_get_parameter,pdf_get_pdi_parameter,% + pdf_get_value,pdf_initgraphics,pdf_lineto,pdf_makespotcolor,% + pdf_new,pdf_open_ccitt,pdf_open_file,pdf_open_gif,% + pdf_open_image,pdf_open_jpeg,pdf_open_memory_image,% + pdf_open_pdi,pdf_open_png,pdf_open_tiff,pdf_open,% + pdf_place_pdi_page,pdf_rect,pdf_restore,pdf_rotate,pdf_save,% + pdf_set_border_color,pdf_set_border_dash,pdf_set_border_style,% + pdf_set_duration,pdf_set_font,pdf_set_horiz_scaling,% + pdf_set_info_creator,pdf_set_info_keywords,pdf_set_info_subject,% + pdf_set_info,pdf_set_leading,pdf_set_parameter,pdf_set_text_pos,% + pdf_set_text_rise,pdf_set_transition,pdf_set_value,% + pdf_setcolor,pdf_setdash,pdf_setflat,pdf_setfont,% + pdf_setgray_stroke,pdf_setgray,pdf_setlinecap,pdf_setlinejoin,% + pdf_setmatrix,pdf_setmiterlimit,pdf_setpolydash,% + pdf_setrgbcolor_stroke,pdf_setrgbcolor,pdf_show_boxed,% + pdf_show,pdf_skew,pdf_stringwidth,pdf_stroke,pdf_translate,% + pfpro_init,pfpro_process_raw,pfpro_process,pfpro_version,% + pg_cancel_query,pg_client_encoding,pg_close,pg_cmdtuples,% + pg_connection_busy,pg_connection_reset,pg_connection_status,% + pg_copy_to,pg_dbname,pg_end_copy,pg_errormessage,% + pg_escape_string,pg_exec,pg_fetch_array,pg_fetch_object,% + pg_fieldisnull,pg_fieldname,pg_fieldnum,pg_fieldprtlen,% + pg_fieldtype,pg_freeresult,pg_get_result,pg_getlastoid,pg_host,% + pg_last_notice,pg_lo_close,pg_lo_seek,pg_lo_tell,pg_loclose,% + pg_loexport,pg_loimport,pg_loopen,pg_loread,pg_loreadall,% + pg_lowrite,pg_numfields,pg_numrows,pg_options,pg_pconnect,% + pg_put_line,pg_request_cancel,pg_result_error,pg_result_status,% + pg_send_query,pg_set_client_encoding,pg_trace,pg_tty,pg_untrace,% + php_sapi_name,php_uname,phpcredits,phpinfo, +%% +\lst@definelanguage{Prolog}% + {morekeywords={op,mod,abort,ancestors,arg,ascii,ask,assert,asserta,% + assertz,atom,atomic,char,clause,close,concat,consult,ed,ef,em,% + eof,fail,file,findall,write,functor,getc,integer,is,length,% + listing,load,name,nl,nonvar,not,numbervars,op,or,pp,prin,print,% + private,prompt,putc,ratom,read,read_from_this_file,rename,repeat,% + retract,retractall,save,see,seeing,seen,sh,skip,statistics,% + subgoal_of,system,tab,tell,telling,time,told,trace,true,unload,% + untrace,var,write},% + sensitive=f,% + morecomment=[l]\%,% + morecomment=[s]{/*}{*/},% + morestring=[bd]",% + morestring=[bd]'% + }[keywords,comments,strings]% +%% +%% SHELXL definition (c) 1999 Aidan Philip Heerdegen +%% +%% +\lst@definelanguage{SHELXL}% + {morekeywords={TITL,CELL,ZERR,LATT,SYMM,SFAC,DISP,UNIT,LAUE,% + REM,MORE,TIME,END,HKLF,OMIT,SHEL,BASF,TWIN,EXTI,SWAT,% + MERG,SPEC,RESI,MOVE,ANIS,AFIX,HFIX,FRAG,FEND,EXYZ,EADP,% + EQIV,OMIT,CONN,PART,BIND,FREE,DFIX,BUMP,SAME,SADI,CHIV,% + FLAT,DELU,SIMU,DEFS,ISOR,SUMP,L.S.,CGLS,SLIM,BLOC,DAMP,% + WGHT,FVAR,BOND,CONF,MPLA,RTAB,LIST,ACTA,SIZE,TEMP,WPDB,% + FMAP,GRID,PLAN,MOLE},% + sensitive=false,% + alsoother=_,% Makes the syntax highlighting ignore the underscores + morecomment=[l]{! },% + }% +%% +%% Tcl/Tk definition (c) Gerd Neugebauer +%% +\lst@definelanguage[tk]{tcl}[]{tcl}% + {morekeywords={activate,add,separator,radiobutton,checkbutton,% + command,cascade,all,bell,bind,bindtags,button,canvas,canvasx,% + canvasy,cascade,cget,checkbutton,config,configu,configur,% + configure,clipboard,create,arc,bitmap,image,line,oval,polygon,% + rectangle,text,textwindow,curselection,delete,destroy,end,entry,% + entrycget,event,focus,font,actual,families,measure,metrics,names,% + frame,get,grab,current,release,status,grid,columnconfigure,% + rowconfigure,image,image,create,bitmap,photo,delete,height,types,% + widt,names,index,insert,invoke,itemconfigure,label,listbox,lower,% + menu,menubutton,message,move,option,add,clear,get,readfile,pack,% + photo,place,radiobutton,raise,scale,scroll,scrollbar,search,see,% + selection,send,stdin,stdout,stderr,tag,bind,text,tk,tkerror,% + tkwait,window,variable,visibility,toplevel,unknown,update,winfo,% + class,exists,ismapped,parent,reqwidth,reqheight,rootx,rooty,% + width,height,wm,aspect,client,command,deiconify,focusmodel,frame,% + geometry,group,iconbitmap,iconify,iconmask,iconname,iconposition,% + iconwindow,maxsize,minsize,overrideredirect,positionfrom,% + protocol,sizefrom,state,title,transient,withdraw,xview,yview,% + yposition,% + -accelerator,-activebackground,-activeborderwidth,% + -activeforeground,-after,-anchor,-arrow,-arrowshape,-aspect,% + -async,-background,-before,-bg,-bigincrement,-bitmap,-bordermode,% + -borderwidth,-button,-capstyle,-channel,-class,-closeenough,% + -colormap,-column,-columnspan,-command,-confine,-container,% + -count,-cursor,-data,-default,-detail,-digits,-direction,% + -displayof,-disableforeground,-elementborderwidth,-expand,% + -exportselection,-extend,-family,-fg,-file,-fill,-focus,-font,% + -fontmap,-foreground,-format,-from,-gamma,-global,-height,% + -highlightbackground,-highlightcolor,-highlightthickness,-icon,% + -image,-in,-insertbackground,-insertborderwidth,-insertofftime,% + -insertontime,-imsertwidth,-ipadx,-ipady,-joinstyle,-jump,% + -justify,-keycode,-keysym,-label,-lastfor,-length,-maskdata,% + -maskfile,-menu,-message,-mode,-offvalue,-onvalue,-orient,% + -outlien,-outlinestipple,-overstrike,-override,-padx,-pady,% + -pageanchor,-pageheight,-pagewidth,-pagey,-pagey,-palette,% + -parent,-place,-postcommand,-relheight,-relief,-relwidth,-relx,% + -rely,-repeatdelay,-repeatinterval,-resolution,-root,-rootx,% + -rooty,-rotate,-row,-rowspan,-screen,-selectcolor,-selectimage,% + -sendevent,-serial,-setgrid,-showvalue,-shrink,-side,-size,% + -slant,-sliderlength,-sliderrelief,-smooth,-splinesteps,-state,% + -sticky,-stipple,-style,-subsample,-subwindow,-tags,-takefocus,% + -tearoff,-tearoffcommand,-text,-textvariable,-tickinterval,-time,% + -title,-to,-troughcolor,-type,-underline,-use,-value,-variable,% + -visual,-width,-wrap,-wraplength,-x,-xscrollcommand,-y,% + -bgstipple,-fgstipple,-lmargin1,-lmargin2,-rmargin,-spacing1,% + -spacing2,-spacing3,-tabs,-yscrollcommand,-zoom,% + activate,add,addtag,bbox,cget,clone,configure,coords,% + curselection,debug,delete,delta,deselect,dlineinfo,dtag,dump,% + entrycget,entryconfigure,find,flash,fraction,get,gettags,handle,% + icursor,identify,index,insert,invoke,itemcget,itemconfigure,mark,% + moveto,own,post,postcascade,postscript,put,redither,ranges,% + scale,select,show,tag,type,unpost,xscrollcommand,xview,% + yscrollcommand,yview,yposition}% + }% +\lst@definelanguage[]{tcl}% + {alsoletter={.:,*=&-},% + morekeywords={after,append,array,names,exists,anymore,donesearch,% + get,nextelement,set,size,startsearch,auto_mkindex,binary,break,% + case,catch,cd,clock,close,concat,console,continue,default,else,% + elseif,eof,error,eval,exec,-keepnewline,exit,expr,fblocked,% + fconfigure,fcopy,file,atime,dirname,executable,exists,extension,% + isdirectory,isfile,join,lstat,mtime,owned,readable,readlink,% + rootname,size,stat,tail,type,writable,-permissions,-group,-owner,% + -archive,-hidden,-readonly,-system,-creator,-type,-force,% + fileevent,flush,for,foreach,format,gets,glob,global,history,if,% + incr,info,argsbody,cmdcount,commands,complete,default,exists,% + globals,level,library,locals,patchlevel,procs,script,tclversion,% + vars,interp,join,lappend,lindex,linsert,list,llength,lrange,% + lreplace,lsearch,-exact,-regexp,-glob,lsort,-ascii,-integer,% + -real,-dictionary,-increasing,-decreasing,-index,-command,load,% + namespace,open,package,forget,ifneeded,provide,require,unknown,% + vcompare,versions,vsatisfies,pid,proc,puts,-nonewline,pwd,read,% + regexp,-indices,regsub,-all,-nocaserename,return,scan,seek,set,% + socket,source,split,string,compare,first,index,last,length,match,% + range,tolower,toupper,trim,trimleft,trimright,subst,switch,tell,% + time,trace,variable,vdelete,vinfo,unknown,unset,uplevel,upvar,% + vwait,while,acos,asin,atan,atan2,ceil,cos,cosh,exp,floor,fmod,% + hypot,log,log10,pow,sin,sinh,sqrt,tan,tanh,abs,double,int,round% + },% + morestring=[d]",% + MoreSelectCharTable=% + \lst@CArgX\#\relax\lst@DefDelimB{}{}% + {\ifx\lst@lastother\lstum@backslash + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@commentmode + {{\lst@commentstyle}\lst@Lmodetrue}% + }[keywords,comments,strings]% +%% +%% VBScript definition (c) 2000 Sonja Weidmann +%% +\lst@definelanguage{VBScript}% + {morekeywords={Call,Case,Const,Dim,Do,Each,Else,End,Erase,Error,Exit,% + Explicit,For,Function,If,Loop,Next,On,Option,Private,Public,% + Randomize,ReDim,Rem,Select,Set,Sub,Then,Wend,While,Abs,Array,Asc,% + Atn,CBool,CByte,CCur,CDate,CDbl,Chr,CInt,CLng,Cos,CreateObject,% + CSng,CStr,Date,DateAdd,DateDiff,DatePart,DateSerial,DateValue,% + Day,Exp,Filter,Fix,FormatCurrency,FormatDateTime,FormatNumber,% + FormatPercent,GetObject,Hex,Hour,InputBox,InStr,InStrRev,Int,% + IsArray,IsDate,IsEmpty,IsNull,IsNumeric,IsObject,Join,LBound,% + LCase,Left,Len,LoadPicture,Log,LTrim,Mid,Minute,Month,MonthName,% + MsgBox,Now,Oct,Replace,RGB,Right,Rnd,Round,RTrim,ScriptEngine,% + ScriptEngineBuildVersion,ScriptEngineMajorVersion,% + ScriptEngineMinorVersion,Second,Sgn,Sin,Space,Split,Sqr,StrComp,% + StrReverse,String,Tan,Time,TimeSerial,TimeValue,Trim,TypeName,% + UBound,UCase,VarType,Weekday,WeekdayName,Year, And,Eqv,Imp,Is,% + Mod,Not,Or,Xor,Add,BuildPath,Clear,Close,Copy,CopyFile,% + CopyFolder,CreateFolder,CreateTextFile,Delete,DeleteFile,% + DeleteFolder,Dictionary,Drive,DriveExists,Drives,Err,Exists,File,% + FileExists,FileSystemObject,Files,Folder,FolderExists,Folders,% + GetAbsolutePathName,GetBaseName,GetDrive,GetDriveName,% + GetExtensionName,GetFile,GetFileName,GetFolder,% + GetParentFolderName,GetSpecialFolder,GetTempName,Items,Keys,Move,% + MoveFile,MoveFolder,OpenAsTextStream,OpenTextFile,Raise,Read,% + ReadAll,ReadLine,Remove,RemoveAll,Skip,SkipLine,TextStream,Write,% + WriteBlankLines,WriteLine,Alias,Archive,CDROM,Compressed,% + Directory,Fixed,ForAppending,ForReading,ForWriting,Hidden,Normal,% + RAMDisk,ReadOnly,Remote,Removable,System,SystemFolder,% + TemporaryFolder,TristateFalse,TristateTrue,TristateUseDefault,% + Unknown,Volume,WindowsFolder,vbAbortRetryIgnore,% + vbApplicationModal,vbArray,vbBinaryCompare,vbBlack,vbBlue,% + vbBoolean,vbByte,vbCr,vbCrLf,vbCritical,vbCurrency,vbCyan,% + vbDataObject,vbDate,vbDecimal,vbDefaultButton1,vbDefaultButton2,% + vbDefaultButton3,vbDefaultButton4,vbDouble,vbEmpty,vbError,% + vbExclamation,vbFirstFourDays,vbFirstFullWeek,vbFirstJan1,% + vbFormFeed,vbFriday,vbGeneralDate,vbGreen,vbInformation,% + vbInteger,vbLf,vbLong,vbLongDate,vbLongTime,vbMagenta,vbMonday,% + vbNewLine,vbNull,vbNullChar,vbNullString,vbOKC,ancel,vbOKOnly,% + vbObject,vbObjectError,vbQuestion,vbRed,vbRetryCancel,vbSaturday,% + vbShortDate,vbShortTime,vbSingle,vbString,vbSunday,vbSystemModal,% + vbTab,vbTextCompare,vbThursday,vbTuesday,vbUseSystem,% + vbUseSystemDayOfWeek,vbVariant,vbVerticalTab,vbWednesday,vbWhite,% + vbYellow,vbYesNo,vbYesNoCancel},% + sensitive=f,% + morecomment=[l]',% + morestring=[d]"% + }[keywords,comments,strings]% +%% +%% VRML definition (c) 2001 Oliver Baum +%% +\lst@definelanguage[97]{VRML} + {morekeywords={DEF,EXTERNPROTO,FALSE,IS,NULL,PROTO,ROUTE,TO,TRUE,USE,% + eventIn,eventOut,exposedField,field,Introduction,Anchor,% + Appearance,AudioClip,Background,Billboard,Box,Collision,Color,% + ColorInterpolator,Cone,Coordinate,CoordinateInterpolator,% + Cylinder,CylinderSensor,DirectionalLight,ElevationGrid,Extrusion,% + Fog,FontStyle,Group,ImageTexture,IndexedFaceSet,IndexedLineSet,% + Inline,LOD,Material,MovieTexture,NavigationInfo,Normal,% + NormalInterpolator,OrientationInterpolator,PixelTexture,% + PlaneSensor,PointLight,PointSet,PositionInterpolator,% + ProximitySensor,ScalarInterpolator,Script,Shape,Sound,Sphere,% + SphereSensor,SpotLight,Switch,Text,TextureCoordinate,% + TextureTransform,TimeSensor,TouchSensor,Transform,Viewpoint,% + VisibilitySensor,WorldInfo},% + morecomment=[l]\#,% bug: starts comment in the first column + morestring=[b]"% + }[keywords,comments,strings] +\endinput +%% +%% End of file `lstlang2.sty'. diff --git a/doc/user/lstlang3.sty b/doc/user/lstlang3.sty new file mode 100644 index 0000000000..c1edd77393 --- /dev/null +++ b/doc/user/lstlang3.sty @@ -0,0 +1,599 @@ +%% +%% This is file `lstlang3.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% lstdrvrs.dtx (with options: `lang3') +%% +%% (w)(c) 1996/1997/1998/1999/2000/2001/2002 Carsten Heinz and/or any +%% other author listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\ProvidesFile{lstlang3} + [2002/07/31 v1.0d listings language file] +\lst@definelanguage[68]{Algol}% + {morekeywords={abs,and,arg,begin,bin,bits,bool,by,bytes,case,channel,% + char,co,comment,compl,conj,divab,do,down,elem,elif,else,empty,% + end,entier,eq,esac,exit,false,fi,file,flex,for,format,from,ge,% + goto,gt,heap,if,im,in,int,is,isnt,le,leng,level,loc,long,lt,lwb,% + minusab,mod,modab,mode,ne,nil,not,od,odd,of,op,or,ouse,out,over,% + overab,par,plusab,plusto,pr,pragmat,prio,proc,re,real,ref,repr,% + round,sema,shl,short,shorten,shr,sign,skip,string,struct,then,% + timesab,to,true,union,up,upb,void,while},% + sensitive=f,% ??? + morecomment=[s]{\#}{\#},% + keywordcomment={co,comment}% + }[keywords,comments,keywordcomments]% +\lst@definelanguage[60]{Algol}% + {morekeywords={array,begin,Boolean,code,comment,div,do,else,end,% + false,for,goto,if,integer,label,own,power,procedure,real,step,% + string,switch,then,true,until,value,while},% + sensitive=f,% ??? + keywordcommentsemicolon={end}{else,end}{comment}% + }[keywords,keywordcomments]% +%% +%% x86masm definition (c) 2002 Andrew Zabolotny +%% +\lst@definelanguage[x86masm]{Assembler}% + {morekeywords={al,ah,ax,eax,bl,bh,bx,ebx,cl,ch,cx,ecx,dl,dh,dx,edx,% + si,esi,di,edi,bp,ebp,sp,esp,cs,ds,es,ss,fs,gs,cr0,cr1,cr2,cr3,% + db0,db1,db2,db3,db4,db5,db6,db7,tr0,tr1,tr2,tr3,tr4,tr5,tr6,tr7,% + st,aaa,aad,aam,aas,adc,add,and,arpl,bound,bsf,bsr,bswap,bt,btc,% + btr,bts,call,cbw,cdq,clc,cld,cli,clts,cmc,cmp,cmps,cmpsb,cmpsw,% + cmpsd,cmpxchg,cwd,cwde,daa,das,dec,div,enter,hlt,idiv,imul,in,% + inc,ins,int,into,invd,invlpg,iret,ja,jae,jb,jbe,jc,jcxz,jecxz,% + je,jg,jge,jl,jle,jna,jnae,jnb,jnbe,jnc,jne,jng,jnge,jnl,jnle,% + jno,jnp,jns,jnz,jo,jp,jpe,jpo,js,jz,jmp,lahf,lar,lea,leave,lgdt,% + lidt,lldt,lmsw,lock,lods,lodsb,lodsw,lodsd,loop,loopz,loopnz,% + loope,loopne,lds,les,lfs,lgs,lss,lsl,ltr,mov,movs,movsb,movsw,% + movsd,movsx,movzx,mul,neg,nop,not,or,out,outs,pop,popa,popad,% + popf,popfd,push,pusha,pushad,pushf,pushfd,rcl,rcr,rep,repe,% + repne,repz,repnz,ret,retf,rol,ror,sahf,sal,sar,sbb,scas,seta,% + setae,setb,setbe,setc,sete,setg,setge,setl,setle,setna,setnae,% + setnb,setnbe,setnc,setne,setng,setnge,setnl,setnle,setno,setnp,% + setns,setnz,seto,setp,setpe,setpo,sets,setz,sgdt,shl,shld,shr,% + shrd,sidt,sldt,smsw,stc,std,sti,stos,stosb,stosw,stosd,str,sub,% + test,verr,verw,wait,wbinvd,xadd,xchg,xlatb,xor,fabs,fadd,fbld,% + fbstp,fchs,fclex,fcom,fcos,fdecstp,fdiv,fdivr,ffree,fiadd,ficom,% + fidiv,fidivr,fild,fimul,fincstp,finit,fist,fisub,fisubr,fld,fld1,% + fldl2e,fldl2t,fldlg2,fldln2,fldpi,fldz,fldcw,fldenv,fmul,fnop,% + fpatan,fprem,fprem1,fptan,frndint,frstor,fsave,fscale,fsetpm,% + fsin,fsincos,fsqrt,fst,fstcw,fstenv,fstsw,fsub,fsubr,ftst,fucom,% + fwait,fxam,fxch,fxtract,fyl2x,fyl2xp1,f2xm1},% + morekeywords=[2]{.align,.alpha,assume,byte,code,comm,comment,.const,% + .cref,.data,.data?,db,dd,df,dosseg,dq,dt,dw,dword,else,end,endif,% + endm,endp,ends,eq,equ,.err,.err1,.err2,.errb,.errdef,.errdif,% + .erre,.erridn,.errnb,.errndef,.errnz,event,exitm,extrn,far,% + .fardata,.fardata?,fword,ge,group,gt,high,if,if1,if2,ifb,ifdef,% + ifdif,ife,ifidn,ifnb,ifndef,include,includelib,irp,irpc,label,% + .lall,le,length,.lfcond,.list,local,low,lt,macro,mask,mod,.model,% + name,ne,near,offset,org,out,page,proc,ptr,public,purge,qword,.% + radix,record,rept,.sall,seg,segment,.seq,.sfcond,short,size,% + .stack,struc,subttl,tbyte,.tfcond,this,title,type,.type,width,% + word,.xall,.xcref,.xlist},% + alsoletter=.,alsodigit=?,% + sensitive=f,% + morestring=[b]",% + morestring=[b]',% + morecomment=[l];% + }[directives,keywords,comments,strings] +%% +%% Clean definition (c) 1999 Jos\'e Romildo Malaquias +%% +%% +%% Clean 1.3 : some standard functional language: pure, lazy, +%% polymorphic type system, modules, type classes, +%% garbage collection, functions as first class citizens +%% +\lst@definelanguage{Clean}% + {otherkeywords={:,::,=,:==,=:,=>,->,<-,<-:,\{,\},\{|,|\},\#,\#!,|,\&,% + [,],!,.,\\\\,;,_},% + morekeywords={from,definition,implementation,import,module,system,% + case,code,if,in,let,let!,of,where,with,infix,infixl,infixr},% + morendkeywords={True,False,Start,Int,Real,Char,Bool,String,World,% + File,ProcId},% + sensitive,% + morecomment=[l]//,% missing comma: Markus Pahlow + morecomment=[n]{/*}{*/},% + morestring=[b]"% + }[keywords,comments,strings]% +\lst@definelanguage{Comal 80}% + {morekeywords={AND,AUTO,CASE,DATA,DEL,DIM,DIV,DO,ELSE,ENDCASE,ENDIF,% + ENDPROC,ENDWHILE,EOD,EXEC,FALSE,FOR,GOTO,IF,INPUT,INT,LIST,LOAD,% + MOD,NEW,NEXT,NOT,OF,OR,PRINT,PROC,RANDOM,RENUM,REPEAT,RND,RUN,% + SAVE,SELECT,STOP,TAB,THEN,TRUE,UNTIL,WHILE,ZONE},% + sensitive=f,% ??? + morecomment=[l]//,% + morestring=[d]"% + }[keywords,comments,strings]% +\lst@definelanguage{Elan}% + {morekeywords={ABS,AND,BOOL,CAND,CASE,CAT,COLUMNS,CONCR,CONJ,CONST,% + COR,DECR,DEFINES,DET,DIV,DOWNTO,ELIF,ELSE,END,ENDIF,ENDOP,% + ENDPACKET,ENDPROC,ENDREP,ENDSELECT,FALSE,FI,FILE,FOR,FROM,IF,% + INCR,INT,INV,LEAVE,LENGTH,LET,MOD,NOT,OF,OP,OR,OTHERWISE,PACKET,% + PROC,REAL,REP,REPEAT,ROW,ROWS,SELECT,SIGN,STRUCT,SUB,TEXT,THEN,% + TRANSP,TRUE,TYPE,UNTIL,UPTO,VAR,WHILE,WITH,XOR,% + maxint,sign,abs,min,max,random,initializerandom,subtext,code,% + replace,text,laenge,pos,compress,change,maxreal,smallreal,floor,% + pi,e,ln,log2,log10,sqrt,exp,tan,tand,sin,sind,cos,cosd,arctan,% + arctand,int,real,lastconversionok,put,putline,line,page,get,% + getline,input,output,sequentialfile,maxlinelaenge,reset,eof,% + close,complexzero,complexone,complexi,complex,realpart,imagpart,% + dphi,phi,vector,norm,replace,matrix,idn,row,column,sub,% + replacerow,replacecolumn,replaceelement,transp,errorsstop,stop},% + sensitive,% + morestring=[d]"% + }[keywords,strings]% +\lst@definelanguage{ksh} + {morekeywords={alias,awk,cat,echo,else,elif,fi,exec,exit,% + for,in,do,done,select,case,esac,while,until,function,% + time,export,cd,eval,fc,fg,kill,let,pwd,read,return,rm,% + glob,goto,history,if,logout,nice,nohup,onintr,repeat,sed,% + set,setenv,shift,source,switch,then,umask,unalias,% + unset,wait,@,env,argv,child,home,ignoreeof,noclobber,% + noglob,nomatch,path,prompt,shell,status,verbose,print,printf,% + sqrt,BEGIN,END},% + morecomment=[l]\#,% + morestring=[d]",% + morestring=[d]'% + }[keywords,comments,strings]% +\lst@definelanguage{Logo}% + {morekeywords={and,atan,arctan,both,break,bf,bl,butfirst,butlast,% + cbreak, close,co,continue,cos,count,clearscreen,cs,debquit,% + describe,diff,difference,ed,edit,either,emptyp,equalp,er,erase,% + errpause,errquit,fifp,filefprint,fifty,fileftype,fip,fileprint,% + fird,fileread,fity,filetype,fiwd,fileword,f,first,or,fp,fprint,% + fput,fty,ftype,full,fullscreen,go,bye,goodbye,gprop,greaterp,% + help,if,iff,iffalse,ift,iftrue,nth,item,keyp,llast,lessp,list,% + local,lput,make,max,maximum,memberp,memtrace,min,minimum,namep,% + not,numberp,oflush,openr,openread,openw,openwrite,op,output,% + pause,plist,pots,pow,pprop,pps,pr,print,product,quotient,random,% + rc,readchar,rl,readlist,remprop,repcount,repeat,request,rnd,run,% + se,sentence,sentencep,setc,setcolor,setipause,setqpause,po,show,% + sin,split,splitscreen,sqrt,stop,sum,test,text,textscreen,thing,% + to,tone,top,toplevel,type,untrace,wait,word,wordp,yaccdebug,is,% + mod,remainder,trace,zerop,back,bk,bto,btouch,fd,forward,fto,% + ftouch,getpen,heading,hit,hitoot,ht,hideturtle,loff,lampoff,lon,% + lampon,lt,left,lot,lotoot,lto,ltouch,penc,pencolor,pd,pendown,pe,% + penerase,penmode,pu,penup,px,penreverse,rt,right,rto,rtouch,% + scrunch,seth,setheading,setscrun,setscrunch,setxy,shownp,st,% + showturtle,towardsxy,clean,wipeclean,xcor,ycor,tur,turtle,% + display,dpy},% + sensitive=f% ??? + }[keywords]% +\lst@definelanguage{Modula-2}% + {morekeywords={AND,ARRAY,BEGIN,BY,CASE,CONST,DIV,DO,ELSE,ELSIF,END,% + EXIT,EXPORT,FOR,FROM,IF,IMPLEMENTATION,IMPORT,IN,MOD,MODULE,NOT,% + OF,OR,POINTER,PROCEDURE,QUALIFIED,RECORD,REPEAT,RETURN,SET,THEN,% + TYPE,UNTIL,VAR,WHILE,WITH,ABS,BITSET,BOOLEAN,CAP,CARDINAL,CHAR,% + CHR,DEC,EXCL,FALSE,FLOAT,HALT,HIGH,INC,INCL,INTEGER,LONGCARD,% + LONGINT,LONGREAL,MAX,MIN,NIL,ODD,ORD,PROC,REAL,SIZE,TRUE,TRUNC,% + VAL,DEFINITION,LOOP},% added keywords due to Peter Bartke 99/07/22 + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% +\lst@definelanguage{NASTRAN} + {morekeywords={ENDDATA},% + morecomment=[l]$,% + MoreSelectCharTable=% + \lst@CArgX BEGIN\ BULK\relax\lst@CDef{}% + {\lst@ifmode\else \ifnum\lst@length=\z@ + \lst@EnterMode{\lst@GPmode}{\lst@modetrue + \let\lst@currstyle\lst@gkeywords@sty}% + \fi \fi}% + {\ifnum\lst@mode=\lst@GPmode + \lst@XPrintToken \lst@LeaveMode + \fi}% + }[keywords,comments]% +\lst@definelanguage{Oberon-2}% + {morekeywords={ARRAY,BEGIN,BOOLEAN,BY,CASE,CHAR,CONST,DIV,DO,ELSE,% + ELSIF,END,EXIT,FALSE,FOR,IF,IMPORT,IN,INTEGER,IS,LONGINT,% + LONGREAL,LOOP,MOD,MODULE,NIL,OF,OR,POINTER,PROCEDURE,REAL,RECORD,% + REPEAT,RETURN,SET,SHORTINT,THEN,TO,TRUE,TYPE,UNTIL,VAR,WHILE,% + WITH,ABS,ASH,CAP,CHR,COPY,DEC,ENTIER,EXCL,HALT,INC,INCL,LEN,LONG,% + MAX,MIN,NEW,ODD,ORD,SHORT,SIZE},% + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% +%% +%% OCL definition (c) 2000 Achim D. Brucker +%% +%% +%% You are allowed to use, modify and distribute this code either under +%% the terms of the LPPL (version 1.0 or later) or the GPL (version 2.0 +%% or later). +%% +\lst@definelanguage[decorative]{OCL}[OMG]{OCL} + {otherkeywords={@pre},% + morendkeywords={name,attributes,associatoinEnds,operations,% + supertypes,allSupertypes,allInstances,oclIsKindOf,oclIsTypeOf,% + oclAsType,oclInState,oclIsNew,evaluationType,abs,floor,round,max,% + min,div,mod,size,concat,toUpper,toLower,substring,includes,% + excludes,count,includesAll,exludesAll,isEmpty,notEmpty,sum,% + exists,forAll,isUnique,sortedBy,iterate,union,intersection,% + including,excluding,symmetricDifference,select,reject,collect,% + asSequence,asBag,asSequence,asSet,append,prepend,subSequence,at,% + first,last,true,false,isQuery}% + }% +\lst@definelanguage[OMG]{OCL}% + {morekeywords={context,pre,inv,post},% + ndkeywords={or,xor,and,not,implies,if,then,else,endif},% + morerdkeywords={Boolean,Integer,Real,String,Set,Sequence,Bag,% + OclType,OclAny,OclExpression,Enumeration,Collection,},% + sensitive=t,% + morecomment=[l]--,% + morestring=[d]'% + }[keywords,rdkeywords,comments,strings]% +\lst@definelanguage{PL/I}% + {morekeywords={ABS,ATAN,AUTOMATIC,AUTO,ATAND,BEGIN,BINARY,BIN,BIT,% + BUILTIN,BY,CALL,CHARACTER,CHAR,CHECK,COLUMN,COL,COMPLEX,CPLX,% + COPY,COS,COSD,COSH,DATA,DATE,DECIMAL,DEC,DECLARE,DCL,DO,EDIT,% + ELSE,END,ENDFILE,ENDPAGE,ENTRY,EXP,EXTERNAL,EXT,FINISH,FIXED,% + FIXEDOVERFLOW,FOFL,FLOAT,FORMAT,GET,GO,GOTO,IF,IMAG,INDEX,% + INITIAL,INIT,INTERNAL,INT,LABEL,LENGTH,LIKE,LINE,LIST,LOG,LOG2,% + LOG10,MAIN,MAX,MIN,MOD,NOCHECK,NOFIXEDOVERFLOW,NOFOFL,NOOVERFLOW,% + NOOFL,NOSIZE,NOUNDERFLOW,NOUFL,NOZERODIVIDE,NOZDIV,ON,OPTIONS,% + OVERFLOW,OFL,PAGE,PICTURE,PROCEDURE,PROC,PUT,READ,REPEAT,RETURN,% + RETURNS,ROUND,SIN,SIND,SINH,SIZE,SKIP,SQRT,STATIC,STOP,STRING,% + SUBSTR,SUM,SYSIN,SYSPRINT,TAN,TAND,TANH,THEN,TO,UNDERFLOW,UFL,% + VARYING,WHILE,WRITE,ZERODIVIDE,ZDIV},% + sensitive=f,% + morecomment=[s]{/*}{*/},% + morestring=[d]'% + }[keywords,comments,strings]% +\lst@definelanguage[IBM]{Simula}[DEC]{Simula}{}% +\lst@definelanguage[DEC]{Simula}[67]{Simula}% + {morekeywords={and,eq,eqv,ge,gt,hidden,imp,le,long,lt,ne,not,% + options,or,protected,short}% + }% +\lst@definelanguage[CII]{Simula}[67]{Simula}% + {morekeywords={and,equiv,exit,impl,not,or,stop}}% +\lst@definelanguage[67]{Simula}% + {morekeywords={activate,after,array,at,before,begin,boolean,% + character,class,comment,delay,detach,do,else,end,external,false,% + for,go,goto,if,in,inner,inspect,integer,is,label,name,new,none,% + notext,otherwise,prior,procedure,qua,reactivate,real,ref,resume,% + simset,simulation,step,switch,text,then,this,to,true,until,value,% + virtual,when,while},% + sensitive=f,% + keywordcommentsemicolon={end}{else,end,otherwise,when}{comment},% + morestring=[d]",% + morestring=[d]'% + }[keywords,keywordcomments,strings]% +\lst@definelanguage{S}[]{R}{} +\lst@definelanguage[PLUS]{S}[]{R}{} +\lst@definelanguage{R}% + {keywords={abbreviate,abline,abs,acos,acosh,action,add1,add,% + aggregate,alias,Alias,alist,all,anova,any,aov,aperm,append,apply,% + approx,approxfun,apropos,Arg,args,array,arrows,as,asin,asinh,% + atan,atan2,atanh,attach,attr,attributes,autoload,autoloader,ave,% + axis,backsolve,barplot,basename,besselI,besselJ,besselK,besselY,% + beta,binomial,body,box,boxplot,break,browser,bug,builtins,bxp,by,% + c,C,call,Call,case,cat,category,cbind,ceiling,character,char,% + charmatch,check,chol,chol2inv,choose,chull,class,close,cm,codes,% + coef,coefficients,co,col,colnames,colors,colours,commandArgs,% + comment,complete,complex,conflicts,Conj,contents,contour,% + contrasts,contr,control,helmert,contrib,convolve,cooks,coords,% + distance,coplot,cor,cos,cosh,count,fields,cov,covratio,wt,CRAN,% + create,crossprod,cummax,cummin,cumprod,cumsum,curve,cut,cycle,D,% + data,dataentry,date,dbeta,dbinom,dcauchy,dchisq,de,debug,% + debugger,Defunct,default,delay,delete,deltat,demo,de,density,% + deparse,dependencies,Deprecated,deriv,description,detach,% + dev2bitmap,dev,cur,deviance,off,prev,,dexp,df,dfbetas,dffits,% + dgamma,dgeom,dget,dhyper,diag,diff,digamma,dim,dimnames,dir,% + dirname,dlnorm,dlogis,dnbinom,dnchisq,dnorm,do,dotplot,double,% + download,dpois,dput,drop,drop1,dsignrank,dt,dummy,dump,dunif,% + duplicated,dweibull,dwilcox,dyn,edit,eff,effects,eigen,else,% + emacs,end,environment,env,erase,eval,equal,evalq,example,exists,% + exit,exp,expand,expression,External,extract,extractAIC,factor,% + fail,family,fft,file,filled,find,fitted,fivenum,fix,floor,for,% + For,formals,format,formatC,formula,Fortran,forwardsolve,frame,% + frequency,ftable,ftable2table,function,gamma,Gamma,gammaCody,% + gaussian,gc,gcinfo,gctorture,get,getenv,geterrmessage,getOption,% + getwd,gl,glm,globalenv,gnome,GNOME,graphics,gray,grep,grey,grid,% + gsub,hasTsp,hat,heat,help,hist,home,hsv,httpclient,I,identify,if,% + ifelse,Im,image,\%in\%,index,influence,measures,inherits,install,% + installed,integer,interaction,interactive,Internal,intersect,% + inverse,invisible,IQR,is,jitter,kappa,kronecker,labels,lapply,% + layout,lbeta,lchoose,lcm,legend,length,levels,lgamma,library,% + licence,license,lines,list,lm,load,local,locator,log,log10,log1p,% + log2,logical,loglin,lower,lowess,ls,lsfit,lsf,ls,machine,Machine,% + mad,mahalanobis,make,link,margin,match,Math,matlines,mat,matplot,% + matpoints,matrix,max,mean,median,memory,menu,merge,methods,min,% + missing,Mod,mode,model,response,mosaicplot,mtext,mvfft,na,nan,% + names,omit,nargs,nchar,ncol,NCOL,new,next,NextMethod,nextn,% + nlevels,nlm,noquote,NotYetImplemented,NotYetUsed,nrow,NROW,null,% + numeric,\%o\%,objects,offset,old,on,Ops,optim,optimise,optimize,% + options,or,order,ordered,outer,package,packages,page,pairlist,% + pairs,palette,panel,par,parent,parse,paste,path,pbeta,pbinom,% + pcauchy,pchisq,pentagamma,persp,pexp,pf,pgamma,pgeom,phyper,pico,% + pictex,piechart,Platform,plnorm,plogis,plot,pmatch,pmax,pmin,% + pnbinom,pnchisq,pnorm,points,poisson,poly,polygon,polyroot,pos,% + postscript,power,ppoints,ppois,predict,preplot,pretty,Primitive,% + print,prmatrix,proc,prod,profile,proj,prompt,prop,provide,% + psignrank,ps,pt,ptukey,punif,pweibull,pwilcox,q,qbeta,qbinom,% + qcauchy,qchisq,qexp,qf,qgamma,qgeom,qhyper,qlnorm,qlogis,qnbinom,% + qnchisq,qnorm,qpois,qqline,qqnorm,qqplot,qr,Q,qty,qy,qsignrank,% + qt,qtukey,quantile,quasi,quit,qunif,quote,qweibull,qwilcox,% + rainbow,range,rank,rbeta,rbind,rbinom,rcauchy,rchisq,Re,read,csv,% + csv2,fwf,readline,socket,real,Recall,rect,reformulate,regexpr,% + relevel,remove,rep,repeat,replace,replications,report,require,% + resid,residuals,restart,return,rev,rexp,rf,rgamma,rgb,rgeom,R,% + rhyper,rle,rlnorm,rlogis,rm,rnbinom,RNGkind,rnorm,round,row,% + rownames,rowsum,rpois,rsignrank,rstandard,rstudent,rt,rug,runif,% + rweibull,rwilcox,sample,sapply,save,scale,scan,scan,screen,sd,se,% + search,searchpaths,segments,seq,sequence,setdiff,setequal,set,% + setwd,show,sign,signif,sin,single,sinh,sink,solve,sort,source,% + spline,splinefun,split,sqrt,stars,start,stat,stem,step,stop,% + storage,strstrheight,stripplot,strsplit,structure,strwidth,sub,% + subset,substitute,substr,substring,sum,summary,sunflowerplot,svd,% + sweep,switch,symbol,symbols,symnum,sys,status,system,t,table,% + tabulate,tan,tanh,tapply,tempfile,terms,terrain,tetragamma,text,% + time,title,topo,trace,traceback,transform,tri,trigamma,trunc,try,% + ts,tsp,typeof,unclass,undebug,undoc,union,unique,uniroot,unix,% + unlink,unlist,unname,untrace,update,upper,url,UseMethod,var,% + variable,vector,Version,vi,warning,warnings,weighted,weights,% + which,while,window,write,\%x\%,x11,X11,xedit,xemacs,xinch,xor,% + xpdrows,xy,xyinch,yinch,zapsmall,zip},% + otherkeywords={!,!=,~,$,*,\&,\%/\%,\%*\%,\%\%,<-,<<-,_,/},% + alsoother={._$},% + sensitive,% + morecomment=[l]\#,% + morestring=[d]",% + morestring=[d]'% 2001 Robert Denham + }% +\lst@definelanguage{SAS}% + {procnamekeys={proc},% + morekeywords={DATA,AND,OR,NOT,EQ,GT,LT,GE,LE,NE,INFILE,INPUT,DO,BY,% + TO,SIN,COS,OUTPUT,END,PLOT,RUN,LIBNAME,VAR,TITLE,FIRSTOBS,OBS,% + DELIMITER,DLM,EOF,ABS,DIM,HBOUND,LBOUND,MAX,MIN,MOD,SIGN,SQRT,% + CEIL,FLOOR,FUZZ,INT,ROUND,TRUNC,DIGAMMA,ERF,ERFC,EXP,GAMMA,% + LGAMMA,LOG,LOG2,LOG10,ARCOS,ARSIN,ATAN,COSH,SINH,TANH,TAN,% + POISSON,PROBBETA,PROBBNML,PROBCHI,PROBF,PROBGAM,PROBHYPR,% + PROBNEGB,PROBNORM,PROBT,BETAINV,CINV,FINV,GAMINV,PROBIT,TINV,CSS,% + CV,KURTOSIS,MEAN,NMISS,RANGE,SKEWNESS,STD,STDERR,SUM,USS,NORMAL,% + RANBIN,RANCAU,RANEXP,RANGAM,RANNOR,RANPOI,RANTBL,RANTRI,RANUNI,% + UNIFORM,IF,THEN,ELSE,WHILE,UNTIL,DROP,KEEP,LABEL,DEFAULT,ARRAY,% + MERGE,CARDS,CARDS4,PUT,SET,UPDATE,ABORT,DELETE,DISPLAY,LIST,% + LOSTCARD,MISSING,STOP,WHERE,ARRAY,DROP,KEEP,WINDOW,LENGTH,RENAME,% + RETAIN,MEANS,UNIVARIATE,SUMMARY,TABULATE,CORR,FREQ,FOOTNOTE,NOTE,% + SHOW},% + otherkeywords={!,!=,~,$,*,\&,_,/,<,>=,=<,>},% + morestring=[d]'% + }[keywords,comments,strings,procnames]% +\lst@definelanguage[AlLaTeX]{TeX}[LaTeX]{TeX}% + {moretexcs={AtBeginDocument,AtBeginDvi,AtEndDocument,AtEndOfClass,% + AtEndOfPackage,ClassError,ClassInfo,ClassWarning,% + ClassWarningNoLine,CurrentOption,DeclareErrorFont,% + DeclareFixedFont,DeclareFontEncoding,DeclareFontEncodingDefaults,% + DeclareFontFamily,DeclareFontShape,DeclareFontSubstitution,% + DeclareMathAccent,DeclareMathAlphabet,DeclareMathAlphabet,% + DeclareMathDelimiter,DeclareMathRadical,DeclareMathSizes,% + DeclareMathSymbol,DeclareMathVersion,DeclareOldFontCommand,% + DeclareOption,DeclarePreloadSizes,DeclareRobustCommand,% + DeclareSizeFunction,DeclareSymbolFont,DeclareSymbolFontAlphabet,% + DeclareTextAccent,DeclareTextAccentDefault,DeclareTextCommand,% + DeclareTextCommandDefault,DeclareTextComposite,% + DeclareTextCompositeCommand,DeclareTextFontCommand,% + DeclareTextSymbol,DeclareTextSymbolDefault,ExecuteOptions,% + GenericError,GenericInfo,GenericWarning,IfFileExists,% + InputIfFileExists,LoadClass,LoadClassWithOptions,MessageBreak,% + OptionNotUsed,PackageError,PackageInfo,PackageWarning,% + PackageWarningNoLine,PassOptionsToClass,PassOptionsToPackage,% + ProcessOptionsProvidesClass,ProvidesFile,ProvidesFile,% + ProvidesPackage,ProvideTextCommand,RequirePackage,% + RequirePackageWithOptions,SetMathAlphabet,SetSymbolFont,% + TextSymbolUnavailable,UseTextAccent,UseTextSymbol},% + morekeywords={array,center,displaymath,document,enumerate,eqnarray,% + equation,flushleft,flushright,itemize,list,lrbox,math,minipage,% + picture,sloppypar,tabbing,tabular,trivlist,verbatim}% + }% +\lst@definelanguage[LaTeX]{TeX}[common]{TeX}% + {moretexcs={a,AA,aa,addcontentsline,addpenalty,addtocontents,% + addtocounter,addtolength,addtoversion,addvspace,alph,Alph,and,% + arabic,array,arraycolsep,arrayrulewidth,arraystretch,author,% + baselinestretch,begin,bezier,bfseries,bibcite,bibdata,bibitem,% + bibliography,bibliographystyle,bibstyle,bigskip,boldmath,% + botfigrule,bottomfraction,Box,caption,center,CheckCommand,circle,% + citation,cite,cleardoublepage,clearpage,cline,columnsep,% + columnseprule,columnwidth,contentsline,dashbox,date,dblfigrule,% + dblfloatpagefraction,dblfloatsep,dbltextfloatsep,dbltopfraction,% + defaultscriptratio,defaultscriptscriptratio,depth,Diamond,% + displaymath,document,documentclass,documentstyle,doublerulesep,% + em,emph,endarray,endcenter,enddisplaymath,enddocument,% + endenumerate,endeqnarray,endequation,endflushleft,endflushright,% + enditemize,endlist,endlrbox,endmath,endminipage,endpicture,% + endsloppypar,endtabbing,endtabular,endtrivlist,endverbatim,% + enlargethispage,ensuremath,enumerate,eqnarray,equation,% + evensidemargin,extracolsep,fbox,fboxrule,fboxsep,filecontents,% + fill,floatpagefraction,floatsep,flushbottom,flushleft,flushright,% + fnsymbol,fontencoding,fontfamily,fontseries,fontshape,fontsize,% + fontsubfuzz,footnotemark,footnotesep,footnotetext,footskip,frac,% + frame,framebox,fussy,glossary,headheight,headsep,height,hline,% + hspace,I,include,includeonly,index,inputlineno,intextsep,% + itemindent,itemize,itemsep,iterate,itshape,Join,kill,label,% + labelsep,labelwidth,LaTeX,LaTeXe,leadsto,lefteqn,leftmargin,% + leftmargini,leftmarginii,leftmarginiii,leftmarginiv,leftmarginv,% + leftmarginvi,leftmark,lhd,lim,linebreak,linespread,linethickness,% + linewidth,list,listfiles,listfiles,listparindent,lrbox,% + makeatletter,makeatother,makebox,makeglossary,makeindex,% + makelabel,MakeLowercase,MakeUppercase,marginpar,marginparpush,% + marginparsep,marginparwidth,markboth,markright,math,mathbf,% + mathellipsis,mathgroup,mathit,mathrm,mathsf,mathsterling,mathtt,% + mathunderscore,mathversion,mbox,mdseries,mho,minipage,% + multicolumn,multiput,NeedsTeXFormat,newcommand,newcounter,% + newenvironment,newfont,newhelp,newlabel,newlength,newline,% + newmathalphabet,newpage,newsavebox,newtheorem,nobreakspace,% + nobreakspace,nocite,nocorr,nocorrlist,nofiles,nolinebreak,% + nonumber,nopagebreak,normalcolor,normalfont,normalmarginpar,% + numberline,obeycr,oddsidemargin,oldstylenums,onecolumn,oval,% + pagebreak,pagenumbering,pageref,pagestyle,paperheight,paperwidth,% + paragraphmark,parbox,parsep,partopsep,picture,poptabs,pounds,% + protect,pushtabs,put,qbezier,qbeziermax,r,raggedleft,raisebox,% + ref,refstepcounter,renewcommand,renewenvironment,restorecr,% + reversemarginpar,rhd,rightmargin,rightmark,rmfamily,roman,Roman,% + rootbox,rule,samepage,sbox,scshape,secdef,section,sectionmark,% + selectfont,setcounter,settodepth,settoheight,settowidth,sffamily,% + shortstack,showoutput,showoverfull,sloppy,sloppypar,slshape,% + smallskip,sqsubset,sqsupset,SS,stackrel,stepcounter,stop,stretch,% + subparagraphmark,subsectionmark,subsubsectionmark,sum,% + suppressfloats,symbol,tabbing,tabbingsep,tabcolsep,tabular,% + tabularnewline,textasciicircum,textasciitilde,textbackslash,% + textbar,textbf,textbraceleft,textbraceright,textbullet,% + textcircled,textcompwordmark,textdagger,textdaggerdbl,textdollar,% + textellipsis,textemdash,textendash,textexclamdown,textfloatsep,% + textfraction,textgreater,textheight,textit,textless,textmd,% + textnormal,textparagraph,textperiodcentered,textquestiondown,% + textquotedblleft,textquotedblright,textquoteleft,textquoteright,% + textregistered,textrm,textsc,textsection,textsf,textsl,% + textsterling,textsuperscript,texttrademark,texttt,textunderscore,% + textup,textvisiblespace,textwidth,thanks,thefootnote,thempfn,% + thempfn,thempfootnote,thepage,thepage,thicklines,thinlines,% + thispagestyle,title,today,topfigrule,topfraction,topmargin,% + topsep,totalheight,tracingfonts,trivlist,ttfamily,twocolumn,% + typein,typeout,unboldmath,unitlength,unlhd,unrhd,upshape,usebox,% + usecounter,usefont,usepackage,value,vector,verb,verbatim,vline,% + vspace,width,% + normalsize,small,footnotesize,scriptsize,tiny,large,Large,LARGE,% + huge,Huge}% + }% +\lst@definelanguage[plain]{TeX}[common]{TeX}% + {moretexcs={advancepageno,beginsection,bf,bffam,bye,cal,cleartabs,% + columns,dosupereject,endinsert,eqalign,eqalignno,fiverm,fivebf,% + fivei,fivesy,folio,footline,hang,headline,it,itemitem,itfam,% + leqalignno,magnification,makefootline,makeheadline,midinsert,mit,% + mscount,nopagenumbers,normalbottom,of,oldstyle,pagebody,% + pagecontents,pageinsert,pageno,plainoutput,preloaded,proclaim,rm,% + settabs,sevenbf,seveni,sevensy,sevenrm,sl,slfam,supereject,% + tabalign,tabs,tabsdone,tabsyet,tenbf,tenex,teni,tenit,tenrm,% + tensl,tensy,tentt,textindent,topglue,topins,topinsert,tt,ttfam,% + ttraggedright,vfootnote}% + }% +\lst@definelanguage[common]{TeX}[primitive]{TeX} + {moretexcs={active,acute,ae,AE,aleph,allocationnumber,allowbreak,% + alpha,amalg,angle,approx,arccos,arcsin,arctan,arg,arrowvert,% + Arrowvert,ast,asymp,b,backslash,bar,beta,bgroup,big,Big,bigbreak,% + bigcap,bigcirc,bigcup,bigg,Bigg,biggl,Biggl,biggm,Biggm,biggr,% + Biggr,bigl,Bigl,bigm,Bigm,bigodot,bigoplus,bigotimes,bigr,Bigr,% + bigskip,bigskipamount,bigsqcup,bigtriangledown,bigtriangleup,% + biguplus,bigvee,bigwedge,bmod,bordermatrix,bot,bowtie,brace,% + braceld,bracelu,bracerd,braceru,bracevert,brack,break,breve,% + buildrel,bullet,c,cap,cases,cdot,cdotp,cdots,centering,% + centerline,check,chi,choose,circ,clubsuit,colon,cong,coprod,% + copyright,cos,cosh,cot,coth,csc,cup,d,dag,dagger,dashv,ddag,% + ddagger,ddot,ddots,deg,delta,Delta,det,diamond,diamondsuit,dim,% + displaylines,div,do,dospecials,dot,doteq,dotfill,dots,downarrow,% + Downarrow,downbracefill,egroup,eject,ell,empty,emptyset,endgraf,% + endline,enskip,enspace,epsilon,equiv,eta,exists,exp,filbreak,% + flat,fmtname,fmtversion,footins,footnote,footnoterule,forall,% + frenchspacing,frown,gamma,Gamma,gcd,ge,geq,gets,gg,goodbreak,% + grave,H,hat,hbar,heartsuit,hglue,hideskip,hidewidth,hom,% + hookleftarrow,hookrightarrow,hphantom,hrulefill,i,ialign,iff,Im,% + imath,in,inf,infty,int,interdisplaylinepenalty,% + interfootnotelinepenalty,intop,iota,item,j,jmath,joinrel,jot,% + kappa,ker,l,L,lambda,Lambda,land,langle,lbrace,lbrack,lceil,% + ldotp,ldots,le,leavevmode,leftarrow,Leftarrow,leftarrowfill,% + leftharpoondown,leftharpoonup,leftline,leftrightarrow,% + Leftrightarrow,leq,lfloor,lg,lgroup,lhook,lim,liminf,limsup,line,% + ll,llap,lmoustache,ln,lnot,log,longleftarrow,Longleftarrow,% + longleftrightarrow,Longleftrightarrow,longmapsto,longrightarrow,% + Longrightarrow,loop,lor,lq,magstep,magstep,magstephalf,mapsto,% + mapstochar,mathhexbox,mathpalette,mathstrut,matrix,max,maxdimen,% + medbreak,medskip,medskipamount,mid,min,models,mp,mu,multispan,% + nabla,narrower,natural,ne,nearrow,neg,negthinspace,neq,newbox,% + newcount,newdimen,newfam,newif,newinsert,newlanguage,newmuskip,% + newread,newskip,newtoks,newwrite,next,ni,nobreak,nointerlineskip,% + nonfrenchspacing,normalbaselines,normalbaselineskip,% + normallineskip,normallineskiplimit,not,notin,nu,null,nwarrow,o,O,% + oalign,obeylines,obeyspaces,odot,oe,OE,offinterlineskip,oint,% + ointop,omega,Omega,ominus,ooalign,openup,oplus,oslash,otimes,% + overbrace,overleftarrow,overrightarrow,owns,P,parallel,partial,% + perp,phantom,phi,Phi,pi,Pi,pm,pmatrix,pmod,Pr,prec,preceq,prime,% + prod,propto,psi,Psi,qquad,quad,raggedbottom,raggedright,rangle,% + rbrace,rbrack,rceil,Re,relbar,Relbar,removelastskip,repeat,% + rfloor,rgroup,rho,rhook,rightarrow,Rightarrow,rightarrowfill,% + rightharpoondown,rightharpoonup,rightleftharpoons,rightline,rlap,% + rmoustache,root,rq,S,sb,searrow,sec,setminus,sharp,showhyphens,% + sigma,Sigma,sim,simeq,sin,sinh,skew,slash,smallbreak,smallint,% + smallskip,smallskipamount,smash,smile,sp,space,spadesuit,sqcap,% + sqcup,sqrt,sqsubseteq,sqsupseteq,ss,star,strut,strutbox,subset,% + subseteq,succ,succeq,sum,sup,supset,supseteq,surd,swarrow,t,tan,% + tanh,tau,TeX,theta,Theta,thinspace,tilde,times,to,top,tracingall,% + triangle,triangleleft,triangleright,u,underbar,underbrace,% + uparrow,Uparrow,upbracefill,updownarrow,Updownarrow,uplus,% + upsilon,Upsilon,v,varepsilon,varphi,varpi,varrho,varsigma,% + vartheta,vdash,vdots,vec,vee,vert,Vert,vglue,vphantom,wedge,% + widehat,widetilde,wlog,wp,wr,xi,Xi,zeta}% + }% +\lst@definelanguage[primitive]{TeX}% + {moretexcs={above,abovedisplayshortskip,abovedisplayskip,aftergroup,% + abovewithdelims,accent,adjdemerits,advance,afterassignment,atop,% + atopwithdelims,badness,baselineskip,batchmode,begingroup,% + belowdisplayshortskip,belowdisplayskip,binoppenalty,botmark,box,% + boxmaxdepth,brokenpenalty,catcode,char,chardef,cleaders,closein,% + closeout,clubpenalty,copy,count,countdef,cr,crcr,csname,day,% + deadcycles,def,defaulthyphenchar,defaultskewchar,delcode,% + delimiter,delimiterfactor,delimitershortfall,dimen,dimendef,% + discretionary,displayindent,displaylimits,displaystyle,% + displaywidowpenalty,displaywidth,divide,doublehyphendemerits,dp,% + edef,else,emergencystretch,end,endcsname,endgroup,endinput,% + endlinechar,eqno,errhelp,errmessage,errorcontextlines,% + errorstopmode,escapechar,everycr,everydisplay,everyhbox,everyjob,% + everymath,everypar,everyvbox,exhyphenpenalty,expandafter,fam,fi,% + finalhypendemerits,firstmark,floatingpenalty,font,fontdimen,% + fontname,futurelet,gdef,global,globaldefs,halign,hangafter,% + hangindent,hbadness,hbox,hfil,hfill,hfilneg,hfuzz,hoffset,% + holdinginserts,hrule,hsize,hskip,hss,ht,hyphenation,hyphenchar,% + hyphenpenalty,if,ifcase,ifcat,ifdim,ifeof,iffalse,ifhbox,ifhmode,% + ifinner,ifmmode,ifnum,ifodd,iftrue,ifvbox,ifvmode,ifvoid,ifx,% + ignorespaces,immediate,indent,input,insert,insertpenalties,% + interlinepenalty,jobname,kern,language,lastbox,lastkern,% + lastpenalty,lastskip,lccode,leaders,left,lefthyphenmin,leftskip,% + leqno,let,limits,linepenalty,lineskip,lineskiplimits,long,% + looseness,lower,lowercase,mag,mark,mathaccent,mathbin,mathchar,% + mathchardef,mathchoice,mathclose,mathcode,mathinner,mathop,% + mathopen,mathord,mathpunct,mathrel,mathsurround,maxdeadcycles,% + maxdepth,meaning,medmuskip,message,mkern,month,moveleft,% + moveright,mskip,multiply,muskip,muskipdef,newlinechar,noalign,% + noboundary,noexpand,noindent,nolimits,nonscript,nonstopmode,% + nulldelimiterspace,nullfont,number,omit,openin,openout,or,outer,% + output,outputpenalty,over,overfullrule,overline,overwithdelims,% + pagedepth,pagefilllstretch,pagefillstretch,pagefilstretch,% + pagegoal,pageshrink,pagestretch,pagetotal,par,parfillskip,% + parindent,parshape,parskip,patterns,pausing,penalty,% + postdisplaypenalty,predisplaypenalty,predisplaysize,pretolerance,% + prevdepth,prevgraf,radical,raise,read,relax,relpenalty,right,% + righthyphenmin,rightskip,romannumeral,scriptfont,% + scriptscriptfont,scriptscriptstyle,scriptspace,scriptstyle,% + scrollmode,setbox,setlanguage,sfcode,shipout,show,showbox,% + showboxbreadth,showboxdepth,showlists,showthe,skewchar,skip,% + skipdef,spacefactor,spaceskip,span,special,splitbotmark,% + splitfirstmark,splitmaxdepth,splittopskip,string,tabskip,% + textfont,textstyle,the,thickmuskip,thinmuskip,time,toks,toksdef,% + tolerance,topmark,topskip,tracingcommands,tracinglostchars,% + tracingmacros,tracingonline,tracingoutput,tracingpages,% + tracingparagraphs,tracingrestores,tracingstats,uccode,uchyph,% + underline,unhbox,unhcopy,unkern,unpenalty,unskip,unvbox,unvcopy,% + uppercase,vadjust,valign,vbadness,vbox,vcenter,vfil,vfill,% + vfilneg,vfuzz,voffset,vrule,vsize,vskip,vsplit,vss,vtop,wd,% + widowpenalty,write,xdef,xleaders,xspaceskip,year},% + sensitive,% + alsoother={0123456789$_},% + morecomment=[l]\%% + }[keywords,tex,comments]% +\endinput +%% +%% End of file `lstlang3.sty'. diff --git a/doc/user/lstmisc.sty b/doc/user/lstmisc.sty new file mode 100644 index 0000000000..55c9c68bad --- /dev/null +++ b/doc/user/lstmisc.sty @@ -0,0 +1,1959 @@ +%% +%% This is file `lstmisc.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% listings.dtx (with options: `misc,0.21') +%% +%% Please read the software license in listings.dtx or listings.dvi. +%% +%% (w)(c) 1996 -- 2002 Carsten Heinz and/or any other author +%% listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% Permission is granted to modify the listings package as well as +%% lstdrvrs.dtx. You are not allowed to distribute a modified version +%% of the package or lstdrvrs.dtx unless you change the file names and +%% provide the original files. In any case it is better to contact the +%% address below; other users will welcome removed bugs, new features, +%% and additional programming languages. +%% +%% The listings package is free software. +%% +%% However, if you distribute the package as part of a commercial +%% product or if you use the package to prepare a commercial document +%% (books, journals, and so on), I'd like to encourage you to make a +%% donation to the LaTeX3 fund. The size of this `license fee' should +%% depend on the value of the package for your product. For more +%% information about LaTeX see http://www.latex-project.org +%% +%% No matter whether you use the package for a commercial or +%% non-commercial document, please send me a copy of the document (.dvi, +%% .ps, .pdf, hardcopy, etc.) to support further development---it is +%% easier to introduce new features or simplify things if I see how the +%% package is used by other people. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\def\filedate{2002/04/01} +\def\fileversion{1.0} +\ProvidesFile{lstmisc.sty} + [\filedate\space\fileversion\space(Carsten Heinz)] +\lst@CheckVersion\fileversion + {\typeout{^^J% + ***^^J% + *** This file requires `listings.sty' version \fileversion.^^J% + *** You have a serious problem, so I'm exiting ...^^J% + ***^^J}% + \batchmode \@@end} +\lst@BeginAspect{writefile} +\newtoks\lst@WFtoken % global +\lst@AddToHook{InitVarsBOL}{\global\lst@WFtoken{}} +\newwrite\lst@WF +\global\let\lst@WFifopen\iffalse % init +\gdef\lst@WFWriteToFile{% + \begingroup + \let\lst@UM\@empty + \expandafter\edef\expandafter\lst@temp\expandafter{\the\lst@WFtoken}% + \immediate\write\lst@WF{\lst@temp}% + \endgroup + \global\lst@WFtoken{}} +\gdef\lst@WFAppend#1{% + \global\lst@WFtoken=\expandafter{\the\lst@WFtoken#1}} +\gdef\lst@BeginWriteFile{\lst@WFBegin\@gobble} +\gdef\lst@BeginAlsoWriteFile{\lst@WFBegin\lst@OutputBox} +\begingroup \catcode`\^^I=11 +\gdef\lst@WFBegin#1#2{% + \begingroup + \let\lst@OutputBox#1% + \def\lst@Append##1{% + \advance\lst@length\@ne + \expandafter\lst@token\expandafter{\the\lst@token##1}% + \ifx ##1\lst@outputspace \else + \lst@WFAppend##1% + \fi}% + \lst@lAddTo\lst@PreGotoTabStop{\lst@WFAppend{^^I}}% + \lst@lAddTo\lst@ProcessSpace{\lst@WFAppend{ }}% + \let\lst@DeInit\lst@WFDeInit + \let\lst@MProcessListing\lst@WFMProcessListing + \lst@WFifopen\else + \immediate\openout\lst@WF=#2\relax + \global\let\lst@WFifopen\iftrue + \@gobbletwo\fi\fi + \fi} +\endgroup +\gdef\lst@EndWriteFile{% + \immediate\closeout\lst@WF \endgroup + \global\let\lst@WFifopen\iffalse} +\global\let\lst@WFMProcessListing\lst@MProcessListing +\global\let\lst@WFDeInit\lst@DeInit +\lst@AddToAtTop\lst@WFMProcessListing{\lst@WFWriteToFile} +\lst@AddToAtTop\lst@WFDeInit{% + \ifnum\lst@length=\z@\else \lst@WFWriteToFile \fi} +\lst@EndAspect +\lst@BeginAspect{strings} +\gdef\lst@stringtypes{d,b,m,bd,db} +\gdef\lst@StringKey#1#2{% + \lst@Delim\lst@stringstyle #2\relax + {String}\lst@stringtypes #1% + {\lst@BeginString\lst@EndString}% + \@@end\@empty{}} +\lst@Key{string}\relax{\lst@StringKey\@empty{#1}} +\lst@Key{morestring}\relax{\lst@StringKey\relax{#1}} +\lst@Key{deletestring}\relax{\lst@StringKey\@nil{#1}} +\lst@Key{stringstyle}{}{\def\lst@stringstyle{#1}} +\lst@AddToHook{EmptyStyle}{\let\lst@stringstyle\@empty} +\lst@Key{showstringspaces}t[t]{\lstKV@SetIf{#1}\lst@ifshowstringspaces} +\gdef\lst@BeginString{% + \lst@DelimOpen + \lst@ifexstrings\else + {\lst@ifshowstringspaces + \lst@keepspacestrue + \let\lst@outputspace\lst@visiblespace + \fi}} +\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifexstrings\iffalse} +\gdef\lst@EndString{\lst@DelimClose\lst@ifexstrings\else} +\gdef\lst@StringDM@d#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimBE{}{}{}#3{#1}{#5}#4} +\gdef\lst@StringDM@b#1#2\@empty#3#4#5{% + \let\lst@ifbstring\iftrue + \lst@CArg #2\relax\lst@DefDelimBE + {\lst@ifletter \lst@Output \lst@letterfalse \fi}% + {\ifx\lst@lastother\lstum@backslash + \expandafter\@gobblethree + \fi}{}#3{#1}{#5}#4} +\global\let\lst@ifbstring\iffalse % init +\lst@AddToHook{SelectCharTable}{% + \lst@ifbstring + \lst@CArgX \\\\\relax \lst@CDefX{}% + {\lst@ProcessOther\lstum@backslash + \lst@ProcessOther\lstum@backslash}% + {}% + \fi} +\global\let\lst@StringDM@bd\lst@StringDM@b +\global\let\lst@StringDM@db\lst@StringDM@bd +\gdef\lst@StringDM@m#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimBE{}{}% + {\let\lst@next\@gobblethree + \lst@ifletter\else + \ifx\lst@lastother)\else \ifx\lst@lastother]\else + \let\lst@next\@empty + \fi \fi \fi + \lst@next}#3{#1}{#5}#4} +\lst@EndAspect +\lst@BeginAspect{comments} +\gdef\lst@commenttypes{l,f,s,n} +\gdef\lst@CommentKey#1#2{% + \lst@Delim\lst@commentstyle #2\relax + {Comment}\lst@commenttypes #1% + {\lst@BeginComment\lst@EndComment}% + i\@empty{\lst@BeginInvisible\lst@EndInvisible}} +\lst@Key{comment}\relax{\lst@CommentKey\@empty{#1}} +\lst@Key{morecomment}\relax{\lst@CommentKey\relax{#1}} +\lst@Key{deletecomment}\relax{\lst@CommentKey\@nil{#1}} +\lst@Key{commentstyle}{}{\def\lst@commentstyle{#1}} +\lst@AddToHook{EmptyStyle}{\let\lst@commentstyle\itshape} +\gdef\lst@BeginComment{% + \lst@DelimOpen + \lst@ifexcomments\else + \lsthk@AfterBeginComment} +\gdef\lst@EndComment{\lst@DelimClose\lst@ifexcomments\else} +\lst@AddToHook{AfterBeginComment}{} +\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifexcomments\iffalse} +\gdef\lst@BeginInvisible#1#2#3\@empty{% + \lst@TrackNewLines \lst@XPrintToken + \lst@BeginDropOutput{#1}} +\gdef\lst@EndInvisible#1\@empty{\lst@EndDropOutput} +\gdef\lst@CommentDM@l#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} +\gdef\lst@CommentDM@f#1{% + \@ifnextchar[{\lst@Comment@@f{#1}}% + {\lst@Comment@@f{#1}[0]}} +\gdef\lst@Comment@@f#1[#2]#3\@empty#4#5#6{% + \lst@CArg #3\relax\lst@DefDelimB{}{}% + {\lst@CalcColumn + \ifnum #2=\@tempcnta\else + \expandafter\@gobblethree + \fi}% + #4{#1}{#6\lst@Lmodetrue}} +\gdef\lst@CommentDM@s#1#2#3\@empty#4#5#6{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% + \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}} +\gdef\lst@CommentDM@n#1#2#3\@empty#4#5#6{% + \ifx\@empty#3\@empty\else + \def\@tempa{#2}\def\@tempb{#3}% + \ifx\@tempa\@tempb + \PackageError{Listings}{Identical delimiters}% + {These delimiters make no sense with nested comments.}% + \else + \lst@CArg #2\relax\lst@DefDelimB + {}% + {\ifnum\lst@mode=#1\relax \expandafter\@gobble \fi}% + {}#4{#1}{#6}% + \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}% + \fi + \fi} +\lst@EndAspect +\lst@BeginAspect{pod} +\lst@Key{printpod}{false}[t]{\lstKV@SetIf{#1}\lst@ifprintpod} +\lst@Key{podcomment}{false}[t]{\lstKV@SetIf{#1}\lst@ifpodcomment} +\lst@AddToHookExe{SetLanguage}{\let\lst@ifpodcomment\iffalse} +\lst@NewMode\lst@PODmode +\lst@AddToHook{SelectCharTable} + {\lst@ifpodcomment + \lst@CArgX =\relax\lst@DefDelimB{}{}% + {\ifnum\@tempcnta=\z@ + \lst@ifprintpod\else + \def\lst@bnext{\lst@BeginDropOutput\lst@PODmode}% + \expandafter\expandafter\expandafter\@gobblethree + \fi + \else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@PODmode\lst@commentstyle + \lst@CArgX =cut\^^M\relax\lst@DefDelimE + {\lst@CalcColumn}% + {\ifnum\@tempcnta=\z@\else + \expandafter\@gobblethree + \fi}% + {}% + \lst@EndComment\lst@PODmode + \fi} +\lst@EndAspect +\lst@BeginAspect{escape} +\lst@Key{texcl}{false}[t]{\lstKV@SetIf{#1}\lst@iftexcl} +\lst@AddToHook{TextStyle}{\let\lst@iftexcl\iffalse} +\lst@AddToHook{EOL} + {\ifnum\lst@mode=\lst@TeXLmode + \expandafter\lst@escapeend + \expandafter\lst@LeaveAllModes + \expandafter\lst@ReenterModes + \fi} +\lst@AddToHook{AfterBeginComment} + {\lst@iftexcl \lst@ifLmode \lst@ifdropinput\else + \lst@PrintToken + \lst@LeaveMode \lst@InterruptModes + \lst@EnterMode{\lst@TeXLmode}{\lst@modetrue\lst@commentstyle}% + \expandafter\expandafter\expandafter\lst@escapebegin + \fi \fi \fi} +\lst@NewMode\lst@TeXLmode +\gdef\lst@ActiveCDefX#1{\lst@ActiveCDefX@#1} +\gdef\lst@ActiveCDefX@#1#2#3{ + \catcode`#1\active\lccode`\~=`#1% + \lowercase{\lst@CDefIt~}{#2}{#3}{}} +\gdef\lst@Escape#1#2#3#4{% + \lst@CArgX #1\relax\lst@CDefX + {}% + {\lst@ifdropinput\else + \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken + \lst@InterruptModes + \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}% + \ifx\^^M#2% + \lst@CArg #2\relax\lst@ActiveCDefX + {}% + {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes}% + {\lst@MProcessListing}% + \else + \lst@CArg #2\relax\lst@ActiveCDefX + {}% + {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes + \lst@whitespacefalse}% + {}% + \fi + #3\lst@escapebegin + \fi}% + {}} +\lst@NewMode\lst@TeXmode +\lst@Key{escapebegin}{}{\def\lst@escapebegin{#1}} +\lst@Key{escapeend}{}{\def\lst@escapeend{#1}} +\lst@Key{escapechar}{} + {\ifx\@empty#1\@empty + \let\lst@DefEsc\relax + \else + \def\lst@DefEsc{\lst@Escape{#1}{#1}{}{}}% + \fi} +\lst@AddToHook{TextStyle}{\let\lst@DefEsc\@empty} +\lst@AddToHook{SelectCharTable}{\lst@DefEsc} +\lst@Key{escapeinside}{}{\lstKV@TwoArg{#1}% + {\let\lst@DefEsc\@empty + \ifx\@empty##1@empty\else \ifx\@empty##2\@empty\else + \def\lst@DefEsc{\lst@Escape{##1}{##2}{}{}}% + \fi\fi}} +\lst@Key{mathescape}{false}[t]{\lstKV@SetIf{#1}\lst@ifmathescape} +\lst@AddToHook{SelectCharTable} + {\lst@ifmathescape \lst@Escape{\$}{\$}% + {\setbox\@tempboxa=\hbox\bgroup$}% + {$\egroup \lst@CalcLostSpaceAndOutput}\fi} +\lst@EndAspect +\lst@BeginAspect{keywords} +\global\let\lst@ifsensitive\iftrue % init +\global\let\lst@ifsensitivedefed\iffalse % init % \global +\lst@ifsavemem\else +\gdef\lst@KeywordTest#1#2#3{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#1@\the\lst@token\endcsname + \endgroup + \ifx\@gtempa\relax\else + \let\lst@thestyle\@gtempa + \fi} +\gdef\lst@KEYWORDTEST{% + \uppercase\expandafter{\expandafter + \lst@KEYWORDTEST@\the\lst@token}\relax} +\gdef\lst@KEYWORDTEST@#1\relax#2#3#4{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#2@#1\endcsname + \endgroup + \ifx\@gtempa\relax\else + \let\lst@thestyle\@gtempa + \fi} +\gdef\lst@WorkingTest#1#2#3{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#1@\the\lst@token\endcsname + \endgroup + \@gtempa} +\gdef\lst@WORKINGTEST{% + \uppercase\expandafter{\expandafter + \lst@WORKINGTEST@\the\lst@token}\relax} +\gdef\lst@WORKINGTEST@#1\relax#2#3#4{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#2@#1\endcsname + \endgroup + \@gtempa} +\gdef\lst@DefineKeywords#1#2#3{% + \lst@ifsensitive + \def\lst@next{\lst@for#2}% + \else + \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}% + \fi + \lst@next\do + {\expandafter\ifx\csname\@lst#1@##1\endcsname\relax + \global\expandafter\let\csname\@lst#1@##1\endcsname#3% + \fi}} +\gdef\lst@UndefineKeywords#1#2#3{% + \lst@ifsensitivedefed + \def\lst@next{\lst@for#2}% + \else + \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}% + \fi + \lst@next\do + {\expandafter\ifx\csname\@lst#1@##1\endcsname#3% + \global\expandafter\let\csname\@lst#1@##1\endcsname\relax + \fi}} +\fi +\lst@ifsavemem +\gdef\lst@IfOneOutOf#1\relax#2{% + \def\lst@temp##1,#1,##2##3\relax{% + \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}% + \def\lst@next{\lst@IfOneOutOf@#1\relax}% + \expandafter\lst@next#2\relax\relax} +\gdef\lst@IfOneOutOf@#1\relax#2#3{% + \ifx#2\relax + \expandafter\@secondoftwo + \else + \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax + \expandafter\lst@next + \fi} +\ifx\iffalse\else\fi +\gdef\lst@IOOOfirst#1\relax#2#3{\fi#2} +\gdef\lst@IFONEOUTOF#1\relax#2{% + \uppercase{\def\lst@temp##1,#1},##2##3\relax{% + \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}% + \def\lst@next{\lst@IFONEOUTOF@#1\relax}% + \expandafter\lst@next#2\relax} +\gdef\lst@IFONEOUTOF@#1\relax#2#3{% + \ifx#2\relax + \expandafter\@secondoftwo + \else + \uppercase + {\expandafter\lst@temp\expandafter,#2,#1,\@empty\relax}% + \expandafter\lst@next + \fi} +\gdef\lst@KWTest{% + \begingroup \let\lst@UM\@empty + \expandafter\xdef\expandafter\@gtempa\expandafter{\the\lst@token}% + \endgroup + \expandafter\lst@IfOneOutOf\@gtempa\relax} +\gdef\lst@KeywordTest#1#2#3{\lst@KWTest #2{\let\lst@thestyle#3}{}} +\global\let\lst@KEYWORDTEST\lst@KeywordTest +\gdef\lst@WorkingTest#1#2#3{\lst@KWTest #2#3{}} +\global\let\lst@WORKINGTEST\lst@WorkingTest +\fi +\lst@Key{sensitive}\relax[t]{\lstKV@SetIf{#1}\lst@ifsensitive} +\lst@AddToHook{SetLanguage}{\let\lst@ifsensitive\iftrue} +\lst@AddToHook{Init} + {\lst@ifsensitive\else + \let\lst@KeywordTest\lst@KEYWORDTEST + \let\lst@WorkingTest\lst@WORKINGTEST + \let\lst@IfOneOutOf\lst@IFONEOUTOF + \fi} +\gdef\lst@MakeMacroUppercase#1{% + \ifx\@undefined#1\else \uppercase\expandafter + {\expandafter\def\expandafter#1\expandafter{#1}}% + \fi} +\gdef\lst@InstallTest#1#2#3#4#5#6#7#8{% + \lst@AddToHook{TrackKeywords}{\lst@TrackKeywords{#1}#2#4#6#7#8}% + \lst@AddToHook{PostTrackKeywords}{\lst@PostTrackKeywords#2#3#4#5}} +\lst@AddToHook{Init}{\lsthk@TrackKeywords\lsthk@PostTrackKeywords} +\lst@AddToHook{TrackKeywords}{}% init +\lst@AddToHook{PostTrackKeywords}{}% init +\lst@AddToHook{Output}{\lst@ifkeywords \lsthk@DetectKeywords \fi} +\lst@AddToHook{DetectKeywords}{}% init +\lst@AddToHook{ModeTrue}{\let\lst@ifkeywords\iffalse} +\lst@AddToHook{Init}{\let\lst@ifkeywords\iftrue} +\gdef\lst@InstallTestNow#1#2#3#4#5{% + \@ifundefined{\string#2#1}% + {\global\@namedef{\string#2#1}{}% + \edef\@tempa{% + \noexpand\lst@AddToHook{\ifx#5dDetectKeywords\else Output\fi}% + {\ifx #4w\noexpand\lst@WorkingTest + \else\noexpand\lst@KeywordTest \fi + {#1}\noexpand#2\noexpand#3}}% + \lst@ifsavemem + \@tempa + \else + \@ifundefined{\@lst#1@if@ins}% + {\@tempa \global\@namedef{\@lst#1@if@ins}{}}% + {}% + \fi} + {}} +\gdef\lst@TrackKeywords#1#2#3#4#5#6{% + \lst@false + \def\lst@arg{{#1}#4}% + \expandafter\expandafter\expandafter\lst@TK@ + \expandafter\lst@arg#2\relax\relax + \lst@ifsavemem\else + \def\lst@arg{{#1}#4#2}% + \expandafter\expandafter\expandafter\lst@TK@@ + \expandafter\lst@arg#3\relax\relax + \fi + \lst@if \lst@InstallTestNow{#1}#2#4#5#6\fi} +\gdef\lst@TK@#1#2#3#4{% + \ifx\lst@ifsensitive\lst@ifsensitivedefed + \ifx#3#4\else + \lst@true + \lst@ifsavemem\else + \lst@UndefineKeywords{#1}#4#2% + \lst@DefineKeywords{#1}#3#2% + \fi + \fi + \else + \ifx#3\relax\else + \lst@true + \lst@ifsavemem\else + \lst@UndefineKeywords{#1}#4#2% + \lst@DefineKeywords{#1}#3#2% + \fi + \fi + \fi + \lst@ifsavemem \ifx#3\relax\else + \lst@ifsensitive\else \lst@MakeMacroUppercase#3\fi + \fi \fi + \ifx#3\relax + \expandafter\@gobblethree + \fi + \lst@TK@{#1}#2} +\gdef\lst@TK@@#1#2#3#4#5{% + \ifx#4\relax + \expandafter\@gobblefour + \else + \lst@IfSubstring{#4#5}#3{}{\lst@UndefineKeywords{#1}#5#2}% + \fi + \lst@TK@@{#1}#2#3} +\lst@AddToHook{InitVars} + {\global\let\lst@ifsensitivedefed\lst@ifsensitive} +\gdef\lst@PostTrackKeywords#1#2#3#4{% + \lst@ifsavemem\else + \global\let#3#1% + \global\let#4#2% + \fi} +\lst@Key{classoffset}\z@{\def\lst@classoffset{#1}} +\gdef\lst@InstallFamily#1#2#3#4#5{% + \lst@Key{#2}\relax{\lst@UseFamily{#2}##1\relax\lst@MakeKeywords}% + \lst@Key{more#2}\relax + {\lst@UseFamily{#2}##1\relax\lst@MakeMoreKeywords}% + \lst@Key{delete#2}\relax + {\lst@UseFamily{#2}##1\relax\lst@DeleteKeywords}% + \ifx\@empty#3\@empty\else + \lst@Key{#3}{#4}{\lstKV@OptArg[\@ne]{##1}% + {\@tempcnta\lst@classoffset \advance\@tempcnta####1\relax + \@namedef{lst@#3\ifnum\@tempcnta=\@ne\else \the\@tempcnta + \fi}{####2}}}% + \fi + \expandafter\lst@InstallFamily@ + \csname\@lst @#2@data\expandafter\endcsname + \csname\@lst @#5\endcsname {#1}{#2}{#3}} +\gdef\lst@InstallFamily@#1#2#3#4#5#6#7#8{% + \gdef#1{{#3}{#4}{#5}#2#7}% + \long\def\lst@temp##1{#6}% + \ifx\lst@temp\@gobble + \lst@AddTo#1{s#8}% + \else + \lst@AddTo#1{w#8}% + \global\@namedef{lst@g#4@wp}##1{#6}% + \fi} +\gdef\lst@UseFamily#1{% + \def\lst@family{#1}% + \@ifnextchar[\lst@UseFamily@{\lst@UseFamily@[\@ne]}} +\gdef\lst@UseFamily@[#1]{% + \@tempcnta\lst@classoffset \advance\@tempcnta#1\relax + \lst@ProvideFamily\lst@family + \lst@UseFamily@a + {\lst@family\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}} +\gdef\lst@UseFamily@a#1{% + \expandafter\lst@UseFamily@b + \csname\@lst @#1@list\expandafter\endcsname + \csname\@lst @#1\expandafter\endcsname + \csname\@lst @#1@also\expandafter\endcsname + \csname\@lst @g#1\endcsname} +\gdef\lst@UseFamily@b#1#2#3#4#5\relax#6{\lstKV@XOptArg[]{#5}#6#1#2#3#4} +\gdef\lst@ProvideFamily#1{% + \@ifundefined{lst@#1\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}% + {\expandafter\expandafter\expandafter\lst@ProvideFamily@ + \csname\@lst @#1@data\endcsname + {\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}% + {}} +\gdef\lst@ProvideFamily@#1#2#3#4#5#6#7#8{% + \expandafter\xdef\csname\@lst @g#2#8@sty\endcsname + {\if #6w% + \expandafter\noexpand\csname\@lst @g#2@wp\endcsname{#8}% + \else + \expandafter\noexpand\csname\@lst @#3#8\endcsname + \fi}% + \ifx\@empty#3\@empty\else + \edef\lst@temp{\noexpand\lst@AddToHook{Init}{% + \noexpand\lst@ProvideStyle\expandafter\noexpand + \csname\@lst @#3#8\endcsname\noexpand#4}}% + \lst@temp + \fi + \expandafter\lst@ProvideFamily@@ + \csname\@lst @#2#8@list\expandafter\endcsname + \csname\@lst @#2#8\expandafter\endcsname + \csname\@lst @#2#8@also\expandafter\endcsname + \csname\@lst @g#2#8@list\expandafter\endcsname + \csname\@lst @g#2#8\expandafter\endcsname + \csname\@lst @g#2#8@sty\expandafter\endcsname + {#1}#5#6#7} +\gdef\lst@ProvideFamily@@#1#2#3#4#5#6#7#8{% + \gdef#1{#2#5}\global\let#2\@empty \global\let#3\@empty % init + \gdef#4{#2#5}\global\let#5\@empty % init + \if #8l\relax + \lst@AddToHook{SetLanguage}{\def#1{#2#5}\let#2\@empty}% + \fi + \lst@InstallTest{#7}#1#2#4#5#6} +\gdef\lst@InstallKeywords#1#2#3#4#5{% + \lst@Key{#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeKeywords}% + \lst@Key{more#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeMoreKeywords}% + \lst@Key{delete#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@DeleteKeywords}% + \ifx\@empty#3\@empty\else + \lst@Key{#3}{#4}{\@namedef{lst@#3}{##1}}% + \fi + \expandafter\lst@InstallFamily@ + \csname\@lst @#2@data\expandafter\endcsname + \csname\@lst @#5\endcsname {#1}{#2}{#3}} +\gdef\lst@ProvideStyle#1#2{% + \ifx#1\@undefined \let#1#2% + \else\ifx#1\relax \let#1#2\fi\fi} +\gdef\lst@BuildClassList#1#2,{% + \ifx\relax#2\@empty\else + \ifx\@empty#2\@empty\else + \lst@lExtend#1{\csname\@lst @#2\expandafter\endcsname + \csname\@lst @g#2\endcsname}% + \fi + \expandafter\lst@BuildClassList\expandafter#1 + \fi} +\gdef\lst@DeleteClassesIn#1#2{% + \expandafter\lst@DCI@\expandafter#1#2\relax\relax} +\gdef\lst@DCI@#1#2#3{% + \ifx#2\relax + \expandafter\@gobbletwo + \else + \def\lst@temp##1#2#3##2{% + \lst@lAddTo#1{##1}% + \ifx ##2\relax\else + \expandafter\lst@temp + \fi ##2}% + \let\@tempa#1\let#1\@empty + \expandafter\lst@temp\@tempa#2#3\relax + \fi + \lst@DCI@#1} +\gdef\lst@MakeKeywords[#1]#2#3#4#5#6{% + \def#3{#4#6}\let#4\@empty \let#5\@empty + \lst@MakeMoreKeywords[#1]{#2}#3#4#5#6} +\gdef\lst@MakeMoreKeywords[#1]#2#3#4#5#6{% + \lst@BuildClassList#3#1,\relax,% + \lst@DefOther\lst@temp{,#2}\lst@lExtend#4\lst@temp} +\gdef\lst@DeleteKeywords[#1]#2#3#4#5#6{% + \lst@MakeKeywords[#1]{#2}\@tempa\@tempb#5#6% + \lst@DeleteClassesIn#3\@tempa + \lst@DeleteKeysIn#4\@tempb} +\lst@InstallFamily k{keywords}{keywordstyle}\bfseries{keywordstyle}{}ld +\lst@Key{ndkeywords}\relax + {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@MakeKeywords}% +\lst@Key{morendkeywords}\relax + {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@MakeMoreKeywords}% +\lst@Key{deletendkeywords}\relax + {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@DeleteKeywords}% +\lst@Key{ndkeywordstyle}\relax{\@namedef{lst@keywordstyle2}{#1}}% +\lst@Key{keywordsprefix}\relax{\lst@DefActive\lst@keywordsprefix{#1}} +\global\let\lst@keywordsprefix\@empty +\lst@AddToHook{SelectCharTable} + {\ifx\lst@keywordsprefix\@empty\else + \expandafter\lst@CArg\lst@keywordsprefix\relax + \lst@CDef{}% + {\lst@ifletter\else + \global\let\lst@prefixkeyword\@empty + \fi}% + {}% + \fi} +\lst@AddToHook{Init}{\global\let\lst@prefixkeyword\relax} +\lst@AddToHook{Output} + {\ifx\lst@prefixkeyword\@empty + \let\lst@thestyle\lst@gkeywords@sty + \global\let\lst@prefixkeyword\relax + \fi}% +\lst@Key{otherkeywords}{}{% + \let\lst@otherkeywords\@empty + \lst@for{#1}\do{% + \lst@MakeActive{##1}% + \lst@lExtend\lst@otherkeywords{% + \expandafter\lst@CArg\lst@temp\relax\lst@CDef + {}\lst@PrintOtherKeyword\@empty}}} +\lst@AddToHook{SelectCharTable}{\lst@otherkeywords} +\gdef\lst@PrintOtherKeyword#1\@empty{% + \lst@XPrintToken + \begingroup + \lst@modetrue \lsthk@TextStyle + \let\lst@ProcessDigit\lst@ProcessLetter + \let\lst@ProcessOther\lst@ProcessLetter + \lst@lettertrue + \lst@gkeywords@sty{#1\lst@XPrintToken}% + \endgroup} +\lst@EndAspect +\lst@BeginAspect[keywords]{emph} +\lst@InstallFamily e{emph}{emphstyle}{}{emphstyle}{}od +\lst@EndAspect +\lst@BeginAspect[keywords]{tex} +\lst@InstallKeywords{cs}{texcs}{texcsstyle}\relax{keywordstyle} + {\ifx\lst@lastother\lstum@backslash + \let\lst@thestyle\lst@texcsstyle + \fi} + ld +\lst@EndAspect +\lst@BeginAspect[keywords]{directives} +\lst@NewMode\lst@CDmode +\lst@AddToHook{EOL}{\ifnum\lst@mode=\lst@CDmode \lst@LeaveMode \fi} +\lst@InstallKeywords{d}{directives}{directivestyle}\relax{keywordstyle} + {\ifnum\lst@mode=\lst@CDmode + \let\lst@thestyle\lst@directivestyle + \fi} + ld +\lst@AddToHook{SelectCharTable} + {\ifx\lst@directives\@empty\else + \lst@DefSaveDef{`\#}\lsts@CCD + {\lst@CalcColumn + \lst@ifmode\else + \ifnum\@tempcnta=\z@ + \lst@EnterMode{\lst@CDmode}{}% + \fi + \fi + \ifnum\lst@mode=\lst@CDmode + \ifnum\@tempcnta=\z@ + \lst@XPrintToken + {\let\lst@currstyle\lst@directivestyle + \lsts@CCD\lst@PrintToken}% + \else \lsts@CCD + \fi + \else \lsts@CCD + \fi}% + \fi} +\lst@AddTo\lst@stringtypes{,directive} +\gdef\lst@StringDM@directive#1#2#3\@empty{% + \lst@CArg #2\relax\lst@CDef + {}% + {\let\lst@bnext\lst@CArgEmpty + \ifnum\lst@mode=\lst@CDmode + \def\lst@bnext{\lst@BeginString{#1}}% + \fi + \lst@bnext}% + \@empty + \lst@CArg #3\relax\lst@CDef + {}% + {\let\lst@enext\lst@CArgEmpty + \ifnum #1=\lst@mode + \let\lst@bnext\lst@EndString + \fi + \lst@bnext}% + \@empty} +\lst@EndAspect +\lst@BeginAspect[keywords]{html} +\lst@NewMode\lst@insidemode +\lst@Key{keywordsinside}{}{\lstKV@TwoArg{#1} + {\let\lst@DefInside\@empty + \ifx\@empty##1\@empty\else \ifx\@empty##2\@empty\else + \def\lst@DefInside{% + \lst@DefSaveDef{`##1}\lsts@insideb + {\lst@ifmode\else \ifnum\lst@mode=\lst@insidemode\else + \lst@XPrintToken + \lst@EnterMode\lst@insidemode{}% + \fi\fi + \lsts@insideb}% + \lst@DefSaveDef{`##2}\lsts@insidee + {\ifnum\lst@mode=\lst@insidemode + \lsts@insidee \lst@XPrintToken\lst@LeaveMode + \else + \expandafter\lsts@insidee + \fi}}% + \fi\fi}} +\lst@AddToHook{SelectCharTable}{\lst@DefInside} +\lst@AddToHook{SetLanguage}{\let\lst@DefInside\@empty} +\lst@AddToHook{Output} + {\ifx\lst@DefInside\@empty\else \ifx\lst@thestyle\lst@gkeywords@sty + \ifnum\lst@mode=\lst@insidemode\else + \let\lst@thestyle\@empty + \fi + \fi\fi} +\lst@Key{usekeywordsinside}t[t]{\lstKV@SetIf{#1}\lst@ifusekeysinside} +\lst@AddToHook{Output} + {\ifnum\lst@mode=\lst@insidemode \lst@ifusekeysinside\else + \let\lst@thestyle\lst@gkeywords@sty + \fi\fi} +\gdef\lst@BeginCDATA#1\@empty{% + \lst@TrackNewLines \lst@PrintToken + \lst@EnterMode\lst@GPmode{}\let\lst@ifmode\iffalse + \lst@mode\lst@insidemode #1\lst@mode\lst@GPmode\relax\lst@modetrue} +\lst@EndAspect +\lst@BeginAspect[keywords,comments]{keywordcomments} +\lst@NewMode\lst@KCmode \lst@NewMode\lst@KCSmode +\gdef\lst@BeginKC{% + \lst@ResetToken + \lst@BeginComment\lst@KCmode\lst@commentstyle\@empty} +\gdef\lst@BeginKCS{% + \lst@ResetToken + \lst@BeginComment\lst@KCSmode\lst@commentstyle\@empty} +\lst@AddToHook{PostOutput}{\lst@KCpost \global\let\lst@KCpost\@empty} +\global\let\lst@KCpost\@empty % init +\gdef\lst@EndKC{\lst@SaveToken \lst@LeaveMode \lst@RestoreToken} +\lst@InstallKeywords{kc}{keywordcomment}{}\relax{} + {\ifnum\lst@mode=\lst@KCmode + \edef\lst@temp{\the\lst@token}% + \ifx\lst@temp\lst@KCmatch + \lst@EndKC + \fi + \else + \lst@ifmode\else + \xdef\lst@KCmatch{\the\lst@token}% + \global\let\lst@KCpost\lst@BeginKC + \fi + \fi} + lo +\lst@Key{keywordcommentsemicolon}{}{\lstKV@ThreeArg{#1}% + {\def\lst@KCAkeywordsB{##1}% + \def\lst@KCAkeywordsE{##2}% + \def\lst@KCBkeywordsB{##3}% + \def\lst@KCkeywords{##1##2##3}}} +\lst@AddToHook{SelectCharTable} + {\ifx\lst@KCkeywords\@empty\else + \lst@DefSaveDef{`\;}\lsts@EKC + {\lst@XPrintToken + \ifnum\lst@mode=\lst@KCmode \lst@EndComment\@empty \else + \ifnum\lst@mode=\lst@KCSmode \lst@EndComment\@empty + \fi \fi + \lsts@EKC}% + \fi} +\gdef\lst@KCAWorkB{% + \lst@ifmode\else \global\let\lst@KCpost\lst@BeginKC \fi} +\gdef\lst@KCBWorkB{% + \lst@ifmode\else \global\let\lst@KCpost\lst@BeginKCS \fi} +\gdef\lst@KCAWorkE{\ifnum\lst@mode=\lst@KCmode \lst@EndKC \fi} +\lst@ProvideFamily@@ + \lst@KCAkeywordsB@list\lst@KCAkeywordsB \lst@KC@also + \lst@gKCAkeywordsB@list\lst@gKCAkeywordsB \lst@KCAWorkB + {kcb}owo % prefix, other key, working procedure, Output hook +\lst@ProvideFamily@@ + \lst@KCAkeywordsE@list\lst@KCAkeywordsE \lst@KC@also + \lst@gKCAkeywordsE@list\lst@gKCAkeywordsE \lst@KCAWorkE + {kce}owo +\lst@ProvideFamily@@ + \lst@KCBkeywordsB@list\lst@KCBkeywordsB \lst@KC@also + \lst@gKCBkeywordsB@list\lst@gKCBkeywordsB \lst@KCBWorkB + {kcs}owo +\lst@EndAspect +\lst@BeginAspect[keywords]{index} +\lst@InstallFamily w{index}{indexstyle}\lstindexmacro{indexstyle} + {\csname\@lst @indexstyle#1\expandafter\endcsname + \expandafter{\the\lst@token}} + od +\lst@UserCommand\lstindexmacro#1{\index{{\ttfamily#1}}} +\lst@EndAspect +\lst@BeginAspect[keywords]{procnames} +\gdef\lst@procnametrue{\global\let\lst@ifprocname\iftrue} +\gdef\lst@procnamefalse{\global\let\lst@ifprocname\iffalse} +\lst@AddToHook{Init}{\lst@procnamefalse} +\lst@AddToHook{DetectKeywords} + {\lst@ifprocname + \let\lst@thestyle\lst@procnamestyle + \lst@ifindexproc \csname\@lst @gindex@sty\endcsname \fi + \lst@procnamefalse + \fi} +\lst@Key{procnamestyle}{}{\def\lst@procnamestyle{#1}} +\lst@Key{indexprocnames}{false}[t]{\lstKV@SetIf{#1}\lst@ifindexproc} +\lst@AddToHook{Init}{\lst@ifindexproc \lst@indexproc \fi} +\gdef\lst@indexproc{% + \@ifundefined{lst@indexstyle1}% + {\@namedef{lst@indexstyle1}##1{}}% + {}} +\lst@InstallKeywords w{procnamekeys}{}\relax{} + {\global\let\lst@PNpost\lst@procnametrue} + od +\lst@AddToHook{PostOutput}{\lst@PNpost\global\let\lst@PNpost\@empty} +\global\let\lst@PNpost\@empty % init +\lst@EndAspect +\lst@BeginAspect{style} +\@ifundefined{lststylefiles} + {\lst@UserCommand\lststylefiles{lststy0.sty}}{} +\lst@UserCommand\lstdefinestyle{\lst@DefStyle\iftrue} +\lst@UserCommand\lst@definestyle{\lst@DefStyle\iffalse} +\gdef\lst@DefStyle{\lst@DefDriver{style}{sty}\lstset} +\global\@namedef{lststy@$}{\lsthk@EmptyStyle} +\lst@AddToHook{EmptyStyle}{}% init +\lst@Key{style}\relax{% + \lst@LAS{style}{sty}{[]{#1}}\lst@NoAlias\lststylefiles + \lsthk@SetStyle + {}} +\lst@AddToHook{SetStyle}{}% init +\lst@EndAspect +\lst@BeginAspect{language} +\@ifundefined{lstdriverfiles} + {\lst@UserCommand\lstlanguagefiles{lstlang0.sty}}{} +\lst@UserCommand\lstdefinelanguage{\lst@DefLang\iftrue} +\lst@UserCommand\lst@definelanguage{\lst@DefLang\iffalse} +\gdef\lst@DefLang{\lst@DefDriver{language}{lang}\lstset} +\lstdefinelanguage{}{} +\lst@Key{language}\relax{\lstKV@OptArg[]{#1}% + {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles + \lsthk@SetLanguage + {\lst@FindAlias[##1]{##2}% + \let\lst@language\lst@malias + \let\lst@dialect\lst@oalias}}} +\lst@Key{alsolanguage}\relax{\lstKV@OptArg[]{#1}% + {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles + {}% + {\lst@FindAlias[##1]{##2}% + \let\lst@language\lst@malias + \let\lst@dialect\lst@oalias}}} +\lst@AddToHook{SetLanguage}{}% init +\lst@UserCommand\lstalias{\@ifnextchar[\lstalias@\lstalias@@} +\gdef\lstalias@[#1]#2[#3]#4{\lst@NormedNameDef{lsta@#2$#1}{#4$#3}} +\gdef\lstalias@@#1#2{\lst@NormedNameDef{lsta@#1}{#2}} +\lst@Key{defaultdialect}\relax + {\lstKV@OptArg[]{#1}{\lst@NormedNameDef{lstdd@##2}{##1}}} +\gdef\lst@FindAlias[#1]#2{% + \lst@NormedDef\lst@oalias{#1}% + \lst@NormedDef\lst@malias{#2}% + \@ifundefined{lsta@\lst@malias}{}% + {\edef\lst@malias{\csname\@lst a@\lst@malias\endcsname}}% + \ifx\@empty\lst@oalias \@ifundefined{lstdd@\lst@malias}{}% + {\edef\lst@oalias{\csname\@lst dd@\lst@malias\endcsname}}% + \fi + \edef\lst@temp{\lst@malias $\lst@oalias}% + \@ifundefined{lsta@\lst@temp}{}% + {\edef\lst@temp{\csname\@lst a@\lst@temp\endcsname}}% + \expandafter\lst@FindAlias@\lst@temp $} +\gdef\lst@FindAlias@#1$#2${% + \def\lst@malias{#1}\def\lst@oalias{#2}% + \ifx\@empty\lst@oalias \@ifundefined{lstdd@\lst@malias}{}% + {\edef\lst@oalias{\csname\@lst dd@\lst@malias\endcsname}}% + \fi} +\gdef\lst@RequireLanguages#1{% + \lst@Require{language}{lang}{#1}\lst@FindAlias\lstlanguagefiles + \ifx\lst@loadaspects\@empty\else + \lst@RequireAspects\lst@loadaspects + \fi} +\global\let\lstloadlanguages\lst@RequireLanguages +\lst@EndAspect +\lst@BeginAspect{formats} +\@ifundefined{lstformatfiles} + {\lst@UserCommand\lstformatfiles{lstfmt0.sty}}{} +\lst@UserCommand\lstdefineformat{\lst@DefFormat\iftrue} +\lst@UserCommand\lst@defineformat{\lst@DefFormat\iffalse} +\gdef\lst@DefFormat{\lst@DefDriver{format}{fmt}\lst@UseFormat} +\lstdefineformat{}{} +\lst@Key{format}\relax{% + \lst@LAS{format}{fmt}{[]{#1}}\lst@NoAlias\lstformatfiles + \lsthk@SetFormat + {}} +\lst@AddToHook{SetFormat}{\let\lst@fmtformat\@empty}% init +\gdef\lst@fmtSplit#1#2{% + \def\lst@temp##1#2##2\relax##3{% + \ifnum##3=\z@ + \ifx\@empty##2\@empty + \lst@false + \let\lst@fmta#1% + \let\lst@fmtb\@empty + \else + \expandafter\lst@temp#1\relax\@ne + \fi + \else + \def\lst@fmta{##1}\def\lst@fmtb{##2}% + \fi}% + \lst@true + \expandafter\lst@temp#1#2\relax\z@} +\gdef\lst@IfNextCharWhitespace#1#2#3{% + \lst@IfSubstring#3\lst@whitespaces{#1}{#2}#3} +\begingroup +\catcode`\^^I=12\catcode`\^^J=12\catcode`\^^M=12\catcode`\^^L=12\relax% +\lst@DefActive\lst@whitespaces{\ ^^I^^J^^M}% add ^^L +\global\let\lst@whitespaces\lst@whitespaces% +\endgroup +\gdef\lst@fmtIfIdentifier#1{% + \ifx\relax#1\@empty + \expandafter\@secondoftwo + \else + \expandafter\lst@fmtIfIdentifier@\expandafter#1% + \fi} +\gdef\lst@fmtIfIdentifier@#1#2\relax{% + \let\lst@next\@secondoftwo + \ifnum`#1=`_\else + \ifnum`#1<64\else + \ifnum`#1<91\let\lst@next\@firstoftwo\else + \ifnum`#1<97\else + \ifnum`#1<123\let\lst@next\@firstoftwo\else + \fi \fi \fi \fi \fi + \lst@next} +\gdef\lst@fmtIfNextCharIn#1{% + \ifx\@empty#1\@empty \expandafter\@secondoftwo \else + \def\lst@next{\lst@fmtIfNextCharIn@{#1}}% + \expandafter\lst@next\fi} +\gdef\lst@fmtIfNextCharIn@#1#2#3#4{% + \def\lst@temp##1#4##2##3\relax{% + \ifx \@empty##2\expandafter\@secondoftwo + \else \expandafter\@firstoftwo \fi}% + \lst@temp#1#4\@empty\relax{#2}{#3}#4} +\gdef\lst@fmtCDef#1{\lst@fmtCDef@#1} +\gdef\lst@fmtCDef@#1#2#3#4#5#6#7{% + \lst@CDefIt#1{#2}{#3}% + {\lst@fmtIfNextCharIn{#5}{#4#2#3}{#6#4#2#3#7}}% + #4% + {}{}{}} +\gdef\lst@fmtCDefX#1{\lst@fmtCDefX@#1} +\gdef\lst@fmtCDefX@#1#2#3#4#5#6#7{% + \let#4#1% + \ifx\@empty#2\@empty + \def#1{\lst@fmtIfNextCharIn{#5}{#4}{#6#7}}% + \else \ifx\@empty#3\@empty + \def#1##1{% + \ifx##1#2% + \def\lst@next{\lst@fmtIfNextCharIn{#5}{#4##1}% + {#6#7}}% + \else + \def\lst@next{#4##1}% + \fi + \lst@next}% + \else + \def#1{% + \lst@IfNextCharsArg{#2#3}% + {\lst@fmtIfNextCharIn{#5}{\expandafter#4\lst@eaten}% + {#6#7}}% + {\expandafter#4\lst@eaten}}% + \fi \fi} +\gdef\lst@UseFormat#1{% + \def\lst@fmtwhole{#1}% + \lst@UseFormat@} +\gdef\lst@UseFormat@{% + \lst@fmtSplit\lst@fmtwhole,% + \let\lst@fmtwhole\lst@fmtb + \ifx\lst@fmta\@empty\else + \lst@fmtSplit\lst@fmta=% + \ifx\@empty\lst@fmta\else + \expandafter\lstKV@XOptArg\expandafter[\expandafter]% + \expandafter{\lst@fmtb}\lst@UseFormat@b + \fi + \fi + \ifx\lst@fmtwhole\@empty\else + \expandafter\lst@UseFormat@ + \fi} +\gdef\lst@UseFormat@b[#1]#2{% + \def\lst@fmtc{{#1}}\lst@lExtend\lst@fmtc{\expandafter{\lst@fmta}}% + \def\lst@fmtb{#2}% + \lst@fmtSplit\lst@fmtb\string + \ifx\@empty\lst@fmta + \lst@lAddTo\lst@fmtc{{}}% + \else + \lst@lExtend\lst@fmtc{\expandafter + {\expandafter\lst@fmtPre\expandafter{\lst@fmta}}}% + \fi + \ifx\@empty\lst@fmtb + \lst@lAddTo\lst@fmtc{{}}% + \else + \lst@lExtend\lst@fmtc{\expandafter + {\expandafter\lst@fmtPost\expandafter{\lst@fmtb}}}% + \fi + \expandafter\lst@UseFormat@c\lst@fmtc} +\gdef\lst@UseFormat@c#1#2#3#4{% + \lst@fmtIfIdentifier#2\relax + {\lst@fmtIdentifier{#2}% + \lst@if\else \PackageWarning{Listings}% + {Cannot drop identifier in format definition}% + \fi}% + {\lst@if + \lst@lAddTo\lst@fmtformat{\lst@CArgX#2\relax\lst@fmtCDef}% + \else + \lst@lAddTo\lst@fmtformat{\lst@CArgX#2\relax\lst@fmtCDefX}% + \fi + \lst@DefActive\lst@fmtc{#1}% + \lst@lExtend\lst@fmtformat{\expandafter{\lst@fmtc}{#3}{#4}}}} +\lst@AddToHook{SelectCharTable}{\lst@fmtformat} +\global\let\lst@fmtformat\@empty +\gdef\lst@fmtPre#1{% + \lst@PrintToken + \begingroup + \let\newline\lst@fmtEnsureNewLine + \let\space\lst@fmtEnsureSpace + \let\indent\lst@fmtIndent + \let\noindent\lst@fmtNoindent + #1% + \endgroup} +\gdef\lst@fmtPost#1{% + \global\let\lst@fmtPostOutput\@empty + \begingroup + \def\newline{\lst@AddTo\lst@fmtPostOutput\lst@fmtEnsureNewLine}% + \def\space{\aftergroup\lst@fmtEnsurePostSpace}% + \def\indent{\lst@AddTo\lst@fmtPostOutput\lst@fmtIndent}% + \def\noindent{\lst@AddTo\lst@fmtPostOutput\lst@fmtNoindent}% + \aftergroup\lst@PrintToken + #1% + \endgroup} +\lst@AddToHook{Init}{\global\let\lst@fmtPostOutput\@empty} +\lst@AddToHook{PostOutput} + {\lst@fmtPostOutput \global\let\lst@fmtPostOutput\@empty} +\gdef\lst@fmtEnsureSpace{% + \lst@ifwhitespace\else \expandafter\lst@ProcessSpace \fi} +\gdef\lst@fmtEnsurePostSpace{% + \lst@IfNextCharWhitespace{}{\lst@ProcessSpace}} +\lst@Key{fmtindent}{20pt}{\def\lst@fmtindent{#1}} +\newdimen\lst@fmtcurrindent +\lst@AddToHook{InitVars}{\global\lst@fmtcurrindent\z@} +\gdef\lst@fmtIndent{\global\advance\lst@fmtcurrindent\lst@fmtindent} +\gdef\lst@fmtNoindent{\global\advance\lst@fmtcurrindent-\lst@fmtindent} +\gdef\lst@fmtEnsureNewLine{% + \global\advance\lst@newlines\@ne + \global\advance\lst@newlinesensured\@ne + \lst@fmtignoretrue} +\lst@AddToAtTop\lst@DoNewLines{% + \ifnum\lst@newlines>\lst@newlinesensured + \global\advance\lst@newlines-\lst@newlinesensured + \fi + \global\lst@newlinesensured\z@} +\newcount\lst@newlinesensured % global +\lst@AddToHook{Init}{\global\lst@newlinesensured\z@} +\gdef\lst@fmtignoretrue{\let\lst@fmtifignore\iftrue} +\gdef\lst@fmtignorefalse{\let\lst@fmtifignore\iffalse} +\lst@AddToHook{InitVars}{\lst@fmtignorefalse} +\lst@AddToHook{Output}{\lst@fmtignorefalse} +\gdef\lst@fmtUseLostSpace{% + \lst@ifnewline \kern\lst@fmtcurrindent \global\lst@lostspace\z@ + \else + \lst@OldOLS + \fi} +\lst@AddToHook{Init} + {\lst@true + \ifx\lst@fmtformat\@empty \ifx\lst@fmt\@empty \lst@false \fi\fi + \lst@if + \let\lst@OldOLS\lst@OutputLostSpace + \let\lst@OutputLostSpace\lst@fmtUseLostSpace + \let\lst@ProcessSpace\lst@fmtProcessSpace + \fi} +\gdef\lst@fmtProcessSpace{% + \lst@ifletter + \lst@Output + \lst@fmtifignore\else + \lst@AppendOther\lst@outputspace + \fi + \else \lst@ifkeepspaces + \lst@AppendOther\lst@outputspace + \else \ifnum\lst@newlines=\z@ + \lst@AppendSpecialSpace + \else \ifnum\lst@length=\z@ + \global\advance\lst@lostspace\lst@width + \global\advance\lst@pos\m@ne + \else + \lst@AppendSpecialSpace + \fi + \fi \fi \fi + \lst@whitespacetrue} +\lst@InstallTest{f} + \lst@fmt@list\lst@fmt \lst@gfmt@list\lst@gfmt + \lst@gfmt@wp + wd +\gdef\lst@fmt@list{\lst@fmt\lst@gfmt}\global\let\lst@fmt\@empty +\gdef\lst@gfmt@list{\lst@fmt\lst@gfmt}\global\let\lst@gfmt\@empty +\gdef\lst@gfmt@wp{% + \begingroup \let\lst@UM\@empty + \let\lst@PrintToken\@empty + \csname\lst@ @fmt$\the\lst@token\endcsname + \endgroup} +\gdef\lst@fmtIdentifier#1#2#3#4{% + \lst@DefOther\lst@fmta{#2}\edef\lst@fmt{\lst@fmt,\lst@fmta}% + \@namedef{\lst@ @fmt$\lst@fmta}{#3#4}} +\lst@EndAspect +\lst@BeginAspect{labels} +\lst@Key{numbers}{none}{% + \let\lst@PlaceNumber\@empty + \lstKV@SwitchCases{#1}% + {none&\\% + left&\def\lst@PlaceNumber{\llap{\normalfont + \lst@numberstyle{\thelstnumber}\kern\lst@numbersep}}\\% + right&\def\lst@PlaceNumber{\rlap{\normalfont + \kern\linewidth \kern\lst@numbersep + \lst@numberstyle{\thelstnumber}}}% + }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}} +\lst@Key{numberstyle}{}{\def\lst@numberstyle{#1}} +\lst@Key{numbersep}{10pt}{\def\lst@numbersep{#1}} +\lst@Key{stepnumber}{1}{\def\lst@stepnumber{#1\relax}} +\lst@AddToHook{EmptyStyle}{\let\lst@stepnumber\@ne} +\lst@Key{numberblanklines}{true}[t] + {\lstKV@SetIf{#1}\lst@ifnumberblanklines} +\lst@Key{firstnumber}{auto}{% + \lstKV@SwitchCases{#1}% + {auto&\let\lst@firstnumber\@undefined\\% + last&\let\lst@firstnumber\c@lstnumber + }{\def\lst@firstnumber{#1\relax}}} +\lst@AddToHook{PreSet}{\let\lst@advancenumber\z@} +\lst@AddToHook{PreInit} + {\ifx\lst@firstnumber\@undefined + \let\lst@firstnumber\lst@firstline + \fi} +\gdef\lst@SetFirstNumber{% + \ifx\lst@firstnumber\@undefined + \@tempcnta 0\csname\@lst no@\lst@intname\endcsname\relax + \ifnum\@tempcnta=\z@ \@tempcnta\lst@firstline + \else \lst@nololtrue \fi + \advance\@tempcnta\lst@advancenumber + \edef\lst@firstnumber{\the\@tempcnta\relax}% + \fi} +\gdef\lst@SaveFirstNumber{% + \expandafter\xdef + \csname\@lst no\ifx\lst@intname\@empty @ \else @\lst@intname\fi + \endcsname{\the\c@lstnumber}} +\newcounter{lstnumber}% \global +\global\c@lstnumber\@ne % init +\renewcommand*\thelstnumber{\@arabic\c@lstnumber} +\lst@AddToHook{EveryPar} + {\global\advance\c@lstnumber\lst@advancelstnum + \global\advance\c@lstnumber\m@ne \refstepcounter{lstnumber}% + \lst@SkipOrPrintLabel}% +\global\let\lst@advancelstnum\@ne +\lst@AddToHook{Init}{\def\@currentlabel{\thelstnumber}} +\lst@AddToHook{InitVars} + {\global\c@lstnumber\lst@firstnumber + \global\advance\c@lstnumber\lst@advancenumber + \global\advance\c@lstnumber-\lst@advancelstnum + \ifx \lst@firstnumber\c@lstnumber + \global\advance\c@lstnumber-\lst@advancelstnum + \fi} +\lst@AddToHook{ExitVars} + {\global\advance\c@lstnumber\lst@advancelstnum} +\AtBeginDocument{% + \def\theHlstnumber{\ifx\lst@@caption\@empty \lst@neglisting + \else \thelstlisting \fi + .\thelstnumber}} +\newcount\lst@skipnumbers % \global +\lst@AddToHook{Init} + {\ifnum \z@>\lst@stepnumber + \let\lst@advancelstnum\m@ne + \edef\lst@stepnumber{-\lst@stepnumber}% + \fi + \ifnum \z@<\lst@stepnumber + \global\lst@skipnumbers\lst@firstnumber + \global\divide\lst@skipnumbers\lst@stepnumber + \global\multiply\lst@skipnumbers-\lst@stepnumber + \global\advance\lst@skipnumbers\lst@firstnumber + \ifnum\lst@skipnumbers>\z@ + \global\advance\lst@skipnumbers -\lst@stepnumber + \fi + \else + \let\lst@SkipOrPrintLabel\relax + \fi} +\gdef\lst@SkipOrPrintLabel{% + \ifnum\lst@skipnumbers=\z@ + \global\advance\lst@skipnumbers-\lst@stepnumber\relax + \lst@PlaceNumber + \fi + \global\advance\lst@skipnumbers\@ne} +\lst@AddToHook{OnEmptyLine}{% + \lst@ifnumberblanklines\else \ifnum\lst@skipnumbers=\z@ + \global\advance\lst@skipnumbers-\lst@stepnumber\relax + \fi\fi} +\lst@EndAspect +\lst@BeginAspect{lineshape} +\lst@Key{xleftmargin}{\z@}{\def\lst@xleftmargin{#1}} +\lst@Key{xrightmargin}{\z@}{\def\lst@xrightmargin{#1}} +\lst@Key{resetmargins}{false}[t]{\lstKV@SetIf{#1}\lst@ifresetmargins} +\lst@AddToHook{BoxUnsafe}{\let\lst@xleftmargin\z@ + \let\lst@xrightmargin\z@} +\lst@AddToHook{TextStyle}{% + \let\lst@xleftmargin\z@ \let\lst@xrightmargin\z@ + \let\lst@ifresetmargins\iftrue} +\lst@Key{linewidth}\linewidth{\def\lst@linewidth{#1}} +\lst@AddToHook{PreInit}{\linewidth\lst@linewidth\relax} +\gdef\lst@parshape{% + \parshape\@ne \@totalleftmargin \linewidth} +\lst@AddToHook{Init} + {\lst@ifresetmargins + \advance\linewidth\@totalleftmargin + \advance\linewidth\rightmargin + \@totalleftmargin\z@ + \fi + \advance\linewidth-\lst@xleftmargin + \advance\linewidth-\lst@xrightmargin + \advance\@totalleftmargin\lst@xleftmargin\relax} +\lst@Key{lineskip}{\z@}{\def\lst@lineskip{#1\relax}} +\lst@AddToHook{Init} + {\parskip\z@ + \ifdim\z@=\lst@lineskip\else + \@tempdima\baselineskip + \advance\@tempdima\lst@lineskip + \divide\@tempdima\strip@pt\baselineskip\relax + \edef\baselinestretch{\strip@pt\@tempdima}% + \selectfont + \fi} +\lst@Key{breaklines}{false}[t]{\lstKV@SetIf{#1}\lst@ifbreaklines} +\lst@Key{breakindent}{20pt}{\def\lst@breakindent{#1}} +\lst@Key{breakautoindent}{t}[t]{\lstKV@SetIf{#1}\lst@ifbreakautoindent} +\lst@Key{prebreak}{}{\def\lst@prebreak{#1}} +\lst@Key{postbreak}{}{\def\lst@postbreak{#1}} +\lst@AddToHook{Init} + {\lst@ifbreaklines + \hbadness\@M \pretolerance\@M + \def\lst@parshape{\parshape\tw@ \@totalleftmargin\linewidth + \lst@breakshape}% + \else + \let\lst@discretionary\@empty + \fi} +\lst@AddToHook{OnNewLine} + {\lst@ifbreaklines \lst@breakNewLine \fi} +\gdef\lst@discretionary{% + \discretionary{\let\space\lst@spacekern\lst@prebreak}% + {\llap{\lsthk@EveryLine \kern\lst@breakcurrindent}% + \let\space\lst@spacekern\lst@postbreak}{}} +\lst@AddToHook{PostOutput}{\lst@discretionary} +\gdef\lst@spacekern{\kern\lst@width} +\gdef\lst@breakNewLine{% + \@tempdima\lst@breakindent\relax + \lst@ifbreakautoindent \advance\@tempdima\lst@lostspace \fi + \@tempdimc-\@tempdima \advance\@tempdimc\linewidth + \advance\@tempdima\@totalleftmargin + \xdef\lst@breakshape{\noexpand\lst@breakcurrindent \the\@tempdimc}% + \xdef\lst@breakcurrindent{\the\@tempdima}} +\gdef\lst@breakshape{\@totalleftmargin \linewidth} +\gdef\lst@breakProcessOther#1{\lst@ProcessOther#1\lst@OutputOther} +\lst@AddToHook{SelectCharTable} + {\lst@ifbreaklines \lst@Def{`)}{\lst@breakProcessOther)}\fi} +\lst@EndAspect +\lst@BeginAspect[lineshape]{frames} +\lst@Key{framexleftmargin}{\z@}{\def\lst@framexleftmargin{#1}} +\lst@Key{framexrightmargin}{\z@}{\def\lst@framexrightmargin{#1}} +\lst@Key{framextopmargin}{\z@}{\def\lst@framextopmargin{#1}} +\lst@Key{framexbottommargin}{\z@}{\def\lst@framexbottommargin{#1}} +\lst@Key{backgroundcolor}{}{\def\lst@bkgcolor{#1}} +\lst@Key{fillcolor}{}{\def\lst@fillcolor{#1}} +\lst@Key{rulecolor}{}{\def\lst@rulecolor{#1}} +\lst@Key{rulesepcolor}{}{\def\lst@rulesepcolor{#1}} +\lst@AddToHook{Init}{% + \ifx\lst@fillcolor\@empty + \let\lst@fillcolor\lst@bkgcolor + \fi + \ifx\lst@rulesepcolor\@empty + \let\lst@rulesepcolor\lst@fillcolor + \fi} +\lst@Key{rulesep}{2pt}{\def\lst@rulesep{#1}} +\lst@Key{framerule}{.4pt}{\def\lst@framerulewidth{#1}} +\lst@Key{framesep}{3pt}{\def\lst@frametextsep{#1}} +\lst@Key{frameshape}{}{% + \let\lst@xrulecolor\@empty + \lstKV@FourArg{#1}% + {\uppercase{\def\lst@frametshape{##1}}% + \uppercase{\def\lst@framelshape{##2}}% + \uppercase{\def\lst@framershape{##3}}% + \uppercase{\def\lst@framebshape{##4}}% + \let\lst@ifframeround\iffalse + \lst@IfSubstring R\lst@frametshape{\let\lst@ifframeround\iftrue}{}% + \lst@IfSubstring R\lst@framebshape{\let\lst@ifframeround\iftrue}{}% + \def\lst@frame{##1##2##3##4}}} +\lst@Key{frameround}\relax + {\uppercase{\def\lst@frameround{#1}}% + \expandafter\lstframe@\lst@frameround ffff\relax} +\global\let\lst@frameround\@empty +\lst@Key{frame}\relax{% + \let\lst@xrulecolor\@empty + \lstKV@SwitchCases{#1}% + {none&\let\lst@frame\@empty\\% + leftline&\def\lst@frame{l}\\% + topline&\def\lst@frame{t}\\% + bottomline&\def\lst@frame{b}\\% + lines&\def\lst@frame{tb}\\% + single&\def\lst@frame{trbl}\\% + shadowbox&\def\lst@frame{tRBl}% + \def\lst@xrulecolor{\lst@rulesepcolor}% + \def\lst@rulesep{\lst@frametextsep}% + }{\def\lst@frame{#1}}% + \expandafter\lstframe@\lst@frameround ffff\relax} +\gdef\lstframe@#1#2#3#4#5\relax{% + \lst@IfSubstring T\lst@frame{\edef\lst@frame{t\lst@frame}}{}% + \lst@IfSubstring R\lst@frame{\edef\lst@frame{r\lst@frame}}{}% + \lst@IfSubstring B\lst@frame{\edef\lst@frame{b\lst@frame}}{}% + \lst@IfSubstring L\lst@frame{\edef\lst@frame{l\lst@frame}}{}% + \let\lst@frametshape\@empty \let\lst@framebshape\@empty + \lst@frameCheck + ltr\lst@framelshape\lst@frametshape\lst@framershape #4#1% + \lst@frameCheck + LTR\lst@framelshape\lst@frametshape\lst@framershape #4#1% + \lst@frameCheck + lbr\lst@framelshape\lst@framebshape\lst@framershape #3#2% + \lst@frameCheck + LBR\lst@framelshape\lst@framebshape\lst@framershape #3#2% + \let\lst@ifframeround\iffalse + \lst@IfSubstring R\lst@frametshape{\let\lst@ifframeround\iftrue}{}% + \lst@IfSubstring R\lst@framebshape{\let\lst@ifframeround\iftrue}{}% + \let\lst@framelshape\@empty \let\lst@framershape\@empty + \lst@IfSubstring L\lst@frame + {\def\lst@framelshape{YY}}% + {\lst@IfSubstring l\lst@frame{\def\lst@framelshape{Y}}{}}% + \lst@IfSubstring R\lst@frame + {\def\lst@framershape{YY}}% + {\lst@IfSubstring r\lst@frame{\def\lst@framershape{Y}}{}}} +\gdef\lst@frameCheck#1#2#3#4#5#6#7#8{% + \lst@IfSubstring #1\lst@frame + {\if #7T\def#4{R}\else \def#4{Y}\fi}% + {\def#4{N}}% + \lst@IfSubstring #3\lst@frame + {\if #8T\def#6{R}\else \def#6{Y}\fi}% + {\def#6{N}}% + \lst@IfSubstring #2\lst@frame{\edef#5{#5#4Y#6}}{}} +\gdef\lst@frameMakeBoxV#1#2#3{% + \setbox#1\hbox{% + \color@begingroup \lst@rulecolor + \llap{\setbox\z@\hbox{\vrule\@width\z@\@height#2\@depth#3% + \lst@frameL}% + \rlap{\lst@frameBlock\lst@rulesepcolor{\wd\z@}% + {\ht\z@}{\dp\z@}}% + \box\z@ + \ifx\lst@framelshape\@empty + \kern\lst@frametextsep\relax + \else + \lst@frameBlock\lst@fillcolor\lst@frametextsep{#2}{#3}% + \fi + \kern\lst@framexleftmargin}% + \rlap{\kern-\lst@framexleftmargin + \@tempdima\linewidth + \advance\@tempdima\lst@framexleftmargin + \advance\@tempdima\lst@framexrightmargin + \lst@frameBlock\lst@bkgcolor\@tempdima{#2}{#3}% + \ifx\lst@framershape\@empty + \kern\lst@frametextsep\relax + \else + \lst@frameBlock\lst@fillcolor\lst@frametextsep{#2}{#3}% + \fi + \setbox\z@\hbox{\vrule\@width\z@\@height#2\@depth#3% + \lst@frameR}% + \rlap{\lst@frameBlock\lst@rulesepcolor{\wd\z@}% + {\ht\z@}{\dp\z@}}% + \box\z@}% + \color@endgroup}} +\gdef\lst@frameBlock#1#2#3#4{% + \color@begingroup + #1% + \setbox\z@\hbox{\vrule\@height#3\@depth#4% + \ifx#1\@empty \@width\z@ \kern#2\relax + \else \@width#2\relax \fi}% + \box\z@ + \color@endgroup} +\gdef\lst@frameR{% + \expandafter\lst@frameR@\lst@framershape\relax + \kern-\lst@rulesep} +\gdef\lst@frameR@#1{% + \ifx\relax#1\@empty\else + \if #1Y\lst@framevrule \else \kern\lst@framerulewidth \fi + \kern\lst@rulesep + \expandafter\lst@frameR@b + \fi} +\gdef\lst@frameR@b#1{% + \ifx\relax#1\@empty + \else + \if #1Y\color@begingroup + \lst@xrulecolor + \lst@framevrule + \color@endgroup + \else + \kern\lst@framerulewidth + \fi + \kern\lst@rulesep + \expandafter\lst@frameR@ + \fi} +\gdef\lst@frameL{% + \kern-\lst@rulesep + \expandafter\lst@frameL@\lst@framelshape\relax} +\gdef\lst@frameL@#1{% + \ifx\relax#1\@empty\else + \kern\lst@rulesep + \if#1Y\lst@framevrule \else \kern\lst@framerulewidth \fi + \expandafter\lst@frameL@ + \fi} +\gdef\lst@frameH#1#2{% + \global\let\lst@framediml\z@ \global\let\lst@framedimr\z@ + \setbox\z@\hbox{}\@tempcntb\z@ + \expandafter\lst@frameH@\expandafter#1#2\relax\relax\relax + \@tempdimb\lst@frametextsep\relax + \advance\@tempdimb\lst@framerulewidth\relax + \@tempdimc-\@tempdimb + \advance\@tempdimc\ht\z@ + \advance\@tempdimc\dp\z@ + \setbox\z@=\hbox{% + \lst@frameHBkg\lst@fillcolor\@tempdimb\@firstoftwo + \if#1T\rlap{\raise\dp\@tempboxa\box\@tempboxa}% + \else\rlap{\lower\ht\@tempboxa\box\@tempboxa}\fi + \lst@frameHBkg\lst@rulesepcolor\@tempdimc\@secondoftwo + \advance\@tempdimb\ht\@tempboxa + \if#1T\rlap{\raise\lst@frametextsep\box\@tempboxa}% + \else\rlap{\lower\@tempdimb\box\@tempboxa}\fi + \rlap{\box\z@}% + }} +\gdef\lst@frameH@#1#2#3#4{% + \ifx\relax#4\@empty\else + \lst@frameh \@tempcntb#1#2#3#4% + \advance\@tempcntb\@ne + \expandafter\lst@frameH@\expandafter#1% + \fi} +\gdef\lst@frameHBkg#1#2#3{% + \setbox\@tempboxa\hbox{% + \kern-\lst@framexleftmargin + #3{\kern-\lst@framediml\relax}{\@tempdima\z@}% + \ifdim\lst@framediml>\@tempdimb + #3{\@tempdima\lst@framediml \advance\@tempdima-\@tempdimb + \lst@frameBlock\lst@rulesepcolor\@tempdima\@tempdimb\z@}% + {\kern-\lst@framediml + \advance\@tempdima\lst@framediml\relax}% + \fi + #3{\@tempdima\z@ + \ifx\lst@framelshape\@empty\else + \advance\@tempdima\@tempdimb + \fi + \ifx\lst@framershape\@empty\else + \advance\@tempdima\@tempdimb + \fi}% + {\ifdim\lst@framedimr>\@tempdimb + \advance\@tempdima\lst@framedimr\relax + \fi}% + \advance\@tempdima\linewidth + \advance\@tempdima\lst@framexleftmargin + \advance\@tempdima\lst@framexrightmargin + \lst@frameBlock#1\@tempdima#2\z@ + #3{\ifdim\lst@framedimr>\@tempdimb + \@tempdima-\@tempdimb + \advance\@tempdima\lst@framedimr\relax + \lst@frameBlock\lst@rulesepcolor\@tempdima\@tempdimb\z@ + \fi}{}% + }} +\gdef\lst@frameh#1#2#3#4#5{% + \lst@frameCalcDimA#1% + \lst@ifframeround \@getcirc\@tempdima \fi + \setbox\z@\hbox{% + \begingroup + \setbox\z@\hbox{% + \kern-\lst@framexleftmargin + \color@begingroup + \ifnum#1=\z@ \lst@rulecolor \else \lst@xrulecolor \fi + \lst@frameCornerX\llap{#2L}#3#1% + \ifdim\lst@framediml<\@tempdimb + \xdef\lst@framediml{\the\@tempdimb}% + \fi + \begingroup + \if#4Y\else \let\lst@framerulewidth\z@ \fi + \@tempdima\lst@framexleftmargin + \advance\@tempdima\lst@framexrightmargin + \advance\@tempdima\linewidth + \vrule\@width\@tempdima\@height\lst@framerulewidth \@depth\z@ + \endgroup + \lst@frameCornerX\rlap{#2R}#5#1% + \ifdim\lst@framedimr<\@tempdimb + \xdef\lst@framedimr{\the\@tempdimb}% + \fi + \color@endgroup}% + \if#2T\rlap{\raise\dp\z@\box\z@}% + \else\rlap{\lower\ht\z@\box\z@}\fi + \endgroup + \box\z@}} +\gdef\lst@frameCornerX#1#2#3#4{% + \setbox\@tempboxa\hbox{\csname\@lst @frame\if#3RR\fi #2\endcsname}% + \@tempdimb\wd\@tempboxa + \if #3R% + #1{\box\@tempboxa}% + \else + \if #3Y\expandafter#1\else + \@tempdimb\z@ \expandafter\vphantom \fi + {\box\@tempboxa}% + \fi} +\gdef\lst@frameCalcDimA#1{% + \@tempdima\lst@rulesep + \advance\@tempdima\lst@framerulewidth + \multiply\@tempdima#1\relax + \advance\@tempdima\lst@frametextsep + \advance\@tempdima\lst@framerulewidth + \multiply\@tempdima\tw@} +\lst@AddToHook{Init}{\lst@frameInit} +\newbox\lst@framebox +\gdef\lst@frameInit{% + \ifx\lst@framelshape\@empty \let\lst@frameL\@empty \fi + \ifx\lst@framershape\@empty \let\lst@frameR\@empty \fi + \def\lst@framevrule{\vrule\@width\lst@framerulewidth\relax}% + \lst@ifframeround + \lst@frameCalcDimA\z@ \@getcirc\@tempdima + \@tempdimb\@tempdima \divide\@tempdimb\tw@ + \advance\@tempdimb -\@wholewidth + \edef\lst@frametextsep{\the\@tempdimb}% + \edef\lst@framerulewidth{\the\@wholewidth}% + \lst@frameCalcDimA\@ne \@getcirc\@tempdima + \@tempdimb\@tempdima \divide\@tempdimb\tw@ + \advance\@tempdimb -\tw@\@wholewidth + \advance\@tempdimb -\lst@frametextsep + \edef\lst@rulesep{\the\@tempdimb}% + \fi + \lst@frameMakeBoxV\lst@framebox{\ht\strutbox}{\dp\strutbox}% + \def\lst@framelr{\copy\lst@framebox}% + \ifx\lst@frametshape\@empty\else + \lst@frameH T\lst@frametshape + \ifvoid\z@\else + \par\lst@parshape + \@tempdima-\baselineskip \advance\@tempdima\ht\z@ + \ifdim\prevdepth<\@cclvi\p@\else + \advance\@tempdima\prevdepth + \fi + \ifdim\@tempdima<\z@ + \vskip\@tempdima\vskip\lineskip + \fi + \noindent\box\z@\par + \lineskiplimit\maxdimen \lineskip\z@ + \fi + \lst@frameSpreadV\lst@framextopmargin + \fi} +\lst@AddToHook{EveryLine}{\lst@framelr} +\global\let\lst@framelr\@empty +\lst@AddToHook{DeInit} + {\ifx\lst@framebshape\@empty\else \lst@frameExit \fi} +\gdef\lst@frameExit{% + \lst@frameSpreadV\lst@framexbottommargin + \lst@frameH B\lst@framebshape + \ifvoid\z@\else + \everypar{}\par\lst@parshape\nointerlineskip\noindent\box\z@ + \fi} +\gdef\lst@frameSpreadV#1{% + \ifdim\z@=#1\else + \everypar{}\par\lst@parshape\nointerlineskip\noindent + \lst@frameMakeBoxV\z@{#1}{\z@}% + \box\z@ + \fi} +\gdef\lst@frameTR{% + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@ + \kern-\lst@framerulewidth + \raise\lst@framerulewidth\hbox{% + \vrule\@width\lst@framerulewidth\@height\z@\@depth.5\@tempdima}} +\gdef\lst@frameBR{% + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@ + \kern-\lst@framerulewidth + \vrule\@width\lst@framerulewidth\@height.5\@tempdima\@depth\z@} +\gdef\lst@frameBL{% + \vrule\@width\lst@framerulewidth\@height.5\@tempdima\@depth\z@ + \kern-\lst@framerulewidth + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@} +\gdef\lst@frameTL{% + \raise\lst@framerulewidth\hbox{% + \vrule\@width\lst@framerulewidth\@height\z@\@depth.5\@tempdima}% + \kern-\lst@framerulewidth + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@} +\gdef\lst@frameRoundT{% + \setbox\@tempboxa\hbox{\@circlefnt\char\@tempcnta}% + \ht\@tempboxa\lst@framerulewidth + \box\@tempboxa} +\gdef\lst@frameRoundB{% + \setbox\@tempboxa\hbox{\@circlefnt\char\@tempcnta}% + \dp\@tempboxa\z@ + \box\@tempboxa} +\gdef\lst@frameRTR{% + \hb@xt@.5\@tempdima{\kern-\lst@framerulewidth + \kern.5\@tempdima \lst@frameRoundT \hss}} +\gdef\lst@frameRBR{% + \hb@xt@.5\@tempdima{\kern-\lst@framerulewidth + \advance\@tempcnta\@ne \kern.5\@tempdima \lst@frameRoundB \hss}} +\gdef\lst@frameRBL{% + \advance\@tempcnta\tw@ \lst@frameRoundB + \kern-.5\@tempdima} +\gdef\lst@frameRTL{% + \advance\@tempcnta\thr@@\lst@frameRoundT + \kern-.5\@tempdima} +\lst@EndAspect +\lst@BeginAspect[keywords]{make} +\lst@NewMode\lst@makemode +\lst@AddToHook{Output}{% + \ifnum\lst@mode=\lst@makemode + \ifx\lst@thestyle\lst@gkeywords@sty + \lst@makekeytrue + \fi + \fi} +\gdef\lst@makekeytrue{\let\lst@ifmakekey\iftrue} +\gdef\lst@makekeyfalse{\let\lst@ifmakekey\iffalse} +\global\lst@makekeyfalse % init +\lst@Key{makemacrouse}f[t]{\lstKV@SetIf{#1}\lst@ifmakemacrouse} +\gdef\lst@MakeSCT{% + \lst@ifmakemacrouse + \lst@ReplaceInput{$(}{% + \lst@PrintToken + \lst@EnterMode\lst@makemode{\lst@makekeyfalse}% + \lst@Merge{\lst@ProcessOther\$\lst@ProcessOther(}}% + \lst@ReplaceInput{)}{% + \ifnum\lst@mode=\lst@makemode + \lst@PrintToken + \begingroup + \lst@ProcessOther)% + \lst@ifmakekey + \let\lst@currstyle\lst@gkeywords@sty + \fi + \lst@OutputOther + \endgroup + \lst@LeaveMode + \else + \expandafter\lst@ProcessOther\expandafter)% + \fi}% + \else + \lst@ReplaceInput{$(}{\lst@ProcessOther\$\lst@ProcessOther(}% + \fi} +\lst@EndAspect +\lst@BeginAspect{0.21} +\lst@Key{labelstyle}{}{\def\lst@numberstyle{#1}} +\lst@Key{labelsep}{10pt}{\def\lst@numbersep{#1}} +\lst@Key{labelstep}{0}{% + \ifnum #1=\z@ \KV@lst@numbers{none}% + \else \KV@lst@numbers{left}\fi + \def\lst@stepnumber{#1\relax}} +\lst@Key{firstlabel}\relax{\def\lst@firstnumber{#1\relax}} +\lst@Key{advancelabel}\relax{\def\lst@advancenumber{#1\relax}} +\let\c@lstlabel\c@lstnumber +\lst@AddToHook{Init}{\let\thelstnumber\thelstlabel} +\newcommand*\thelstlabel{\@arabic\c@lstlabel} +\lst@Key{first}\relax{\def\lst@firstline{#1\relax}} +\lst@Key{last}\relax{\def\lst@lastline{#1\relax}} +\lst@Key{framerulewidth}{.4pt}{\def\lst@framerulewidth{#1}} +\lst@Key{framerulesep}{2pt}{\def\lst@rulesep{#1}} +\lst@Key{frametextsep}{3pt}{\def\lst@frametextsep{#1}} +\lst@Key{framerulecolor}{}{\lstKV@OptArg[]{#1}% + {\ifx\@empty##2\@empty + \let\lst@rulecolor\@empty + \else + \ifx\@empty##1\@empty + \def\lst@rulecolor{\color{##2}}% + \else + \def\lst@rulecolor{\color[##1]{##2}}% + \fi + \fi}} +\lst@Key{backgroundcolor}{}{\lstKV@OptArg[]{#1}% + {\ifx\@empty##2\@empty + \let\lst@bkgcolor\@empty + \else + \ifx\@empty##1\@empty + \def\lst@bkgcolor{\color{##2}}% + \else + \def\lst@bkgcolor{\color[##1]{##2}}% + \fi + \fi}} +\lst@Key{framespread}{\z@}{\def\lst@framespread{#1}} +\lst@AddToHook{PreInit} + {\@tempdima\lst@framespread\relax \divide\@tempdima\tw@ + \edef\lst@framextopmargin{\the\@tempdima}% + \let\lst@framexrightmargin\lst@framextopmargin + \let\lst@framexbottommargin\lst@framextopmargin + \advance\@tempdima\lst@xleftmargin\relax + \edef\lst@framexleftmargin{\the\@tempdima}} +\newdimen\lst@innerspread \newdimen\lst@outerspread +\lst@Key{spread}{\z@,\z@}{\lstKV@CSTwoArg{#1}% + {\lst@innerspread##1\relax + \ifx\@empty##2\@empty + \divide\lst@innerspread\tw@\relax + \lst@outerspread\lst@innerspread + \else + \lst@outerspread##2\relax + \fi}} +\lst@AddToHook{BoxUnsafe}{\lst@outerspread\z@ \lst@innerspread\z@} +\lst@Key{wholeline}{false}[t]{\lstKV@SetIf{#1}\lst@ifresetmargins} +\lst@Key{indent}{\z@}{\def\lst@xleftmargin{#1}} +\lst@AddToHook{PreInit} + {\lst@innerspread=-\lst@innerspread + \lst@outerspread=-\lst@outerspread + \ifodd\c@page \advance\lst@innerspread\lst@xleftmargin + \else \advance\lst@outerspread\lst@xleftmargin \fi + \ifodd\c@page + \edef\lst@xleftmargin{\the\lst@innerspread}% + \edef\lst@xrightmargin{\the\lst@outerspread}% + \else + \edef\lst@xleftmargin{\the\lst@outerspread}% + \edef\lst@xrightmargin{\the\lst@innerspread}% + \fi} +\lst@Key{defaultclass}\relax{\def\lst@classoffset{#1}} +\lst@Key{stringtest}\relax{}% dummy +\lst@Key{outputpos}\relax{\lst@outputpos#1\relax\relax} +\lst@Key{stringspaces}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowstringspaces} +\lst@Key{visisblespaces}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowspaces} +\lst@Key{visibletabs}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowtabs} +\lst@EndAspect +\lst@BeginAspect{fancyvrb} +\@ifundefined{FancyVerbFormatLine} + {\typeout{^^J% + ***^^J% + *** `listings.sty' needs `fancyvrb.sty' right now.^^J% + *** Please ensure its availability and try again.^^J% + ***^^J}% + \batchmode \@@end}{} +\gdef\lstFV@fancyvrb{% + \lst@iffancyvrb + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine\else + \let\lstFV@FVFL\FancyVerbFormatLine + \let\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \fi + \else + \ifx\lstFV@FVFL\@undefined\else + \let\FancyVerbFormatLine\lstFV@FVFL + \let\lstFV@FVFL\@undefined + \fi + \fi} +\gdef\lstFV@VerbatimBegin{% + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \lsthk@TextStyle \lsthk@BoxUnsafe + \lsthk@PreSet + \lst@activecharsfalse + \let\normalbaselines\relax + \lst@Init\relax + \lst@ifresetmargins \advance\linewidth-\@totalleftmargin \fi + \everypar{}\global\lst@newlines\z@ + \lst@mode\lst@nomode \let\lst@entermodes\@empty + \lst@InterruptModes +%% D.G. modification begin - Nov. 25, 1998 + \let\@noligs\relax +%% D.G. modification end + \fi} +\gdef\lstFV@VerbatimEnd{% + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \global\setbox\lstFV@gtempboxa\box\@tempboxa + \global\let\@gtempa\FV@ProcessLine + \lst@mode\lst@Pmode + \lst@DeInit + \let\FV@ProcessLine\@gtempa + \setbox\@tempboxa\box\lstFV@gtempboxa + \fi} +\newbox\lstFV@gtempboxa +\lst@AddTo\FV@VerbatimBegin\lstFV@VerbatimBegin +\lst@AddToAtTop\FV@VerbatimEnd\lstFV@VerbatimEnd +\lst@AddTo\FV@LVerbatimBegin\lstFV@VerbatimBegin +\lst@AddToAtTop\FV@LVerbatimEnd\lstFV@VerbatimEnd +\lst@AddTo\FV@BVerbatimBegin\lstFV@VerbatimBegin +\lst@AddToAtTop\FV@BVerbatimEnd\lstFV@VerbatimEnd +\gdef\lstFV@FancyVerbFormatLine#1{% + \let\lst@arg\@empty \lst@FVConvert#1\@nil + \global\lst@newlines\z@ + \vtop{\leavevmode\lst@parshape + \lst@ReenterModes + \lst@arg \lst@PrintToken\lst@EOLUpdate\lsthk@InitVarsBOL + \lst@InterruptModes}} +\gdef\lst@FVConvert{\futurelet\@let@token\lst@FVConvert@@} +\gdef\lst@FVConvert@@{% + \ifcat\noexpand\@let@token\bgroup \expandafter\lst@FVConvertArg + \else \expandafter\lst@FVConvert@ \fi} +\gdef\lst@FVConvertArg#1{% + {\let\lst@arg\@empty + \lst@FVConvert#1\@nil + \global\let\@gtempa\lst@arg}% + \lst@lExtend\lst@arg{\expandafter{\@gtempa\lst@PrintToken}}% + \lst@FVConvert} +\gdef\lst@FVConvert@#1{% + \ifx \@nil#1\else + \if\relax\noexpand#1% + \lst@lAddTo\lst@arg{\lst@OutputLostSpace\lst@PrintToken#1}% + \else + \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% + \fi + \expandafter\lst@FVConvert + \fi} +\lst@EndAspect +\lst@BeginAspect[keywords,comments,strings,language]{lgrind} +\gdef\lst@LGGetNames#1:#2\relax{% + \lst@NormedDef\lstlang@{#1}\lst@ReplaceInArg\lstlang@{|,}% + \def\lst@arg{:#2}} +\gdef\lst@LGGetValue#1{% + \lst@false + \def\lst@temp##1:#1##2##3\relax{% + \ifx\@empty##2\else \lst@LGGetValue@{#1}\fi} + \expandafter\lst@temp\lst@arg:#1\@empty\relax} +\gdef\lst@LGGetValue@#1{% + \lst@true + \def\lst@temp##1:#1##2:##3\relax{% + \@ifnextchar=\lst@LGGetValue@@{\lst@LGGetValue@@=}##2\relax + \def\lst@arg{##1:##3}}% + \expandafter\lst@temp\lst@arg\relax} +\gdef\lst@LGGetValue@@=#1\relax{\def\lst@LGvalue{#1}} +\gdef\lst@LGGetComment#1#2{% + \let#2\@empty + \lst@LGGetValue{#1b}% + \lst@if + \let#2\lst@LGvalue + \lst@LGGetValue{#1e}% + \ifx\lst@LGvalue\lst@LGEOL + \edef\lstlang@{\lstlang@,commentline={#2}}% + \let#2\@empty + \else + \edef#2{{#2}{\lst@LGvalue}}% + \fi + \fi} +\gdef\lst@LGGetString#1#2{% + \lst@LGGetValue{#1b}% + \lst@if + \let#2\lst@LGvalue + \lst@LGGetValue{#1e}% + \ifx\lst@LGvalue\lst@LGEOL + \edef\lstlang@{\lstlang@,morestringizer=[l]{#2}}% + \else + \ifx #2\lst@LGvalue + \edef\lstlang@{\lstlang@,morestringizer=[d]{#2}}% + \else + \edef\lst@temp{\lst@LGe#2}% + \ifx \lst@temp\lst@LGvalue + \edef\lstlang@{\lstlang@,morestringizer=[b]{#2}}% + \else + \PackageWarning{Listings}% + {String #2...\lst@LGvalue\space not supported}% + \fi + \fi + \fi + \fi} +\gdef\lst@LGDefLang{% + \lst@LGReplace + \let\lstlang@\empty + \lst@LGGetValue{kw}% + \lst@if + \lst@ReplaceInArg\lst@LGvalue{{ },}% + \edef\lstlang@{\lstlang@,keywords={\lst@LGvalue}}% + \fi + \lst@LGGetValue{oc}% + \lst@if + \edef\lstlang@{\lstlang@,sensitive=f}% + \fi + \lst@LGGetValue{id}% + \lst@if + \edef\lstlang@{\lstlang@,alsoletter=\lst@LGvalue}% + \fi + \lst@LGGetComment a\lst@LGa + \lst@LGGetComment c\lst@LGc + \ifx\lst@LGa\@empty + \ifx\lst@LGc\@empty\else + \edef\lstlang@{\lstlang@,singlecomment=\lst@LGc}% + \fi + \else + \ifx\lst@LGc\@empty + \edef\lstlang@{\lstlang@,singlecomment=\lst@LGa}% + \else + \edef\lstlang@{\lstlang@,doublecomment=\lst@LGc\lst@LGa}% + \fi + \fi + \lst@LGGetString s\lst@LGa + \lst@LGGetString l\lst@LGa + \lst@LGGetValue{tc}% + \lst@if + \edef\lstlang@{\lstlang@,lgrindef=\lst@LGvalue}% + \fi + \expandafter\xdef\csname\@lst LGlang@\lst@language@\endcsname + {\noexpand\lstset{\lstlang@}}% + \lst@ReplaceInArg\lst@arg{{: :}:}\let\lst@LGvalue\@empty + \expandafter\lst@LGDroppedCaps\lst@arg\relax\relax + \ifx\lst@LGvalue\@empty\else + \PackageWarningNoLine{Listings}{Ignored capabilities for + \space `\lst@language@' are\MessageBreak\lst@LGvalue}% + \fi} +\gdef\lst@LGDroppedCaps#1:#2#3{% + \ifx#2\relax + \lst@RemoveCommas\lst@LGvalue + \else + \edef\lst@LGvalue{\lst@LGvalue,#2#3}% + \expandafter\lst@LGDroppedCaps + \fi} +\begingroup +\catcode`\/=0 +\lccode`\z=`\:\lccode`\y=`\^\lccode`\x=`\$\lccode`\v=`\| +\catcode`\\=12\relax +/lowercase{% +/gdef/lst@LGReplace{/lst@ReplaceInArg/lst@arg + {{\:}{z }{\^}{y}{\$}{x}{\|}{v}{ \ }{ }{:\ :}{:}{\ }{ }{\(}({\)})}} +/gdef/lst@LGe{\e} +} +/endgroup +\gdef\lst@LGRead#1\par{% + \lst@LGGetNames#1:\relax + \def\lst@temp{endoflanguagedefinitions}% + \ifx\lstlang@\lst@temp + \let\lst@next\endinput + \else + \expandafter\lst@IfOneOf\lst@language@\relax\lstlang@ + {\lst@LGDefLang \let\lst@next\endinput}% + {\let\lst@next\lst@LGRead}% + \fi + \lst@next} +\lst@Key{lgrindef}\relax{% + \lst@NormedDef\lst@language@{#1}% + \begingroup + \@ifundefined{lstLGlang@\lst@language@}% + {\everypar{\lst@LGRead}% + \catcode`\\=12\catcode`\{=12\catcode`\}=12\catcode`\%=12% + \catcode`\#=14\catcode`\$=12\catcode`\^=12\catcode`\_=12\relax + \input{\lstlgrindeffile}% + }{}% + \endgroup + \@ifundefined{lstLGlang@\lst@language@}% + {\PackageError{Listings}% + {LGrind language \lst@language@\space undefined}% + {The language is not loadable. \@ehc}}% + {\lsthk@SetLanguage + \csname\@lst LGlang@\lst@language@\endcsname}} +\@ifundefined{lstlgrindeffile} + {\lst@UserCommand\lstlgrindeffile{lgrindef.}}{} +\lst@EndAspect +\lst@BeginAspect[keywords]{hyper} +\lst@Key{hyperanchor}\hyper@@anchor{\let\lst@hyperanchor#1} +\lst@Key{hyperlink}\hyperlink{\let\lst@hyperlink#1} +\lst@InstallKeywords{h}{hyperref}{}\relax{} + {\begingroup + \let\lst@UM\@empty \xdef\@gtempa{\the\lst@token}% + \endgroup + \lst@GetFreeMacro{lstHR@\@gtempa}% + \global\expandafter\let\lst@freemacro\@empty + \@tempcntb\@tempcnta \advance\@tempcntb\m@ne + \edef\lst@alloverstyle##1{% + \let\noexpand\lst@alloverstyle\noexpand\@empty + \noexpand\smash{\raise\baselineskip\hbox + {\noexpand\lst@hyperanchor{lst.\@gtempa\the\@tempcnta}% + {\relax}}}% + \ifnum\@tempcnta=\z@ ##1\else + \noexpand\lst@hyperlink{lst.\@gtempa\the\@tempcntb}{##1}% + \fi}% + } + od +\lst@EndAspect +\endinput +%% +%% End of file `lstmisc.sty'. diff --git a/doc/user/lstpatch.sty b/doc/user/lstpatch.sty new file mode 100644 index 0000000000..0f05d93e50 --- /dev/null +++ b/doc/user/lstpatch.sty @@ -0,0 +1,464 @@ +%% +%% This is file `lstpatch.sty', generated manually. +%% +%% Please read the software license in listings.dtx or listings.dvi. +%% +%% (w)(c) 2002 Carsten Heinz +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +%% This patch file will remove the following bugs from the listings package. +%% Each item contains the bug finder with date of report and first bug fix +%% version, a short description of the problem, and the reason for the bug +%% in parenthesis. +%% +%% 1) Jochen Schneider, 2002/04/03, 1.0a (2002/04/05) +%% +%% undefined control sequence \lst@CommentB with HTML, XML, tcl +%% (I didn't renamed them to \lst@DefDelimB|E) +%% +%% 2) Michael Niedermair, 2002/04/07, 1.0b +%% +%% undefined control sequence \lst@commentmode with XML +%% (mode not defined any more) +%% +%% 3) Carsten Heinz, 2002/04/08, 1.0b +%% +%% bad PODs (investigating bugs 1 and 2) +%% (definition doesn't use 1.0 style) +%% +%% 4) Peter Bartke, 2002/04/10, 1.0b +%% +%% various problems with fancyvrb interface: string ".5" at beginning +%% of first line when using lineskip; ditto "perhaps a missing \item +%% error"; wrong placed characters , and - when using fancyvrb +%% (bad use of \strip@pt; TeX is not in vertical mode when leaving +%% Verbatim; bad `noligs' handling) +%% +%% 5) Rolf Niepraschk, 2002/04/12, 1.0b +%% +%% \RequirePackage is missing keywordstyle when near the top of a page +%% (\lst@lastother not saved away across page breaks) +%% +%% 6) Peter Ruckdeschel, 2002/04/12, 1.0b +%% Timothy Van Zandt analyzed and fixed the bug +%% +%% incompatibility with seminar class +%% (bad assignment of \lst@do@noligs in \lst@SelectCharTable) +%% +%% 7) Rene H. Larsen, 2002/04/12, 1.0b +%% +%% \lstinputlistings and texcl conflict +%% (^^M not active to reenter modes) +%% +%% 8) Carsten Heinz, 2002/04/15, 1.0b (2002/04/15) +%% +%% gobble doesn't always work (investigating problem with VTeX) +%% (\lst@BOLGobble@ must test against \lst@Process{FormFeed|Tabulator}X) +%% +%% 9) Peter Bartke, 2002/04/17, 1.0c +%% +%% TeX capacity exceeded with fancyvrb +%% (\let\lst@entermodes\@empty must stay in \lstFV@VerbatimBegin) +%% +%% 10) Svend Tollak Munkejord, 2002/04/17, 1.0c +%% Heiko Oberdiek analyzed and fixed the bug +%% +%% package incompatible with Lucida .fd files +%% (parentheses have active catcodes when reading the file) +%% +%% 11) Carsten Hamm, 2002/04/19, 1.0c (2002/04/24) +%% +%% wrong frame rules with breaklines and xleftmargin>0pt +%% (missing \kern-\lst@xleftmargin in \lst@discretionary) +%% +%% 12) Michael Niedermair, 2002/05/14, 1.0d +%% +%% backgroundcolor take effect on bottom captions +%% (wrong order of \everypar{} and \lsthk@ExitVars in \lst@DeInit) +%% +%% 13) Georg Rehm, 2002/05/14, 1.0d +%% +%% bad baselineskip with captionpos=b +%% (missing \normalbaselines) +%% +%% 14) Herfried Karl Wagner, 2002/05/11, 1.0d +%% +%% undefined control sequence \lst@entermodes +%% (\output called before first \lst@EnterMode) +%% +%% 15) Peter K\"oller, 2002/05/24, 1.0d +%% +%% XML keywords don't have keywordstyle +%% (missing \ifx... in implementation of contentsstyle) +%% +%% 16) Stephen Reindl, 2002/05/28, 1.0d +%% +%% \inaccessible using Cobol +%% (\lst@Delim@option didn't enclose option in []) +%% +%% 17) Stephen Reindl, 2002/06/04, 1.0d (2002/06/12) +%% +%% frames not deactivated for text style listings +%% +%% 18) Carsten Heinz, 2002/07/27, 1.0e (2002/07/31) +%% +%% broken keywordcomments +%% (\lst@KCpost inside group level 2; bad \lst@BeginComment call) +%% +%% 19) Kris Luyten, 2002/07/30, 1.0f (2002/08/03) +%% +%% Undefined control sequence \lst@thestyle +%% (undefined \lst@directives after _loading_ C) +%% +%% 20) Kris Luyten, 2002/08/03, 1.0g (2002/08/06) +%% +%% Undefined control sequence \lst@thestyle +%% (side effect of 19-bugfix on \lst@ProvideFamily) +%% +%% 21) Venkatesh Prasad Ranganath, 2002/08/31, 1.0h +%% +%% Undefined control sequence \thelstnumber with 0.21-option +%% (\let must be changed to a \def inition) +%% +%% 22) Fermin Reig, 2002/09/04, 1.0h (2002/09/09) +%% +%% Bad top frame inside figure+centering +%% (reset of leftskip, rightskip and parfillskip comes too late) +%% +%% 23) Hermann H\"uttler, 2002/10/05, 1.0i (2002/10/13) +%% +%% C++-string "... \\" does not end with second double quote +%% (missing \let\lst@lastother\@empty in old fix) +%% +%% +%% Moreover the following functionality is added. +%% +%% a) option "final" (Rolf Niepraschk, Enrico Straube) +%% +%% b) keys "fvcmdparams" and "morefvcmdparams" (Denis Girou) +%% +%% c) key "contentstyle" (Peter K\"oller) +%% +%% d) key "numberfirstline" (Georg Rehm) +%% +%% +\ProvidesFile{lstpatch.sty}[2002/10/13 1.0i (Carsten Heinz)] +\lst@CheckVersion{1.0} +{\typeout{^^J% + ***^^J% + *** This is a patch for `listings.sty' version 1.0, but^^J% + *** you're using version \lst@version.^^J% + ***^^J + *** Patch file not loaded.^^J% + ***^^J}% + \endinput +} +% +% 1) Define the missing control sequences. (Not needed any more.) +\def\lstpatch@comments{% + \global\let\lst@CommentB\lst@DefDelimB + \global\let\lst@CommentE\lst@DefDelimE} +% +% 2) Define \lst@commentmode. +\lst@NewMode\lst@commentmode +% +% 3) Introduce \lst@ifxpodcomment as master-clause and define 1.0 style +% contents for SelectCharTable. +\def\lstpatch@pod{% +\lst@Key{podcomment}{false}[t]{\lstKV@SetIf{##1}\lst@ifxpodcomment}% +\lst@AddToHookExe{SetLanguage}{\let\lst@ifxpodcomment\iffalse}% +\lst@AddToHook{SelectCharTable}% + {\lst@ifxpodcomment + \lst@CArgX =\relax\lst@DefDelimB{}{}% + {\ifnum\@tempcnta=\z@ + \lst@ifprintpod\else + \def\lst@bnext{\lst@BeginDropOutput\lst@PODmode}% + \expandafter\expandafter\expandafter\@gobblethree + \fi + \else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@PODmode{{\lst@commentstyle}}% modified + \lst@CArgX =cut\^^M\relax\lst@DefDelimE + {\lst@CalcColumn}% + {\ifnum\@tempcnta=\z@\else + \expandafter\@gobblethree + \fi}% + {}% + \lst@EndComment\lst@PODmode + \fi}% +} +% +% 4) Redefine lineskip like podcomment above and don't use \strip@pt +% together with \divide. +\def\lstpatch@lineshape{% +\lst@Key{lineskip}{\z@}{\def\lst@xlineskip{##1\relax}} +\lst@AddToHook{Init} + {\ifdim\z@=\lst@xlineskip\else + \@tempdima\baselineskip + \advance\@tempdima\lst@xlineskip + \multiply\@tempdima\@cclvi + \divide\@tempdima\baselineskip\relax + \multiply\@tempdima\@cclvi + \edef\baselinestretch{\strip@pt\@tempdima}% + \selectfont + \fi}% +% 11) Add \kern-\lst@xleftmargin. +\gdef\lst@discretionary{% + \discretionary{\let\space\lst@spacekern\lst@prebreak}% + {\llap{\lsthk@EveryLine + \kern\lst@breakcurrindent\kern-\lst@xleftmargin}% + \let\space\lst@spacekern\lst@postbreak}{}}% +} +% Back to 4): Insert \par for vertical mode. +\def\lstpatch@fancyvrb{% +\gdef\lstFV@VerbatimEnd{% + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \global\setbox\lstFV@gtempboxa\box\@tempboxa + \global\let\@gtempa\FV@ProcessLine + \lst@mode\lst@Pmode + \lst@DeInit + \let\FV@ProcessLine\@gtempa + \setbox\@tempboxa\box\lstFV@gtempboxa + \par % modified + \fi}% +% 9) Redefined \lstFV@VerbatimBegin removed. +% b) Refine conversion definitions to either work as usual or to ... +\gdef\lst@FVConvert{\@tempcnta\z@ \lst@FVConvertO@}% +\gdef\lst@FVConvertO@{% + \ifcase\@tempcnta \expandafter + \futurelet\expandafter\@let@token\expandafter\lst@FVConvert@@ + \else +% append arguments as they are. + \expandafter\lst@FVConvertO@a + \fi}% +\gdef\lst@FVConvertO@a##1{% + \lst@lAddTo\lst@arg{{##1}}\advance\@tempcnta\m@ne + \lst@FVConvertO@}% +% Here, ... +\gdef\lst@FVConvert@##1{% + \ifx \@nil##1\else + \if\relax\noexpand##1% + \lst@lAddTo\lst@arg{\lst@OutputLostSpace\lst@PrintToken##1}% +% ... actually here, we check for commands with arguments and set the +% value of \@tempcnta as required. + \def\lst@temp####1,##1####2,####3####4\relax{% + \ifx####3\@empty \else \@tempcnta####2\relax \fi}% + \expandafter\lst@temp\lst@FVcmdparams,##1\z@,\@empty\relax + \else + \lccode`\~=`##1\lowercase{\lst@lAddTo\lst@arg~}% + \fi + \expandafter\lst@FVConvertO@ + \fi} +% Eventually we define user keys to adjust \lst@FVcmdparams. The base +% set of commands and parameter numbers was provided by Denis Girou. +\lst@Key{fvcmdparams}% +% D.G. suggestion begin - 2002/05/31 + {\overlay\@ne}% +% D.G. suggestion end + {\def\lst@FVcmdparams{,##1}}% +\lst@Key{morefvcmdparams}\relax{\lst@lAddTo\lst@FVcmdparams{,##1}}% +} +% +% 5) Extend \lst@SaveToken to save \lst@lastother. +\def\lst@SaveToken{% + \global\let\lst@gthestyle\lst@thestyle + \global\let\lst@glastother\lst@lastother + \xdef\lst@RestoreToken{\noexpand\lst@token{\the\lst@token}% + \noexpand\lst@length\the\lst@length\relax + \noexpand\let\noexpand\lst@thestyle + \noexpand\lst@gthestyle + \noexpand\let\noexpand\lst@lastother + \noexpand\lst@glastother}% +} +% +% 6) Assign \lst@do@noligs to \do. +\def\lst@SelectCharTable{% + \lst@SelectStdCharTable + \lst@ifactivechars + \catcode9\active \catcode12\active \catcode13\active + \@tempcnta=32\relax + \@whilenum\@tempcnta<128\do + {\catcode\@tempcnta\active\advance\@tempcnta\@ne}% + \fi + \lst@ifec \lst@DefEC \fi + \let\do\lst@do@noligs \verbatim@nolig@list % modified + \lsthk@SelectCharTable + \lst@DeveloperSCT + \ifx\lst@Backslash\relax\else + \lst@LetSaveDef{"5C}\lsts@backslash\lst@Backslash + \fi} +% 4)+6) And we need correct versions of \lst@do@noligs[@]. +\def\lst@do@noligs#1{% + \begingroup \lccode`\~=`#1\lowercase{\endgroup + \lst@do@noligs@~}} +\def\lst@do@noligs@#1{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\lst@NoLig#1}} +% +% 7) Make ^^M active. +\def\lst@InputListing#1{% + \begingroup + \lsthk@PreSet \gdef\lst@intname{#1}% + \expandafter\lstset\expandafter{\lst@set}% + \lsthk@DisplayStyle + \catcode\active=\active % added + \lst@Init\relax \let\lst@gobble\z@ + \lst@SkipToFirst + \lst@ifprint \def\lst@next{\input{#1}}% + \else \let\lst@next\@empty \fi + \lst@next + \lst@DeInit + \endgroup} +% +% 8) Replace \lst@Process{FormFeed|Tabulator}. +\def\lst@ProcessFormFeedX{\lst@ProcessFormFeed} +\def\lst@ProcessTabulatorX{\lst@ProcessTabulator} +\def\lst@BOLGobble@#1{% + \let\lst@next#1% + \ifx \lst@next\relax\else + \ifx \lst@next\lst@MProcessListing\else + \ifx \lst@next\lst@ProcessFormFeedX\else + \ifx \lst@next\lstenv@backslash + \let\lst@next\lstenv@BOLGobble@@ + \else + \let\lst@next\lst@BOLGobble@@ + \ifx #1\lst@ProcessTabulatorX + \advance\@tempcnta-\lst@tabsize\relax + \ifnum\@tempcnta<\z@ + \lst@length-\@tempcnta \lst@PreGotoTabStop + \fi + \else + \advance\@tempcnta\m@ne + \fi + \fi \fi \fi \fi + \lst@next} +% +% 10) Add some \@makeother to \lst@nfss@catcodes. +\def\lst@nfss@catcodes{% + \lst@makeletter + ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\relax + \@makeother (\@makeother )\@makeother ,\@makeother :\@makeother &% + \@makeother 0\@makeother 1\@makeother 2\@makeother 3\@makeother 4% + \@makeother 5\@makeother 6\@makeother 7\@makeother 8\@makeother 9% + \@makeother =\lsts@nfss@catcodes} +% +% 12) and 13) Deactivate \everypar and use normal baseline parameters. +\lst@AddToHook{DeInit}{\everypar{}\normalbaselines} +% +% 14) Define \lst@entermodes. +\let\lst@entermodes\@empty +% +% 16) Insert [ and ] in replacement text. +\def\lst@Delim@option[#1]{\def\lst@arg{[#1]}\lst@Delim@delim} +% +% 17) Just empty `frame' and top, right, bottom, and left shape. +\lst@AddToHook{TextStyle} + {\let\lst@frame\@empty + \let\lst@frametshape\@empty + \let\lst@framershape\@empty + \let\lst@framebshape\@empty + \let\lst@framelshape\@empty} +% +% 18) Execute \lst@BeginKC and \lst@BeginKCS outside the two groups. +% Modify third argument to \lst@BeginComment to work properly. +\def\lstpatch@keywordcomments{% +\gdef\lst@BeginKC{\aftergroup\aftergroup\aftergroup\lst@BeginKC@}% +\gdef\lst@BeginKC@{% + \lst@ResetToken + \lst@BeginComment\lst@KCmode{{\lst@commentstyle}\lst@modetrue}\@empty}% +\gdef\lst@BeginKCS{\aftergroup\aftergroup\aftergroup\lst@BeginKCS@}% +\gdef\lst@BeginKCS@{% + \lst@ResetToken + \lst@BeginComment\lst@KCSmode{{\lst@commentstyle}\lst@modetrue}\@empty}% +\gdef\lst@EndKC{\lst@SaveToken \lst@LeaveMode \lst@RestoreToken + \let\lst@thestyle\lst@identifierstyle \lsthk@Output}% renew style selection +} +% +% 19) Init \lst@directives. +\def\lstpatch@directives{% + \global\let\lst@directives\@empty} +% +% 20) Use new prefix for a family -- the now initialized \lst@directives +% clashes with the default. +\def\lstpatch@keywords{% +\gdef\lst@ProvideFamily##1{% + \@ifundefined{lstfam@##1\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}% + {\@namedef{lstfam@##1\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}{}% + \expandafter\expandafter\expandafter\lst@ProvideFamily@ + \csname\@lst @##1@data\endcsname + {\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}% + {}}% +} +% 21) Define \thelstnumber every listing via \def. +\@namedef{lstpatch@021}{% + \lst@AddToHook{Init}{\def\thelstnumber{\thelstlabel}}% +} +% 22) Reset the registers in PreInit hook +\lst@AddToHook{PreInit} + {\rightskip\z@ \leftskip\z@ \parfillskip\z@ plus 1fil} +% +% 23) Add \let\lst@lastother\@empty +\lst@AddToHook{SelectCharTable}{% + \lst@ifbstring + \lst@CArgX \\\\\relax \lst@CDefX{}% + {\lst@ProcessOther\lstum@backslash + \lst@ProcessOther\lstum@backslash + \let\lst@lastother\@empty}% + {}% + \fi} +% +% a) Just declare the option. +\DeclareOption{final}{\let\lst@ifdraft\iffalse} +% +% c) Define contentstyle and use it. +\def\lstpatch@html{% +\lst@Key{contentstyle}{}{\def\lst@contentstyle{##1}}% +\lst@AddToHook{Init}% + {\ifx\lst@DefInside\@empty\else + \let\lst@tagstyle\lst@identifierstyle + \let\lst@identifierstyle\lst@contentstyle + \fi}% +\lst@AddToHook{Output}% + {\ifnum\lst@mode=\lst@insidemode +% 15) Check for keywordstyle. + \ifx\lst@thestyle\lst@gkeywords@sty\else + \lst@ifusekeysinside \let\lst@thestyle\lst@tagstyle + \else \let\lst@thestyle\lst@gkeywords@sty \fi + \fi\fi}% +\lst@AddToHook{OutputOther}% + {\lst@ifmode\else \ifnum\lst@mode=\lst@insidemode\else + \ifx\lst@DefInside\@empty\else + \let\lst@thestyle\lst@contentstyle + \fi + \fi\fi}% +} +% +% d) Define key and adjust \lst@SkipOrPrintLabel. +\def\lstpatch@labels{% +\lst@Key{numberfirstline}{f}[t]{\lstKV@SetIf{##1}\lst@ifnumberfirstline}% +\gdef\lst@numberfirstlinefalse{\let\lst@ifnumberfirstline\iffalse} +\gdef\lst@SkipOrPrintLabel{% + \ifnum\lst@skipnumbers=\z@ + \global\advance\lst@skipnumbers-\lst@stepnumber\relax + \lst@PlaceNumber + \lst@numberfirstlinefalse + \else + \lst@ifnumberfirstline + \lst@PlaceNumber + \lst@numberfirstlinefalse + \fi + \fi + \global\advance\lst@skipnumbers\@ne}% +} +%% +\endinput +%% +%% End of file `lstpatch.sty'. \ No newline at end of file diff --git a/doc/user/mca-ompi.tex b/doc/user/mca-ompi.tex new file mode 100644 index 0000000000..5a68e4afe5 --- /dev/null +++ b/doc/user/mca-ompi.tex @@ -0,0 +1,2044 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Open MPI Components} +\label{sec:mca-ompi} + +{\Huge JMS Needs massive overhaul} + +There are multiple types of MPI components: + +\begin{enumerate} +\item \mcafw{rpi}: MPI point-to-point communication, also known as the + Open MPI Request Progression Interface (RPI). + +\item \mcafw{coll}: MPI collective communication. + +\item \mcafw{cr}: Checkpoint/restart support for MPI programs. +\end{enumerate} + +Each of these types, and the modules that are available in the default +Open MPI distribution, are discussed in detail below. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{General MPI MCA Parameters} +\label{sec:mca-ompi:mpi-params} + +\changebegin{7.1} + +The default hostmap file is \ifile{\$sysconf/lam-hostmap} (typically +\file{\$prefix/etc/lam-hostmap.txt}). This file is only useful in +environments with multiple TCP networks, and is typically populated by +the system administrator (see the Open MPI Installation Guide for more +details on this file). + +The MCA parameter \issiparam{mpi\_hostmap} can be used to specify an +alternate hostmap file. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -ssi mpi_hostmap my_hostmap.txt my_mpi_application +\end{lstlisting} +% stupid emacs mode: $ + +This tells Open MPI to use the hostmap \file{my\_hostmap.txt} instead of +\file{\$sysconf/lam-hostmap.txt}. The special filename +``\cmdarg{none}'' can also be used to indicate that no address +remapping should be performed. + +\changeend{7.1} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI Module Selection Process} +\label{sec:mca-ompi-component-selection} + +The modules used in an MPI process may be related or dependent upon +external factors. For example, the \rpi{gm} RPI cannot be used for +MPI point-to-point communication unless there is Myrinet hardware +present in the node. The \crssi{blcr} checkpoint/restart module +cannot be used unless thread support was included. And so on. As +such, it is important for users to understand the module selection +algorithm. + +\begin{enumerate} +\item Set the thread level to be what was requested, either via + \mpifunc{MPI\_\-INIT\_\-THREAD} or the environment variable + \ienvvar{Open MPI\_\-MPI\_\-THREAD\_\-LEVEL}. + +\item Query relevant modules and make lists of the resulting available + modules. ``Relevant'' means either a specific module (or set of + modules) if the user specified them through MCA parameters, or all + modules if not specified. + +\item Eliminate all modules who do not support the current MPI thread + level. + +\item If no \kind{rpi} modules remain, try a lower thread support + level until all levels have been tried. If no thread support level + can provide an \kind{rpi} module, abort. + +\item Select the highest priority \kind{rpi} module. Reset the thread + level (if necessary) to be at least the lower bound of thread levels + that the selected \kind{rpi} module supports. + +\item Eliminate all \kind{coll} and \kind{cr} modules that cannot + operate at the current thread level. + +\item If no \kind{coll} modules remain, abort. Final selection + \kind{coll} modules is discussed in + Section~\ref{sec:mca-ompi-coll-select} + (page~\pageref{sec:mca-ompi-coll-select}). + +\item If no \kind{cr} modules remain and checkpoint/restart support + was specifically requested, abort. Otherwise, select the highest + priority \kind{cr} module. +\end{enumerate} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI Point-to-point Communication (Request Progression + Interface / RPI)} +\label{sec:mca-ompi-rpi} + +Open MPI provides multiple MCA modules for MPI point-to-point +communication. Also known as the Request Progression Interface (RPI), +these modules are used for all aspects of MPI point-to-point +communication in an MPI application. Some of the modules require +external hardware and/or software (e.g., the native Myrinet RPI module +requires both Myrinet hardware and the GM message passing library). +The \icmd{laminfo} command can be used to determine which RPI modules +are available in a Open MPI installation. + +Although one RPI module will likely be the default, the selection of +which RPI module is used can be changed through the MCA parameter +\issiparam{rpi}. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun -ssi rpi tcp C my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +\noindent runs the \file{my\_\-mpi\_\-program} executable on all +available CPUs using the \rpi{tcp} RPI module, while: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun -ssi rpi gm C my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +\noindent runs the \file{my\_\-mpi\_\-program} executable on all +available CPUs using the \rpi{gm} RPI module. + +It should be noted that the choice of RPI usually does not affect the +\kind{boot} MCA module -- hence, the \cmd{lamboot} command +requirements on hostnames specified in the boot schema is not +dependent upon the RPI. For example, if the \rpi{gm} RPI is selected, +\cmd{lamboot} may still require TCP/IP hostnames in the boot schema, +not Myrinet hostnames. Also note that selecting a particular module +does not guarantee that it will be able to be used. For example, +selecting the \rpi{gm} RPI module will still cause a run-time failure +if there is no Myrinet hardware present. + +The available modules are described in the sections below. Note that +much of this information (particularly the tunable MCA parameters) is +also available in the \file{lamssi\_\-rpi(7)} manual page. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\changebegin{7.0.3} + +\subsection{Two Different Shared Memory RPI Modules} +\label{sec:mca-ompi-shmem} + +The \rpi{sysv} (Section~\ref{sec:mca-ompi-sysv}, +page~\pageref{sec:mca-ompi-sysv}) and the \rpi{usysv} +(Section~\ref{sec:mca-ompi-usysv}, page~\pageref{sec:mca-ompi-usysv}) +modules differ only in the mechanism used to synchronize the transfer +of messages via shared memory. +% +The \rpi{sysv} module uses System V semaphores while the \rpi{usysv} +module uses spin locks with back-off. +% +Both modules use a small number of System V semaphores for +synchronizing both the deallocation of shared structures and access to +the shared pool. + +The blocking nature of the \rpi{sysv} module should generally provide +better performance than \rpi{usysv} on oversubscribed nodes (i.e., +when the number of processes is greater than the number of available +processors). System V semaphores will effectively force processes +yield to other processes, allowing at least some degree of +fair/regular scheduling. In non-oversubscribed environments (i.e., +where the number of processes is less than or equal to the number of +available processors), the \rpi{usysv} RPI should generally provide +better performance than the \rpi{sysv} RPI because spin locks keep +processors busy-waiting. This hopefully keeps the operating system +from suspending or swapping out the processes, allowing them to react +immediately when the lock becomes available. + +\changeend{7.0.3} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{crtcp} Module (Checkpoint-able TCP + Communication)} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt crtcp} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 25 \\ + {\bf Checkpoint / restart:} & yes \\ + \hline +\end{tabular} +\vspace{11pt} + +The \rpi{crtcp} RPI module is almost identical to the \rpi{tcp} +module, described in Section~\ref{sec:mca-ompi-tcp}. TCP sockets are +used for communication between MPI processes. + +%%%%% + +\subsubsection{Overview} + +The following are the main differences between the \rpi{tcp} and +\rpi{crtcp} RPI modules: + +\begin{itemize} +\item The \rpi{crtcp} module can be checkpointed and restarted. It is + currently the {\em only} RPI module in Open MPI that supports + checkpoint/restart functionality. + +\item The \rpi{crtcp} module does not have the ``fast'' message + passing optimization that is in the \rpi{tcp} module. As result, + there is a small performance loss in certain types of MPI + applications. +\end{itemize} + +All other aspects of the \rpi{crtcp} module are the same as the +\rpi{tcp} module. + +%%%%% + +\subsubsection{Checkpoint/Restart Functionality} + +The \rpi{crtcp} module is designed to work in conjunction with a +\kind{cr} module to provide checkpoint/restart functionality. See +Section~\ref{sec:mca-ompi-cr} for a description of how Open MPI's overall +checkpoint/restart functionality is used. + +The \rpi{crtcp} module's checkpoint/restart functionality is invoked +when the \kind{cr} module indicates that it is time to perform a +checkpoint. The \rpi{crtcp} then quiesces all ``in-flight'' MPI +messages and then allows the checkpoint to be performed. Upon +restart, TCP connections are re-formed, and message passing processing +continues. No additional buffers or ``rollback'' mechanisms are +required, nor is any special coding required in the user's MPI +application. + +%%%%% + +\subsubsection{Tunable Parameters} + +\changebegin{7.1} + +The \rpi{crtcp} module has the same tunable parameters as the +\rpi{tcp} module (maximum size of a short message and amount of OS +socket buffering), although they have different names: +\issiparam{rpi\_\-crtcp\_\-short}, +\issiparam{rpi\_\-crtcp\_\-sockbuf}. + +\changeend{7.1} + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-crtcp\_\-priority}{25}{Default priority + level.} +% + \ssiparamentry{rpi\_\-crtcp\_\-short}{65535}{Maximum length + (in bytes) of a ``short'' message.} +% + \ssiparamentry{rpi\_\-crtcp\_\-sockbuf}{-1}{Socket buffering in + the OS kernel (-1 means use the short message size).} + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{crtcp} RPI module.} + \label{tbl:mca-ompi-crtcp-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{gm} Module (Myrinet)} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt gm} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 50 \\ + {\bf Checkpoint / restart:} & yes (*) \\ + \hline +\end{tabular} +\vspace{11pt} + +The \rpi{gm} RPI module is for native message passing over Myrinet +networking hardware. The \rpi{gm} RPI provides low latency, high +bandwidth message passing performance. + +\changebegin{7.1} + +Be sure to also read the release notes entitled ``Operating System +Bypass Communication: Myrinet and Infiniband'' in the Open MPI +Installation Guide for notes about memory management with Myrinet. +Specifically, it deals with Open MPI's automatic overrides of the +\func{malloc()}, \func{calloc()}, and \func{free()} functions. + +\changeend{7.1} + +%%%%% + +\subsubsection{Overview} + +In general, using the \rpi{gm} RPI module is just like using any other +RPI module -- MPI functions will simply use native GM message passing +for their back-end message transport. + +Although it is not required, users are strongly encouraged to use the +\mpifunc{MPI\_\-ALLOC\_\-MEM} and \mpifunc{MPI\_\-FREE\_\-MEM} +functions to allocate and free memory (instead of, for example, +\func{malloc()} and \func{free()}. + +\changebegin{7.1} + +The \rpi{gm} RPI module is marked as ``yes'' for checkpoint / restart +support, but this is only true when the module was configured and +compiled with the \confflag{with-rpi-gm-get} configure flag. This +enables Open MPI to use the GM 2.x function \func{gm\_\-get()}. Note that +enabling this feature slightly with the \ssiparam{rpi\_\-gm\_\-cr} MCA +parameter decreases the performance of the \rpi{gm} module (which is +why it is disabled by default) because of additional bookkeeping that +is necessary. The performance difference is actually barely +measurable -- it is well below one microsecond. It is not the default +behavior simply on principle. + +At the time of this writing, there still appeared to be problems with +\func{gm\_\-get()}, so this behavior is disabled by default. It is +not clear whether the problems with \func{gm\_\-get()} are due to a +problem with Myricom's GM library or a problem in Open MPI itself; the +\confflag{with-rpi-gm-get} option is provided as a ``hedging our +bets'' solution; if the problem does turn out to be with the GM +library, Open MPI users can enable checkpoint support (and slightly lower +long message latency) by using this switch. + +\changeend{7.1} + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-ompi-gm-mca-params} shows the MCA parameters that +may be changed at run-time; the text below explains each one in +detail. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-gm\_\-cr}{0}{Whether to enable checkpoint / + restart support or not.} +% + \ssiparamentry{rpi\_\-gm\_\-fast}{0}{Whether to enable the + ``fast'' algorithm for sending short messages. This is an + unreliable transport and is not recommended for MPI applications + that do not continually invoke the MPI progression engine.} +% + \ssiparamentry{rpi\_\-gm\_\-maxport}{32}{Maximum GM port + number to check during \mpifunc{MPI\_\-INIT} when looking for an + available port.} +% + \ssiparamentry{rpi\_\-gm\_\-nopin}{0}{Whether to let Open MPI + register (``pin'') arbitrary buffers or not.} +% + \ssiparamentry{rpi\_\-gm\_\-port}{-1}{Specific GM port to use + (-1 indicates none).} +% + \ssiparamentry{rpi\_\-gm\_\-priority}{50}{Default priority level.} +% + \ssiparamentry{rpi\_\-gm\_\-tinymsglen}{1024}{Maximum length + (in bytes) of a ``tiny'' message.} + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{gm} RPI module.} + \label{tbl:mca-ompi-gm-mca-params} +\end{table} + +%%%%% + +\subsubsection{Port Allocation} + +It is usually unnecessary to specify which Myrinet/GM port to use. +Open MPI will automatically attempt to acquire ports greater than 1. + +By default, Open MPI will check for any available port between 1 and 8. If +your Myrinet hardware has more than 8 possible ports, you can change +the upper port number that Open MPI will check with the +\issiparam{rpi\_\-gm\_\-maxport} MCA parameter. + +However, if you wish Open MPI to use a specific GM port number (and not +check all the ports from $[1, {\rm maxport}]$), you can tell Open MPI which +port to use with the \issiparam{rpi\_\-gm\_\-port} MCA parameter. +% +Specifying which port to use has precedence over the port range check +-- if a specific port is indicated, Open MPI will try to use that and not +check a range of ports. Specifying to use port ``-1'' (or not +specifying to use a specific port) will tell Open MPI to check the range of +ports to find any available port. + +Note that in all cases, if Open MPI cannot acquire a valid port for every +MPI process in the job, the entire job will be aborted. + +Be wary of forcing a specific port to be used, particularly in +conjunction with the MPI dynamic process calls (e.g., +\mpifunc{MPI\_\-COMM\_\-SPAWN}). For example, attempting to spawn a +child process on a node that already has an MPI process in the same +job, Open MPI will try to use the same specific port, which will result in +failure because the MPI process already on that node will have already +claimed that port. + +%%%%% + +\subsubsection{Adjusting Message Lengths} + +The \rpi{gm} RPI uses two different protocols for passing data between +MPI processes: tiny and long. Selection of which protocol to use is +based solely on the length of the message. Tiny messages are sent +(along with tag and communicator information) in one transfer to the +receiver. Long messages use a rendezvous protocol -- the envelope is +sent to the destination, the receiver responds with an ACK (when it is +ready), and then the sender sends another envelope followed by the +data of the message. + +The message lengths at which the different protocols are used can be +changed with the MCA parameter \issiparam{rpi\_\-gm\_\-tinymsglen} , +which represent the maximum length of tiny messages. Open MPI defaults to +1,024 bytes for the maximum lengths of tiny messages. + +It may be desirable to adjust these values for different kinds of +applications and message passing patterns. The Open MPI Team would +appreciate feedback on the performance of different values for real +world applications. + +%%%%% + +\subsubsection{Pinning Memory} +\label{sec:mca-ompi-gm-ptmalloc} + +The Myrinet native communication library (gm) can only communicate +through ``registered'' (sometimes called ``pinned'') memory. In most +operating systems, Open MPI handles this automatically by pinning +user-provided buffers when required. This allows for good message +passing performance, especially when re-using buffers to send/receive +multiple messages. + +However, the gm library does not have the ability to pin arbitrary +memory on Solaris systems -- auxiliary buffers must be used. Although +Open MPI controls all pinned memory, this has a detrimental effect on +performance of large messages: Open MPI must copy all messages from the +application-provided buffer to an auxiliary buffer before it can be +sent (and vice versa for receiving messages). As such, users are +strongly encouraged to use the \mpifunc{MPI\_\-ALLOC\_\-MEM} and +\mpifunc{MPI\_\-FREE\_\-MEM} functions instead of \func{malloc()} and +\func{free()}. Using these functions will allocate ``pinned'' memory +such that Open MPI will not have to use auxiliary buffers and an extra +memory copy. + +The \ssiparam{rpi\_\-gm\_\-nopin} MCA parameter can be used to force +Solaris-like behavior. On Solaris platforms, the default value is +``1'', specifying to use auxiliary buffers as described above. On +non-Solaris platforms, the default value is ``0'', meaning that +Open MPI will attempt to pin and send/receive directly from user +buffers. + +Note that since Open MPI manages all pinned memory, Open MPI must be +aware of memory that is freed so that it can be properly unpinned +before it is returned to the operating system. Hence, Open MPI must +intercept calls to functions such as \func{sbrk()} and \func{munmap()} +to effect this behavior. Since gm cannot pin arbitrary memory on +Solaris, Open MPI does not need to intercept these calls on Solaris +machines. + +To this end, support for additional memory allocation packages are +included in Open MPI and will automatically be used on platforms that +support arbitrary pinning. These memory allocation managers allow +Open MPI to intercept the relevant functions and ensure that memory is +unpinned before returning it to the operating system. Use of these +managers will effectively overload all memory allocation functions +(e.g., \func{malloc()}, \func{calloc()}, \func{free()}, etc.) for all +applications that are linked against the Open MPI libraries +(potentially regardless of whether they are using the ib RPI module or +not). + +See Section \ref{release-notes:os-bypass} (page +\pageref{release-notes:os-bypass}) for more information on Open MPI's +memory allocation managers. + +%%%%% + +\subsubsection{Memory Checking Debuggers} + +When running Open MPI's \rpi{gm} RPI through a memory checking debugger +(see Section~\ref{sec:debug-mem}), a number of ``Read from +unallocated'' (RUA) and/or ``Read from uninitialized'' (RFU) errors +may appear, originating from functions beginning with ``\func{gm\_*}'' +or ``\func{lam\_\-ssi\_\-rpi\_\-gm\_*}''. These RUA/RFU errors are +normal -- they are not actually reads from unallocated sections of +memory. The Myrinet hardware and gm kernel device driver handle some +aspects of memory allocation, and therefore the operating +system/debugging environment is not always aware of all valid memory. +As a result, a memory checking debugger will often raise warnings, +even though this is valid behavior. + +%%%%% + +\subsubsection{Known Issues} + +As of Open MPI \lamversion, the following issues still remain in the +\rpi{gm} RPI module: + +\begin{itemize} +\item Heterogeneity between big and little endian machines is not + supported. + +\item The \rpi{gm} RPI is not supported with IMPI. + +\item Mixed shared memory / GM message passing is not yet supported; + all message passing is through Myrinet / GM. + +\item XMPI tracing is not yet supported. + +\changebegin{7.0.3} + +\item The \rpi{gm} RPI module is designed to run in environments where + the number of available processors is greater than or equal to the + number of MPI processes on a given node. The \rpi{gm} RPI module + will perform poorly (particularly in blocking MPI communication + calls) if there are less processors than processes on a node. + +\changeend{7.0.3} + +\changebegin{7.1} + +\item ``Fast'' support is available and slightly decreases the latency + for short gm messages. However, it is unreliable and is subject to + timeouts for MPI applications that do not invoke the MPI progression + engine often, and is therefore not the default behavior. + +\item Support for the \func{gm\_\-get()} function in the GM 2.x series + is available starting with Open MPI 7.1, but is disabled by support. + See the Installation Guide for more details. + +\item Checkpoint/restart support is included for the \rpi{gm} module, + but is only possible when the \rpi{gm} module was compiled with + support for \func{gm\_\-get()}. + +\changeend{7.1} + +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{ib} Module (Infiniband)} +\label{sec:mca-ompi-ib} + +\changebegin{7.1} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt ib} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 50 \\ + {\bf Checkpoint / restart:} & no \\ + \hline +\end{tabular} +\vspace{11pt} + + +The \rpi{ib} RPI module is for native message passing over Infiniband +networking hardware. The \rpi{ib} RPI provides low latency, high +bandwidth message passing performance. + +Be sure to also read the release notes entitled ``Operating System +Bypass Communication: Myrinet and Infiniband'' in the Open MPI +Installation Guide for notes about memory management with Infiniband. +Specifically, it deals with Open MPI's automatic overrides of the +\func{malloc()}, \func{calloc()}, and \func{free()} functions. + +%%%%% + +\subsubsection{Overview} + +In general, using the \rpi{ib} RPI module is just like using any other +RPI module -- MPI functions will simply use native Infiniband message +passing for their back-end message transport. + +Although it is not required, users are strongly encouraged to use the +\mpifunc{MPI\_\-ALLOC\_\-MEM} and \mpifunc{MPI\_\-FREE\_\-MEM} +functions to allocate and free memory used for communication (instead +of, for example, \func{malloc()} and \func{free()}. This would avoid +the need to pin the memory during communication time and hence save on +message passsing latency. + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-ompi-ib-mca-params} shows the MCA parameters that +may be changed at run-time; the text below explains each one in +detail. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-ib\_\-hca\_\-id}{X}{The string ID of the + Infiniband hardware HCA to be used} +% + \ssiparamentry{rpi\_\-ib\_\-num\_\-envelopes}{64}{Number of + envelopes to be preposted per peer process.} +% + \ssiparamentry{rpi\_\-ib\_\-port}{-1}{Specific IB port to use + (-1 indicates none).} +% + \ssiparamentry{rpi\_\-ib\_\-priority}{50}{Default priority level.} +% + \ssiparamentry{rpi\_\-ib\_\-tinymsglen}{1024}{Maximum length + (in bytes) of a ``tiny'' message.} +% + \ssiparamentry{rpi\_\-ib\_\-mtu}{1024}{Maximum Transmission + Unit (MTU) value to be used for IB.} + + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{ib} RPI module.} + \label{tbl:mca-ompi-ib-mca-params} +\end{table} + +%%%%% + +\subsubsection{Port Allocation} + +It is usually unnecessary to specify which Infiniband port to use. +Open MPI will automatically attempt to acquire ports greater than 1. + +However, if you wish Open MPI to use a specific Infiniband port number, you +can tell Open MPI which port to use with the \issiparam{rpi\_\-ib\_\-port} +MCA parameter. +% +Specifying which port to use has precedence over the port range check +-- if a specific port is indicated, Open MPI will try to use that and not +check a range of ports. Specifying to use port ``-1'' (or not +specifying to use a specific port) will tell Open MPI to check the range of +ports to find any available port. + +Note that in all cases, if Open MPI cannot acquire a valid port for every +MPI process in the job, the entire job will be aborted. + +Be wary of forcing a specific port to be used, particularly in +conjunction with the MPI dynamic process calls (e.g., +\mpifunc{MPI\_\-COMM\_\-SPAWN}). For example, attempting to spawn a +child process on a node that already has an MPI process in the same +job, Open MPI will try to use the same specific port, which will result in +failure because the MPI process already on that node will have already +claimed that port. + +%%%%% + +\subsubsection{Choosing an HCA ID} + +The HCA ID is the Mellanox Host Channel Adapter ID. For example: +InfiniHost0. It is usually unnecessary to specify which HCA ID to +use. Open MPI will search for all HCAs available and select the first +one which is available. If you want to use a fixed HCA ID, then you +can specify that using the \ssiparam{rpi\_\-ib\_\-hca\_\-id} MCA +parameter. + +%%%%% + +\subsubsection{Adjusting Message Lengths} + +The \rpi{ib} RPI uses two different protocols for passing data between +MPI processes: tiny and long. Selection of which protocol to use is +based solely on the length of the message. Tiny messages are sent +(along with tag and communicator information) in one transfer to the +receiver. Long messages use a rendezvous protocol -- the envelope is +sent to the destination, the receiver responds with an ACK (when it is +ready), and then the sender sends another envelope followed by the +data of the message. + +The message lengths at which the different protocols are used can be +changed with the MCA parameter \issiparam{rpi\_\-ib\_\-tinymsglen} , +which represent the maximum length of tiny messages. Open MPI defaults to +1,024 bytes for the maximum lengths of tiny messages. + +It may be desirable to adjust these values for different kinds of +applications and message passing patterns. The Open MPI Team would +appreciate feedback on the performance of different values for real +world applications. + +%%%%% + +\subsubsection{Posting Envelopes to Recieve / Scalability} +\label{sec:mca-ompi-ib-envelopes} + +Receive buffers must be posted to the IB communication +hardware/library before any receives can occur. Open MPI uses +enevelopes that contain MPI signature information, and in the case of +tiny messages, they also hold the actual message contents. +% +The size of each envelope is therefore sum of the size of the headers +and the maximum size of a tiny message (controlled by +\issiparam{rpi\_\-ib\_\-tinymsglen} MCA parameter). Open MPI pre-posts 64 +evnvelope buffers per peer process by default, but can be overridden +at run-time with then \issiparam{rpi\_\-ib\_\-num\_\-envelopes} MCA +parameter. + +\changebegin{7.1.2} + +These two MCA parameters can have a large effect on scalability. +Since Open MPI pre-posts a total of $((num\_processes - 1) \times +num\_envelopes \times tinymsglen)$ bytes, this can be prohibitive if +$num\_processes$ grows large. However, $num\_envelopes$ and +$tinymsglen$ can be adjusted to help keep this number low, although +they may have an effect on run-time performance. Changing the number +of pre-posted envelopes effectively controls how many messages can be +simultaneously flowing across the network; changing the tiny message +size affects when Open MPI switches to use a rendezvous sending protocol +instead of an eager send protocol. Relevant values for these +parameters are likely to be application-specific; keep this in mind +when running large parallel jobs. + +\changeend{7.1.2} + +%%%%% + +\subsubsection{Modifying the MTU value} +\label{sec:mca-ompi-ib-mtu} + +\changebegin{7.1.2} + +The Maximum Transmission Unit (MTU) values to be used for Infiniband +can be configured at runtime using the +\issiparam{rpi\_\-ib\_\-mtu} MCA parameter. It can take in +values of 256, 512, 1024, 2048 and 4096 corresponding to MTU256, +MTU512, MTU1024, MTU2048 and MTU4096 values of Infiniband MTUs +respectively. The default value is 1024 (corresponding to MTU1024). + +\changeend{7.1.2} + +%%%%% + +\subsubsection{Pinning Memory} +\label{sec:mca-ompi-ib-ptmalloc} + +The Infiniband communication library can only communicate through +``registered'' (sometimes called ``pinned'') memory. Open MPI handles +this automatically by pinning user-provided buffers when required. +This allows for good message passing performance, especially when +re-using buffers to send/receive multiple messages. + +Note that since Open MPI manages all pinned memory, Open MPI must be +aware of memory that is freed so that it can be properly unpinned +before it is returned to the operating system. Hence, Open MPI must +intercept calls to functions such as \func{sbrk()} and \func{munmap()} +to effect this behavior. + +To this end, support for additional memory allocation packages are +included in Open MPI and will automatically be used on platforms that +support arbitrary pinning. These memory allocation managers allow +Open MPI to intercept the relevant functions and ensure that memory is +unpinned before returning it to the operating system. Use of these +managers will effectively overload all memory allocation functions +(e.g., \func{malloc()}, \func{calloc()}, \func{free()}, etc.) for all +applications that are linked against the Open MPI libraries +(potentially regardless of whether they are using the ib RPI module or +not). + +See Section \ref{release-notes:os-bypass} (page +\pageref{release-notes:os-bypass}) for more information on Open MPI's +memory allocation managers. + +%%%%% + +\subsubsection{Memory Checking Debuggers} + +When running Open MPI's \rpi{ib} RPI through a memory checking debugger +(see Section~\ref{sec:debug-mem}), a number of ``Read from +unallocated'' (RUA) and/or ``Read from uninitialized'' (RFU) errors +may appear pertaining to VAPI. These RUA/RFU errors are +normal -- they are not actually reads from unallocated sections of +memory. The Infiniband hardware and kernel device driver handle some +aspects of memory allocation, and therefore the operating +system/debugging environment is not always aware of all valid memory. +As a result, a memory checking debugger will often raise warnings, +even though this is valid behavior. + +%%%%% + +\subsubsection{Known Issues} + +As of Open MPI \lamversion, the following issues remain in the +\rpi{ib} RPI module: + +\begin{itemize} + +\changebegin{7.1.2} + +\item The \rpi{ib} \kind{rpi} will not scale well to large numbers of + processes. See the section entitled ``Posting Envelopes to Receive + / Scalability,'' above. + +\changeend{7.1.2} + +\item On machines which have IB (VAPI) shared libraries but not the IB + hardware, and when Open MPI is compiled with IB support, you may see some + error messages like ``can't open device file'' when trying to use + Open MPI, even when you are not using the IB module. This error + message pertains to IB (VAPI) shared libraries and is not from + within Open MPI. It results because when Open MPI tries to query the + shared libraries, VAPI tries to open the IB device during the shared + library init phase, which is not proper. + +\item Heterogeneity between big and little endian machines is not + supported. + +\item The \rpi{ib} RPI is not supported with IMPI. + +\item Mixed shared memory / IB message passing is not yet supported; + all message passing is through Infiniband. + +\item XMPI tracing is not yet supported. + +\item The \rpi{ib} RPI module is designed to run in environments where + the number of available processors is greater than or equal to the + number of MPI processes on a given node. The \rpi{ib} RPI module + will perform poorly (particularly in blocking MPI communication + calls) if there are less processors than processes on a node. + +\changeend{7.1} + +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{lamd} Module (Daemon-Based Communication)} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt lamd} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 10 \\ + {\bf Checkpoint / restart:} & no \\ + \hline +\end{tabular} +\vspace{11pt} + +The \rpi{lamd} RPI module uses the Open MPI daemons for all interprocess +communication. This allows for true asynchronous message passing +(i.e., messages can progress even while the user's program is +executing), albeit at the cost of a significantly higher latency and +lower bandwidth. + +%%%%% + +\subsubsection{Overview} + +Rather than send messages directly from one MPI process to another, +all messages are routed through the local Open MPI daemon, the remote Open MPI +daemon (if the target process is on a different node), and then +finally to the target MPI process. This potentially adds two hops to +each MPI message. + +Although the latency incurred can be significant, the \rpi{lamd} RPI +can actually make message passing progress ``in the background.'' +Specifically, since Open MPI is an single-threaded MPI implementation, +it can typically only make progress passing messages when the user's +program is in an MPI function call. With the \rpi{lamd} RPI, since +the messages are all routed through separate processes, message +passing can actually occur when the user's program is {\em not} in an +MPI function call. + +User programs that utilize latency-hiding techniques can exploit this +asynchronous message passing behavior, and therefore actually achieve +high performance despite of the high overhead associated with the +\rpi{lamd} RPI.\footnote{Several users on the Open MPI mailing list + have mentioned this specifically; even though the \rpi{lamd} RPI is + slow, it provides {\em significantly} better performance because it + can provide true asynchronous message passing.} + +%%%%% + +\subsubsection{Tunable Parameters} + +The \rpi{lamd} module has only one tunable parameter: its priority. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-lamd\_\-priority}{10}{Default priority + level.} + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{lamd} RPI module.} + \label{tbl:mca-ompi-lamd-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{sysv} Module (Shared Memory Using System V + Semaphores)} +\label{sec:mca-ompi-sysv} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt sysv} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 30 \\ + {\bf Checkpoint / restart:} & no \\ + \hline +\end{tabular} +\vspace{11pt} + +The \rpi{sysv} RPI is the one of two combination shared-memory/TCP +message passing modules. Shared memory is used for passing messages +to processes on the same node; TCP sockets are used for passing +messages to processes on other nodes. System V semaphores are used +for synchronization of the shared memory pool. + +\changebegin{7.0.3} + +Be sure to read Section~\ref{sec:mca-ompi-shmem} +(page~\pageref{sec:mca-ompi-shmem}) on the difference between this +module and the \rpi{usysv} module. + +\changeend{7.0.3} + +%%%%% + +\subsubsection{Overview} + +Processes located on the same node communicate via shared memory. One +System V shared segment is shared by all processes on the same node. +This segment is logically divided into three areas. The total size of +the shared segment (in bytes) allocated on each node is: + +\[ +(2 \times C) + (N \times (N-1) \times (S + C)) + P +\] + +where $C$ is the cache line size, $N$ is the number of processes on +the node, $S$ is the maximum size of short messages, and $P$ is the +size of the pool for large messages, + +The first area (of size $(2 \times C)$) is for the global pool lock. +The \rpi{sysv} module allocates a semaphore set (of size six) for each +process pair communicating via shared memory. On some systems, the +operating system may need to be reconfigured to allow for more +semaphore sets if running tasks with many processes communicating via +shared memory. + +The second area is for ``postboxes,'' or short message passing. A +postbox is used for communication one-way between two processes. Each +postbox is the size of a short message plus the length of a cache +line. There is enough space allocated for $(N \times (N-1))$ +postboxes. The maximum size of a short message is configurable with +the \issiparam{rpi\_\-ssi\_\-sysv\_\-short} MCA parameter. + +% JMS: Someday, cache line should be an MCA parameter. + +% \const{CACHELINESIZE} must be the size of a cache line or a multiple +% thereof. The default setting is 64 bytes. You shouldn't need to +% change it. \const{CACHELINESIZE} bytes in the postbox are used for a +% cache-line sized synchronization location. + +The final area in the shared memory area (of size $P$) is used as a +global pool from which space for long message transfers is allocated. +Allocation from this pool is locked. The default lock mechanism is a +System V semaphore but can be changed to a process-shared pthread +mutex lock. The size of this pool is configurable with the +\issiparam{rpi\_\-ssi\_\-sysv\_\-shmpoolsize} MCA parameter. Open MPI will +try to determine $P$ at configuration time if none is explicitly +specified. Larger values should improve performance (especially when +an application passes large messages) but will also increase the +system resources used by each task. + +%%%%% + +\subsubsection{Use of the Global Pool} + +When a message larger than ($2S$) is sent, the transport sends $S$ +bytes with the first packet. When the acknowledgment is received, it +allocates (${\rm message length} - S$) bytes from the global pool to +transfer the rest of the message. + +To prevent a single large message transfer from monopolizing the +global pool, allocations from the pool are actually restricted to a +maximum of \issiparam{rpi\_\-ssi\_\-sysv\_\-shmmaxalloc} bytes. Even +with this restriction, it is possible for the global pool to +temporarily become exhausted. In this case, the transport will fall +back to using the postbox area to transfer the message. Performance +will be degraded, but the application will progress. + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-ompi-sysv-mca-params} shows the MCA parameters that +may be changed at run-time. Each of these parameters were discussed +in the previous sections. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-sysv\_\-priority}{30}{Default priority level.} +% + \ssiparamentry{rpi\_\-sysv\_\-pollyield}{1}{Whether or not to force + the use of \func{yield()} to yield the processor.} +% + \ssiparamentry{rpi\_\-sysv\_\-shmmaxalloc}{From configure}{Maximum + size of a large message atomic transfer. The default value is + calculated when Open MPI is configured.} +% + \ssiparamentry{rpi\_\-sysv\_\-shmpoolsize}{From configure}{Size of + the shared memory pool for large messages. The default value is + calculated when Open MPI is configured.} +% + \ssiparamentry{rpi\_\-sysv\_\-short}{8192}{Maximum length (in bytes) + of a ``short'' message for sending via shared memory (i.e., + on-node). Directly affects the size of the allocated ``postbox'' + shared memory area.} +% + \ssiparamentry{rpi\_\-tcp\_\-short}{65535}{Maximum length + (in bytes) of a ``short'' message for sending via TCP sockets + (i.e., off-node).} +% + \ssiparamentry{rpi\_\-tcp\_\-sockbuf}{-1}{Socket buffering in the OS + kernel (-1 means use the short message size).} + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{sysv} RPI module.} + \label{tbl:mca-ompi-sysv-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{tcp} Module (TCP Communication)} +\label{sec:mca-ompi-tcp} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt tcp} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 20 \\ + {\bf Checkpoint / restart:} & no \\ + \hline +\end{tabular} +\vspace{11pt} + +The \rpi{tcp} RPI module uses TCP sockets for MPI point-to-point +communication. + +%%%%% + +\subsubsection{Tunable Parameters} + +Two different protocols are used to pass messages between processes: +short and long. Short messages are sent eagerly and will not block +unless the operating system blocks. Long messages use a rendezvous +protocol; the body of the message is not sent until a matching MPI +receive is posted. The crossover point between the short and long +protocol defaults to 64KB, but can be changed with the +\issiparam{rpi\_\-tcp\_\-short} MCA parameter, an integer specifying +the maximum size (in bytes) of a short message. +% +\changebegin{7.1} +% +Additionally, the amount of socket buffering requested of the kernel +defaults to the size of short messages. It can be altered with the +\issiparam{rpi\_\-tcp\_\-sockbuf} parameter. When this value is -1, +the value of the \issiparam{rpi\_\-tcp\_\-short} parameter is used. +Otherwise, its value is passed to the \func{setsockopt(2)} system call +to set the amount of operating system buffering on every socket that +is used for MPI communication. + +\changeend{7.1} + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-tcp\_\-priority}{20}{Default priority level.} +% + \ssiparamentry{rpi\_\-tcp\_\-short}{65535}{Maximum length + (in bytes) of a ``short'' message.} +% + \ssiparamentry{rpi\_\-tcp\_\-sockbuf}{-1}{Socket buffering in the OS + kernel (-1 means use the short message size).} + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{tcp} RPI module.} + \label{tbl:mca-ompi-tcp-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \rpi{usysv} Module (Shared Memory Using Spin Locks)} +\label{sec:mca-ompi-usysv} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt usysv} \\ + {\bf Kind:} & \kind{rpi} \\ + {\bf Default MCA priority:} & 40 \\ + {\bf Checkpoint / restart:} & no \\ + \hline +\end{tabular} +\vspace{11pt} + +The \rpi{usysv} RPI is the one of two combination shared-memory/TCP +message passing modules. Shared memory is used for passing messages +to processes on the same node; TCP sockets are used for passing +messages to processes on other nodes. Spin locks with back-off are +used for synchronization of the shared memory pool (a System V +semaphore or pthread mutex is also used for access to the per-node +shared memory pool). + +\changebegin{7.0.3} + +The nature of spin locks means that the \rpi{usysv} RPI will perform +poorly when there are more processes than processors (particularly in +blocking MPI communication calls). If no higher priority RPI modules +are available (e.g., Myrinet/\rpi{gm}) and the user does not select a +specific RPI module through the \ssiparam{rpi} MCA parameter, +\rpi{usysv} may be selected as the default -- even if there are more +processes than processors. Users should keep this in mind; in such +circumstances, it is probably better to manually select the \rpi{sysv} +or \rpi{tcp} RPI modules. + +\changeend{7.0.3} + +%%%%% + +\subsubsection{Overview} + +Aside from synchronization, the \rpi{usysv} RPI module is almost +identical to the \rpi{sysv} module. +% +The \rpi{usysv} module uses spin locks with back-off. When a process +backs off, it attempts to yield the processor. If the configure +script found a system-provided yield function,\footnote{Such as + \func{yield()} or \func{sched\_\-yield()}.} it is used. If no such +function is found, then \func{select()} on \const{NULL} file +descriptor sets with a timeout of 10us is used. + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-ompi-usysv-mca-params} shows the MCA parameters that +may be changed at run-time. Many of these parameters are identical to +their \rpi{sysv} counterparts and are not re-described here. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{rpi\_\-tcp\_\-short}{65535}{Maximum length + (in bytes) of a ``short'' message for sending via TCP sockets + (i.e., off-node).} +% + \ssiparamentry{rpi\_\-tcp\_\-sockbuf}{-1}{Socket buffering in the OS + kernel (-1 means use the short message size).} +% + \ssiparamentry{rpi\_\-usysv\_\-pollyield}{1}{Same as \rpi{sysv} + counterpart.} +% + \ssiparamentry{rpi\_\-usysv\_\-priority}{40}{Default priority level.} +% + \ssiparamentry{rpi\_\-usysv\_\-readlockpoll}{10,000}{Number of + iterations to spin before yielding the processing while waiting to + read.} +% + \ssiparamentry{rpi\_\-usysv\_\-shmmaxalloc}{From configure}{Same as + \rpi{sysv} counterpart.} +% + \ssiparamentry{rpi\_\-usysv\_\-shmpoolsize}{From configure}{Same as + \rpi{sysv} counterpart.} +% + \ssiparamentry{rpi\_\-usysv\_\-short}{8192}{Same as \rpi{sysv} + counterpart.} +% + \ssiparamentry{rpi\_\-usysv\_\-writelockpoll}{10}{Number of + iterations to spin before yielding the processing while waiting to + write.} + \end{ssiparamtb} + \caption{MCA parameters for the \rpi{usysv} RPI module.} + \label{tbl:mca-ompi-usysv-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI Collective Communication} +\label{sec:mca-ompi-coll} +\index{collective MCA modules|(} +\index{MPI collective modules|see {collective MCA modules}} +\index{MCA collective modules|see {collective MCA modules}} + +MPI collective communication functions have their basic functionality +outlined in the MPI standard. However, the implementation of this +functionality can be optimized and/or implemented in different ways. +As such, Open MPI provides modules for implementing the MPI collective +routines that are targeted for different environments. + +\begin{itemize} +\item Basic algorithms +\item SMP-optimized algorithms +\item Shared Memory algorithms +\end{itemize} + +These modules are discussed in detail below. Note that the sections +below each assume that support for these modules have been compiled +into Open MPI. The \icmd{laminfo} command can be used to determine +exactly which modules are supported in your installation (see +Section~\ref{sec:commands-laminfo}, +page~\pageref{sec:commands-laminfo}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Selecting a \kind{coll} Module} +\label{sec:mca-ompi-coll-select} +\index{collective MCA modules!selection process} + +\kind{coll} modules are selected on a per-communicator basis. Most +users will not need to override the \kind{coll} selection mechanisms; +the \kind{coll} modules currently included in Open MPI usually select +the best module for each communicator. However, mechanisms are +provided to override which \kind{coll} module will be selected on a +given communicator. + +When each communicator is created (including \mcw\ and \mcs), all +available \kind{coll} modules are queried to see if they want to be +selected. A \kind{coll} module may therefore be in use by zero or +more communicators at any given time. The final selection of which +module will be used for a given communicator is based on priority; the +module with the highest priority from the set of available modules +will be used for all collective calls on that communicator. + +Since the selection of which module to use is inherently dynamic and +potentially different for each communicator, there are two levels of +parameters specifying which modules should be used. The first level +specifies the overall set of \kind{coll} modules that will be +available to {\em all} communicators; the second level is a +per-communicator parameter indicating which specific module should be +used. + +The first level is provided with the \issiparam{coll} MCA parameter. +Its value is a comma-separated list of \kind{coll} module names. If +this parameter is supplied, only these modules will be queried at run +time, effectively determining the set of modules available for +selection on all communicators. If this parameter is not supplied, +all \kind{coll} modules will be queried. + +The second level is provided with the MPI attribute +\mpiattr{Open MPI\_\-MPI\_\-MCA\_\-COLL}. This attribute can be set to +the string name of a specific \kind{coll} module on a parent +communicator before a new communicator is created. If set, the +attribute's value indicates the {\em only} module that will be +queried. If this attribute is not set, all available modules are +queried. + +Note that no coordination is done between the MCA frameworks in each +MPI process to ensure that the same modules are available and/or are +selected for each communicator. Although \cmd{mpirun} allows +different environment variables to be exported to each MPI process, +and the value of an MPI attribute is local to each process, Open MPI's +behavior is undefined if the same MCA parameters are not available in +all MPI processes. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{\kind{coll} MCA Parameters} + +There are three parameters that apply to all \kind{coll} modules. +Depending on when their values are checked, they may be set by +environment variables, command line switches, or attributes on MPI +communicators. + +\begin{itemize} +\item \issiparam{coll\_\-base\_\-associative}: The MPI standard defines + whether reduction operations are commutative or not, but makes no + provisions for whether an operator is associative or not. This + parameter, if defined to 1, asserts that all reduction operations on + a communicator are assumed to be associative. If undefined or + defined to 0, all reduction operations are assumed to be + non-associative. + + This parameter is examined during every reduction operation. See + {\bf Commutative and Associative Reduction Operators}, below. + +\item \issiparam{coll\_\-crossover}: If set, define the maximum number + of processes that will be used with a linear algorithm. More than + this number of processes may use some other kind of algorithm. + + This parameter is only examined during \mpifunc{MPI\_\-INIT}. + +\item \issiparam{coll\_\-reduce\_\-crossover}: For reduction + operations, the determination as to whether an algorithm should be + linear or not is not based on the number of process, but rather by + the number of bytes to be transferred by each process. If this + parameter is set, it defines the maximum number of bytes transferred + by a single process with a linear algorithm. More than this number + of bytes may result in some other kind of algorithm. + + This parameter is only examined during \mpifunc{MPI\_\-INIT}. +\end{itemize} + +%%%%% + +\subsubsection{Commutative and Associative Reduction Operators} + +MPI-1 defines that all built-in reduction operators are commutative. +User-defined reduction operators can specify whether they are +commutative or not. The MPI standard makes no provisions for whether +a reduction operation is associative or not. +% +For some operators and datatypes, this distinction is largely +irrelevant (e.g., find the maximum in a set of integers). However, +for operations involving the combination of floating point numbers, +associativity and commutativity matter. An {\em Advice to + Implementors} note in MPI-1, section 4.9.1, 114:20, states: + +\begin{quote} + It is strongly recommended that \mpifunc{MPI\_\-REDUCE} be + implemented so that the same result be obtained whenever the + function is applied on the same arguments, appearing in the same + order. Note that this may prevent optimizations that take advantage + of the physical location of processors. +\end{quote} + +Some implementations of the reduction operations may specifically take +advantage of data locality, and therefore assume that the reduction +operator is associative. +% +As such, Open MPI will always take the conservative approach to reduction +operations and fall back to non-associative algorithms (e.g., +\coll{lam\_\-basic}) for the reduction operations unless specifically +told to use associative (SMP-optimized) algorithms by setting the MCA +parameter \issiparam{coll\_\-base\_\-associative} to 1. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \coll{lam\_\-basic} Module} +\index{collective MCA modules!lam\_basic@\coll{lam\_\-basic}} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt lam\_\-basic} \\ + {\bf Kind:} & \kind{coll} \\ + {\bf Default MCA priority:} & 0 \\ + {\bf Checkpoint / restart:} & yes \\ + \hline +\end{tabular} +\vspace{11pt} + +The \coll{lam\_\-basic} module provides simplistic algorithms for each +of the MPI collectives that are layered on top of point-to-point +functionality.\footnote{The basic algorithms are the same that have + been included in Open MPI since at least version 6.2.} It can be +used in any environment. Its priority is sufficiently low that it +will be chosen if no other \kind{coll} module is available. + +Many of the algorithms are twofold: for $N$ or less processes, linear +algorithms are used. For more than $N$ processes, binomial algorithms +are used. No attempt is made to determine the locality of processes, +however -- the \coll{lam\_\-basic} module effectively assumes that +there is equal latency between all processes. All reduction +operations are performed in a strictly-defined order; associativity is +not assumed. + +\subsubsection{Collectives for Intercommunicators} + +As of now, only \coll{lam\_\-basic} module supports intercommunicator +collectives according to the MPI-2 standard. These algorithms are +built over point-to-point layer and they also make use of an +intra-communicator collectives with the help of intra-communicator +corresponding to the local group. Mapping among the intercommunicator +and corresponding local-intracommunicator is separately managed in the +\coll{lam\_\-basic} module. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \coll{smp} Module} +\index{collective MCA modules!smp@\coll{smp}} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt smp} \\ + {\bf Kind:} & \kind{coll} \\ + {\bf Default MCA priority:} & 50 \\ + {\bf Checkpoint / restart:} & yes \\ + \hline +\end{tabular} +\vspace{11pt} + +The \coll{smp} module is geared towards SMP nodes in a LAN. Heavily +inspired by the MagPIe +algorithms~\cite{kielmann++:00:magpie_bandwidth}, the \coll{smp} +module determines the locality of processes before setting up a +dynamic structure in which to perform the collective function. +Although all communication is still layered on MPI point-to-point +functions, the algorithms attempt to maximize the use of on-node +communication before communicating with off-node processes. This +results in lower overall latency for the collective operation. + +The \coll{smp} module assumes that there are only two levels of +latency between all processes. As such, it will only allow itself to +be available for selection when there are at least two nodes in a +communicator and there are at least two processes on the same +node.\footnote{As a direct result, \coll{smp} will never be selected + for \mcs.} + +Only some of the collectives have been optimized for SMP environments. +Table~\ref{tbl:mca-ompi-coll-smp-algorithms} shows which collective +functions have been optimized, which were already optimal (from the +\coll{lam\_\-basic} module), and which will eventually be optimized. + +\def\lbid{Identical to \coll{lam\_\-basic} algorithm; already + optimized for SMP environments.} +\def\smpopt{Optimized for SMP environments.} +\def\smpnoopt{Not yet optimized for SMP environments; uses + \coll{lam\_\-basic} algorithm instead.} + +\begin{table}[htbp] + \centering + \begin{tabular}{|l|p{3.7in}|} + \hline + \multicolumn{1}{|c|}{MPI function} & + \multicolumn{1}{|c|}{Status} \\ + \hline + \hline + \mpifunc{MPI\_\-ALLGATHER} & \smpopt \\ + \hline + \mpifunc{MPI\_\-ALLGATHERV} & \smpopt \\ + \hline + \mpifunc{MPI\_\-ALLREDUCE} & \smpopt \\ + \hline + \mpifunc{MPI\_\-ALLTOALL} & \lbid \\ + \hline + \mpifunc{MPI\_\-ALLTOALLV} & \lbid \\ + \hline + \mpifunc{MPI\_\-ALLTOALLW} & lbid. \\ + \hline + \mpifunc{MPI\_\-BARRIER} & \smpopt \\ + \hline + \mpifunc{MPI\_\-BCAST} & \smpopt \\ + \hline + \mpifunc{MPI\_\-EXSCAN} & lbid. \\ + \hline + \mpifunc{MPI\_\-GATHER} & \lbid \\ + \hline + \mpifunc{MPI\_\-GATHERV} & \lbid \\ + \hline + \mpifunc{MPI\_\-REDUCE} & \smpopt \\ + \hline + \mpifunc{MPI\_\-REDUCE\_\-SCATTER} & \smpopt \\ + \hline + \mpifunc{MPI\_\-SCAN} & \smpopt \\ + \hline + \mpifunc{MPI\_\-SCATTER} & \lbid \\ + \hline + \mpifunc{MPI\_\-SCATTERV} & \lbid \\ + \hline + \end{tabular} + \caption{Listing of MPI collective functions indicating which have + been optimized for SMP environments.} + \label{tbl:mca-ompi-coll-smp-algorithms} +\end{table} + +%%%%% + +\subsubsection{Special Notes} + +Since the goal of the SMP-optimized algorithms attempt to take +advantage of data locality, it is strongly recommended to maximize the +proximity of \mcw\ rank neighbors on each node. The \cmdarg{C} +nomenclature to \cmd{mpirun} can ensure this automatically. + +Also, as a result of the data-locality exploitation, the +\issiparam{coll\_\-base\_\-associative} parameter is highly relevant -- if it +is not set to 1, the \coll{smp} module will fall back to the +\coll{lam\_\-basic} reduction algorithms. + +\index{collective MCA modules|)} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\changebegin{7.1} + +\subsection{The \coll{shmem} Module} +\index{collective MCA modules!shmem@\coll{shmem}} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt shmem} \\ + {\bf Kind:} & \kind{coll} \\ + {\bf Default MCA priority:} & 50 \\ + {\bf Checkpoint / restart:} & yes \\ + \hline +\end{tabular} +\vspace{11pt} + +The \coll{shmem} module is developed to facilitate fast collective +communication among processes on a single node. Processes on a N-way +SMP node can take advantage of the shared memory for message +passing. The module will be selected only if the communicator spans +over a single node and the all the processes in the communicator can +successfully attach the shared memory region to their address space. + +The shared memory region consists two disjoint sections. First section +of the shared memory is used for synchronization among the processes +while the second section is used for message passing (Copying data +into and from shared memory). + +The second section is known as \const{MESSAGE\_POOL} and is divided +into N equal segments. Default value of $N$ is 8 and is configurable +with the \issiparam{coll\_base\_shmem\_num\_segments} MCA +parameter. The size of the \const{MESSAGE\_POOL} can be also configured +with the \issiparam{coll\_base\_shmem\_message\_pool\_size} MCA +parameter. Default size of the \const{MESSAGE\_POOL} is $(16384 \times +8)$. + +The first section is known as \const{CONTROL\_SECTION} and it is +logicallu divided into $(2 \times N + 2)$ segments. $N$ is the number +of segments in the \const{MESSAGE\_POOL} section. Total size of this +section is: + +\[ +((2 \times N) + 2) \times C \times S +\] + +Where $C$ is the cache line size, $S$ is the size of the communicator. +Shared variabled for synchronization are placed in different +\const{CACHELINE} for each processes to prevent trashing due to cache +invalidation. + +%%%%% + +\subsubsection{General Logic behind Shared Memory Management} + +Each segment in the \const{MESSAGE\_POOL} corresponds to {\em TWO} +segments in the \const{CONTROL\_SECTION}. Whenever a particular segment +in \const{MESSAGE\_POOL} is active, its corresponding segments in the +\const{CONTROL\_SECTION} are used for synchronization. Processes can +operate on one segment (Copy the messages), set appropriate +synchronizattion variables and can continue with the next message +segment. This approach improves performance of the collective +algorithms. All the process need to complete a \mpifunc{MPI\_BARRIER} + at the last (Default 8th) segment to prevent race conditions. The + extra 2 segments in the \const{CONTROL\_SECTION} are used exclusively + for explicit \mpifunc{MPI\_BARRIER}. + +Only some of the collectives have been optimized for SMP environments. +Table~\ref{tbl:mca-ompi-coll-shmem-algorithms} shows which collective +functions have been optimized, which were already optimal (from the +\coll{lam\_\-basic} module), and which will eventually be optimized. + +%%%%% + +\subsubsection{List of Algorithms} + +Only some of the collectives have been implemented using shared memory +Table~\ref{tbl:mca-ompi-coll-shmem-algorithms} shows which collective +functions have been implemented and which uses \coll{lam\_\-basic} +module) + +\def\shmemopt{Implemented using shared memory.} +\def\shmemnoopt{Uses \coll{lam\_\-basic} algorithm.} + +\begin{table}[htbp] + \centering + \begin{tabular}{|l|p{3.7in}|} + \hline + \multicolumn{1}{|c|}{MPI function} & + \multicolumn{1}{|c|}{Status} \\ + \hline + \hline + \mpifunc{MPI\_\-ALLGATHER} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-ALLGATHERV} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-ALLREDUCE} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-ALLTOALL} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-ALLTOALLV} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-ALLTOALLW} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-BARRIER} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-BCAST} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-EXSCAN} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-GATHER} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-GATHERV} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-REDUCE} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-REDUCE\_\-SCATTER} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-SCAN} & \shmemnoopt \\ + \hline + \mpifunc{MPI\_\-SCATTER} & \shmemopt \\ + \hline + \mpifunc{MPI\_\-SCATTERV} & \shmemnoopt \\ + \hline + \end{tabular} + \caption{Listing of MPI collective functions indicating which have + been implemented using Shared Memory} + \label{tbl:mca-ompi-coll-shmem-algorithms} +\end{table} + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-ompi-shmem-mca-params} shows the MCA parameters that +may be changed at run-time. Each of these parameters were discussed +in the previous sections. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{coll\_\-base\_\-shmem\_\-message\_\-pool\_\-size}{$16384 + \times 8$}{Size of the shared memory pool for the messages.} +% + \ssiparamentry{coll\_\-base\_\-shmem\_\-num\_\-segments}{8}{Number + of segments in the message pool section.} + \end{ssiparamtb} + \caption{MCA parameters for the \coll{shmem} \kind{coll} module.} + \label{tbl:mca-ompi-shmem-mca-params} +\end{table} + +%%%%% + +\subsubsection{Special Notes} + +Open MPI provides \rpi{sysv} and \rpi{usysv} RPI for the intra\-node +communication. In this case, the collective communication also +happens through the shared memory but indirectly in terms of Sends and +Recvs. Shared Memory Collective algorithms avoid all the overhead +associated with the indirection and provide a minimum blocking way for +the collective operations. + +The shared memory is created by only one process in the communicator +and rest of the processes simply attach the shared memory region to +their address space. The process which finalizes last, hands back the +shared memory region to the kernel while processes leaving before +simply detach the shared memory region from their address space. + +\index{collective MCA modules|)} + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Checkpoint/Restart of MPI Jobs} +\label{sec:mca-ompi-cr} +\index{checkpoint/restart MCA modules|(} + +Open MPI supports the ability to involuntarily checkpoint and restart +parallel MPI jobs. Due to the asynchronous nature of the +checkpoint/restart design, such jobs must run with a thread level of +at least \mpiconst{MPI\_\-THREAD\_\-SERIALIZED}. This allows the +checkpoint/restart framework to interrupt the user's job for a +checkpoint regardless of whether it is performing message passing +functions or not in the MPI communications layer. + +Open MPI does not provide checkpoint/restart functionality itself; +\kind{cr} MCA modules are used to invoke back-end systems that save +and restore checkpoints. The following notes apply to checkpointing +parallel MPI jobs: + +\begin{itemize} +\item No special code is required in MPI applications to take + advantage of Open MPI's checkpoint/restart functionality, although + some limitations may be imposed (depending on the back-end + checkpointing system that is used). + +\item Open MPI's checkpoint/restart functionality {\em only} involves MPI + processes; the Open MPI universe is not checkpointed. A Open MPI universe + must be independently established before an MPI job can be restored. + +\item Open MPI does not yet support checkpointing/restarting MPI-2 + applications. In particular, Open MPI's behavior is undefined when + checkpointing MPI processes that invoke any non-local MPI-2 + functionality (including dynamic functions and IO). + +\item Migration of restarted processes is available on a limited + basis; the \rpi{crtcp} RPI will start up properly regardless of what + nodes the MPI processes are re-started on, but other system-level + resources may or may not be restarted properly (e.g., open files, + shared memory, etc.). + +\changebegin{7.1} +\item Checkpoint files are saved using a two-phase commit protocol that is + coordinated by \cmd{mpirun}. \cmd{mpirun} initiates a checkpoint request + for each process in the MPI job by supplying a temporary context filename. + If all the checkpoint requests completed successfully, the saved context + files are renamed to their respective target filenames; otherwise, the + checkpoint files are discarded. +\changeend{7.1} + +\item Checkpoints can only be performed after all processes have + invoked \mpifunc{MPI\_\-INIT} and before any process has invoked + \mpifunc{MPI\_\-FINALIZE}. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Selecting a \kind{cr} Module} +\index{checkpoint/restart MCA modules!selection process} + +The \kind{cr} framework coordinates with all other MCA modules to +ensure that the entire MPI application is ready to be checkpointed +before the back-end system is invoked. Specifically, for a parallel +job to be able to checkpoint and restart, all the MCA modules that it +uses must support checkpoint/restart capabilities. + +All \kind{coll} modules in the Open MPI distribution currently support +checkpoint/restart capability because they are layered on MPI +point-to-point functionality -- as long as the RPI module being used +supports checkpoint/restart, so do the \kind{coll} modules. +% +However, only one RPI module currently supports checkpoint/restart: +\rpi{crtcp}. Attempting to checkpoint an MPI job when using any other +\kind{rpi} module will result in undefined behavior. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{\kind{cr} MCA Parameters} + +The \issiparam{cr} MCA parameter can be used to specify which +\kind{cr} module should be used for an MPI job. An error will occur +if a \kind{cr} module is requested and an \kind{rpi} or \kind{coll} +module cannot be found that supports checkpoint/restart functionality. + +Additionally, the \issiparam{cr\_\-base\_\-dir} MCA parameter can be +used to specify the directory where checkpoint file(s) will be saved. +If it is not set, and no default value was provided when Open MPI was +configured (with the \confflag{with-cr-file-dir} flag) the user's home +directory is used. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \crssi{blcr} Module} +\index{Berkeley Lab Checkpoint/Restart single-node checkpointer} +\index{blcr checkpoint/restart MCA module@\crssi{blcr} checkpoint/restart MCA module} +\index{checkpoint/restart MCA modules!blcr@\crssi{blcr}} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt blcr} \\ + {\bf Kind:} & \kind{cr} \\ + {\bf Default MCA priority:} & 50 \\ + {\bf Checkpoint / restart:} & yes \\ + \hline +\end{tabular} +\vspace{11pt} + +Berkeley Lab's Checkpoint/Restart (BLCR)~\cite{BLCR02} single-node +checkpointer provides the capability for checkpointing and restarting +processes under Linux. The \crssi{blcr} module, when used with +checkpoint/restart MCA modules, will invoke the BLCR system to save +and restore checkpoints. + +%%%%% + +\subsubsection{Overview} + +The \crssi{blcr} module will only automatically be selected when the +thread level is \mpiconst{MPI\_\-THREAD\_\-SERIALIZED} and all +selected MCA modules support checkpoint/restart functionality (see the +MCA module selection algorithm, +Section~\ref{sec:mca-ompi-component-selection}, +page~\pageref{sec:mca-ompi-component-selection}). The \crssi{blcr} module +can be specifically selected by setting the \ssiparam{cr} MCA +parameter to the value \issivalue{cr}{blcr}. Manually selecting the +\crssi{blcr} module will force the MPI thread level to be at least +\mpiconst{MPI\_\-THREAD\_\-SERIALIZED}. + +%%%%% + +\subsubsection{Running a Checkpoint/Restart-Capable MPI Job} + +There are multiple ways to run a job with checkpoint/restart support: + +\begin{itemize} +\item Use the \rpi{crtcp} RPI, and invoke + \mpifunc{MPI\_\-INIT\_\-THREAD} with a requested thread level of + \mpiconst{MPI\_\-THREAD\_\-SERIALIZED}. This will automatically + make the \crssi{blcr} module available. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -ssi rpi crtcp my_mpi_program +\end{lstlisting} + % stupid emacs mode: $ + +\item Use the \rpi{crtcp} RPI and manually select the \crssi{blcr} + module: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -ssi rpi crtcp -ssi cr blcr my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ +\end{itemize} + +\changebegin{7.0.5} + +Depending on the location of the BLCR shared library, it may be +necessary to use the \ienvvar{LD\_\-LIBRARY\_\-PATH} environment +variable to specify where it can be found. Specifically, if the BLCR +library is not in the default path searched by the linker, errors will +occur at run time because it cannot be found. In such cases, adding +the directory where the \file{libcr.so*} file(s) can be found to the +\ienvvar{LD\_\-LIBRARY\_\-PATH} environment variable {\em on all nodes + where the MPI application will execute} will solve the problem. +% +Note that this may entail editing user's ``dot'' files to augment the +\ienvvar{LD\_\-LIBRARY\_\-PATH} variable.\footnote{Ensure to see + Section~\ref{sec:getting-started-path} for details about which + shell startup files should be edited. Also note that + shell startup files are {\em only} read when starting the Open MPI + universe. Hence, if you change values in shell startup files, you + will likely need to re-invoke the \icmd{lamboot} command to put your + changes into effect.} For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +# ...edit user's shell startup file to augment LD_LIBRARY_PATH... +shell$ lamboot hostfile +shell$ mpirun C -ssi rpi crtcp -ssi cr blcr my_mpi_program +\end{lstlisting} + +Alternatively, the ``\cmd{-x}'' option to \icmd{mpirun} can be used to +export the \ienvvar{LD\_\-LIBRARY\_\-PATH} environment variable to all +MPI processes. For example (Bourne shell and derrivates): + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ LD_LIBRARY_PATH=/location/of/blcr/lib:$LD_LIBRARY_PATH +shell$ export LD_LIBRARY_PATH +shell$ mpirun C -ssi rpi crtcp -ssi cr blcr -x LD_LIBRARY_PATH my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +For C shell and derivates: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell% setenv LD_LIBRARY_PATH /location/of/blcr/lib:$LD_LIBRARY_PATH +shell% mpirun C -ssi rpi crtcp -ssi cr blcr -x LD_LIBRARY_PATH my_mpi_program +\end{lstlisting} + +\changeend{7.0.5} + +%%%%% + +\subsubsection{Checkpointing and Restarting} + +Once a checkpoint-capable job is running, the BLCR command +\icmd{cr\_\-checkpoint} can be used to invoke a checkpoint. Running +\cmd{cr\_\-checkpoint} with the PID of \cmd{mpirun} will cause a +context file to be created for \cmd{mpirun} as well as a context file +for each running MPI process. Before it is checkpointed, \cmd{mpirun} +will also create an application schema file to assist in restoring the +MPI job. These files will all be created in the directory specified +by Open MPI's configured default, the \issiparam{cr\_\-base\_\-dir}, or +the user's home directory if no default is specified. + +The BLCR \icmd{cr\_\-restart} command can then be invoked with the PID +and context file generated from \cmd{mpirun}, which will restore the +entire MPI job. + +%%%%% + +\subsubsection{Tunable Parameters} + +There are no tunable parameters to the \crssi{blcr} \kind{cr} module. + +%%%%% + +\subsubsection{Known Issues} + +\begin{itemize} +\item BLCR has its own limitations (e.g., BLCR does not yet support + saving and restoring file descriptors); see the documentation + included in BLCR for further information. Check the project's main + web site\footnote{\url{http://ftg.lbl.gov/}} to find out more about + BLCR. + +\changebegin{7.1} +\item Since a checkpoint request is initiated by invoking + \cmd{cr\_checkpoint} with the PID of \cmd{mpirun}, it is not + possible to checkpoint MPI jobs that were started using the + \cmdarg{-nw} option to \cmd{mpirun}, or directly from the + command-line without using \cmd{mpirun}. + +\item While the two-phase commit protocol that is used to save + checkpoints provides a reasonable guarantee of consistency of saved + global state, there is at least one case in which this guarantee + fails. For example, the renaming of checkpoint files by + \cmd{mpirun} is not atomic; if a failure occurs when \cmd{mpirun} is + in the process of renaming the checkpoint files, the collection of + checkpoint files might result in an inconsistent global state. + +\item If the BLCR module(s) are compiled dynamically, the + \ienvvar{LD\_\-PRELOAD} environment variable must include the + location of the \ifile{libcr.so} library. This is to ensure that + \ifile{libcr.so} is loaded before the PThreads library. +\changeend{7.1} + +\end{itemize} + + +\changebegin{7.1} +\subsection{The \crssi{self} Module} + +\begin{tabular}{rl} + \multicolumn{2}{c}{Module Summary} \\ + \hline + {\bf Name:} & {\tt blcr} \\ + {\bf Kind:} & \kind{cr} \\ + {\bf Default MCA priority:} & 25 \\ + {\bf Checkpoint / restart:} & yes \\ + \hline +\end{tabular} +\vspace{11pt} + +The \crssi{self} module, when used with checkpoint/restart MCA modules, will +invoke the user-defined functions to save and restore checkpoints. + +%%%%% + +\subsubsection{Overview} + +The \crssi{self} module can be specifically selected by setting the +\ssiparam{cr} MCA parameter to the value \issivalue{cr}{self}. Manually +selecting the \crssi{self} module will force the MPI thread level to be at +least \mpiconst{MPI\_\-THREAD\_\-SERIALIZED}. + +%%%%% + +\subsubsection{Running a Checkpoint/Restart-Capable MPI Job} + +Use the \rpi{crtcp} RPI and manually select the \crssi{self} module: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -ssi rpi crtcp -ssi cr self my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +%%%%% + +\subsubsection{Checkpointing and Restarting} + +The names of the Checkpoint, Restart and Continue functions can be specified +in one of the following ways: + +\begin{itemize} + \item Use the \ssiparam{cr\_\-self\_\-user\_\-prefix} to specify a prefix. This will + cause Open MPI to assume that the Checkpoint, Restart and Continue functions + are prefix\_checkpoint, prefix\_restart and prefix\_continue respectively, + where prefix is the value of the \ssiparam{cr\_\-self\_\-user\_\-prefix} MCA parameter. + + \item To specify the names of the Checkpoint, Restart and Continue functions + separately, use the \ssiparam{cr\_\-self\_\-user\_\-checkpoint}, + \ssiparam{cr\_\-ssi\_\-user\_\-restart} and the + \ssiparam{cr\_\-self\_\-user\_\-continue} MCA parameters respectively. In + case both the \ssiparam{cr\_\-ssi\_\-user\_\-prefix} and any of these + above three parameters are specified, these parameters are given higher preference. + + +\end{itemize} + +%%%%% + +In case none of the above four parameters are supplied, and the \crssi{self} +module is selected, \cmd{mpirun} aborts with the error message indicating +that symbol-lookup failed. \cmd{mpirun} also aborts in case any of the +Checkpoint, Restart or Continue functions is not found in the MPI application. + +Once a checkpoint-capable job is running, the Open MPI command +\cmd{lamcheckpoint} can be used to invoke a checkpoint. Running +\cmd{lamcheckpoint} with the PID of \cmd{mpirun} will cause the user-defined +Checkpoint function to be invoked. Before it is checkpointed, \cmd{mpirun} +will also create an application schema file to assist in restoring the +MPI job. These files will all be created in the directory specified +by Open MPI's configured default, the \issiparam{cr\_\-base\_\-dir}, or +the user's home directory if no default is specified. + +\cmd{lamboot} can be used to restart an MPI application. In case the +\crssi{self} module is selected the second argument to \cmd{lamboot} is the +set of arguments to be passed to the new \cmd{mpirun}. +%%%%% + +\subsubsection{Tunable Parameters} + +There are no tunable parameters to the \crssi{self} \kind{cr} module. + +%%%%% + +\subsubsection{Known Issues} + +\begin{itemize} + +\item Since a checkpoint request is initiated by invoking + \cmd{lamcheckpoint} with the PID of \cmd{mpirun}, it is not possible to + checkpoint MPI jobs that were started using the \cmdarg{-nw} option to + \cmd{mpirun}, or directly from the command-line without using \cmd{mpirun}. + +\end{itemize} +\changeend{7.1} + +\index{checkpoint/restart MCA modules|)} +\index{checkpoint/restart MCA modules|)} diff --git a/doc/user/mca-orte.tex b/doc/user/mca-orte.tex new file mode 100644 index 0000000000..1087cee0c0 --- /dev/null +++ b/doc/user/mca-orte.tex @@ -0,0 +1,852 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Available ORTE Components} +\label{sec:mca-orte} + +There is currently only type of ORTE component that is visible to +users: \kind{boot}, which is used to start the Open MPI run-time +environment, most often through the \icmd{lamboot} command. The +\cmd{lamboot} command itself is discussed in +Section~\ref{sec:commands-lamboot} +(page~\pageref{sec:commands-lamboot}); the discussion below focuses on +the boot modules that make up the ``back end'' implementation of +\cmd{lamboot}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Using the Open Run-Time Environment} +\label{sec:mca-orte-pls} +\index{ORTE MCA components|(} +\index{MCA boot components|see {boot MCA components}} + +{\Huge JMS needs massive overhaul} + +Open MPI provides a number of modules for starting the \cmd{lamd} +control daemons. In most cases, the \cmd{lamd}s are started using the +\icmd{lamboot} command. In previous versions of Open MPI, +\icmd{lamboot} could only use \icmd{rsh} or \icmd{ssh} for starting +the Open MPI run-time environment on remote nodes. In Open MPI +\ompiversion, it is possible to use a variety of mechanisms for this +process startup. The following mechanisms are available in Open MPI +\ompiversion: + +\begin{itemize} +\item BProc +\item Globus (beta-level support) +\item \cmd{rsh} / \cmd{ssh} +\item OpenPBS / PBS Pro / Torque (using the Task Management interface) +\changebegin{7.1} +\item SLURM (using its native interface) +\changeend{7.1} +\end{itemize} + +These mechanisms are discussed in detail below. Note that the +sections below each assume that support for these modules have been +compiled into Open MPI. The \icmd{laminfo} command can be used to +determine exactly which modules are supported in your installation +(see Section~\ref{sec:commands-laminfo}, +page~\pageref{sec:commands-laminfo}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Boot Schema Files (a.k.a., ``Hostfiles'' or + ``Machinefiles'')} +\label{sec:mca-orte-pls-schema} +\index{boot schema} +\index{hostfile|see {boot schema}} +\index{machinefile|see {boot schema}} +\cmdindex{lamboot}{boot schema file} + +Before discussing any of the specific boot MCA modules, this section +discusses the boot schema file, commonly referred to as a ``hostfile'' +or a ``machinefile''. Most (but not all) boot MCA modules require a +boot schema, and the text below makes frequent mention of them. +Hence, it is worth discussing them before getting into the details of +each boot MCA. + +A boot schema is a text file that, in its simplest form, simply lists +every host that the Open MPI run-time environment will be invoked on. For +example: + +\lstset{style=lam-shell} +\begin{lstlisting} +# This is my boot schema +inky.cluster.example.com +pinky.cluster.example.com +blinkly.cluster.example.com +clyde.cluster.example.com +\end{lstlisting} + +Lines beginning with ``{\tt \#}'' are treated as comments and are +ignored. Each non-blank, non-comment line must, at a minimum, list a +host. Specifically, the first token on each line must specify a host +(although the definition of how that host is specified may vary differ +between boot modules). + +However, each line can also specify arbitrary ``key=value'' pairs. A +common global key is ``{\tt cpu}''. This key takes an integer value +and indicates to Open MPI how many CPUs are available for Open MPI to use. If +the key is not present, the value of 1 is assumed. This number does +{\em not} need to reflect the physical number of CPUs -- it can be +smaller then, equal to, or greater than the number of physical CPUs in +the machine. It is solely used as a shorthand notation for +\icmd{mpirun}'s ``C'' notation, meaning ``launch one process per CPU +as specified in the boot schema file.'' For example, in the following +boot schema: + +\lstset{style=lam-shell} +\begin{lstlisting} +inky.cluster.example.com cpu=2 +pinky.cluster.example.com cpu=4 +blinkly.cluster.example.com cpu=4 +# clyde doesn't mention a cpu count, and is therefore implicitly 1 +clyde.cluster.example.com +\end{lstlisting} + +\noindent issuing the command ``{\tt mpirun C foo}'' would actually +launch 11 copies of \cmd{foo}: 2 on \host{inky}, 4 on \host{pinky}, 4 +on \host{blinky}, and 1 on \host{clyde}. + +Note that listing a host more than once has the same effect as +incrementing the CPU count. The following boot schema has the same +effect as the previous example (i.e., CPU counts of 2, 4, 4, and 1, +respectively): + +\lstset{style=lam-shell} +\begin{lstlisting} +# inky has a CPU count of 2 +inky.cluster.example.com +inky.cluster.example.com +# pinky has a CPU count of 4 +pinky.cluster.example.com +pinky.cluster.example.com +pinky.cluster.example.com +pinky.cluster.example.com +# blinky has a CPU count of 4 +blinkly.cluster.example.com +blinkly.cluster.example.com +blinkly.cluster.example.com +blinkly.cluster.example.com +# clyde only has 1 CPU +clyde.cluster.example.com +\end{lstlisting} + +Other keys are defined on a per-boot-MCA-module, and are described +below. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Minimum Requirements} +\label{sec:mca-orte-pls-min-reqs} + +In order to successfully launch a process on a remote node, several +requirements must be met. Although each of the boot modules have +different specific requirements, all of them share the following +conditions for successful operation: + +\begin{enumerate} +\item Each target host must be reachable and operational. + +\item The user must be able to execute arbitrary processes on the + target. + +\item The Open MPI executables must be locatable on that machine. This + typically involves using: the shell's search path, the + \ienvvar{Open MPIHOME} environment variable, or a boot-module-specific + mechanism. + +\item The user must be able to write to the Open MPI session directory + (typically somewhere under \file{/tmp}; see + Section~\ref{sec:misc-session-directory}, + page~\pageref{sec:misc-session-directory}). + +\item All hosts must be able to resolve the fully-qualified domain + name (FQDN) of all the machines being booted (including itself). + +\item Unless there is only one host being booted, any host + resolving to the IP address 127.0.0.1 cannot be included in the list + of hosts. +\end{enumerate} + +If all of these conditions are not met, \cmd{lamboot} will fail. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Selecting a \kind{boot} Module} + +Only one \kind{boot} module will be selected; it will be used for the +life of the Open MPI universe. As such, module priority values are the +only factor used to determine which available module should be +selected. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{\kind{boot} MCA Parameters} + +On many kinds of networks, Open MPI can know exactly which nodes should be +making connections while booting the Open MPI run-time environment, and +promiscuous connections (i.e., allowing any node to connect) are +discouraged. However, this is not possible in some complex network +configurations and promiscuous connections {\em must} be enabled. + +By default, Open MPI's base \kind{boot} MCA startup protocols disable +promiscuous connections. However, this behavior can be overridden +when Open MPI is configured and at run-time. If the MCA parameter +\issiparam{boot\_\-base\_\-promisc} set to an empty value, or set to +the integer value 1, promiscuous connections will be accepted when +than Open MPI RTE is booted. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \boot{bproc} Module} +\index{bproc boot MCA module@\boot{bproc} boot MCA module} +\index{boot MCA modules!bproc@\boot{bproc}} + +The Beowulf Distributed Process Space (BProc) +project\footnote{\url{http://bproc.sourceforge.net/}} is set of kernel +modifications, utilities and libraries which allow a user to start +processes on other machines in a Beowulf-style cluster. Remote +processes started with this mechanism appear in the process table of +the front-end machine in a cluster. + +Open MPI functionality has been tested with BProc version 3.2.5. Prior +versions had a bug that affected at least some Open MPI functionality. +It is strongly recommended to upgrade to at least version 3.2.5 before +attempting to use the Open MPI native BProc capabilities. + +%%%%% + +\subsubsection{Minimum Requirements} + +Several of the minimum requirements listed in +Section~\ref{sec:mca-orte-pls-min-reqs} will already be met in a BProc +environment because BProc will copy \cmd{lamboot}'s entire environment +(including the \envvar{PATH}) to the remote node. Hence, if +\cmd{lamboot} is in the user's path on the local node, it will also +[automatically] be in the user's path on the remote node. + +However, one of the minimum requirements conditions (``The user must +be able to execute arbitrary processes on the target'') deserves a +BProc-specific clarification. BProc has its own internal permission +system for determining if users are allowed to execute on specific +nodes. The system is similar to the user/group/other mechanism +typically used in many Unix filesystems. Hence, in order for a user +to successfully \cmd{lamboot} on a BProc cluster, he/she must have +BProc execute permissions on each of the target nodes. Consult the +BProc documentation for more details. + +%%%%% + +\subsubsection{Usage} + +In most situations, the \cmd{lamboot} command (and related commands) +should automatically ``know'' to use the \boot{bproc} boot MCA module +when running on the BProc head node; no additional command line +parameters or environment variables should be required. +% +Specifically, when running in a BProc environment, the \boot{bproc} +module will report that it is available, and artificially inflate its +priority relatively high in order to influence the boot module +selection process. +% +However, the BProc boot module can be forced by specifying the +\issiparam{boot} MCA parameter with the value of +\issivalue{boot}{bproc}. + +Running \cmd{lamboot} on a BProc cluster is just like running +\cmd{lamboot} in a ``normal'' cluster. Specifically, you provide a +boot schema file (i.e., a list of nodes to boot on) and run +\cmd{lamboot} with it. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot hostfile +\end{lstlisting} +% stupid emacs mode: $ + +Note that when using the \boot{bproc} module, \cmd{lamboot} will only +function properly from the head node. If you launch \cmd{lamboot} +from a client node, it will likely either fail outright, or fall back +to a different boot module (e.g., \cmd{rsh}/\cmd{ssh}). + +It is suggested that the \file{hostfile} file contain hostnames in the +style that BProc prefers -- integer numbers. For example, +\file{hostfile} may contain the following: + +\lstset{style=lam-shell} +\begin{lstlisting} +-1 + 0 + 1 + 2 + 3 +\end{lstlisting} + +\noindent which boots on the BProc front end node (-1) and four slave +nodes (0, 1, 2, 3). Note that using IP hostnames will also work, but +using integer numbers is recommended. + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-orte-pls-bproc-mca-params} lists the MCA parameters +that are available to the \boot{bproc} module. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{boot\_\-bproc\_\-priority}{50}{Default priority level.} + \end{ssiparamtb} + \caption{MCA parameters for the \boot{bproc} boot module.} + \label{tbl:mca-orte-pls-bproc-mca-params} +\end{table} + +%%%%% + +\subsubsection{Special Notes} + +After booting, Open MPI will, by default, not schedule to run MPI jobs on +the BProc front end. Specifically, Open MPI implicitly sets the +``no-schedule'' attribute on the -1 node in a BProc cluster. See +Section~\ref{sec:commands-lamboot} +(page~\pageref{sec:commands-lamboot}) for more detail about this +attribute and boot schemas in general, and +\ref{sec:commands-lamboot-no-schedule} (page +\pageref{sec:commands-lamboot-no-schedule}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \boot{globus} Module} +\index{globus boot MCA module@\boot{globus} boot MCA module} +\index{boot MCA modules!globus@\boot{globus}} + +Open MPI \ompiversion\ includes beta support for Globus. +Specifically, only limited types of execution are possible. The Open +MPI Team would appreciate feedback from the Globus community on +expanding Globus support in Open MPI. + +%%%%% + +\subsubsection{Minimum Requirements} + +Open MPI jobs in Globus environment can only be started on nodes using +the ``fork'' job manager for the Globus gatekeeper. Other job +managers are not yet supported. + +%%%%% + +\subsubsection{Usage} + +Starting the Open MPI run-time environmetn in Globus environment makes use +of the Globus Resource Allocation Manager (GRAM) client +\icmd{globus-job-run}. +% +The Globus boot MCA module will never run automatically; it must +always be specifically requested setting the \issiparam{boot} MCA +parameter to \issivalue{boot}{globus}. Specifically, although the +\boot{globus} module will report itself available if +\icmd{globus-job-run} can be found in the \envvar{PATH}, the default +priority will be quite low, effectively ensuring that it will not be +selected unless it is the only module available (which will only occur +if the \ssiparam{boot} parameter is set to \issivalue{boot}{globus}). + +Open MPI needs to be able to find the Globus executables. This can be +accompilshed either by adding the appropriate directory to your path, +or by setting the \ienvvar{GLOBUS\_\-LOCATION} environment variable. + +Additionally, the \ienvvar{Open MPI\_\-MPI\_\-SEMCAON\_\-SUFFIX} +environment variable should be set to a unique value. This ensures +that this instance of the Open MPI universe does not conflict with any +other, concurrent Open MPI universes that are running under the same +username on nodes in the Globus environment. Although any value can +be used for this variable, it is probably best to have some kind of +organized format, such as {\tt + -}. + +Next, create a boot schema to use with \cmd{lamboot}. +% +Hosts are listed by their Globus contact strings (see the Globus +manual for more information about contact strings). In cases where +the Globus gatekeeper is running as a \cmd{inetd} service on the node, +the contact string will simply be the hostname. If the contact string +contains whitespace, the {\em entire} contact string must be enclosed +in quotes (i.e., not just the values with whitespaces). +% +For example, if your contact string is: + +\centerline{\tt host1:port1:/O=xxx/OU=yyy/CN=aaa bbb ccc} + +Then you will need to have it listed as: + +\centerline{\tt "host1:port1:/O=xxx/OU=yyy/CN=aaa bbb ccc"} + +The following will not work: + +\centerline{\tt host1:port1:/O=xxx/OU=yyy/CN="aaa bbb ccc"} + +Each host in the boot schema must also have a ``{\tt + lam\_\-install\_\-path}'' key indicating the absolute directory +where Open MPI is installed. This value is mandatory because you +cannot rely on the \ienvvar{PATH} environment variable in Globus +environment because users' ``dot'' files are not executed in Globus +jobs (and therefore the \envvar{PATH} environment variable is not +provided). Other keys can be used as well; {\tt + lam\_\-install\_\-path} is the only mandatory key. + +Here is a sample Globus boot schema: + +\changebegin{7.0.5} +\lstset{style=lam-shell} +\begin{lstlisting} +# Globus boot schema +``inky.mycluster:12853:/O=MegaCorp/OU=Mine/CN=HPC Group'' prefix=/opt/lam cpu=2 +``pinky.yourcluster:3245:/O=MegaCorp/OU=Yours/CN=HPC Group'' prefix=/opt/lam cpu=4 +``blinky.hiscluster:23452:/O=MegaCorp/OU=His/CN=HPC Group'' prefix=/opt/lam cpu=4 +``clyde.hercluster:82342:/O=MegaCorp/OU=Hers/CN=HPC Group'' prefix=/software/lam +\end{lstlisting} +\changeend{7.0.5} + +Once you have this boot schema, the \cmd{lamboot} command can be used +to launch it. Note, however, that unlike the other boot MCA modules, +the Globus boot module will never be automatically selected by Open MPI -- +it must be selected manually with the \issiparam{boot} MCA parameter +with the value \issivalue{boot}{globus}. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot -ssi boot globus hostfile +\end{lstlisting} +% stupid emacs mode: $ + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-orte-pls-globus-mca-params} lists the MCA +parameters that are available to the \boot{globus} module. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{boot\_\-globus\_\-priority}{3}{Default priority level.} + \end{ssiparamtb} + \caption{MCA parameters for the \boot{globus} boot module.} + \label{tbl:mca-orte-pls-globus-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \boot{rsh} Module (including \cmd{ssh})} +\index{rsh (ssh) boot MCA module@\boot{rsh} (\cmd{ssh}) boot MCA module} +\index{boot MCA modules!rsh (rsh/ssh)@\boot{rsh} (\cmd{rsh}/\cmd{ssh})} + +The \cmd{rsh}/\cmd{ssh} boot MCA module is typically the ``least +common denominator'' boot module. When not in an otherwise +``special'' environment (such as a batch scheduler), the +\cmd{rsh}/\cmd{ssh} boot module is typically used to start the Open MPI +run-time environment. + +%%%%% + +\subsubsection{Minimum Requirements} + +In addition to the minimum requirements listed in +Section~\ref{sec:mca-orte-pls-min-reqs}, the following additional +conditions must also be met for a successful \cmd{lamboot} using the +\cmd{rsh} / \cmd{ssh} boot module: + +\begin{enumerate} +\item The user must be able to execute arbitrary commands on each + target host without being prompted for a password. + +\item The shell's start-up script must not print anything on standard + error. The user can take advantage of the fact that \cmd{rsh} / + \cmd{ssh} will start the shell non-interactively. The start-up + script can exit early in this case, before executing many commands + relevant only to interactive sessions and likely to generate output. + + \changebegin{7.1} + This has now been changed in version 7.1; if the MCA parameter + \issiparam{boot\_\-rsh\_\-ignore\_\-stderr} is nonzero, any output + on standard error will {\em not} be treated as an error. + \changeend{7.1} +\end{enumerate} + +Section~\ref{sec:getting-started} (page~\pageref{sec:getting-started}) +provides a short tutorial on using the \cmd{rsh} / \cmd{ssh} boot +module, including tips on setting up ``dot'' files, setting up +password-less remote execution, etc. + +%%%%% + +\subsubsection{Usage} + +Using \cmd{rsh}, \cmd{ssh}, or other remote-execution agent is +probably the most common method for starting the Open MPI run-time +execution environment. The boot schema typically lists the hostnames, +CPU counts, and an optional username (if the user's name is different +on the remote machine). + +\changebegin{7.1} + +The boot schema can also list an optional ``prefix'', which specifies +the Open MPI installatation to be used on the particular host listed in +the boot schema. This is typically used if the user has mutliple +Open MPI installations on a host and want to switch between them +without changing the dot files or \envvar{PATH} environment variables, +or if the user has Open MPI installed under different paths on +different hosts. If the prefix is not specified for a host in the +boot schema file, then the Open MPI installation which is available in +the \envvar{PATH} will be used on that host, or if the \cmdarg{-prefix + $<$/lam/install/path$>$} option is specified for \cmd{lamboot}, the +$<$/lam/install/path$>$ installation will be used. The prefix option +in the boot schema file however overrides any prefix option specified +on the \cmd{lamboot} command line for that host. + +For example: + +\lstset{style=lam-shell} +\begin{lstlisting} +# rsh boot schema +inky.cluster.example.com cpu=2 +pinky.cluster.example.com cpu=4 prefix=/home/joe/lam7.1/install/ +blinky.cluster.example.com cpu=4 +clyde.cluster.example.com user=jsmith +\end{lstlisting} + +\changeend{7.1} + +The \cmd{rsh} / \cmd{ssh} boot module will usually run when no other +boot module has been selected. It can, however, be manually selected, +even when another module would typically [automatically] be selected +by specifying the \issiparam{boot} MCA parameter with the value of +\issivalue{boot}{rsh}. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot -ssi boot rsh hostfile +\end{lstlisting} +% stupid emacs mode: $ + +%%%%% + +\subsubsection{Tunable Parameters} + +\changebegin{7.1} + +Table~\ref{tbl:mca-orte-pls-rsh-mca-params} lists the MCA parameters that +are available to the \boot{rsh} module. + +\changeend{7.1} + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{boot\_\-rsh\_\-agent}{From configure}{Remote shell + agent to use.} +% + \ssiparamentry{boot\_\-rsh\_\-ignore\_\-stderr}{0}{If nonzero, + ignore output from \file{stderr} when booting; don't treat it as + an error.} \ssiparamentry{boot\_\-rsh\_\-priority}{10}{Default + priority level.} +% + \ssiparamentry{boot\_\-rsh\_\-no\_\-n}{0}{If nonzero, don't use + ``\cmd{-n}'' as an argument to the boot agent} +% + \ssiparamentry{boot\_\-rsh\_\-no\_\-profile}{0}{If nonzero, don't + attempt to run ``\file{.profile}'' for Bourne-type shells.} +% + \ssiparamentry{boot\_\-rsh\_\-username}{None}{Username to use if + different than login name.} + \end{ssiparamtb} + \caption{MCA parameters for the \boot{rsh} boot module.} + \label{tbl:mca-orte-pls-rsh-mca-params} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \boot{slurm} Module} +\index{batch queue systems!SLURM boot MCA module} +\index{slurm boot MCA module@\boot{slurm} boot MCA module} +\index{boot MCA modules!slurm@\boot{slurm}} + +\changebegin{7.1} + +As its name implies, the Simple Linux Utility for Resource Management +(SLURM)\footnote{http://www.llnl.gov/linux/slurm/} package is commonly +used for managing Linux clusters, typically in high-performance +computing environments. SLURM contains a native system for launching +applications across the nodes that it manages. When using SLURM, +\cmd{rsh}/\cmd{ssh} is not necessary to launch jobs on remote nodes. +Instead, the \boot{slurm} boot module will automatically use SLURM's +native job-launching interface to start Open MPI daemons. + +The advantages of using SLURM's native interface are: + +\begin{itemize} +\item SLURM can generate proper accounting information for all nodes in + a parallel job. + +\item SLURM can kill entire jobs properly when the job ends. + +\item \icmd{lamboot} executes significantly faster when using SLURM as + compared to when it uses \cmd{rsh} / \cmd{ssh}. +\end{itemize} + +%%%%% + +\subsubsection{Usage} + +SLURM allows running jobs in multiple ways. The \boot{slurm} boot +module is only supported in some of them: + +\begin{itemize} +\item ``Batch'' mode: where a script is submitted via the \icmd{srun} + command and is executed on the first node from the set that SLURM + allocated for the job. The script runs \icmd{lamboot}, + \icmd{mpirun}, etc., as is normal for a Open MPI job. + + This method is supported, and is perhaps the most common way to run + Open MPI automated jobs in SLURM environments. + +\item ``Allocate'' mode: where the ``\cmdarg{-A}'' option is given to + \icmd{srun}, meaning that the shell were \icmd{lamboot} runs is + likely to {\em not} be one of the nodes that SLURM has allocated for + the job. In this case, Open MPI daemons will be launched on all nodes + that were allocated by SLURM as well as the origin (i.e., the node + where \cmd{lamboot} was run. The origin will be marked as + ``no-schedule,'' meaning that applications launched by \cmd{mpirun} + and \cmd{lamexec} will not be run there unless specifically + requested (see See Section~\ref{sec:commands-lamboot}, + page~\pageref{sec:commands-lamboot}, for more detail about this + attribute and boot schemas in general). + + This method is supported, and is perhaps the most common way to run + Open MPI interactive jobs in SLURM environments. + +\item ``\icmd{srun}'' mode: where a script is submitted via the + \icmd{srun} command and is executed on {\em all} nodes that SLURM + allocated for the job. In this case, the commands in the script + (e.g., \icmd{lamboot}, \icmd{mpirun}, etc.) will be run on {\em all} + nodes simultaneously, which is most likely not what you want. + + This mode is not supported. +\end{itemize} + +When running in any of the supported SLURM modes, Open MPI will +automatically detect that it should use the \boot{slurm} boot module +-- no extra command line parameters or environment variables should be +necessary. +% +Specifically, when running in a SLURM job, the \boot{slurm} module +will report that it is available, and artificially inflate its +priority relatively high in order to influence the boot module +selection process. +% +However, the \boot{slurm} boot module can be forced by specifying the +\issiparam{boot} MCA parameter with the value of +\issivalue{boot}{slurm}. + +Unlike the \cmd{rsh}/\cmd{ssh} boot module, you do not need to specify +a hostfile for the \boot{slurm} boot module. Instead, SLURM itself +provides a list of nodes (and associated CPU counts) to Open MPI. Using +\icmd{lamboot} is therefore as simple as: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot +\end{lstlisting} +% stupid emacs mode: $ + +\changebegin{7.1} + +Note that in environments with multiple TCP networks, SLURM may be +configured to use a network that is specifically designated for +commodity traffic -- another network may exist that is specifically +allocated for high-speed MPI traffic. By default, Open MPI will use the +same hostnames that SLURM provides for all of its traffic. This means +that Open MPI will send all of its MPI traffic across the same network that +SLURM uses. + +However, Open MPI has the ability to boot using one set of hostnames / +addresses and then use a second set of hostnames / addresses for MPI +traffic. As such, Open MPI can redirect its TCP MPI traffic across a +secondary network. It is possible that your system administrator has +already configured Open MPI to operate in this manner. + +If a secondary TCP network is intended to be used for MPI traffic, see +the section entitled ``Separating Open MPI and MPI TCP Traffic'' in the +Open MPI Installation Guide. Note that this functionality has no +effect on non-TCP \kind{rpi} modules (such as Myrinet, Infiniband, +etc.). + +\changeend{7.1} + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-orte-pls-slurm-mca-params} lists the MCA parameters +that are available to the \boot{slurm} module. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{boot\_\-slurm\_\-priority}{50}{Default priority level.} + \end{ssiparamtb} + \caption{MCA parameters for the \boot{slurm} boot module.} + \label{tbl:mca-orte-pls-slurm-mca-params} +\end{table} + +%%%%% + +\subsubsection{Special Notes} + +Since the \boot{slurm} boot module is designed to work in SLURM jobs, +it will fail if the \boot{slurm} boot module is manually specified and +Open MPI is not currently running in a SLURM job. + +The \boot{slurm} module does not start a shell on the remote node. +Instead, the entire environment of \cmd{lamboot} is pushed to the +remote nodes before starting the Open MPI run-time environment. + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{The \boot{tm} Module (OpenPBS / PBS Pro / Torque)} +\index{batch queue systems!OpenPBS / PBS Pro / Torque (TM) boot MCA module} +\index{tm boot MCA module@\boot{tm} boot MCA module} +\index{boot MCA modules!tm (PBS / Torque)@\boot{tm} (PBS / Torque)} + +Both OpenPBS and PBS Pro (both products of Altair Grid Technologies, +LLC), contain support for the Task Management (TM) interface. Torque, +the open source fork of the Open MPI product, also contains the TM +interface. When using TM, \cmd{rsh}/\cmd{ssh} is not necessary to +launch jobs on remote nodes. + +The advantages of using the TM interface are: + +\begin{itemize} +\item PBS/Torque can generate proper accounting information for all + nodes in a parallel job. + +\item PBS/Torque can kill entire jobs properly when the job ends. + +\item \icmd{lamboot} executes significantly faster when using TM as + compared to when it uses \cmd{rsh} / \cmd{ssh}. +\end{itemize} + +%%%%% + +\subsubsection{Usage} + +When running in a PBS/Torque batch job, Open MPI will automatically detect +that it should use the \boot{tm} boot module -- no extra command line +parameters or environment variables should be necessary. +% +Specifically, when running in a PBS/Torque job, the \boot{tm} module +will report that it is available, and artificially inflate its +priority relatively high in order to influence the boot module +selection process. +% +However, the \boot{tm} boot module can be forced by specifying the +\issiparam{boot} MCA parameter with the value of \issivalue{boot}{tm}. + +Unlike the \cmd{rsh}/\cmd{ssh} boot module, you do not need to specify +a hostfile for the \boot{tm} boot module. Instead, PBS/Torque itself +provides a list of nodes (and associated CPU counts) to Open MPI. Using +\icmd{lamboot} is therefore as simple as: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ lamboot +\end{lstlisting} +% stupid emacs mode: $ + +The \boot{tm} boot modules works in both interactive and +non-interactive batch jobs. + +\changebegin{7.1} + +Note that in environments with multiple TCP networks, PBS / Torque may +be configured to use a network that is specifically designated for +commodity traffic -- another network may exist that is specifically +allocated for high-speed MPI traffic. By default, Open MPI will use the +same hostnames that the TM interface provides for all of its traffic. +This means that Open MPI will send all of its MPI traffic across the same +network that PBS / Torque uses. + +However, Open MPI has the ability to boot using one set of hostnames / +addresses and then use a second set of hostnames / addresses for MPI +traffic. As such, Open MPI can redirect its TCP MPI traffic across a +secondary network. It is possible that your system administrator has +already configured Open MPI to operate in this manner. + +If a secondary TCP network is intended to be used for MPI traffic, see +the section entitled ``Separating Open MPI and MPI TCP Traffic'' in the +Open MPI Installation Guide. Note that this has no effect on non-TCP +\kind{rpi} modules (such as Myrinet, Infiniband, etc.). + +\changeend{7.1} + +%%%%% + +\subsubsection{Tunable Parameters} + +Table~\ref{tbl:mca-orte-pls-tm-mca-params} lists the MCA parameters +that are available to the \boot{tm} module. + +\begin{table}[htbp] + \begin{ssiparamtb} +% + \ssiparamentry{boot\_\-tm\_\-priority}{50}{Default priority level.} + \end{ssiparamtb} + \caption{MCA parameters for the \boot{tm} boot module.} + \label{tbl:mca-orte-pls-tm-mca-params} +\end{table} + +%%%%% + +\subsubsection{Special Notes} + +Since the \boot{tm} boot module is designed to work in PBS/Torque +jobs, it will fail if the \boot{tm} boot module is manually specified +and Open MPI is not currently running in a PBS/Torque job. + +The \boot{tm} module does not start a shell on the remote node. +Instead, the entire environment of \cmd{lamboot} is pushed to the +remote nodes before starting the Open MPI run-time environment. + +Also note that the Altair-provided client RPMs for PBS Pro do not +include the \icmd{pbs\_\-demux} command, which is necessary for proper +execution of TM jobs. The solution is to copy the executable from the +server RPMs to the client nodes. + +Finally, TM does not provide a mechanism for path searching on the +remote nodes, so the \cmd{lamd} executable is required to reside in +the same location on each node to be booted. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Close of index + +\index{ORTE MCA components|)} + diff --git a/doc/user/mca.tex b/doc/user/mca.tex new file mode 100644 index 0000000000..33052d3870 --- /dev/null +++ b/doc/user/mca.tex @@ -0,0 +1,421 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Modular Component Architecture (MCA) Overview} +\label{sec:mca} +\index{MCA!overview|(} +\index{Modular Component Architecture|see {MCA}} + +The Modular Component Architecture (MCA) makes up the core of Open MPI. +It influences how many commands and MPI processes are executed. This +chapter provides an overview of what MCA is and what users need to +know about how to use it to maximize performance of MPI applications. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Frameworks and Components} +\index{MCA!component frameworks} + +The MCA provides component frameworks for the Open MPI run-time +environment (otherwise known as the Open Run-Time Environment, or +ORTE) and the MPI communications layer. Components are selected from +each type at run-time and used to effect the RTE and MPI library. + +{\Huge JMS Right ideas, but needs much overhauling} + +There are currently four types of components used by +Open MPI: + +\begin{itemize} +\item \kind{boot}: Starting the Open MPI run-time environment, used mainly + with the \cmd{lamboot} command. + +\item \kind{coll}: MPI collective communications, only used within MPI + processes. + +\item \kind{cr}: Checkpoint/restart functionality, used both within + Open MPI commands and MPI processes. + +\item \kind{rpi}: MPI point-to-point communications, only used within + MPI processes. +\end{itemize} + +The Open MPI distribution includes instances of each component type +referred to as modules. Each module is an implementation of the +component type which can be selected and used at run-time to provide +services to the Open MPI RTE and MPI communications layer. +Chapters~\ref{sec:lam-mca} and~\ref{sec:mca-ompi} list the modules that +are available in the Open MPI distribution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Terminology} + +\begin{description} +\item[Available] The term ``available'' is used to describe a module + that reports (at run-time) that it is able to run in the current + environment. For example, an RPI module may check to see if + supporting network hardware is present before reporting that it is + available or not. + + Chapters~\ref{sec:lam-mca} and~\ref{sec:mca-ompi} list the modules + that are included in the Open MPI distribution, and detail the + requirements for each of them to indicate whether they are available + or not. + +\item[Selected] The term ``selected'' means that a module has been + chosen to be used at run-time. Depending on the module type, zero + or more modules may be selected. + +\item[Scope] Each module selection has a scope depending on the type + of the module. ``Scope'' refers to the duration of the module's + selection. Table~\ref{tbl:mca-module-scopes} lists the scopes for + each module type. +\end{description} + +\begin{table}[htbp] + \centering + \begin{tabular}{|l|p{4in}|} + \hline + \multicolumn{1}{|c|}{Type} & + \multicolumn{1}{|c|}{Scope description} \\ + \hline + \hline + \kind{boot} & A module is selected at the beginning of + \cmd{lamboot} (or \cmd{recon}) and is used for the duration of the + Open MPI universe. \\ + \hline + \kind{coll} & A module is selected every time an MPI communicator + is created (including \mpiconst{MPI\_\-COMM\_\-WORLD} and + \mpiconst{MPI\_\-COMM\_\-SELF}). It remains in use until that + communicator has been freed. \\ + \hline + \kind{cr} & Checkpoint/restart modules are selected at the + beginning of an MPI job and remain in use until the job + completes. \\ + \hline + \kind{rpi} & RPI modules are selected during \mpifunc{MPI\_\-INIT} + and remain in use until \mpifunc{MPI\_\-FINALIZE} returns. \\ + \hline + \end{tabular} + \caption{MCA module types and their corresponding scopes.} + \label{tbl:mca-module-scopes} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MCA Parameters} +\label{sec:commands-mca-module-parameters} +\index{MCA!parameter overview} + +One of the founding principles of MCA is to allow the passing of +run-time parameters through the MCA framework. This allows both the +selection of which modules will be used at run-time (by passing +parameters to the MCA framework itself) as well as tuning run-time +performance of individual modules (by passing parameters to each +module). +% +Although the specific usage of each MCA module parameter is defined by +either the framework or the module that it is passed to, the value of +most parameters will be resolved by the following: + +\begin{enumerate} +\item If a valid value is provided via a run-time MCA parameter, use + that. + +\item Otherwise, attempt to calculate a meaningful value at run-time + or use a compiled-in default value.\footnote{Note that many MCA + modules provide configure flags to set compile-time defaults + for ``tweakable'' parameters. + See~\cite{lamteam03:_lam_mpi_install_guide}.} +\end{enumerate} + +As such, it is typically possible to set a parameter's default value +when Open MPI is configured/compiled, but use a different value at run +time. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Naming Conventions} + +MCA parameter names are generally strings containing only letters and +underscores, and can typically be broken down into three parts. For +example, the parameter \mcaparam{boot\_\-rsh\_\-agent} can be broken +into its three components: + +\begin{itemize} +\item MCA module type: The first string of the name. In this case, it + is \mcaparam{boot}. + +\item MCA module name: The second string of the name, corresponding to + a specific MCA module. In this case, it is \mcaparam{rsh}. + +\item Parameter name: The last string in the name. It may be an + arbitrary string, and include multiple underscores. In this case, + it is \mcaparam{agent}. +\end{itemize} + +Although the parameter name is technically only the last part of the +string, it is only proper to refer to it within its overall context. +Hence, it is correct to say ``the \mcaparam{boot\_\-rsh\_\-agent} +parameter'' as well as ``the \mcaparam{agent} parameter to the +\boot{rsh} boot module''. + +Note that the reserved string \mcaparam{base} may appear as a module +name, referring to the fact that the parameter applies to all modules +of a give type. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Setting Parameter Values} + +MCA parameters each have a unique name and can take a single string +value. The parameter/value pairs can be passed by multiple different +mechanisms. Depending on the target module and the specific +parameter, mechanisms may include: + +\begin{itemize} +\item Using command line flags when Open MPI was configured. +\item Setting environment variables before invoking Open MPI commands. +\item Using the \cmdarg{-mca} command line switch to various Open MPI + commands. +\item Setting attributes on MPI communicators. +\end{itemize} + +Users are most likely to utilize the latter three methods. Each is +described in detail, below. Listings and explanations of available +MCA parameters are provided in Chapters~\ref{sec:lam-mca} +and~\ref{sec:mca-ompi} (pages~\pageref{sec:lam-mca} +and~\pageref{sec:mca-ompi}, respectively), categorized by MCA type and +module. + +%%%%% + +\subsubsection{Environment Variables} + +MCA parameters can be passed via environment variables prefixed with +\envvar{Open MPI\_\-MPI\_\-MCA}. For example, selecting which RPI module +to use in an MPI job can be accomplished by setting the environment +variable \envvar{Open MPI\_\-MPI\_\-MCA\_\-rpi} to a valid RPI module name +(e.g., \cmdarg{tcp}). + +Note that environment variables must be set {\em before} invoking the +corresponding Open MPI commands that will use them. + +%%%%% + +\subsubsection{\cmdarg{-mca} Command Line Switch} + +Open MPI commands that interact with MCA modules accept the +\cmdarg{-mca} command line switch. This switch expects two parameters +to follow: the name of the MCA parameter and its corresponding value. +For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -mca rpi tcp my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +\noindent runs the \cmd{my\_\-mpi\_\-program} on all available CPUs in +the Open MPI universe using the \rpi{tcp} RPI module. + +%%%%% + +\subsubsection{Communicator Attributes} + +Some MCA types accept MCA parameters via MPI communicator attributes +(notably the MPI collective communication modules). These parameters +follow the same rules and restrictions as normal MPI attributes. Note +that for portability between 32 and 64 bit systems, care should be +taken when setting and getting attribute values. The following is an +example of portable attribute C code: + +\lstset{style=lam-c} +\begin{lstlisting} +int flag, attribute_val; +void *set_attribute; +void **get_attribute; +MPI_Comm comm = MPI_COMM_WORLD; +int keyval = Open MPI_MPI_MCA_COLL_BASE_ASSOCIATIVE; + +/* Set the value */ +set_attribute = (void *) 1; +MPI_Comm_set_attr(comm, keyval, &set_attribute); + +/* Get the value */ +get_attribute = NULL; +MPI_Comm_get_attr(comm, keyval, &get_attribute, &flag); +if (flag == 1) { + attribute_val = (int) *get_attribute; + printf(``Got the attribute value: %d\n'', attribute_val); +} +\end{lstlisting} +% stupid emacs mode: $ + +Specifically, the following code is neither correct nor portable: + +\lstset{style=lam-c} +\begin{lstlisting} +int flag, attribute_val; +MPI_Comm comm = MPI_COMM_WORLD; +int keyval = Open MPI_MPI_MCA_COLL_BASE_ASSOCIATIVE; + +/* Set the value */ +attribute_val = 1; +MPI_Comm_set_attr(comm, keyval, &attribute_val); + +/* Get the value */ +attribute_val = -1; +MPI_Comm_get_attr(comm, keyval, &attribute_val, &flag); +if (flag == 1) + printf(``Got the attribute value: %d\n'', attribute_val); +\end{lstlisting} +% stupid emacs mode: $ + +\index{MCA!overview|)} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Dynamic Shared Object (DSO) Modules} + +\changebegin{7.1} + +Open MPI has the capability of building MCA modules statically as part of +the MPI libraries or as dynamic shared objects (DSOs). DSOs are +discovered and loaded into Open MPI processes at run-time. This allows +adding (or removing) functionality from an existing Open MPI installation +without the need to recompile or re-link user applications. + +The default location for DSO MCA modules is \file{\$prefix/lib/lam}. +If otherwise unspecified, this is where Open MPI will look for DSO MCA +modules. However, the MCA parameter +\imcaparam{base\_\-module\_\-path} can be used to specify a new +colon-delimited path to look for DSO MCA modules. This allows users +to specify their own location for modules, if desired. + +Note that specifying this parameter overrides the default location. +If users wish to augment their search path, they will need to include +the default location in the path specification. + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -mca base_module_path $prefix/lib/lam:$HOME/my_lam_modules ... +\end{lstlisting} +% stupid emacs mode: $ + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Selecting Modules} + +As implied by the previous sections, modules are selected at run-time +either by examining (in order) user-specified parameters, run-time +calculations, and compiled-in defaults. The selection process +involves a flexible negotitation phase which can be both tweaked and +arbitrarily overriden by the user and system administrator. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Specifying Modules} + +Each MCA type has an implicit MCA parameter corresponding to the type +name indicating which module(s) to be considered for selection. For +example, to specify in that the \rpi{tcp} RPI module should be used, +the MCA parameter \mcaparam{rpi} should be set to the value +\mcaparam{tcp}. For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -mca rpi tcp my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +The same is true for the other MCA types (\kind{boot}, \kind{cr}, and +\kind{coll}), with the exception that the \kind{coll} type can be used +to specify a comma-separated list of modules to be considered as each +MPI communicator is created (including +\mpiconst{MPI\_\-COMM\_\-WORLD}). For example: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ mpirun C -mca coll smp,shmem,lam_basic my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +\noindent indicates that the \coll{smp} and \coll{lam\_\-basic} +modules will potentially both be considered for selection for each MPI +communicator. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Setting Priorities} + +Although typically not useful to individual users, system +administrators may use priorities to set system-wide defaults that +influence the module selection process in Open MPI jobs. + +Each module has an associated priority which plays role in whether a +module is selected or not. Specifically, if one or more modules of a +given type are available for selection, the modules' priorities will +be at least one of the factors used to determine which module will +finally be selected. Priorities are in the range $[-1, 100]$, with +$-1$ indicating that the module should not be considered for +selection, and $100$ being the highest priority. Ties will be broken +arbitrarily by the MCA framework. + +A module's priorty can be set run-time through the normal MCA +parameter mechanisms (i.e., environment variables or using the +\cmdarg{-mca} parameter). Every module has an implicit priority MCA +parameter in the form \mcaparam{$<$type$>$\_\-$<$module + name$>$\_\-priority}. + +For example, a system administrator may set environment variables in +system-wide shell setup files (e.g., \file{/etc/profile}, +\file{/etc/bashrc}, or \file{/etc/csh.cshrc}) to change the default +priorities. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Selection Algorithm} + +For each component type, the following general selection algorithm is +used: + +\begin{itemize} +\item A list of all available modules is created. If the user + specified one or more modules for this type, only those modules are + queried to see if they are available. Otherwise, all modules are + queried. + +\item The module with the highest priority (and potentially meeting + other selection criteria, depending on the module's type) will be + selected. +\end{itemize} + +Each MCA type may define its own additional selection rules. For +example, the selection of \kind{coll}, \kind{cr}, and \kind{rpi} +modules may be inter-dependant, and depend on the supported MPI thread +level. Chapter~\ref{sec:mca-ompi} (page~\pageref{sec:mca-ompi}) +details the selection algorithm for MPI MCA modules. + diff --git a/doc/user/misc.tex b/doc/user/misc.tex new file mode 100644 index 0000000000..c85131903e --- /dev/null +++ b/doc/user/misc.tex @@ -0,0 +1,303 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Miscellaneous} +\label{sec:misc} + +This chapter covers a variety of topics that don't conveniently fit +into other chapters. + +{\Huge JMS Needs a lot of overhauling} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Singleton MPI Processes} + +It is possible to run an MPI process without the \cmd{mpirun} or +\cmd{mpiexec} commands -- simply run the program as one would normally +launch a serial program: + +\lstset{style=lam-cmdline} +\begin{lstlisting} +shell$ my_mpi_program +\end{lstlisting} +% Stupid emacs mode: $ + +Doing so will create an \mcw with a single process. This process can +either run by itself, or spawn or connect to other MPI processes and +become part of a larger MPI jobs using the MPI-2 dynamic function +calls. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI-2 I/O Support} +\index{ROMIO} +\index{MPI-2 I/O support|see {ROMIO}} +\index{I/O support|see {ROMIO}} + +MPI-2 I/O support is provided through the ROMIO +package~\cite{thak99a,thak99b}. ROMIO has been fully integrated into +Open MPI. As such, \mpitype{MPI\_\-Request} objects can be used ..... + +ROMIO includes its own documentation and listings of known issues and +limitations. See the \file{README} file in the ROMIO directory in the +Open MPI distribution. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Fortran Process Names} +\index{fortran process names} +\cmdindex{mpitask}{fortran process names} + +Since Fortran does not portably provide the executable name of the +process (similar to the way that C programs get an array of {\tt + argv}), the \icmd{mpitask} command lists the name ``Open MPI MPI Fortran +program'' by default for MPI programs that used the Fortran binding +for \mpifunc{MPI\_\-INIT} or \mpifunc{MPI\_\-INIT\_\-THREAD}. + +The environment variable \ienvvar{Open MPI\_\-MPI\_\-PROCESS\_\-NAME} can +be used to override this behavior. +% +Setting this environment variable before invoking \icmd{mpirun} will +cause \cmd{mpitask} to list that name instead of the default title. +% +This environment variable only works for processes that invoke the +Fortran binding for \mpifunc{MPI\_\-INIT} or +\mpifunc{MPI\_\-INIT\_\-THREAD}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI Thread Support} +\label{sec:misc-threads} +\index{threads and MPI} +\index{MPI and threads|see {threads and MPI}} + +\def\mtsingle{\mpiconst{MPI\_\-THREAD\_\-SINGLE}} +\def\mtfunneled{\mpiconst{MPI\_\-THREAD\_\-FUNNELED}} +\def\mtserial{\mpiconst{MPI\_\-THREAD\_\-SERIALIZED}} +\def\mtmultiple{\mpiconst{MPI\_\-THREAD\_\-MULTIPLE}} +\def\mpiinit{\mpifunc{MPI\_\-INIT}} +\def\mpiinitthread{\mpifunc{MPI\_\-INIT\_\-THREAD}} + +Open MPI currently implements support for \mtsingle, \mtfunneled, and +\mtserial. The constant \mtmultiple\ is provided, although Open MPI will +never return \mtmultiple\ in the \funcarg{provided} argument to +\mpiinitthread. + +Open MPI makes no distinction between \mtsingle\ and \mtfunneled. When +\mtserial\ is used, a global lock is used to ensure that only one +thread is inside any MPI function at any time. + +\subsection{Thread Level} + +Selecting the thread level for an MPI job is best described in terms +of the two parameters passed to \mpiinitthread: \funcarg{requested} +and \funcarg{provided}. \funcarg{requested} is the thread level that +the user application requests, while \funcarg{provided} is the thread +level that Open MPI will run the application with. + +\begin{itemize} +\item If \mpiinit\ is used to initialize the job, \funcarg{requested} + will implicitly be \mtsingle. However, if the + \ienvvar{Open MPI\_\-MPI\_\-THREAD\_\-LEVEL} environment variable is set + to one of the values in Table~\ref{tbl:mpi-env-thread-level}, the + corresponding thread level will be used for \funcarg{requested}. + +\item If \mpiinitthread\ is used to initialized the job, the + \funcarg{requested} thread level is the first thread level that the + job will attempt to use. There is currently no way to specify lower + or upper bounds to the thread level that Open MPI will use. + + The resulting thread level is largely determined by the SSI modules + that will be used in an MPI job; each module must be able to support + the target thread level. A complex algorithm is used to attempt to + find a thread level that is acceptable to all SSI modules. + Generally, the algorithm starts at \funcarg{requested} and works + backwards towards \mpiconst{MPI\_\-THREAD\_\-SINGLE} looking for an + acceptable level. However, any module may {\em increase} the thread + level under test if it requires it. At the end of this process, if + an acceptable thread level is not found, the MPI job will abort. +\end{itemize} + +\begin{table}[htbp] + \centering + \begin{tabular}{|c|l|} + \hline + Value & \multicolumn{1}{|c|}{Meaning} \\ + \hline + \hline + undefined & \mtsingle \\ + 0 & \mtsingle \\ + 1 & \mtfunneled \\ + 2 & \mtserial \\ + 3 & \mtmultiple \\ + \hline + \end{tabular} + \caption{Valid values for the \envvar{Open MPI\_\-MPI\_\-THREAD\_\-LEVEL} + environment variable.} + \label{tbl:mpi-env-thread-level} +\end{table} + +Also note that certain SSI modules require higher thread support +levels than others. For example, any checkpoint/restart SSI module +will require a minimum of \mtserial, and will attempt to adjust the +thread level upwards as necessary (if that CR module will be used +during the job). + +Hence, using \mpiinit\ to initialize an MPI job does not imply that +the provided thread level will be \mtsingle. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI-2 Name Publishing} +\index{published names} +\index{dynamic name publishing|see {published names}} +\index{name publising|see {published names}} + +Open MPI supports the MPI-2 functions \mpifunc{MPI\_\-PUBLISH\_\-NAME} +and \mpifunc{MPI\_\-UNPUBLISH\_\-NAME} for publishing and unpublishing +names, respectively. Published names are stored within the Open MPI +daemons, and are therefore persistent, even when the MPI process that +published them dies. + +As such, it is important for correct MPI programs to unpublish their +names before they terminate. However, if stale names are left in the +Open MPI universe when an MPI process terminates, the \icmd{lamclean} +command can be used to clean {\em all} names from the Open MPI RTE. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Batch Queuing System Support} +\label{sec:misc-batch} +\index{batch queue systems} +\index{Portable Batch System|see {batch queue systems}} +\index{PBS|see {batch queue systems}} +\index{PBS Pro|see {batch queue systems}} +\index{OpenPBS|see {batch queue systems}} +\index{Load Sharing Facility|see {batch queue systems}} +\index{LSF|see {batch queue systems}} +\index{Clubmask|see {batch queue systems}} + +Open MPI is now aware of some batch queuing systems. Support is currently +included for PBS, LSF, and Clubmask-based +systems. There is also a generic functionality that allows users of +other batch queue systems to take advantages of this functionality. + +\begin{itemize} +\item When running under a supported batch queue system, Open MPI will take + precautions to isolate itself from other instances of Open MPI in + concurrent batch jobs. That is, the multiple Open MPI instances from the + same user can exist on the same machine when executing in batch. + This allows a user to submit as many Open MPI jobs as necessary, and even + if they end up running on the same nodes, a \cmd{lamclean} in one + job will not kill MPI applications in another job. + +\item This behavior is {\em only} exhibited under a batch environment. + Other batch systems can easily be supported -- let the Open MPI Team know + if you'd like to see support for others included. Manually setting + the environment variable \ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-SUFFIX} + on the node where \icmd{lamboot} is run achieves the same ends. + \end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Location of Open MPI's Session Directory} +\label{sec:misc-session-directory} +\index{session directory} + +By default, Open MPI will create a temporary per-user session directory +in the following directory: + +\centerline{\file{/lam-@[-]}} + +\noindent Each of the components is described below: + +\begin{description} +\item[\file{}]: Open MPI will set the prefix used for the session + directory based on the following search order: + + \begin{enumerate} + \item The value of the \ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-PREFIX} + environment variable + + \item The value of the \ienvvar{TMPDIR} environment variable + + \item \file{/tmp/} + \end{enumerate} + + It is important to note that (unlike + \ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-SUFFIX}), the environment + variables for determining \file{} must be set on each node + (although they do not necessarily have to be the same value). + \file{} must exist before \icmd{lamboot} is run, or + \icmd{lamboot} will fail. + +\item[\file{}]: The user's name on that host. + +\item[\file{}]: The hostname. + +\item[\file{}]: Open MPI will set the suffix (if any) used + for the session directory based on the following search order: + + \begin{enumerate} + + \item The value of the \ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-SUFFIX} + environment variable. + + \item If running under a supported batch system, a unique session + ID (based on information from the batch system) will be used. + \end{enumerate} +\end{description} + +\ienvvar{Open MPI\_\-MPI\_\-SESSION\_\-SUFFIX} and the batch information +only need to be available on the node from which \icmd{lamboot} is +run. \icmd{lamboot} will propagate the information to the other +nodes. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Signal Catching} +\index{signals} + +Open MPI MPI catches the signals SEGV, BUS, FPE, and ILL. The +signal handler terminates the application. This is useful in batch +jobs to help ensure that \icmd{mpirun} returns if an application +process dies. To disable the catching of signals use the +\cmdarg{-nsigs} option to \icmd{mpirun}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI Attributes} + +\begin{discuss} + Need to have discussion of built-in attributes here, such as + MPI\_\-UNIVERSE\_\-SIZE, etc. Should specifically mention that + MPI\_\-UNIVERSE\_\-SIZE is fixed at \mpifunc{MPI\_\-INIT} time (at + least it is as of this writing -- who knows what it will be when we + release 7.1? :-). + + This whole section is for 7.1. +\end{discuss} diff --git a/doc/user/mpi-details.tex b/doc/user/mpi-details.tex new file mode 100644 index 0000000000..27a44bdef7 --- /dev/null +++ b/doc/user/mpi-details.tex @@ -0,0 +1,703 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Supported MPI Functionality} +\label{sec:mpi-functionality} + +This chapter discusses the exact levels of MPI functionality that is +supported by Open MPI. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI-1 Support} + +Open MPI \ompiversion\ has support for all MPI-1 functionality. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Language Bindings} +\label{sec:mpi-details-mpi1-language} + +Open MPI provides C, C++, Fortran 77, and Fortran 90 bindings for all +MPI-1 functions, types, and constants. +% +Profiling support is available in all four languages (if Open MPI was +configured and compiled with profiling support). The \icmd{ompi\_info} +command can be used to see if profiling support was included in +Open MPI. + +{\Huge JMS needs massive overhauling} + +Support for optional Fortran types has now been added. +Table~\ref{tbl:mpi-details-optional-fortran-dtypes} lists the new +datatypes. Note that \mpidatatype{MPI\_\-INTEGER8} and +\mpidatatype{MPI\_\-REAL16} are listed even though they are not +defined by the MPI standard. Support for these types is included per +request from Open MPI users. + +\begin{table}[htbp] + \centering + \begin{tabular}{|ll|} + \hline + \multicolumn{2}{|c|}{Supported Datatypes} \\ + \hline + \hline + \mpidatatype{MPI\_\-INTEGER1} & + \mpidatatype{MPI\_\-INTEGER2} \\ +% + \mpidatatype{MPI\_\-INTEGER4} & + \mpidatatype{MPI\_\-INTEGER8} \\ +% + \mpidatatype{MPI\_\-REAL4} & + \mpidatatype{MPI\_\-REAL8} \\ +% + \mpidatatype{MPI\_\-REAL16} & + ~ \\ + \hline + \end{tabular} + \caption{Supported optional fortran datatypes.} + \label{tbl:mpi-details-optional-fortran-dtypes} +\end{table} + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{\mpifunc{MPI\_\-CANCEL}} + +\mpifunc{MPI\_\-CANCEL} works properly for receives, but will almost +never work on sends. \mpifunc{MPI\_\-CANCEL} is most frequently used +with unmatched \mpifunc{MPI\_\-IRECV}'s that were made ``in case'' a +matching message arrived. This simply entails removing the receive +request from the local queue, and is fairly straightforward to +implement. + +Actually canceling a send operation is much more difficult because +some meta information about a message is usually sent immediately. As +such, the message is usually at least partially sent before an +\mpifunc{MPI\_\-CANCEL} is issued. Trying to chase down all the +particular cases is a nightmare, to say the least. + +As such, the Open MPI Team decided not to implement \mpifunc{MPI\_\-CANCEL} +on sends, and instead concentrate on other features. + +But in true MPI Forum tradition, we would be happy to discuss any code +that someone would like to submit that fully implements +\mpifunc{MPI\_\-CANCEL}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI-2 Support} + +Open MPI \lamversion\ has support for many MPI-2 features. The main +chapters of the MPI-2 standard are listed below, along with a summary +of the support provided for each chapter. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Miscellany} + +%%%%% + +\paragraph{Portable MPI Process Startup.} + +The \icmd{mpiexec} command is now supported. Common examples include: + +\lstset{style=lam-shell} +\begin{lstlisting} +# Runs 4 copes of the MPI program my_mpi_program +shell$ mpiexec -n 4 my_mpi_program + +# Runs my_linux_program on all available Linux machines, and runs +# my_solaris_program on all available Solaris machines +shell$ mpiexec -arch linux my_linux_program : -arch solaris my_solaris_program + +# Boot the Open MPI run-time environment, run my_mpi_program on all +# available CPUs, and then shut down the Open MPI run-time environment. +shell$ mpiexec -machinefile hostfile my_mpi_program +\end{lstlisting} +% stupid emacs mode: $ + +See the \file{mpiexec(1)} man page for more details on supported +options as well as more examples. + +%%%%% + +\paragraph{Passing \const{NULL} to \mpifunc{MPI\_\-INIT}.} + +Passing \const{NULL} as both arguments to \mpifunc{MPI\_\-INIT} is +fully supported. + +%%%%% + +\paragraph{Version Number.} + +Open MPI \lamversion\ reports its MPI version as 1.2 through the function +\mpifunc{MPI\_\-GET\_\-VERSION}. + +%%%%% + +\paragraph{Datatype Constructor \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-INDEXED\_\-BLOCK}.} + +The MPI function \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-INDEXED\_\-BLOCK} +is not supported by Open MPI. + +%%%%% + +\paragraph{Treatment of \mpitype{MPI\_\-Status}.} + +Although Open MPI supports the constants \mpiconst{MPI\_\-STATUS\_\-IGNORE} +and \mpiconst{MPI\_\-STATUSES\_\-IGNORE}, the function +\mpifunc{MPI\_\-REQUEST\_\-GET\_\-STATUS} is not provided. + +%%%%% + +\paragraph{Error class for invalid keyval.} + +The error class for invalid keyvals, \mpiconst{MPI\_\-ERR\_\-KEYVAL}, +is fully supported. + +%%%%% + +\paragraph{Committing committed datatype.} + +Committing a committed datatype is fully supported; its end effect is +a no-op. + +%%%%% + +\paragraph{Allowing user functions at process termination.} + +Attaching attributes to \mpiconst{MPI\_\-COMM\_\-SELF} that have +user-specified delete functions will now trigger these functions to be +invoked as the first phase of \mpifunc{MPI\_\-FINALIZE}. When these +functions are run, MPI is still otherwise fully functional. + +%%%%% + +\paragraph{Determining whether MPI has finished.} + +The function \mpifunc{MPI\_\-FINALIZED} is fully supported. + +%%%%% + +\paragraph{The {\sf Info} object.} + +Full support for \mpitype{MPI\_\-Info} objects is provided. See +Table~\ref{tbl:mpi-details-info-functions}. + +\begin{table}[htbp] + \centering + \begin{tabular}{|lll|} + \hline + \multicolumn{3}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-INFO\_\-CREATE} & + \mpifunc{MPI\_\-INFO\_\-FREE} & + \mpifunc{MPI\_\-INFO\_\-GET\_\-NTHKEY} \\ +% + \mpifunc{MPI\_\-INFO\_\-DELETE} & + \mpifunc{MPI\_\-INFO\_\-GET} & + \mpifunc{MPI\_\-INFO\_\-GET\_\-VALUELEN} \\ +% + \mpifunc{MPI\_\-INFO\_\-DUP} & + \mpifunc{MPI\_\-INFO\_\-GET\_\-NKEYS} & + \mpifunc{MPI\_\-INFO\_\-SET} \\ + \hline + \end{tabular} + \caption{Supported MPI-2 info functions.} + \label{tbl:mpi-details-info-functions} +\end{table} + +%%%%% + +\paragraph{Memory allocation.} + +The \mpifunc{MPI\_\-ALLOC\_\-MEM} and \mpifunc{MPI\_\-FREE\_\-MEM} +functions will return ``special'' memory that enable fast memory +passing in RPIs that support it. +% +These functions are simply wrappers to \func{malloc()} and +\func{free()} (respectively) in RPI modules that do not take advantage +of ``special'' memory. +% +These functions can be used portably for potential performance gains. + +%%%%% + +\paragraph{Language interoperability.} + +Inter-language interoperability is supported. It is possible to +initialize Open MPI from either C or Fortran and mix MPI calls from +both languages. Handle conversions for inter-language +interoperability are fully supported. See +Table~\ref{tbl:mpi-details-handle-conversion-functions}. + +\begin{table}[htbp] + \centering + \begin{tabular}{|ll|} + \hline + \multicolumn{2}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-COMM\_\-F2C} & + \mpifunc{MPI\_\-COMM\_\-C2F} \\ +% + \mpifunc{MPI\_\-GROUP\_\-F2C} & + \mpifunc{MPI\_\-GROUP\_\-C2F} \\ +% + \mpifunc{MPI\_\-TYPE\_\-F2C} & + \mpifunc{MPI\_\-TYPE\_\-C2F} \\ +% + \mpifunc{MPI\_\-REQUEST\_\-F2C} & + \mpifunc{MPI\_\-REQUEST\_\-C2F} \\ +% + \mpifunc{MPI\_\-INFO\_\-F2C} & + \mpifunc{MPI\_\-INFO\_\-C2F} \\ +% + \mpifunc{MPI\_\-WIN\_\-F2C} & + \mpifunc{MPI\_\-WIN\_\-C2F} \\ +% + \mpifunc{MPI\_\-STATUS\_\-F2C} & + \mpifunc{MPI\_\-STATUS\_\-C2F} \\ + \hline + \end{tabular} + \caption{Supported MPI-2 handle conversion functions.} + \label{tbl:mpi-details-handle-conversion-functions} +\end{table} + +%%%%% + +\paragraph{Error handlers.} + +Communicator and window error handler functions are fully supported; +this functionality is not yet supported for \mpitype{MPI\_\-File} +handles. See Table~\ref{tbl:mpi-details-err-handler-functions} + +\begin{table}[htbp] + \centering + \begin{tabular}{|ll|} + \hline + \multicolumn{2}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-COMM\_\-CREATE\_\-ERRHANDLER} & + \mpifunc{MPI\_\-WIN\_\-CREATE\_\-ERRHANDLER} \\ +% + \mpifunc{MPI\_\-COMM\_\-GET\_\-ERRHANDLER} & + \mpifunc{MPI\_\-WIN\_\-GET\_\-ERRHANDLER} \\ +% + \mpifunc{MPI\_\-COMM\_\-SET\_\-ERRHANDLER} & + \mpifunc{MPI\_\-WIN\_\-SET\_\-ERRHANDLER} \\ + \hline + \end{tabular} + \caption{Supported MPI-2 error handler functions.} + \label{tbl:mpi-details-err-handler-functions} +\end{table} + +%%%%% + +\paragraph{New datatype manipulation functions.} + +Several new datatype manipulation functions are provided. +Table~\ref{tbl:mpi-details-new-dtype-manip-functions} lists the new +functions. + +\begin{table}[htbp] + \centering + \begin{tabular}{|ll|} + \hline + \multicolumn{2}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-GET\_\-ADDRESS} & + \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-SUBARRAY} \\ +% + \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-DARRAY} & + \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-STRUCT} \\ +% + \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-HINDEXED} & + \mpifunc{MPI\_\-TYPE\_\-GET\_\-EXTENT} \\ +% + \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-HVECTOR} & + \mpifunc{MPI\_\-TYPE\_\-GET\_\-TRUE\_\-EXTENT} \\ +% + \mpifunc{MPI\_\-TYPE\_\-CREATE\_\-RESIZED} & + ~ \\ + \hline + \end{tabular} + \caption{Supported MPI-2 new datatype manipulation functions.} + \label{tbl:mpi-details-new-dtype-manip-functions} +\end{table} + +%%%%% + +\paragraph{New predefined datatypes.} + +Support has been added for the +\mpidatatype{MPI\_\-LONG\_\-LONG\_\-INT}, +\mpidatatype{MPI\_\-UNSIGNED\_\-LONG\_\-LONG} and +\mpidatatype{MPI\_\-WCHAR} basic datatypes. + +%%%%% + +\paragraph{Canonical \mpifunc{MPI\_\-PACK}, \mpifunc{MPI\_\-UNPACK}.} + +Support is not provided for \mpifunc{MPI\_\-PACK\_\-EXTERNAL}, +\mpifunc{MPI\_\-UNPACK\_\-EXTERNAL}, or +\mpifunc{MPI\_\-PACK\_\-EXTERNAL\_\-SIZE}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Process Creation and Management} + +Open MPI supports all MPI-2 dynamic process management. +Table~\ref{tbl:mpi-details-dynamic-functions} lists all the supported +functions. + +\begin{table}[htbp] + \centering + \begin{tabular}{|lll|} + \hline + \multicolumn{3}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-CLOSE\_\-PORT} & + \mpifunc{MPI\_\-COMM\_\-GET\_\-PARENT} & + \mpifunc{MPI\_\-LOOKUP\_\-NAME} \\ +% + \mpifunc{MPI\_\-COMM\_\-ACCEPT} & + \mpifunc{MPI\_\-COMM\_\-JOIN} & + \mpifunc{MPI\_\-OPEN\_\-PORT} \\ +% + \mpifunc{MPI\_\-COMM\_\-SPAWN} & + \mpifunc{MPI\_\-COMM\_\-CONNECT} & + \mpifunc{MPI\_\-PUBLISH\_\-NAME} \\ +% + \mpifunc{MPI\_\-COMM\_\-DISCONNECT} & + \mpifunc{MPI\_\-COMM\_\-SPAWN\_\-MULTIPLE} & + \mpifunc{MPI\_\-UNPUBLISH\_\-NAME} \\ + \hline + \end{tabular} + \caption{Supported MPI-2 dynamic functions.} + \label{tbl:mpi-details-dynamic-functions} +\end{table} + +As requested by Open MPI users, \mpifunc{MPI\_\-COMM\_\-SPAWN} and +\mpifunc{MPI\_\-COMM\_\-SPAWN\_\-MULTIPLE} supports some +\mpitype{MPI\_\-Info} keys for spawning MPMD applications and for more +fine-grained control about where children processes are spawned. See +the \file{MPI\_\-Comm\_\-spawn(3)} man page for more details. + +These functions supersede the \mpifunc{MPIL\_\-COMM\_\-SPAWN} function +that Open MPI introduced in version 6.2b. Hence, +\mpifunc{MPIL\_\-COMM\_\-SPAWN} is no longer available. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{One-Sided Communication} + +Support is provided for get/put/accumulate data transfer operations +and for the post/wait/start/complete and fence synchronization +operations. No support is provided for window locking. + +The datatypes used in the get/put/accumulate operations are restricted +to being basic datatypes or single level contiguous/vectors of basic +datatypes. + +The implementation of the one-sided operations is layered on top of +the point-to-point functions, and will thus perform no better than +them. Nevertheless it is hoped that providing this support will aid +developers in developing and debugging codes using one-sided +communication. + +Table~\ref{tbl:mpi-details-one-sided-functions} lists the functions +related to one-sided communication that have been implemented. + +\begin{table}[htbp] + \centering + \begin{tabular}{|lll|} + \hline + \multicolumn{3}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-ACCUMULATE} & + \mpifunc{MPI\_\-WIN\_\-CREATE} & + \mpifunc{MPI\_\-WIN\_\-POST} \\ +% + \mpifunc{MPI\_\-GET} & + \mpifunc{MPI\_\-WIN\_\-FENCE} & + \mpifunc{MPI\_\-WIN\_\-START} \\ +% + \mpifunc{MPI\_\-PUT} & + \mpifunc{MPI\_\-WIN\_\-FREE} & + \mpifunc{MPI\_\-WIN\_\-WAIT} \\ +% + \mpifunc{MPI\_\-WIN\_\-COMPLETE} & + \mpifunc{MPI\_\-WIN\_\-GET\_\-GROUP} & + ~ \\ + \hline + \end{tabular} + \caption{Supported MPI-2 one-sided functions.} + \label{tbl:mpi-details-one-sided-functions} +\end{table} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Extended Collective Operations} +\label{sec:mpi:extended-collectives} + +\changebegin{7.1} + +Open MPI implements the new MPI-2 collective functions +\mpifunc{MPI\_\-EXSCAN} and \mpifunc{MPI\_\-ALLTOALLW} for +intracommunicators. + +Intercommunicator collectives are implemented for all the functions +listed in Table~\ref{tbl:mpi-details-intercomm-collective-functions}. +Notably, intercommunicator collectives are {\em not} defined for +\mpifunc{MPI\_\-SCAN} (because the MPI standard does not define it), +\mpifunc{MPI\_\-ALLGATHERV}, and +\mpifunc{MPI\_\-EXSCAN}.\footnote{These two functions were + unfortunately overlooked and forgotten about when Open MPI v7.1 was + frozen for release.} + +\begin{table}[htbp] + \centering + \begin{tabular}{|lll|} + \hline + \multicolumn{3}{|c|}{Supported Functions} \\ + \hline + \hline + \mpifunc{MPI\_\-ALLGATHER} & + \mpifunc{MPI\_\-ALLGATHERV} & + \mpifunc{MPI\_\-ALLTOALL} \\ +% + \mpifunc{MPI\_\-ALLTOALLV} & + \mpifunc{MPI\_\-ALLTOALLW} & + \mpifunc{MPI\_\-ALLREDUCE} \\ +% + \mpifunc{MPI\_\-REDUCE\_\-SCATTER} & + \mpifunc{MPI\_\-GATHER} & + \mpifunc{MPI\_\-GATHERV} \\ +% + \mpifunc{MPI\_\-REDUCE} & + \mpifunc{MPI\_\-BCAST} & + \mpifunc{MPI\_\-SCATTER} \\ +% + \mpifunc{MPI\_\-SCATTERV} & + \mpifunc{MPI\_\-BARRIER} & + ~ \\ + \hline + \end{tabular} + \caption{Supported MPI-2 intercommunicator collective functions.} + \label{tbl:mpi-details-intercomm-collective-functions} +\end{table} + +\changeend{7.1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{External Interfaces} + +The external interfaces chapter lists several different major topics. +Open MPI's support for these topics is summarized in +Table~\ref{tbl:mpi-details-ext-int-summary}, and the exact list of +functions that are supported is listed +in~\ref{tbl:mpi-details-ext-int-functions}. + +\begin{table}[htbp] + \centering + \begin{tabular}{|c|p{3in}|} + \hline + \multicolumn{1}{|c|}{Supported} & + \multicolumn{1}{|c|}{Description} \\ + \hline + \hline +% + \supportno & Generalized requests \\ +% + \supportno & Associating information with \mpitype{MPI\_\-Status} \\ +% + \supportyes & Naming objects \\ +% + \supportno & Error classes \\ + \supportno & Error codes \\ + \supportyes & Error handlers \\ +% + \supportyes & Decoding a datatype \\ +% + \supportyes & MPI and threads \\ +% + \supportyes & New attribute caching functions \\ +% + \supportyes & Duplicating a datatype \\ + \hline + \end{tabular} + \caption{Major topics in the MPI-2 chapter ``External Interfaces'', + and Open MPI's level of support.} + \label{tbl:mpi-details-ext-int-summary} +\end{table} + +\begin{table}[htbp] + \centering + \begin{tabular*}{\textwidth}{llllll|} + \hline + \multicolumn{6}{|c|}{Supported Functions} \\ + \hline \hline + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-SET\_\-NAME}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-SET\_\-NAME}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-SET\_\-NAME}} \\ +% + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-GET\_\-NAME}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-GET\_\-NAME}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-GET\_\-NAME}} \\ +% + \hline +% + \hline + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-COMM\_\-CREATE\_\-ERRHANDLER}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-WIN\_\-CREATE\_\-ERRHANDLER}} \\ +% + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-COMM\_\-GET\_\-ERRHANDLER}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-WIN\_\-GET\_\-ERRHANDLER}} \\ +% + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-COMM\_\-SET\_\-ERRHANDLER}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-WIN\_\-SET\_\-ERRHANDLER}} \\ +% + \hline +% + \hline + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-TYPE\_\-GET\_\-CONTENTS}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-INIT\_\-THREAD}} \\ + +% + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-TYPE\_\-GET\_\-ENVELOPE}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-QUERY\_\-THREAD}} \\ +% + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-TYPE\_\-GET\_\-EXTENT}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-IS\_\-THREAD\_\-MAIN}} \\ +% + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-TYPE\_\-GET\_\-TRUE\_\-EXTENT}} & + \multicolumn{3}{|l|}{\mpifunc{MPI\_\-TYPE\_\-DUP}} \\ +% + \hline +% + \hline + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-CREATE\_\-KEYVAL}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-CREATE\_\-KEYVAL}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-CREATE\_\-KEYVAL}} \\ +% + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-FREE\_\-KEYVAL}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-FREE\_\-KEYVAL}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-FREE\_\-KEYVAL}} \\ +% + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-DELETE\_\-ATTR}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-DELETE\_\-ATTR}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-DELETE\_\-ATTR}} \\ +% + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-GET\_\-ATTR}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-GET\_\-ATTR}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-GET\_\-ATTR}} \\ +% + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-COMM\_\-SET\_\-ATTR}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-TYPE\_\-SET\_\-ATTR}} & + \multicolumn{2}{|l|}{\mpifunc{MPI\_\-WIN\_\-SET\_\-ATTR}} \\ +% + \hline + \end{tabular*} + \caption{Supported MPI-2 external interface functions, grouped by + function.} + \label{tbl:mpi-details-ext-int-functions} +\end{table} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{I/O} + +MPI-IO support is provided by including the ROMIO package from Argonne +National Labs,\footnote{\url{http://www.mcs.anl.gov/romio/}} version +1.2.5.1. +% +The Open MPI wrapper compilers (\icmd{mpicc}, \icmd{mpiCC}/\icmd{mpic++}, +and \icmd{mpif77}) will automatically provide all the necessary flags +to compile and link programs that use ROMIO function calls. + +Although the ROMIO group at Argonne has included support for Open MPI in +their package, there are still a small number of things that the Open MPI +Team had to do to make ROMIO compile and install properly with +Open MPI. As such, if you try to install the ROMIO package manually +with Open MPI, you will experience some difficulties. + +There are some important limitations to ROMIO that are discussed in +the \file{romio/README} file. +% +One limitation that is not currently listed in the ROMIO README file +is that atomic file access will not work with AFS. This is because of +file locking problems with AFS (i.e., AFS iteself does not support +file locking). The ROMIO test program \cmd{atomicity} will fail if +you specify an output file on AFS. + +Additionally, ROMIO does not support the following Open MPI functionality: + +\begin{itemize} +\item Open MPI MPI-2 datatypes cannot be used with ROMIO; ROMIO makes the + fundamental assumption that MPI-2 datatypes are built upon MPI-1 + datatypes. Open MPI builds MPI-2 datatypes natively -- ROMIO cannot + presently handle this case. + + This will hopefully be fixed in some future release of ROMIO. The + ROMIO test programs \cmd{coll\_\-test}, \cmd{fcoll\_\-test}, + \cmd{large\_\-array}, and \cmd{coll\_\-perf} will fail because they + use the MPI-2 datatype \mpidatatype{MPI\_\-DARRAY}. +\end{itemize} + +Please see the sections ``ROMIO Users Mailing List'' and ``Reporting +Bugs'' in \file{romio/README} for how to submit questions and bug +reports about ROMIO (that do not specifically pertain to Open MPI). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Language Bindings} + +Open MPI provides C, C++, and Fortran 77 bindings for all supported MPI-2 +functions, types, and constants. Open MPI does not provide a Fortran 90 +module. +% +However, it is possible to use the Fortran 77 bindings with a Fortran +90 compiler by specifying the F90 compiler as your Fortran compiler +when configuring/compiling Open MPI. See the Open MPI Installation +Guide~\cite{lamteam03:_lam_mpi_install_guide} for more details. + +The C++ bindings include support for the C++ only \mpitype{MPI::BOOL}, +\mpitype{MPI::COMPLEX}, \mpitype{MPI::DOUBLE\_\-COMPLEX}, and +\mpitype{MPI::LONG\_\-DOUBLE\_\-COMPLEX} datatypes. + +Note that there are some issues with using MPI and Fortran 90 +together. See the F90 / C++ chapter in the MPI-2 +standard~\cite{geist96:_mpi2_lyon} for more information on using MPI +with Fortran 90. + +As mentioned in Section~\ref{sec:mpi-details-mpi1-language}, profiling +support is available in all three languages (if Open MPI was compiled +with profiling support). The \icmd{ompi\_info} command can be used to +see if profiling support was included in Open MPI. + diff --git a/doc/user/openmpi_logo-only.png b/doc/user/openmpi_logo-only.png new file mode 100644 index 0000000000..0174cacacc Binary files /dev/null and b/doc/user/openmpi_logo-only.png differ diff --git a/doc/user/refs.bib b/doc/user/refs.bib new file mode 100644 index 0000000000..ead4ecfedd --- /dev/null +++ b/doc/user/refs.bib @@ -0,0 +1,184 @@ +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +@Manual{gnu-code-standards, + title = {GNU Coding Standards}, + author = {Richard Stallman et al.}, + organization = {Free Software Foundation}, + month = {October}, + year = 2001, + note = {Included in the GNU {\tt autoconf} distribution; see {\tt ftp://ftp.gnu.org/gnu/autoconf/}} +} + +@Manual{lamteam03:_lam_mpi_user_guide, + title = {Open MPI User's Guide}, + author = {The Open MPI Team}, + organization = {The Open MPI Project} +} + +@Manual{lamteam03:_lam_mpi_install_guide, + title = {Open MPI Installation Guide}, + author = {The Open MPI Team}, + organization = {The Open MPI Project} +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ROMIO +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@InProceedings{thak99b, + author = {Rajeev Thakur and William Gropp and Ewing Lusk}, + title = {On Implementing {MPI-IO} Portably and with High Performance}, + booktitle = {Proceedings of the 6th Workshop on I/O in Parallel and + Distributed Systems}, + pages = {23--32}, + year = {1999}, + month = {May}, + pubaddress = "New York, NY", + publisher = {ACM Press} +} + +@InProceedings{thak99a, + author = {Rajeev Thakur and William Gropp and Ewing Lusk}, + title = {Data Sieving and Collective {I/O} in {ROMIO}}, + booktitle = {Proceedings of the 7th Symposium on the Frontiers of Massively + Parallel Computation}, + pages = {182--189}, + year = {1999}, + month = {February}, + publisher = {IEEE Computer Society Press} +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% MPI +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@Book{ gropp94:_using_mpi, + author = "William Gropp and Ewing Lusk and Anthony Skjellum", + title = "Using {MPI}: {P}ortable {P}arallel {P}rogramming + with the {M}essage {P}assing {I}nterface", + publisher = "MIT Press", + year = 1994 +} + +@Book{ gropp99:_using_mpi_2, + author = "William Gropp and Ewing Lusk and Rajeev Thakur", + title = "Using {MPI-2}: {A}dvanced {F}eatures of the + {M}essage {P}assing {I}nterface", + publisher = "MIT Press", + year = 1999 +} + +@Book{ snir96:_mpi_the_compl_refer, + author = "Marc Snir and Steve W. Otto and Steve Huss-Lederman + and David W. Walker and Jack Dongarra", + title = "{MPI}: {T}he {C}omplete {R}eference", + address = "Cambridge, MA", + publisher = "MIT Press", + year = 1996 +} + +@Book{gropp98:_mpi2, + author = {William Gropp and Steven Huss-Lederman and Andrew + Lumsdaine and Ewing Lusk and Bill Nitzberg and + William Saphir and Marc Snir}, + title = {{MPI} --- {T}he Complete Reference: {V}olume 2, the + {MPI}-2 Extensions}, + publisher = {MIT Press}, + year = 1998 +} + +@inproceedings{ mpi_forum93:_mpi, + title = "{MPI}: {A} {M}essage {P}assing {I}nterface", + author = "{Message Passing Interface Forum}", + booktitle = "Proc.~of Supercomputing '93", + publisher = "{IEEE} Computer Society Press", + place = "Portland, OR", + month = "November", + pages = "878--883", + year = 1993 +} + +@InProceedings{ geist96:_mpi2_lyon, + author = "Al Geist and William Gropp and Steve Huss-Lederman + and Andrew Lumsdaine and Ewing Lusk and William + Saphir and Tony Skjellum and Marc Snir", + title = "{MPI}-2: {E}xtending the {M}essage-{P}assing {I}nterface", + booktitle = "Euro-Par '96 Parallel Processing", + editor = "Luc Bouge and Pierre Fraigniaud and Anne Mignotte + and Yves Robert", + number = 1123, + series = "Lecture Notes in Computer Science", + year = 1996, + publisher = "Springer Verlag", + pages = "128--135" +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% MagPIe +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@inproceedings{kielmann++:00:magpie_bandwidth, + author = {Thilo Kielmann and Henri E. Bal and Sergei Gorlatch}, + title = {{Bandwidth-efficient Collective Communication + for Clustered Wide Area Systems}}, + booktitle = {{International Parallel and Distributed Processing Symposium + (IPDPS 2000)}}, + address = {Cancun, Mexico}, + month = {May}, + year = 2000, + pages = {492--499}, + publisher = {IEEE} +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% BLCR +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +@Misc{BLCR02, + author = {Jason Duell and Paul Hargrove and Eric Roman}, + title = {{T}he {D}esign and {I}mplementation of {B}erkeley {L}ab's + {L}inux {C}heckpoint/{R}estart}, + year = {2002} +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% random +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +@Misc{Netpipe96, + author = "Q. Snell and A. Mikler and J. Gustafson", + title = "{NetPIPE}: {A} {N}etwork {P}rotocol {I}ndependent {P}erformace + {E}valuator", + text = "Q.O. Snell, A.Mikler, and J.L. Gustafson. Netpipe: A Network + Protocol Independent Performance Evaluator. In IASTED International Conference + on Intelligent Information Management and Systems, June 1996.", + year = "1996" +} diff --git a/doc/user/release-notes.tex b/doc/user/release-notes.tex new file mode 100644 index 0000000000..af40093fc8 --- /dev/null +++ b/doc/user/release-notes.tex @@ -0,0 +1,143 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Release Notes} +\label{sec:release-notes} +\index{release notes|(} + +This chapter contains release notes as they pertain to the run-time +operation of Open MPI. The Installation Guide contains additional +release notes on the configuration, compilation, and installation of +Open MPI. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Alpha Release} + +Greetings! + +The Open MPI development team is pleased to announce an alpha-quality +release of the current state of our software to a limited set of +"friends" -- those who are knowledgeable about MPI and can provide +intelligent feedback to us before a public release. Our intent with +this release is to get the Open MPI software onto other people's +machines and see what creative ways you can come up with to break it, +and to send us your comments and suggestions. + +However, we want to stress the following points: + +\begin{itemize} +\item This is an {\em alpha} quality release. We're quite aware that + there are several things still broken (but report them anyway!). + +\item Most notably, if you run basic performance testing, you'll + notice that, for example, the GM numbers are still a microsecond or + two too high (we've been concentrating on functionality for the last + month -- performance tuning is coming shortly). + +\item Since the competition in the HPC community is rather fierce, + please do not redistribute this software without our permission. + Also, please do not publish any results (good or bad) because, as + mentioned above, this is pre-release software and we still have + performance tuning to do. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Release Frequency / Updates} + +You have probably downloaded this tarball from +\url{http://www.open-mpi.org/nightly/}. This directory is updated at +least once a day around 2am US/Indiana time (assuming that there is +new code to release). It may be updated more frequently if a critical +bug fix is reported and fixed. + +The best way to report bugs, send comments, or ask questions is to +sign up on the \url{mailto:devel@open-mpi.org} mailing list: + +\centerline{\url{http://www.open-mpi.org/mailman/listinfo.cgi/devel}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Known Issues} + +This tarball is an alpha release of Open MPI. It is not yet complete, +mainly in the following areas: + +\begin{itemize} +\item Support for Infiniband (both verbs and OpenIB) is missing +\item Support for Quadrics is missing +\item Support for Myrinet needs performance tuning +\item Support for MX needs performance tuning +\item Support for TCP needs performance tuning +\item Support for shared memory is not fully debugged + + If this becomes a problem during your testing, run the following: + +\lstset{style=ompi-cmdline} +\begin{lstlisting} +shell$ rm -f /lib/openmpi/*sm* +\end{lstlisting} +% Stupid emacs mode: $ + + where \cmdarg{} is the directory where you installed Open + MPI. + +\item Striping MPI messages across multiple networks is supported (and + happens automatically when multiple networks are available), but + needs performance tuning + +\item The only run-time systems supported are: + \begin{itemize} + \item \cmd{rsh} / \cmd{ssh} + \item BProc of the flavor that is used at Los Alamos National Labs (in + particular, it must be used with the BJS scheduler) + \end{itemize} + +\item TotalView and other parallel debugger support is missing. + +\item Complete user and system administrator documentation is missing + (this file comprises the majority of the current user documentation) + +\item The only systems that have been tested on are: + \begin{itemize} + \item Linux, 32 bit, with \cmd{gcc} + \end{itemize} + +\item Other systems have been lightly (but not fully tested): + \begin{itemize} + \item Linux, 64 bit, with \cmd{gcc} + \item OS X (10.3), 32 bit, with \cmd{gcc} + \end{itemize} + +\item Missing MPI functionality: + \begin{itemize} + \item The Fortran 90 MPI API is disabled (it is not complete). + \item MPI-2 dynamic functionality is temporarily broken. + \item MPI-2 one-sided functionality will not be included in the + first few releases of Open MPI + \end{itemize} + +\item After running MPI applications, the directory + \file{/tmp/openmpi-sessions-@*} will exist (but + will likely be empty). It is safe to remove. + +\end{itemize} + + +\index{release notes|)} diff --git a/doc/user/titlepage.tex b/doc/user/titlepage.tex new file mode 100644 index 0000000000..0fd15d0834 --- /dev/null +++ b/doc/user/titlepage.tex @@ -0,0 +1,50 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\title{Open MPI User's Guide \\ +Version \ompiversion \\ +\ \\ +\centerline{\includegraphics[width=2in]{openmpi_logo-only}}} + +\author{The Open MPI Team \\ +\url{http://www.open-mpi.org/}} + +\maketitle + +\thispagestyle{empty} + +\newpage + +\vspace*{6in} + +\noindent +Copyright $\copyright$ 2004-2005 The Trustees of Indiana University. +All rights reserved. \\ +Copyright $\copyright$ 2004-2005 The Trustees of the University of +Tennessee. +All rights reserved. \\ +Copyright $\copyright$ 2004-2005 High Performance Computing Center +Stuttgart, University of Stuttgart. All rights +reserved. \\ +Copyright $\copyright$ 2004-2005 The Regents of the University of +California. +All rights reserved. \\ + +Additional copyrights may follow + +{\Huge JMS need to find event library copyright notice} +{\Huge JMS need to find ROMIO copyright notice} diff --git a/doc/user/troubleshooting.tex b/doc/user/troubleshooting.tex new file mode 100644 index 0000000000..d3b2b1b9ec --- /dev/null +++ b/doc/user/troubleshooting.tex @@ -0,0 +1,247 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\chapter{Troubleshooting} +\label{sec:troubleshooting} + +{\Huge JMS Not bad, but needs tweaking} + +Although Open MPI is a robust run-time environment, and its MPI layer +is a mature software system, errors do occur. Particularly when using +Open MPI for the first time, some of the initial, per-user setup can +be confusing (e.g., setting up \ifile{.rhosts} or SSH keys for +password-less remote logins). This section aims to identify a few +common problems and solutions. + +Much more information can be found on the Open MPI FAQ on the main +Open MPI web site.\footnote{\url{http://www.open-mpi.org/faq/}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{The Open MPI Mailing Lists} +\label{troubleshooting:mailing-lists} +\index{e-mail lists} +\index{mailing lists} +\index{listserv mailing lists} + +There are two mailing lists: one for Open MPI announcements, and +another for questions and user discussion of Open MPI. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Announcements} + +This is a low-volume list that is used to announce new version of +Open MPI, important patches, etc. To subscribe to the Open MPI announcement +list, visit its list information page (you can also use that page to +unsubscribe or change your subscription options): + +\vspace{11pt} + +\centerline{\url{http://www.lam-mpi.org/mailman/listinfo.cgi/lam-announce}} + +\vspace{11pt} + +\noindent {\bf NOTE: Users cannot post to this list; all such posts + are automatically rejected -- only the Open MPI Team can post to this + list.} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{General Discussion / User Questions} + +{\bf BEFORE YOU POST TO THIS LIST:} {\em Please} check all the other +resources listed in this chapter first. Search the mailing list to +see if anyone else had a similar problem before you did. Re-read the +error message that Open MPI displayed to you (Open MPI can sometimes give {\em + incredibly} detailed error messages that tell you {\em exactly} how +to fix the problem). This, unfortunately, does not stop some users +from cut-n-pasting the entire error message, verbatim (including the +solution to their problem) into a mail message, sending it to the +list, and asking ``How do I fix this problem?'' So please: think (and +read) before you post.\footnote{Our deep appologies if some of the + information in this section appears to be repetitive and + condescending. Believe us when we say that we have tried all other + approaches -- some users simply either do not read the information + provided, or only read the e-mail address to send ``help!'' e-mails + to. It is our hope that big, bold print will catch some people's + eyes and enable them to help themselves rather than having to wait + for their post to distribute around the world and then further wait + for someone to reply telling them that the solution to their problem + was already printed on their screen. Thanks for your time in + reading all of this!} + +\vspace{11pt} + +This list is used for general questions and discussion of Open MPI. +User can post questions, comments, etc. to this list. {\bf Due to + recent increases in spam, only subscribers are allowed to post to + the list}. If you are not subscribed to the list, your posts will +be discarded. + +To subscribe or unsubscribe from the list, visit the list information +page: + +\vspace{11pt} +\centerline{\url{http://www.lam-mpi.org/mailman/listinfo.cgi/lam}} +\vspace{11pt} + +After you have subscribed (and received a confirmation e-mail), you +can send mail to the list at the following address: + +\vspace{11pt} +\centerline{{\bf You must be subscribed in order to post to the list}} +\centerline{\url{lam@lam-mpi.org}} +\centerline{{\bf You must be subscribed in order to post to the list}} +\vspace{11pt} + +Be sure to include the following information in your e-mail: + +\begin{itemize} +\item The \file{config.log} file from the top-level Open MPI directory, if + available ({\bf please compress!}). + +\item The output of ``\icmd{laminfo}\ \ \cmdarg{-all}''. + +\item A {\em detailed} description of what is failing. The more + details that you provide, the better. E-mails saying ``My + application doesn't work!'' will inevitably be answered with + requests for more information about {\em exactly what doesn't work}; + so please include as much detailed information in your initial + e-mail as possible. +\end{itemize} + +{\bf NOTE:} People tend to only reply to the list; if you subscribe, +post, and then unsubscribe from the list, you will likely miss +replies. + +Also please be aware that the list goes to several hundred people +around the world -- it is not uncommon to move a high-volume exchange +off the list, and only post the final resolution of the problem/bug +fix to the list. This prevents exchanges like ``Did you try X?'', +``Yes, I tried X, and it did not work.'', ``Did you try Y?'', etc. +from cluttering up peoples' inboxes. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{Open MPI Run-Time Environment Problems} + +Some common problems with the Open MPI run-time environment are listed +below. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Problems with the \icmd{lamboot} Command} + +Many first-time Open MPI users do not have their environment properly +configured for Open MPI to boot properly. Refer to +Section~\ref{sec:getting-started-lamboot} for the list of conditions +that Open MPI requires to boot properly. User problems with \cmd{lamboot} +typically fall into one of the following categories: + +\begin{itemize} +\item \cmd{rsh}/\cmd{ssh} is not set up properly for password-less + logins to remote nodes. + + {\bf Solution:} Set up \cmd{rsh}/\cmd{ssh} properly for + password-less remote logins. Consult local documentation or + internet tutorials for how to set up \file{\$HOME/.rhosts} and SSH + keys. Note that the Open MPI Team {\bf STRONGLY} discourages the use of + \cmdarg{+} in \file{.rhosts} or \file{host.equiv} files! + +\item \cmd{rsh}/\cmd{ssh} prints something on \file{stderr}. + + {\bf Solution:} Clean up system or user ``dot'' files so that + nothing is printed on \file{stderr} during a remote login. + +\item A Open MPI daemon is unable to open a connection back to + \cmd{lamboot}. + + {\bf Solution:} Many Linux distributions ship with firewalls + enabled. Open MPI uses random TCP ports to communicate, and + therefore firewall support must be either disabled or opened between + machines that will be using Open MPI. + +\item Open MPI is unable to open a session directory. + + {\bf Solution:} Open MPI needs to use a per-user, per-session temporary + directory, typically located under \file{/tmp} (see + Section~\ref{sec:misc-session-directory}, + page~\pageref{sec:misc-session-directory}). Open MPI must be able to + read/write in this session directory; check permissions in this + tree. + +\item Open MPI is unable to find the current host in the boot schema. + + {\bf Solution:} Open MPI can only boot a universe that includes the + current node. If the current node is not listed in the hostfile, or + is not listed by a name that can be resolved and identified as the + current node, \cmd{lamboot} (and friends) will abort. + +\item Open MPI is unable to resolve all names in the boot schema. + + {\bf Solution:} All names in the boot schema must be resolvable by + the boot SSI module that is being used. This typically means that + there end up being IP hostnames that must be resolved to IP + addresses. Resolution can occur by any valid OS mechanism (e.g., + through DNS, local file lookup, etc.). Note that the name ``{\tt + localhost}'' (or any address that resolves to 127.0.0.1) cannot be + used in a boot schema that includes more than one host -- otherwise + the other nodes in the resulting Open MPI universe will not be able to + contact that host. +\end{itemize} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{MPI Problems} + +For the most part, Open MPI implements the MPI standard similarly to other +MPI implementations. Hence, most MPI programmers are not too +surprised by how Open MPI handles various errors, etc. However, there are +some cases that Open MPI handles in its own unique fashion. In these cases +Open MPI tries to display a helpful message discussing what happened. + +Here's some more background on a few of the messages: + +\begin{itemize} +\item ``One of the processes started by mpirun has exited with a + nonzero exit code.'' + + This means that at least one MPI process has exited after invoking + \mpifunc{MPI\_\-INIT}, but before invoking + \mpifunc{MPI\_\-FINALIZE}. This is therefore an error, and Open MPI + will abort the entire MPI application. The last line of the error + message indicates the PID, node, and exit status of the failed + process. + +\item ``MPI\_{\tt }: process in local group is dead (rank + {\tt }, MPI\_\-COMM\_\-WORLD)'' + + This means that some MPI function tried to communicate with a peer + MPI process and discovered that the peer process is dead. Common + causes of this problem include attempting to communicate with + processes that have failed (which, in some cases, won't generate the + ``One of the processes started by mpirun has exited...'' messages), + or have already invoked \mpifunc{MPI\_\-FINALIZE}. Communication + should not be initiated that could involve processes that have + already invoked \mpifunc{MPI\_\-FINALIZE}. This may include using + \mpiconst{MPI\_\-ANY\_\-SOURCE} or collectives on communicators that + include processes that have already finalized. +\end{itemize} diff --git a/doc/user/user.tex b/doc/user/user.tex new file mode 100644 index 0000000000..518e133380 --- /dev/null +++ b/doc/user/user.tex @@ -0,0 +1,47 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\documentclass[11pt]{book} + +\input{defs} + +\begin{document} + +\include{titlepage} + +\tableofcontents + +%\listoftables + +%\include{audience} +\include{introduction} +\include{release-notes} +%\include{getting-started} +%\include{mpi-details} +%\include{mca} +%\include{commands} +%\include{mca-orte} +%\include{mca-ompi} +%\include{debuggers} +%\include{troubleshooting} +%\include{misc} + +\include{bibliography} + +\printindex + +\end{document} diff --git a/doc/user/version.tex.in b/doc/user/version.tex.in new file mode 100644 index 0000000000..2271f79490 --- /dev/null +++ b/doc/user/version.tex.in @@ -0,0 +1,18 @@ +% -*- latex -*- +% +% Copyright (c) 2004-2005 The Trustees of Indiana University. +% All rights reserved. +% Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +% All rights reserved. +% Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +% University of Stuttgart. All rights reserved. +% Copyright (c) 2004-2005 The Regents of the University of California. +% All rights reserved. +% $COPYRIGHT$ +% +% Additional copyrights may follow +% +% $HEADER$ +% + +\def\ompiversion{@OMPI_VERSION@}