JUBE tutorial

This tutorial is meant to give you an overview about the basic usage of JUBE.

Installation

Requirements: JUBE needs Python 3.2 (or any higher version)

If you plan to use YAML based JUBE input files, you have to add the pyyaml module https://pyyaml.org to your Python module library. Additionally the ruamel.yaml module https://pypi.org/project/ruamel.yaml is optional. If installed it is used to verify the validity of the YAML files.

To use the JUBE command line tool, the PYTHONPATH must contain the position of the JUBE package. This can be achieved in different ways:

  • You can use the installation script to copy all files to the right position (preferred):

    >>> python setup.py install --user
    

    This will install the JUBE package files and executables to your $HOME/.local directory. Instead of --user also a user specific --prefix option is available. Here you might have to set the PYTHONPATH environment variable first (this will be mentioned during the install process).

  • You can utilize pip[3] to take care of the installation process (including the download)

    >>> pip3 install http://apps.fz-juelich.de/jsc/jube/jube2/download.php?version=latest --user
    # or
    >>> pip3 install http://apps.fz-juelich.de/jsc/jube/jube2/download.php?version=latest --prefix=...
    

    You might have to adjust your PYTHONPATH.

  • You can add the parent folder path of the JUBE package-folder (jube2 directory) to the PYTHONPATH environment variable:

    >>> export PYTHONPATH=<parent folder path>:$PYTHONPATH
    
  • You can move the JUBE package by hand to an existing Python package folder like site-packages

To use the JUBE command line tool like a normal command line command you can add it to the PATH environment variable:

>>> export PATH=$HOME/.local/bin:$PATH

To check your final installation, you can use

>>> jube --version

which should highlight the current version number.

Configuration

The main JUBE configuration bases on the given input configuration file. But in addition, some shell environment variables are available which can be used to set system specific options:

  • JUBE_INCLUDE_PATH: Can contain a list of paths (seperated by :) pointing to directories, which contain system relevant include configuration files. This technique can be used to store platform specific parameter in a platform specific directory.

  • JUBE_EXEC_SHELL: JUBE normally uses /bin/sh to execute the given shell commands. This default shell can be changed by using this environment variable.

  • JUBE_GROUP_NAME: JUBE will use the given UNIX groupname to share benchmarks between different users. The group must exist and the JUBE user must be part of this group. The given group will be the owner of new benchmark runs. By default (without setting the environment variable) all file and directory permissions are defined by the normal UNIX rules.

BASH autocompletion can be enabled by using the eval "$(jube complete)" command. You can store the command in your bash profile settings if needed.

Input format

JUBE supports two different types of input formats: XML based files and YAML based files. Both formats support the same amount of JUBE features and you can select your more preffered input format.

The following sections will always show all examples using both formats. However the explanations will mostly stick to the XML format but can be easily transfered to the YAML solution.

Both formats depends on a specifc special scharacter handling. More details can be found in the following FAQ sections:

Internally JUBE always uses the XML based format, by converting YAML based configuration files into XML if necessary. This is why parsing error messages might point to XML errors even if the YAML format was used.

Hello World

In this example we will show you the basic structure of a JUBE input file and the basic command line options.

The files used for this example can be found inside examples/hello_world.

The input file hello_world.xml:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<jube>
 3  <benchmark name="hello_world" outpath="bench_run">
 4    <comment>A simple hello world</comment>
 5
 6    <!-- Configuration -->
 7    <parameterset name="hello_parameter">
 8      <parameter name="hello_str">Hello World</parameter>
 9    </parameterset>
10    
11    <!-- Operation -->
12    <step name="say_hello">
13      <use>hello_parameter</use> <!-- use existing parameterset -->
14      <do>echo $hello_str</do> <!-- shell command -->
15    </step>    
16  </benchmark>
17</jube>

The input file hello_world.yaml:

 1name: hello_world
 2outpath: bench_run
 3comment: A simple hello world
 4
 5#Configuration
 6parameterset:
 7  name: hello_parameter
 8  parameter: {name: hello_str,  _: Hello World}
 9
10#Operation
11step:
12  name: say_hello
13  use: hello_parameter #use existing parameter
14  do: echo $hello_str #shell command

Every JUBE XML based input file starts (after the general XML header line) with the root tag <jube>. This root tag must be unique. XML does not allow multiple root tags.

The first tag which contains benchmark specific information is <benchmark>. hello_world is the benchmarkname which can be used to identify the benchmark (e.g. when there are multiple benchmarks inside a single input file, or when different benchmarks use the same run directory).

The outpath describes the benchmark run directory (relative to the position of the input file). This directory will be managed by JUBE and will be automatically created if it does not exist. The directory name and position are very important, because they are the main interface to communicate with your benchmark, after it was submitted.

Using the <comment> you can store some benchmark related comments inside the benchmark directory. You can also use normal XML-comments to structure your input-file:

<!-- your comment -->

In this benchmark a <parameterset> is used to store the single <parameter name="hello_str">. The name of the parameter should contain only letters, numbers (should not be the first character) or the _ (like a normal Python identifier). The name of the parameterset must be unique (relative to the current benchmark). In further examples we will see that there are more types of sets, which can be distinguished by their names. Also the name of the parameter must be unique (relative to the parameterset).

The <step> contains the operation tasks. The name must be unique. It can use different types of existing sets. All used sets must be given by name using the <use>. There can be multiple <use> inside the same <step> and also multiple names within the same <use> are allowed (separated by ,). Only sets, which are explicitly used, are available inside the step! The <do> contains a single shell command. This command will run inside of a sandbox directory environment (inside the outpath directory tree). The step and its corresponding parameter space is named workpackage.

Available parameters can be used inside the shell commands. To use a parameter you have to write

$parametername

or

${parametername}

The brackets must be used if you want variable concatenation. $hello_strtest will not be replaced, ${hello_str}test will be replaced. If a parameter does not exist or isn’t available the variable will not be replaced! If you want to use $ inside your command, you have to write $$ to mask the symbol. Parameter substitution will be done before the normal shell substitution!

To run the benchmark just type:

>>> jube run hello_world.xml

This benchmark will produce the follwing output:

 1######################################################################
 2# benchmark: hello_world
 3# id: 0
 4#
 5# A simple hello world
 6######################################################################
 7
 8Running workpackages (#=done, 0=wait, E=error):
 9############################################################ (  1/  1)
10
11  |  stepname | all | open | wait | error | done |
12  |-----------|-----|------|------|-------|------|
13  | say_hello |   1 |    0 |    0 |     0 |    1 |
14
15>>>> Benchmark information and further useful commands:
16>>>>       id: 0
17>>>>   handle: bench_run
18>>>>      dir: bench_run/000000
19>>>>  analyse: jube analyse bench_run --id 0
20>>>>   result: jube result bench_run --id 0
21>>>>     info: jube info bench_run --id 0
22>>>>      log: jube log bench_run --id 0
23######################################################################

As you can see, there was a single step say_hello, which runs one shell command echo $hello_str that will be expanded to echo Hello World.

The id is (in addition to the benchmark directory handle) an important number. Every benchmark run will get a new unique id inside the benchmark directory.

Inside the benchmark directory you will see the follwing structure:

 1bench_run               # the given outpath
 2|
 3+- 000000               # the benchmark id
 4   |
 5   +- configuration.xml # the stored benchmark configuration
 6   +- workpackages.xml  # workpackage information
 7   +- run.log           # log information
 8   +- 000000_say_hello  # the workpackage
 9      |
10      +- done           # workpackage finished marker
11      +- work           # user sandbox folder
12         |
13         +- stderr      # standard error messages of used shell commands
14         +- stdout      # standard output of used shell commands

stdout will contain Hello World in this example case.

Help

JUBE contains a command line based help functionality:

>>> jube help <keyword>

By using this command you will have direct access to all keywords inside the glossary.

Another useful command is the info command. It will show you information concerning your existing benchmarks:

1# display a list of existing benchmarks
2>>> jube info <benchmark-directory>
3# display information about given benchmark
4>>> jube info <benchmark-directory> -- id <id>
5# display information about a step inside the given benchmark
6>>> jube info <benchmark-directory> -- id <id> --step <stepname>

The third, also very important, functionality is the logger. Every run, continue, analyse and result execution will produce log information inside your benchmark directory. This file contains much useful debugging output.

You can easily access these log files by using the JUBE log viewer command:

>>> jube log [benchmark-directory] [--id id] [--command cmd]

e.g.:

>>> jube log bench_runs --command run

will display the run.log of the last benchmark found inside of bench_runs.

Log output can also be displayed during runtime by using the verbose output:

>>> jube -v run <input-file>

-vv can be used to display stdout output during runtime and -vvv will display the stdout output as well as the log output at the same time.

Since the parsing step is done before creating the benchmark directory, there will be a jube-parse.log inside your current working directory, which contains the parser log information.

Errors within a <do> command will create a log entry and stop further execution of the corresponding parameter combination. Other parameter combinations will still be executed by default. JUBE can also stop automatically any further execution by using the -e option:

>>> jube run -e <input-file>

There is also a debugging mode integrated in JUBE:

>>> jube --debug <command> [other-args]

This mode avoids any shell execution but will generate a single log file (jube-debug.log) in your current working directory.

Parameter space creation

In this example we will show you an important feature of JUBE: The automatic parameter space generation.

The files used for this example can be found inside examples/parameterspace.

The input file parameterspace.xml:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<jube>
 3  <benchmark name="parameterspace" outpath="bench_run">
 4    <comment>A parameterspace example</comment>
 5    
 6    <!-- Configuration -->
 7    <parameterset name="param_set">
 8      <!-- Create a parameterspace out of two template parameter -->
 9      <parameter name="number" type="int">1,2,4</parameter>
10      <parameter name="text" separator=";">Hello;World</parameter>
11    </parameterset>
12    
13    <!-- Operation -->
14    <step name="say_hello">
15      <use>param_set</use> <!-- use existing parameterset -->
16      <do>echo "$text $number"</do> <!-- shell command -->
17    </step>    
18  </benchmark>
19</jube>

The input file parameterspace.yaml:

 1name: parameterspace
 2outpath: bench_run
 3comment: A parameterspace example
 4
 5#Configuration
 6parameterset:
 7  name: param_set
 8  #Create a parameterspace out of two template parameter
 9  parameter:
10    - {name: number, type: int, _: "1,2,4"} #comma separated integer must be quoted
11    - {name: text, separator: ;, _: Hello;World}
12
13#Operation
14step:
15  name: say_hello
16  use: param_set #use existing parameterset
17  do: echo "$text $number" #shell command

Whenever a parameter contains a , (this can be changed using the separator attribute) this parameter becomes a template. A step which uses the parameterset containing this parameter will run multiple times to iterate over all possible parameter combinations. In this example the step say_hello will run 6 times:

|  stepname | all | open | wait | error | done |
|-----------|-----|------|------|-------|------|
| say_hello |   6 |    0 |    0 |     0 |    6 |

Every parameter combination will run in its own sandbox directory.

Another new keyword is the type attribute. The parameter type is not used inside the substitution process, but for sorting operations inside the result creation. The default type is string. Possible basic types are string, int and float.

Step dependencies

If you start writing a complex benchmark structure, you might want to have dependencies between different steps, for example between a compile and the execution step. JUBE can handle these dependencies and will also preserve the given parameter space.

The files used for this example can be found inside examples/dependencies.

The input file dependencies.xml:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<jube>
 3  <benchmark name="dependencies" outpath="bench_run">
 4    <comment>A Dependency example</comment>
 5    
 6    <!-- Configuration -->
 7    <parameterset name="param_set">
 8      <parameter name="number" type="int">1,2,4</parameter>
 9    </parameterset>
10    
11    <!-- Operations -->
12    <step name="first_step">
13      <use>param_set</use> <!-- use existing parameterset -->
14      <do>echo $number</do> <!-- shell command -->
15    </step>
16    
17    <!-- Create a dependency between both steps -->
18    <step name="second_step" depend="first_step">
19      <do>cat first_step/stdout</do> <!-- shell command -->
20    </step>    
21  </benchmark>
22</jube>

The input file dependencies.yaml:

 1name: dependencies
 2outpath: bench_run
 3comment: A Dependency example
 4
 5#Configuration
 6parameterset:
 7  name: param_set
 8  parameter: {name: number, type: int,  _: "1,2,4" } #comma separated integers must be quoted
 9
10#Operation
11step:
12  - name: first_step
13    use: param_set #use existing parameterset
14    do: echo $number #shell command
15  - name: second_step
16    depend: first_step #Create a dependency between both steps
17    do: cat first_step/stdout #shell command

In this example we create a dependency between first_step and second_step. After first_step is finished, the corresponding second_step will start. Steps can also have multiple dependencies (separated by , in the definition), but circular definitions will not be resolved. A dependency is a unidirectional link!

To communicate between a step and its dependency there is a link inside the work directory pointing to the corresponding dependency step work directory. In this example we use

cat first_step/stdout

to write the stdout-file content of the dependency step into the stdout-file of the current step.

Because the first_step uses a template parameter which creates three execution runs, there will also be three second_step runs each pointing to different first_step-directories:

|    stepname | all | open | wait | error | done |
|-------------|-----|------|------|-------|------|
|  first_step |   3 |    0 |    0 |     0 |    3 |
| second_step |   3 |    0 |    0 |     0 |    3 |

Loading files and substitution

Every step runs inside a unique sandbox directory. Usually, you will need to have external files inside this directory (e.g. the source files) and in some cases you want to change a parameter inside the file based on your current parameter space. There are two additional set-types which handle this behaviour inside of JUBE.

The files used for this example can be found inside examples/files_and_sub.

The input file files_and_sub.xml:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<jube>
 3  <benchmark name="files_and_sub" outpath="bench_run">
 4    <comment>A file copy and substitution example</comment>
 5
 6    <!-- Configuration -->
 7    <parameterset name="param_set">
 8      <parameter name="number" type="int">1,2,4</parameter>
 9      <parameter name="zahl" type="int">2,4,5</parameter>
10    </parameterset>
11
12    <!-- Files -->
13    <fileset name="files">
14      <copy>file.in</copy>
15    </fileset>
16
17    <!-- Substitute -->
18    <substituteset name="substitute">
19      <!-- Substitute files -->
20      <iofile in="file.in" out="file.out" />
21      <!-- Substitute commands -->
22      <sub source="#NUMBER#" dest="$number" />
23      <sub source="#[^NUMBER]+#" dest="$zahl" mode="regex"/>
24    </substituteset>
25
26    <!-- Operation -->
27    <step name="sub_step">
28      <use>param_set</use> <!-- use existing parameterset -->
29      <use>files</use>        <!-- use existing fileset -->
30      <use>substitute</use>   <!-- use existing substituteset -->
31      <do>cat file.out</do>   <!-- shell command -->
32    </step>
33  </benchmark>
34</jube>

The input file files_and_sub.yaml:

 1name: files_and_sub
 2outpath: bench_run
 3comment: A file copy and substitution example
 4
 5#Configuration
 6parameterset:
 7  name: param_set
 8  parameter:
 9    - {name: number, type: int,  _: "1,2,4"} #comma separated integers must be quoted
10    - {name: zahl, type: int,  _: "2,4,5"} #comma separated integers must be quoted
11
12#Files
13fileset:
14  name: files
15  copy: file.in
16
17#Substitute
18substituteset:
19  name: substitute
20  iofile: {in: file.in, out: file.out}
21  sub:
22    - {source: "#NUMBER#", dest: $number} #"#" must be quoted
23    - {source: "#[^NUMBER]+#", dest: $zahl, mode: "regex"} #"#" must be quoted
24
25#Operation
26step:
27  name: sub_step
28  use: 
29    - param_set #use existing parameterset
30    - files #use existing fileset
31    - substitute #use existing substituteset
32  do: cat file.out #shell command

The content of file file.in:

Number: #NUMBER#
Zahl: #ZAHL#

Inside the <fileset> the current location (relative to the current input file; also absolute paths are allowed) of files is defined. <copy> specifies that the file should be copied to the sandbox directory when the fileset is used. Also a <link> option is available to create a symbolic link to the given file inside the sandbox directory.

If there are additional operations needed to prepare your files (e.g. expand a tar-file). You can use the <prepare>-tag inside your <fileset>.

The <substituteset> describes the substitution process. The <iofile> contains the input and output filename. The path is relative to the sandbox directory. Because we do/should not know that location we use the fileset to copy file.in to this directory.

The <sub> specifies the substitution. All occurrences of source will be substituted by dest. As you can see, you can use parameters inside the substitution. In addition to the standard text substitution (see <sub source="#NUMBER#" ... />), the mode attribute (introduced in JUBE version 2.6.0) also allows regular expressions to be used for the substitution (see <sub mode="regex" source="#[^NUMBER]+#" ... />). The regular expression in this example searches for a capitalised text enclosed in #. It matches the following text in the file file.in: #ZAHL#.

There is no <use> inside any set. The combination of all sets will be done inside the <step>. So if you use a parameter inside a <sub> you must also add the corresponding <parameterset> inside the <step> where you use the <substituteset>!

In the sub_step we use all available sets. The use order is not relevant. The normal execution process will be:

  1. Parameter space expansion

  2. Copy/link files

  3. Prepare operations

  4. File substitution

  5. Run shell operations

The resulting directory-tree will be:

 1bench_run               # the given outpath
 2|
 3+- 000000               # the benchmark id
 4   |
 5   +- configuration.xml # the stored benchmark configuration
 6   +- workpackages.xml  # workpackage information
 7   +- 000000_sub_step   # the workpackage ($number = 1, $zahl = 2)
 8      |
 9      +- done           # workpackage finished marker
10      +- work           # user sandbox folder
11         |
12         +- stderr      # standard error messages of used shell commands
13         +- stdout      # standard output of used shell commands (Number: 1 Zahl: 2)
14         +- file.in     # the file copy
15         +- file.out    # the substituted file
16   +- 000001_sub_step   # the workpackage ($number = 1, $zahl = 4)
17      |
18      +- ...
19   +- ...

And the content of file file.out in 000000_sub_step/work:

Number: 1
Zahl: 2

Creating a result table

Finally, after running the benchmark, you will get several directories. JUBE allows you to parse your result files distributed over these directories to extract relevant data (e.g. walltime information) and create a result table.

The files used for this example can be found inside examples/result_creation.

The input file result_creation.xml:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<jube>
 3  <benchmark name="result_creation" outpath="bench_run">
 4    <comment>A result creation example</comment>
 5    
 6    <!-- Configuration -->
 7    <parameterset name="param_set">
 8      <!-- Create a parameterspace with one template parameter -->
 9      <parameter name="number" type="int">1,2,4</parameter>
10    </parameterset>
11    
12    <!-- Regex pattern -->
13    <patternset name="pattern_all">
14      <pattern name="number_pat" type="int">.*? $jube_pat_int</pattern>
15    </patternset>
16    <patternset name="pattern_en">
17      <pattern name="number_pat_en" type="int">Number: $jube_pat_int</pattern>
18    </patternset>
19    <patternset name="pattern_de">
20      <pattern name="number_pat_de" type="int">Zahl: $jube_pat_int</pattern>
21    </patternset>
22    
23    <!-- Operation -->
24    <step name="write_number">
25      <use>param_set</use> <!-- use existing parameterset -->
26      <do>echo "Number: $number" > en </do> <!-- shell command -->
27      <do>echo "Zahl: $number" > de </do> <!-- shell command -->
28    </step>
29    
30    <!-- Analyse -->
31    <analyser name="analyse">
32      <use>pattern_all</use> <!-- use this patternset for all files -->
33      <analyse step="write_number">
34        <file use="pattern_en">en</file> <!-- file en will be scanned with pattern_all and pattern_en -->
35        <file use="pattern_de">de</file> <!-- file de will be scanned with pattern_all and pattern_de -->
36      </analyse>
37    </analyser>
38    
39    <!-- Create result table -->
40    <result>
41      <use>analyse</use> <!-- use existing analyser -->
42      <table name="result" style="pretty" sort="number">
43        <column>number</column>
44        <column>number_pat</column> <!-- Column with title same as pattern name -->
45        <column title="Number">number_pat_en</column> <!-- Column with costum title -->
46        <column title="Zahl">number_pat_de</column>
47      </table>
48    </result>
49  </benchmark>
50</jube>

The input file result_creation.yaml:

 1name: result_creation
 2outpath: bench_run
 3comment: A result creation example
 4
 5#Configuration
 6parameterset:
 7  name: param_set
 8  #Create a parameterspace with one template parameter
 9  parameter: {name: number, type: int, _: "1,2,4"} # comma separated integer must be quoted
10
11#Regex pattern
12patternset:
13- name: pattern_all
14  pattern:
15  - {name: number_pat, type: int, _: ".*? $jube_pat_int"} # "?" must be quoted
16- name: pattern_en
17  pattern:
18  - {name: number_pat_en, type: int, _: "Number: $jube_pat_int"} # ":" must be quoted
19- name: pattern_de
20  pattern:
21  - {name: number_pat_de, type: int, _: "Zahl: $jube_pat_int"}
22
23#Operation
24step:
25  name: write_number
26  use: param_set #use existing parameterset
27  do:
28  - 'echo "Number: $number" > en'
29  - 'echo "Zahl: $number" > de' #shell commands
30
31#Analyse
32analyser:
33- name: analyse
34  use: pattern_all #use existing patternset for all files
35  analyse:
36    step: write_number
37    file:
38    - use: pattern_en  #use patternset only for this file
39      _: en
40    - use: pattern_de
41      _: de
42
43#Create result table
44result:
45  use: analyse #use existing analyser
46  table:
47    name: result
48    style: pretty
49    sort: number
50    column:
51    - number
52    - number_pat # Column with title same as pattern name
53    - { title: "Number", _: number_pat_en} # Column with costum title
54    - { title: "Zahl", _: number_pat_de}

Using <parameterset> and <step> we create three workpackages. Each writing Number: $number to en and Zahl: $number to de.

Now we want to parse these en and de files to extract information (in this example case the written number). First of all we have to declare a <patternset>. Here we can describe a set of <pattern>. A <pattern> is a regular expression which will be used to parse your result files and search for a given string. In this example we have the <pattern> number_pat which matches both file contents and the more specific version number_pat_en and number_pat_de. The name of the pattern must be unique (based on the usage of the <patternset>). The type is optional. It is used when the extracted data will be sorted. The regular expression can contain other patterns or parameters. The example uses $jube_pat_int which is a JUBE default pattern matching integer values. The pattern can contain a group, given by brackets (...), to declare the extraction part ($jube_pat_int already contains these brackets).

E.g. $jube_pat_int and $jube_pat_fp are defined in the following way:

<pattern name="jube_pat_int" type="int">([+-]?\d+)</pattern>
<pattern name="jube_pat_fp" type="float">([+-]?\d*\.?\d+(?:[eE][-+]?\d+)?)</pattern>

A complete list of predefined patterns is in the glossary. If there are multiple matches inside a single file you can add a reduce option. By default, only the first match will be extracted.

To use your <patternset> you have to specify the files which should be parsed. This can be done using the <analyser>. It uses relevant patternsets. Inside the <analyse> a step-name and a file inside this step is given. Every workpackage file combination and every analyser will create its own result entry. Additional <patternset> can be used inside the <file> tag in order to apply this set only to one file.

The analyser automatically knows all parameters which were used in the given step and in depending steps. There is no <use> option to include additional <parameterset> that have not been already used within the analysed <step>.

To run the anlayse you have to write:

>>> jube analyse bench_run

The analyse data will be stored inside the benchmark directory.

The last part is the result table creation. Here you have to use an existing analyser. The <column> contains a pattern or a parameter name. sort is the optional sorting order (separated by ,). The style attribute can be csv, pretty or aligned to get different ASCII representations.

To create the result table you have to write:

>>> jube result bench_run -i last

If you run the result command for the first time, the analyse step will be executed automatically, if it wasn’t executed before. So it is not necessary to run the separate analyse step all the time. However you need the separate analyse if you want to force a re-run of the analyse step, otherwise only the stored values of the previous analyse will be used in the result step.

The analyse and result instructions can be combined within one single command:

>>> jube result bench_run -a

The result table will be written to STDOUT and into a result.dat file inside bench_run/<id>/result.

The --id or -i option can be used to output the result of a specific benchmark ID. If this option is not set, the result of the last benchmark will be shown (i.e. the default is last).

Output of the given example:

1| number | number_pat | Number | Zahl |
2|--------|------------|--------|------|
3|      1 |          1 |      1 |    1 |
4|      2 |          2 |      2 |    2 |
5|      4 |          4 |      4 |    4 |

If you want to hide or show only certain output columns, you can use the --select and --exclude options since JUBE version 2.6.0. These options take parameter and pattern names as arguments. For example, you can use the following commands to display only the number column of the result table:

>>> jube result bench_run --select number

or

>>> jube result bench_run --exclude number_pat number_pat_en number_pat_de

The specified columns are hidden not only in the output, but also in the results file. Both options can be given on the command line, and only the columns included in --select and not --exclude will be displayed.

This was the last example of the basic JUBE tutorial. Next you can start the advanced tutorial to get more information about including external sets, jobsystem representation and scripting parameter.