rimpy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rimpy-0.1.0/.github/workflows/release.yml +79 -0
- rimpy-0.1.0/.gitignore +22 -0
- rimpy-0.1.0/Cargo.lock +304 -0
- rimpy-0.1.0/Cargo.toml +27 -0
- rimpy-0.1.0/PKG-INFO +160 -0
- rimpy-0.1.0/README.md +125 -0
- rimpy-0.1.0/benchmarks/bench_engine.py +150 -0
- rimpy-0.1.0/pyproject.toml +65 -0
- rimpy-0.1.0/python/rimpy/__init__.py +65 -0
- rimpy-0.1.0/python/rimpy/_engine.py +34 -0
- rimpy-0.1.0/python/rimpy/_engine_py.py +189 -0
- rimpy-0.1.0/python/rimpy/_loaders.py +291 -0
- rimpy-0.1.0/python/rimpy/_rake.py +1092 -0
- rimpy-0.1.0/src/engine.rs +476 -0
- rimpy-0.1.0/src/lib.rs +281 -0
- rimpy-0.1.0/tests/test_backend_parity.py +135 -0
- rimpy-0.1.0/uv.lock +292 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: Build & Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
workflow_dispatch: # manual trigger for testing
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
# ---------------------------------------------------------------
|
|
13
|
+
# Build wheels for each OS × Python version
|
|
14
|
+
# ---------------------------------------------------------------
|
|
15
|
+
build:
|
|
16
|
+
name: Build / ${{ matrix.os }} / ${{ matrix.python }}
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
21
|
+
python: ["3.12", "3.13", "3.14"]
|
|
22
|
+
runs-on: ${{ matrix.os }}
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- uses: PyO3/maturin-action@v1
|
|
28
|
+
with:
|
|
29
|
+
command: build
|
|
30
|
+
args: --release -o dist -i python${{ matrix.python }}
|
|
31
|
+
|
|
32
|
+
- uses: actions/upload-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: wheel-${{ matrix.os }}-py${{ matrix.python }}
|
|
35
|
+
path: dist/*.whl
|
|
36
|
+
|
|
37
|
+
# ---------------------------------------------------------------
|
|
38
|
+
# Build source distribution (fallback for unsupported platforms)
|
|
39
|
+
# ---------------------------------------------------------------
|
|
40
|
+
sdist:
|
|
41
|
+
name: Build sdist
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
|
|
46
|
+
- uses: PyO3/maturin-action@v1
|
|
47
|
+
with:
|
|
48
|
+
command: sdist
|
|
49
|
+
args: -o dist
|
|
50
|
+
|
|
51
|
+
- uses: actions/upload-artifact@v4
|
|
52
|
+
with:
|
|
53
|
+
name: sdist
|
|
54
|
+
path: dist/*.tar.gz
|
|
55
|
+
|
|
56
|
+
# ---------------------------------------------------------------
|
|
57
|
+
# Publish everything to PyPI
|
|
58
|
+
# ---------------------------------------------------------------
|
|
59
|
+
publish:
|
|
60
|
+
name: Publish to PyPI
|
|
61
|
+
needs: [build, sdist]
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
environment: pypi
|
|
64
|
+
permissions:
|
|
65
|
+
id-token: write # trusted publishing (no API token needed)
|
|
66
|
+
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/download-artifact@v4
|
|
69
|
+
with:
|
|
70
|
+
pattern: wheel-*
|
|
71
|
+
merge-multiple: true
|
|
72
|
+
path: dist
|
|
73
|
+
|
|
74
|
+
- uses: actions/download-artifact@v4
|
|
75
|
+
with:
|
|
76
|
+
name: sdist
|
|
77
|
+
path: dist
|
|
78
|
+
|
|
79
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
rimpy-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Rust build artifacts
|
|
2
|
+
target/
|
|
3
|
+
Cargo.lock
|
|
4
|
+
|
|
5
|
+
# Compiled Python extensions (built by maturin)
|
|
6
|
+
*.pyd
|
|
7
|
+
*.so
|
|
8
|
+
*.dylib
|
|
9
|
+
|
|
10
|
+
# Python
|
|
11
|
+
__pycache__/
|
|
12
|
+
*.pyc
|
|
13
|
+
*.egg-info/
|
|
14
|
+
dist/
|
|
15
|
+
build/
|
|
16
|
+
|
|
17
|
+
# Virtual environments
|
|
18
|
+
.venv/
|
|
19
|
+
|
|
20
|
+
# IDE
|
|
21
|
+
.idea/
|
|
22
|
+
.vscode/
|
rimpy-0.1.0/Cargo.lock
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.0"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "crossbeam-deque"
|
|
13
|
+
version = "0.8.6"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
|
16
|
+
dependencies = [
|
|
17
|
+
"crossbeam-epoch",
|
|
18
|
+
"crossbeam-utils",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[[package]]
|
|
22
|
+
name = "crossbeam-epoch"
|
|
23
|
+
version = "0.9.18"
|
|
24
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
25
|
+
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
|
26
|
+
dependencies = [
|
|
27
|
+
"crossbeam-utils",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[[package]]
|
|
31
|
+
name = "crossbeam-utils"
|
|
32
|
+
version = "0.8.21"
|
|
33
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
34
|
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
35
|
+
|
|
36
|
+
[[package]]
|
|
37
|
+
name = "either"
|
|
38
|
+
version = "1.15.0"
|
|
39
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
40
|
+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|
41
|
+
|
|
42
|
+
[[package]]
|
|
43
|
+
name = "equivalent"
|
|
44
|
+
version = "1.0.2"
|
|
45
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
46
|
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
47
|
+
|
|
48
|
+
[[package]]
|
|
49
|
+
name = "hashbrown"
|
|
50
|
+
version = "0.16.1"
|
|
51
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
52
|
+
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
|
53
|
+
|
|
54
|
+
[[package]]
|
|
55
|
+
name = "heck"
|
|
56
|
+
version = "0.5.0"
|
|
57
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
58
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
59
|
+
|
|
60
|
+
[[package]]
|
|
61
|
+
name = "indexmap"
|
|
62
|
+
version = "2.13.0"
|
|
63
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
64
|
+
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
|
65
|
+
dependencies = [
|
|
66
|
+
"equivalent",
|
|
67
|
+
"hashbrown",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[[package]]
|
|
71
|
+
name = "libc"
|
|
72
|
+
version = "0.2.182"
|
|
73
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
74
|
+
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
|
75
|
+
|
|
76
|
+
[[package]]
|
|
77
|
+
name = "matrixmultiply"
|
|
78
|
+
version = "0.3.10"
|
|
79
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
80
|
+
checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
|
|
81
|
+
dependencies = [
|
|
82
|
+
"autocfg",
|
|
83
|
+
"rawpointer",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[[package]]
|
|
87
|
+
name = "ndarray"
|
|
88
|
+
version = "0.17.2"
|
|
89
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
90
|
+
checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d"
|
|
91
|
+
dependencies = [
|
|
92
|
+
"matrixmultiply",
|
|
93
|
+
"num-complex",
|
|
94
|
+
"num-integer",
|
|
95
|
+
"num-traits",
|
|
96
|
+
"portable-atomic",
|
|
97
|
+
"portable-atomic-util",
|
|
98
|
+
"rawpointer",
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
[[package]]
|
|
102
|
+
name = "num-complex"
|
|
103
|
+
version = "0.4.6"
|
|
104
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
105
|
+
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
|
106
|
+
dependencies = [
|
|
107
|
+
"num-traits",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[[package]]
|
|
111
|
+
name = "num-integer"
|
|
112
|
+
version = "0.1.46"
|
|
113
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
114
|
+
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
|
115
|
+
dependencies = [
|
|
116
|
+
"num-traits",
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
[[package]]
|
|
120
|
+
name = "num-traits"
|
|
121
|
+
version = "0.2.19"
|
|
122
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
123
|
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
124
|
+
dependencies = [
|
|
125
|
+
"autocfg",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
[[package]]
|
|
129
|
+
name = "numpy"
|
|
130
|
+
version = "0.28.0"
|
|
131
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
132
|
+
checksum = "778da78c64ddc928ebf5ad9df5edf0789410ff3bdbf3619aed51cd789a6af1e2"
|
|
133
|
+
dependencies = [
|
|
134
|
+
"libc",
|
|
135
|
+
"ndarray",
|
|
136
|
+
"num-complex",
|
|
137
|
+
"num-integer",
|
|
138
|
+
"num-traits",
|
|
139
|
+
"pyo3",
|
|
140
|
+
"pyo3-build-config",
|
|
141
|
+
"rustc-hash",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
[[package]]
|
|
145
|
+
name = "once_cell"
|
|
146
|
+
version = "1.21.3"
|
|
147
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
148
|
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|
149
|
+
|
|
150
|
+
[[package]]
|
|
151
|
+
name = "portable-atomic"
|
|
152
|
+
version = "1.13.1"
|
|
153
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
154
|
+
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
|
155
|
+
|
|
156
|
+
[[package]]
|
|
157
|
+
name = "portable-atomic-util"
|
|
158
|
+
version = "0.2.5"
|
|
159
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
160
|
+
checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5"
|
|
161
|
+
dependencies = [
|
|
162
|
+
"portable-atomic",
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
[[package]]
|
|
166
|
+
name = "proc-macro2"
|
|
167
|
+
version = "1.0.106"
|
|
168
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
169
|
+
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
170
|
+
dependencies = [
|
|
171
|
+
"unicode-ident",
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
[[package]]
|
|
175
|
+
name = "pyo3"
|
|
176
|
+
version = "0.28.1"
|
|
177
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
178
|
+
checksum = "14c738662e2181be11cb82487628404254902bb3225d8e9e99c31f3ef82a405c"
|
|
179
|
+
dependencies = [
|
|
180
|
+
"libc",
|
|
181
|
+
"once_cell",
|
|
182
|
+
"portable-atomic",
|
|
183
|
+
"pyo3-build-config",
|
|
184
|
+
"pyo3-ffi",
|
|
185
|
+
"pyo3-macros",
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
[[package]]
|
|
189
|
+
name = "pyo3-build-config"
|
|
190
|
+
version = "0.28.1"
|
|
191
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
192
|
+
checksum = "f9ca0864a7dd3c133a7f3f020cbff2e12e88420da854c35540fd20ce2d60e435"
|
|
193
|
+
dependencies = [
|
|
194
|
+
"target-lexicon",
|
|
195
|
+
]
|
|
196
|
+
|
|
197
|
+
[[package]]
|
|
198
|
+
name = "pyo3-ffi"
|
|
199
|
+
version = "0.28.1"
|
|
200
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
201
|
+
checksum = "9dfc1956b709823164763a34cc42bbfd26b8730afa77809a3df8b94a3ae3b059"
|
|
202
|
+
dependencies = [
|
|
203
|
+
"libc",
|
|
204
|
+
"pyo3-build-config",
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
[[package]]
|
|
208
|
+
name = "pyo3-macros"
|
|
209
|
+
version = "0.28.1"
|
|
210
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
211
|
+
checksum = "29dc660ad948bae134d579661d08033fbb1918f4529c3bbe3257a68f2009ddf2"
|
|
212
|
+
dependencies = [
|
|
213
|
+
"proc-macro2",
|
|
214
|
+
"pyo3-macros-backend",
|
|
215
|
+
"quote",
|
|
216
|
+
"syn",
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
[[package]]
|
|
220
|
+
name = "pyo3-macros-backend"
|
|
221
|
+
version = "0.28.1"
|
|
222
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
223
|
+
checksum = "e78cd6c6d718acfcedf26c3d21fe0f053624368b0d44298c55d7138fde9331f7"
|
|
224
|
+
dependencies = [
|
|
225
|
+
"heck",
|
|
226
|
+
"proc-macro2",
|
|
227
|
+
"pyo3-build-config",
|
|
228
|
+
"quote",
|
|
229
|
+
"syn",
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
[[package]]
|
|
233
|
+
name = "quote"
|
|
234
|
+
version = "1.0.44"
|
|
235
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
236
|
+
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
|
237
|
+
dependencies = [
|
|
238
|
+
"proc-macro2",
|
|
239
|
+
]
|
|
240
|
+
|
|
241
|
+
[[package]]
|
|
242
|
+
name = "rawpointer"
|
|
243
|
+
version = "0.2.1"
|
|
244
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
245
|
+
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
|
246
|
+
|
|
247
|
+
[[package]]
|
|
248
|
+
name = "rayon"
|
|
249
|
+
version = "1.11.0"
|
|
250
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
251
|
+
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
|
252
|
+
dependencies = [
|
|
253
|
+
"either",
|
|
254
|
+
"rayon-core",
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
[[package]]
|
|
258
|
+
name = "rayon-core"
|
|
259
|
+
version = "1.13.0"
|
|
260
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
261
|
+
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
|
262
|
+
dependencies = [
|
|
263
|
+
"crossbeam-deque",
|
|
264
|
+
"crossbeam-utils",
|
|
265
|
+
]
|
|
266
|
+
|
|
267
|
+
[[package]]
|
|
268
|
+
name = "rimpy_engine"
|
|
269
|
+
version = "0.1.0"
|
|
270
|
+
dependencies = [
|
|
271
|
+
"indexmap",
|
|
272
|
+
"numpy",
|
|
273
|
+
"pyo3",
|
|
274
|
+
"rayon",
|
|
275
|
+
]
|
|
276
|
+
|
|
277
|
+
[[package]]
|
|
278
|
+
name = "rustc-hash"
|
|
279
|
+
version = "2.1.1"
|
|
280
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
281
|
+
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
|
282
|
+
|
|
283
|
+
[[package]]
|
|
284
|
+
name = "syn"
|
|
285
|
+
version = "2.0.115"
|
|
286
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
287
|
+
checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12"
|
|
288
|
+
dependencies = [
|
|
289
|
+
"proc-macro2",
|
|
290
|
+
"quote",
|
|
291
|
+
"unicode-ident",
|
|
292
|
+
]
|
|
293
|
+
|
|
294
|
+
[[package]]
|
|
295
|
+
name = "target-lexicon"
|
|
296
|
+
version = "0.13.4"
|
|
297
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
298
|
+
checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba"
|
|
299
|
+
|
|
300
|
+
[[package]]
|
|
301
|
+
name = "unicode-ident"
|
|
302
|
+
version = "1.0.23"
|
|
303
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
304
|
+
checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
|
rimpy-0.1.0/Cargo.toml
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "rimpy_engine"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2024"
|
|
5
|
+
description = "Fast RIM/raking engine for rimpy"
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
|
|
8
|
+
[lib]
|
|
9
|
+
name = "_rimpy_engine"
|
|
10
|
+
crate-type = ["cdylib"]
|
|
11
|
+
|
|
12
|
+
[dependencies]
|
|
13
|
+
pyo3 = { version = "0.28", features = ["extension-module"] }
|
|
14
|
+
numpy = "0.28" # Zero-copy NumPy array access
|
|
15
|
+
rayon = "1.10" # Parallel iteration for grouped raking
|
|
16
|
+
indexmap = "2" # Preserves insertion order like Python dict
|
|
17
|
+
# arrow = { version = "54", optional = true } # Future: zero-copy from Polars
|
|
18
|
+
|
|
19
|
+
[features]
|
|
20
|
+
default = []
|
|
21
|
+
# arrow = ["dep:arrow"] # Enable when ready for Arrow FFI path
|
|
22
|
+
|
|
23
|
+
[profile.release]
|
|
24
|
+
lto = true # Link-time optimization for max speed
|
|
25
|
+
codegen-units = 1 # Single codegen unit = better optimization
|
|
26
|
+
opt-level = 3
|
|
27
|
+
strip = true
|
rimpy-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rimpy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Rust
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering
|
|
12
|
+
Requires-Dist: narwhals>=2.16.0
|
|
13
|
+
Requires-Dist: numpy>=2.4.2
|
|
14
|
+
Requires-Dist: polars>=1.38.1 ; extra == 'all'
|
|
15
|
+
Requires-Dist: pandas>=3.0.0 ; extra == 'all'
|
|
16
|
+
Requires-Dist: pytest>=9.0.2 ; extra == 'dev'
|
|
17
|
+
Requires-Dist: pandas>=3.0.0 ; extra == 'dev'
|
|
18
|
+
Requires-Dist: polars>=1.38.1 ; extra == 'dev'
|
|
19
|
+
Requires-Dist: pandas>=3.0.0 ; extra == 'pandas'
|
|
20
|
+
Requires-Dist: polars>=1.38.1 ; extra == 'polars'
|
|
21
|
+
Provides-Extra: all
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Provides-Extra: pandas
|
|
24
|
+
Provides-Extra: polars
|
|
25
|
+
Summary: Fast RIM (raking) survey weighting with narwhals - supports polars and pandas
|
|
26
|
+
Keywords: survey,weighting,raking,rim,rim-weighting,iterative-proportional-fitting,ipf,market-research,polars,pandas,narwhals
|
|
27
|
+
Author: Albert Li
|
|
28
|
+
License-Expression: MIT
|
|
29
|
+
Requires-Python: >=3.12
|
|
30
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
31
|
+
Project-URL: Documentation, https://github.com/albertxli/rimpy
|
|
32
|
+
Project-URL: Homepage, https://github.com/albertxli/rimpy
|
|
33
|
+
Project-URL: Repository, https://github.com/albertxli/rimpy
|
|
34
|
+
|
|
35
|
+
# rimpy — Rust-accelerated RIM engine
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
rimpy/
|
|
41
|
+
├── Cargo.toml # Rust crate definition
|
|
42
|
+
├── pyproject.toml # Python package (maturin build)
|
|
43
|
+
├── src/ # Rust source
|
|
44
|
+
│ ├── lib.rs # PyO3 bindings + module exports
|
|
45
|
+
│ └── engine.rs # Core RIM algorithm (pure Rust)
|
|
46
|
+
├── python/ # Python source (maturin mixed layout)
|
|
47
|
+
│ └── rimpy/
|
|
48
|
+
│ ├── __init__.py # Public API (unchanged)
|
|
49
|
+
│ ├── _engine.py # Shim: tries Rust → falls back to Python
|
|
50
|
+
│ ├── _engine_py.py # Pure Python/NumPy fallback
|
|
51
|
+
│ ├── _rake.py # Narwhals orchestration (unchanged)
|
|
52
|
+
│ └── _loaders.py # Scheme loaders (unchanged)
|
|
53
|
+
├── tests/
|
|
54
|
+
│ └── test_backend_parity.py # Validates Rust == Python results
|
|
55
|
+
└── benchmarks/
|
|
56
|
+
└── bench_engine.py # Performance comparison
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### What changed, what didn't
|
|
60
|
+
|
|
61
|
+
| File | Status | Why |
|
|
62
|
+
|------|--------|-----|
|
|
63
|
+
| `_rake.py` | **Unchanged** | Orchestration layer, not a bottleneck |
|
|
64
|
+
| `_loaders.py` | **Unchanged** | I/O bound, no benefit from Rust |
|
|
65
|
+
| `__init__.py` | **Unchanged** | Public API stays the same |
|
|
66
|
+
| `_engine.py` | **Now a shim** | Tries `rimpy_engine` (Rust), falls back to `_engine_py` |
|
|
67
|
+
| `_engine_py.py` | **Renamed original** | Pure Python fallback for portability |
|
|
68
|
+
| `src/engine.rs` | **New** | Core RIM loop in Rust (raw slices, zero alloc) |
|
|
69
|
+
| `src/lib.rs` | **New** | PyO3 bindings accepting NumPy arrays |
|
|
70
|
+
|
|
71
|
+
### Why this design
|
|
72
|
+
|
|
73
|
+
- **Zero API changes**: `_rake.py` still does `from ._engine import RakeResult, rim_iterate`. Users see no difference.
|
|
74
|
+
- **Graceful fallback**: No Rust compiler? No problem — pure Python still works.
|
|
75
|
+
- **Check which backend**: `rimpy._engine.get_backend()` returns `"rust"` or `"python"`.
|
|
76
|
+
|
|
77
|
+
## Building
|
|
78
|
+
|
|
79
|
+
### Prerequisites
|
|
80
|
+
|
|
81
|
+
- Rust toolchain: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
|
|
82
|
+
- uv (already installed)
|
|
83
|
+
|
|
84
|
+
### Development build
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# uv reads [build-system] → maturin, handles everything
|
|
88
|
+
uv pip install -e ".[dev]"
|
|
89
|
+
|
|
90
|
+
# Verify
|
|
91
|
+
uv run python -c "from rimpy._engine import get_backend; print(get_backend())"
|
|
92
|
+
# → "rust"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Release build (wheel)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
uv build
|
|
99
|
+
# Output: dist/rimpy-0.2.0-cp312-cp312-*.whl
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Publish to PyPI
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
uv publish
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Run benchmarks
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
uv run python benchmarks/bench_engine.py
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Run tests
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
uv run pytest tests/ -v
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Rust engine design decisions
|
|
121
|
+
|
|
122
|
+
### Why raw `Vec<f64>` instead of ndarray or Arrow?
|
|
123
|
+
|
|
124
|
+
RIM's core operation is **indexed gather/scatter on a 1D array**:
|
|
125
|
+
- Gather: sum `weights[indices]` for each category
|
|
126
|
+
- Scatter: `weights[indices] *= multiplier`
|
|
127
|
+
|
|
128
|
+
This is trivially expressed with plain slices. `ndarray` would add abstraction overhead
|
|
129
|
+
and allocate on fancy indexing. Arrow is a columnar format, not a compute engine.
|
|
130
|
+
|
|
131
|
+
Raw slices let `rustc` + LLVM auto-vectorize with SIMD, and the hot loop does **zero
|
|
132
|
+
heap allocations** (the `old_weights` buffer is pre-allocated and reused via `copy_from_slice`).
|
|
133
|
+
|
|
134
|
+
### Why Rayon for grouped raking?
|
|
135
|
+
|
|
136
|
+
Each country/segment gets its own weights vector — no shared mutable state.
|
|
137
|
+
This is embarrassingly parallel. `rayon::par_iter()` gives near-linear speedup
|
|
138
|
+
across CPU cores with zero synchronization overhead.
|
|
139
|
+
|
|
140
|
+
### Data ingress
|
|
141
|
+
|
|
142
|
+
Currently accepts NumPy arrays via `pyo3-numpy` (near-zero-copy for contiguous arrays).
|
|
143
|
+
|
|
144
|
+
**Future**: Arrow FFI path for zero-copy from Polars. The engine itself stays the same —
|
|
145
|
+
only the ingress layer changes.
|
|
146
|
+
|
|
147
|
+
## Integration with existing code
|
|
148
|
+
|
|
149
|
+
Your `_rake.py` and `_loaders.py` remain identical. The only structural change is:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
# Before (in _rake.py):
|
|
153
|
+
from ._engine import RakeResult, rim_iterate
|
|
154
|
+
|
|
155
|
+
# After (same import — _engine.py is now a shim):
|
|
156
|
+
from ._engine import RakeResult, rim_iterate # tries Rust, falls back to Python
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The shim handles everything transparently.
|
|
160
|
+
|