Summary
The marrow hash-aggregate GroupBy kernel accumulates sum, min, and max as float64 internally, even for int64 value columns. The result is then cast back to Int64. For values exceeding 2^53 (~9.0e15), this round-trip through float64 loses precision that the native int64 path preserves.
Background
Introduced by the marrow GroupBy integration (#583). The marrow kernel's AggregateFunction stores running values as float64 (see vendor/marrow/marrow/kernels/groupby.mojo, AggregateFunction.__init__). The bison _marrow_agg helper casts the float64 result back to Int64 via Int64(Float64(scalar)).
The native (non-marrow) fallback path uses Column.sum_int64(), Column.min_int64(), Column.max_int64() which accumulate natively in Int64 and preserve full precision.
Impact
Low in practice — most real-world groupby aggregations involve values well within float64's exact integer range. But it is a subtle correctness difference between the marrow and native paths.
Possible fixes
- Document the limitation — note in code comments that the marrow path has reduced precision for very large integers
- Add an int64 accumulator path to marrow's AggregateFunction — upstream change in marrow to use
int64 state when the input dtype is int64 and the aggregation is sum/min/max
- Skip marrow path for int64 columns — only use marrow for float64 value columns, keep native path for int64 (loses half the perf benefit)
Option 2 is the best long-term fix but requires changes in the marrow library.
Related
Summary
The marrow hash-aggregate GroupBy kernel accumulates
sum,min, andmaxasfloat64internally, even forint64value columns. The result is then cast back toInt64. For values exceeding 2^53 (~9.0e15), this round-trip throughfloat64loses precision that the nativeint64path preserves.Background
Introduced by the marrow GroupBy integration (#583). The marrow kernel's
AggregateFunctionstores running values asfloat64(seevendor/marrow/marrow/kernels/groupby.mojo,AggregateFunction.__init__). The bison_marrow_agghelper casts the float64 result back toInt64viaInt64(Float64(scalar)).The native (non-marrow) fallback path uses
Column.sum_int64(),Column.min_int64(),Column.max_int64()which accumulate natively inInt64and preserve full precision.Impact
Low in practice — most real-world groupby aggregations involve values well within float64's exact integer range. But it is a subtle correctness difference between the marrow and native paths.
Possible fixes
int64state when the input dtype isint64and the aggregation issum/min/maxOption 2 is the best long-term fix but requires changes in the marrow library.
Related