mirror of
https://github.com/cp2k/cp2k.git
synced 2026-07-21 06:25:15 -04:00
PAO-ML: Add pao-diff.py tool (#5577)
This commit is contained in:
parent
e2d766a6da
commit
b2ac3daf86
2 changed files with 49 additions and 5 deletions
40
tools/pao-ml/pao-diff.py
Executable file
40
tools/pao-ml/pao-diff.py
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# author: Ole Schuett
|
||||
|
||||
import numpy as np
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from pao.io import parse_pao_file
|
||||
from pao.dataset import prepare_xblock
|
||||
from pao.training import loss_function
|
||||
|
||||
|
||||
# ======================================================================================
|
||||
def main() -> None:
|
||||
description = "Compares two PAO files by computing the loss between their xblocks."
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument("pao_file_a", type=Path)
|
||||
parser.add_argument("pao_file_b", type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
a = parse_pao_file(args.pao_file_a)
|
||||
b = parse_pao_file(args.pao_file_b)
|
||||
|
||||
assert a.kinds == b.kinds
|
||||
assert a.atom2kind == b.atom2kind
|
||||
assert np.all(a.cell == b.cell)
|
||||
assert np.all(a.coords == b.coords)
|
||||
|
||||
for iatom in range(len(a.atom2kind)):
|
||||
xa = prepare_xblock(a.xblocks[iatom])
|
||||
xb = prepare_xblock(b.xblocks[iatom])
|
||||
loss = loss_function(xa, xb)
|
||||
print(f"iatom: {iatom+1} kind: {a.atom2kind[iatom]} loss: {loss:.8e}")
|
||||
|
||||
|
||||
# ======================================================================================
|
||||
main()
|
||||
|
||||
# EOF
|
||||
|
|
@ -29,6 +29,14 @@ def _as_int_tensor(x: List[Any] | npt.NDArray[np.int64]) -> torch.Tensor:
|
|||
return torch.tensor(np.array(x, dtype=np.int64))
|
||||
|
||||
|
||||
# ======================================================================================
|
||||
def prepare_xblock(xblock: npt.NDArray[np.float64]) -> torch.Tensor:
|
||||
# Orthonormalize labels as it's required for the loss_functions.
|
||||
ortho_xblock = np.linalg.svd(xblock, full_matrices=False)[2]
|
||||
# Add an extra leading dimension to simplify the batching.
|
||||
return _as_float_tensor(ortho_xblock).unsqueeze(0)
|
||||
|
||||
|
||||
# ======================================================================================
|
||||
class PaoDataset(Dataset[AtomicDataDict]):
|
||||
def __init__(
|
||||
|
|
@ -86,17 +94,13 @@ class PaoDataset(Dataset[AtomicDataDict]):
|
|||
|
||||
# TODO remove edges that are more than num_layers hops await from iatom.
|
||||
|
||||
# Orthonormalize labels as it's required for the loss_functions.
|
||||
xblock = np.linalg.svd(f.xblocks[iatom], full_matrices=False)[2]
|
||||
|
||||
# Collect all tensors into an AtomicDataDict for NequIP.
|
||||
self.examples.append(
|
||||
{
|
||||
"atom_types": _as_int_tensor(neighbor_atom_types),
|
||||
"edge_index": _as_int_tensor(edge_index).T,
|
||||
"edge_vectors": _as_float_tensor(edge_vectors),
|
||||
# Adding an extra leading dimension to simplify the batching.
|
||||
"xblock": _as_float_tensor(xblock).unsqueeze(0),
|
||||
"xblock": prepare_xblock(f.xblocks[iatom]),
|
||||
# The "pos" key is used by batched_from_list() to compute edge_index offsets.
|
||||
"pos": torch.zeros(len(neighbor_pos)),
|
||||
# Within an example the central atom is always the first atom.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue