Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
21 changes: 19 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,25 @@ degenerate input, and tests under `tests/proptest_sos.rs` enforce that.
`Vertex`, `Cell`, `Facet`, `Ridge`, `InSphere`, `Orientation`,
`insphere`, `circumcenter`, `circumradius`. Avoid Rust‑ecosystem
abstractions that obscure the math.
- Use `tracing::{debug,info,warn,error}!` for all runtime diagnostics.
Never `eprintln!` / `println!` outside examples and benches.
- Use `tracing::{debug,info,warn,error}!` for committed diagnostics
across production code, tests, and benchmarks, especially for
library/runtime code, non-trivial test diagnostics, and debugging of
numerical or topological invariants.
- `eprintln!` is acceptable only for short-lived local debugging while
investigating a problem; remove it before landing changes.
- Never log inside hot benchmark loops or Criterion-measured closures.
Emit setup/summary diagnostics outside the measured path instead.
- Gate non-essential test/benchmark diagnostics behind feature flags.
In this repository use `test-debug` for test diagnostics and
`bench-logging` for benchmark diagnostics, e.g.:

```rust
#[cfg(feature = "test-debug")]
tracing::debug!("test diagnostic");

#[cfg(feature = "bench-logging")]
tracing::debug!("diagnostic message");
```

### Scientific notation in docs

Expand Down
152 changes: 142 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Merged Pull Requests

- Orient Delaunay repair replacement cells [#307](https://github.com/acgetchell/delaunay/pull/307) [#336](https://github.com/acgetchell/delaunay/pull/336)
- Use dedicated perf profile for consistent benchmark measurement [#334](https://github.com/acgetchell/delaunay/pull/334)
- Periodic-aware Delaunay verification (Level 4) for toroidal tria… [#333](https://github.com/acgetchell/delaunay/pull/333)
- Adopt Rust 1.95.0 MSRV [#330](https://github.com/acgetchell/delaunay/pull/330)
- Bump actions-rust-lang/setup-rust-toolchain [#328](https://github.com/acgetchell/delaunay/pull/328)
Expand Down Expand Up @@ -53,6 +55,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add T² (3×3 grid) and T³ (3×3×3 Freudenthal) integration tests
validating χ = 0 via explicit construction

- Instrument large-scale 4D debugging and widen local repair seeds
[`fd5dbf2`](https://github.com/acgetchell/delaunay/commit/fd5dbf211af14124db6cc21ceef0b821b53cdffe)

- Thread cavity-touched cells through insertion as `repair_seed_cells`
so post-insertion local Delaunay repair widens its frontier beyond
the inserted vertex star; cells shrunk out of the conflict region
during cavity reduction now participate in the next repair pass.

- Accumulate ridge-fan extras across every fan in a conflict region
before returning `RidgeFan`, letting one cavity-reduction step
shrink all detected fans at once instead of peeling them iteration
by iteration.

- Add release-visible diagnostic hooks routed through `tracing::debug!`:
`DELAUNAY_BULK_PROGRESS_EVERY` for periodic batch-construction
progress, `DELAUNAY_DEBUG_RETRYABLE_SKIP` for retryable
conflict-region skip traces, `DELAUNAY_DEBUG_CAVITY_REDUCTION_ONCE`
for the first cavity-reduction chain, `DELAUNAY_DEBUG_RIDGE_FAN_ONCE`
for the first detected ridge fan, and
`DELAUNAY_REPAIR_DEBUG_POSTCONDITION_FACET` /
`DELAUNAY_REPAIR_DEBUG_RIDGE_MIN_MULTIPLICITY` for repair
postcondition debugging.

- Thread `last_applied_flip` through repair postcondition verification
so unresolved k=2 facet and ridge snapshots can relate the violating
local star to the immediately preceding flip.

- Replace `ConflictError::InternalInconsistency { context: String }`
with a typed `InternalInconsistencySite` enum carrying structured
indices and counts, so callers can `matches!` on specific sites
instead of parsing prose.

- Generalize the large-scale incremental prefix bisect over `const D`,
add a 4D counterpart targeting the seeded 500-point repro
(`0xD225_B8A0_7E27_4AE6`), and expose it via
`just debug-large-scale-4d-incremental-bisect`.

- Switch the large-scale debug just recipes to `--release` and
document the 2026-04-23 re-verification: historical 35-point 3D and
100-point 4D correctness repros from #306/#307 now pass, while a
500-point 4D seed still fails all shuffled retries with
`Ridge fan detected: 4 facets share ridge with 3 vertices`.

- Default the large-scale debug harness tracing filter to `debug` when
any of the new release-visible env vars are present so library-side
`tracing::debug!` events surface without extra `RUST_LOG` wiring.

- Broaden `test_perturbation_retry_and_exhaustion_4d` and
`test_perturbation_retry_seeded_branch_4d` to iterate over 50 seeds
so the retry-path assertions stay robust to insertion-path
improvements that make individual well-conditioned seeds less likely
to trigger retries.

### Changed

- Rename tds file and move delaunay/builder into triangulation/ [#317](https://github.com/acgetchell/delaunay/pull/317)
Expand Down Expand Up @@ -94,10 +149,12 @@ Perform a general dependency update, including a patch bump for `uuid`.
updates, and merged pull requests. Add `.kilo/` to the ignored user
configuration patterns.

- Use dedicated perf profile for consistent benchmark measurement
[`ebf9abf`](https://github.com/acgetchell/delaunay/commit/ebf9abf1571b397aeabd47196a101961c456c0c4)
- Use dedicated perf profile for consistent benchmark measurement [#334](https://github.com/acgetchell/delaunay/pull/334)
[`f527c0c`](https://github.com/acgetchell/delaunay/commit/f527c0cf37b76f09222800afcfc138e623957678)

- Changed: use dedicated perf profile for consistent benchmark measurement

Introduce a `perf` Cargo profile that inherits from `release` but
Introduce a `perf` Cargo profile that inherits from `release` but
restores ThinLTO and single codegen units. This ensures local, CI, and
release benchmarks are generated with identical optimization settings.

Expand All @@ -107,18 +164,61 @@ Introduce a `perf` Cargo profile that inherits from `release` but
A new `bench-smoke` target provides quick harness validation without
the overhead of high-sample measurements.

Also deniest warnings via the manifest lint policy to ensure consistent
Also denies warnings via the manifest lint policy to ensure consistent
repository-wide enforcement.

- Standardize benchmark profiles and enhance SARIF analysis [`9acf503`](https://github.com/acgetchell/delaunay/commit/9acf503ad75f031a4c2c5978f0f353951623499f)
- Changed: standardize benchmark profiles and enhance SARIF analysis

Standardize benchmark workflows to use the `perf` profile by default
Standardize benchmark workflows to use the `perf` profile by default
across local scripts and CI for consistent optimization settings. Add a
dedicated CodeQL analysis workflow and refactor SARIF reporting for
cargo-audit, Clippy, and Codacy to improve GitHub Code Scanning
integration. Update manifest lints to comply with RFC 3389 priority
requirements and fix the minimum sample size for benchmark smoke tests.

- Changed: track sampling metadata and standardize benchmark profiles

Enhance performance regression testing by embedding sampling configuration
(Criterion settings and Cargo profile) into baseline files. This enables
automatic detection of configuration mismatches during comparisons.
Standardize benchmarking scripts on the trusted perf profile and update
developer guidelines for naming conventions and local imports.

- Changed: enable debug line tables for perf profile and refine validation

Include `debug = "line-tables-only"` in the perf Cargo profile to
enable source-level profiling. Update the benchmark comparison logic
to ensure that legacy baselines with missing or "Unknown" metadata
trigger configuration mismatch warnings.

- Changed: expand benchmark metadata validation tests

Update the benchmark utility tests to verify that differences or
omissions in Criterion measurement and warm-up time are correctly
reported in configuration mismatch warnings.

- Changed: enable CodeRabbit request changes workflow

Enable the request_changes_workflow in the CodeRabbit configuration to
allow the AI reviewer to formally request changes on pull requests. This
ensures that identified issues are explicitly addressed during the
review process rather than appearing as informational comments only.

- Harden flip diagnostics and refine large-scale debug workflows
[`fb23595`](https://github.com/acgetchell/delaunay/commit/fb23595fd664ef19bb3ea7ca134e725214dfeeca)

Refactor flip snapshotting and cavity-reduction bookkeeping to ensure
diagnostic reliability and accurate repair-seed collection. Update
documentation and justfile recipes to reflect fixed historical repros
and transition to monitoring active scalability investigations for 3D,
4D, and 5D datasets.

- Move removed-cell vertex capturing into fallible internal helpers
- Implement lazy evaluation for cavity-reduction diagnostic logs
- Harden vertex deduplication with fallible epsilon validation
- Update 4D known issues to reflect 100-point and 500-point fixes
- Simplify the large-scale debug harness CLI and documentation

### Documentation

- Sync documentation with post-v0.7.5 changes [skip ci] [`5fa36aa`](https://github.com/acgetchell/delaunay/commit/5fa36aa67cb99bb3a5781e4c2733c2acec3adea8)
Expand Down Expand Up @@ -210,6 +310,38 @@ Standardize benchmark workflows to use the `perf` profile by default
- Add unit tests for align_periodic_offset (identity, delta shifts,
higher-dimension, overflow).

- Orient Delaunay repair replacement cells [#307](https://github.com/acgetchell/delaunay/pull/307) [#336](https://github.com/acgetchell/delaunay/pull/336)
[`68deb62`](https://github.com/acgetchell/delaunay/commit/68deb6212a0860cd85776744d29ba7e76f368579)

- fix: orient Delaunay repair replacement cells [#307](https://github.com/acgetchell/delaunay/pull/307)

- Build flip replacement cell order from oriented cavity-boundary constraints.
- Keep raw bistellar flips topology-oriented while requiring positive replacement geometry for Delaunay repair.
- Canonicalize bulk repair results before continuing construction.
- Add a 4D regression test for the issue #307 bulk construction failure.
- Document branch naming conventions for contributors and agents.
- Close the 4D bulk repair retry collapse [`8c110f3`](https://github.com/acgetchell/delaunay/commit/8c110f3d1eac51ca189eb608fd6f09715afde879)

- Raise the D≥4 per-insertion repair budget, add a rate-limited escalation pass, and widen local post-repair validation so the 500-point #204 repro converges
without skipped vertices.
- Preserve removed-cell snapshots and predecessor context in flip diagnostics, drop stale repair seeds after cavity reduction, and re-export locate conflict
diagnostics from the prelude.
- Replace committed `eprintln!` diagnostics in production, tests, and benches with `tracing` , using `test-debug` and `bench-logging` gates and keeping logs
out of Criterion hot loops.
- Document the #204 investigation, refresh the 4D known-issues and TODO notes, and record the repository logging policy plus release-visible debug environment
variables.
- Normalize indented headings in changelog post-processing [`cff07db`](https://github.com/acgetchell/delaunay/commit/cff07db377414f8e0176d7e41d8fe6073c661576)

Update the changelog post-processing script to convert indented ATX
headings from commit bodies into bold prose. This ensures the generated
CHANGELOG.md complies with Markdownlint rule MD023 (headings must start
at column 0) while preserving the visual hierarchy and readability of
historical commit summaries.

Additionally, internal diagnostic state for Delaunay repair was moved
from global atomics to a per-attempt structure to ensure reliable
rate-limiting across concurrent threads.

### Maintenance

- Bump pytest in the uv group across 1 directory [#322](https://github.com/acgetchell/delaunay/pull/322)
Expand Down Expand Up @@ -1979,7 +2111,7 @@ Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.2.0 to
Implements correctness fixes, API improvements, and comprehensive testing
for the Hilbert space-filling curve ordering utilities.

## Correctness Fixes
**Correctness Fixes**

- Add debug_assert guards in hilbert_index_from_quantized for parameter
validation (bits range and overflow checks)
Expand All @@ -1988,7 +2120,7 @@ Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.2.0 to
to scaled.round().to_u32() for fairer spatial distribution across grid
cells, improving point ordering quality

## API Design
**API Design**

- Add HilbertError enum with InvalidBitsParameter, IndexOverflow, and
DimensionTooLarge variants for proper error handling
Expand All @@ -1999,7 +2131,7 @@ Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.2.0 to
- Bulk API avoids redundant quantization computation, significantly
improving performance for large insertion batches

## Testing
**Testing**

- Add 4D continuity test verifying Hilbert curve property on 256-point
grid (bits=2)
Expand All @@ -2012,7 +2144,7 @@ Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.2.0 to

- All 17 Hilbert-specific tests pass (11 existing + 6 new)

## Known Issue
**Known Issue**

Temporarily ignore repair_fallback_produces_valid_triangulation test as
the rounding change affects insertion order, exposing a latent geometric
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 50 additions & 10 deletions benches/large_scale_performance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,37 @@ use std::sync::{Mutex, OnceLock};
use std::time::Duration;
use sysinfo::{ProcessRefreshKind, ProcessesToUpdate, RefreshKind, System};

#[cfg(feature = "bench-logging")]
fn init_tracing() {
static INIT: std::sync::Once = std::sync::Once::new();
INIT.call_once(|| {
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info"));
let _ = tracing_subscriber::fmt().with_env_filter(filter).try_init();
});
}

#[cfg(not(feature = "bench-logging"))]
const fn init_tracing() {}

macro_rules! bench_info {
($($arg:tt)*) => {{
#[cfg(feature = "bench-logging")]
{
init_tracing();
tracing::info!($($arg)*);
}
}};
}

/// Memory usage information for benchmarking (in KiB)
#[cfg_attr(
not(feature = "bench-logging"),
expect(
dead_code,
reason = "Memory fields are unpacked by optional bench diagnostics"
)
)]
#[derive(Debug, Clone)]
struct MemoryInfo {
before: u64,
Expand All @@ -104,7 +134,7 @@ fn get_memory_usage() -> u64 {

// Log memory unit on first call for clarity in all benchmark runs
UNIT_LOGGED.call_once(|| {
eprintln!("[INFO] Memory measurements in KiB (sysinfo::Process::memory() / 1024)");
bench_info!("Memory measurements in KiB (sysinfo::Process::memory() / 1024)");
});

let pid = sysinfo::get_current_pid().expect("Failed to get current PID");
Expand All @@ -126,7 +156,8 @@ fn get_memory_usage() -> u64 {

/// Get the deterministic base seed for random point generation.
/// Reads `DELAUNAY_BENCH_SEED` (decimal or 0x-hex). Defaults to 42.
/// Prints the resolved seed once on first use if `PRINT_BENCH_SEED` is set.
/// Logs the resolved seed once on first use if `PRINT_BENCH_SEED` is set and
/// the `bench-logging` feature is enabled.
fn get_benchmark_seed() -> u64 {
static SEED: OnceLock<u64> = OnceLock::new();
*SEED.get_or_init(|| {
Expand All @@ -141,7 +172,7 @@ fn get_benchmark_seed() -> u64 {
.unwrap_or(42);

if std::env::var("PRINT_BENCH_SEED").is_ok() {
eprintln!("Benchmark seed: 0x{seed:X} ({seed})");
bench_info!("Benchmark seed: 0x{seed:X} ({seed})");
}

seed
Expand Down Expand Up @@ -281,16 +312,24 @@ fn bench_memory_usage<const D: usize>(c: &mut Criterion, dimension_name: &str, n
// Single measurement for memory delta - reduce sample size
group.sample_size(10);

#[cfg(feature = "bench-logging")]
if std::env::var_os("BENCH_PRINT_MEM").is_some() {
let mem_info = measure_construction_with_memory::<D>(n_points, seed);
bench_info!(
"Memory sample: before={} KiB, after={} KiB, delta={} KiB (TDS-only: {} KiB)",
mem_info.before,
mem_info.after,
mem_info.delta,
mem_info.tds_delta
);
}

// Prime the one-time memory-unit log outside Criterion's measured closure.
let _ = get_memory_usage();

group.bench_function("construction_memory_delta", |b| {
b.iter(|| {
let mem_info = measure_construction_with_memory::<D>(n_points, seed);
// Report memory usage to stderr (won't interfere with benchmark timing)
if std::env::var_os("BENCH_PRINT_MEM").is_some() {
eprintln!(
"Memory: before={} KiB, after={} KiB, delta={} KiB (TDS-only: {} KiB)",
mem_info.before, mem_info.after, mem_info.delta, mem_info.tds_delta
);
}
black_box(mem_info)
});
});
Expand Down Expand Up @@ -527,6 +566,7 @@ fn bench_5d_suite(c: &mut Criterion) {
criterion_group!(
name = large_scale_benches;
config = {
init_tracing();
let sample_size = std::env::var("BENCH_SAMPLE_SIZE")
.ok()
.and_then(|v| v.parse::<usize>().ok())
Expand Down
Loading
Loading