Using custom NNPs with Auto3D

Auto3D (>= 2.3.0) is compatible with any jitable NNPs. This notebook demonstrates how to wrapper and jit a custom NNP to a specific format that Auto3D can use.

[ ]:
import os, sys
root = os.path.dirname(os.path.dirname(os.path.abspath("__file__")))

import torch
import torchani
import Auto3D
from Auto3D import Auto3DOptions, main

print(Auto3D.__version__)
[3]:
# Below is the template of the wrapper that you need to implement with your custom NNP.
class userNNP(torch.nn.Module):
    def __init__(self):
        super(userNNP, self).__init__()
        """This is an example NNP model that can be used with Auto3D.
        You can initialize an NNP model however you want,
        just make sure that:
            - It contains the coord_pad and species_pad attributes
              (These values will be used when processing the molecules in batch.)
            - The signature of the forward method is the same as below.
        """
        # Here I constructed an example NNP using ANI2x.
        # In your case, you can replace this with your own NNP model.
        self.model = torchani.models.ANI2x(periodic_table_index=True)

        self.coord_pad = 0  # int, the padding value for coordinates
        self.species_pad = -1  # int, the padding value for species.

    def forward(self,
                species: torch.Tensor,
                coords: torch.Tensor,
                charges: torch.Tensor) -> torch.Tensor:
        """
        Your NNP should take species, coords, and charges as input
        and return the energies of the molecules.

        species contains the atomic numbers of the atoms in the molecule: [B, N]
        where B is the batch size, N is the number of atoms in the largest molecule.

        coords contains the coordinates of the atoms in the molecule: [B, N, 3]
        where B is the batch size, N is the number of atoms in the largest molecule,
        and 3 represents the x, y, z coordinates.

        charges contains the molecular charges: [B]

        The forward function returns the energies of the molecules: [B],
        output energy unit: eV"""

        # an example for computing molecular energy, replace with your NNP model
        energies = self.model((species, coords)).energies * 27.211386245988
        return energies
[5]:
# initialize and jit the wrapper with your NNP model
myNNP = userNNP()
myNNP_jit = torch.jit.script(myNNP)

# save the model to a file for later use
model_path = os.path.join(root, 'myNNP.pt')
torch.jit.save(myNNP_jit, model_path)
/home/jack/miniconda3/envs/py39/lib/python3.9/site-packages/torchani/resources/
[ ]:
# Now you can run Auto3D with your custom NNP model.
# Simply pass the model_path to the optimizing_engine argument

smi_path = os.path.join(root, "example/files/smiles.smi")  # You can specify the path to your file here
config = Auto3DOptions(path=smi_path, k=1, optimizing_engine=model_path, use_gpu=True, gpu_idx=0)
out = main(config)
print(out)
[ ]: