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:
A complete parallel benchmark flow
Thehomonuclear_diatomics flow in mlip_arena/flows/diatomics.py is a production example that parallelizes energy curve calculations across all 118 elements:
@taskon individual per-element calculations.@flowwraps the loop and calls.submit()on each task.wait(futures)blocks until all futures complete before theanalyzetask runs.- Results are collected with
raise_on_failure=Falseto tolerate partial failures.
Caching behavior
All MLIP Arena tasks use theTASK_SOURCE + INPUTS cache policy:
- The task’s source code (
TASK_SOURCE) — cache is invalidated when the task implementation changes. - 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 adask_jobqueue worker pool that submits jobs to SLURM, PBS, or SGE:
1
Install dask-jobqueue
2
Configure a DaskTaskRunner
3
Run the flow
.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
Useprefect.futures.wait() to block until a set of futures completes before proceeding:
analyze) depends on the output files written by all upstream tasks.