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

[ntuple] Add support for std::map fields #13904

Merged
merged 5 commits into from
Nov 21, 2023

Conversation

enirolf
Copy link
Contributor

@enirolf enirolf commented Oct 20, 2023

This PR adds support for std::map fields through collection proxies (similar to std::set).

In theory, other (custom) associative collections (provided they implement a collection proxy) should now also be able to be added as fields. Because the use case for this is not yet obvious, this is still disabled.

@enirolf enirolf requested review from pcanal and vepadulano October 20, 2023 13:29
@enirolf enirolf self-assigned this Oct 20, 2023
@enirolf enirolf requested a review from jblomer as a code owner October 20, 2023 13:29
@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-3.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

1 similar comment
@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-2.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@phsft-bot
Copy link

Build failed on windows10/default.
Running on null:C:\build\workspace\root-pullrequests-build
See console output.

@github-actions
Copy link

github-actions bot commented Oct 20, 2023

Test Results

       11 files         11 suites   1d 19h 11m 11s ⏱️
  2 483 tests   2 480 ✔️ 0 💤 3
26 178 runs  26 175 ✔️ 0 💤 3

For more details on these failures, see this check.

Results for commit 573abaa.

♻️ This comment has been updated with latest results.

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.

Very nice!

I think we should make the following adjustments:

  • Let's change the on-disk representation to a collection of pairs. This would correspond to the collection proxy representation. And it would naturally let SplitValue return std::pair values, which I'd find more natural than alternating key and value.
  • I'm not sure we should make the associative collection proxy field inherit from the simple one. It looks to me cleaner to add the additional functionality directly to the RProxiedCollectionField class.

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-2.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Warnings:

  • [2023-10-24T15:10:38.427Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:59: warning: ‘offsetof’ within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<char, std::map<int, CustomStruct> >, void>::ContainerT’ {aka ‘std::pair<char, std::map<int, CustomStruct> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:10:38.427Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:88: warning: ‘offsetof’ within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<char, std::map<int, CustomStruct> >, void>::ContainerT’ {aka ‘std::pair<char, std::map<int, CustomStruct> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:10:38.427Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:59: warning: ‘offsetof’ within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<float, std::map<char, int> >, void>::ContainerT’ {aka ‘std::pair<float, std::map<char, int> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:10:38.427Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:88: warning: ‘offsetof’ within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<float, std::map<char, int> >, void>::ContainerT’ {aka ‘std::pair<float, std::map<char, int> >’} is conditionally-supported [-Winvalid-offsetof]

Failing tests:

@phsft-bot
Copy link

Build failed on ROOT-performance-centos8-multicore/soversion.
Running on olbdw-01.cern.ch:/data/sftnight/workspace/root-pullrequests-build
See console output.

Warnings:

  • [2023-10-24T15:31:49.820Z] /data/sftnight/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:59: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<char, std::map<int, CustomStruct> >, void>::ContainerT’ {aka ‘std::pair<char, std::map<int, CustomStruct> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:31:49.820Z] /data/sftnight/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:88: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<char, std::map<int, CustomStruct> >, void>::ContainerT’ {aka ‘std::pair<char, std::map<int, CustomStruct> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:31:50.331Z] /data/sftnight/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:59: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<float, std::map<char, int> >, void>::ContainerT’ {aka ‘std::pair<float, std::map<char, int> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:31:50.331Z] /data/sftnight/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:88: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<float, std::map<char, int> >, void>::ContainerT’ {aka ‘std::pair<float, std::map<char, int> >’} is conditionally-supported [-Winvalid-offsetof]

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2004/python3.
Running on root-ubuntu-2004-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Warnings:

  • [2023-10-24T15:25:44.658Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:59: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<char, std::map<int, CustomStruct> >, void>::ContainerT’ {aka ‘std::pair<char, std::map<int, CustomStruct> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:25:44.914Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:88: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<char, std::map<int, CustomStruct> >, void>::ContainerT’ {aka ‘std::pair<char, std::map<int, CustomStruct> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:25:44.914Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:59: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<float, std::map<char, int> >, void>::ContainerT’ {aka ‘std::pair<float, std::map<char, int> >’} is conditionally-supported [-Winvalid-offsetof]
  • [2023-10-24T15:25:44.914Z] /home/sftnight/build/workspace/root-pullrequests-build/root/tree/ntuple/v7/inc/ROOT/RField.hxx:2488:88: warning: offsetof within non-standard-layout type ‘ROOT::Experimental::RField<std::pair<float, std::map<char, int> >, void>::ContainerT’ {aka ‘std::pair<float, std::map<char, int> >’} is conditionally-supported [-Winvalid-offsetof]

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@enirolf enirolf requested a review from jblomer October 26, 2023 15:09
@enirolf
Copy link
Contributor Author

enirolf commented Oct 27, 2023

@phsft-bot build just on ROOT-ubuntu2204/nortcxxmod

@phsft-bot
Copy link

Starting build on ROOT-ubuntu2204/nortcxxmod
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

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.

Great! Some minor suggestions added.

void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;

public:
RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<Detail::RFieldBase> itemField);
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 use a PairField?

Suggested change
RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<Detail::RFieldBase> itemField);
RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RPairField> itemField);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, this causes trouble with CloneImpl because when we call Clone on the subfield, a RFieldBase is returned (unless there's a way to cast it to an RPairField that I'm unaware of?)

Copy link
Contributor

@jblomer jblomer Oct 27, 2023

Choose a reason for hiding this comment

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

Right, I think we can do a dynamic_cast to a RPairField. We know it must be a RPairField.

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on mac12arm/cxx20.
Running on macphsft26.dyndns.cern.ch:/Users/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-2.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@@ -66,6 +66,13 @@
#pragma link C++ class std::map<char, std::map<int, CustomStruct>> +;
#pragma link C++ class std::map<float, std::map<char, std::int32_t>> +;

#pragma link C++ class std::pair <char, long> +;
Copy link
Member

Choose a reason for hiding this comment

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

The dictionary requests for std::pair do not hurt but they also should not be needed. What lead you to add them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I don't include them, the std::map tests will fail on builds with runtime modules disabled (see all the failing tests on ROOT-ubuntu2204/nortcxxmod in this thread). I'm not really knowledgeable on these modules, so I don't know if this just hides some other underlying issue or not..

Copy link
Member

@pcanal pcanal Nov 16, 2023

Choose a reason for hiding this comment

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

What was the error? Note: it is a goal/requirement that the support for std::map does not require the user to request the dictionary for std::pair

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can actually see it on the latest Jenkins build failure: https://lcgapp-services.cern.ch/root-jenkins/job/root-pullrequests-build/189474/testReport/projectroot.tree.ntuple.v7/test/gtest_tree_ntuple_v7_test_ntuple_types/, because apparently now it also fails for a std::set test that contains a std::pair without a dictionary. Which is also weird, because these tests used to pass just fine on the same platform before (it does not seem something changed in the Jenkins/build config since).

Copy link
Member

Choose a reason for hiding this comment

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

You will need to reproduce the problem locally and/or instrument:

ROOT::Experimental::RPairField::RPairField(std::string_view fieldName,
                                           std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
   : ROOT::Experimental::RRecordField(fieldName, std::move(itemFields), {},
                                      "std::pair<" + GetTypeList(itemFields) + ">")
{
   // ISO C++ does not guarantee any specific layout for `std::pair`; query TClass for the member offsets
   fClass = TClass::GetClass(GetType().c_str());
   if (!fClass)
      throw RException(R__FAIL("cannot get type information for " + GetType()));
   fSize = fClass->Size();
   if (fClass->GetDataMember("first") == nullptr || fClass->GetDataMember("second") == nullptr) {
      std::cerr << "The TClass for " << GetType() << " is in state: " << fClass->GetState << " and has: \n";
      fClass->GetListOfDataMembers()->ls();
      fClass->GetStreamerInfo()->ls();
      throw RException(R__FAIL("Insufficient information for " + GetType()));
   }
   fOffsets[0] = fClass->GetDataMember("first")->GetOffset();
   fOffsets[1] = fClass->GetDataMember("second")->GetOffset();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I observe the same thing locally. For a std::map<char,std::int64_t> field (and thus with a child field of type std::pair<char,std::int64_t>) as defined in the test here:

auto otherField = RFieldBase::Create("test", "std::map<char, int64_t>").Unwrap();
the output of the snippet above is

The TClass for std::pair<char,std::int64_t> is in state: 2 and has:
OBJ: TListOfDataMembers	TListOfDataMembers	List of TDataMembers for a class : 0

StreamerInfo for class: pair<char,Long64_t>, checksum=0xb5fb752
  char           first           offset=  0 type= 1 Emulation
  Long64_t       second          offset=  8 type=16 Emulation
   i= 0, first           type=  1, offset=  0, len=1, method=0
   i= 1, second          type= 16, offset=  8, len=1, method=0
unknown file: Failure
C++ exception with description "Insufficient information for std::pair<char,std::int64_t>

When I add the dictionary entry for this std::pair type the test passes without issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's discuss this in a follow-up issue / PR.

Copy link
Member

Choose a reason for hiding this comment

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

C++ exception with description "Insufficient information for std::pair<char,std::int64_t>

Where does the error comes from (stack trace)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've opened a issue to further discuss this: #14084

@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

1 similar comment
@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@phsft-bot
Copy link

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-2.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

enirolf and others added 5 commits November 21, 2023 11:25
This macro is conditionally supported and with the addition of
`std::map` fields, compilation warnings will be thrown for nested maps.
To prevent these warnings, the offsets are determined in a similar way
to `std::tuple` fields.
Necessary for builds without runtime modules enabled.
Inner fields *must* be of type `RPairField`. Ideally this should be done
at compile time through the constructor argument type, but this is still
causing issues and needs further investigation. Thus, this runtime check
is added as a temporary solution.
@phsft-bot
Copy link

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

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

Successfully merging this pull request may close these issues.

5 participants