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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/Packages
xcuserdata/
DerivedData/
.derived-data-log-*
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
11 changes: 11 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ let package = Package(
name: "MaxVol",
targets: ["MaxVol"]
),
.executable(
name: "MaxVolBenchmark",
targets: ["MaxVolBenchmark"]
),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
Expand All @@ -25,6 +29,13 @@ let package = Package(
.define("ACCELERATE_LAPACK_ILP64"),
]
),
.executableTarget(
name: "MaxVolBenchmark",
dependencies: ["MaxVol"],
resources: [
.copy("Resources/fixtures.json"),
]
),
.testTarget(
name: "MaxVolTests",
dependencies: ["MaxVol"]
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,39 @@ deprecated compatibility shims.
points.
- Consider complex support only after real-valued APIs are stable.

## Benchmarking

`MaxVolBenchmark` runs deterministic fixtures through the Swift implementation
and prints one JSON object per result:

```bash
swift run -c release MaxVolBenchmark --iterations 20
```

The Python comparison harness reads the same checked-in fixture values and runs
the official `maxvolpy` implementation from the PyPI source distribution:

```bash
uv run --python 3.11 scripts/compare_maxvolpy.py --iterations 20
```

To compare correctness-oriented fields, write both outputs as JSONL and run the
parity checker:

```bash
swift run -c release MaxVolBenchmark --iterations 20 > /tmp/maxvol-swift.jsonl
uv run --python 3.11 scripts/compare_maxvolpy.py --iterations 20 > /tmp/maxvol-python.jsonl
python3 scripts/check_benchmark_parity.py /tmp/maxvol-swift.jsonl /tmp/maxvol-python.jsonl
```

For allocation profiling, build the executable once and record the workload with
Instruments from the command line:

```bash
swift build -c release --product MaxVolBenchmark
xcrun xctrace record --template 'Allocations' --output /tmp/MaxVolBenchmark.trace --launch -- .build/release/MaxVolBenchmark --iterations 100
```

## Non-Goals For The First Pass

- Exact exhaustive maximum-volume search.
Expand Down
22 changes: 21 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Current Focus

- Build from `v0.7.0` toward `v1.0.0` with real-valued `Double` and `Float`
- Build from `v0.8.0` toward `v1.0.0` with real-valued `Double` and `Float`
algorithms backed by modern Accelerate BLAS/LAPACK.
- Keep Swift Testing as the package test surface and require reference fixtures
before broadening the algorithm surface.
Expand Down Expand Up @@ -39,6 +39,8 @@
- Reduce temporary allocations in square row swaps and rectangular appends.
- Reuse workspace buffers where it improves measured throughput.
- Add benchmark coverage for representative row counts and ranks.
- Compare Swift Release-mode results with official `maxvolpy` runs on shared
deterministic fixtures before changing allocation behavior.

## Test Coverage

Expand All @@ -51,6 +53,8 @@
implementations when algorithm behavior changes.
- Keep randomized orthonormal-matrix tests similar to `Maxvol.jl` across
supported scalar types.
- Keep benchmark fixture parity checks available for every supported scalar and
algorithm family.
- Keep Release-mode validation in the release path for optimization-sensitive
Accelerate calls.
- Keep validation clean under the modern Accelerate `ACCELERATE_NEW_LAPACK` and
Expand All @@ -66,6 +70,8 @@
- Keep public API docs aligned with tested behavior.
- Expand DocC with algorithm notes, limitations, and reference-fixture
provenance before `1.0.0`.
- Keep benchmark and profiling commands documented so performance work remains
reproducible.

## Swift Package Index

Expand Down Expand Up @@ -95,3 +101,17 @@
- Expand DocC with reference-fixture provenance and a short comparison with
Python, Julia, and R implementations.
- Verify Swift Package Index renders the tagged `v1.0.0` documentation cleanly.

## Planned `v0.9.0`

- Use `MaxVolBenchmark` and the `maxvolpy` comparison harness as the baseline
evidence source before changing performance-sensitive code.
- Measure Release-mode square row-swap throughput and RectMaxVol append
throughput across the checked-in deterministic fixture set.
- Capture allocation traces for the largest fixtures and identify temporary
buffers created inside coefficient construction, square row replacement, and
rectangular appends.
- Decide whether reusable workspaces should remain an internal optimization or
become a public advanced API.
- Implement only measured allocation reductions, then re-run parity, timing, and
allocation checks before tagging `v0.9.0`.
66 changes: 66 additions & 0 deletions Sources/MaxVol/MaxVol.docc/BenchmarkingAndParity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Benchmarking and Parity

Use the package benchmark executable and Python harness to compare MaxVol's
Accelerate-backed implementation with `maxvolpy` on identical deterministic
fixtures.

## Swift Benchmark

Build and run the benchmark executable in Release mode when measuring runtime:

```bash
swift run -c release MaxVolBenchmark --iterations 20
```

The executable reads bundled fixture values from `MaxVolBenchmark` resources and
prints JSON Lines. Each record includes the fixture, algorithm, scalar type,
selected row count, convergence status, algorithm iteration count, reconstruction
residual, coefficient magnitude, and elapsed nanoseconds.

Filter the workload when recording a focused trace:

```bash
swift run -c release MaxVolBenchmark --fixture gaussian-192x16 --algorithm square --scalar double --iterations 100
```

## Python Comparison

The Python harness downloads the official `maxvolpy` source distribution from
PyPI, imports its implementation, and runs it against the same checked-in fixture
values:

```bash
uv run --python 3.11 scripts/compare_maxvolpy.py --iterations 20
```

Use the `pure` implementation mode for the Python reference path. The `api` mode
uses `maxvolpy.maxvol` and `maxvolpy.rect_maxvol`, which may use the compiled
extension if the package is installed with one available.

## Parity Check

Compare correctness-oriented fields by writing Swift and Python output to JSONL
files:

```bash
swift run -c release MaxVolBenchmark --iterations 20 > /tmp/maxvol-swift.jsonl
uv run --python 3.11 scripts/compare_maxvolpy.py --iterations 20 > /tmp/maxvol-python.jsonl
python3 scripts/check_benchmark_parity.py /tmp/maxvol-swift.jsonl /tmp/maxvol-python.jsonl
```

The checker verifies that both runs produced the same fixture, algorithm, and
scalar keys, then compares selected row counts, reconstruction residuals, and
rectangular unselected-row norms.

## Allocation Profiling

Build before profiling so the trace captures benchmark work instead of package
resolution or compilation:

```bash
swift build -c release --product MaxVolBenchmark
xcrun xctrace record --template 'Allocations' --output /tmp/MaxVolBenchmark.trace --launch -- .build/release/MaxVolBenchmark --fixture gaussian-192x16 --iterations 100
```

Keep trace artifacts out of the repository unless a future performance report
explicitly needs to preserve one as release evidence.
1 change: 1 addition & 0 deletions Sources/MaxVol/MaxVol.docc/MaxVol.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@ let rectangular = try rectMaxVol(matrix, options: RectMaxVolOptions(minRows: 3))
### Algorithm Notes

- <doc:ToleranceAndConvergence>
- <doc:BenchmarkingAndParity>
Loading
Loading