What is AiiDA?🔗
AiiDA is an open-source workflow manager geared towards automating complex calculations. At it's core it is a generic framework which handles the submission of calculations, manages the data storage of calculation results, and enables complex error handling to name a few features.
AiiDA requires several other services to run such as a Postrgres database and a RabbitMQ service. Both of these can be found at LaunchIT. Before starting your AiiDA installation process you should initiate both of these services and keep the information readily available.
Getting started with AiiDA🔗
The original development of AiiDA developed around the idea of allowing a personal laptop act as the central repository. It would then be able to log into other computers/servers to submit jobs and retrieve after they had finished. With the advancedment of firewalls and security, especially at the lab, it is not as feasible to configure AiiDA with this type of installation. The following instructions will outline the total installation process on LC machines at the lab.
Cloning and basic AiiDA Setup🔗
There are two ways that you can install the core AiiDA package into your system. For either case, it is highly recommended to create a python or conda environment to keep your AiiDA installation separate to prevent breaking possible dependencies. This can be done with
python -m venv /path/to/environment/aiida source /path/to/environment/aiida/bin/activate
or
conda create -n aiida conda activate aiida
Once you have your environment initialized, you can install AiiDA through pip
pip install aiida
or download and and install from the AiiDA git repository.
git clone https://github.com/aiidateam/aiida-core.git cd aiida-core git checkout v2.6.2 # Decide if there is a more recent version you will use. pip install -e .
Anytime that you will be working with AiiDA you will need to activate this environment to gain access to the AiiDA commands. Activating your environment adds the name of your environment before the command prompt. It also changes the default binaries for python and pip to be those found in your environment.
Creating a profile🔗
The first thing you'll need to do is create a profile that will be associated with all the simulations launched through AiiDA. The profile will control which Postgres database and RabbitMQ service you will be connecting to. This can be used to separate projects if needed.
The main command to interact with AiiDA is `verdi`. This command should be available to you after installing the AiiDA package. You can list all possible commands with `verdi --help`.
There are several ways to setup a profile. The first is typing
verdi profile setup core.psql_dos
This will prompt you for relative information to set up your profile. A somewhat easier method would be to simply pass a yaml file that the command will read to create your profile.
verdi profile setup core.psql_dos --config profile.yaml
This file should look something like this:
non_interactive: y profile_name: <profile_name> email: <email> first_name: <First> last_name: <Last> institution: LLNL set_default: true use_rabbitmq: y database_engine: core.psql_dos database_hostname: <hostname> # Postgres LaunchIT database_port: <port> # Postgres LaunchIT database_name: <name> # Postgres LaunchIT database_username: <username> # Postgres LaunchIT database_password: <password> # Postgres LaunchIT repository_uri: file:///path/to/where/you/want/the/repository
The last line with `repository_uri` should be set to space with a large amount of storage. Your /usr/workspace can work for this. At some point, AiiDA will create a hidden folder called `.aiida`. The location of this can change but is either in your home folder or near your installation of aiida-core. The repository_uri can also be pointed to that location such that `~/.aiida/repository/main` would be the location where you replace ~ with the path. At this point you should be able to see that you have a profile created with `verdi profile list` which should return your chosen username.
AiiDA recently has changed so that you can configure your RabbitMQ server separately. At the time of writing this tutorial, the command to configure the RabbitMQ did not appear to be working correctly. To configure RabbitMQ with AiiDA, you can find a file named `config.json` inside of the `.aiida` folder. Find your user profile and edit the default values that AiiDA provides for the RabbitMQ. These values can be found from your LaunchIT instance. It should look something similar to the following example.
"backend": "core.rabbitmq", "config": { "broker_protocol": "amqps", "broker_username": "<username>", "broker_password": "<password>", "broker_host": "<hostname>", "broker_port": <port>, "broker_virtual_host": "<virtual_host>", "broker_parameters": { "no_verify_ssl": "1", "cafile": "/etc/pki/tls/cert.pem" } }
The value `broker_parameters` must also be added to the file and can be seen above.
At this point you can test the status of the AiiDA installation by typing `verdi status`. The only thing that should not be initiated at this point is the daemon which interacts with the RabbitMQ server. This can be started with
verdi daemon start
By default it starts with a single daemon. You can increase the number by setting a number at the end of the command or by increasing or decreasing the current number with
verdi daemon incr 1 verdi daemon decr 1
Additionally, a nice with to interact with the python api is to use
verdi shell
which essentially initiates an ipython instance with many of the AiiDA modules pre-loaded.
Set up and configure a computer🔗
Set up computer🔗
A computer within the AiiDA context is where calculations will be ran. This can be any machine that you can ssh into and submit jobs. To give an example, we will create a computer for the Ruby server here at the lab. When setting up a computer. You will want to create a directory where all the simulations will be ran. Ideally, this would be some kind of scratch file system that has plenty of space for your simulations. For Ruby we have the Lustre file system which can be found at "/p/lustre1/<username>". I would recommend creating a folder in that space named AiiDA or something that will prompt you not to delete it in the future.
Similarly to the profile setup process, we can provide a yaml file to simplify the installation process. This can be done with
verdi computer setup --config ruby.yaml
where ruby.yaml is the file that will contain the following settings
label: ruby hostname: "ruby.llnl.gov" # Make sure you can ssh to this before installation by typing `ssh ruby.lln.gov` description: "Ruby server at LLNL" transport: core.ssh scheduler: "core.slurm" work_dir: "/p/lustre1/<username>/AiiDA" # You will need to confirm which lustre folder you are a part of. mpirun_command: "srun -n {tot_num_mpiprocs}" mpiprocs_per_machine: "56" prepend_text: "" append_text: " " shebang: "#!/bin/bash"
Once the initial step has been taken to setup the computer you will need to finish configuring the computer with
verdi computer configure core.ssh configure_ruby.yml
where configure_ruby.yaml contains
username: "<lc_username>" port: 22 look_for_keys: true key_filename: "/g/g1/<username>/.ssh/id_ecdsa" # Path to where your SSH key is at timeout: 60 allow_agent: true proxy_command: "" compress: true gss_auth: false gss_kex: false gss_deleg_creds: false gss_host: "ruby" load_system_host_keys: true key_policy: "RejectPolicy" use_login_shell: true safe_interval: 10.0
Test computer🔗
To make sure this computer is configured correctly, execute and make sure all tests pass:
verdi computer test ruby
Make sure that all tests pass at this point. Some common issues include needing to modify your .bashrc file to allow for non-interactive sessions. One way to do this is to prepend the following text to your .bashrc file.
if [[ $- != *i* ]] ; then return fi
Configure code🔗
At this point AiiDA can connect to your database/RabbitMQ service and connect to the different servers to which you are wanting to submit calculations. The next step in the process is to configure a code executable so that AiiDA knows where it is located. For an example, we will show how INQ and VASP can be configured to run within AiiDA.
AiiDA works by relying on plugins to specify how a code will interact with the AiiDA framework. Many of the popular code packages already have a community that supports a plugin and can found at the AiiDA plugin registry.
Before installing either of these plugins, we can check what current calculation plugins are currently installed with something like:
verdi plugin list aiida.calculations Registered entry points for aiida.calculations: * arithmetic.add * core.transfer * templatereplacer Report: Pass the entry point as an argument to display detailed information
Install plugin for INQ🔗
To install the plugin for INQ, execute the following commands:
git clone https://github.com/LLNL/aiida-inq cd aiida-inq pip install -e .
After installing aiida-inq, the plugin list should be updated to show the new calculations that can be performed.
Set up INQ code🔗
To set up INQ with a script, create file inq_code.yml with the following content
label: inq description: "INQ code from LLNL" default_calc_job_plugin: "inq.inq" filepath_executable: "/bin/bash" computer: ruby use_double_quotes: false with_mpi: true prepend_text: "" append_text: ""
You might notice that the path to the executable has been set to "/bin/bash". The AiiDA implementation for INQ works by creating a bash script. Inside of that script it will make reference to the INQ binary. With that being the case, make sure that the INQ binary can be found in your $PATH. This can be done by appending the following line to your .bashrc file
export PATH="/path/to/inq/binary:$PATH"
To install the code within AiiDA, you can then execute the following command:
verdi code create core.code.installed --config inq_code.yml
To check if the code has correctly installed and is recognized by AiiDA, you can execute:
verdi code list
Run an INQ calculation🔗
Running a job from a script🔗
One of the easiest ways to launch a job within AiiDA is through simple python scripts. An example script, launch.py, is shown below
from aiida import load_profile from aiida.orm import load_code, Dict from aiida.plugins import CalculationFactory, DataFactory from aiida.engine import run,submit from ase.build import bulk # Initiate the default profile load_profile() # Get the calculator from AiiDA InqCalculation = CalculationFactory('inq.inq') # Find the code you will use for the calculation code = load_code('inq@ruby') # Create a structure StructureData = DataFactory('core.structure') atoms = bulk('Si', crystalstructure='diamond', a=5.43) atoms.positions structure = StructureData(ase=atoms) inputs = { 'code': code, 'structure': structure, 'parameters' : Dict(dict={ 'electrons': { 'cutoff': '35.0 Ha', 'extra-states': 3 }, 'kpoints': { 'gamma': '', 'insert': '-0.5 -0.5 -0.5 0.0' }, 'ground-state': { 'tolerance': 1e-8 }, 'run': { 'ground-state': '' } }), 'metadata': { #'dry_run': True, # If uncommented, will only create the files. #'store_provenance': False, # Will not store any of the provenance in the database. 'options': { 'resources': { 'tot_num_mpiprocs': 4 } } } } # Will show detailed results run(InqCalculation, **inputs) # Comment the previous line and use the following if you want to get the pk value to follow along with. #calc = submit(InqCalculation, **inputs) #print(f'Created calculation with PK={calc.pk}')
which can then be run via
verdi run launch.py
You can again learn the pk of this number by running `verdi process list` or `verdi process list -a` to show all calculations. Check the help documentation, `verdi process list --help`, to see all the possible options.
Install plugin for VASP🔗
In order to run VASP you will need to have a current license. If you are not sure if you have access you should reach out to your group or project leaders to see. To install the plugin for VASP, execute the following commands:
pip install aiida-vasp
This will install the latest stable version of aiida-vasp. After installing aiida-vasp, the plugin list should be updated to show the new calculations that can be performed.
Set up VASP code🔗
To set up VASP with a script, create file vasp_code.yml with the following content
label: vasp_std description: "VASP code Ruby server at LLNL" default_calc_job_plugin: "vasp.vasp" filepath_executable: "/path/to/vasp/binary" computer: ruby use_double_quotes: false with_mpi: true prepend_text: "" append_text: ""
To install the code within AiiDA, you can then execute the following command:
verdi code create core.code.installed --config vasp_code.yml
To check if the code has correctly installed and is recognized by AiiDA, you can execute:
verdi code list
Install VASP POTCAR files🔗
VASP comes with proprietary PAW pseudopotential files which are named POTCAR. Elements can have multiple pseudopotential files depending on the number of electrons that were included when creating the file. To upload these to your AiiDA instance you will need to upload the files. This can be done by providing a tar file with all the POTCAR files. The format should be the same as they are provided from the VASP software.
% verdi data vasp-potcar uploadfamily --path=/path/to/potpaw_PBE.54.tar --name=PBE.54 --description="PBE potentials version 54" POTCAR files found: 327. New files uploaded: 327, Added to Family: 327
The name that you provide here is how the pseudopotential family will be referenced by AiiDA later.
Run a VASP calculation🔗
Running a job from a script🔗
One of the easiest ways to launch a job within AiiDA is through simple python scripts. An example script, launch.py, is shown below
from aiida import load_profile from aiida.orm import load_code, load_group, Str, Group, Int from aiida.plugins import DataFactory, WorkflowFactory from aiida.common.extendeddicts import AttributeDict from ase.io import read from ase.build import bulk, sort from aiida.engine import submit, run # Initiate the default profile load_profile() # Initiate workchain and other inputs workchain = WorkflowFactory('vasp.relax') inputs = AttributeDict() settings = AttributeDict() dict_data = DataFactory('core.dict') kpoints_data = DataFactory('core.array.kpoints') Bool = DataFactory('core.bool') # Settings settings.parser_settings = { 'include_node': ['energies', 'trajectory'], 'include_quantity': ['forces', 'stress'], 'electronic_step_energies': True } inputs.settings = dict_data(dict=settings) # Find the code you will use for the calculation code = load_code('vasp_std@ruby') # This will change based on the computer you install on. # Structure information StructureData = DataFactory('core.structure') atoms = bulk('Si', crystalstructure='diamond', a=5.43) structure = StructureData(ase=atoms) inputs.structure = structure # KPOINTS kpoints = kpoints_data() kpoints.set_kpoints_mesh([3,3,3]) inputs.kpoints = kpoints # INCAR inputs.parameters = dict_data(dict={ 'incar': { 'algo': 'Conjugate', 'encut': 500, 'prec': 'ACCURATE', 'ediff': 1E-4, 'ispin': 2, 'magmom': [0]*len(atoms), 'lorbit': 11, 'ismear': 0, 'sigma': 0.1, 'gga': 'PS', 'kpar': 2, 'ncore': 14, 'nelm': 500 } }) inputs.converge = AttributeDict({'pwcutoff_samples': Int(15)}) # POTCAR information inputs.potential_family = Str('PBE.54') # Name you previously specified when uploading POTCAR inputs.potential_mapping = dict_data(dict={'Si': 'Si'}) # Submission options options = AttributeDict() options.account = 'bank_name' # Name of the bank on LC options.queue_name = 'pbatch' options.max_wallclock_seconds = 60 * 60 * 12 options.resources = {'num_machines': 1} # Number of nodes inputs.options = dict_data(dict=options) # Relax options relax = AttributeDict() relax.perform = Bool(True) # Select relaxation algorithm relax.algo = DataFactory('core.str')('cg') # Set force cutoff limit (EDIFFG, but no sign needed) relax.force_cutoff = DataFactory('core.float')(0.01) # Turn on relaxation of positions (strictly not needed as the default is on) # The three next parameters correspond to the well known ISIF=3 setting relax.positions = DataFactory('core.bool')(True) # Turn on relaxation of the cell shape (defaults to False) relax.shape = DataFactory('core.bool')(True) # Turn on relaxation of the volume (defaults to False) relax.volume = DataFactory('core.bool')(True) # Set maximum number of ionic steps relax.steps = DataFactory('core.int')(100) inputs.relax = relax # Label inputs.label = Str('Pu2O3 structure optimization') inputs.description = Str('Structure optimization of Pu2O3 without optimized spin states. Will be computed afterwards.') inputs.clean_workdir = False # Submit the workchain calc = run(workchain, **inputs) print(f'Launched geometry optimization with PK={calc.pk}')
This comprehensive script will launch a calculation of silicon. There are several parameters to consider when launching. The settings portion of the inputs contains the parser settings and tells AiiDA which sections to parse. This list is rather large and you should consult the documentation for aiida-vasp to see how to get a particular property. The options section contains the job submission details such as bank, queue, resources, and walltime. There are many options for specifying how to optimize the geometry of the structure. Most of the options have been listed here to show the full capabilities of the relax workflow.
The launch.py script can then be run via
verdi run launch.py
The pk of the launched job can be found by running `verdi process list` or `verdi process list -a` to show all calculations. Check the help documentation, `verdi process list --help`, to see all the possible options.
Checking job status in AiiDA🔗
If you run `verdi process list`, current calculation will show up at the bottom of the list, with its identifying “pk” number in the leftmost column:
verdi process list PK Created Process label Process State Process status ---- --------- --------------- --------------- ---------------- 3339 13m ago InqCalculation ⏹ Finished [0]
You can then take that number and run verdi process show <pk> to learn more about the process.
Property Value ----------- ------------------------------------------------------------- type InqTDDFTWorkChain state Finished [11] The process did not register a required output. pk 3339 uuid c9d7fde2-12bf-4901-9893-3954695ff78c label description ctime 2024-10-01 17:58:04.092209+00:00 mtime 2024-10-01 17:58:18.093927+00:00 Inputs PK Type ------------------ ---- ------------- gs inq code 1 InstalledCode structure 3331 StructureData parameters 3332 Dict clean_workdir 3333 Bool max_iterations 3334 Int tddft inq code 1 InstalledCode structure 3331 StructureData parameters 3335 Dict clean_workdir 3336 Bool max_iterations 3337 Int clean_workdir 3338 Bool structure 3331 StructureData Outputs PK Type ----------------- ---- ------------- output_parameters 3354 Dict output_structure 3353 StructureData Called PK Type ------------ ---- ---------------- Ground_State 3341 InqBaseWorkChain TDDFT 3348 InqBaseWorkChain Log messages --------------------------------------------- There are 3 log messages for this calculation Run 'verdi process report 3339' to see them
Troubleshooting a job🔗
Once you have the pk number of a job, you can learn more about the calculation and its outputs via
verdi process show <pk> verdi process report <pk> verdi calcjob gotocomputer <pk>
The last option takes you to a directory where you’ll see the outputs from the job and the script actually submitted to slurm to run the desired calculations.
If necessary, you can kill a process with verdi process kill <pk>.
Getting results🔗
To look at the results of the calculation you can either write a script or start a verdi shell instance. The following code will get the results of the previous calculation.
verdi shell node = load_node(3339) outputs = node.outputs.output_parameters.get_dict() print(outputs)
Conclusion🔗
Hopefully this brief tutorial is enough to get you started running calculations using AiiDA on the LC servers at LLNL. For further documentation we highly suggest going over the documentation and tutorials that AiiDA has on their website.