|
| 1 | +# PyTensor Copilot Instructions |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +**PyTensor**: Python library for defining, optimizing, and evaluating mathematical expressions with multi-dimensional arrays. Computational backend for PyMC with extensible graph framework. Supports C, JAX, and Numba compilation backends. ~27MB, 492 Python files, Python 3.11-3.13, uses NumPy, SciPy, pytest, Sphinx. |
| 6 | + |
| 7 | +## Critical: Environment & Commands |
| 8 | + |
| 9 | +**ALWAYS use micromamba environment**: PyTensor is pre-installed in `.github/workflows/copilot-setup-steps.yml`. |
| 10 | + |
| 11 | +All commands MUST use: `micromamba run -n pytensor-test <command>` |
| 12 | + |
| 13 | +Example: `micromamba run -n pytensor-test python -m pytest tests/` |
| 14 | + |
| 15 | +## Testing & Building |
| 16 | + |
| 17 | +### Running Tests (ALWAYS use micromamba) |
| 18 | + |
| 19 | +```bash |
| 20 | +micromamba run -n pytensor-test python -m pytest tests/ # All tests (10-20 min) |
| 21 | +micromamba run -n pytensor-test python -m pytest tests/test_updates.py -v # Single file (<2 min) |
| 22 | +micromamba run -n pytensor-test python -m pytest tests/ --runslow # Include slow tests |
| 23 | +``` |
| 24 | + |
| 25 | +### Code Style |
| 26 | + |
| 27 | +**DO NOT run pre-commit/ruff locally** - they're not in copilot environment. CI handles style validation via `.github/workflows/test.yml`. |
| 28 | + |
| 29 | +### Documentation |
| 30 | + |
| 31 | +```bash |
| 32 | +micromamba run -n pytensor-test python -m sphinx -b html ./doc ./html # Build docs (2-3 min) |
| 33 | +``` |
| 34 | +**Never commit `html` directory**. |
| 35 | + |
| 36 | +### MyPy |
| 37 | + |
| 38 | +```bash |
| 39 | +micromamba run -n pytensor-test python ./scripts/run_mypy.py --verbose |
| 40 | +``` |
| 41 | +**PyTensor incompatible with strict mypy**. Liberal `type: ignore[rule]` and file exclusions are acceptable. |
| 42 | + |
| 43 | +## PyTensor Design Principles |
| 44 | + |
| 45 | +### API Differences from NumPy |
| 46 | + |
| 47 | +1. **Lazy evaluation**: Expressions are symbolic until `pytensor.function()` compiles or `.eval()` evaluates |
| 48 | +2. **Pure semantics**: Use `new_x = x[idx].set(y)` instead of `x[idx] = y` |
| 49 | +3. **Immutable/hashable**: `a == b` tests identity (`a is b`), not equality |
| 50 | +4. **Static shapes**: Broadcasting requires static shape of 1. Valid: `pt.add(pt.vector("x", shape=(1,)), pt.vector("y"))`. Invalid: `pt.add(pt.vector("x", shape=(None,)), pt.vector("y"))` with x.shape=1. |
| 51 | + |
| 52 | +### Config Flags |
| 53 | + |
| 54 | +Tests run with `config.floatX == "float32"` and `config.mode = "FAST_COMPILE"`: |
| 55 | +- Cast values: `test_value.astype(symbolic_var.type.dtype)` |
| 56 | +- Set custom mode or skip tests in `FAST_COMPILE` if needed |
| 57 | + |
| 58 | +## Code Style |
| 59 | + |
| 60 | +- **Comments**: Very sparingly, only for complex logic |
| 61 | +- **Testing**: Very succinct |
| 62 | + - Prefer `tests.unittest_tools.assert_equal_computations` over numerical evaluation |
| 63 | + - Test multiple inputs on one compiled function vs multiple compilations |
| 64 | + - Minimize conditions; if compiled, always evaluate once |
| 65 | + - Integrate with existing tests via parametrization |
| 66 | + |
| 67 | +## Repository Structure |
| 68 | + |
| 69 | +### Root |
| 70 | +`.github/` (workflows), `pyproject.toml` (config), `setup.py` (Cython build), `conftest.py` (pytest config), `environment.yml` (conda env) |
| 71 | + |
| 72 | +### Source (`pytensor/`) |
| 73 | +- `configdefaults.py`: Config system (floatX, mode) |
| 74 | +- `gradient.py`: Auto-differentiation |
| 75 | +- `compile/`: Function compilation |
| 76 | +- `graph/`: IR and optimization (`graph/rewriting/`) |
| 77 | +- `link/`: Backends (`c/`, `jax/`, `numba/`, `pytorch/`) |
| 78 | +- `tensor/`: Tensor ops (largest module, subdirs: `random/`, `rewriting/`, `conv/`) |
| 79 | +- `scalar/`: Scalar ops |
| 80 | +- `scan/`: Loop operations (`scan_perform.pyx` Cython) |
| 81 | +- `sparse/`: Sparse tensors |
| 82 | + |
| 83 | +### Tests (`tests/`) |
| 84 | +Mirrors source structure. `unittest_tools.py` has testing utilities. |
| 85 | + |
| 86 | +## CI/CD Pipeline |
| 87 | + |
| 88 | +### Workflows (`.github/workflows/`) |
| 89 | +1. **test.yml**: Main suite - Python 3.11/3.12/3.13, fast-compile (0/1), float32 (0/1), 7 test parts + backend jobs (numba, jax, torch) |
| 90 | +2. **mypy.yml**: Type checking |
| 91 | +3. **copilot-setup-steps.yml**: Environment setup |
| 92 | + |
| 93 | +### PR Requirements |
| 94 | +1. Style check (pre-commit: ruff, debug statements) |
| 95 | +2. All test matrix configurations pass |
| 96 | +3. MyPy passes (with exclusions) |
| 97 | + |
| 98 | +Test partitioning: 7 parts for parallelization (general, scan, tensor splits) |
| 99 | + |
| 100 | +## Common Issues |
| 101 | + |
| 102 | +### Import Errors |
| 103 | +Always use: `micromamba run -n pytensor-test python <command>` |
| 104 | + |
| 105 | +### Cython Rebuild |
| 106 | +If modifying `scan_perform.pyx`: `micromamba run -n pytensor-test pip install -e .` |
| 107 | + |
| 108 | +### BLAS Verification |
| 109 | +```bash |
| 110 | +micromamba run -n pytensor-test python -c 'import pytensor; assert pytensor.config.blas__ldflags != ""' |
| 111 | +``` |
| 112 | + |
| 113 | +### Config Test Failures |
| 114 | +- Cast dtypes: `value.astype(var.type.dtype)` |
| 115 | +- Skip FAST_COMPILE if test depends on optimizations |
| 116 | + |
| 117 | +## Trust These Instructions |
| 118 | + |
| 119 | +Comprehensive and tested. Search only if: (1) incomplete, (2) incorrect, or (3) need deeper implementation details. |
0 commit comments