Repository navigation
Introduce Menudet 0.1 draft for portable array and table computation - #741
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Active issues remain, including a critical dispatch flag that prevents supported native Menudet calls from reaching compilation, a missing CMake header dependency that can leave generated bindings stale, and inaccurate performance-record metadata.
3 open issues
What changed in this PR
This pull request introduces Menudet 0.1 as a portable, validated computation and persistence layer for arrays and tables. It adds native artifact execution, replaces runtime NumExpr integration, and expands persistence, qualification, documentation, examples, and regression coverage.
Changes:
- Adds Menudet authoring, specialization, native execution, graph support, numerical policies, and portable persistence.
- Updates LazyUDFs, table transformations, remote storage, deserialization, and legacy DSL migration behavior.
- Adds native qualification tooling, benchmarks, CI workflows, WASM coverage, documentation, and examples.
| File | Summary | Review note |
|---|---|---|
tools/menudet_batch_qualification.py |
Adds cross-compiler Menudet corpus qualification. | Moderate: Add an unversioned gcc fallback; the current default only probes gcc-16. (1 vote) |
tests/test_tip11_hash.py |
Tests portable integer hash behavior. | — |
tests/test_remote_store_cache_locking.py |
Tests Windows cache-lock contention. | — |
tests/test_remote_caterva2.py |
Gates rich Caterva2 tests on NumPy string support. | Moderate: Safely guard access to np.dtypes for NumPy 1.26. (1 vote) |
tests/test_releasegil_isolation.py |
Verifies release-GIL fixture isolation. | — |
tests/test_pytest_configuration.py |
Tests pytest without its cache provider. | — |
tests/test_orthogonal_cases.py |
Tests deterministic orthogonal sampling. | — |
tests/test_objectarray.py |
Updates Menudet object persistence assertions. | — |
tests/test_numpy_boolean_fallback.py |
Tests scalar and array boolean fallback semantics. | — |
tests/test_native_qualification_evidence.py |
Validates native qualification evidence. | — |
tests/test_menudet_math_vectors.py |
Verifies numerical certification vectors. | — |
tests/test_menudet_inverse_names.py |
Tests canonical native math-function names. | — |
tests/test_menudet_descriptor_host.py |
Tests native descriptor routing. | — |
tests/test_menudet_backend.py |
Tests Menudet backend and execution policies. | — |
tests/test_locking.py |
Limits worker-thread creation in locking tests. | — |
tests/test_http_server_diagnostics.py |
Tests HTTP error diagnostics. | — |
tests/test_expression_threads.py |
Tests expression-thread isolation. | Moderate: Propagate child interpreter assertion and import failures. (1 vote) |
tests/test_deserialization.py |
Tests safe LazyExpr persistence and loading. | — |
tests/test_compressors.py |
Updates compressor test coverage. | — |
tests/test_chunk_reader_lifetime.py |
Tests nested persisted-reader lifetime management. | — |
tests/test_cache_lock.py |
Updates Windows cache-lock expectations. | — |
tests/test_bench_sum_linear_idx.py |
Tests Menudet coordinate and reduction benchmarks. | — |
tests/test_bench_linear_constructor.py |
Tests Menudet linear constructor benchmarks. | — |
tests/test_bench_jit_dsl.py |
Tests JIT benchmark captures and outputs. | — |
tests/test_bench_evaluator_fallbacks.py |
Validates evaluator fallback diagnostics. | — |
tests/test_bench_evaluate_numpy_parity.py |
Tests NumPy-output parity qualification. | — |
tests/test_bench_compute_expr_udf.py |
Tests predicate benchmark bindings. | — |
tests/test_b2nd_to_zarr.py |
Adjusts Zarr warning handling. | — |
tests/ndarray/test_wasm_dsl_jit.py |
Updates WASM kernel fixtures. | — |
tests/ndarray/test_stringarrays.py |
Reduces representative string-array combinations. | — |
tests/ndarray/test_string_output.py |
Updates string-kernel fixtures. | — |
tests/ndarray/test_setitem_chunkwise.py |
Adjusts NumPy-version-specific assignment expectations. | — |
tests/ndarray/test_safer_jit.py |
Expands safer-JIT workload and cache checks. | — |
tests/ndarray/test_math_backend.py |
Tests per-call math backend selection. | — |
tests/ndarray/test_lazyudf.py |
Updates LazyUDF persistence coverage. | — |
tests/ndarray/test_jit_dsl_dispatch.py |
Updates Menudet control-flow dispatch expectations. | — |
tests/ndarray/test_expression_fusion_threads.py |
Tests thread-local fusion state. | — |
tests/ndarray/test_elementwise_funcs.py |
Samples elementwise function and layout combinations. | — |
tests/ndarray/test_dsl_js.py |
Updates JavaScript-transpiler fixtures. | — |
tests/ndarray/test_dsl_comparisons.py |
Uses source normalization for comparisons. | — |
tests/ndarray/test_auto_parts.py |
Uses orthogonal sampling for storage parts. | — |
tests/ndarray/safer_jit_probe.py |
Adds a focused safer-JIT workload. | — |
tests/ctable/test_utf8.py |
Updates UTF-8 Menudet fixtures. | — |
tests/ctable/test_pandas_arrow_import.py |
Gates UTF-8 Arrow imports on NumPy support. | Moderate: Guard the absent np.dtypes namespace before accessing StringDType. (1 vote) |
tests/ctable/test_null_storage_schema.py |
Tests UTF-8 behavior without StringDType. |
— |
tests/ctable/test_null_channel.py |
Tests null predicates during equality suppression. | — |
tests/ctable/test_groupby.py |
Updates groupby kernel fixtures. | — |
tests/ctable/test_dictionary_column.py |
Adds pandas-free dictionary import coverage. | — |
tests/ctable/test_ctable_apply.py |
Updates CTable apply fixtures. | — |
tests/ctable/test_arrow_interop.py |
Updates DuckDB result-fetching compatibility. | — |
src/blosc2/zarr_source.py |
Preserves accounting through Zarr read-only wrappers. | Moderate: Preserve the metadata mapping when creating CountingStore. (1 vote) |
src/blosc2/version.py |
Bumps the development version to 4.15.0. | — |
src/blosc2/tree_store.py |
Adds persistence preflight validation. | — |
src/blosc2/schunk.py |
Enforces Menudet and legacy deserialization policies. | — |
src/blosc2/remote_store_cache.py |
Adds Windows cache-lock retry behavior. | — |
src/blosc2/remote_parquet.py |
Records original Parquet storage provenance. | — |
src/blosc2/remote_array.py |
Records remote-array expression provenance. | Moderate: Update expression provenance when RemoteArray.refresh() replaces its source. (1 vote) |
src/blosc2/proxy.py |
Routes DSL-shaped JIT wrappers through Menudet. | Critical: Avoid setting the compatibility flag so that supported native control-flow calls are rejected before Menudet dispatch. (1 vote) |
src/blosc2/objectarray.py |
Updates Menudet persistence documentation. | — |
src/blosc2/jit_config.py |
Adds scoped math backend options. | — |
src/blosc2/indexing.py |
Migrates indexed evaluation to the typed evaluator. | — |
src/blosc2/groupby.py |
Uses source-authored kernel normalization. | — |
src/blosc2/exceptions.py |
Adds legacy-recipe and deserialization errors. | — |
src/blosc2/embed_store.py |
Adds persistence preflight validation. | — |
src/blosc2/dsl_js.py |
Clarifies internal source-kernel transpilation. | — |
src/blosc2/dsl_array_bridge.h |
Adds native array artifact and reader bridges. | — |
src/blosc2/dict_store.py |
Adds lazy-size estimation and persistence preflight. | — |
src/blosc2/deserialization.py |
Handles objects without physical carriers. | — |
src/blosc2/ctable_storage.py |
Tracks logical dtype overrides. | — |
src/blosc2/ctable_nulls.py |
Keeps sentinel predicates lazy during fusion. | — |
src/blosc2/ctable_indexing.py |
Restricts summary bitmap projection to sound conjunctions. | — |
src/blosc2/core.py |
Removes NumExpr integration and rejects legacy recipes. | — |
src/blosc2/cli/zarr_to_b2nd.py |
Supports enum-valued codec and filter options. | — |
src/blosc2/batch_array.py |
Updates Menudet persistence documentation. | — |
src/blosc2/_utf8_array.py |
Renames UTF-8 evaluator options. | — |
src/blosc2/__init__.py |
Exposes Menudet APIs and removes NumExpr initialization. | — |
scripts/verify_safe_lazyexpr.py |
Records bounded safe-graph qualification evidence. | — |
scripts/verify_native_qualification.py |
Verifies exact native revision qualification. | — |
scripts/qualify_without_numexpr.py |
Provides NumExpr-free qualification execution. | — |
pytest.ini |
Registers native semantics and warning configuration. | — |
pyproject.toml |
Removes NumExpr and updates the package version. | — |
plans/portable-jit-api.md |
Records the rejected portable-JIT API decision. | — |
plans/menudet-jit-expanded-conformance.json |
Records expanded native conformance results. | — |
plans/mathlib-performance.md |
Documents math backend performance observations. | Nit: Replace the obsolete PortableKernel reference with MenudetKernel, or mark it as historical. (2 votes) |
plans/lazyexpr-prefilter-before-profile.txt |
Records pre-optimization profiling data. | — |
plans/lazyexpr-prefilter-after-profile.txt |
Records post-optimization profiling data. | — |
plans/compute-expr-udf-profile-before.txt |
Preserves pre-optimization UDF profiling data. | — |
plans/compute-expr-udf-legacy.md |
Preserves historical benchmark context. | — |
examples/vlstore-lazyudf.py |
Migrates an object-store example to Menudet. | — |
examples/ndarray/portable_artifact.py |
Demonstrates standalone artifact execution. | — |
examples/ndarray/mandelbrot-pure-dsl.ipynb |
Labels the retired DSL notebook as historical. | — |
examples/ndarray/mandelbrot-dsl.ipynb |
Labels historical DSL comparison content. | — |
examples/ndarray/malformed_dsl.py |
Demonstrates Menudet validation and execution errors. | — |
examples/ndarray/ironpill1.ipynb |
Updates benchmark engine documentation. | — |
examples/ndarray/dsl_save.py |
Demonstrates Menudet recipe persistence. | — |
examples/ndarray/black-scholes_hist-dsl.ipynb |
Labels historical DSL benchmark content. | — |
examples/menudet.py |
Adds array, table, and reduction examples. | — |
examples/menudet_decorator.py |
Demonstrates Menudet authoring and specialization. | — |
examples/embedded-expr-udf-b2z.py |
Migrates embedded UDF execution to Menudet. | — |
doc/reference/schunk.rst |
Documents Menudet persistence support. | — |
doc/reference/save_load.rst |
Documents safe and full deserialization policies. | — |
doc/reference/objectarray.rst |
Updates ObjectArray persistence documentation. | — |
doc/reference/msgpack_serialization.rst |
Documents Menudet MessagePack recipes. | — |
doc/reference/misc.rst |
Documents the finfo alias. |
— |
doc/reference/menudet.rst |
Adds the Menudet API reference. | — |
doc/reference/menudet_accuracy.md |
Documents numerical behavior and limits. | — |
doc/reference/lazyarray.rst |
Updates LazyArray and legacy DSL guidance. | — |
doc/reference/index.rst |
Includes Menudet reference pages. | — |
doc/reference/ctable.rst |
Documents table concurrency and Menudet columns. | — |
doc/reference/additional_funcs.rst |
Documents complex and remainder functions. | — |
doc/guides/index.rst |
Adds Menudet and migration guides. | — |
doc/getting_started/installation.rst |
Fixes installation-extra formatting. | — |
doc/development/menudet_certification.md |
Documents numerical certification methodology. | — |
doc/development/index.rst |
Includes Menudet development documentation. | — |
doc/development/expression_evaluator_migration.md |
Documents the typed evaluator rollout. | — |
doc/conf.py |
Updates documentation exclusions and autodoc handling. | — |
CMakeLists.txt |
Pins and configures the native Menudet dependency and bridges. | Moderate: Add dsl_array_bridge.h to the custom command dependencies to prevent stale generated Cython output. (2 votes) |
bench/qualification/result.schema.json |
Defines qualification result structure. | — |
bench/qualification/resources.py |
Captures runner resource fingerprints. | — |
bench/qualification/requirements.txt |
Pins qualification dependencies. | — |
bench/qualification/profiles/smoke.json |
Defines the smoke qualification profile. | — |
bench/qualification/profiles/observation.json |
Defines the observation qualification profile. | — |
bench/qualification/profiles/macos-arm.json |
Defines the macOS ARM qualification profile. | — |
bench/qualification/measurement.py |
Implements bounded timing and compiler-cache isolation. | — |
bench/qualification/historical-controls.json |
Records historical performance controls. | — |
bench/qualification/freshness.py |
Adds a qualification freshness watchdog. | — |
bench/qualification/__init__.py |
Identifies the qualification package. | — |
bench/optim_tips/README.md |
Documents the Menudet Tip 11 qualification. | — |
bench/ndarray/sum-linear-idx.py |
Migrates coordinate and reduction benchmarking. | — |
bench/ndarray/ramp-comparison.py |
Compares ramp construction routes. | — |
bench/ndarray/ramp-cold.py |
Measures cold ramp latency. | — |
bench/ndarray/profile-lazyexpr-prefilter.py |
Profiles native prefilter dispatch. | — |
bench/ndarray/native-graph-preparation.py |
Compares native graph preparation paths. | Moderate: Make Git revision capture optional or resolve it independently of the current working directory. (1 vote) |
bench/ndarray/menudet-ramp.py |
Measures Menudet ramp setup and evaluation. | — |
bench/ndarray/eye-comparison.py |
Compares eye-generation routes. | — |
bench/ndarray/evaluator_migration.py |
Compares legacy and typed evaluator routes. | — |
bench/ndarray/compute_expr_udf.py |
Provides Menudet predicate benchmark kernels. | — |
bench/menudet-profile-reader.c |
Adds a profiling-only compressed reader. | — |
bench/menudet-integer-increment.py |
Benchmarks resident integer increment routes. | — |
bench/js-transpiler/README.md |
Labels JavaScript DSL benchmarks as historical. | — |
bench/chicago-taxi/string-ops-menudet-prefilter-full.json |
Records compressed string-operation results. | — |
AGENTS.md |
Documents native iteration and testing guidance. | — |
.github/workflows/wasm-tests.yml |
Expands typed evaluator and WASM qualification. | — |
.github/workflows/perf-qualification-menudet-watchdog.yml |
Adds scheduled qualification freshness checks. | — |
.github/workflows/cibuildwheels.yml |
Adds Menudet wheel and numerical qualification. | — |
.github/menudet-performance-baseline.json |
Defines the performance baseline. | — |
.github/menudet-native-ref |
Pins the experimental native revision. | — |
Review effort: Lite
…elbrot benchmarks
|
I think this is good to go. Will probably continue improving that in the future, but for a 0.1 draft, I think this is a good start. @FabianIsensee feel free to assess performance in your boxes; I have been using a Mac Mini with M4 Pro processor, so thing should (and will!) vary. |
|
Hi Francesc, thanks for merging! Here are numbers from two of our boxes: the original 300×512×512 workload from my Nov 3 comment, and the typed-evaluator micro-benchmarks from #754. Setup. Correctness. With #741, all 30 cases give NumPy's values and dtypes on both boxes. Before #741, int32 Original workload (300×512×512 float32, default chunks)
The Micro-benchmarks from #754 (200×512×512, chunks (10, 512, 512), blocks (1, 128, 512))
The 8-147x slowdowns of the int, bool and mask cases in #754's table (fe932dc) are gone. Of the 23 cases that ran before #741, 20 are as fast or faster on the Ryzen (most 0.5-0.65x), 16 on Grace. What is still slower, in case it helps:
Legacy evaluator ( legacy evaluator tables
I can share the scripts if you want to run the same cases on your Mac. AI disclosure: the measurements and this comment were prepared with Claude Code; I reviewed them. Best, |



Supersedes #735.
Menudet is a little language for portable computation on arrays and tables, with Python-like syntax and native execution through miniexpr. Validated kernels can be saved and loaded without reconstructing Python functions, while preserving defined numeric semantics and logical computation groups. Menudet 1.0 remains a draft specification.
Main changes
@blosc2.menudetauthoring with annotated or inferred dtypes, and native execution without Python reconstruction or execution fallback.deserialize="full"for legacy Python-specific recipes and reject unsupported saves before destination writes.Performance and validation
For
x + (y - 1)over 100K float64 NumPy operands on macOS arm64, with 12 configured threads and fresh NumPy outputs, preparation-cold medians from 151 samples were:Preparation/compiler caches were cleared before each cold sample; inputs were prebuilt and CPU/OS caches were not flushed. Measurements used a rebuilt native extension containing the pinned uniform-cast optimization. Compressed-output LazyExpr is excluded from this comparison.