Lesson 4: Introduction to the DynRM Resource Manager

../_images/dynrm.png

DynRM is a modular resource manager written in Python and is part of the DynRes software project. It supports the DPP design principles for dynamic resource management. DynRM is developed to support research on novel, dynamic scheduling optimizations.


Modular Architecture

The modular architecture of DynRM allows simple customizations/extension to target particular use case scenarios. I.e. custom modules can be written and used with DynRM for the following components:

../_images/architecture.png

  • resource manager

  • system

  • process manager

  • policy

  • event loop

  • RPC

  • logging

  • submission

  • topologies

  • performance models

  • COL creation





DynRM uses a graph-based system representation:

  • Topology Graph: The topology graph contains system components (such as nodes, cores, …) as vertices and relations between components (such as containment) as edges. When only considering containment relations, the topology graph is a tree.

  • Task Graphs: The Task Graphs represent user submissions, i.e. a set of one or more jobs/tasks (vertices) possibly with dependencies (edges). This representation therefore also covers workflows.

  • PSet Graphs: The PSet Graphs consists of Process Sets (vertices) and Process Set Operations (edges). The PSet Graphs establish a mapping between the Task Graphs and the Topology Graph and is the basis of the DPP-based approach for dynamic resources.

Commands

While a completely custom DynRM instance can be created via the Python API, DynRM provides a high-level command to run experiments with limited options for customizations:

dynrm_run [OPTIONS]
    OPTIONS:
        --topology_file=[path/to/file]          // Path to file containing the topology description (yaml)
        --submission_file=[path/to/file]        // Path to .batch or .mix file containing the topology description (yaml/csv)
        --policy=[policy_class]                 // Name of the policy class to be used for scheduling
        --policy_params=["{'key': 'val'}"]      // Python dictionary containing policy parameters
        --verbosity=[verbosity]                 // Verbosity level to be used for printing
        --output_dir=[dirname]                  // Name of the outputdir to store DynRM logging data

Examples:

  • topology_file.yaml:

topology:
nodes:
    n1:
        num_cores: 8
    n2:
        num_cores: 8
  • submission.batch:

tasks: # Define the list of tasks of the workflow
    -   name:  "Expand Task" # The name of the task
        executable: "/opt/hpc/build/dyn_rm_examples/submissions/sleep_expand_dynrm_nb.sh" # The task executable
        arguments:
            - "arg"
        # Parameters for initial launch
        launch_generator:
            function: "output_space_generator_launch"       # Output space generator function to use
            model: "AmdahlPsetModel"    # PSet Model to use
            model_params:   # PSet Model parameters
                t_s: 1
                t_p: 300
            mapping : "dense"   # Use all cores on node, other options: 'sparse' -> 1 proc per node, 'N:node' -> N procs per node
            num_procs : 8       # Number of processes to start with

        # Parameters for reconfigurations
        generators:
            - key: "replace_generator"      # key to be used to reference this COL info
              function: "output_space_generator_replace"
              model: "AmdahlPsetModel"
              model_params:
                't_s': 1
                't_p' : 300
              num_procs_add: 8  # Allow adding exactly 8 procs per reconfiguration
              mapping: "dense"
  • submission.mix:


Arrival Time

Batch file

Parameters

1

/opt/hpc/build/dyn_rm_examples/submissions/job1.batch

20

/opt/hpc/build/dyn_rm_examples/submissions/job2.batch

40

/opt/hpc/build/dyn_rm_examples/submissions/job3.batch

{‘terminate_soon’: True}

Hands-On

Change to the ‘dyn_rm_examples’ directory.

(tutorial_dynreshpc26) [mpiuser@n1 mpi_tests]$ cd /opt/hpc/build/dyn_rm_examples

Example 1:

In our first example we will run a single job:

  • on a system with 8 nodes, each with 8 cores

  • which starts with exactly 8 processes

  • mapping: 1 process per core

  • allows adding exactly 8 processes per reconfiguration

  • scheduled by the Discrete_Steepest_Ascend [sic] policy

(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ time dynrm_run \
    --topology_file=topology_files/8_node_system.yaml \
    --submission_file=submissions/expand.batch \
    --verbosity=3 \
    --output_dir=expansion_test \
    --policy=Discrete_Steepest_Ascend \
    --policy_params="{'step_size': 'single'}"

Example 2:

In our second example we will run a job mix:

  • on a system with 8 nodes, each with 8 cores

  • with 3 static jobs each requiring 6 nodes

  • uses 1 process per core

  • scheduled by the static EasyBackfilling policy

(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ time dynrm_run \
    --topology_file=topology_files/8_node_system.yaml \
    --submission_file=submissions/mix_demo.mix \
    --verbosity=3 \
    --output_dir=mix_static_test \
    --policy=EasyBackfilling \
    --policy_params="{}"

Example 3:

In our third example we will run a job mix:

  • on a system with 8 nodes, each with 8 cores

  • with 3 dynamic jobs without contraints on number of processes

  • all jobs have the same scalability

  • mapping: 1 process per core

  • scheduled by the static Discrete_Steepest_Ascend [sic] policy

(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ time dynrm_run \
    --topology_file=topology_files/8_node_system.yaml \
    --submission_file=submissions/mix_demo.mix \
    --verbosity=3 \
    --output_dir=mix_dyn_test \
    --policy=Discrete_Steepest_Ascend \
    --policy_params="{'step_size': 'linear'}"

Ongoing & Future Work:

  • Intra-node scheduling

  • Co-scheduling

  • Carbon-Aware Scheduling

Patch for LibADR tutorial:

(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ dynpkgs pkg_reinstall ompi && sed -i 's|#define MPI_MAX_INFO_VAL[[:space:]]*OPAL_MAX_INFO_VAL|#define MPI_MAX_INFO_VAL         10000|' /opt/hpc/build/ompi/ompi/include/mpi.h && cd /opt/hpc/build/ompi && make -j8 all && make -j install
(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ cd /opt/hpc/build/dyn_rm && git pull && dynpkgs pkg_reinstall dyn_rm
(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ rm -rf /opt/hpc/build/libadr /opt/hpc/install/libadr && dynpkgs pkg_install libadr
(tutorial_dynreshpc26) [mpiuser@n1 dyn_procs_setup]$ python3 run_test_dynrm.py --topology_file=2_node_system.yaml --submission_file=example_basic.batch --verbosity=3 --output_dir=expansion_test --step_size=single