Skip to content

Commit 32c776a

Browse files
committed
adding tests for dissimrs and build wf
1 parent 2467dfc commit 32c776a

5 files changed

Lines changed: 124 additions & 174 deletions

File tree

.github/workflows/CI.yml

Lines changed: 19 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1,181 +1,28 @@
1-
# This file is autogenerated by maturin v1.9.5
2-
# To update, run
3-
#
4-
# maturin generate-ci github
5-
#
6-
name: CI
1+
name: Build-test
72

83
on:
94
push:
10-
branches:
11-
- main
12-
- master
13-
tags:
14-
- '*'
5+
branches: [main, master]
156
pull_request:
16-
workflow_dispatch:
17-
18-
permissions:
19-
contents: read
7+
branches: [main, master]
208

219
jobs:
22-
linux:
23-
runs-on: ${{ matrix.platform.runner }}
24-
strategy:
25-
matrix:
26-
platform:
27-
- runner: ubuntu-22.04
28-
target: x86_64
29-
- runner: ubuntu-22.04
30-
target: x86
31-
- runner: ubuntu-22.04
32-
target: aarch64
33-
- runner: ubuntu-22.04
34-
target: armv7
35-
- runner: ubuntu-22.04
36-
target: s390x
37-
- runner: ubuntu-22.04
38-
target: ppc64le
39-
steps:
40-
- uses: actions/checkout@v4
41-
- uses: actions/setup-python@v5
42-
with:
43-
python-version: 3.x
44-
- name: Build wheels
45-
uses: PyO3/maturin-action@v1
46-
with:
47-
target: ${{ matrix.platform.target }}
48-
args: --release --out dist --find-interpreter
49-
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
50-
manylinux: auto
51-
- name: Upload wheels
52-
uses: actions/upload-artifact@v4
53-
with:
54-
name: wheels-linux-${{ matrix.platform.target }}
55-
path: dist
56-
57-
musllinux:
58-
runs-on: ${{ matrix.platform.runner }}
59-
strategy:
60-
matrix:
61-
platform:
62-
- runner: ubuntu-22.04
63-
target: x86_64
64-
- runner: ubuntu-22.04
65-
target: x86
66-
- runner: ubuntu-22.04
67-
target: aarch64
68-
- runner: ubuntu-22.04
69-
target: armv7
70-
steps:
71-
- uses: actions/checkout@v4
72-
- uses: actions/setup-python@v5
73-
with:
74-
python-version: 3.x
75-
- name: Build wheels
76-
uses: PyO3/maturin-action@v1
77-
with:
78-
target: ${{ matrix.platform.target }}
79-
args: --release --out dist --find-interpreter
80-
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
81-
manylinux: musllinux_1_2
82-
- name: Upload wheels
83-
uses: actions/upload-artifact@v4
84-
with:
85-
name: wheels-musllinux-${{ matrix.platform.target }}
86-
path: dist
87-
88-
windows:
89-
runs-on: ${{ matrix.platform.runner }}
90-
strategy:
91-
matrix:
92-
platform:
93-
- runner: windows-latest
94-
target: x64
95-
- runner: windows-latest
96-
target: x86
97-
steps:
98-
- uses: actions/checkout@v4
99-
- uses: actions/setup-python@v5
100-
with:
101-
python-version: 3.x
102-
architecture: ${{ matrix.platform.target }}
103-
- name: Build wheels
104-
uses: PyO3/maturin-action@v1
105-
with:
106-
target: ${{ matrix.platform.target }}
107-
args: --release --out dist --find-interpreter
108-
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
109-
- name: Upload wheels
110-
uses: actions/upload-artifact@v4
111-
with:
112-
name: wheels-windows-${{ matrix.platform.target }}
113-
path: dist
114-
115-
macos:
116-
runs-on: ${{ matrix.platform.runner }}
117-
strategy:
118-
matrix:
119-
platform:
120-
- runner: macos-13
121-
target: x86_64
122-
- runner: macos-14
123-
target: aarch64
124-
steps:
125-
- uses: actions/checkout@v4
126-
- uses: actions/setup-python@v5
127-
with:
128-
python-version: 3.x
129-
- name: Build wheels
130-
uses: PyO3/maturin-action@v1
131-
with:
132-
target: ${{ matrix.platform.target }}
133-
args: --release --out dist --find-interpreter
134-
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
135-
- name: Upload wheels
136-
uses: actions/upload-artifact@v4
137-
with:
138-
name: wheels-macos-${{ matrix.platform.target }}
139-
path: dist
140-
141-
sdist:
10+
test:
11+
name: Run Rust tests
14212
runs-on: ubuntu-latest
14313
steps:
14414
- uses: actions/checkout@v4
145-
- name: Build sdist
146-
uses: PyO3/maturin-action@v1
147-
with:
148-
command: sdist
149-
args: --out dist
150-
- name: Upload sdist
151-
uses: actions/upload-artifact@v4
152-
with:
153-
name: wheels-sdist
154-
path: dist
155-
156-
release:
157-
name: Release
158-
runs-on: ubuntu-latest
159-
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
160-
needs: [linux, musllinux, windows, macos, sdist]
161-
permissions:
162-
# Use to sign the release artifacts
163-
id-token: write
164-
# Used to upload release artifacts
165-
contents: write
166-
# Used to generate artifact attestation
167-
attestations: write
168-
steps:
169-
- uses: actions/download-artifact@v4
170-
- name: Generate artifact attestation
171-
uses: actions/attest-build-provenance@v2
172-
with:
173-
subject-path: 'wheels-*/*'
174-
- name: Publish to PyPI
175-
if: ${{ startsWith(github.ref, 'refs/tags/') }}
176-
uses: PyO3/maturin-action@v1
177-
env:
178-
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
179-
with:
180-
command: upload
181-
args: --non-interactive --skip-existing wheels-*/*
15+
16+
- name: Set up Rust
17+
uses: actions-rust-lang/setup-rust-toolchain@v1
18+
19+
- name: Run tests
20+
run: cargo test core --no-default-features
21+
22+
- name: Check code formatting
23+
run: cargo fmt -- --check
24+
continue-on-error: true
25+
26+
- name: Run clippy
27+
run: cargo clippy -- -D warnings
28+
continue-on-error: true

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,21 @@ pyo3 = {version = "0.22", default-features = false, features = ["macros", "gil-r
1313
pyo3-built = "0.5"
1414
numpy = {version = "0.22", features = ["gil-refs"]}
1515
ndarray = "0.16"
16-
rayon = "1.10" # or the latest version
16+
rayon = "1.11"
1717
num_cpus = "1.16"
1818
simsimd = "6.5.9"
1919
rand = "0.8"
2020
anyhow = "1.0.100"
2121

22+
[dev-dependencies]
23+
approx = "0.5"
24+
2225
[profile.release]
2326
strip = true
2427
lto = true
2528
codegen-units = 1
26-
opt-level = 3
29+
opt-level = 3
30+
31+
[features]
32+
extension-module = ["pyo3/extension-module"]
33+
default = ["extension-module"]

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,16 @@ Finally, compile and install the library into your active Python environment:
2727
```bash
2828
maturin develop --release
2929
```
30+
31+
## Unit testing
32+
33+
Testing core module (without Python binding):
34+
35+
```bash
36+
cargo test core
37+
```
38+
Testing main Rust fucntion (same as above, now):
39+
40+
```bash
41+
cargo test dissimrs
42+
```

src/core.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,76 @@ pub fn dissimrs(
8484
Ok(out)
8585
}
8686

87+
88+
89+
#[cfg(test)]
90+
mod tests {
91+
use super::*;
92+
use ndarray::Array2;
93+
use approx::assert_relative_eq;
94+
95+
fn create_test_affine() -> Affine {
96+
let aff = (1.0, 0.0, 0.0, 0.0, 1.0, 0.0);
97+
aff.into()
98+
}
99+
100+
#[test]
101+
fn test_dissimrs_basic() {
102+
let x = Array2::from_shape_vec((3, 2), vec![
103+
1.0, 2.0,
104+
1.5, 2.5,
105+
10.0, 20.0
106+
]).unwrap();
107+
108+
let trans = create_test_affine();
109+
let result = dissimrs(&x, &trans, false, 1.0, None, 0, 2, 42).unwrap();
110+
111+
assert_eq!(result.len(), 3);
112+
assert!(result.iter().all(|&v| v.is_finite()));
113+
assert!(result[2] > result[0]);
114+
assert!(result[2] > result[1]);
115+
}
116+
117+
#[test]
118+
fn test_dissimrs_with_nan() {
119+
let x = Array2::from_shape_vec((4, 2), vec![
120+
1.0, 2.0,
121+
f32::NAN, 2.0,
122+
3.0, 4.0,
123+
5.0, f32::NAN,
124+
]).unwrap();
125+
126+
let trans = create_test_affine();
127+
let result = dissimrs(&x, &trans, false, 1.0, None, 0, 2, 42).unwrap();
128+
129+
assert!(result[0].is_finite());
130+
assert!(result[1].is_nan());
131+
assert!(result[2].is_finite());
132+
assert!(result[3].is_nan());
133+
}
134+
135+
#[test]
136+
fn test_dissimrs_identical_cells() {
137+
let x = Array2::from_shape_vec((3, 2), vec![
138+
1.0, 2.0,
139+
1.0, 2.0,
140+
1.0, 2.0,
141+
]).unwrap();
142+
143+
let trans = create_test_affine();
144+
let result = dissimrs(&x, &trans, false, 1.0, None, 0, 2, 42).unwrap();
145+
146+
for &val in &result {
147+
assert_relative_eq!(val, 0.0, epsilon = 1e-10);
148+
}
149+
}
150+
151+
#[test]
152+
fn test_dissimrs_invalid_bandwidth() {
153+
let x = Array2::from_shape_vec((3, 2), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).unwrap();
154+
let trans = create_test_affine();
155+
156+
assert!(dissimrs(&x, &trans, false, 0.0, None, 0, 2, 42).is_err());
157+
assert!(dissimrs(&x, &trans, false, -1.0, None, 0, 2, 42).is_err());
158+
}
159+
}

0 commit comments

Comments
 (0)