Lazy snapshot in pyroot

Dear experts,

I define an RDataFrame using FromSpec (json file small_mc_files.txt (1.8 KB) attached). I want to create several snapshots from the same RDF. In order to do it multi-threaded I set the Snapshot to be lazy and then I want to execute all the snapshots later using RunGraphs. This is what I do:

import ROOT
import json
ROOT.EnableImplicitMT() 
opts = ROOT.RDF.RSnapshotOptions()
opts.fLazy = True
with open("small_mc_files.txt", 'r') as f:
    RDF_spec = json.load(f)
df = ROOT.RDF.Experimental.FromSpec("small_mc_files.txt")
all_original_columns = df.GetColumnNames()
df = df.DefinePerSample("fname",'rdfsampleinfo_.GetS("short_name")')
snapshots = []
# looping over all unique categories in my spec file
for did in RDF_spec["samples"].keys():
    # for each value of short_name I want to create a separate root file using Snapshot
    thisname = RDF_spec["samples"][did]["metadata"]["short_name"]
    outname = f'./mc_{thisname}.root'
    snapshots.append(df.Filter(f'fname == "{thisname}"').Snapshot("analysis",outname[-1],all_original_columns,opts))
ROOT.RDF.RunGraphs([snapshots])

However, this does not work (see full error message below). Is there a way to do this? Or would I need to do one snapshot after the other (i.e. not lazy)?

Thanks for any help!

best,
Eirik

Warning in <Snapshot>: A lazy Snapshot action was booked but never triggered.
Warning in <Snapshot>: A lazy Snapshot action was booked but never triggered.
cling JIT session error: Failed to materialize symbols: { (main, { _ZNSt6vectorIN4ROOT3RDF13RResultHandleESaIS2_EE12emplace_backIJRNS1_10RResultPtrINS1_10RInterfaceINS0_6Detail3RDF12RLoopManagerEvEEEESD_EEERS2_DpOT_ }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZNSt6vectorIN4ROOT3RDF13RResultHandleESaIS2_EEC1ERKS4_ }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZNSt6vectorIN4ROOT3RDF13RResultHandleESaIS2_EED1Ev }) }
Error in <TClingCallFunc::make_dtor_wrapper>: Failed to compile
  ==== SOURCE BEGIN ====
__attribute__((used)) extern "C" void __dtor_57(void* obj, unsigned long nary, int withFree)
{
   if (withFree) {
      if (!nary) {
         delete (std::vector<ROOT::RDF::RResultHandle, std::allocator<ROOT::RDF::RResultHandle> >*) obj;
      }
      else {
         delete[] (std::vector<ROOT::RDF::RResultHandle, std::allocator<ROOT::RDF::RResultHandle> >*) obj;
      }
   }
   else {
      typedef std::vector<ROOT::RDF::RResultHandle, std::allocator<ROOT::RDF::RResultHandle> > Nm;
if (!nary) {
         ((Nm*)obj)->~Nm();
      }
      else {
         do {
            (((Nm*)obj)+(--nary))->~Nm();
         } while (nary);
      }
   }
}

  ==== SOURCE END ====
Error in <TClingCallFunc::ExecDestructor>: Called with no wrapper, not implemented!

ROOT Version: 6.34.00

Dear Eirik,

Thanks for reaching out to the forum! I am sorry the experience was not smooth out of the box. Before doing a more thorough debugging, I noticed a small typo in the snippet which might be relevant. You call to RunGraphs is taking in the parameter [snapshots], but snapshots is itself already a list, so the call should be RunGraphs(snapshots) instead. Can you try that and let me know if it works?

Cheers,
Vincenzo

Thanks for the quick reply. Yes, I was initially trying just to send the list, but then it complained about the following.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_763368/1792880259.py in <module>
     16     outname = f'./mc_{thisname}.root'
     17     snapshots.append(df.Filter(f'fname == "{thisname}"').Snapshot("analysis",outname[-1],all_original_columns,opts))
---> 18 ROOT.RDF.RunGraphs(snapshots)

TypeError: unsigned int ROOT::RDF::RunGraphs(vector<ROOT::RDF::RResultHandle>) =>
    TypeError: could not convert argument 1

But it seems to somehow continue and fails with the following message (similar as reported above):

cling JIT session error: Failed to materialize symbols: { (main, { _ZNSt10shared_ptrIN4ROOT8Internal3RDF11RActionBaseEEC1ERKS4_ }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZN4ROOT3RDF13RResultHandleC1INS0_10RInterfaceINS_6Detail3RDF12RLoopManagerEvEEEERKNS0_10RResultPtrIT_EE }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZN4ROOT3RDF13RResultHandleC1INS0_10RInterfaceINS_6Detail3RDF12RLoopManagerEvEEEERKNS0_10RResultPtrIT_EE }) }
cling JIT session error: Failed to materialize symbols: { (main, { _ZNSt6vectorIN4ROOT3RDF13RResultHandleESaIS2_EED1Ev }) }
Error in <TClingCallFunc::make_dtor_wrapper>: Failed to compile
  ==== SOURCE BEGIN ====
__attribute__((used)) extern "C" void __dtor_52(void* obj, unsigned long nary, int withFree)
{
   if (withFree) {
      if (!nary) {
         delete (std::vector<ROOT::RDF::RResultHandle, std::allocator<ROOT::RDF::RResultHandle> >*) obj;
      }
      else {
         delete[] (std::vector<ROOT::RDF::RResultHandle, std::allocator<ROOT::RDF::RResultHandle> >*) obj;
      }
   }
   else {
      typedef std::vector<ROOT::RDF::RResultHandle, std::allocator<ROOT::RDF::RResultHandle> > Nm;
if (!nary) {
         ((Nm*)obj)->~Nm();
      }
      else {
         do {
            (((Nm*)obj)+(--nary))->~Nm();
         } while (nary);
      }
   }
}

  ==== SOURCE END ====
Error in <TClingCallFunc::ExecDestructor>: Called with no wrapper, not implemented!