vasp.runners module#
Runners for executing VASP calculations.
Runners handle the execution of VASP jobs, whether locally, on a cluster scheduler (SLURM), or on Kubernetes. They provide a uniform interface for submitting jobs and checking status.
Example
>>> from vasp.runners import LocalRunner, SlurmRunner
>>>
>>> # For local execution
>>> runner = LocalRunner(vasp_command='vasp_std')
>>>
>>> # For SLURM cluster
>>> runner = SlurmRunner(partition='compute', nodes=2)
- class vasp.runners.Runner[source]#
Bases:
ABCAbstract base class for VASP execution backends.
Runners handle submitting and monitoring VASP calculations. They are designed for non-blocking operation: - run() submits/starts a job and returns immediately - status() checks current state without blocking - Exceptions signal state transitions to calling code
Subclasses must implement: - run(): Submit or start a calculation - status(): Check current job status
Example
>>> runner = LocalRunner(vasp_command='vasp_std') >>> status = runner.run('/path/to/calc') >>> if status.state == JobState.COMPLETE: ... print("Done!")
- abstract run(directory)[source]#
Start or submit a VASP calculation.
This method should NOT block waiting for completion. For async runners (SLURM, K8s), it submits the job. For local runners, behavior depends on configuration.
- Parameters:
directory (str) – Path to calculation directory containing input files.
- Returns:
JobStatus with current state after submission.
- Raises:
VaspSubmitted – Job was just submitted (contains jobid).
VaspQueued – Job is already queued.
VaspRunning – Job is currently running.
VaspSetupError – Input files missing or invalid.
- Return type:
- abstract status(directory)[source]#
Check status of a calculation without blocking.
This method never starts a new calculation. It only reports the current state based on job scheduler status and output files.
- wait(directory, timeout=None, poll_interval=30.0)[source]#
Block until calculation completes (for interactive use).
This is a convenience method that polls status() until the job is done. For most workflows, you should use status() directly with your own retry logic.
- Parameters:
- Returns:
Final JobStatus.
- Raises:
TimeoutError – If timeout is reached before completion.
- Return type:
- class vasp.runners.JobState(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]#
Bases:
EnumPossible states of a VASP calculation.
- NOT_STARTED = 'not_started'#
- SUBMITTED = 'submitted'#
- QUEUED = 'queued'#
- RUNNING = 'running'#
- COMPLETE = 'complete'#
- FAILED = 'failed'#
- UNKNOWN = 'unknown'#
- class vasp.runners.JobStatus(state, jobid=None, message=None, metadata=<factory>)[source]#
Bases:
objectStatus information for a VASP calculation.
- state#
Current state of the job.
- class vasp.runners.LocalRunner(vasp_executable=None, nprocs='auto', mpi_command='mpirun', mpi_extra_args=None, background=False, vasp_command=None)[source]#
Bases:
RunnerRun VASP on the local machine.
By default runs synchronously (blocking until complete). Use background=True for non-blocking execution.
The runner intelligently determines the number of MPI processes: - If nprocs=’auto’ (default): detects based on CPUs and system size - If nprocs is an int: uses that exact number - Respects NCORE settings in INCAR
Environment variables (in order of precedence): - VASP_EXECUTABLE: Path to VASP binary (e.g., /opt/vasp/bin/vasp_std) - VASP_COMMAND: Full command (legacy, e.g., ‘mpirun -np 8 vasp_std’) - VASP_NPROCS: Number of MPI processes (or ‘auto’) - VASP_MPI_EXTRA_ARGS: Extra MPI arguments (e.g., ‘–map-by hwthread’)
- Parameters:
vasp_executable (str | None) – Path to VASP binary. Defaults to $VASP_EXECUTABLE, then extracts from $VASP_COMMAND, or ‘vasp_std’.
nprocs (int | str) – Number of MPI processes. ‘auto’ (default) detects optimal count, or specify an integer. Set to 1 for serial execution.
mpi_command (str | None) – MPI launcher (default: ‘mpirun’). Set to None to disable MPI and run serial VASP.
mpi_extra_args (str | None) – Extra arguments for MPI launcher.
background (bool) – If True, run in background and return immediately.
vasp_command (str | None)
Example
>>> # Auto-detect optimal parallelization >>> runner = LocalRunner() >>> calc = Vasp('my_calc', runner=runner, ...)
>>> # Specify exact process count >>> runner = LocalRunner(nprocs=16)
>>> # Serial execution (no MPI) >>> runner = LocalRunner(nprocs=1, mpi_command=None)
>>> # Custom MPI settings >>> runner = LocalRunner( ... nprocs=8, ... mpi_extra_args='--bind-to core --map-by socket' ... )
- run(directory)[source]#
Run VASP in the specified directory.
- Parameters:
directory (str) – Path to calculation directory with input files.
- Returns:
JobStatus indicating outcome.
- Raises:
VaspRunning – If background=True and job is still running.
VaspSetupError – If required input files are missing.
- Return type:
- vasp.runners.get_optimal_nprocs(directory=None)[source]#
Determine optimal number of MPI processes.
Uses heuristics based on available CPUs and system size: - Reads NCORE/NPAR from INCAR if available - Checks number of atoms from POSCAR - Returns reasonable default based on CPU count
- class vasp.runners.MockRunner(results=None, energy=None, forces=None, stress=None, state_sequence=None, delay_calls=0, delay=0, fail_on_run=False, error_message='Mock error', write_outputs=True)[source]#
Bases:
RunnerMock runner for testing without VASP.
Simulates VASP execution by writing fake output files. Useful for testing calculator logic, workflow integration, and development when VASP is not available.
- Parameters:
results (MockResults | None) – MockResults object with calculation outputs.
energy (float | None) – Shortcut to set results.energy.
forces (list | np.ndarray | None) – Shortcut to set results.forces.
state_sequence (list[JobState] | None) – List of JobStates to cycle through on each status() call. Useful for testing async workflows.
delay_calls (int) – Number of status() calls before returning COMPLETE. Alternative to state_sequence for simple cases.
fail_on_run (bool) – If True, immediately fail when run() is called.
error_message (str) – Error message if fail_on_run is True.
write_outputs (bool) – If True, write mock OUTCAR/vasprun.xml files.
stress (list | np.ndarray | None)
delay (float)
Example
>>> # Simple successful calculation >>> runner = MockRunner(energy=-15.3) >>> >>> # Simulate job that takes 3 status checks to complete >>> runner = MockRunner( ... energy=-15.3, ... state_sequence=[ ... JobState.QUEUED, ... JobState.RUNNING, ... JobState.RUNNING, ... JobState.COMPLETE, ... ] ... ) >>> >>> # Simulate failed calculation >>> runner = MockRunner(fail_on_run=True, error_message="ZBRENT error")
- class vasp.runners.MockResults(energy=-10.0, forces=None, stress=None, magmom=0.0, magmoms=None, fermi_level=-5.0, eigenvalues=None, occupations=None, ibz_kpts=None, kpt_weights=None, converged=True, metadata=<factory>)[source]#
Bases:
objectContainer for mock calculation results.
- Parameters:
- forces#
Forces array of shape (natoms, 3) in eV/Angstrom.
- Type:
list[list[float]] | numpy.ndarray | None
- stress#
Stress tensor as 6-element Voigt array in kBar.
- Type:
list[float] | numpy.ndarray | None
- magmoms#
Per-atom magnetic moments.
- Type:
list[float] | numpy.ndarray | None
- eigenvalues#
Eigenvalue array (nspin, nkpts, nbands).
- Type:
numpy.ndarray | None
- occupations#
Occupation numbers (nspin, nkpts, nbands).
- Type:
numpy.ndarray | None
- ibz_kpts#
IBZ k-points array (nkpts, 3).
- Type:
numpy.ndarray | None
- kpt_weights#
K-point weights (nkpts,).
- Type:
numpy.ndarray | None
- class vasp.runners.SlurmRunner(partition='normal', nodes=1, ntasks_per_node=24, time='24:00:00', memory=None, account=None, qos=None, vasp_command=None, modules=None, extra_sbatch=None, constraint=None)[source]#
Bases:
RunnerRun VASP via SLURM scheduler.
Submits jobs to SLURM and monitors status. All operations are non-blocking - run() submits and returns immediately.
- Parameters:
partition (str) – SLURM partition name.
nodes (int) – Number of nodes.
ntasks_per_node (int) – MPI tasks per node.
time (str) – Wall time limit (HH:MM:SS format).
memory (str | None) – Memory per node (e.g., ‘64G’).
account (str | None) – SLURM account for billing.
qos (str | None) – Quality of service.
vasp_command (str | None) – Command to run VASP. Defaults to ‘srun $VASP_COMMAND’ if VASP_COMMAND is set, or ‘srun vasp_std’ otherwise.
modules (list[str] | None) – List of modules to load before running.
extra_sbatch (list[str] | None) – Additional #SBATCH directives as list of strings.
constraint (str | None) – Node constraint (e.g., ‘gpu’ or ‘skylake’).
Example
>>> runner = SlurmRunner( ... partition='compute', ... nodes=2, ... ntasks_per_node=48, ... time='24:00:00', ... modules=['vasp/6.3.0'], ... ) >>> >>> calc = Vasp('my_calc', runner=runner, atoms=atoms) >>> try: ... energy = calc.potential_energy ... except VaspSubmitted as e: ... print(f"Submitted job {e.jobid}")
- class vasp.runners.KubernetesRunner(namespace='default', image='vasp:latest', pvc_name='vasp-pvc', pvc_mount_path='/data', cpu_request='4', cpu_limit=None, memory_request='8Gi', memory_limit=None, gpu_limit=None, node_selector=None, tolerations=None, service_account=None, image_pull_secrets=None, vasp_command='mpirun -np $NPROCS vasp_std', env_vars=None, ttl_seconds_after_finished=86400, active_deadline_seconds=None, backoff_limit=0, use_in_cluster_config=False)[source]#
Bases:
RunnerRun VASP on Kubernetes cluster.
Submits VASP calculations as Kubernetes Job resources. Input/output files must be on shared storage (PVC).
- Parameters:
namespace (str) – Kubernetes namespace.
image (str) – Container image with VASP.
pvc_name (str) – PersistentVolumeClaim name for data.
pvc_mount_path (str) – Mount path in container.
cpu_request (str) – CPU request (e.g., ‘4’).
cpu_limit (str | None) – CPU limit (defaults to request).
memory_request (str) – Memory request (e.g., ‘16Gi’).
memory_limit (str | None) – Memory limit (defaults to request).
gpu_limit (int | None) – Number of GPUs (for vasp_gpu).
node_selector (dict[str, str] | None) – Dict of node labels for scheduling.
tolerations (list[dict] | None) – List of tolerations for scheduling.
service_account (str | None) – ServiceAccount name.
image_pull_secrets (list[str] | None) – List of image pull secret names.
vasp_command (str) – Command to run VASP.
env_vars (dict[str, str] | None) – Environment variables dict.
ttl_seconds_after_finished (int) – Job cleanup time (default 1 day).
active_deadline_seconds (int | None) – Job timeout.
backoff_limit (int) – Retry count (default 0 = no retries).
use_in_cluster_config (bool) – Use in-cluster config (for pods).
Example
>>> runner = KubernetesRunner( ... namespace='vasp-jobs', ... image='my-registry/vasp:6.3.0', ... pvc_name='vasp-data', ... cpu_request='8', ... memory_request='32Gi', ... ) >>> >>> calc = Vasp('/data/calculations/my_calc', runner=runner, ...)
- class vasp.runners.InteractiveRunner(vasp_command=None, mpi_command=None, timeout=3600, parse_stress=False)[source]#
Bases:
RunnerRun VASP in interactive mode with persistent process.
This runner maintains a live VASP process and communicates via stdin/stdout. It’s designed for geometry optimizations where reusing wavefunctions between steps provides significant speedup.
- Parameters:
vasp_command (str | None) – Command to run VASP. Defaults to $VASP_COMMAND environment variable, or ‘vasp_std’ if not set.
mpi_command (str | None) – MPI launcher command, e.g., ‘mpirun -np 4’.
timeout (float) – Seconds to wait for VASP response (default: 3600).
parse_stress (bool) – Whether to parse stress tensor (default: False).
Example
>>> runner = InteractiveRunner(vasp_command='vasp_std') >>> runner.start('/path/to/calc') >>> >>> # Optimization loop >>> for step in range(100): ... results = runner.step(atoms) ... if converged(results.forces): ... break ... atoms.positions = optimize(atoms, results.forces) >>> >>> runner.close()
Note
The INCAR must NOT contain NSW > 0 or IBRION settings. This runner handles the ionic loop externally.
- start(directory, atoms)[source]#
Start VASP interactive session.
- Parameters:
directory (str) – Path to calculation directory with input files.
atoms (Atoms) – Initial atomic structure.
- Returns:
Results from initial SCF calculation.
- Raises:
VaspSetupError – If input files are missing or invalid.
VaspError – If VASP fails to start.
- Return type:
- step(atoms)[source]#
Send new positions and get updated results.
- Parameters:
atoms (Atoms) – Updated atomic structure.
- Returns:
Energy, forces, and optionally stress from new SCF.
- Raises:
VaspError – If VASP process died or communication failed.
- Return type:
- close()[source]#
Gracefully close the VASP session.
Writes STOPCAR to trigger clean shutdown, then waits for VASP to finish writing output files.
- Return type:
None
- class vasp.runners.InteractiveResults(energy, forces, stress=None, converged=True)[source]#
Bases:
objectResults from a single interactive step.
- class vasp.runners.SocketServer(config=None)[source]#
Bases:
objectSocket server for driving VASP calculations.
This server implements the driver side of the i-PI protocol. It sends atomic positions to a VASP client and receives energies and forces.
- Parameters:
config (SocketConfig | None) – Socket configuration.
Example
>>> server = SocketServer(SocketConfig(port=31415)) >>> server.start() >>> server.wait_for_client() >>> >>> # Send positions, get forces >>> results = server.calculate(atoms) >>> >>> server.close()
- class vasp.runners.SocketClient(config, runner=None)[source]#
Bases:
objectSocket client for VASP to receive positions and send forces.
This is typically run by a wrapper around VASP. It receives positions from a driver, passes them to VASP, and sends back energies and forces.
- Parameters:
config (SocketConfig) – Socket configuration.
runner (InteractiveRunner | None) – InteractiveRunner instance for VASP communication.
Example
>>> from vasp.runners import InteractiveRunner >>> >>> runner = InteractiveRunner() >>> client = SocketClient(config, runner) >>> client.connect() >>> client.run() # Main loop
- class vasp.runners.SocketConfig(host='localhost', port=31415, unix_socket=None, timeout=3600.0)[source]#
Bases:
objectConfiguration for socket connection.
Base Classes#
- class vasp.runners.Runner[source]#
Bases:
ABCAbstract base class for VASP execution backends.
Runners handle submitting and monitoring VASP calculations. They are designed for non-blocking operation: - run() submits/starts a job and returns immediately - status() checks current state without blocking - Exceptions signal state transitions to calling code
Subclasses must implement: - run(): Submit or start a calculation - status(): Check current job status
Example
>>> runner = LocalRunner(vasp_command='vasp_std') >>> status = runner.run('/path/to/calc') >>> if status.state == JobState.COMPLETE: ... print("Done!")
- abstract run(directory)[source]#
Start or submit a VASP calculation.
This method should NOT block waiting for completion. For async runners (SLURM, K8s), it submits the job. For local runners, behavior depends on configuration.
- Parameters:
directory (str) – Path to calculation directory containing input files.
- Returns:
JobStatus with current state after submission.
- Raises:
VaspSubmitted – Job was just submitted (contains jobid).
VaspQueued – Job is already queued.
VaspRunning – Job is currently running.
VaspSetupError – Input files missing or invalid.
- Return type:
- abstract status(directory)[source]#
Check status of a calculation without blocking.
This method never starts a new calculation. It only reports the current state based on job scheduler status and output files.
- wait(directory, timeout=None, poll_interval=30.0)[source]#
Block until calculation completes (for interactive use).
This is a convenience method that polls status() until the job is done. For most workflows, you should use status() directly with your own retry logic.
- Parameters:
- Returns:
Final JobStatus.
- Raises:
TimeoutError – If timeout is reached before completion.
- Return type:
Runners#
- class vasp.runners.LocalRunner(vasp_executable=None, nprocs='auto', mpi_command='mpirun', mpi_extra_args=None, background=False, vasp_command=None)[source]#
Bases:
RunnerRun VASP on the local machine.
By default runs synchronously (blocking until complete). Use background=True for non-blocking execution.
The runner intelligently determines the number of MPI processes: - If nprocs=’auto’ (default): detects based on CPUs and system size - If nprocs is an int: uses that exact number - Respects NCORE settings in INCAR
Environment variables (in order of precedence): - VASP_EXECUTABLE: Path to VASP binary (e.g., /opt/vasp/bin/vasp_std) - VASP_COMMAND: Full command (legacy, e.g., ‘mpirun -np 8 vasp_std’) - VASP_NPROCS: Number of MPI processes (or ‘auto’) - VASP_MPI_EXTRA_ARGS: Extra MPI arguments (e.g., ‘–map-by hwthread’)
- Parameters:
vasp_executable (str | None) – Path to VASP binary. Defaults to $VASP_EXECUTABLE, then extracts from $VASP_COMMAND, or ‘vasp_std’.
nprocs (int | str) – Number of MPI processes. ‘auto’ (default) detects optimal count, or specify an integer. Set to 1 for serial execution.
mpi_command (str | None) – MPI launcher (default: ‘mpirun’). Set to None to disable MPI and run serial VASP.
mpi_extra_args (str | None) – Extra arguments for MPI launcher.
background (bool) – If True, run in background and return immediately.
vasp_command (str | None)
Example
>>> # Auto-detect optimal parallelization >>> runner = LocalRunner() >>> calc = Vasp('my_calc', runner=runner, ...)
>>> # Specify exact process count >>> runner = LocalRunner(nprocs=16)
>>> # Serial execution (no MPI) >>> runner = LocalRunner(nprocs=1, mpi_command=None)
>>> # Custom MPI settings >>> runner = LocalRunner( ... nprocs=8, ... mpi_extra_args='--bind-to core --map-by socket' ... )
- run(directory)[source]#
Run VASP in the specified directory.
- Parameters:
directory (str) – Path to calculation directory with input files.
- Returns:
JobStatus indicating outcome.
- Raises:
VaspRunning – If background=True and job is still running.
VaspSetupError – If required input files are missing.
- Return type:
- class vasp.runners.MockRunner(results=None, energy=None, forces=None, stress=None, state_sequence=None, delay_calls=0, delay=0, fail_on_run=False, error_message='Mock error', write_outputs=True)[source]#
Bases:
RunnerMock runner for testing without VASP.
Simulates VASP execution by writing fake output files. Useful for testing calculator logic, workflow integration, and development when VASP is not available.
- Parameters:
results (MockResults | None) – MockResults object with calculation outputs.
energy (float | None) – Shortcut to set results.energy.
forces (list | np.ndarray | None) – Shortcut to set results.forces.
state_sequence (list[JobState] | None) – List of JobStates to cycle through on each status() call. Useful for testing async workflows.
delay_calls (int) – Number of status() calls before returning COMPLETE. Alternative to state_sequence for simple cases.
fail_on_run (bool) – If True, immediately fail when run() is called.
error_message (str) – Error message if fail_on_run is True.
write_outputs (bool) – If True, write mock OUTCAR/vasprun.xml files.
stress (list | np.ndarray | None)
delay (float)
Example
>>> # Simple successful calculation >>> runner = MockRunner(energy=-15.3) >>> >>> # Simulate job that takes 3 status checks to complete >>> runner = MockRunner( ... energy=-15.3, ... state_sequence=[ ... JobState.QUEUED, ... JobState.RUNNING, ... JobState.RUNNING, ... JobState.COMPLETE, ... ] ... ) >>> >>> # Simulate failed calculation >>> runner = MockRunner(fail_on_run=True, error_message="ZBRENT error")