Skip to content

I25: one lean io package; drop the legacy IOHprofiler reader - #25

Merged
jacobdenobel merged 6 commits into
mainfrom
wp/I25-io-consolidation
Nov 11, 2026
Merged

jacobdenobel merged 6 commits into
mainfrom
wp/I25-io-consolidation

Conversation

@jacobdenobel

Copy link
Copy Markdown
Contributor

WP I25: Reader consolidation: one lean io package

Branch: wp/I25-io-consolidation
Status: ready for review

Done

  • step 0: extdata golden fixture converted to format v1 with the legacy reader; legacy reader, docs and tests removed
  • steps 1-2, 6: one reader table and a shared base; archives opened in one place; readers stream (see Decisions)
  • step 3: functions split below pylint/lizard limits (two class-level suppressions), shared input_root;
    duplicate tests merged (ioh/COCO defect tests that repeated test_ioh/test_coco; COCO archive tests moved
    to one convert test of unsafe and broken archives)
  • step 4: convert outputs of 53 inputs byte-identical before and after (below)
  • step 5: line counts (below)

Line counts (step 5)

before after
src/iohinspector/io 5,023 (14 modules) 3,251 (10 modules)
of which the legacy reader 1,234 0
tests/io 3,199 2,309
src/iohinspector/convert.py 382 248
src/iohinspector/verify/_scan.py 246 241
tests/test_convert.py + tests/test_verify.py 548 576

Net against main: src +1,393 / -3,304 lines, tests (without fixtures) +130 / -893, docs +11 / -119.

Next step

Controller: push, open the PR, wait for CI and Codacy. Then delete this file.

Inventory (step 1)

Before: io/ had 5,023 lines in 14 modules. Duplicated jobs, now one implementation each:

  • opening archives: archive.open_tree (COCO's own archive reading) and convert.staged_input
    (extract, then re-link by source path) -> archive.staged, used by convert for every reader.
  • splitting a text file into runs at header lines, hashing each run's lines: ioh._split_lines,
    _coco_dat._split -> base.split_lines / DataLines.
  • UTF-8 decoding with ReaderError, first-line sniffing: two copies each -> base.read_text, base.first_line.
  • number tokens: base.NUMBER, _csv._FLOAT/_INT, convert._typed/_BOOLS, _csv.parse_*
    -> base.NUMBER/INTEGER + _csv.parse_token (tags use it too).
  • building the tables (runs rows, descriptors, sources, warnings, empty-trace schema, runs input schema):
    ioh._Builder/_result/_RUNS_INPUT, coco._Builder/_result/_RUNS_INPUT, _csv.runs_frame/_run_dtypes
    -> base.Tables (runs use RUNS_SCHEMA).
  • renaming reserved names: base.Renamer and _csv._rename -> Renamer.rename.
  • "did you mean": _csv._unknown, custom_csv._suggest -> _csv.suggest.
  • CSV source file choice and default dataset id: convert._csv_file, _csv._dataset_id_from -> _csv._csv_file
    (dataset id is required by every reader; convert defaults it).
  • reader tables: READERS + CONVERTERS -> READERS only; every reader is read(path, dataset_id, **options) -> ReadResult.
  • COCO detection: is_coco_info and _is_coco -> one _is_coco.
  • ioh text columns: second parse of every file with a text column -> extra columns kept as text per file,
    cast to float64 at the end when numeric in every file.

Decisions

  • tests/golden/fixtures/extdata is now a format v1 dataset (converted before the reader was removed).
    generate.R reads IOHanalyzer's own inst/extdata (identical to the old fixture) via system.file.
    tests/golden/test_extdata_dataset.py (was tests/io/test_legacy_golden.py) ties the dataset to the goldens.
  • A legacy .info source fails with "legacy IOHprofiler format is not supported" (raised by the COCO
    data-file check, so detection and read_coco both say it).
  • The split-file-family verify test now uses coco_old (.dat + .tdat, two dimensions).
  • Archives are opened by convert only (archive.staged), for every reader. read_coco no longer opens
    archives itself, so the COCO-only archive descriptor (outermost archive, origin path) is gone. Through
    convert it never appeared (convert staged archives before the reader), so convert outputs are unchanged.
  • Streaming (step 6): base.Tables writes each file's trace/positions frame to a temporary Arrow file;
    ReadResult.lazy_trace / lazy_positions scan them and the writer streams them. ReadResult.trace and
    .positions collect for in-memory use. The CSV reader reads its file once (was three passes).
  • API: convert_nevergrad / convert_custom_csv (write a dataset) became read_nevergrad(source, dataset_id) / read_custom_csv(source, dataset_id, mapping) (return a ReadResult), like read_ioh
    and read_coco; iohinspector.convert.convert writes. A CSV reader given a folder reads its only CSV
    file (was in convert). Unreleased API (I08/I09), so no deprecation shims.
  • --tag values use the format's number rules (parse_token, shared with CSV): 1_000 or infinity
    are no longer accepted as int/float tags.
  • COCO header key archive is no longer renamed to archive_experiment (the key was reserved for the
    removed descriptor).
  • CSV data errors are ReaderError (was FormatError); one message changed in precedence: a bad budget
    token in Nevergrad files is reported as the run field (budget: '10.5' is not an integer).
  • Memory (the bbob part of the COCO archive sample, 15 archives, 2.6 M trace rows, 2.4 M position rows):
    reading peaks at 438 MB (was 1,008 MB); the whole convert still peaks at about 1.55 GB, old and new,
    because format.writer dominates (memory_limit 256 MB per table, positions with up to 40 columns).
    The writer is outside this package; follow-up if convert must use less.
  • Byte-identical check: a scratch script converts 53 inputs (all non-legacy fixtures, CSV samples,
    archives, tags, and a 24-archive sample of the COCO data archive) before and after.

Open questions / Blocked

  • none

Work package from the IOHanalyzer rebuild plan (plan/ in IOHprofiler/ioh-web). Review and merge are done by a person.

🤖 Generated with Claude Code

jacobdenobel and others added 5 commits November 11, 2026 11:11
…rofiler reader

The golden fixture tests/golden/fixtures/extdata was converted once with the
legacy reader and is committed as a dataset; generate.R reads IOHanalyzer's own
inst/extdata. The legacy reader, its scanner kinds, docs and tests are removed.
A legacy source now fails with 'legacy IOHprofiler format is not supported'.
The split-file-family verify test uses the COCO coco_old fixture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n convert, streaming readers

READERS holds every reader (ioh, coco, nevergrad-csv, custom-csv) with one
interface; CONVERTERS is gone. base.Tables collects runs, descriptors, sources
and warnings and spills each file's trace to a temporary Arrow file, so readers
hold one source file at a time; base.split_lines splits ioh and COCO data files.
archive.staged opens archives for every reader in convert. The CSV reader reads
its file once. Convert outputs of 53 inputs are byte-identical to before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ests

Split ioh and CSV functions below the pylint and lizard limits, share
input_root, extract archive members without open handles, and fold the
reader defect tests that repeated test_ioh and test_coco into them. COCO
archive tests move to one convert test of unsafe and broken archives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…counts

Convert outputs of all 53 inputs are byte-identical to main. io/ goes from
5,023 to 3,251 lines, tests/io from 3,199 to 2,309.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics -35 complexity · -21 duplication

Metric Results
Complexity -35
Duplication -21

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jacobdenobel
jacobdenobel marked this pull request as ready for review November 11, 2026 11:18
@jacobdenobel
jacobdenobel merged commit 1f44cfe into main Nov 11, 2026
17 checks passed
@jacobdenobel
jacobdenobel deleted the wp/I25-io-consolidation branch November 11, 2026 11:19
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.

1 participant