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

STL collection object in TFile not compatible across OSX and Linux #17216

Open
1 task done
ktf opened this issue Dec 6, 2024 · 7 comments
Open
1 task done

STL collection object in TFile not compatible across OSX and Linux #17216

ktf opened this issue Dec 6, 2024 · 7 comments
Assignees
Labels

Comments

@ktf
Copy link
Contributor

ktf commented Dec 6, 2024

Check duplicate issues.

  • Checked for duplicates

Description

As reported this summer in https://root-forum.cern.ch/t/stl-collection-object-in-tfile-not-compatible-across-osx-and-linux/60321

Using:

#include <array>
#include <iostream>
#include <vector>

#include "TFile.h"

#pragma link C++ class std::vector<std::array<ULong64_t, 2>>+ ;

void writeVector() {
  std::vector < std::array < ULong64_t, 2>> test { { 1ull, 2ull }, { 3ull, 4ull }, { 5ull, 6ull } };
  TFile f("test.root", "RECREATE");
  f.WriteObject(&test, "test");
  f.Close();
}

void readVector() {
  TFile f("test.root");
  auto test = f.Get<std::vector<std::array < ULong64_t, 2> > >("test");

  for (auto &a: *test) {
    std::cout << a[0] << " " << a[1] << std::endl;
  }
  f.Close();
}

to write on one platform and then read the result back on the other results in:

Error in <TBufferFile::ReadVersion>: Could not find the StreamerInfo with a checksum of 0x44178e08 for the class "array<ULong64_t,2>" in test.root.
Error in <TBufferFile::CheckByteCount>: object of class array<ULong64_t,2> read too few bytes: 6 instead of 22
Error in <TBufferFile::ReadVersion>: Could not find the StreamerInfo with a checksum of 0x44178e08 for the class "array<ULong64_t,2>" in test.root.
Error in <TBufferFile::CheckByteCount>: object of class array<ULong64_t,2> read too few bytes: 6 instead of 22
Error in <TBufferFile::ReadVersion>: Could not find the StreamerInfo with a checksum of 0x44178e08 for the class "array<ULong64_t,2>" in test.root.
Error in <TBufferFile::CheckByteCount>: object of class array<ULong64_t,2> read too few bytes: 6 instead of 22

Similarly, if I adapt the above to be an std::unordered_map rather than a vector of pairs it crashes with:

[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[/Users/ktf/src/sw/BUILD/44309b19dcd447bff3ead99ccd49cb399f7edcaa/O2/compiled_macros/Users/ktf/src/sw/BUILD/44309b19dcd447bff3ead99ccd49cb399f7edcaa/O2/foo_C.so] readVector() (no
debug info)
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const (no debug info)
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) (no debug info)
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] cling::Interpreter::EvaluateInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__
1::allocator<char>> const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) (no debug info)
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] cling::Interpreter::process(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::alloca
tor<char>> const&, cling::Value*, cling::Transaction**, bool) (no debug info)
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*,
bool) (no debug info)
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&,
 cling::Value*) /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/metacling/src/TCling.cxx:2447
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCling.6.32.06.so] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/
0/core/metacling/src/TCling.cxx:0
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libRint.6.32.06.so] TRint::ProcessLineNr(char const*, char const*, int*) /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/r
int/src/TRint.cxx:0
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libRint.6.32.06.so] TRint::HandleTermInput() /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/rint/src/TRint.cxx:649
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCore.6.32.06.so] TUnixSystem::CheckDescriptors() /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/unix/src/TUnixSystem.c
xx:0
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCore.6.32.06.so] TMacOSXSystem::DispatchOneEvent(bool) /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/macosx/src/TMacO
SXSystem.mm:378
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCore.6.32.06.so] TSystem::InnerLoop() /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/base/src/TSystem.cxx:404
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCore.6.32.06.so] TSystem::Run() /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/base/src/TSystem.cxx:354
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libCore.6.32.06.so] TApplication::Run(bool) /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/base/src/TApplication.cxx:1887
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/lib/libRint.6.32.06.so] TRint::Run(bool) /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/core/rint/src/TRint.cxx:0
[/Users/ktf/src/sw/osx_arm64/ROOT/10b8d555b9-local1/bin/root.exe] main /Users/ktf/src/sw/SOURCES/ROOT/10b8d555b9/0/main/src/rmain.cxx:86

Running on the same platform works as expected.

Reproducer

See description

ROOT version

6.32.6 built with alibuild

Installation method

alibuild

Operating system

macOS + linux (lxplus)

Additional context

This is preventing us to read some calibration objects which were created during datataking and use them to perform analysis tasks on macOS.

@ktf ktf added the bug label Dec 6, 2024
@pcanal
Copy link
Member

pcanal commented Dec 6, 2024

Does it happens to anything beside a STL collection of std::array? This combination is not yet supported (and sadly not yet explicitly rejected either :( ). [ the recommendation it to use std::collection< struct_wrapping_std_array<..>> ]

@ktf
Copy link
Contributor Author

ktf commented Dec 6, 2024

Yes, with unordered_map<uin64_t, double > , which is how we (re)discovered this today.

@pcanal
Copy link
Member

pcanal commented Dec 6, 2024

I would not expect the same error message (type) with that. It is likely that uin64_t has a different underlying type on Linux and Macos and hence result in effectively different class name for unordered_map<uin64_t, double >.
What is the actual error message in this case?

@ktf
Copy link
Contributor Author

ktf commented Dec 6, 2024

root [0]
Attaching file 6382c81b-b32b-11ef-81d0-0aa202c71b9a as _file0...
Warning in <TStreamerInfo::BuildCheck>:
   The StreamerInfo of class o2::grp::GRPEnvVariables read from file 6382c81b-b32b-11ef-81d0-0aa202c71b9a
   has the same version (=1) as the active class but a different checksum.
   You should update the version to ClassDef(o2::grp::GRPEnvVariables,2).
   Do not try to write objects with the current class definition,
   the files will not be readable.

Warning in <TStreamerInfo::CompareContent>: The following data member of
the on-file layout version 1 of class 'o2::grp::GRPEnvVariables' differs from
the in-memory layout version 1:
   unordered_map<string,vector<pair<unsigned long,double> > > mEnvVars; //
vs
   unordered_map<string,vector<pair<ULong64_t,double> > > mEnvVars; //
(TFile *) 0x12db0c0d0
root [1] .q

is the original error in the production code.

@pcanal
Copy link
Member

pcanal commented Dec 6, 2024

Alright. That error is what I expect. If you are using std::uin64_t with the current ROOT code, the schema will be different on different platforms. Until we had support for this typedefs (in the plan for work for 2025), your best solution is to use the ROOT typedef instead (i.e. ULong64_t) or (for this case) unsigned long long would also work. [Two other solutions might be to remove the class version from that class and just rely on checksum or to make the class version platform dependent]

@ktf
Copy link
Contributor Author

ktf commented Dec 7, 2024

If we substitute with unsigned long long, would that require bumping the version to read it correctly?

@pcanal
Copy link
Member

pcanal commented Dec 7, 2024

Yes, the only way to avoid the warnings in most cases is to change the type and increase the version number. (You might still get the warning when trying to read in the same process files written on both mac and linux - because 2 conflicting version 1 would be read)

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

No branches or pull requests

3 participants