Follow-up from the searchAny work (#1680). searchAny currently searches string and integer columns (numeric-term-gated), matching the streamgl-viz inspector's shouldSearch for those dtypes. It does not search float or date columns, which the inspector does (numeric-term-gated). This issue tracks closing that gap.
Reference (ground truth)
~/Work/graphistry/apps/core/viz/src/worker/services/dataframe/sortAndFilterRowsByQuery.js + src/formatters/defaultFormat.js. The inspector searches number/integer/date columns (iff the term is numeric) via defaultFormat: fractional floats → sprintf('%.4f'); whole numbers → raw String(); dates → moment MMM D YYYY, h:mm:ss a z. Full analysis: plans/viz-filter-pipeline/research/searchany-inspector-parity.md.
Float — proven native cross-engine path (dgx-probed, NO host-bridge, NO broad-NIE)
The naive astype(str) diverges in the exponent regime (1e16 → '1e16' vs '1e+16') — the original reason floats were excluded. The fix:
round(4) then fixed-point decimal render: cudf .astype(Decimal128(scale=4)).astype(str) ≡ polars .cast(Decimal(scale=4)).cast(str) exactly (vectorized, no exponent, GPU-native).
- Apply the same
round(4)+decimal convention on pandas too (not its f\"{v:.4f}\", which uses true float bits and diverges at half-boundaries like 0.12345→0.1235 vs 0.1234) so all four engines agree.
Implementation sketch (on graphistry/compute/gfql/search_any.py + lazy/engine/polars/search.py)
_is_float_dtype + include float in the auto gate for numeric terms.
_canonical_float_str(series) = round(4) → fixed-4-decimal string, engine-aware (pandas/cudf/polars Decimal).
- Wire into
search_any_mask (kernel) + search_any_polars.
- Remove the now-unneeded exclusions: the cuDF explicit-float NIE (
search_any.py) and the polars _stringify_ok float-exclusion (search.py).
- Verify with a dgx rounding fuzzer — cross-engine
round(4) half-rounding consistency is the one residual risk (stringification-parity class); pandas is the oracle, so either canonicalize to agreement or pin the boundary behavior.
Date (lower priority, likely a separate slice)
Inspector formats dates via moment MMM D YYYY, h:mm:ss a z; exact cross-engine replication (tz/locale) is hard → candidate honest-NIE + doc.
Test hooks
test_engine_polars_conformance_matrix.py::test_search_any_* + test_viz_pipeline_conformance.py trick matrix — add float-search pins (fractional, whole, negative, large-magnitude, null) 4-engine parity-or-NIE.
Follow-up from the searchAny work (#1680). searchAny currently searches string and integer columns (numeric-term-gated), matching the streamgl-viz inspector's
shouldSearchfor those dtypes. It does not search float or date columns, which the inspector does (numeric-term-gated). This issue tracks closing that gap.Reference (ground truth)
~/Work/graphistry/apps/core/viz/src/worker/services/dataframe/sortAndFilterRowsByQuery.js+src/formatters/defaultFormat.js. The inspector searches number/integer/date columns (iff the term is numeric) viadefaultFormat: fractional floats →sprintf('%.4f'); whole numbers → rawString(); dates → momentMMM D YYYY, h:mm:ss a z. Full analysis:plans/viz-filter-pipeline/research/searchany-inspector-parity.md.Float — proven native cross-engine path (dgx-probed, NO host-bridge, NO broad-NIE)
The naive
astype(str)diverges in the exponent regime (1e16→'1e16'vs'1e+16') — the original reason floats were excluded. The fix:round(4)then fixed-point decimal render:cudf .astype(Decimal128(scale=4)).astype(str)≡polars .cast(Decimal(scale=4)).cast(str)exactly (vectorized, no exponent, GPU-native).round(4)+decimalconvention on pandas too (not itsf\"{v:.4f}\", which uses true float bits and diverges at half-boundaries like0.12345→0.1235vs0.1234) so all four engines agree.Implementation sketch (on
graphistry/compute/gfql/search_any.py+lazy/engine/polars/search.py)_is_float_dtype+ include float in the auto gate for numeric terms._canonical_float_str(series)=round(4)→ fixed-4-decimal string, engine-aware (pandas/cudf/polars Decimal).search_any_mask(kernel) +search_any_polars.search_any.py) and the polars_stringify_okfloat-exclusion (search.py).round(4)half-rounding consistency is the one residual risk (stringification-parity class); pandas is the oracle, so either canonicalize to agreement or pin the boundary behavior.Date (lower priority, likely a separate slice)
Inspector formats dates via moment
MMM D YYYY, h:mm:ss a z; exact cross-engine replication (tz/locale) is hard → candidate honest-NIE + doc.Test hooks
test_engine_polars_conformance_matrix.py::test_search_any_*+test_viz_pipeline_conformance.pytrick matrix — add float-search pins (fractional, whole, negative, large-magnitude, null) 4-engine parity-or-NIE.