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
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ just check
just ci
```

Codex sandbox shells may not include Homebrew on `PATH`. When a validation
recipe or direct tooling command needs `uv`, prefer:

```bash
PATH=/opt/homebrew/bin:$PATH just check
/opt/homebrew/bin/uv run pytest scripts/tests
```

Refer to `docs/dev/commands.md` for full details.

For tooling-alignment work, update `docs/dev/tooling-alignment.md` with the
Expand Down
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,15 @@ PRs are evaluated on:
- **Style**: Does the code follow project conventions?
- **Mathematical Accuracy**: Are geometric algorithms correct?

### Non-Substantive Changes

PRs that only introduce whitespace churn, blank-line changes, formatting noise, or other
non-substantive edits may be declined unless they are part of a clearly justified cleanup or
required by project tooling.

Accepted contributions should materially improve correctness, numerical robustness, topology
invariants, performance, documentation clarity, tests, maintainability, or user-facing behavior.

### Handling Feedback

- **Respond to all comments**: Address each piece of feedback
Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,16 @@ Choose the smallest prelude that matches the task:

| Task | Import |
|---|---|
| Build, configure, insert, or remove vertices | `use delaunay::prelude::triangulation::*` |
| Construct/configure a Delaunay triangulation | `use delaunay::prelude::triangulation::construction::*` |
| Read-only traversal, adjacency, convex hulls, and comparison helpers | `use delaunay::prelude::query::*` |
| Points, kernels, predicates, and geometric measures | `use delaunay::prelude::geometry::*` |
| Random points or triangulations for examples, tests, and benchmarks | `use delaunay::prelude::generators::*` |
| Low-level incremental insertion building blocks | `use delaunay::prelude::triangulation::insertion::*` |
| Bistellar flips / Edit API | `use delaunay::prelude::triangulation::flips::*` |
| Delaunay repair diagnostics and policies | `use delaunay::prelude::triangulation::repair::*` |
| Delaunayize workflow | `use delaunay::prelude::triangulation::delaunayize::*` |
| Construction telemetry diagnostics | `use delaunay::prelude::triangulation::diagnostics::*` |
| Construction validation cadence/policy | `use delaunay::prelude::triangulation::validation::*` |
| Hilbert ordering and quantization utilities | `use delaunay::prelude::ordering::*` |
| Low-level TDS cells, facets, keys, and validation reports | `use delaunay::prelude::tds::*` |
| Collection aliases and small buffers | `use delaunay::prelude::collections::*` |
Expand All @@ -107,9 +110,11 @@ Choose the smallest prelude that matches the task:

`use delaunay::prelude::*` remains available for quick experiments, but examples
and benchmarks in this repository prefer focused preludes so imports document intent.
The broad `delaunay::prelude::triangulation::*` import is retained for compatibility,
but new docs and tests should prefer the narrow workflow preludes above.

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{DelaunayTriangulation, vertex};

// Create a 4D Delaunay triangulation from a set of vertices (uses AdaptiveKernel by default).
let vertices = vec![
Expand Down Expand Up @@ -138,7 +143,9 @@ assert!(dt.is_valid().is_ok());
For periodic boundary conditions, use `DelaunayTriangulationBuilder`:

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{
DelaunayTriangulationBuilder, TopologyKind, vertex,
};

// Phase 1: Canonicalization (wraps coordinates into [0, 1)²)
let vertices = vec![
Expand Down Expand Up @@ -196,7 +203,11 @@ The construction pipeline exposes deterministic controls for experiments and reg
- Explicit topology/validation configuration via `TopologyGuarantee` and `ValidationPolicy`

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{
ConstructionOptions, DedupPolicy, DelaunayTriangulationBuilder, InsertionOrderStrategy,
RetryPolicy, TopologyGuarantee, vertex,
};
use delaunay::prelude::triangulation::validation::ValidationPolicy;

let vertices = vec![
vertex!([0.0, 0.0]),
Expand Down
8 changes: 5 additions & 3 deletions benches/ci_performance_suite.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![forbid(unsafe_code)]

//! CI Performance Suite - optimized performance regression testing for CI/CD
//!
//! This benchmark is the small, durable performance contract for the delaunay
Expand Down Expand Up @@ -36,12 +38,12 @@ use delaunay::prelude::geometry::{
AdaptiveKernel, Coordinate, Point, RobustKernel, simplex_volume,
};
use delaunay::prelude::query::ConvexHull;
use delaunay::prelude::triangulation::construction::{
ConstructionOptions, DelaunayTriangulation, InsertionOrderStrategy, RetryPolicy, Vertex,
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.
use delaunay::prelude::triangulation::flips::{
BistellarFlips, CellKey, EdgeKey, FacetHandle, RidgeHandle, TopologyGuarantee, TriangleHandle,
};
use delaunay::prelude::triangulation::{
ConstructionOptions, DelaunayTriangulation, InsertionOrderStrategy, RetryPolicy, Vertex,
};
use delaunay::vertex;
use std::{env, hint::black_box, num::NonZeroUsize, sync::Once};
#[cfg(feature = "bench-logging")]
Expand Down
2 changes: 1 addition & 1 deletion benches/large_scale_performance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
use criterion::{BatchSize, Criterion, Throughput, criterion_group, criterion_main};
use delaunay::prelude::generators::generate_random_points_seeded;
use delaunay::prelude::geometry::AdaptiveKernel;
use delaunay::prelude::triangulation::{
use delaunay::prelude::triangulation::construction::{
ConstructionOptions, DelaunayTriangulation, RetryPolicy, Vertex,
};
use delaunay::vertex;
Expand Down
2 changes: 1 addition & 1 deletion benches/profiling_suite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ use delaunay::prelude::generators::{
};
use delaunay::prelude::geometry::{Coordinate, safe_usize_to_scalar};
use delaunay::prelude::query::*;
use delaunay::prelude::triangulation::{
use delaunay::prelude::triangulation::construction::{
ConstructionOptions, DelaunayTriangulationBuilder, RetryPolicy,
};
use delaunay::vertex;
Expand Down
8 changes: 5 additions & 3 deletions benches/topology_guarantee_construction.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![forbid(unsafe_code)]

//! Benchmark: construction cost vs topology guarantee (2D–5D)
//!
//! This benchmark compares `TopologyGuarantee::Pseudomanifold`, `TopologyGuarantee::PLManifold`
Expand All @@ -14,9 +16,9 @@

use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use delaunay::prelude::generators::generate_random_points_seeded;
use delaunay::prelude::triangulation::{
DelaunayRepairPolicy, DelaunayTriangulation, TopologyGuarantee, ValidationPolicy,
};
use delaunay::prelude::triangulation::construction::{DelaunayTriangulation, TopologyGuarantee};
use delaunay::prelude::triangulation::repair::DelaunayRepairPolicy;
use delaunay::prelude::triangulation::validation::ValidationPolicy;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
use delaunay::vertex;
use std::hint::black_box;
use std::time::Duration;
Expand Down
8 changes: 4 additions & 4 deletions docs/api_design.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ The library provides two distinct APIs for different use cases:
For most use cases, the simple constructor is sufficient:

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{DelaunayTriangulation, vertex};

// Simple construction from vertices (Euclidean space, default options)
let vertices = vec![
Expand All @@ -87,7 +87,7 @@ For advanced configuration (toroidal topology, custom validation policies, etc.)
use `DelaunayTriangulationBuilder`:

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{DelaunayTriangulationBuilder, vertex};

// Toroidal (periodic) triangulation in 2D
let vertices = vec![
Expand Down Expand Up @@ -148,7 +148,7 @@ for topology guarantee and validation policy details.
The Edit API is exposed through the `BistellarFlips` trait in `prelude::triangulation::flips`:

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{DelaunayTriangulation, vertex};
use delaunay::prelude::triangulation::flips::*;

// Start with a valid triangulation
Expand Down Expand Up @@ -257,7 +257,7 @@ After applying flips, you should:
You can mix both APIs in the same workflow:

```rust
use delaunay::prelude::triangulation::*;
use delaunay::prelude::triangulation::construction::{DelaunayTriangulation, vertex};
use delaunay::prelude::triangulation::flips::*;

// 1. Build initial triangulation (Builder API)
Expand Down
205 changes: 205 additions & 0 deletions docs/archive/issue_341_n1_repair_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# Issue #341: N=1 Repair Performance Plan

This note captures the current plan for resolving #341 after defaulting batch
construction repair to every insertion (`N=1`). The goal is reasonable
performance on 10K vertices in 3D without compromising correctness,
orthogonality, or valid Delaunay output.

## Priority Order

1. Numerical correctness
2. Topological correctness
3. Orthogonality and maintainability
4. Performance within scope

## Current Direction

The branch now treats `EveryInsertion` / `N=1` as the default batch repair
cadence. Because of that, the next performance work should not optimize around
the `N=2` slowdown directly unless it exposes the same hotspot that affects the
default path.

The local flip-repair path has already been improved enough that it is no
longer the dominant 10K cost. The post-insertion topology validation path has
also been scoped to the cells touched by each ordinary insertion. The hot
insertion path now avoids full-TDS orientation normalization when the local
mutation scope is known. Repair-side ridge-link validation also follows the
flip-created mutation frontier, even when a repair attempt used full-TDS queue
seeding; final full validation and defensive full fallbacks remain enabled. The
remaining dominant costs are local repair, hull extension, and ordinary
insertion overhead.

## Latest Measurements

### 3K 3D, `N=1`

#### Before Scoped Post-Insertion Topology Validation

- Metadata: commit `34b4bfb9`; hardware `Apple M4 Max`; build profile
`cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 3000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=3000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 54.571s.
- Insertion wall time: 52.908s.
- Local repairs: 485 calls, 5.499s total, 74.848ms max.
- Final repair: 1.082s, 0 flips.
- Final validation report: 580.243ms, OK.

#### After Scoped Post-Insertion Topology Validation

- Metadata: commit `55be4ddb`; hardware `Apple M4 Max`; build profile
`cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 3000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=3000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 27.991s.
- Insertion wall time: 26.356s.
- Local repairs: 485 calls, 5.561s total, 74.713ms max.
- Final repair: 1.068s, 0 flips.
- Final validation report: 565.459ms, OK.

#### After Local Insertion Orientation Validation

- Metadata: base commit `55be4ddb` with branch-local orientation patch;
hardware `Apple M4 Max`; build profile `cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 3000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=3000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 14.599s.
- Insertion wall time: 12.950s.
- Cavity insertions: 2511 calls, 143.671ms total, 0.238ms max.
- Local repairs: 485 calls, 5.653s total, 76.645ms max.
- Final repair: 1.072s, 0 flips.
- Final validation report: 576.049ms, OK.

#### After Scoped Repair Ridge-Link Validation

- Metadata: base commit `55be4ddb` with branch-local scoped-repair patch;
hardware `Apple M4 Max`; build profile `cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 3000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=3000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 14.493s.
- Insertion wall time: 12.876s.
- Final repair: 1.056s, 0 flips.
- Final validation report: 560.835ms, OK.

### 10K 3D, `N=1`

#### Before Scoped Post-Insertion Topology Validation

- Metadata: commit `34b4bfb9`; hardware `Apple M4 Max`; build profile
`cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 10000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=10000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 630.582s.
- Insertion loop: 622.605s.
- Local repairs: 1037 calls, 35.162s total, 384.335ms max.
- Final repair: 3.784s, 0 flips.
- Final validation report: 2.004s, OK.
- Sampling showed the current hotspot in `validate_after_insertion`, especially
`validate_ridge_links`, ridge-link graph construction, and temporary
facet/ridge key work.

#### After Scoped Post-Insertion Topology Validation

- Metadata: commit `55be4ddb`; hardware `Apple M4 Max`; build profile
`cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 10000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=10000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 261.368s.
- Insertion loop: 253.540s.
- Transactional insertion wall: 190.238s.
- Cavity insertions: 8959 calls, 145.820s total, 36.662ms max.
- Hull extensions: 1037 calls, 14.403s total, 43.503ms max.
- Local repairs: 1037 calls, 46.638s total, 383.214ms max.
- Final repair: 3.689s, 0 flips.
- Final validation report: 2.008s, OK.

#### After Local Insertion Orientation Validation

- Metadata: base commit `55be4ddb` with branch-local orientation patch;
hardware `Apple M4 Max`; build profile `cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 10000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=10000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 99.466s.
- Insertion loop: 91.593s.
- Transactional insertion wall: 29.593s.
- Cavity insertions: 8959 calls, 743.262ms total, 0.496ms max.
- Hull extensions: 1037 calls, 14.276s total, 40.226ms max.
- Local repairs: 1037 calls, 45.478s total, 370.416ms max.
- Final repair: 3.713s, 0 flips.
- Final validation report: 2.015s, OK.

#### After Scoped Repair Ridge-Link Validation

- Metadata: base commit `55be4ddb` with branch-local scoped-repair patch;
hardware `Apple M4 Max`; build profile `cargo test --release`; command
`PATH=/opt/homebrew/bin:$PATH just debug-large-scale-3d 10000 1`; env
`DELAUNAY_BULK_PROGRESS_EVERY=100`,
`DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800`,
`DELAUNAY_LARGE_DEBUG_N_3D=10000`,
`DELAUNAY_LARGE_DEBUG_REPAIR_EVERY=1`, `OMP_NUM_THREADS` unset.
- Result: valid Delaunay triangulation, no skipped vertices.
- Total wall time: 99.827s.
- Insertion wall time: 94.102s.
- Final repair: 3.708s, 0 flips.
- Final validation report: 2.016s, OK.
- This did not materially change the 10K wall time, which suggests full-reseed
repair ridge-link validation is not a dominant cost for this path.

### Rejected Experiments

- Facet-first repair queue scheduling reduced diagnostics-mode local repair
time, but the clean 10K run regressed to 100.514s total wall time. The change
was backed out; keep the alternating facet/ridge schedule unless a broader
benchmark shows a consistent win.

## Plan

1. Preserve the correctness model: every mutation must remain locally
topology-safe, and final seeded repair, final global fallback, orientation
canonicalization, and final validation must remain enabled.
2. Keep the scoped post-insertion topology validation path and compare it
against full validation in focused tests whenever its scope changes.
3. Keep full validation available for final validation, explicit public
validation, and any path where the mutation scope cannot be represented
precisely.
4. Profile and optimize local repair without changing correctness: prioritize
repeated facet/ridge checks, queue deduplication, and frontier narrowing.
5. Re-run the 3K and 10K large-scale debug cases with `N=1`, then compare
local repair time, hull-extension time, final repair, and final validation.
6. Reconsider #364 only if profiling shows snapshot/rollback or postcondition
replay dominates after topology validation is scoped.

## Immediate Next Step

Profile the local repair facet/ridge queues at 10K scale with diagnostics
enabled, then reduce repeated checks without weakening the final repair or final
validation safety nets. If repair queue work is no longer dominant, inspect hull
extension timing next.
Loading
Loading