Skip to content

refactor: reorganize the partition module by codepath - #940

Merged
ivan-aksamentov merged 18 commits into
rustfrom
refactor/partition-codepath-layout
Aug 31, 2026
Merged

refactor: reorganize the partition module by codepath#940
ivan-aksamentov merged 18 commits into
rustfrom
refactor/partition-codepath-layout

Conversation

@ivan-aksamentov

@ivan-aksamentov ivan-aksamentov commented Aug 31, 2026

Copy link
Copy Markdown
Member

Update:

Follow-up to: #939

The partition module had grown into a flat directory where representation storage, marginal reconstruction, optimization, parsimony, and serialization all sat side by side, and several filenames hid which codepath they served. The sparse marginal reconstruction in particular was scattered across four files whose names did not reveal that they were sparse-only, so tracing one reconstruction from its caller meant opening a shifting set of unrelated files.

This change groups the module by concern and, within marginal reconstruction, by codepath. Representation payloads move under partition/storage/. Marginal reconstruction moves under partition/marginal/, split into a shared pass framework [src] and one directory per representation: sparse/ with execution-ordered stages (partition, message, pass, reconstruct, count, reroot), dense/, and a single discrete module. Branch-length optimization, Fitch parsimony, and Augur serialization move under optimize/, fitch/, and io/. Tests move beside the codepath they exercise. Module paths now read general to specific, so a filename or path names its codepath.

The single-consumer sparse chain (formerly three separate modules) is merged into the sparse directory as sequential pipeline stages rather than kept as remote modules, so following the sparse reconstruction is a linear descent through one directory instead of a search across the module. No behavior changes: the full test suite passes unchanged.

Work items

  • Group representation payloads under partition/storage/ (dense, sparse, discrete) [src]
  • Split marginal reconstruction into a shared framework and per-representation codepaths under partition/marginal/ [src]
  • Merge the single-consumer sparse chain into execution-ordered stage files under marginal/sparse/ [src]
  • Group optimization, Fitch parsimony, and Augur serialization under optimize/, fitch/, and io/ [src]
  • Colocate partition tests with the codepath they exercise
  • Update the crate README partition layout [src]

Possible improvements

- Move dense, sparse, discrete state types under partition/storage/ so the
  representation payloads cluster instead of sorting apart from the code that
  consumes them.
- Rename discrete_states to storage::discrete for a consistent module name.
…odule

- Move optimization contribution, dense coefficients, and sparse coefficients under partition/optimize/ so the optimization concern reads as one unit.
- Qualify consumers through the parent optimize module for a stable reference path.
- Move the Fitch partition into fitch/partition and its config into fitch/config so the parsimony codepath reads as one unit.
- Move the Augur ancestral node-data serialization out of the partition root into partition/io/ so output serialization is separate from partition math.
…codepath

- Move the dense/discrete marginal pass framework and the all-codepath log-likelihood helpers into marginal/shared so both representations import one framework module.
- Merge the single-consumer sparse chain (former marginal_sparse, marginal_passes, marginal_helpers) into a marginal/sparse directory with execution-ordered stage files: partition, message, pass, reconstruct, count, reroot.
- Relocate normalize_1d_inplace to the sparse message stage where its only callers live.
…odule

- Split the dense marginal partition into a marginal/dense directory: partition holds the type and its trait surface, pass holds the message-passing hooks.
- Move the discrete marginal partition to marginal/discrete as a single cohesive module.
- Both representations now sit beside the shared framework and sparse codepath under marginal/.
- Move the shared-framework tests beside marginal/shared, the sparse partition and transition-counting tests beside marginal/sparse, and leave the indexed-pass tests at the partition root.
- Rename the former marginal_core test module to marginal_shared to match its module.
- Describe the reorganized partition submodules: storage, marginal codepaths, fitch, optimize, and io.
… submodules

Group the flat shared module by concern: `data` holds `MarginalData` and the partition traits, `pass` holds the indexed backward and forward passes, and `normalize` holds the profile normalization and cavity-message helpers. Drop the non-indexed `marginal_process_node_backward`/`_forward` functions, which had no callers in the workspace.
…omment submodules

Separate the discrete partition type and its trait impls from the leaf-profile setup (`input`) and the Newick comment provider (`comment`).
…rd submodules

Separate the pass drivers from the per-node backward and forward reconstruction so each traversal direction reads on its own.
Move the generic parallel DAG scheduler (`run_dependency_queue`, `validate_dependency_graph`, and its worker pool) into its own module. The engine operates only on index-based prerequisites and successors, so isolating it lets a reader trace the indexed pass without crossing the concurrency machinery.
Marginal inference runs entirely through the indexed pass, so the `MarginalPartition::leaf_profile`, `backward_internal_pre`, and `forward_post` methods had no call sites. Drop them from the trait and from the dense and discrete implementations.
…directory

Move the propagate_raw_per_site tests out of a per-file message submodule into sparse/__tests__, alongside the other sparse tests, and rename them to the test_message_* convention.
Make `partition::timetree` a directory module matching sibling partitions, with the dispatch enum grouped by operational concern (branch, optimize, marginal) so each capability is traced in one file.
…ules

Each pass orchestrator drove a single per-node worker in a sibling module and had a single caller, forming a single-consumer chain across three files. Colocating each orchestrator with its worker lets a reader trace a pass end to end in one file and makes the worker a private helper.
…-graph

- Relocate the payload-agnostic dependency-queue scheduler and the graph-generic indexed pass beside the frontier traversals they complement, so callers depend on the lower, more stable crate.
- Move the pass tests to treetime-graph with crate-local fixtures.
… at the sparse root

The backward and forward marginal pass modules live directly under the sparse module, with no intermediate pass subdirectory, so the partition dispatch calls them without an extra path segment.
@ivan-aksamentov ivan-aksamentov changed the title refactor/partition codepath layout refactor: reorganize the partition module by codepath Aug 31, 2026
Base automatically changed from feat/timetree-ancestral-sequence-output to rust August 31, 2026 17:40
@ivan-aksamentov
ivan-aksamentov merged commit b1c07ee into rust Aug 31, 2026
9 checks passed
@ivan-aksamentov
ivan-aksamentov deleted the refactor/partition-codepath-layout branch August 31, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant