Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
725 changes: 0 additions & 725 deletions .benchmarks/Linux-CPython-3.11-64bit/0001_pr_vectorized.json

This file was deleted.

725 changes: 0 additions & 725 deletions .benchmarks/Linux-CPython-3.11-64bit/0002_master_loop.json

This file was deleted.

84 changes: 4 additions & 80 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,12 @@
# Changelog

## 44.5.0 [#1368](https://github.com/openfisca/openfisca-core/pull/1368)

#### New features

- Add `transition_formula` to `Variable` for formula-driven `as_of` forward simulation.
- A variable with `transition_formula` computes sparse updates instead of full arrays: the formula returns `(selector, values)` where `selector` is a boolean mask or index array, and `values` is the new values for the selected individuals.
- Each call to `get_array` at a new period triggers the transition formula once (guarded by `_as_of_transition_computed`), applies the sparse diff via `set_input_sparse`, and caches the result.
- `set_input_sparse` is also exposed as a public method on `Holder` for callers that want to apply sparse patches directly.

- Add `initial_formula` to `Variable` for seeding `as_of` variables without a prior `set_input`.
- When a `transition_formula` needs to read the variable at `period - 1` but no base snapshot exists, OpenFisca now calls `initial_formula` instead of raising an error.
- `initial_formula` follows the same date-dispatch convention as regular formulas (`initial_formula_YYYY`, `initial_formula_YYYY_MM`, etc.).
- Requires `as_of = True` on the same variable; a `ValueError` is raised at definition time otherwise.

- Add multi-snapshot LRU cache to `as_of` variable holders.
- Replaces the previous single-entry snapshot cursor with an `OrderedDict`-based LRU cache keeping the K most-recently-used reconstructed snapshots.
- Cache size defaults to 3 and is configurable per variable (`Variable.snapshot_count`) or globally (`MemoryConfig.asof_max_snapshots`), with variable-level taking priority.
- Retroactive `set_input` (out-of-order writes) evicts all cached snapshots at or after the written instant to preserve correctness.

- Add `formula_type` field to `TraceNode` for `as_of` formula visibility.
- When `transition_formula` or `initial_formula` runs, the tracer records `formula_type = "transition"` or `formula_type = "initial"` on the corresponding trace node.

- Add `show_formula_type` option to `computation_log`.
- `simulation.tracer.computation_log.print_log(show_formula_type=True)` appends `[transition]` or `[initial]` tags to the relevant lines, making it easy to see which `as_of` formula ran during a simulation.

#### Bug fixes

- Fix false `SpiralError` when a `transition_formula` reads its own variable at the previous period.
- The existing spiral detector raised `SpiralError` immediately when the same variable appeared in the call stack at any different period, which always triggers for temporal recursion (`V@P` → `V@P-1` → `V@P-2`).
- Fix: in `_calculate_transition`, the cycle check is replaced by `_check_for_strict_cycle`, which only raises `CycleError` for the exact same `(variable, period)` pair. Termination is guaranteed by `_as_of_transition_computed`.

## 44.4.1

#### Performance improvements

- Fix quadratic reconstruction cost in `as_of` forward simulations.
- In the typical GET(M-1) → compute → SET(M) monthly loop, `_set_as_of` was unconditionally clearing the snapshot cursor after each write, forcing the next `get_array(M)` to reconstruct from the base through all M patches — O(N + M·k) per step, quadratic overall.
- Root cause: `_reconstruct_at` advanced the snapshot to `instant` during the internal diff computation, so the invalidation guard `snapshot[0] >= instant` triggered on equality even for strictly forward writes.
- Fix: when the new patch is appended at the end of the list (forward-sequential SET), the snapshot is updated to the new state instead of being discarded. Retroactive (out-of-order) writes still invalidate the snapshot correctly.
- Benchmark (N=1M, forward simulation): 1 yr / 10% change ×1.4, 5 yr / 10% ×4.1, 5 yr / 30% ×5.4.

## 44.4.0 [#1366](https://github.com/openfisca/openfisca-core/pull/1366)

#### Performance improvements

- Replace dense array storage with sparse patch storage for `as_of` variables.
- Instead of storing one full array per `set_input` call, the holder now keeps a single base array and a list of `(instant, changed_indices, changed_values)` patches.
- Memory reduction: ~60× for a 0.5% monthly change rate over 120 months (e.g. ~4 MB vs ~240 MB for 1M individuals).
- GET performance: a snapshot cursor makes forward-sequential reads O(k) (only new patches applied) instead of O(N); backward jumps degrade gracefully to O(N + k×P).
- Retroactive `set_input` (out-of-order patches) is supported with automatic snapshot invalidation.
- No change to the public API (`set_input`, `get_array`, `Variable.as_of`).
- Fix quadratic reconstruction cost in `as_of` forward simulations: when the new patch is appended at the end (forward-sequential SET), the snapshot is updated instead of discarded so the next GET does not reconstruct from base through all patches; retroactive writes still invalidate correctly.

## 44.4.0 [#1364](https://github.com/openfisca/openfisca-core/pull/1364)

#### New features

- **Entity links**: role-based and positional accessors, and dynamic population period-index helpers.
- `Many2OneLink.get_by_role(variable_name, period, role_value=...)`, `One2ManyLink.get_by_role(...)` and `ImplicitOne2ManyLink.get_by_role(...)`.
- `Many2OneLink.rank(variable_name, period)` (and on chained getter, e.g. `person.links["mother"].household.rank("age", period)`).
- `One2ManyLink.nth(n, variable_name, period, role=..., condition=...)` for the n-th target member per source.
- `has_role(role_value)` now supports `Role` objects (comparison by `.key`) in addition to raw values.
- `CorePopulation.snapshot_period(period)` and `get_period_id_to_rownum(period)` for optional dynamic-population period indexing.

#### Technical changes

- Removed unused `openfisca_core.model_api` import in `tests/core/parameters_date_indexing/test_date_indexing.py`.
- SimulationBuilder sets `_id_to_rownum` identity mapping for static simulations (`build_default_simulation`, `build_from_dict` / `build_from_entities`), for dynamic-population support.
- Add `PYTHON` variable to `tasks/lint.mk` so `make lint PYTHON=.venv/bin/python` works; fix style in `test_link_accessors.py` and remove unused variable in `test_many2one.py`.

## 44.3.0 [#1365](https://github.com/openfisca/openfisca-core/pull/1365)

#### New features

- **Generic Entity Links (Phase 1-6)**: Introduced a new Liam2-inspired generic entity linking system avoiding rigid hierarchies like `Person -> Household`.
- Added new `Many2OneLink` and `One2ManyLink` models to create powerful inter-entity networks (e.g., `Person -> Employer`).
- Added implicit links directly binding members arrays. This powers the new `population.links` property natively inside `TaxBenefitSystem.instantiate_entities()`.
- Full capability to chain relationships via python: `person.mother.household.get("rent", period)`.
- Powerful vectorized declarative aggregations out-of-the-box (e.g., `households.persons.sum("salary", period, condition=is_female)`).
## 44.6.0

#### Technical changes

- Backward compatibility is 100% maintained. Existing syntax via Projectors natively redirects to implicit links via modified `__getattr__`.
- Revert the codebase to commit `8d26af3` to align the repository with the currently published `44.2.2` baseline on PyPI.
- Mark versions `44.3.0`, `44.4.0`, `44.4.1`, and `44.5.0` as yanked.
- Bump version to `44.6.0` to restore continuous deployment from this reverted baseline.

## 44.2.2

Expand Down
57 changes: 0 additions & 57 deletions PR_DESCRIPTION.md

This file was deleted.

39 changes: 0 additions & 39 deletions benchmarks/README.md

This file was deleted.

61 changes: 0 additions & 61 deletions benchmarks/conftest.py

This file was deleted.

Loading
Loading