This page is available as a Jupyter notebook: tutorials/4-generalized-makers.ipynb.
Writing generalized Makers#
Creating a generalized maker (ex. a defect maker that works for all supported DFT codes) is difficult since the general functionalities built around DFT code (VASP, CP2K, etc.) can differ significantly. Ideally you don’t want to write completely independent
Makers for each supported DFT code from scratch since much of the logic will be shared between these builders.
Assuming you have a sufficiently complex workflow made up of many job, the logic in each job will usually be mostly DFT-code-independent with a few crucial steps that are specific to each code. An example will be reading the structure form an exiting directory which requires the code-specific parsing functions.
Disentangling the DFT-code-dependent and independent parts can be a massive headache.
As such we recommend the the following approach.
Define a base
Makerobject that defines the DFT-code-independent
jobs invoked by the common
Callableparameters for each code-specific operation.
The code-specific operations will be defined as abstract functions in the base
Each code-specific operation should be implemented in the child
Makerwhich will be concrete implementations of the base
from jobflow import Maker, job, Flow from jobflow.managers.local import run_locally
class BaseMaker(Maker): def code_specific_func(self, arg1): raise NotImplementedError() def make(self): return Flow([job1(self.code_specific_func, "ARG1")]) @job def job1(func, arg1): print("DO CODE INDEPENDENT STUFF") func(arg1)
class Code1Maker(BaseMaker): def code_specific_func(self, arg1): print("DO STUFF specific to CODE 1") flow = Code1Maker().make() responses = run_locally(flow)
2023-02-09 15:45:25,123 INFO Started executing jobs locally 2023-02-09 15:45:25,124 INFO Starting job - job1 (8ca82264-99f8-4862-bf1e-5ae7d8a4b350) DO CODE INDEPENDENT STUFF DO STUFF specific to CODE 1 2023-02-09 15:45:25,139 INFO Finished job - job1 (8ca82264-99f8-4862-bf1e-5ae7d8a4b350) 2023-02-09 15:45:25,140 INFO Finished executing jobs locally
class Code2Maker(BaseMaker): def code_specific_func(self, arg1): print("DO STUFF specific to CODE 2") flow = Code2Maker().make() responses = run_locally(flow)
2023-02-09 15:45:37,552 INFO Started executing jobs locally 2023-02-09 15:45:37,553 INFO Starting job - job1 (366f6780-be82-4e13-b88c-3aeaac44cd86) DO CODE INDEPENDENT STUFF DO STUFF specific to CODE 2 2023-02-09 15:45:37,564 INFO Finished job - job1 (366f6780-be82-4e13-b88c-3aeaac44cd86) 2023-02-09 15:45:37,564 INFO Finished executing jobs locally