Metadata-Version: 2.1
Name: mlipcpp
Version: 0.1.2
Summary: Fast C++ implementation of Machine Learning Interatomic Potentials
Author-Email: Peter Spackman <peterspackman@fastmail.com>
License: BSD 3-Clause License
         
         Copyright (c) 2025, Peter Spackman
         
         Redistribution and use in source and binary forms, with or without
         modification, are permitted provided that the following conditions are met:
         
         1. Redistributions of source code must retain the above copyright notice, this
            list of conditions and the following disclaimer.
         
         2. Redistributions in binary form must reproduce the above copyright notice,
            this list of conditions and the following disclaimer in the documentation
            and/or other materials provided with the distribution.
         
         3. Neither the name of the copyright holder nor the names of its
            contributors may be used to endorse or promote products derived from
            this software without specific prior written permission.
         
         THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
         AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
         IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
         DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
         FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
         DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
         SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
         CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
         OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
         OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: C++
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Scientific/Engineering :: Physics
Project-URL: Homepage, https://github.com/peterspackman/mlip.cpp
Requires-Python: >=3.12
Requires-Dist: numpy>=1.24.0
Provides-Extra: ase
Requires-Dist: ase>=3.22.0; extra == "ase"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: ase>=3.22.0; extra == "test"
Description-Content-Type: text/markdown

# mlipcpp

> **WARNING: Pre-alpha software**
> This project is in early development. APIs may change without notice, and there may be bugs or incomplete features. Not recommended for production use.

Standalone C++ implementation of Machine Learning Interatomic Potentials (MLIPs) using [ggml](https://github.com/ggml-org/ggml).

Currently supports [PET/uPET](https://github.com/lab-cosmo/pet-mad) models (energy, forces, stresses).

## Quick start (Python)

```bash
# Install the package
pip install .

# Download and convert a model to GGUF
uv run scripts/convert_models.py --models pet-mad-s
```

```python
import numpy as np
import mlipcpp

# Load a model
model = mlipcpp.Predictor("gguf/pet-mad-s.gguf")
print(f"Model type: {model.model_type}, cutoff: {model.cutoff} A")

# Water molecule
positions = np.array([
    [0.000,  0.000, 0.000],  # O
    [0.757,  0.586, 0.000],  # H
    [-0.757, 0.586, 0.000],  # H
], dtype=np.float32)
atomic_numbers = np.array([8, 1, 1], dtype=np.int32)

# Predict energy
result = model.predict(positions, atomic_numbers, compute_forces=False)
print(f"Energy: {result.energy:.4f} eV")
# => Energy: -14.3693 eV

# Predict energy + forces
result = model.predict(positions, atomic_numbers, compute_forces=True)
print(f"Energy: {result.energy:.4f} eV")
forces = np.array(result.forces).reshape(-1, 3)
print(f"Forces (eV/A):\n{forces}")
```

### ASE integration

```python
from ase.io import read
from mlipcpp.ase import MLIPCalculator

atoms = read("structure.xyz")
atoms.calc = MLIPCalculator("gguf/pet-mad-s.gguf")
print(f"Energy: {atoms.get_potential_energy():.4f} eV")
```

## Converting models

Download and convert uPET models from HuggingFace to GGUF format:

```bash
# Convert all available models
uv run scripts/convert_models.py

# Convert a specific model
uv run scripts/convert_models.py --models pet-mad-s

# List available models
uv run scripts/convert_models.py --list
```

Default models: `pet-mad-s`, `pet-oam-l`, `pet-omad-xs`, `pet-omad-s`, `pet-omat-xs`, `pet-omat-s`, `pet-spice-s`

Use `--all` to also convert larger variants: `pet-oam-xl`, `pet-omad-l`, `pet-omat-m`, `pet-omat-l`, `pet-omat-xl`, `pet-omatpes-l`, `pet-spice-l`

## Building from source

### Dependencies

- [ggml](https://github.com/ggml-org/ggml) - Tensor library (fetched automatically via CMake)
- [fmt](https://github.com/fmtlib/fmt) - Formatting library (fetched automatically)

**Note:** This project uses a [modified fork of ggml](https://github.com/peterspackman/ggml) with additional backpropagation support for `CONCAT` and `CLAMP` operations, required for force/stress computation.

### Build

```bash
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j
```

### C++ CLI

```bash
# Energy only
./build/bin/graph_inference gguf/pet-mad-s.gguf structure.xyz

# With forces
./build/bin/graph_inference gguf/pet-mad-s.gguf structure.xyz --forces

# With forces and stress (periodic systems)
./build/bin/graph_inference gguf/pet-mad-s.gguf structure.xyz --forces --stress
```

## API

C, C++, Fortran, and Python APIs are provided. See `examples/` for usage.

## License

BSD 3-Clause
