Workflow components

As mentioned in the tutorial, Noodles is the workflow engine used both to create the dependency graph between the jobs and to run such graph. Noodles provides a python decorator call schedule that when applied to a function or method returns a promise or future object (see noodles schedule tutorial).

The xtp_job_control library, wraps the different XTP calculators into their own functions decorated with schedule. These scheduled functions can then be organized in different workflows by injecting the output of one function as the input of another function. For example, the single point energy workflow is implemented like:

def dftgwbse_workflow(options: dict) -> object:

 # create results object
 results = Results({})

 # Run DFT + GWBSE
 results['dftgwbse'] = run_dftgwbse(results, options)

 # Compute partial charges
 results['partialcharges'] = run_partialcharges(
     results, options, promise=results["dftgwbse"]["system"])

 output = run(results)

In the previous example, both functions run_dftgwbse and run_partialcharges are scheduled functions implemented in the xtp_workflow module. Results, is a subclass of the Python dictionary extended with functionality to handle the jobs booking.

Notice that jobs are stored as nodes in the results dictionary and also the promised object results['dftgwbse'] contains a system property that can be passed to a partial charges calculator.

The resulting dependency graph in this particular case, contains two nodes, one for each job and a edge representing the system dependency.

runner

The run function in the previous snippet is implemented in the runner module and encapsulate the noodles details. Noodles offers a different variety of runner for different architectures and purposes (see runners). Currently, the xtp_job_control library use a parallel multithread runner with an sqlite interface for storing the jobs metadata.