mxframe 0.1.2__tar.gz → 0.2.3__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.
Files changed (34) hide show
  1. mxframe-0.2.3/CHANGELOG.md +178 -0
  2. {mxframe-0.1.2 → mxframe-0.2.3}/MANIFEST.in +1 -1
  3. mxframe-0.2.3/PKG-INFO +572 -0
  4. mxframe-0.2.3/README.md +539 -0
  5. {mxframe-0.1.2 → mxframe-0.2.3}/__init__.py +1 -1
  6. {mxframe-0.1.2 → mxframe-0.2.3}/aot_kernels.py +617 -310
  7. {mxframe-0.1.2 → mxframe-0.2.3}/custom_ops.py +255 -157
  8. mxframe-0.2.3/kernels.mojopkg +0 -0
  9. mxframe-0.2.3/kernels_aot/libmxkernels_aot.so +0 -0
  10. mxframe-0.2.3/kernels_aot/libmxkernels_aot_gpu.so +0 -0
  11. mxframe-0.2.3/mxframe.egg-info/PKG-INFO +572 -0
  12. {mxframe-0.1.2 → mxframe-0.2.3}/mxframe.egg-info/requires.txt +1 -1
  13. {mxframe-0.1.2 → mxframe-0.2.3}/pyproject.toml +2 -2
  14. mxframe-0.1.2/CHANGELOG.md +0 -64
  15. mxframe-0.1.2/PKG-INFO +0 -437
  16. mxframe-0.1.2/README.md +0 -404
  17. mxframe-0.1.2/kernels.mojopkg +0 -0
  18. mxframe-0.1.2/kernels_aot/libmxkernels_aot.so +0 -0
  19. mxframe-0.1.2/kernels_aot/libmxkernels_aot_gpu.so +0 -0
  20. mxframe-0.1.2/mxframe.egg-info/PKG-INFO +0 -437
  21. {mxframe-0.1.2 → mxframe-0.2.3}/_modidx.py +0 -0
  22. {mxframe-0.1.2 → mxframe-0.2.3}/compiler.py +0 -0
  23. {mxframe-0.1.2 → mxframe-0.2.3}/docs/vision-and-architecture.md +0 -0
  24. {mxframe-0.1.2 → mxframe-0.2.3}/kernels_aot/__init__.py +0 -0
  25. {mxframe-0.1.2 → mxframe-0.2.3}/lazy_expr.py +0 -0
  26. {mxframe-0.1.2 → mxframe-0.2.3}/lazy_frame.py +0 -0
  27. {mxframe-0.1.2 → mxframe-0.2.3}/mxframe.egg-info/SOURCES.txt +0 -0
  28. {mxframe-0.1.2 → mxframe-0.2.3}/mxframe.egg-info/dependency_links.txt +0 -0
  29. {mxframe-0.1.2 → mxframe-0.2.3}/mxframe.egg-info/top_level.txt +0 -0
  30. {mxframe-0.1.2 → mxframe-0.2.3}/optimizer.py +0 -0
  31. {mxframe-0.1.2 → mxframe-0.2.3}/plan_validation.py +0 -0
  32. {mxframe-0.1.2 → mxframe-0.2.3}/setup.cfg +0 -0
  33. {mxframe-0.1.2 → mxframe-0.2.3}/setup.py +0 -0
  34. {mxframe-0.1.2 → mxframe-0.2.3}/sql_frontend.py +0 -0
@@ -0,0 +1,178 @@
1
+ # 📋 Changelog
2
+
3
+ All notable changes to MXFrame are documented here.
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
+
6
+ ---
7
+
8
+ ## [0.2.3] — 2026-07-09
9
+
10
+ ### ⚡ Performance
11
+ - **Phase 4 — Device-resident GPU join pipeline** (`join_count_i32_gpu` + `join_scatter_i32_gpu`):
12
+ GPU inner joins now bypass MAX Graph JIT entirely. Cold-start join latency drops from ~300 ms (MAX session init + JIT) to ~70 ms. `AOTKernelsGPU.hash_join()` caches key arrays via `_cached_upload`; `AOTKernelsGPU.gather_table()` gathers all numeric columns with a single shared device-resident index upload.
13
+ - **Phase 5 — GPU sort + top-k** (`sort_topk_i32_gpu`): `ORDER BY … LIMIT k` fuses sort and limit in a single AOT bitonic sort kernel, downloading only `k × 4` bytes instead of `N × 4`. `_apply_post_ops_custom` peek-ahead passes `topk=k` directly to the sort kernel.
14
+ - **Phase 3 — Vectorised rank mapping**: `_encode_sort_key` replaces the per-unique-value Python `for` loop with a single vectorised NumPy scatter (`rank_of[sorted_order] = np.arange(n_unique)`). ~1.5× speedup for sort-key encoding at 5 M rows.
15
+
16
+ ### 🛠 Fixed
17
+ - **GPU sort+limit crash**: `_apply_sort_custom` was calling `_gpu_gather_table` which referenced `gather_f32` as a MAX Graph custom op — that kernel was never registered in the mojopkg. Any `ORDER BY` on `device="gpu"` would crash. Now routes through `_aot_gpu.gather_table` (AOT ctypes, no MAX Graph).
18
+ - `_apply_sort_custom` CPU path now uses `np.argpartition` (O(N) partial sort) when `topk < N`, instead of a full O(N log N) argsort.
19
+
20
+ ### 🔨 Infrastructure
21
+ - **Mojo/MAX 26.4 migration**: all `kernels/*.mojo` and `kernels_aot/*.mojo` migrated from 26.2 API (`fn` → `def`, `from tensor import` → `from extensibility import`, `DeviceContextPtr` → `DeviceContext`, `enqueue_function_experimental` → `enqueue_function`).
22
+ - **`kernels/_atomic.mojo`** (new): drop-in replacement for the missing `std.os.atomic.Atomic`. Implements `fetch_add`, `min`, `max`, `compare_exchange` via MLIR `llvm.atomicrmw` / `llvm.cmpxchg` instructions — portable across NVIDIA and AMD; works in both `mojo package` (JIT) and `mojo build --emit shared-lib` (AOT) contexts.
23
+ - All compiled artifacts rebuilt with Mojo 1.0.0b2 (modular 26.4): `kernels.mojopkg`, `libmxkernels_aot.so`, `libmxkernels_aot_gpu.so`.
24
+
25
+ ---
26
+
27
+ ## [0.2.2] — 2026-07-08
28
+
29
+ ### 🔨 Infrastructure
30
+ - First release targeting **Mojo/MAX 26.4** (`modular = "26.4.*"` in `pixi.toml`).
31
+ - `_atomic.mojo` shim introduced to replace the removed `std.os.atomic` module.
32
+ - All kernel source files migrated to 26.4 syntax; compiled artefacts rebuilt.
33
+ - `pyproject.toml` `runtime` extra pinned to `modular>=26.4` to prevent 26.2 wheels from being installed by Colab/pip users.
34
+
35
+ ---
36
+
37
+ ## [0.2.1] — 2026-06-xx
38
+
39
+ ### 🔨 Infrastructure
40
+ - TestPyPI re-upload to validate wheel packaging. No functional changes.
41
+
42
+ ---
43
+
44
+ ## [0.2.0] — 2026-05-xx
45
+
46
+ ### ✨ Added
47
+ - **Phase 1 — GPU buffer cache + masked global min/max**:
48
+ - `masked_global_min_f32_gpu` / `masked_global_max_f32_gpu` Mojo AOT kernels.
49
+ - `AOTKernelsGPU` device-buffer cache (`_cached_upload`, eviction, `clear_buf_cache`) — eliminates redundant PCIe uploads on repeated hot queries.
50
+ - `group_mean_f32` GPU kernel (sum + count on GPU, divide on CPU).
51
+ - Masked global min/max fast-paths wired in `custom_ops.py`.
52
+ - **Phase 2 — Masked global aggregation for any expression**:
53
+ - `_compute_masked_global_agg` extended to handle any inner expression via `_eval_expr_arrow` (e.g. `a*(1-b)`, `case_when`, `startswith`, `isin`) — SUM reduction stays GPU-resident.
54
+ - Join-only plans emit `"join_mojo_shortcut"` provenance (not `"pyarrow_shortcut"`) — Q19 restructured to single-pass join+filter+global_agg.
55
+ - `audit_gpu_paths.py` updated: `join_mojo_shortcut` counted as Mojo-backed.
56
+ - **Phase 3 — GPU integer key encoding**:
57
+ - `group_encode_i32_gpu` open-addressing hash-table kernel for integer group keys; replaces PyArrow `dictionary_encode` for integer-keyed group-by on GPU.
58
+ - **Audit tool** (`scripts/audit_gpu_paths.py`): classifies each of 22 TPC-H queries as `GPU-CLEAN` / `MOJO-CPU` / `FALLBACK` via `last_compile_provenance["path"]`.
59
+ - **Interactive visualiser** (`visualize/mxframe_pipeline.html`): step-through of how a Python query becomes a plan tree and dispatches to GPU kernels.
60
+
61
+ ### ⚡ Performance
62
+ - **22/22 TPC-H queries GPU-CLEAN** (100% Mojo-backed on GPU, zero PyArrow fallbacks in the reduction and join hot paths).
63
+
64
+ ---
65
+
66
+ ## [0.1.2] — 2026-04-22
67
+
68
+ ### 🛠 Fixed
69
+ - `pip install "mxframe[runtime]"` now gives a working install. The `[runtime]` extra pulls `modular>=25.5`, which provides the `max.engine` / `max.driver` modules that `mxframe.compiler` imports at module load. (Pixi users get `modular` from the Modular conda channel and should install `mxframe` without the extra.)
70
+ - `sqlglot` import in `mxframe.sql_frontend` is now lazy: `import mxframe` no longer requires the `[sql]` extra. Calling `mxframe.sql(…)` without `sqlglot` installed raises a clear `ImportError` with the install hint.
71
+ - `__init__.py` `__version__` now matches `pyproject.toml`.
72
+
73
+ ---
74
+
75
+ ## [0.1.1] — 2026-04-22
76
+
77
+ ### 🛠 Fixed
78
+ - Packaging: `readme` now points to `README.md` so PyPI shows the full project page with benchmarks and quickstart (was accidentally showing the internal vision/architecture doc)
79
+ - CI: `AOTKernelsGPU` init no longer hard-fails on CPU-only runners (`CUDA driver unavailable` is caught, `self._aot_gpu` falls back to `None`)
80
+ - CI: `_find_kernels_path()` uses `Path(__file__).resolve().parent` directly, removing the stale `/home/ablearn/mxdf/…` dev fallback that surfaced in installed wheels
81
+ - Bug: `NameError: cache_key_count` in `_hash_join_mojo_cpu` MAX Graph fallback
82
+ - Tests: `scripts/_test_phase0_custom_ops.py` and `_test_phase1.py` no longer hard-code a developer's kernels path; they use the auto-detected default
83
+
84
+ ---
85
+
86
+ ## [0.1.0] — 2026-04-20
87
+
88
+ ### ✨ Added
89
+ - **All 22 TPC-H queries** on CPU and GPU AOT paths
90
+ - **GPU LEFT JOIN** — `join_count_left` + `join_scatter_left` Mojo kernels wired to Python (Q13)
91
+ - `bench_simple.py` — clean 4-column benchmark (Pandas | Polars | MX CPU | MX GPU)
92
+ - `--queries` and `--runs` flags for targeted benchmarking
93
+
94
+ ### ⚡ Performance
95
+ - **Q22** phone prefix anti-join: vectorized via `pc.utf8_slice_codeunits` + `pc.is_in` + `np.isin` — 3.6× faster than Polars CPU (was 10× **slower**)
96
+ - **Q20** semi-join chain: eliminated `.to_pandas()` Pandas detour — 8.7× faster than Polars (was comparable)
97
+ - **Q21** EXISTS+NOT EXISTS: replaced `.to_pandas().groupby.nunique()` with NumPy composite key dedup
98
+ - **Q18** large volume customers: replaced `.to_pylist()` semi-join with Mojo join — semi-join now uses AOT kernel path
99
+ - **Q15** argmax supplier: replaced `0.9999 * max_rev` tolerance hack with exact `pc.equal()` on float32
100
+ - **Q13** LEFT JOIN: removed `.to_pandas()` groupby detour — now fully on GPU AOT path (19ms CPU, 29ms GPU vs 25ms Polars)
101
+
102
+ ### 🐛 Fixed
103
+ - `not use_gpu_filter` gate bug in `custom_ops.py` section 4.6 that blocked GPU filter path
104
+ - Q7 nation pre-join cache key now uses `id()` preventing cache misses on repeated hot calls
105
+
106
+ ### 🏗️ Infrastructure
107
+ - `pyproject.toml` updated with full metadata, dependencies, optional extras, package-data for `.so` files
108
+ - `CONTRIBUTING.md` — developer guide with kernel writing tutorial
109
+ - `PUBLISHING.md` — step-by-step pip release guide
110
+ - GitHub Actions: `test.yml` (CI), `publish.yml` (PyPI via OIDC)
111
+
112
+ ### 📊 Benchmark Summary (1M and 10M rows, all 22 queries, warm median of 3)
113
+
114
+ See the full table in [README.md § TPC-H Benchmark](README.md#-tpc-h-benchmark--all-22-queries),
115
+ sourced from `scripts/bench_results_1M.csv` and `scripts/bench_results_10M.csv`.
116
+
117
+ - **Correctness:** 22/22 queries pass on CPU and GPU paths
118
+ - **MX CPU wins vs Polars:** **21/22** at 1 M, **18/22** at 10 M
119
+ — headline: **Q9 128× · Q12 89× · Q7 42× · Q8 31× · Q17 24× · Q5 22×** (at 10 M)
120
+ - **MX GPU wins vs Polars:** **16/22** at 1 M, **15/22** at 10 M
121
+ — headline: **Q12 26.5× · Q9 12× · Q8 10.8× · Q17 9.7× · Q7 4.7×** (at 10 M)
122
+ - **Remaining losses (Q4, Q6, Q13, Q21):** ops that still route through PyArrow fallback — kernel replacements tracked in `roadmap.md`
123
+
124
+ ### 🛠 Fixed
125
+ - `pip install "mxframe[runtime]"` now gives a working install. The `[runtime]` extra pulls `modular>=25.5`, which provides the `max.engine` / `max.driver` modules that `mxframe.compiler` imports at module load. (Pixi users get `modular` from the Modular conda channel and should install `mxframe` without the extra.)
126
+ - `sqlglot` import in `mxframe.sql_frontend` is now lazy: `import mxframe` no longer requires the `[sql]` extra. Calling `mxframe.sql(…)` without `sqlglot` installed raises a clear `ImportError` with the install hint.
127
+ - `__init__.py` `__version__` now matches `pyproject.toml`.
128
+
129
+ ---
130
+
131
+ ## [0.1.1] — 2026-04-22
132
+
133
+ ### 🛠 Fixed
134
+ - Packaging: `readme` now points to `README.md` so PyPI shows the full project page with benchmarks and quickstart (was accidentally showing the internal vision/architecture doc)
135
+ - CI: `AOTKernelsGPU` init no longer hard-fails on CPU-only runners (`CUDA driver unavailable` is caught, `self._aot_gpu` falls back to `None`)
136
+ - CI: `_find_kernels_path()` uses `Path(__file__).resolve().parent` directly, removing the stale `/home/ablearn/mxdf/…` dev fallback that surfaced in installed wheels
137
+ - Bug: `NameError: cache_key_count` in `_hash_join_mojo_cpu` MAX Graph fallback
138
+ - Tests: `scripts/_test_phase0_custom_ops.py` and `_test_phase1.py` no longer hard-code a developer's kernels path; they use the auto-detected default
139
+
140
+ ---
141
+
142
+ ## [0.1.0] — 2026-04-20
143
+
144
+ ### ✨ Added
145
+ - **All 22 TPC-H queries** on CPU and GPU AOT paths
146
+ - **GPU LEFT JOIN** — `join_count_left` + `join_scatter_left` Mojo kernels wired to Python (Q13)
147
+ - `bench_simple.py` — clean 4-column benchmark (Pandas | Polars | MX CPU | MX GPU)
148
+ - `--queries` and `--runs` flags for targeted benchmarking
149
+
150
+ ### ⚡ Performance
151
+ - **Q22** phone prefix anti-join: vectorized via `pc.utf8_slice_codeunits` + `pc.is_in` + `np.isin` — 3.6× faster than Polars CPU (was 10× **slower**)
152
+ - **Q20** semi-join chain: eliminated `.to_pandas()` Pandas detour — 8.7× faster than Polars (was comparable)
153
+ - **Q21** EXISTS+NOT EXISTS: replaced `.to_pandas().groupby.nunique()` with NumPy composite key dedup
154
+ - **Q18** large volume customers: replaced `.to_pylist()` semi-join with Mojo join — semi-join now uses AOT kernel path
155
+ - **Q15** argmax supplier: replaced `0.9999 * max_rev` tolerance hack with exact `pc.equal()` on float32
156
+ - **Q13** LEFT JOIN: removed `.to_pandas()` groupby detour — now fully on GPU AOT path (19ms CPU, 29ms GPU vs 25ms Polars)
157
+
158
+ ### 🐛 Fixed
159
+ - `not use_gpu_filter` gate bug in `custom_ops.py` section 4.6 that blocked GPU filter path
160
+ - Q7 nation pre-join cache key now uses `id()` preventing cache misses on repeated hot calls
161
+
162
+ ### 🏗️ Infrastructure
163
+ - `pyproject.toml` updated with full metadata, dependencies, optional extras, package-data for `.so` files
164
+ - `CONTRIBUTING.md` — developer guide with kernel writing tutorial
165
+ - `PUBLISHING.md` — step-by-step pip release guide
166
+ - GitHub Actions: `test.yml` (CI), `publish.yml` (PyPI via OIDC)
167
+
168
+ ### 📊 Benchmark Summary (1M and 10M rows, all 22 queries, warm median of 3)
169
+
170
+ See the full table in [README.md § TPC-H Benchmark](README.md#-tpc-h-benchmark--all-22-queries),
171
+ sourced from `scripts/bench_results_1M.csv` and `scripts/bench_results_10M.csv`.
172
+
173
+ - **Correctness:** 22/22 queries pass on CPU and GPU paths
174
+ - **MX CPU wins vs Polars:** **21/22** at 1 M, **18/22** at 10 M
175
+ — headline: **Q9 128× · Q12 89× · Q7 42× · Q8 31× · Q17 24× · Q5 22×** (at 10 M)
176
+ - **MX GPU wins vs Polars:** **16/22** at 1 M, **15/22** at 10 M
177
+ — headline: **Q12 26.5× · Q9 12× · Q8 10.8× · Q17 9.7× · Q7 4.7×** (at 10 M)
178
+ - **Remaining losses (Q4, Q6, Q13, Q21):** ops that still route through PyArrow fallback — kernel replacements tracked in `roadmap.md`
@@ -17,5 +17,5 @@ include kernels.mojopkg
17
17
  recursive-include kernels_aot *.py *.so
18
18
  prune llm-ctx
19
19
  prune scripts
20
- prune kernels_v261
20
+ prune kernels
21
21
  global-exclude __pycache__ *.py[cod]