RDF + Friend Tree in subdirectory of file + MT not working

Hi!

I have issues analyzing a tree with a friend tree using the RDF with ImplicitMT enabled. The reason seems to be that the trees are not saved in the same directory in the file. Here is a code which demonstrates the behavior:

#include <TROOT.h>
#include <ROOT/RDataFrame.hxx>
#include <ROOT/RVec.hxx>
#include <TNtuple.h>
#include <TFile.h>

void create_file()
{
   // Setting up trees
   auto f = TFile::Open("myfile.root", "RECREATE");
   TNtuple* t = new TNtuple("main", "", "val");
   TNtuple* tf = new TNtuple("friend", "", "val2");
   const auto vals = {1, 2, 3, 4, 5}; 
   for (const auto& val : vals)
   {   
      t->Fill(val);
      tf->Fill(-val);
   }   
   auto dir = f->mkdir("main");
   dir->cd();
   t->Write();
   f->cd();
   auto dir2 = f->mkdir("friend");
   dir2->cd();
   tf->Write();
   f->Close();
}

void analyze()
{
   // Read file
   auto f = TFile::Open("myfile.root", "READ");
   TTree* t = (TTree*) f->Get("main/main");
   TTree* tf = (TTree*) f->Get("friend/friend");

   // Add friend
   t->AddFriend(tf, "friend");

   auto df = ROOT::RDataFrame(*t);

   // Trigger event loop
   std::cout << *df.Count() << std::endl;
}

int main()
{
   ROOT::EnableImplicitMT();
   create_file();
   analyze();
}

If MT is enabled it will seg fault in the line where the event loop is triggered.

===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f45c4b9ea3c in waitpid () from /lib64/libc.so.6
#1  0x00007f45c4b1cde2 in do_system () from /lib64/libc.so.6
#2  0x00007f45c96b27c4 in TUnixSystem::StackTrace() () from /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/lib/libCore.so.6.16
#3  0x00007f45c96b4efc in TUnixSystem::DispatchSignals(ESignals) () from /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/lib/libCore.so.6.16
#4  <signal handler called>
#5  0x00007f45c71aeaed in ROOT::TTreeProcessorMT::Process(std::function<void (TTreeReader&)>) () from /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/lib/libTreePlayer.so.6.16
#6  0x00007f45c5b72d05 in ROOT::Detail::RDF::RLoopManager::RunTreeProcessorMT() () from /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/lib/libROOTDataFrame.so.6.16
#7  0x00007f45c5b73635 in ROOT::Detail::RDF::RLoopManager::Run() () from /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/lib/libROOTDataFrame.so.6.16
#8  0x00000000004063fa in TriggerRun (this=<optimized out>) at /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/include/ROOT/RResultPtr.hxx:286
#9  Get (this=0x7ffec1e29530) at /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/include/ROOT/RResultPtr.hxx:128
#10 operator* (this=0x7ffec1e29530) at /cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.16.00/x86_64-centos7-gcc48-opt/include/ROOT/RResultPtr.hxx:159
#11 analyze () at example.cc:42
#12 0x0000000000405b25 in main () at example.cc:49
===========================================================

Without MT everything is working. If I save the trees in the root directory or different files everything is fine as well. But if they are stored in subdirectories the code crashes when I use MT.

An easy workaround would be to write a script which saves them in the root directory of a file but it would be nice if it also works with subdirectories so I can give my files a bit more structure or do I have a bug in my code?

best
Jonas


ROOT Version: 6.16
Platform: CC7
Compiler: gcc48


Could you try something like:

void create_file()
{
   // Setting up trees
   auto f = TFile::Open("myfile.root", "RECREATE");
   auto dir = f->mkdir("main");
   dir->cd(); // or f->cd("main");
   TNtuple* t = new TNtuple("main", "", "val");
   f->cd();
   auto dir2 = f->mkdir("friend");
   dir2->cd(); // or f->cd("friend");
   TNtuple* tf = new TNtuple("friend", "", "val2");
   const auto vals = {1, 2, 3, 4, 5}; 
   for (const auto& val : vals)
   {   
      t->Fill(val);
      tf->Fill(-val);
   }   
   f->cd("main");
   t->Write();
   f->cd("friend");
   tf->Write();
   f->Close();
}

crashes as well. The files also look nice and without MT I see correct values like 5 entries, mean of 3 and -3 for the tree and the friend tree.

Maybe @Danilo has an idea (could it be because your directories have the same names than your TNtuples?)

No the names do not matter at all. I think I can put them even in the same subdirectory and it still did not work

Hi,
Looks like a bug! Please open a ticket on jira (https://sft.its.cern.ch/jira/projects/ROOT) with a small reproducer and we’ll take a look asap.

Cheers,
Enrico

Sorry this took so long, this is now fixed in master and the fix will be included in v6.22/04 and v6.24.

Cheers,
Enrico