Skip to content

Give DataLoader a proper eltype - #253

Merged
CarloLucibello merged 1 commit into
mainfrom
cl/dataloader-eltype
Jul 31, 2026
Merged

Give DataLoader a proper eltype#253
CarloLucibello merged 1 commit into
mainfrom
cl/dataloader-eltype

Conversation

@CarloLucibello

Copy link
Copy Markdown
Member

Fixes the eltype(DataLoader) items of #227 (section A).

Problem

eltype(::DataLoader) returned Any — no eltype method was defined. The previous attempt (commented out in the source) rebuilt a BatchView without the loader's collate, so it computed an eltype inconsistent with the actual batches and broke collect.

Change

A DataLoader iterates the batches of its wrapped BatchView/ObsView (d._data), which is built with the loader's real collate. So its element type is exactly eltype(d._data):

Base.eltype(::Type{<:DataLoader{T}}) where {T} = eltype(T)

BatchView's eltype is made type-based so it composes with the above.

IteratorEltype is deliberately kept as EltypeUnknown(): for containers whose per-batch getobs is not fully inferable (a Dict with heterogeneous value types), the declared eltype is only a supertype of the real batches. Keeping EltypeUnknown lets collect narrow the element type from the batches themselves — so collect's behaviour (and its existing tests) are unchanged, while eltype(d) now returns a useful type.

Tests

Un-breaks the eltype(DataLoader) cases in test/dataloader.jl for arrays, tuples, named tuples, and homogeneous dicts (changed @test_broken@test). The full dataloader (394 pass, 1 broken) and batchview (585 pass) testsets pass locally.

The one remaining @test_broken is the heterogeneous Dict case (Matrix + Vector values): its eltype needs getobs(::Dict) to be type-inferred, which is #227 item B and lives in MLCore.jl. This PR does not close #227 (a tracking issue).

🤖 Generated with Claude Code

`eltype(::DataLoader)` returned `Any` because no `eltype` method was
defined (the previous attempt was commented out — it rebuilt a
`BatchView` *without* the loader's `collate`, producing an eltype
inconsistent with the actual batches and breaking `collect`).

A `DataLoader` iterates the batches of its wrapped `BatchView`/`ObsView`
(`d._data`), so its eltype is exactly `eltype(d._data)`, computed from
the real `collate`. Define `eltype(::Type{<:DataLoader{T}}) = eltype(T)`
(and make `BatchView`'s `eltype` type-based so it composes).

`IteratorEltype` is kept as `EltypeUnknown`: for containers whose
per-batch `getobs` is not fully inferable (e.g. a `Dict` with
heterogeneous value types) the declared eltype is only a supertype of
the real batches, so `collect` is left to narrow the element type from
the batches rather than pre-committing to the wider type. This keeps
`collect` behaviour (and its tests) unchanged while fixing `eltype`.

Un-breaks the `eltype(DataLoader)` cases in test/dataloader.jl for
arrays, tuples, named tuples and homogeneous dicts. The heterogeneous
`Dict` case stays `@test_broken`: it needs `getobs(::Dict)` to be
inferable (#227 item B, lives in MLCore).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CarloLucibello
CarloLucibello merged commit d4be88c into main Jul 31, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking: untracked TODOs and broken tests in src/ and tests

1 participant