Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I/O Customizaton Rules: add support for changing the input type. #17347

Open
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

pcanal
Copy link
Member

@pcanal pcanal commented Jan 2, 2025

With these changes, one can request the schema evolution (usually implicit) of the input data members from the on-file type to a custom type. Example of the changes support in the test roottest/root/io/evolution/rules/execSourceTypes.cxx added by the companion roottest PR

This fixes #17346 17346

@pcanal pcanal requested a review from dpiparo as a code owner January 2, 2025 23:19
@pcanal pcanal requested review from jblomer and dpiparo and removed request for dpiparo January 2, 2025 23:19
@pcanal pcanal self-assigned this Jan 2, 2025
Copy link

github-actions bot commented Jan 3, 2025

Test Results

    2 files      2 suites   8h 51m 9s ⏱️
2 432 tests 2 296 ✅ 136 💤 0 ❌
4 849 runs  4 849 ✅   0 💤 0 ❌

Results for commit 7b3edc4.

♻️ This comment has been updated with latest results.

pcanal added 22 commits January 3, 2025 18:22
Previously the call to RemoveStreamerInfo was working only if the slot was the the slot of the current version.
(the actually removed StreamerInfo was hard-coded to be the current version
The data members are cached (because they are input of a rule) need to be read into the original type not
the 'current in memory type' so that the rule can properly function if the type has changed.

We should upgrade further for the in-memory type of the input of a rule to be the one specified in
the rule independently of the onfile type and the final in-memory type.
In the "list of real data", the array members' name is "datamembername[arraysizes]" in most cases.
GetRealData already has code to find the real data if
* input has brackets and name has brackets
* input has brackets and name does not have brackets
* input has no brackets and name has no brackets
This commit adds:
* input has no brackats and name has brackets.

This is required for simplicity of searching from the code generated for I/O customization rules
In TStreamerInfo::InsertArtificialElements search for
the offset of the data member based on the already calculated
'real data' spelling to speedup the lookup.
Previous, the inner code was looking an inexistent members (actually the name of the object
in its parent rather than an inner data member) and was appearing to work because the
offset return in case of error was '0' (which worked since indeed there was no offset
to be added to the address we already calculated)
Instead of returning 0 when not finding any information about the data
member, `TClass::GetDataMemberOffset` now returns TVirtualStreamerInfo::kMissing.

This allows the reading of the element to be "skipped" rather than
having it over-write other members
Return the underlying type and other piece and information separately
This reverts commit e900d32.

Bug fix: I/O customization rules which missing input are no
longer (inappropriately) run.

We now properly warn if a rule is requesting an input that is not
present in the StreamerInfo that the rule is being applied to.

To avoid the warning in some cases (in particular the cases used
to support `HepMC` and are located in `$ROOTSYS/etc/class.rules`)
we introduce a new "attribute" for I/O customization rules:

   `CanIgnore:`

    When using this attribute the rule will be ignored if the input is
    missing from the schema/class-layout they apply to instead of issue a `Warning`

wip: Revert "Don't warn when ..."
In TStreamerInfo's Build and BuildOld update the artificial StreamerElement's description of the
in memory type to be used to store the data.

This allows the rule to request an implicit transformation from onfile representation to in memory
representation before running the explicit customization rules
This allows to remove data member whose type is array of (sub)objects.
Previously the code in TStreamerElement assumed that GetClassPointer return the underlying type of the in memory representation.
This was true until recently as you could not change the representation in the 'current' StreamerInfo ( GetClassPointer was
matching the layout as decribed by the Clang AST ) and if the class was not loaded, the 'old/onfile' representation was the
only possible choice.   However we now can change the representation on file (i.e. GetClassPointer) for the current StreamerInfo
of a loaded class (i.e. later using Write rule, now in the case of enum class and collection thereof) and in the case of
the synthetic/artifical class created to cache inputs of rules (they are named `classname@@versionNumber`), the rule now
dictates the representation in memory
@pcanal pcanal force-pushed the io-rules-type-change branch from ba28c30 to 7b3edc4 Compare January 4, 2025 00:25
@pcanal pcanal closed this Jan 4, 2025
@pcanal pcanal reopened this Jan 4, 2025
@pcanal pcanal closed this Jan 5, 2025
@pcanal pcanal reopened this Jan 5, 2025
@dpiparo dpiparo closed this Jan 6, 2025
@dpiparo dpiparo reopened this Jan 6, 2025
@pcanal pcanal marked this pull request as ready for review January 6, 2025 17:39
@pcanal pcanal closed this Jan 6, 2025
@pcanal pcanal reopened this Jan 6, 2025
@dpiparo dpiparo closed this Jan 8, 2025
@dpiparo dpiparo reopened this Jan 8, 2025
@@ -7403,7 +7403,7 @@ void TClass::RemoveStreamerInfo(Int_t slot)
if (fStreamerInfo->GetSize() >= slot) {
R__LOCKGUARD(gInterpreterMutex);
TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)fStreamerInfo->At(slot);
fStreamerInfo->RemoveAt(fClassVersion);
fStreamerInfo->RemoveAt(slot);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a test for adding and removing streamer infos?

}
if (objName == nameNoDim) {
return static_cast<TRealData*>(obj);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a test for the 4 cases?

Comment on lines +548 to +550
Error("Setup","%s",Form("Negative offset %d for %s in %s, class: %s",
fMemberOffset, fDataMember.Data(), fBranch->GetName(), fClass->GetName()));
fMemberOffset = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this happen? If so, can we add a test for this?

}

} else if (fClass) {
} else if (fParent && fClass) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Which case do we cover by the additional check for fParent?

@@ -253,6 +253,62 @@ namespace {
TStreamerInfo* fInfo;
};

decltype(auto) GetSourceType(ROOT::TSchemaRule::TSources *s)
Copy link
Contributor

@jblomer jblomer Jan 8, 2025

Choose a reason for hiding this comment

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

Why do we need decltype(auto) instead of the spelled out type std::tuple<...>?

Comment on lines +333 to +335
for (Int_t j=0;j<compinfo->fLength;j++) {
b.SkipObjectAny();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is not tested by root-project/roottest#1247. In this case, can a test be added?

@@ -257,13 +257,14 @@ namespace {
{
std::string localtypename(s->GetUnderlyingTypeName());
Int_t ndim = 0;
Int_t totaldim = 1;
Int_t totaldim = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps merge this with the commit adding totaldim

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.

I/O Customization rules fails in case of changes in the inputs types.
3 participants