Skip to content

feat(mohu-io): implement Arrow IPC file and stream read/write - #264

Open
madhu-mitha-e wants to merge 4 commits into
mohu-org:mainfrom
madhu-mitha-e:add-arrow-ipc
Open

feat(mohu-io): implement Arrow IPC file and stream read/write#264
madhu-mitha-e wants to merge 4 commits into
mohu-org:mainfrom
madhu-mitha-e:add-arrow-ipc

Conversation

@madhu-mitha-e

@madhu-mitha-e madhu-mitha-e commented Jun 1, 2026

Copy link
Copy Markdown

Closes #35

What

Implement Arrow IPC file and streaming format support in crates/mohu-io/src/arrow.rs:

  • read_ipc_file — reads Arrow IPC file format (random-access, seekable)
  • read_ipc_stream — reads Arrow IPC streaming format (sequential, no footer)
  • write_ipc_file — writes buffers to Arrow IPC file format
  • write_ipc_stream — writes buffers to Arrow IPC streaming format

Why

Without streaming IPC, mohu cannot participate in zero-copy Arrow pipelines where producers and consumers live in different processes or machines (Polars pipe, DuckDB query results, Arrow Flight protocol). arrow = "54" was already in workspace deps.

How

  • Used arrow::ipc::reader::{FileReader, StreamReader} and arrow::ipc::writer::{FileWriter, StreamWriter}
  • Each Buffer becomes one column in a RecordBatch
  • Supports all numeric dtypes: i8/i16/i32/i64, u8/u16/u32/u64, f32/f64
  • Added features = ["ipc"] to mohu-io/Cargo.toml

Checklist

  • cargo test --workspace passes
  • cargo clippy --workspace -- -D warnings passes
  • cargo fmt --all applied
  • CHANGELOG.md updated
  • Benchmarks added or updated

Summary by CodeRabbit

New Features

  • Added Arrow IPC (Inter-Process Communication) serialization support for reading and writing Arrow IPC files and streams
  • Enables seamless data format conversion with robust error handling for batch operations

Closes mohu-org#35

Signed-off-by: madhu-mitha-e <e.madhumitha06052006@gmail.com>
@madhu-mitha-e
madhu-mitha-e requested a review from Bbn08 as a code owner June 1, 2026 05:45
@github-actions
github-actions Bot requested a review from mugiwaraluffy56 June 1, 2026 05:45
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@madhu-mitha-e, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 57 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 18694bd0-8052-476d-8bbd-77fc60452435

📥 Commits

Reviewing files that changed from the base of the PR and between d1020ce and 52a4402.

📒 Files selected for processing (10)
  • crates/mohu-fft/src/freq helpers nd norm plan real transform.rs
  • crates/mohu-index/src/boolean fancy gather slice take where_op.rs
  • crates/mohu-io/Cargo.toml
  • crates/mohu-masked/src/arith array compress fill io mask_ops reduce.rs
  • crates/mohu-random/src/continuous discrete entropy generator multivariate permutation seeding.rs
  • crates/mohu-simd/src/arith bitwise cast cmp copy fill fma math reduce detect.rs
  • crates/mohu-sparse/src/arith bsr coo csc csr convert dia linalg slice spmm spmv.rs
  • crates/mohu-special/src/beta bessel erf expint gamma misc stats_fn trig.rs
  • crates/mohu-testing/src/approx assert dtype fixtures gen perf.rs
  • crates/mohu-ufunc/src/broadcast dispatch loop_impl macros methods reduce resolver traits.rs
📝 Walkthrough

Walkthrough

This PR adds Arrow IPC (Inter-Process Communication) support to mohu by introducing serialization and deserialization functions for both file and streaming formats. The implementation enables bidirectional conversions between mohu Buffers and Arrow arrays, with proper error handling and comprehensive unit tests covering multiple data types.

Changes

Arrow IPC file and stream support

Layer / File(s) Summary
Workspace dependency configuration
crates/mohu-io/Cargo.toml
Dependencies use consistent workspace = true style; the arrow crate gains the ipc feature flag to enable IPC reader and writer APIs.
Type conversions and batch handling
crates/mohu-io/src/arrow.rs (module setup, conversions)
Module documentation, imports, and helper functions implement bidirectional conversions: mohu DType ↔ Arrow DataType, mohu Buffer ↔ Arrow ArrayRef, and Vec<Buffer> ↔ Arrow RecordBatch, with error mapping for unsupported types and schema construction failures.
Public IPC read/write functions and tests
crates/mohu-io/src/arrow.rs (public API)
Four public functions (read_ipc_file, read_ipc_stream, write_ipc_file, write_ipc_stream) construct Arrow IPC readers/writers, iterate record batches, and delegate error handling to conversion helpers; unit tests verify round-trip correctness for f32, f64, i32 dtypes and multi-buffer stream scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • #150: Both target the same module and implement Arrow IPC and Buffer↔Arrow conversions for zero-copy interoperability with Arrow pipelines.

Poem

🐰 Whiskers twitching with glee,
Buffers hop through Arrow's IPC stream,
File or flow—both dreams realized,
Zero-copy hops to another machine! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature: implementing Arrow IPC file and stream read/write functions in mohu-io, which is the primary change in the PR.
Linked Issues check ✅ Passed The PR implements all required objectives from issue #35: exposing read_ipc_file, read_ipc_stream, write_ipc_file, and write_ipc_stream functions with proper Buffer-to-ArrayRef conversions for both file and streaming IPC formats.
Out of Scope Changes check ✅ Passed All changes are in scope: Cargo.toml updates add the required IPC feature flag, and arrow.rs implements exactly the four IPC functions specified in issue #35 with no extraneous modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

PR Check Summary

Item Value
Branch add-arrow-ipc
Changed crates crates/mohu-io
Files changed 2

CI will run: build, test, clippy, fmt, cargo-deny, DCO, semver.
Reviewer assigned from CODEOWNERS.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/mohu-io/src/arrow.rs`:
- Around line 318-329: Tests compare floating-point slices using assert_eq!
which is brittle; replace those exact-equality assertions with mohutesting's
approximate checker by importing mohutesting::approx::assert_allclose and
changing the assert_eq! calls in the float tests (e.g.,
round_trip_ipc_stream_f32, round_trip_ipc_stream_f64 and the other float slice
assertion around line 353 that checks result[i].as_slice::<f32|f64>()) to use
assert_allclose(result[..].as_slice::<f32|f64>().unwrap(), &[...] ) so the tests
use approximate float comparison when validating
read_ipc_stream/write_ipc_stream and Buffer round-trip values.
- Around line 181-183: Wrap the Arrow operation failures with a context
breadcrumb before converting to MohuError: for each site (e.g.,
RecordBatch::try_new -> currently mapped to MohuError::ArrowSchema, and the
various ArrowIpc reads/writes mapped to MohuError::ArrowIpc) insert a
.with_context(|| "attempting to <brief op description>") or .context("attempting
to <brief op description>") call on the Result (for example, before the final
.map_err(|e| MohuError::ArrowSchema(e.to_string())) for RecordBatch::try_new add
.with_context(|| "creating RecordBatch via RecordBatch::try_new") so the error
carries what was being attempted, and do the same for each ArrowIpc site
(reads/writes) describing the specific IPC operation being attempted before
mapping to MohuError::ArrowIpc.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d0eac1c-f866-470d-908c-65c32106f479

📥 Commits

Reviewing files that changed from the base of the PR and between 0afc975 and d1020ce.

📒 Files selected for processing (2)
  • crates/mohu-io/Cargo.toml
  • crates/mohu-io/src/arrow.rs

Comment thread crates/mohu-io/src/arrow.rs Outdated
Comment on lines +181 to +183
RecordBatch::try_new(schema, arrays)
.map_err(|e| MohuError::ArrowSchema(e.to_string()))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify all direct Arrow IPC/schema map_err conversions lacking context in this file.
rg -nP 'map_err\(\|e\|\s*MohuError::Arrow(Ipc|Schema)\(e\.to_string\(\)\)\)' crates/mohu-io/src/arrow.rs

Repository: mohu-org/mohu

Length of output: 785


Add operation .context(...)/.with_context(...) to Arrow error conversions in crates/mohu-io/src/arrow.rs.

The file contains multiple direct map_err(|e| MohuError::ArrowSchema/ArrowIpc(e.to_string())) conversions without an operation breadcrumb (e.g., RecordBatch::try_new at line 182, and ArrowIpc sites at lines 208, 212, 231, 235, 259, 263, 267, 290, 294, 298). Wrap these failures with .context("what was being attempted") (or .with_context(|| ...)) so errors include the attempted Arrow IPC/schema operation.

Example (current state)
RecordBatch::try_new(schema, arrays)
    .map_err(|e| MohuError::ArrowSchema(e.to_string()))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/mohu-io/src/arrow.rs` around lines 181 - 183, Wrap the Arrow operation
failures with a context breadcrumb before converting to MohuError: for each site
(e.g., RecordBatch::try_new -> currently mapped to MohuError::ArrowSchema, and
the various ArrowIpc reads/writes mapped to MohuError::ArrowIpc) insert a
.with_context(|| "attempting to <brief op description>") or .context("attempting
to <brief op description>") call on the Result (for example, before the final
.map_err(|e| MohuError::ArrowSchema(e.to_string())) for RecordBatch::try_new add
.with_context(|| "creating RecordBatch via RecordBatch::try_new") so the error
carries what was being attempted, and do the same for each ArrowIpc site
(reads/writes) describing the specific IPC operation being attempted before
mapping to MohuError::ArrowIpc.

Comment thread crates/mohu-io/src/arrow.rs Outdated
Comment on lines +318 to +329
assert_eq!(result[0].as_slice::<f32>().unwrap(), &[1.0_f32, 2.0, 3.0, 4.0]);
}

#[test]
fn round_trip_ipc_stream_f64() {
let buf = Buffer::from_slice(&[10.0_f64, 20.0, 30.0]).unwrap();
let mut bytes = Vec::new();
write_ipc_stream(&mut bytes, &[buf.clone()]).unwrap();

let result = read_ipc_stream(Cursor::new(bytes)).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].as_slice::<f64>().unwrap(), &[10.0_f64, 20.0, 30.0]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace float assert_eq! with assert_allclose.

Line 318, Line 329, and Line 353 compare float slices using exact equality. Please switch these to mohu_testing::approx::assert_allclose to satisfy test policy and avoid brittle comparisons.

Suggested test update
 #[cfg(test)]
 mod tests {
     use super::*;
+    use mohu_testing::approx::assert_allclose;
     use std::io::Cursor;
@@
-        assert_eq!(result[0].as_slice::<f32>().unwrap(), &[1.0_f32, 2.0, 3.0, 4.0]);
+        assert_allclose(result[0].as_slice::<f32>().unwrap(), &[1.0_f32, 2.0, 3.0, 4.0], 1e-6, 1e-6);
@@
-        assert_eq!(result[0].as_slice::<f64>().unwrap(), &[10.0_f64, 20.0, 30.0]);
+        assert_allclose(result[0].as_slice::<f64>().unwrap(), &[10.0_f64, 20.0, 30.0], 1e-12, 1e-12);
@@
-        assert_eq!(result[1].as_slice::<f64>().unwrap(), &[4.0_f64, 5.0, 6.0]);
+        assert_allclose(result[1].as_slice::<f64>().unwrap(), &[4.0_f64, 5.0, 6.0], 1e-12, 1e-12);

As per coding guidelines, "Float comparison must use mohu-testing::approx::assert_allclose — never == on floats."

Also applies to: 353-353

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/mohu-io/src/arrow.rs` around lines 318 - 329, Tests compare
floating-point slices using assert_eq! which is brittle; replace those
exact-equality assertions with mohutesting's approximate checker by importing
mohutesting::approx::assert_allclose and changing the assert_eq! calls in the
float tests (e.g., round_trip_ipc_stream_f32, round_trip_ipc_stream_f64 and the
other float slice assertion around line 353 that checks
result[i].as_slice::<f32|f64>()) to use
assert_allclose(result[..].as_slice::<f32|f64>().unwrap(), &[...] ) so the tests
use approximate float comparison when validating
read_ipc_stream/write_ipc_stream and Buffer round-trip values.

Signed-off-by: madhu-mitha-e <e.madhumitha06052006@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing: Arrow IPC streaming format support in mohu-io

1 participant