Metadata-Version: 2.4
Name: engram
Version: 0.1.0a1
Summary: Shared research utilities for differentiable rendering, vision-model training, and perceptual analysis.
Author-email: Benjamin Beilharz <b@ben.graphics>
License: MIT
Keywords: differentiable-rendering,neural-networks,pytorch,vision-science
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: <3.14,>=3.12
Requires-Dist: drjit>=0.4
Requires-Dist: matplotlib>=3.8
Requires-Dist: mitsuba-scene-description>=0.2.2
Requires-Dist: mitsuba>=3.5
Requires-Dist: numpy>=1.26
Requires-Dist: torch>=2.2
Provides-Extra: all
Requires-Dist: accelerate>=0.28; extra == 'all'
Requires-Dist: flip-evaluator>=1.6; extra == 'all'
Requires-Dist: gpytoolbox>=0.2; extra == 'all'
Requires-Dist: moviepy>=1.0; extra == 'all'
Requires-Dist: pandas>=2.0; extra == 'all'
Requires-Dist: scipy>=1.11; extra == 'all'
Requires-Dist: transformers>=4.40; extra == 'all'
Requires-Dist: wandb>=0.16; extra == 'all'
Provides-Extra: flip
Requires-Dist: flip-evaluator>=1.6; extra == 'flip'
Provides-Extra: geometry
Requires-Dist: gpytoolbox>=0.2; extra == 'geometry'
Provides-Extra: hf
Requires-Dist: accelerate>=0.28; extra == 'hf'
Requires-Dist: transformers>=4.40; extra == 'hf'
Provides-Extra: stats
Requires-Dist: scipy>=1.11; extra == 'stats'
Provides-Extra: track
Requires-Dist: pandas>=2.0; extra == 'track'
Requires-Dist: wandb>=0.16; extra == 'track'
Provides-Extra: video
Requires-Dist: moviepy>=1.0; extra == 'video'
Description-Content-Type: text/markdown

# engram

Personal research utilities for differentiable rendering (Mitsuba 3 / Dr.Jit), NN training and vision science.
Engram in this context is more a "memory trace" that I upload here. It will be updated as I go, and may not be fully functional at any given time.
The goal however is to provide a stable package at post-alpha time with a clean API making it easier for vision/neuro researchers to use Mitsuba 3 and Dr.Jit in their experiments.

> Moves with the experiments I am running. The API is still unstable. Consider this pre-alpha.

```sh
uv add engram            # core: numpy, torch, matplotlib, mitsuba, drjit, mitsuba-scene-description
uv add "engram[all]"     # + scipy, wandb/pandas, flip-evaluator, moviepy, gpytoolbox, transformers/accelerate
```

Python >= 3.12. `import engram` is side-effect free: no Mitsuba variant is
selected, nothing heavy is imported until you touch the module that needs it.

## Module tour

| Module            | What's inside                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `engram.color`    | Correct piecewise sRGB encode/decode (`linear_to_srgb`, `srgb_to_linear`), `reinhard`/`hable_filmic` tonemaps, `linear_to_srgb_ldr` display transform. Backend-generic: numpy, torch, and Dr.Jit tensors.                                                                                                                                                                             |
| `engram.io`       | `save_image`/`load_image` (one writer for numpy/torch/Mitsuba images), `ensure_dir`, `renumber_frames` + `frames_to_video` (ffmpeg).                                                                                                                                                                                                                                                  |
| `engram.imagenet` | Offline ImageNet-1k `idx2label`/`label2idx` and ImageNet/CLIP normalization constants.                                                                                                                                                                                                                                                                                                |
| `engram.losses`   | `smooth_minimum`, the controversiality score family (Golan et al. 2020: classification, regression, undirected, confidence-weighted, hard), diagonal-Gaussian W2/symmetric-KL distances. Pure torch.                                                                                                                                                                                  |
| `engram.metrics`  | Torch-native `pearsonr`/`spearmanr` (tie-aware)/`r2_score`/`cohens_d`, RDM + RSA helpers, FLIP wrapper, colormapped `pixel_error_map`.                                                                                                                                                                                                                                                |
| `engram.stats`    | JZS Bayes factors (directional + rank-based) and vectorized permutation tests for paired condition scores.                                                                                                                                                                                                                                                                            |
| `engram.plot`     | Loss curves, image grids, side-by-side comparisons, RDM/RSA figures, sampled and analytic (GGX) polar BSDF-lobe plots.                                                                                                                                                                                                                                                                |
| `engram.track`    | `StepLogger` (per-run CSV + PNG persistence, wandb-free), lazy `init_wandb_run`, `wandb_image_grid`, `flatten_params`/`flatten_history` for readable log keys.                                                                                                                                                                                                                        |
| `engram.mi`       | `set_variant()` (explicit, env-var aware, autodetecting), `Variant` enum, `wrap_torch`/`wrap_drjit` autodiff bridges, Fibonacci-lattice cameras + sensor builders, envmap emitter, pixel/param/dual-buffer losses in correct sRGB, Large Steps registration, `SigmoidReparam` box constraints, spp-batched gradient accumulation, forward-gradient visualization, `SceneDescription`. |
| `engram.train`    | `seed_everything` + deterministic `render_seed` pairs, `EarlyStopping` (snapshots torch _and_ Dr.Jit optimizer state) + `PixelChangeCriterion`, torch helpers (device probe, FSDP-aware checkpointing, DDP mean-reduce), and the training framework below.                                                                                                                            |

## Training framework

`engram.train` ships an HF-`Trainer`-shaped framework that covers inverse
rendering and NN training with one interface: `OptimizationConfig` mirrors
`TrainingArguments` (output dir, evaluation/save strategies, gradient
accumulation, logging frequency), and `Optimization` subclasses implement the
step/loop methods. With `use_accelerator=True` the run goes through Hugging
Face `accelerate` (device placement, DDP, mixed precision — `engram[hf]`).

```python
import mitsuba as mi
from engram.mi import set_variant

set_variant()  # cuda_ad_rgb -> llvm_ad_rgb -> scalar_rgb, or $ENGRAM_MI_VARIANT

from engram.mi.scene import SceneDescription
from engram.train import DROptimization, OptimizationConfig
from engram.train.render import RenderPipeline
from engram.train.optimization import GroundTruth

scene = SceneDescription.from_dict(mi.cornell_box())      # dicts or msd.Plugin objects
target_render = scene.render()
scene["red.reflectance.value"] = mi.Color3f(0.5, 0.5, 0.5)

optim = DROptimization(
    config=OptimizationConfig(output_dir="albedo-recovery", epochs=15, learning_rate=0.05),
    pipeline=RenderPipeline(spp=16),
    scene=scene,
)

report = optim.fit(GroundTruth(image=target_render))
report.plot_losses()
```

Scene dictionaries can be authored with
[`mitsuba-scene-description`](https://pypi.org/project/mitsuba-scene-description/)
(typed dataclasses per Mitsuba plugin); `SceneDescription.from_dict` accepts
anything exposing `to_dict()`.

## Install groups (just pick what you need)

| Extra      | Enables                                | Pulls in                 |
| ---------- | -------------------------------------- | ------------------------ |
| `stats`    | `engram.stats`, exotic RDM metrics     | scipy                    |
| `track`    | `StepLogger` CSV output, wandb helpers | pandas, wandb            |
| `flip`     | `engram.metrics.flip_error`            | flip-evaluator           |
| `video`    | moviepy fallback for video assembly    | moviepy                  |
| `geometry` | remeshing workflows                    | gpytoolbox               |
| `hf`       | `use_accelerator=True` runs            | transformers, accelerate |
| `all`      | everything above                       |                          |

## Development

```sh
uv sync --group dev
uv run pytest          # mitsuba tests use llvm_ad_rgb/scalar_rgb and skip when unavailable
uv run ruff check src tests

# package up for PyPI
uv build
```
