.. _run_vtr_task:

run_vtr_task
---------------
This script is used to execute one or more *tasks* (i.e. collections of benchmarks and architectures).

.. seealso:: See :ref:`vtr_tasks` for creation and configuration of tasks.

Under the hood, this script runs the VTR flow for each benchmark circuit, architecture file, and CAD tool option 
combination.

The script is located at::

    $VTR_ROOT/vtr_flow/scripts/run_vtr_task.py

.. program:: run_vtr_task.py

Basic Usage
~~~~~~~~~~~

Typical usage is::

    run_vtr_task.py <task_name1> <task_name2> ...

.. note:: At least one task must be specified, either directly as a parameter or via the :option:`-l` options.

Output
~~~~~~
Each task will execute the script specified in the configuration file for every benchmark/circuit/option combination.
The standard output of the underlying script will be forwarded to the output of this script.

If golden results exist (see :ref:`parse_vtr_task`), they will be inspected for runtime and memory usage.

Detailed Command-line Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. option:: -s <script_param> ...

    Treat the remaining command line options as parameters to forward to the underlying script (e.g. :ref:`run_vtr_flow`).

.. option:: -j <N>

    Perform parallel execution using ``N`` threads.

    .. note::
        Only effective for ``-system local``

    .. warning::
        Large benchmarks will use very large amounts of memory (several to 10s of gigabytes).
        Because of this, parallel execution often saturates the physical memory, requiring the use of swap memory, which significantly slows execution.
        Be sure you have allocated a sufficiently large swap memory or errors may result.

.. option:: -l <task_list_file>

    A file containing a list of tasks to execute.

    Each task name should be on a separate line, e.g.::

        <task_name1>
        <task_name2>
        <task_name3>
        ...

.. option:: -temp_dir <path>

    Alternate directory for files generated by a set of tasks.
    The script will automatically create this directory if necessary.

    **Default:** ``config/..`` for each task being run

    Specifies the parent directory for the output of this set of tasks, which will contain ``<task_name>/run<#>`` directories, as well as any generated parse results.
    
    A task folder or list with a config directory must still be specified when invoking the script.

.. option:: -system {local | scripts}

   Controls how the actions (e.g. invocations of :ref:`run_vtr_flow`) are called.

   **Default:** ``local``

   * ``local``: Runs the flow invocations on the local machine (potentially in parallel with the ``-j`` option).

      Example:

      .. code-block:: console

         #From $VTR_ROOT/vtr_flow/tasks

         $ ../scripts/run_vtr_task.py regression_tests/vtr_reg_basic/basic_timing
         regression_tests/vtr_reg_basic/basic_timing: k6_N10_mem32K_40nm.xml/ch_intrinsics.v/common          OK              (took 2.24 seconds)
         regression_tests/vtr_reg_basic/basic_timing: k6_N10_mem32K_40nm.xml/diffeq1.v/common                OK              (took 10.94 seconds)

   * ``scripts``: Prints out all the generated script files (instead of calling them to run all the flow invocations).

      Example:

      .. code-block:: console

         #From $VTR_ROOT/vtr_flow/tasks

         $ ../scripts/run_vtr_task.py regression_tests/vtr_reg_basic/basic_timing -system scripts
         /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_basic/basic_timing/run001/k6_N10_mem32K_40nm.xml/ch_intrinsics.v/common/vtr_flow.sh
         /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_basic/basic_timing/run001/k6_N10_mem32K_40nm.xml/diffeq1.v/common/vtr_flow.sh

      Each generated script file (``vtr_flow.sh``) corresponds to a particular flow invocation generated by the task, and is located within its own directory.

      This list of scripts can be used to run flow invocations on different computing infrastructures (e.g. a compute cluster).

      **Using the output of -system scripts to run a task**

      An example of using the output would be:

      .. code-block:: console

         #From $VTR_ROOT/vtr_flow/tasks

         $ ../scripts/run_vtr_task.py regression_tests/vtr_reg_basic/basic_timing -system scripts | parallel -j4 'cd $(dirname {}) && {}'
         regression_tests/vtr_reg_basic/basic_timing: k6_N10_mem32K_40nm.xml/ch_intrinsics.v/common          OK              (took 2.11 seconds)
         regression_tests/vtr_reg_basic/basic_timing: k6_N10_mem32K_40nm.xml/diffeq1.v/common                OK              (took 10.94 seconds)

      where ``{}`` is a special variable interpreted by the ``parallel`` command to represent the input line (i.e. a script, see ``parallel``'s documentation for details).
      This will run the scripts generated by run_vtr_task.py in parallel (up to 4 at-a-time due to ``-j4``).
      Each script is invoked in the script's containing directory (``cd $(dirname {})``), which mimics the behaviour of ``-system local -j4``.

      .. note::
         While this example shows how the flow invocations could be run locally, similar techniques can be used to submit jobs to other compute infrastructures (e.g. a compute cluster)

      **Determining Resource Requirements**

      Often, when running in a cluster computing environment, it is useful to know what compute resources are required for each flow invocation.

      Each generated ``vtr_flow.sh`` scripts contains the expected run-time and memory use of each flow invocation (derived from golden reference results).
      These can be inspected to determine compute requirements:

      .. code-block:: console

         $ grep VTR_RUNTIME_ESTIMATE_SECONDS /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_basic/basic_timing/run001/k6_N10_mem32K_40nm.xml/ch_intrinsics.v/common/vtr_flow.sh
         VTR_RUNTIME_ESTIMATE_SECONDS=2.96

         $ grep VTR_MEMORY_ESTIMATE_BYTES /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_basic/basic_timing/run001/k6_N10_mem32K_40nm.xml/ch_intrinsics.v/common/vtr_flow.sh
         VTR_MEMORY_ESTIMATE_BYTES=63422464

      .. note::
         If the resource estimates are unknown they will be set to ``0``
