Skip to content

RNTuple: I/O rule with multiple source members assigns every target the first source value of its type #23146

Description

@olantwin

Check duplicate issues.

  • Checked for duplicates

Description

When an I/O customization rule has more than one source member, RNTuple applies it incorrectly: every target member receives the value of the first source member of its type, and that value isn't exact for floating point (1.5 read back as 1.5000000000000002). A rule with a single source member works as expected. The same dictionary reads the equivalent TTree data correctly, and the generated dictionary wrapper seems to have correct per-member offset_Onfile_* entries, so the onfile staging offsets appear to collapse per member type on the RNTuple side.

I wouldn't exclude user error, I found it quite hard to find documentation on the I/O customization rules.

Real-world occurrence: ShipSoft/data-model#25
(6 structs, ~30 renamed members; TTree reads correctly, RNTuple collapses).

Reproducer

(Full reproduction script: reproduce.sh bash reproduce.sh (self-contained, builds old/new dictionaries and computes the checksum at run time))

Renaming members of a plain unversioned struct:

// on disk: struct Hit { int a; int b; double x; double y; };  a=1 b=2 x=1.5 y=2.5
#pragma read sourceClass="Hit" targetClass="Hit" checksum="[<old>]" \
  source="int a; int b; double x; double y" target="a_r,b_r,x_r,y_r" \
  code="{ a_r = onfile.a; b_r = onfile.b; x_r = onfile.x; y_r = onfile.y; }"

Expected behaviour

Each onfile.<member> refers to that member's staged on-disk value, as in the TTree case.

Actual behaviour

First value of a given type is reused for all following (and for floating point numbers does not seem to be exact):

a_r  want 1    got 1                      ok
b_r  want 2    got 1                      WRONG
x_r  want 1.5  got 1.5000000000000002     WRONG
y_r  want 2.5  got 1.5000000000000002     WRONG

ROOT version

  ------------------------------------------------------------------
  | Welcome to ROOT 6.40.02                        https://root.cern |
  | (c) 1995-2025, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for linuxx8664gcc on Jul 13 2026, 09:13:28                 |
  | From tags/6-40-02@6-40-02                                        |
  | With  std202302                                                  |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

Installation method

conda-forge, root_base 6.40.02 cxx23_hbf4e8c7_2, linux-64

Operating system

Linux (NixOS)

Additional context

Maybe related to #17713 ("fix I/O rule handling for unversioned classes"). Maybe also related to a TTree unversioned-class lookup problem: #14491.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugexperimentAffects an experiment / reported by its software & computimng expertsin:RNTuple

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions