Metadata-Version: 2.5
Name: faster-diffbloch
Version: 0.1.0
Summary: Drop-in Metal GPU and CPU acceleration for diffBloch electron crystallography
Project-URL: Homepage, https://godofecht.github.io/diffFlow/
Project-URL: Repository, https://github.com/godofecht/diffFlow
Project-URL: Issues, https://github.com/godofecht/diffFlow/issues
Project-URL: Original diffBloch, https://diffbloch.com
Author-email: Abhishek Shivakumar <abhishek@example.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Requires-Dist: numpy>=1.24
Requires-Dist: torch>=2.0
Provides-Extra: diffbloch
Requires-Dist: diffbloch; extra == 'diffbloch'
Description-Content-Type: text/markdown

# faster-diffBloch

Drop-in Apple Silicon Metal GPU and optimized CPU acceleration for [diffBloch](https://diffbloch.com) electron crystallography structure refinement.

Documentation and comparison benchmarks: [https://godofecht.github.io/diffFlow/](https://godofecht.github.io/diffFlow/)

Original diffBloch project: [https://diffbloch.com](https://diffbloch.com)

---

## Why faster-diffBloch?

1. **Native Metal GPU Execution:**
   PyTorch MPS lacks a native GPU kernel for `aten::linalg_matrix_exp`, which causes PyTorch to fall back to CPU execution with host-device memory transfers. `faster-diffBloch` executes matrix exponentials directly on Apple Silicon Metal with zero-copy unified memory.

2. **Blocked-Pair Adjoint Formulation:**
   Standard matrix exponential autograd embeds the operator into a $2N \times 2N$ block matrix, costing $8 \times N^3$ FLOPs. `faster-diffBloch` evaluates the pullback in the block-triangular pair algebra $(Y_a Y_b, Y_a L_b + L_a Y_b)$, reducing the work to $3 \times N^3$ FLOPs (2.67x fewer products).

3. **Bit-for-Bit Validation:**
   Passes all 738 unit tests in diffBloch and reproduces the experimental 99-rotation quartz dataset ($R_{\text{obs}} = 0.0486$).

---

## Performance

Forward and backward timing comparison on Apple Silicon (M4 Max) at $N=579$ beams (CsPbBr3 scale):

| Implementation | Forward | Forward + Backward | Speedup vs PyTorch CPU | Speedup vs PyTorch MPS |
| :--- | :---: | :---: | :---: | :---: |
| PyTorch CPU | 25.7 ms | 130.3 ms | 1.00x | 1.17x |
| PyTorch MPS (fallback) | 26.2 ms | 153.0 ms | 0.85x | 1.00x |
| **faster-diffBloch CPU** | **24.4 ms** | **83.5 ms** | **1.56x** | **1.83x** |
| **faster-diffBloch Metal GPU** | **13.1 ms** | **58.1 ms** | **2.24x** | **2.63x** |

---

## Installation

```bash
pip install faster-diffbloch
```

---

## Usage

### 1. Drop-in CLI

Use `diffbloch-fast` or `faster-diffbloch` anywhere you would use `diffbloch`:

```bash
diffbloch-fast infer examples/Colmey_et_al_2026/data/quartz-no-abs
diffbloch-fast refine examples/Colmey_et_al_2026/data/quartz-no-abs
```

### 2. Python API Injection

Enable acceleration inside any existing diffBloch script:

```python
import faster_diffbloch

# Enable Metal GPU acceleration
faster_diffbloch.enable(device="gpu")

# Or CPU acceleration
faster_diffbloch.enable(device="cpu")

# Run standard diffBloch code
import diffBloch
# All propagate and matrix_exp calls now route through faster-diffBloch
```
