JUBE Conversion

Experimental Feature

JUBE conversion is experimental. It may contain bugs or undergo breaking changes in future releases. Please report any issues you encounter.

Convert existing JUBE benchmark configurations to IOPS format using iops convert.


Overview

JUBE (Juelich Benchmarking Environment) is an HPC benchmarking framework that uses XML configurations. iops convert provides a best-effort translation of JUBE benchmarks to IOPS YAML, using JUBE’s own Python library to parse the XML for accurate interpretation of JUBE-specific syntax. The output includes TODO markers for features that require manual adjustment.

Prerequisites

The JUBE Python library must be installed (JUBE is not available on PyPI):

pip install git+https://github.com/FZJ-JSC/JUBE.git

If iops convert is run without JUBE installed, it displays installation instructions.


Usage

iops convert <input.xml> [options]

Arguments:

  • input.xml (positional) - Path to the JUBE XML benchmark file

Options:

  • -o, --output PATH - Output YAML path (default: <input_stem>_iops.yaml)
  • --benchmark NAME - Select a specific benchmark if the XML contains multiple
  • --executor {local,slurm} - Target executor (default: local)
  • -n, --dry-run - Print converted YAML to stdout instead of writing a file

Examples:

# Basic conversion
iops convert benchmark.xml

# SLURM target, custom output path, preview only
iops convert benchmark.xml -o my_config.yaml --executor slurm --dry-run

# Select specific benchmark from multi-benchmark XML
iops convert multi.xml --benchmark ior_bench

Concept Mapping

JUBE ElementIOPS EquivalentNotes
<parameter> (comma-separated values)vars[].sweep.mode=listValues split by separator, cast to type
<parameter> (single value)vars[] with literal valueNo sweep
<parameter mode="python">vars[].expr$var converted to {{ var }}
<parameter mode="shell">TODO markerCannot auto-convert
<step> with <do> operationsscripts[].script_templateOperations concatenated
Variable substitution ($var)Jinja2 {{ var }}Automatic syntax conversion
<fileset> (copy/link)Shell commands in script preamblecp -r / ln -sf commands
<patternset> (regex)scripts[].parser.parser_scriptGenerates Python parse() function
Derived patternComputed metric in parserExpression converted to Python
<analyser>scripts[].parserMaps output file and metrics
<result> tableoutput.sink type=csvDefault CSV output
Step iterationsbenchmark.repetitionsApproximate mapping

Example Walkthrough

Input: JUBE XML

<?xml version="1.0" encoding="UTF-8"?>
<jube>
  <benchmark name="io_bench" outpath="bench_run">
    <comment>I/O performance benchmark</comment>

    <parameterset name="system_params">
      <parameter name="nodes" type="int">1,2,4,8</parameter>
      <parameter name="ppn" type="int">4,8</parameter>
      <parameter name="total_procs" type="int" mode="python">
        $nodes * $ppn
      </parameter>
    </parameterset>

    <step name="execute">
      <use>system_params</use>
      <do>mpirun -np $total_procs ./io_benchmark --nodes $nodes</do>
    </step>

    <patternset name="metrics">
      <pattern name="bandwidth" type="float">
        Bandwidth: $jube_pat_fp MB/s
      </pattern>
    </patternset>

    <analyser name="analyse">
      <use>metrics</use>
      <analyse step="execute">
        <file>stdout</file>
      </analyse>
    </analyser>
  </benchmark>
</jube>

Command

iops convert io_bench.xml -o io_bench_iops.yaml

Output: IOPS YAML

benchmark:
  name: io_bench
  description: I/O performance benchmark
  workdir: ./workdir
  executor: local
  search_method: exhaustive
  repetitions: 1

vars:
  nodes:
    type: int
    sweep:
      mode: list
      values: [1, 2, 4, 8]
  ppn:
    type: int
    sweep:
      mode: list
      values: [4, 8]
  total_procs:
    type: int
    expr: "{{ nodes * ppn }}"

command:
  template: "mpirun -np {{ total_procs }} ./io_benchmark --nodes {{ nodes }}"

scripts:
  - name: main
    submit: bash
    script_template: |
      #!/bin/bash

      {{ command.template }}      
    parser:
      file: "{{ execution_dir }}/stdout"
      metrics:
        - name: bandwidth
      parser_script: |
        import re

        def parse(file_path):
            results = {}
            with open(file_path) as f:
                content = f.read()
            m = re.search(r"Bandwidth: ([+-]?(?:\d*\.?\d+(?:[eE][-+]?\d+)?|\d+\.))", content)
            if m:
                results["bandwidth"] = float(m.group(1))
            return results        

output:
  sink:
    type: csv
    path: "{{ workdir }}/results.csv"

Limitations and Manual Adjustments

The following JUBE features cannot be automatically converted and produce TODO markers or warnings:

Parameters:

  • Shell-mode parameters (mode="shell") execute shell commands to compute values. Replace manually with IOPS expressions or pre-computed values.
  • Perl-mode parameters are not supported.

Workflow:

  • Multi-step DAG workflows are flattened. JUBE allows step dependencies as a directed acyclic graph; IOPS uses a flat script model. Steps are concatenated in dependency order but may need restructuring.
  • Step cycles (cycles attribute) have no direct equivalent. Consider increasing repetitions or restructuring the workflow.
  • Shared directories between workpackages are not supported in IOPS.

Execution:

  • Async operations (checking for completion files) are handled differently by IOPS executors. Remove async-related operations from the script template.
  • Substitutesets targeting external files (not the script template) are not converted. Add file manipulation to the script preamble if needed.

Other:

  • JUBE internal variables ($jube_wp_id, $jube_wp_relpath, etc.) are preserved as-is and should be replaced with IOPS equivalents ({{ execution_id }}, {{ execution_dir }}, etc.).
  • Tag-based parameter selection is simplified to static values.

Post-Conversion Validation

Always validate and preview before running:

iops check io_bench_iops.yaml       # Validate the generated configuration
iops run io_bench_iops.yaml --dry-run  # Preview the execution plan
iops run io_bench_iops.yaml         # Run the benchmark

Search for TODO markers in the generated YAML and address them before execution. The converter prints a summary of warnings to help identify areas needing attention.