Molecular graphs, equivariance and docking
Species-conditioned self connections and parity-aware gates
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
Apply species-conditioned channel maps, scalar activations, and parity-aware gates to irrep features. Return updated features, activated gates, and output parities.
Function signature
equivariant_gated_update(
activations: dict,
parameters: dict,
masks: dict,
structure: dict,
even_gate: str = 'silu',
residual: bool = False,
) -> dict[str, torch.Tensor]Worked example
Even and odd gates
The even scalar becomes \operatorname{SiLU}(1)\approx0.7311. The first vector has an even gate: \operatorname{sigmoid}(0)=1/2 turns [2, 4, 6] into [1, 2, 3] and preserves odd parity. The second vector has an odd gate: \tanh(1) scales every component and changes the output parity to even. No component is centered.
import torch
activations = {
'message': torch.tensor([[[[1.0, 0.0, 0.0]], [[2.0, 4.0, 6.0]], [[2.0, 4.0, 6.0]]]], dtype=torch.float64, requires_grad=True),
'skip': torch.full((1, 3, 1, 3), 0.0, dtype=torch.float64, requires_grad=True),
'gates': torch.tensor([[[0.0], [0.0], [1.0]]], dtype=torch.float64, requires_grad=True),
}
parameters = {
'w_message': torch.tensor([[[1.0]], [[1.0]], [[1.0]]], dtype=torch.float64, requires_grad=True),
'w_self': torch.tensor([[[[0.0]], [[0.0]], [[0.0]]]], dtype=torch.float64, requires_grad=True),
'bias': torch.tensor([[0.0], [0.0], [0.0]], dtype=torch.float64, requires_grad=True),
'w_gate': torch.tensor([[[1.0]], [[1.0]], [[1.0]]], dtype=torch.float64, requires_grad=True),
'gate_bias': torch.tensor([[0.0], [0.0], [0.0]], dtype=torch.float64, requires_grad=True),
'activation_scales': torch.tensor([[[1.0], [1.0], [1.0]], [[1.0], [1.0], [1.0]]], dtype=torch.float64, requires_grad=True),
}
masks = {
'valid': torch.tensor([True], dtype=torch.bool),
}
structure = {
'species': torch.tensor([0], dtype=torch.int64),
'irreps': torch.tensor([[0, 1], [1, -1], [1, -1]], dtype=torch.int64),
'gate_parities': torch.tensor([1, 1, -1], dtype=torch.int64),
}
even_gate = 'sigmoid'
residual = False
result = equivariant_gated_update(activations=activations, parameters=parameters, masks=masks, structure=structure, even_gate=even_gate, residual=residual)Expected return
{
'features': torch.tensor([[[[0.7310585786300049, 0.0, 0.0]], [[1.0, 2.0, 3.0]], [[1.5231883119115297, 3.0463766238230594, 4.569564935734589]]]], dtype=torch.float64),
'activated_gates': torch.tensor([[[0.0], [0.5], [0.7615941559557649]]], dtype=torch.float64),
'out_parities': torch.tensor([1, -1, 1], dtype=torch.int64),
}Parameters
| Parameter | Shape and meaning |
|---|---|
activationsdict | Supplied intermediate tensors. |
parametersdict | Supplied model parameters, keyed as shown below. |
masksdict | Supplied masks. Each field below defines what True includes or permits. |
structuredict | Fields supplied together in this dictionary. |
even_gatestrDefault 'silu' | Choose "silu" or "sigmoid" for even scalar gates. Odd gates use the separately specified parity-compatible rule. |
residualboolDefault False | When True, add the supplied skip features after gating; this requires output parity to match the skip representation. |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- For each type t, output copy o and component m, compute
z_{ntom}=\sum_c message_{ntcm}\,w^{message}_{tco}+\sum_c skip_{ntcm}\,w^{self}_{species(n),tco}. Weight matrices are input-copy then output-copy; the component axis is unchanged. Add bias only for even scalars (l=0, p=+1). - For scalar
l=0, apply\operatorname{SiLU}(z)ifp=+1,\operatorname{tanh}(z)ifp=-1, then multiplyactivation_scales[0,t]. - For
l>0, compute a scalar gateg=\mathrm{gates}\mathbin{@}w_{\mathrm{gate}}[t]; addgate_biasonly if\mathrm{gate\_parities}[t]=+1. Evengatesuse configeven_gate='silu'default or 'sigmoid'; oddgatesalways tanh. - Multiply the gate by
activation_scales[1,t], then multiply every component ofzby that channel's gate. The output scalar parity staysp; nonscalar output parity isp\cdot \mathrm{gate\_parities}[t]. - Config
residual=Falseby default;Trueadds rawskipafter gating/scalar activation, and is legal only when all nonscalar gate parities are+1so outputirrepsmatch. Reject incompatible residual parity. Returnactivated_gateszero for scalar types and masked rows. - Ignore component padding, invalid nodes/
species, unused scalar-gate payloads and parity-forbiddenbiasentries, including NaNs. Global learned weights and activation scales are finite. The scales explicitly expose activation second-moment normalization instead of silently assuming library constants. - No arbitrary
l>0componentbiasis ever allowed. A packed block(l,p)has2\cdot l+1real components and multiplicityC;pis+1or-1under inversion.Dis a common padded width. Padding is ignored, includingNaNpadding. Distinct copies of a type are channels, not XYZ coordinates. - Use
sigmoid(z)=1/(1+e^{-z})andSiLU(z)=z\,sigmoid(z); odd scalar/gate activations use tanh.
Why this matters
Channels can mix within an irrep, but the activation or gate parity determines whether the output still transforms as the intended type.
Starter code
You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.
import torch
def equivariant_gated_update(
activations: dict,
parameters: dict,
masks: dict,
structure: dict,
even_gate: str = 'silu',
residual: bool = False,
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
features: (N, T, C, D).
activated_gates: (N, T, C).
out_parities: (T,)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement equivariant_gated_update")
Ready to implement it?
3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.