Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7a3c5ac
feat(fft): implement 1D FFT/IFFT and frequency helpers
sonusharma6-dsa May 29, 2026
9d2b2e9
fix(fft): handle zero-length FFT/IFFT and correct rfftfreq
sonusharma6-dsa May 29, 2026
89c95c3
fix(fft): correct fftfreq Nyquist sign for even n
sonusharma6-dsa May 29, 2026
4219497
chore(dtype): address clippy lints (doc spacing, FromStr impl, unnece…
sonusharma6-dsa May 29, 2026
2544e58
ci: ignore cargo-machete unused-deps for mohu-fft (partial impl)
sonusharma6-dsa May 29, 2026
d1f9012
style: apply rustfmt-like formatting fixes for reporter, test_utils, …
sonusharma6-dsa May 29, 2026
9d5a58f
style: apply rustfmt fixes reported by CI
sonusharma6-dsa May 29, 2026
73c4483
style: apply rustfmt fixes reported by CI
sonusharma6-dsa May 29, 2026
a9acc32
feat(io): add CSV I/O (Fixes #228)
sonusharma6-dsa May 29, 2026
f14e789
Potential fix for pull request finding
sonusharma6-dsa May 29, 2026
dd94e4a
Potential fix for pull request finding
sonusharma6-dsa May 29, 2026
c7c1edc
Potential fix for pull request finding
sonusharma6-dsa May 29, 2026
d7c2914
fix csv writer reuse for standard line terminators
Copilot May 29, 2026
ed6ce00
document custom terminator fallback in csv writer
Copilot May 29, 2026
04006f2
fix(ci): pin dco-check action
sonusharma6-dsa May 29, 2026
ebdb5d4
fix(ci): pin dco-check action
sonusharma6-dsa May 29, 2026
0048bbd
fix(ci): pin dco-check action
sonusharma6-dsa May 29, 2026
4f24443
feat(io): add csv read/write support
sonusharma6-dsa May 29, 2026
d4f975f
chore(windows): add llvm-mingw helper
sonusharma6-dsa May 29, 2026
a9171cf
fix(testing): add assert_allclose macro
sonusharma6-dsa May 29, 2026
bcb2617
style: rustfmt workspace
sonusharma6-dsa May 29, 2026
e51f953
chore: apply automatic clippy fixes
sonusharma6-dsa May 29, 2026
07b2a42
chore: remove accidental embedded repo entry
sonusharma6-dsa May 29, 2026
951ae66
feat(bench): add mohu-benchmarks scaffold using Criterion.rs
sonusharma6-dsa May 30, 2026
dc84f4a
ci(bench): add benchmark workflow and integration test scaffold
sonusharma6-dsa May 30, 2026
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
49 changes: 49 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Benchmark

on:
workflow_dispatch:
schedule:
# Run every Monday at 3:00 UTC
- cron: '0 3 * * 1'

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

jobs:
benchmark:
name: Run Benchmarks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Run benchmarks
run: |
cd crates/mohu-benchmarks
cargo bench -- --output-format bencher | tee output.txt
- name: Upload benchmark results
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: crates/mohu-benchmarks/output.txt
retention-days: 30
- name: Upload Criterion reports
uses: actions/upload-artifact@v4
with:
name: criterion-reports
path: crates/mohu-benchmarks/target/criterion/
Comment thread
sonusharma6-dsa marked this conversation as resolved.
retention-days: 30
# Optional: Enable github-action-benchmark for trend charts
# To enable:
# 1. Uncomment the step below
# 2. Create a GitHub secret named BENCHMARK_TOKEN (or use GITHUB_TOKEN)
# 3. Set up the benchmark-data repository or use the default
# See: https://github.com/benchmark-action/github-action-benchmark
# - name: Store benchmark result
# uses: benchmark-action/github-action-benchmark@v1
# with:
# tool: 'cargo'
# output-file-path: crates/mohu-benchmarks/output.txt
# github-token: ${{ secrets.GITHUB_TOKEN }}
# auto-push: true
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: christophebedard/dco-check@v0.5.0
- uses: christophebedard/dco-check@0.5.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pin the GitHub Action to a full commit SHA, not a tag.

Using @0.5.1 is still mutable and can be retagged. Pin this action to an immutable commit SHA to prevent supply-chain drift in CI.

Suggested change
-      - uses: christophebedard/dco-check@0.5.1
+      - uses: christophebedard/dco-check@<full_commit_sha>
🧰 Tools
🪛 zizmor (1.25.2)

[error] 26-26: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 26, Replace the mutable action reference
"christophebedard/dco-check@0.5.1" with an immutable commit SHA: locate the
desired commit in the christophebedard/dco-check repository (e.g., the commit
corresponding to the 0.5.1 release) and update the workflow step to use
"christophebedard/dco-check@<full-commit-sha>" so the CI uses a pinned,
immutable action reference.

with:
token: ${{ secrets.GITHUB_TOKEN }}

Expand Down
29 changes: 29 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ members = [

# ── Developer tooling ─────────────────────────────────────────────────────
"crates/mohu-testing", # test fixtures, property tests, array comparison
"crates/mohu-benchmarks",
]
resolver = "2"

Expand Down Expand Up @@ -104,6 +105,7 @@ serde = { version = "1", features = ["derive"] }

# ── I/O ───────────────────────────────────────────────────────────────────────
memmap2 = "0.9"
csv = "1.4"

# ── Python bindings ───────────────────────────────────────────────────────────
pyo3 = { version = "0.23", features = ["extension-module"] }
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ Polars proved you can rewrite the data layer in Rust and win. mohu is that same

Early. The foundation is being laid. If you believe the Python numerical stack deserves a rewrite, watch this repo or contribute.

## windows

On Windows, use `scripts/use-llvm-mingw.ps1` to run the `mohu-io` test target
with the LLVM-MinGW linker setup that works in this workspace.

```powershell
.\scripts\use-llvm-mingw.ps1
```

## built with

- [Rust](https://rust-lang.org)
Expand Down
1 change: 1 addition & 0 deletions crates/mohu-array/src/array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions crates/mohu-array/src/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions crates/mohu-array/src/shape.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions crates/mohu-array/src/slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions crates/mohu-array/src/view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions crates/mohu-benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "mohu-benchmarks"
version = "0.1.0"
edition = "2024"

[dependencies]
criterion = { version = "0.4", features = ["html_reports"] }
# Use the workspace mohu-array crate when available; maintainers can enable this
# once the public API for benchmarks is agreed.
mohu-array = { workspace = true }
Comment on lines +6 to +10

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether criterion is centralized in root workspace deps
rg -n --glob 'Cargo.toml' '^\[workspace\.dependencies\]|^criterion\s*=' -C2

Repository: mohu-org/mohu

Length of output: 747


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Show root workspace dependency block lines around where criterion would be declared
root_cargo="Cargo.toml"
echo "== Root Cargo.toml: workspace.dependencies (lines 40-120) =="
nl -ba "$root_cargo" | sed -n '40,120p'

echo "== Search root Cargo.toml for criterion declaration =="
rg -n '^\s*criterion\s*=' "$root_cargo" || true

echo "== Search entire repo for criterion entries in [workspace.dependencies] =="
rg -n --glob 'Cargo.toml' --context 2 '^\[workspace\.dependencies\]|\bcriterion\s*=\s*' "$root_cargo" crates || true

Repository: mohu-org/mohu

Length of output: 179


🏁 Script executed:

#!/bin/bash
set -euo pipefail
root_cargo="Cargo.toml"

echo "== Find [workspace.dependencies] range in root Cargo.toml =="
grep -n '^\[workspace\.dependencies\]' -n "$root_cargo" || true

echo "== Search root Cargo.toml for criterion declarations =="
rg -n '^\s*criterion\s*=' "$root_cargo" || true

echo "== Print workspace.dependencies block (approx. lines 35-110) =="
sed -n '35,110p' "$root_cargo"

Repository: mohu-org/mohu

Length of output: 3748


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n --glob 'Cargo.toml' 'criterion\s*=\s*\{' .
rg -n --glob 'Cargo.toml' '^\s*criterion\s*=' .
rg -n --glob 'Cargo.toml' '\[workspace\.dependencies\]' Cargo.toml

Repository: mohu-org/mohu

Length of output: 283


Use workspace-managed dependency for criterion (move it to root [workspace.dependencies])

crates/mohu-benchmarks/Cargo.toml pins criterion locally:

[dependencies]
criterion = { version = "0.4", features = ["html_reports"] }

This conflicts with the workspace rule (“all external dependency versions must live in root [workspace.dependencies] and crates must use { workspace = true }). Add criterion to the root [workspace.dependencies], then change the crate entry to use criterion = { workspace = true, features = ["html_reports"] } (or omit features if identical to root).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/mohu-benchmarks/Cargo.toml` around lines 6 - 10, The crate currently
pins criterion locally in crates/mohu-benchmarks/Cargo.toml; move the criterion
version entry into the root Cargo.toml under [workspace.dependencies] and then
update the crate entry (criterion in crates/mohu-benchmarks) to use the
workspace-managed dependency by using criterion = { workspace = true, features =
["html_reports"] } (or omit features if they match the root), ensuring the
workspace follows the rule that all external dependency versions live at the
root and crates reference them with workspace = true.


[package.metadata]
description = "Benchmark suite scaffolding for the Mohu project using Criterion.rs"
repository = "https://github.com/mohu-org/mohu"
62 changes: 62 additions & 0 deletions crates/mohu-benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Mohu Benchmarks

This crate provides a Criterion.rs-based benchmark scaffold for the Mohu project. It intentionally starts small with well-documented microbenchmarks for:

- Element-wise arithmetic (vector add)
- Reduction (sum)
- Memory stride access comparison (row-major vs column-major scanning)

## Architecture Note

**Important**: The ROADMAP.md suggests `mohu-benchmarks` should be a standalone repository to allow anyone to run benchmarks without building the full library. However, this PR implements it as a workspace member crate for tighter integration with the CI pipeline and easier maintenance. If maintainers prefer the standalone repo approach, this can be migrated in a follow-up PR.

## Current Status

**Note**: `mohu-array` is currently in stub status (module files are empty as documented in CRATE_MAP.md). The current benchmarks use plain `Vec<T>` operations as placeholders. Once `mohu-array` is implemented, these benchmarks should be extended to use the actual array API.

### What's Implemented

- Basic microbenchmarks using `Vec<T>` operations
- Integration test placeholder in `tests/` directory
- CI workflow for scheduled benchmark runs (`.github/workflows/benchmark.yml`)
- Proper use of `criterion::black_box()` to prevent compiler optimization

### Next Steps

Once `mohu-array` is implemented, maintainers and contributors should extend this suite with:

1. **Integration Tests**: Replace the placeholder in `tests/integration_test.rs` with actual `mohu-array` construction and operation tests
2. **Array Benchmarks**: Extend benchmarks to use `mohu-array` compute paths (ufunc/reduction APIs directly in bench closures)
3. **I/O Benchmarks**: Add benchmarks for `.npy`/`.csv` using `mohu-io`
4. **Cross-comparisons**: Add NumPy comparisons (scripted externally via Python)
5. **Advanced Experiments**: SIMD vs scalar kernels and threaded vs sequential experiments
6. **Baseline Reports**: Generate and commit baseline `target/criterion/` HTML reports or JSON summaries for regression detection (requires properly configured build environment with MSVC toolchain on Windows)

## Running Benchmarks

Run locally:

```sh
cd crates/mohu-benchmarks
cargo bench --bench bench_core
```

Run with bencher output format (for CI):

```sh
cd crates/mohu-benchmarks
cargo bench -- --output-format bencher | tee output.txt
```

## CI Integration

A scheduled benchmark workflow is configured in `.github/workflows/benchmark.yml`:
- Runs every Monday at 3:00 UTC via cron schedule
- Can also be triggered manually via `workflow_dispatch`
- Uploads benchmark results and Criterion reports as artifacts (30-day retention)
- Uses `bencher` output format for potential integration with `github-action-benchmark` for trend charts

For full regression detection, consider:
- Storing Criterion reports in S3-compatible storage
- Using `github-action-benchmark` for trend visualization
- Comparing specific baseline outputs across runs
70 changes: 70 additions & 0 deletions crates/mohu-benchmarks/benches/bench_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};

// Lightweight core benchmarks scaffold. These are intentionally simple and
// provide maintainers a starting point to add mohu-array-specific benchmarks.

fn bench_arithmetic_add(c: &mut Criterion) {
let size = 1_000_000usize;
let a: Vec<f64> = (0..size).map(|i| (i as f64) * 0.5).collect();
let b: Vec<f64> = (0..size).map(|i| (i as f64) * 1.5).collect();

c.bench_function("vec_add_iter", |bencher| {
bencher.iter(|| {
let mut r = vec![0.0f64; size];
for i in 0..size {
r[i] = black_box(a[i]) + black_box(b[i]);
}
black_box(r)
})
});
}

fn bench_reduction_sum(c: &mut Criterion) {
let size = 2_000_000usize;
let a: Vec<f64> = (0..size).map(|i| (i as f64) * 0.25).collect();

c.bench_function("vec_sum_iter", |bencher| {
bencher.iter(|| {
let mut s = 0.0f64;
for &v in &a {
s += black_box(v);
}
black_box(s)
})
});
}

fn bench_stride_access(c: &mut Criterion) {
let rows = 10_000usize;
let cols = 1_000usize;
// simulate flat storage
let mut data: Vec<f64> = vec![0.0; rows * cols];
for i in 0..(rows * cols) { data[i] = (i as f64) % 100.0; }

c.bench_function("row_major_sum", |bencher| {
bencher.iter(|| {
let mut s = 0.0f64;
for r in 0..rows {
for cidx in 0..cols {
s += black_box(data[r * cols + cidx]);
}
}
black_box(s)
})
});

c.bench_function("col_major_sum", |bencher| {
bencher.iter(|| {
let mut s = 0.0f64;
for cidx in 0..cols {
for r in 0..rows {
s += black_box(data[r * cols + cidx]);
}
}
black_box(s)
})
});
}

criterion_group!(benches, bench_arithmetic_add, bench_reduction_sum, bench_stride_access);
criterion_main!(benches);
28 changes: 28 additions & 0 deletions crates/mohu-benchmarks/tests/integration_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Integration test for mohu-array usage
//
// This test is a placeholder that will be expanded once mohu-array is implemented.
// Currently, mohu-array modules are stubs (empty files) as documented in CRATE_MAP.md.
//
// When mohu-array is implemented, this test should:
// - Construct a mohu-array object (e.g., NdArray<T>)
// - Perform a simple operation (e.g., element-wise add, reduction sum)
// - Assert a known result to verify the wiring works
//
// Example (to be implemented):
// ```rust
// use mohu_array::array::NdArray;
//
// #[test]
// fn test_array_construction_and_sum() {
// let arr = NdArray::from_vec(vec![1.0, 2.0, 3.0, 4.0]);
// let sum = arr.sum();
// assert!((sum - 10.0).abs() < 1e-9);
// }
// ```

#[test]
fn test_placeholder() {
// Placeholder test to ensure the tests directory is recognized
// This will be replaced with actual mohu-array integration tests
assert!(true);
}
Loading
Loading