Writing out events larger than 1 GB

In the protoDUNE DAQ, we occasionally run tests that produce raw data events that are larger than 1 GB (for example, 4.6 GB with a TPC readout window of 1 second). At the moment, the configuration of our ROOT/art output module can not handle these large events. We’ve determined that <~ 1 GB is the largest event size that we can currently write to disk.

It would be great to learn which ROOT configuration parameter(s) we need to change in order to be able to handle larger events. Are there examples available that demonstrate the writing of large events to disk with RootOutputTree::fillTree?

In the current code, the stack trace from one of our failed attempts to write a large event is the following:

Thread 1 “art” received signal SIGSEGV, Segmentation fault.
0x00007efc142e3e09 in tobuf(char*&, unsigned long long) () from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libRIO.so
(gdb) where
#0 0x00007efc142e3e09 in tobuf(char*&, unsigned long long) () from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libRIO.so
#1 0x00007efc142e02c9 in TBufferFile::WriteFastArray(long long const*, int) () from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libRIO.so
#2 0x00007efc143f521f in int TStreamerInfo::WriteBufferAux<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libRIO.so
#3 0x00007efc1435575c in TStreamerInfoActions::VectorLooper::GenericWrite(TBuffer&, void*, void const*, TStreamerInfoActions::TLoopConfiguration const*, TStreamerInfoActions::TConfiguration const*) () from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libRIO.so
#4 0x00007efc142de4bc in TBufferFile::ApplySequence(TStreamerInfoActions::TActionSequence const&, void*, void*) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libRIO.so
#5 0x00007efc131ab978 in TBranchElement::FillLeavesCollectionMember(TBuffer&) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libTree.so
#6 0x00007efc131a37e5 in TBranch::FillImpl(ROOT::Internal::TBranchIMTHelper*) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libTree.so
#7 0x00007efc131b0873 in TBranchElement::FillImpl(ROOT::Internal::TBranchIMTHelper*) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libTree.so
#8 0x00007efc131b0952 in TBranchElement::FillImpl(ROOT::Internal::TBranchIMTHelper*) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libTree.so
#9 0x00007efc131b0952 in TBranchElement::FillImpl(ROOT::Internal::TBranchIMTHelper*) ()
from /nfs/sw/artdaq/products/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/lib/libTree.so
#10 0x00007efc193a2fb2 in TBranch::Fill (this=<optimized out>)
at /scratch/workspace/art-release-build/SLF7/prof/build/root/v6_12_04e/Linux64bit+3.10-2.17-e15-prof/include/TBranch.h:154
#11 art::fillTreeBranches (threshold=-1, saveMemory=false, branches=…)
at /scratch/workspace/art-release-build/SLF7/prof/build/art/v2_10_02/src/art/Framework/IO/Root/RootOutputTree.cc:139
#12 art::RootOutputTree::fillTree (this=0x54e3c20) at /scratch/workspace/art-release-build/SLF7/prof/build/art/v2_10_02/src/art/Framework/IO/Root/RootOutputTree.cc:154
#13 0x00007efc030d72a1 in art::RootDAQOutFile::fillBranches<(art::BranchType)0> (this=this@entry=0x53aff00, principal=…, vpp=0x53b0058)
at /nfs/sw/work_dirs/dune-artdaq_artdaq_v3_03_01_plusFour/srcs/artdaq/artdaq/ArtModules/RootDAQOutput/RootDAQOutFile.cc:930
#14 0x00007efc030c4978 in art::RootDAQOutFile::writeOne (this=0x53aff00, e=…)
at /nfs/sw/work_dirs/dune-artdaq_artdaq_v3_03_01_plusFour/srcs/artdaq/artdaq/ArtModules/RootDAQOutput/RootDAQOutFile.cc:580
#15 0x00007efc035a82ce in art::RootDAQOut::write (this=0x52aa5a0, ep=…)
at /nfs/sw/work_dirs/dune-artdaq_artdaq_v3_03_01_plusFour/srcs/artdaq/artdaq/ArtModules/RootDAQOutput/RootDAQOut_module.cc:334
#16 0x00007efc190bd24b in art::OutputModule::doWriteEvent (this=0x52aa5a0, ep=…)
at /scratch/workspace/art-release-build/SLF7/prof/build/art/v2_10_02/src/art/Framework/Core/OutputModule.cc:178
#17 0x00007efc190c8571 in art::OutputWorker::writeEvent (this=this@entry=0x5399900, srp=…)
at /scratch/workspace/art-release-build/SLF7/prof/build/art/v2_10_02/src/art/Framework/Core/OutputWorker.cc:69
#18 0x00007efc19089881 in art::EndPathExecutor::<lambda(auto:25)>::operator()<art::OutputWorker*> (w=0x5399900, _closure=<synthetic pointer>)
at /scratch/workspace/art-release-build/SLF7/prof/build/art/v2_10_02/src/art/Framework/Core/EndPathExecutor.cc:133
#19 art::EndPathExecutor::doForAllEnabledOutputWorkers
<art::EndPathExecutor::writeEvent(art::EventPrincipal&)::<lambda(auto:25)> > (fcn=…, this=0x525aeb0)
at /scratch/workspace/art-release-build/SLF7/prof/build/art/v2_10_02/src/art/Framework/Core/EndPathExecutor.h:175
—Type <return> to continue, or q <return> to quit—q
Quit
(gdb) quit

Thanks,
Kurt

Maybe this can help (you can also search the forum…):

Maybe: 1GB buffer limit

Try to use tree “branch splitting” so that individual branches are split into subbranches (with one subbranch for each data member so that there are multiple smaller buffers, one buffer per subbranch).

The crash you see should be fixed by [io] fix crash due to overflow in buffer length variable by ferdymercury · Pull Request #14627 · root-project/root · GitHub

How to improve the limit is not so easy:

You would need to change all data types of TBufferFile from Int_t to Long64_t