Skip to content

[ntuple] detect runtime member streamers via TRealData#21281

Open
JasMehta08 wants to merge 1 commit intoroot-project:masterfrom
JasMehta08:detect-custom-streamers
Open

[ntuple] detect runtime member streamers via TRealData#21281
JasMehta08 wants to merge 1 commit intoroot-project:masterfrom
JasMehta08:detect-custom-streamers

Conversation

@JasMehta08
Copy link
Contributor

This Pull request:

Changes or fixes:

When a class member has a custom streamer set at runtime via TClass::SetMemberStreamer() or TClass::AdoptMemberStreamer(),

RFieldBase::Create() now detects this by iterating TRealData and checking TRealData::GetStreamer().

If any member has a custom streamer, an RStreamerField is used instead of RClassField, preventing the class from being split into columns which would bypass the member's custom serialization logic.

Checklist:

  • tested changes locally

This PR fixes #20448

Copy link
Contributor

@jblomer jblomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I think that automatically using a streamer field is undesired. Custom member streamers are a rare case and for now, I think we should simply detect this case in RClassField and fail with an error message.

We would also need a test for this.

@JasMehta08 JasMehta08 force-pushed the detect-custom-streamers branch from c4e0f67 to 695bd21 Compare March 4, 2026 08:34
@JasMehta08
Copy link
Contributor Author

@jblomer

I have updated the PR,

  • I moved the check to RFieldMeta.cxx to detect if any member has
    custom streamer present, and to throw error if it is present.
  • I have also added a test for the same.

Please let me know if I should change anything.

Thanks!

@JasMehta08 JasMehta08 requested a review from jblomer March 4, 2026 08:43
Copy link
Contributor

@jblomer jblomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks quite close to being merge ready!

// Detect custom streamers set on individual members at runtime via
// TClass::SetMemberStreamer() or TClass::AdoptMemberStreamer().
// These are stored in TRealData and are not caught by CanSplit().
if (auto realDataList = fClass->GetListOfRealData()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the following snippet to iterate the real data:
for (auto realMember : ROOT::Detail::TRangeStaticCast<TRealData>(*fClass->GetListOfRealData())) {

@@ -101,4 +101,11 @@ struct TemperatureKelvin {
float fValue;
};

// Test class for runtime member streamers set via TClass::SetMemberStreamer
struct MemberStreamerContainer {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct MemberStreamerContainer {
struct MemberWithCustomStreamer {

@@ -101,4 +101,11 @@ struct TemperatureKelvin {
float fValue;
};

// Test class for runtime member streamers set via TClass::SetMemberStreamer
struct MemberStreamerContainer {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class should go in CustomStruct.hxx

@@ -27,4 +27,6 @@
#pragma link C++ options = rntupleStreamerMode(true) class TemperatureCelsius + ;
#pragma link C++ options = rntupleStreamerMode(true) class TemperatureKelvin + ;

#pragma link C++ class MemberStreamerContainer + ;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#pragma link C++ class MemberStreamerContainer + ;
#pragma link C++ class MemberStreamerContainer+;

b << *val;
}
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps also check that "CanSplit" is still true

@@ -407,3 +407,26 @@ TEST(RField, StreamerClassMismatch)
false /* matchFullMessage */);
reader->LoadEntry(0);
}

// Detect custom streamers set on class members at runtime via TClass::SetMemberStreamer.
TEST(RField, MemberCustomStreamer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test should go in rfield_class.cxx

@JasMehta08 JasMehta08 force-pushed the detect-custom-streamers branch from 695bd21 to b1324a7 Compare March 4, 2026 18:46
@JasMehta08
Copy link
Contributor Author

JasMehta08 commented Mar 4, 2026

@jblomer

i have updated the code,

  • i used the snippet provided by you.
  • also added the Cansplit() test
  • and move the test to rfield_class.cxx

Thanks!

@JasMehta08 JasMehta08 force-pushed the detect-custom-streamers branch from b1324a7 to f6314db Compare March 5, 2026 05:12
@JasMehta08 JasMehta08 requested a review from jblomer March 5, 2026 05:13
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Test Results

    21 files      21 suites   3d 3h 50m 29s ⏱️
 3 831 tests  3 822 ✅ 1 💤  8 ❌
72 929 runs  72 824 ✅ 9 💤 96 ❌

For more details on these failures, see this check.

Results for commit f6314db.

Copy link
Contributor

@jblomer jblomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle looks good to me but see the CI report (missing TBuffer.h include)

struct MemberWithCustomStreamer {
int fNormal = 0;
int fCustom = 0;
ClassDefNV(MemberWithCustomStreamer, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
ClassDefNV(MemberWithCustomStreamer, 1);
ClassDefNV(MemberWithCustomStreamer, 2);

@JasMehta08
Copy link
Contributor Author

JasMehta08 commented Mar 5, 2026

@jblomer
I think the segmentation errors is caused by the GetListOfRealData() returns nullptr because we are not checking for that and trying to access it.
Do you think that fixing that would fix the errors? if so, should I add a if check?

@JasMehta08 JasMehta08 force-pushed the detect-custom-streamers branch from f6314db to 14a18ab Compare March 5, 2026 12:10
@JasMehta08
Copy link
Contributor Author

@jblomer

I have added the changes that you had pointed out about
the missing header and the updated the class version.

I also changed the code snippet as i think it is the cause of the segmentation fault.
Please let me know if i have gotten the reasoning behind the segmentation fault wrong.

Thanks!

@JasMehta08 JasMehta08 requested a review from jblomer March 5, 2026 12:41
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.

[ntuple] detect custom streamers of class members

3 participants