Lightning-AI / Lightning-AI/pytorch-lightning

`CombinedLoader(max_size_cycle)` stops immediately when one iterable is empty

Open
#21,893 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ver: 2.7.x
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.