Implement native adjacent byte range coalescing in cat_ranges - #1024
Implement native adjacent byte range coalescing in cat_ranges#1024yuxin00j wants to merge 26 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements _cat_ranges and cat_ranges in both GCSFileSystem and ExtendedGcsFileSystem to fetch multiple byte ranges efficiently, supporting range coalescing and leveraging AsyncMultiRangeDownloader for zonal buckets. It also adds comprehensive unit tests. The review feedback suggests extracting the duplicated input validation logic into a shared helper and removing an unnecessary fallback default value of 64 for the batch size.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1024 +/- ##
==========================================
+ Coverage 90.10% 90.26% +0.15%
==========================================
Files 16 16
Lines 3679 3902 +223
==========================================
+ Hits 3315 3522 +207
- Misses 364 380 +16 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
/gcbrun |
|
/gcbrun |
…m.cat_ranges Optimizes Fsspec DCP payload downloads by heavily coalescing contiguous/adjacent data chunks into singular block reads natively within _cat_ranges, preventing multi-shard GET amplification. Support includes zero-copy memoryview splicing.
…o _coalesce_ranges helper
…extended_gcsfs.py
- Fix TypeError on unbounded ranges in _coalesce_ranges when end=None - Fix batch exception scoping in ExtendedGcsFileSystem._cat_ranges - Support contiguous range coalescing when max_gap=0 - Lazily query object metadata only when unbounded ranges are present - Execute zonal and non-zonal bucket fetches concurrently - Add unit tests for middle unbounded ranges, empty inputs, mixed buckets, and partial batch failures
… lifecycle - Ensure mrd_pool is properly closed in try...finally block in _fetch_zonal_file - Move _process_limits_to_offset_and_length to GCSFileSystem and normalize limits before coalescing - Return empty bytes directly for zero-length slices without issuing I/O - Support batch_size=-1 for unchunked execution and cap effective_batch_size at 1000 - Bound concurrent zonal file download jobs with asyncio.Semaphore - Add unit tests for pool cleanup, normalization, and batch_size=-1
…ne fast path, and return types - Support tuple of paths in _validate_cat_ranges_input - Handle s is None (offset 0) in fast path without triggering unhandled _info calls - Honor caller batch_size for outer file_concurrency semaphore in ExtendedGcsFileSystem - Ensure bytes return type in ExtendedGcsFileSystem when max_gap is None - Add unit tests for tuple paths, start=None lazy info and error handling, and batch_size semaphore
…_size helpers - Centralize per-file range limit normalization, fast-path, and zero-length slice handling in GCSFileSystem._normalize_file_ranges - Eliminate duplicate normalization block in ExtendedGcsFileSystem._cat_ranges by reusing inherited _normalize_file_ranges with get_size_fn - Centralize bounded batch size computation in _compute_effective_batch_size - Add unit test for _normalize_file_ranges helper
- Merge tuple paths into test_gcsfs_cat_ranges_validation - Merge start=None normalization into test_gcsfs_cat_ranges_normalization - Merge start=None error handling into test_gcsfs_cat_ranges_error_handling - Merge zonal start=None lazy info into test_extended_gcsfs_cat_ranges_zonal_lazy_info - Merge zonal pool error handling into test_extended_gcsfs_cat_ranges_zonal_error_handling
9bf4ea9 to
799cdd1
Compare
fa21041 to
495e363
Compare
495e363 to
ef9f758
Compare
…azy info optimization
…in cat_ranges for Zonal buckets
…xtendedGcsFileSystem._cat_ranges
… and non-zonal requests
Summary
This PR implements native byte range coalescing for
GCSFileSystem.cat_rangesandExtendedGcsFileSystem.cat_rangesto optimize chunk-based workload downloads (such as PyTorch Distributed Checkpoint / DCP payload loading).Adjacent and near-adjacent byte requests on the same object are coalesced into singular block reads natively, reducing request amplification and leveraging zero-copy
memoryviewslicing.Key Changes
Core Coalescing & Unpacking Helpers (
gcsfs/core.py):_coalesce_ranges: Groups and merges overlapping, contiguous (max_gap=0), and near-contiguous (gap <= max_gap) range requests for a given file, generating relative slice offsets mapped to caller indices._merge_file_ranges&_is_coalesce_enabled: Unifies conditional coalescing vs 1-to-1 range mapping._unpack_range_results: Safely populates caller results withbyteswhen coalescing is inactive (max_gap is Noneor< 0) ormemoryviewslices when active (max_gap >= 0).end=None), empty inputs, scalar broadcasting, and separate non-overlapping clusters.GCSFileSystem._cat_ranges(gcsfs/core.py):asyn._run_coros_in_chunksrespectingbatch_size.startsandends.on_error="return"andon_error="raise"error modes.ExtendedGcsFileSystem._cat_ranges(gcsfs/extended_gcsfs.py):RAPID) buckets viaAsyncMultiRangeDownloader(MRD).pool_size = min(max_batches, max(1, concurrency))to stream multiple batches in parallel across pooled MRDs, avoiding head-of-line blocking and single-stream throughput bottlenecks on large multi-gigabyte transfers.asyn._run_coros_in_chunks, providing global concurrency throttling._info()) only when unbounded ranges (end=Noneor negative offsets) require file size resolution.MRDPoolinstances are cleanly closed infinallyblocks upon completion or failure.Testing
gcsfs/tests/test_core.py:_coalesce_rangescovering single, contiguous, overlapping, unordered, unbounded, and multi-cluster cases.max_gap=0), multi-file coalescing, and error modes.gcsfs/tests/test_extended_gcsfs.py:MockMRD, mixed zonal/non-zonal paths in a single call, partial batch failure preservation, and lazy metadata validation._run_coros_in_chunks, return types (bytesvsmemoryview), and pool cleanup upon error.