NequIP / model /nn /misc.py
dadadaxi's picture
Upload folder using huggingface_hub
3e02ab8 verified
Raw
History Blame Contribute Delete
2.47 kB
# This file is a part of the `nequip` package. Please see LICENSE and README at the root for information on using it.
from typing import List, Optional
import torch
from e3nn.o3._irreps import Irreps
from onescience.datapipes.materials.nequip import AtomicDataDict
from ._graph_mixin import GraphModuleMixin
class Concat(GraphModuleMixin, torch.nn.Module):
"""Concatenate multiple fields into one."""
def __init__(self, in_fields: List[str], out_field: str, irreps_in={}):
super().__init__()
self.in_fields = list(in_fields)
self.out_field = out_field
self._init_irreps(irreps_in=irreps_in, required_irreps_in=self.in_fields)
self.irreps_out[self.out_field] = sum(
(self.irreps_in[k] for k in self.in_fields), Irreps()
)
def forward(self, data: AtomicDataDict.Type) -> AtomicDataDict.Type:
data[self.out_field] = torch.cat([data[k] for k in self.in_fields], dim=-1)
return data
class ApplyFactor(GraphModuleMixin, torch.nn.Module):
"""Applies factor to field."""
def __init__(
self,
in_field: str,
factor: float,
out_field: Optional[str] = None,
irreps_in={},
):
super().__init__()
self.in_field = in_field
self.out_field = in_field if out_field is None else out_field
self.factor = factor
self._init_irreps(irreps_in=irreps_in)
self.irreps_out[self.out_field] = self.irreps_in[self.in_field]
def forward(self, data: AtomicDataDict.Type) -> AtomicDataDict.Type:
data[self.out_field] = self.factor * data[self.in_field]
return data
class SaveForOutput(torch.nn.Module, GraphModuleMixin):
"""Copy a field and disconnect it from the autograd graph.
Copy a field and disconnect it from the autograd graph, storing it under another key for inspection as part of the models output.
Args:
field: the field to save
out_field: the key to put the saved copy in
"""
field: str
out_field: str
def __init__(self, field: str, out_field: str, irreps_in=None):
super().__init__()
self._init_irreps(irreps_in=irreps_in)
self.irreps_out[out_field] = self.irreps_in[field]
self.field = field
self.out_field = out_field
def forward(self, data: AtomicDataDict.Type) -> AtomicDataDict.Type:
data[self.out_field] = data[self.field].detach().clone()
return data