Skip to main content
MLIP Arena uses Prefect as its workflow engine. Prefect handles task caching, parallel execution, state tracking, and integration with HPC schedulers — without requiring changes to your simulation code.

Flows vs tasks in Prefect

Prefect distinguishes two primitives: In MLIP Arena, every simulation operation (OPT, EOS, MD, etc.) is a @task. Benchmark scripts wrap those tasks in a @flow to run them in parallel across models and structures.

Running tasks directly

You can call any task directly without a flow for single calculations:

Using .submit() for parallel execution

To run calculations concurrently, call .submit() on the task instead of calling it directly. .submit() returns a PrefectFuture immediately and dispatches the work to a Prefect worker. Wrap all .submit() calls inside a @flow so Prefect can track and schedule them:
raise_on_failure=False lets you collect all results even if some models fail. Inspect the returned State objects to identify which models succeeded.

A complete parallel benchmark flow

The homonuclear_diatomics flow in mlip_arena/flows/diatomics.py is a production example that parallelizes energy curve calculations across all 118 elements:
Key patterns in this flow:
  • @task on individual per-element calculations.
  • @flow wraps the loop and calls .submit() on each task.
  • wait(futures) blocks until all futures complete before the analyze task runs.
  • Results are collected with raise_on_failure=False to tolerate partial failures.

Caching behavior

All MLIP Arena tasks use the TASK_SOURCE + INPUTS cache policy:
This policy stores a cache key from the hash of:
  1. The task’s source code (TASK_SOURCE) — cache is invalidated when the task implementation changes.
  2. All input parameters (INPUTS) — separate results are cached for each unique (atoms, calculator, kwargs) combination.

Fresh execution

Pass refresh_cache=True via .with_options() to bypass the cache and re-run a task:

Persistent results

Pass persist_result=True to write results to a Prefect result backend. EOS uses this for intermediate OPT results:

Running on HPC with dask_jobqueue

For large-scale benchmarks, configure Prefect to use a dask_jobqueue worker pool that submits jobs to SLURM, PBS, or SGE:
1

Install dask-jobqueue

2

Configure a DaskTaskRunner

3

Run the flow

Prefect submits each .submit() call as a Dask task, which dask_jobqueue dispatches as individual SLURM jobs.
For a practical HPC example, refer to the MD stability benchmark notebook at benchmarks/stability/temperature.ipynb.

Waiting for futures

Use prefect.futures.wait() to block until a set of futures completes before proceeding:
This is necessary when a downstream task (like analyze) depends on the output files written by all upstream tasks.