%%%begin-myprojects
\documentclass[hyperref={colorlinks=true}]{beamer}

\usepackage{fancyvrb,relsize}
\usepackage{graphicx}

\setbeamertemplate{navigation symbols}{}

%\usetheme{Boadilla}
%\usetheme{CambridgeUS}
%\usetheme{Malmoe}
%\usetheme{Singapore}
%\usetheme{boxes}

%\usecolortheme{crane}
%\usecolortheme{dove}
\usecolortheme{seagull} % very cool with \usetheme{default}
%\usefonttheme{professionalfonts}
%\useinnertheme{rectangles}

\mode<presentation>
\title{paexec -- distributes tasks over network or CPUs}
\author{Aleksey Cheusov \\ \texttt{vle@gmx.net}}
\date{Minsk, Belarus, 2013}

\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newenvironment{CodeSmall}[1]%
               {\Verbatim[label=\bf{#1},frame=single,%
                   fontsize=\footnotesize,%
                   commandchars=\\\{\}]}%
               {\endVerbatim}
\newenvironment{CodeSmallNoLabel}%
               {\Verbatim[frame=single,%
                   fontsize=\footnotesize,%
                   commandchars=\\\{\}]}%
               {\endVerbatim}

\newenvironment{Code}[1]%
              {\Verbatim[label=\bf{#1},frame=single,%
                  fontsize=\small,%
                  commandchars=\\\{\}]}%
              {\endVerbatim}
\newenvironment{CodeNoLabel}%
               {\Verbatim[frame=single,%
                   fontsize=\small,%
                   commandchars=\\\{\}]}%
               {\endVerbatim}

\newenvironment{CodeLarge}[1]%
               {\Verbatim[label=\bf{#1},frame=single,%
                   fontsize=\large,%
                   commandchars=\\\{\}]}%
               {\endVerbatim}
\newenvironment{CodeLargeNoLabel}%
               {\Verbatim[frame=single,%
                   fontsize=\large,%
                   commandchars=\\\{\}]}%
               {\endVerbatim}

%\newcommand{\prompt}[1]{\textcolor{blue}{#1}}
%\newcommand{\prompt}[1]{\textbf{#1}\textnormal{}}
\newcommand{\prompt}[1]{{\bf{#1}}}
%\newcommand{\h}[1]{\textbf{#1}}
%\newcommand{\h}[1]{\bf{#1}\textnormal{}}
\newcommand{\h}[1]{{\bf{#1}}}
\newcommand{\name}[1]{{\tt{#1}}}
\newcommand{\URL}[1]{\textbf{#1}}
\newcommand{\AutohellFile}[1]{\textcolor{red}{#1}}
\newcommand{\MKCfile}[1]{\textcolor{green}{#1}}
\newcommand{\ModuleName}[1]{\textbf{#1}\textnormal{}}
\newcommand{\ProgName}[1]{\textbf{#1}\textnormal{}}
\newcommand{\ProjectName}[1]{\textbf{#1}\textnormal{}}
\newcommand{\PackageName}[1]{\textbf{#1}\textnormal{}}
\newcommand{\MKC}[1]{\large\textsf{#1}\textnormal{}\normalsize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \begin{frame}
%%   \frametitle{qqq}
%%   \begin{code}{files in the directory}
%%     bla bla bla
%%   \end{code}
%% \end{frame}

%%%end-myprojects

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}
  \titlepage
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{}
  \frametitle{Problem}
  \begin{block}{}
    \begin{itemize}
    \item Huge amount of data to process
    \item Typical desktop machines have more than one CPU
    \item Unlimited resources are available on the Internet
    \item Heterogeneous environment (*BSD, Linux, Windows...)
    \end{itemize}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Solution}

  \begin{block}{}
      \begin{CodeLarge}{Usage}
paexec [OPTIONS] \textbackslash
  -n 'machines or CPUs' \textbackslash
  -t 'transport program' \textbackslash
  -c 'calculator' < tasks
      \end{CodeLarge}
      \begin{CodeLarge}{example}
ls -1 *.wav | \textbackslash
paexec -x -c 'flac -s' -n +4 > /dev/null
      \end{CodeLarge}
      \begin{CodeLarge}{example}
paexec \textbackslash
  -n 'host1 host2 host3' \textbackslash
  -t /usr/bin/ssh \textbackslash
  -c ~/bin/toupper < tasks
      \end{CodeLarge}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
  Our goal is to convert strings to upper case in parallel
  \begin{block}{}
      \begin{Code}{\~{}/bin/toupper}
#!/usr/bin/awk -f
\{
   print " ", toupper(\$0)
   print ""  # empty line -- end-of-task marker!
   fflush()  # We must flush stdout!
\}
      \end{Code}
  \end{block}
  \begin{block}{}
      \begin{Code}{\~{}/tmp/tasks}
apple
bananas
orange
      \end{Code}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
\name{\~{}/bin/toupper} script will be run only once on remote servers
``server1'' and ``server2''.  It takes tasks from stdin (one task per
line). Transport program is \name{ssh(1)}.
  \begin{block}{}
      \begin{CodeLarge}{paexec invocation}
\prompt{\$} paexec \h{-t} ssh \h{-c} ~/bin/toupper \textbackslash
   \h{-n} 'server1 server2' < tasks > results
\prompt{\$} cat results
 BANANAS
 ORANGE
 APPLE
\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
Options \h{-l} and \h{-r} add the task number and server where this
task is processed to stdout.
  \begin{block}{}
      \begin{CodeLarge}{paexec -lr invocation}
\prompt{\$} paexec \h{-lr} -t ssh -c ~/bin/toupper \textbackslash
   -n 'server1 server2' < tasks > results
\prompt{\$} cat results
\h{server2 2}  BANANAS
\h{server2 3}  ORANGE
\h{server1 1}  APPLE
\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
The same as above but four instances of \name{\~{}/bin/toupper} are ran locally.
  \begin{block}{}
      \begin{CodeLarge}{paexec invocation}
\prompt{\$} paexec \h{-n} +4 -c ~/bin/toupper
   < tasks > results
\prompt{\$} cat results
BANANAS
ORANGE
APPLE
\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
The same as above but without \name{\~{}/bin/toupper}.  In this example we
run AWK program for each individual task.  At the same time we still
make only one ssh connection to each server regardless of a number of
tasks given on input.
  \begin{block}{}
      \begin{CodeLarge}{paexec invocation}
\prompt{\$} paexec \h{-x} -t ssh -n 'server1 server2' \textbackslash
\h{-c} "awk 'BEGIN \{print toupper(ARGV[1])\}' " \textbackslash
    < tasks > results
\prompt{\$} cat results
ORANGE
BANANAS
APPLE
\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
If we want to "shquate" less one can use option \h{-C} instead of \h{-c}
and specify command after options.
  \begin{block}{}
      \begin{CodeLarge}{paexec invocation}
\prompt{\$} paexec -x \h{-C} -t ssh -n 'server1 server2' \textbackslash
awk 'BEGIN \{print toupper(ARGV[1])\}' \textbackslash
    < tasks > results
\prompt{\$} cat results
ORANGE
BANANAS
APPLE
\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 1: toupper}
With options \h{-z} or \h{-Z} we can easily run our tasks on
unreliable hosts. If we cannot connect or lost connection to the
server, paexec will redistribute failed tasks to another server.
  \begin{block}{}
      \begin{CodeLarge}{paexec invocation}
\prompt{\$} paexec \h{-Z}240 -x -t ssh \textbackslash
-n 'server1 badhostname server2' \textbackslash
-c "awk 'BEGIN \{print toupper(ARGV[1])\}' " \textbackslash
    < tasks > results
{\it ssh: Could not resolve hostname badhostname:}
{\it  No address associated with hostname}
{\it  badhostname 1 fatal}
\prompt{\$} cat results
ORANGE
BANANAS
APPLE
\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\linespread{0.5}
\begin{frame}[fragile]
  \frametitle{Example 2: parallel banner(1)}

  \begin{block}{}
      \begin{CodeLarge}{what is banner(1)?}
\prompt{\$} banner -f @ NetBSD

@     @                 @@@@@@   @@@@@  @@@@@@
@@    @  @@@@@@   @@@@@ @     @ @     @ @     @
@ @   @  @          @   @     @ @       @     @
@  @  @  @@@@@      @   @@@@@@   @@@@@  @     @
@   @ @  @          @   @     @       @ @     @
@    @@  @          @   @     @ @     @ @     @
@     @  @@@@@@     @   @@@@@@   @@@@@  @@@@@@


\prompt{\$}
      \end{CodeLarge}
  \end{block}
\end{frame}
\linespread{1}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 2: parallel banner(1)}
\name{\~{}/bin/pbanner} is wrapper for \name{banner(1)} for reading tasks line by line.
Magic line is used instead empty line as an end-of-task marker.
  \begin{block}{}
      \begin{Code}{\~{}/bin/pbanner}
#!/usr/bin/env sh

while read task; do
   banner -f M "\$task" |
   echo \h{"\$PAEXEC\_EOT"} # end-of-task marker
done
      \end{Code}
      \begin{Code}{tasks}
pae
xec
      \end{Code}

      \begin{Code}{paexec invocation}
\prompt{\$} paexec -l \h{-mt='SE@X-L0S0!&'} -c ~/bin/pbanner \textbackslash
   -n +2 < tasks > result
\prompt{\$}
      \end{Code}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\linespread{0.5}
\begin{frame}[fragile]
  \frametitle{Example 2: parallel banner(1)}
\name{paexec(1)} reads calculator's output asynchronously.
So, its output is sliced.
  \begin{block}{}
      \begin{CodeSmall}{Sliced result}
\prompt{\$} cat result
2 
2 
2  M    M  MMMMMM   MMMM
2   M  M   M       M    M
1 
1 
1  MMMMM     MM    MMMMMM
1  M    M   M  M   M
1  M    M  M    M  MMMMM
1  MMMMM   MMMMMM  M
2    MM    MMMMM   M
2    MM    M       M
2   M  M   M       M    M
2  M    M  MMMMMM   MMMM
2 
1  M       M    M  M
1  M       M    M  MMMMMM
1 
\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}
\linespread{1}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\linespread{0.5}
\begin{frame}[fragile]
  \frametitle{Example 2: parallel banner(1)}
\name{paexec\_reorder(1)} normalizes \name{paexec(1)}'s output.
  \begin{block}{}
      \begin{CodeSmall}{Ordered result}
\prompt{\$} paexec_reorder \h{-mt='SE@X-L0S0!&'} results


MMMMM     MM    MMMMMM
M    M   M  M   M
M    M  M    M  MMMMM
MMMMM   MMMMMM  M
M       M    M  M
M       M    M  MMMMMM



M    M  MMMMMM   MMMM
 M  M   M       M    M
  MM    MMMMM   M
  MM    M       M
 M  M   M       M    M
M    M  MMMMMM   MMMM


\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}
\linespread{1}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\linespread{0.5}
\begin{frame}[fragile]
  \frametitle{Example 2: parallel banner(1)}
The same as above but using magic end-of-task marker provided by \name{paexec(1)}.
  \begin{block}{}
      \begin{CodeSmall}{Ordered result}
\prompt{\$} paexec \h{-y} -lc ~/bin/pbanner -n+2 < tasks | paexec_reorder \h{-y}


MMMMM     MM    MMMMMM
M    M   M  M   M
M    M  M    M  MMMMM
MMMMM   MMMMMM  M
M       M    M  M
M       M    M  MMMMMM



M    M  MMMMMM   MMMM
 M  M   M       M    M
  MM    MMMMM   M
  MM    M       M
 M  M   M       M    M
M    M  MMMMMM   MMMM


\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}
\linespread{1}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\linespread{0.5}
\begin{frame}[fragile]
  \frametitle{Example 2: parallel banner(1)}
For this trivial task wrapper like \name{\~{}/bin/pbanner} is not needed.
We can easily run \name{banner(1)} directly.
  \begin{block}{}
      \begin{CodeSmall}{Sliced result}
\prompt{\$} paexec -l \h{-x} -c banner -n+2 < tasks
2 
2 
2  M    M  MMMMMM   MMMM
2   M  M   M       M    M
2    MM    MMMMM   M
2    MM    M       M
2   M  M   M       M    M
1 
1 
1  MMMMM     MM    MMMMMM
1  M    M   M  M   M
1  M    M  M    M  MMMMM
1  MMMMM   MMMMMM  M
2  M    M  MMMMMM   MMMM
2 
1  M       M    M  M
1  M       M    M  MMMMMM
1 
\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}
\linespread{1}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
\name{paexec(1)} is able to build tasks taking into account their ``dependencies''.
Here ``devel/gmake'' and others are pkgsrc packages. Our goal in this example
is to build pkgsrc package audio/abcde and all its build-time and compile-time
dependencies.
  \begin{block}{}
    \begin{figure}
      \includegraphics[width=\textwidth, height=\textheight, keepaspectratio=true]{dep-graph.eps}
    \end{figure}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
\name{``paexec \h{-g}''} takes a dependency graph on input (in \name{tsort(1)} format).
Tasks are separated by space (\name{paexec -md=}).
  \begin{block}{}
      \begin{CodeSmall}{\~{}/tmp/packages\_to\_build}
audio/cd-discid audio/abcde
textproc/gsed audio/abcde
audio/cdparanoia audio/abcde
audio/id3v2 audio/abcde
audio/id3 audio/abcde
misc/mkcue audio/abcde
shells/bash audio/abcde
devel/libtool-base audio/cdparanoia
devel/gmake audio/cdparanoia
devel/libtool-base audio/id3lib
devel/gmake audio/id3v2
audio/id3lib audio/id3v2
devel/m4 devel/bison
lang/f2c devel/libtool-base
devel/gmake misc/mkcue
devel/bison shells/bash
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
If option -g is applied, every task may succeed or fail. In case of failure
all dependants fail recursively.
For this to work we have to slightly adapt ``calculator''.
  \begin{block}{}
      \begin{CodeSmall}{\~{}/bin/pkg\_builder}
#!/usr/bin/awk -f

\{
   print "build " \$0
   \h{print "success"} # build succeeded! (paexec -ms=)
   print ""        # end-of-task marker
   fflush()        # we must flush stdout
\}
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}

  \begin{block}{}
      \begin{CodeSmall}{paexec -g invocation (no failures)}
\prompt{\$} paexec \h{-g} -l -c ~/bin/pkg_builder -n 'server2 server1' \textbackslash
    -t ssh < ~/tmp/packages_to_build | paexec_reorder > result
\prompt{\$} cat result
build textproc/gsed
\h{success}
build devel/gmake
success
build misc/mkcue
success
build devel/m4
success
build devel/bison
success
...
build audio/id3v2
success
build audio/abcde
success
\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
Let's suppose that ``devel/gmake'' fails to build.

  \begin{block}{}
      \begin{CodeSmall}{\~{}/bin/pkg\_builder}
#!/usr/bin/awk -f

\{
   print "build " \$0
   if (\$0 == "devel/gmake")
      \h{print "failure"} # Oh no...
   else
      print "success" # build succeeded!

   print ""        # end-of-task marker
   fflush()        # we must flush stdout
\}
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
Package ``devel/gmake'' and all dependants are marked as failed.
Even if failures happen, the build continues.
  \begin{block}{}
      \begin{CodeSmall}{paexec -g invocation (with failures)}
\prompt{\$} paexec -gl -c ~/bin/pkg_builder -n 'server2 server1' \textbackslash
    -t ssh < ~/tmp/packages_to_build | paexec_reorder > result
\prompt{\$} cat result
build audio/cd-discid
success
build audio/id3
success
build devel/gmake
\h{failure}
\h{devel/gmake audio/cdparanoia audio/abcde audio/id3v2 misc/mkcue}
build devel/m4
success
build textproc/gsed
success
...
\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
paexec is resistant not only to network failures but also to
\h{unexpected} calculator \h{exits or crashes}.
  \begin{block}{}
      \begin{CodeSmall}{\~{}/bin/pkg\_builder}
#!/usr/bin/awk -f

\{
   "hostname -s" | getline hostname
   print "build " \$0 " on " hostname

   if (hostname == "server1" && \$0 == "textproc/gsed")
      \h{exit 139}
      # Damn it, I'm dying...
      # Take a note that exit status doesn't matter.
   else
      print "success" # Yes! :-)

   print ""        # end-of-task marker
   fflush()        # we must flush stdout
\}
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 3: dependency graph of tasks}
``textproc/gsed'' failed on ``server1'' but then succeeded on ``server2''.
Every 300 seconds we try to reconnect to ``server1''. Keywords ``success'',
``failure'' and ``fatal'' may be changed with a help of -ms=, -mf= and
-mF= options respectively.
  \begin{block}{}
      \begin{CodeSmall}{paexec -Z300 invocation (with failure)}
\prompt{\$} paexec -gl -Z300 -t ssh -c ~/bin/pkg_builder \textbackslash
      -n 'server2 server1' < ~/tmp/packages_to_build \textbackslash
      | paexec_reorder > result
\prompt{\$} cat result
build audio/cd-discid on server2
success
\h{build textproc/gsed on server1}
\h{fatal}
\h{build textproc/gsed on server2}
\h{success}
build audio/id3 on server2
success
...
\prompt{\$}
      \end{CodeSmall}
  \end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 4: Converting .wav files to .flac or .ogg}
In trivial cases we don't need relatively complex ``calculator''.
Running a trivial command may be enough.
Below we run three .wav to .flac/.ogg convertors in parallel.
If \h{-x} is applied, task is passed to calculator as an argument.
\begin{block}{}
  \begin{CodeSmall}{paexec -x invocation}
\prompt{\$} ls -1 *.wav | paexec \h{-x} -c 'flac -s' -n+3 >/dev/null
\prompt{\$}
  \end{CodeSmall}
\end{block}
\begin{block}{}
  \begin{CodeSmall}{paexec -x invocation}
\prompt{\$} ls -1 *.wav | paexec -ixC -n+3 oggenc -Q | grep .
01-Crying_Wolf.wav
02-Autumn.wav
03-Time_Heals.wav
04-Alice_(Letting_Go).wav
05-This_Side_Of_The_Looking_Glass.wav
...
\prompt{\$}
  \end{CodeSmall}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 5: paexec -W}
If different tasks take different amount of time to process, than it
makes sense to process ``heavier'' ones earlier in order to minimize
total calculation time. For this to work one can weigh each tasks.
Note that this mode enables ``graph'' mode automatically.
\begin{block}{}
  \begin{CodeSmall}{\~{}/bin/calc}
#!/bin/sh
# \$1 -- task given on input
if test \$1 = huge; then
    sleep 6
else
    sleep 1
fi

echo "task \$1 done"
  \end{CodeSmall}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 5: paexec -W}
This is how we run unweighted tasks. The whole process takes 8 seconds.
\begin{block}{}
  \begin{CodeSmall}{paexec invocation}
\prompt{\$} printf 'small1\textbackslash{nsmall2}\textbackslash{nsmall3}\textbackslash{nsmall4}\textbackslash{nsmall5}\textbackslash{nhuge}\textbackslash{n}' |
time -p paexec -c \~{}/bin/calc -n +2 -xg | grep -v success
task small2 done
task small1 done
task small3 done
task small4 done
task small5 done
task huge done
real         8.04
user         0.03
sys          0.03
\prompt{\$}
  \end{CodeSmall}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{Example 5: paexec -W}
If we say paexec that the task ``huge'' is performed 6 times longer than others,
it starts``huge'' first and then others. In total we spend 6 seconds for all tasks.
\begin{block}{}
  \begin{CodeSmall}{paexec -W1 invocation}
\prompt{\$} printf 'small1\textbackslash{nsmall2}\textbackslash{nsmall3}\textbackslash{nsmall4}\textbackslash{nweight: huge 6}\textbackslash{n}' |
time -p paexec -c \~{}/bin/calc -n +2 -x \h{-W1} | grep -v success
task small1 done
task small2 done
task small3 done
task small4 done
task small5 done
task huge done
real         6.02
user         0.03
sys          0.02
\prompt{\$}
  \end{CodeSmall}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}[fragile]
  \frametitle{}
  For details see the manual page.
  \begin{center}
    \huge
    The End
  \end{center}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\end{document}
