Skip to main content

vernier_core/
lib.rs

1//! Pure-Rust core for vernier.
2//!
3//! This crate has **no Python dependencies** and is usable directly from Rust
4//! binaries, CLI tools, and embedded contexts.
5//!
6//! By design, the public API of this crate is the source of truth for vernier's
7//! evaluation semantics. The `vernier-ffi` crate is a thin data-conversion
8//! layer over this one; if you find yourself adding logic to `vernier-ffi`
9//! rather than here, that's a code smell worth resolving.
10//!
11//! See the project's `docs/explanation/` for the architecture overview and
12//! `docs/adr/` for the design decisions that shaped this crate.
13
14#![forbid(unsafe_code)]
15#![warn(missing_docs)]
16#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used, clippy::panic))]
17
18pub mod accumulate;
19pub mod bench_counters;
20pub mod boundary_parity;
21pub mod breakdown;
22pub mod calibration;
23pub mod dataset;
24pub mod distributed;
25pub mod error;
26pub mod evaluate;
27pub mod evaluate_parallel;
28pub mod lrp;
29pub mod lvis_parity;
30pub mod manifest;
31pub mod manifest_csv;
32pub mod matching;
33pub mod parity;
34pub mod partition;
35pub mod segmentation;
36pub mod similarity;
37pub mod stream;
38pub mod summarize;
39pub mod tables;
40pub mod tide;
41
42// Each item lives at exactly one path — its home module. Adding a
43// re-export here widens the headline; treat it as a deliberate
44// decision keyed to the README minimal-usage example, not a default
45// for new pub items.
46pub use accumulate::Accumulated;
47pub use dataset::{CocoDataset, CocoDetections, EvalDataset};
48pub use error::EvalError;
49pub use evaluate::{
50    evaluate_bbox, evaluate_boundary, evaluate_keypoints, evaluate_segm, evaluate_with, AreaRange,
51    EvalGrid, EvaluateParams,
52};
53pub use evaluate_parallel::{
54    evaluate_bbox_parallel, evaluate_boundary_cached_parallel, evaluate_boundary_parallel,
55    evaluate_keypoints_parallel, evaluate_segm_cached_parallel, evaluate_segm_parallel,
56    evaluate_with_parallel,
57};
58pub use parity::ParityMode;
59pub use summarize::Summary;
60
61/// Library version string. Useful for parity tracing in fixtures and for
62/// debugging mismatches between Rust and Python sides of the FFI boundary.
63pub const VERSION: &str = env!("CARGO_PKG_VERSION");
64
65/// Stage-0 instrumentation hook for the bbox-IoU optimization plan.
66///
67/// Writes the `(kind, g, d, wall_ns)` records accumulated across every
68/// `BboxIou::compute` and `BboxIou::compute_overlap_mask` call to
69/// `path` as CSV (header `kind,g,d,wall_ns`; `kind` is the variant
70/// label `FullIou` or `OverlapMask`), then clears the in-process
71/// buffer. Returns the number of records written.
72///
73/// Only present when the crate is compiled with `--features
74/// bench-histogram`. Bench harness builds set this; the shipped wheel
75/// never does, so production runs carry zero recording overhead.
76#[cfg(feature = "bench-histogram")]
77pub fn dump_bbox_iou_histogram_csv(path: &std::path::Path) -> std::io::Result<usize> {
78    similarity::bbox::histogram::dump_csv(path)
79}
80
81/// `(par_iter_ns, serial_post_ns, n_calls)` for [`evaluate_with_parallel`]
82/// since last read, then resets. Gated on `bench-timings`.
83#[cfg(feature = "bench-timings")]
84pub fn read_and_reset_evaluate_parallel_timings() -> (u64, u64, u64) {
85    evaluate_parallel::timings::read_and_reset()
86}
87
88/// `build_gt_anns` + `build_dt_anns` call count since last read,
89/// then resets. Gated on `bench-timings`.
90#[cfg(feature = "bench-timings")]
91pub fn read_and_reset_build_anns_count() -> u64 {
92    evaluate::build_anns_count::read_and_reset()
93}
94
95/// `(gt_parse_ns, gt_from_parts_ns, dt_parse_ns, dt_from_inputs_ns)`
96/// for the COCO loaders since last read, then resets. Gated on `bench-timings`.
97#[cfg(feature = "bench-timings")]
98pub fn read_and_reset_dataset_timings() -> (u64, u64, u64, u64) {
99    dataset::dataset_timings::read_and_reset()
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    #[test]
107    fn version_is_set() {
108        assert!(!VERSION.is_empty());
109    }
110}