Lightning-AI / Lightning-AI/pytorch-lightning
`CombinedLoader(max_size_cycle)` stops immediately when one iterable is empty
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 31.4k
- Forks
- 3.8k
- Avg merge
- 6d 7h
- Merged PRs (30d)
- 6
Description
### Bug description
`CombinedLoader(..., mode=max_size_cycle)` stops immediately when one source is empty, even when another source has batches. This contradicts the mode's documented behavior of stopping after the longest iterable is exhausted and also makes `len(combined_loader)` disagree with the number of yielded batches.
On current `master` (`fcef404516264798b6c582ef556eaa17e5c29bfb`), the example below reports length 3 but yields no batches.
### What version are you seeing the problem on?
master
### How to reproduce the bug
```python
from lightning.pytorch.utilities.combined_loader import CombinedLoader
loader = CombinedLoader([[], [1, 2, 3]], mode=max_size_cycle)
iter(loader)
print(length:, len(loader))
print(batches:, list(loader))
```
Actual output:
```text
length: 3
batches: []
```
The first source raises `StopIteration`, so `_MaxSizeCycle` resets it. Because it is genuinely empty, `next()` raises again, and this second exception escapes from the combined iterator before the non-empty source can contribute.
Expected: the combined iterator should not silently discard all batches from the longest source. One compatible behavior would be to retain `None` for an empty source while yielding the non-empty source:
```text
[([None, 1], 0, 0), ([None, 2], 1, 0), ([None, 3], 2, 0)]
```
Alternatively, if empty inputs are invalid for `max_size_cycle`, construction or iteration should reject them explicitly instead of reporting a positive length and then yielding zero batches. I have a focused local regression and a minimal implementation of the first behavior, but am holding the PR for agreement on the contract.
### Environment
- Lightning: source checkout at `fcef404516264798b6c582ef556eaa17e5c29bfb`
- PyTorch: 2.13.0+cpu
- Python: 3.11.9
- OS: Windows 11
### More info
The existing mixed-empty fetcher test already expects an empty/non-empty pair not to be considered done for modes other than `min_size`, but it does not consume the iterator and therefore misses this termination path.
Prepared with assistance from OpenAI Codex; the reproduction, history/duplicate search, local regression, and proposed patch were verified locally on CPU.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lightning.pytorch.utilities.combined_loader at CombinedLoader and _MaxSizeCycle, then inspect the existing mixed-empty fetcher test. Reproduce the empty/non-empty case and add or run a focused regression that consumes the iterator. Done means max_size_cycle has a decided, tested behavior for empty inputs and len(loader) matches the batches yielded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- data, machine-learning
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100