Proof lite performance

Hi experts,
I am using proof lite with 4 workers, and I get no performance speed-up. I am reading in a tree, and writing one out. There are ~100K events in the input tree, and I hope to extract event-level parallelism. It is a compiled executable, and all works fine with compilation and output. Just no speed-up.

In the .h file I have

class subAnalyzer : public TSelector {
private :
   TTree          *outTree;

public :
   TChain     *inTree;   
   Int_t         fCurrent;
    
   TString     fMode;
   TString     fChannel;

   Float_t       outVariable;

   
   Float_t         inVariable;
   TBranch        *b_event_branch_inVariable;   //!

   subAnalyzer(TTree * /*tree*/ =0) { }
   virtual ~subAnalyzer() { }
   virtual void     Begin(const TString mode, const TString channel,const TString inFileName,const TString outFileName);
   virtual void     SlaveBegin();
   virtual void     Init();
   virtual Bool_t   Notify();
   virtual void     Show(Long64_t entry = -1);
   virtual Bool_t   Process(Long64_t entry);
   virtual void     Loop();
   virtual Int_t    GetEntry(Long64_t entry);
   virtual Long64_t LoadTree(Long64_t entry);
   virtual void     SetInputList(TList *input) { fInput = input; }
   virtual TList   *GetOutputList() const { return fOutput; }
   virtual void     SlaveTerminate();
   virtual void     Terminate();
};


void subAnalyzer::Init()
{
   // Set branch addresses and branch pointers
   fCurrent=-1;
   if (!inTree) return;
   inTree->SetMakeClass(1);
   inTree->SetBranchAddress("inVariable", &inVariable, &b_event_branch_inVariable);
 }

And in the .cxx file


void subAnalyzer::Begin(const TString mode, const TString channel, const TString inFileName,const TString outFileName)
{
  TFile *inFile = TFile::Open(inFileName.Data());
  TProof::Open("");
  inTree = (TChain*)inFile->Get("usertree");
  inTree->SetProof();
  inTreeInit();
  fMode=mode;
  fChannel=channel;
}

void subAnalyzer::SlaveBegin()
{
  outTree = new TTree("outTree","outTree");
  outTree->Branch("outVariable",  &outVariable);
  fOutput->Add(outTree); 
}

Int_t subAnalyzer::Cut(){
  Int_t keep=1;
  if( inVariable > someValue) return -1;
  return keep;
}


Bool_t subAnalyzer::Process(Long64_t entry)
{
  inTree->GetEntry(entry);
  outVariable = inVariable;
  outTree->Fill();
  return kTRUE;
}


void subAnalyzer::Loop(){
  if (inTree == 0) {cout << "no tree " << "\n"; return;}
  Long64_t nentries = inTree->GetEntries();
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) {
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0){
      cout<<"Warning: LoadTree(): centry = "<<ientry<<endl;
      return;
    }
    nb = inTree->GetEntry(jentry); nbytes += nb;
    if(Cut()<0) continue;
    Process(jentry);
  }// END OF ENTRIES LOOP
}

void subAnalyzer::SlaveTerminate()
{

}

void subAnalyzer::Terminate()
{
  outTree = (TTree *) fOutput->FindObject("outTree");
  if (outTree) {
    cout << "-->successfully made the bush." << endl;
    cout << "-->it has # of entries = " << outTree->GetEntries() << endl;
    TFile *f = TFile::Open("testing.root", "RECREATE");
    f->WriteObject(outTree, "bush");
    delete f;
  }

}

Am I missing something basic as to how to interface with proof to extract parallelism?

Many Thanks!

Dear mgv4ce,

Can you explain how do you run PROOF?
It looks like you initialize it in Init ? How do you invoke the selector?

Have a look at root.cern.ch/basic-processing#apiprocchain .

G Ganis

The class above is compiled and linked into an executable. The main program, which instantiates the class and calls its methods is


int main (int argc, char *argv[]) 
{
   const TString mode        = argv[1];
   const TString channel     = argv[2];
   const TString outFileName = argv[3];
   const TString inFileName  = argv[4];

   subAnalyzer *s = new subAnalyzer();
   s->Begin(mode, channel, inFileName,outFileName);
   s->SlaveBegin();
   s->Loop();
   s->SlaveTerminate();
   s->Terminate();
   
   return 0;
}

It is not clear to me how to translate the interactive call in the link you provide into a default method within the class methods. Probably just inexperience with proof. I am just getting started.

Yes, I initialize the proof session in the Init function. I thought my usage was equivalent to the interactive call.

Many thanks!

In this way you are doing you own event loop in ::Loop and there is nothing that PROOF can parallelize.
The ROOT analysis model, which is the one implemented by PROOF, controls the events loop so that it can parallelize it, if required.

Basically you need to:

  1. Put your file in a TChain (or another supported data set structure)
  2. Remove the PROOF initialization from Init and do it out side, some where at the beginning of main()
  3. Remove your loop ::Loop ; move the cut condition inside the loop in Process .
  4. Call the Process method of TChain, after telling TChain to use PROOF; see root.cern.ch/basic-processing#apiprocchain .

Can you try this way?

G Ganis

I use the method you say. This however kills all my events–the resulting output is an empty tree. Obviously I implement it wrongly.

I have changed my code to that below:

main.cxx

int main (int argc, char *argv[])
{
   const TString mode        = argv[1];
   const TString channel     = argv[2];
   const TString outFileName = argv[3];
   const TString inFileName  = argv[4];

   TFile *inFile = TFile::Open(inFileName.Data());
   cout<<"-->Opened inFile : " << inFileName << endl;
   TPoof *proof = TProof::Open("");
   TChain *inTree = (TChain*)inFile->Get("usertree");
   inTree->SetProof(proof);

   TStopwatch* loopTimer = new TStopwatch();

   subAnalyzer *s = new subAnalyzer();
   s->Begin(mode, channel, inTree);
   s->SlaveBegin();
   inTree->Process(s,"",100000,0);
   s->SlaveTerminate();
   s->Terminate();
   loopTimer->Stop();
   cout<<"Time: "<<loopTimer->RealTime()<<" s\n";

   return 0;
}

The .h file (with details removed) is

class subAnalyzer : public TSelector {
private :
   TTree          *outTree;

public :
   TChain          *inTree;   //!pointer to the analyzed TTree or TChain
   TString         fMode;
   TString         fChannel;
   Float_t         outVariable;
   Float_t         inVariable;
   TBranch        *b_event_branch_inVariable;   
...
   virtual void     inTreeInit(TChain *inTree);
...
}

inTreeInit(TChain *intree)
{
   fCurrent=-1;
   if (!intree) return;
   inTree = intree;
   inTree->SetMakeClass(1);
   inTree->SetBranchAddress("inVariable", & inVariable, &b_event_branch_inVariable);
   
 }

The Begin routine:

void subAnalyzer::Begin(const TString mode, const TString channel, TChain *inTree)
{
  fMode=mode;
  fChannel=channel;
  inTreeInit(inTree);
}

The slave begin routine is the same:

void subAnalyzer::SlaveBegin()
{
  outTree = new TTree("outTree","outTree");
  outTree->Branch("outVariable",  &outVariable);
  fOutput->Add(outTree); 
}

The Process routine:

Bool_t subAnalyzer::Process(Long64_t entry)
{
   inTree->GetEntry(entry); 
   outVariable=inVariable;
   outTree->Fill();
   return kTRUE;
}

Thank you for the help!

In order to provide a little more info:
–I put a cout statement in the Process method, and it never is evaluated.
–I check the value of Process, and it returns as false. So although I call the function it never is evaluated.

Thanks again!

I found a thread that had sort of similar problems: G++ standalone: TProof using TChain

It seems that it is hard to call a TSelector object within compiled code. One needs the code-generation of root (via CINT or something).

So I adapted my code to use the call-by-filename method that seems easier. I have adapted my main program to be that below:

int main (int argc, char *argv[]) 
{
   const TString mode        = argv[1];
   const TString channel     = argv[2];
   const TString outFileName = argv[3];
   const TString inFileName  = argv[4];

   TFile *inFile = TFile::Open(inFileName.Data());
   cout<<"-->Opened inFile : " << inFileName << endl;
   TChain *inTree = (TChain*)inFile->Get("usertree");
   TProof *proof = TProof::Open("");
   inTree->SetProof(proof);

   TStopwatch* loopTimer = new TStopwatch();
   subAnalyzerClass *s = new subAnalyzerClass();
   s->Begin(mode, channel, inTree);
   s->SlaveBegin();
   inTree->Process("subAnalyzerClass.C");
   s->SlaveTerminate();
   s->Terminate();
   loopTimer->Stop();
   cout<<"Time: "<<loopTimer->RealTime()<<" s\n";
   return 0;
}

The other methods are unchanged. Running this gives the following output:

-->Opened inFile : result.root
 +++ Starting PROOF-Lite with 4 workers +++
Opening connections to workers: OK (4 workers)                 
Setting up worker servers: OK (4 workers)                 
PROOF set to parallel mode (4 workers)
set the mode and channel
Beginning slave.
Slave begun.
Error: Symbol __BEGIN_DECLS#include is not defined in current scope  /usr/include/sys/types.h:34:
Error: Symbol bits is not defined in current scope  /usr/include/sys/types.h:34:
Error: Symbol types is not defined in current scope  /usr/include/sys/types.h:34:
Error: Failed to evaluate types.h
Error: operator '/' divided by zero /usr/include/sys/types.h:34:
Error: Invalid type '#ifdef' in declaration of '__USE_BSD#ifndef __u_char_defined typedef __u_char u_char' /usr/include/sys/types.h:34:
Error: Symbol #ifdef __USE_BSD#ifndef __u_char_defined typedef __u_char u_char is not defined in current scope  /usr/include/sys/types.h:34:
*** Interpreter error recovered ***
Error in <TSelector::GetSelector>: The file subAnalyzerClass.C does not define a class named subAnalyzerClass.
reporting status for Process as: 1
-->successfully made the bush.
-->it has # of entries = 0
Time: 0.112967 s

How can I get CINT to process my macro here?

Many Thanks!
Mike

Dear mgv4ce,

Can you try the following?


int main (int argc, char *argv[]) 
{
   const TString mode        = argv[1];
   const TString channel     = argv[2];
   const TString outFileName = argv[3];
   const TString inFileName  = argv[4];

   TFile *inFile = TFile::Open(inFileName.Data());
   cout<<"-->Opened inFile : " << inFileName << endl;
   TChain *inTree = (TChain*)inFile->Get("usertree");
   TProof *proof = TProof::Open("");
   inTree->SetProof(proof);

   TStopwatch* loopTimer = new TStopwatch();
   proof->Load("subAnalyzerClass.C");   // This loads the new class everywhere, locally and on the PROOF workers
   subAnalyzerClass *s = new subAnalyzerClass();
   // s->Begin(mode, channel, inTree);
   // s->SlaveBegin();
   inTree->Process("subAnalyzerClass");   // Identify the selector class by name
   // s->SlaveTerminate();
   // s->Terminate();
   loopTimer->Stop();
   cout<<"Time: "<<loopTimer->RealTime()<<" s\n";
   return 0;
}

Note that Begin should only take ‘TTree *’, so if you need to set other parameters, do it in the constructor of subAnalyserClass .
Begin, SlaveBegin, SlaveTerminate, Terminate are called by PROOF internally.

G Ganis

Hi,
When I do this, I get

 +++ Starting PROOF-Lite with 20 workers +++
Opening connections to workers: OK (20 workers)                 
Setting up worker servers: OK (20 workers)                 
PROOF set to parallel mode (20 workers)
Note: pthread.dll is not found. Do 'sh setup' in $CINTSYSDIR/lib/pthread directory if you use UNIX.

I try to run the script as indicated. I do

-bash-4.1$ export CINTSYSDIR="/mypath/root-5.34.28/cint/cint/"
-bash-4.1$ sh $CINTSYSDIR/lib/pthread/setup

which returns

/mypath/root-5.34.28/cint/cint/lib/pthread/setup: line 20: makecint: command not found

If pthread is not set up, then I assume that PROOF cannot work. Any advice?

Thanks!

I have one other question: I generate a dictionary using the LinkDef.h and ClassDict.cxx approach. Could I use the resulting shared object instead of the file name? That is, could I do

   proof->Load("subAnalyzerClass.so");
   inTree->SetProof(proof);
   subAnalyzerClass *s = new subAnalyzerClass();
   Bool_t status = (Bool_t)inTree->Process("subAnalyzerClass");

Perhaps I would need to load some things to gSystem like below?

   gProof->Exec("gSystem->Load(\"libCintex\")");
   gProof->Exec("ROOT::Cintex::Cintex::Enable()");
   gProof->Exec("gSystem->Load(\"/workingDirectory/subAnalyzerClass.so\")");

Dear mgv4ce,

No, PROOF uses multi-processing, pthread is not used.

pthread.dll is something for windows, on which system are you running?
How do you configure the running environment (PATH, LD_LIBRARY_PATH, …)?

Yes, but you have to give the absolute path, because the subprocesses have a different working dir:

proof->Load(TString::Format("%s/subAnalyzerClass.so", gSystem->WorkingDirectory()));

G Ganis

Dear Ganis,
I am on a 64-bit Linux distro. Here is some terminal output

-bash-4.1$ lsb_release -a
LSB Version:	:base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID:	CentOS
Description:	CentOS release 6.5 (Final)
Release:	6.5
Codename:	Final
-bash-4.1$ uname -a
Linux udc-ba36-27 2.6.32-431.11.2.el6.x86_64 #1 SMP Tue Mar 25 19:59:55 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

While in my working directory I use

export PATH=$PATH:$(pwd)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)

Then I make clean ; make ; and execute.

I am using the shared object approach now. With the proof loading as you detailed, I get fine compilation etc. The output at run-time is

 +++ Starting PROOF-Lite with 20 workers +++
Opening connections to workers: OK (20 workers)                 
Setting up worker servers: OK (20 workers)                 
PROOF set to parallel mode (20 workers)
12:52:23 56469 Wrk-0.0 | Info in <TProofServLite::HandleCache>: loading macro subAnalyzer.so ...
dlopen error: /nv/blue/mgv4ce/.proof/nv-blue-mgv4ce-testing/session-udc-ba36-27-1462294342-56457/worker-0.0/./subAnalyzer.so: undefined symbol: _ZN5MySel11ShowMembersER16TMemberInspector
Load Error: Failed to load Dynamic link library /nv/blue/mgv4ce/.proof/nv-blue-mgv4ce-testing/session-udc-ba36-27-1462294342-56457/worker-0.0/./subAnalyzer.so
....

That error is repeated for all workers. Is the error obvious to you or perhaps an updated minimal working example would help?

Thanks,
Mike

Dear Mike,

It looks like it does not find the ROOT libs .
Is your ROOT installation local (i.e. under a given directory)?
If yes, under ‘bin’, there should be a ‘thisroot.sh’ script: are you sourcing it?
Does it change anything sourcing it?

If you have a system installation, is ldconfig aware of the ROOT libs?

G Ganis

Dear Ganis,
The installation is local. However, running the source script does not change anything. Same output.
Thanks,
Mike

Dear Mike,

Sorry, I was too quick ast evening; looking again at the error message, it looks for

Where is MySel defined or referred to? Is it in subAnalyzer.so ? If not you need to load also the shared library where it is defined.

G Ganis

My apologies. I pasted the wrong terminal output. I was transitioning to a simpler/updated minimal working example and posted a halfway point.

I attach these new files in this post. It shows the simplifications/adaptations in this thread (like using .so files, removing the mode/channel args, and loading things to proof the way you proscribe etc.). It should be clearer. The output is the same error:

12:58:29 166627 Wrk-0.1 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
dlopen error: /nv/blue/mgv4ce/.proof/nv-blue-mgv4ce-testing/session-udc-ba36-27-1462381103-166600/worker-0.1/./MySel.so: undefined symbol: _ZN5MySel11ShowMembersER16TMemberInspector
Load Error: Failed to load Dynamic link library /nv/blue/mgv4ce/.proof/nv-blue-mgv4ce-testing/session-udc-ba36-27-1462381103-166600/worker-0.1/./MySel.so
12:58:29 166631 Wrk-0.3 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
dlopen error: /nv/blue/mgv4ce/.proof/nv-blue-mgv4ce-testing/session-udc-ba36-27-1462381103-166600/worker-0.3/./MySel.so: undefined symbol: _ZN5MySel11ShowMembersER16TMemberInspector
...

In case it is more convenient I put the files here as well:
The .h file

#ifndef MySel_h
#define MySel_h

#include "headers.h"

class MySel: public TSelector {
 private :
  TTree          *outTree;

 public :
  TChain          *inTree;
  Float_t         inVariable;
  Float_t         outVariable;

  Long64_t nbytes, nb;
  Int_t    fCurrent;
  
  TBranch        *b_event_branch_inVariable;  

  MySel(TTree * /*tree*/ =0) { }
  virtual ~MySel() { }
  virtual void           Begin(TChain *inTree);
  virtual void           SlaveBegin();
  virtual void           inTreeInit(TChain *inTree);
  virtual Bool_t        Notify();
  virtual void           Show(Long64_t entry = -1);
  virtual Bool_t        Process(Long64_t entry);
  virtual Int_t          GetEntry(Long64_t entry);
  virtual Long64_t    LoadTree(Long64_t entry);
  virtual TList          *GetOutputList() const { return fOutput; }
  virtual void           SlaveTerminate();
  virtual void           Terminate();

  ClassDef(MySel,2);
};

#endif

#ifdef MySel_cxx
void MySel::Show(Long64_t entry){
  // Print contents of entry.
  // If entry is not specified, print current entry
  if (!inTree) return;
  inTree->Show(entry);
  }
  
  Int_t MySel::GetEntry(Long64_t entry){
  // Read contents of entry.
  if (!inTree) return 0;
  Int_t getall=1;
  return inTree->GetEntry(entry, getall);
  }
  
  Long64_t MySel::LoadTree(Long64_t entry){
  // Set the environment to read one entry
  if (!inTree) return -5;
  Long64_t centry = inTree->LoadTree(entry);
  if (centry < 0) return centry;
  if (!inTree->InheritsFrom(TChain::Class()))  return centry;
  TChain *chain = (TChain*)inTree;
  if (chain->GetTreeNumber() != fCurrent) {
  fCurrent = chain->GetTreeNumber();
  Notify();
  }
  return centry;
  }
 
  
  Bool_t MySel::Notify()
  {
  return kTRUE;
  }
  
  
  void MySel::inTreeInit(TChain *intree)
  {
  // Set branch addresses and branch pointers
  fCurrent=-1;
  if (!intree) return;
  inTree = intree;
  inTree->SetMakeClass(1);
  inTree->SetBranchAddress("inVariable", &inVariable, &b_event_branch_inVariable);
  
  Notify();
  }
  
 #endif 

The .C file

#define MySel_cxx
#include "MySel.h"
ClassImp(MySel);
void MySel::Begin(TChain *inTree) 
{
  inTreeInit(inTree);
}

void MySel::SlaveBegin()
{
  outTree = new TTree("outTree","outTree");
  outTree->Branch("outVariable", &outVariable);
  fOutput->Add(outTree); 
}

Bool_t MySel::Process(Long64_t entry)
{
  cout << " Process called " << endl;
  inTree->GetEntry(entry); 
  outVariable = inVariable;
  outTree->Fill();
  return kTRUE;
}


void MySel::SlaveTerminate()
{
}

void MySel::Terminate()
{
  outTree = (TTree *) fOutput->FindObject("outTree");
  if (outTree) {
    TFile *f = TFile::Open("testing.root", "RECREATE");
    f->WriteObject(outTree, "bush");
    delete f;
  }

}

The main program

#include "MySel.h"
using namespace std;

int main (int argc, char *argv[]) 
{
   const TString mode        = argv[1];
   const TString channel     = argv[2];
   const TString outFileName = argv[3];
   const TString inFileName  = argv[4];

   TFile  *inFile = TFile::Open(inFileName.Data());
   TChain *inTree = (TChain*)inFile->Get("usertree");
   TProof *proof  = TProof::Open("");
   //gProof->Exec("gSystem->Load(\"libCintex\")");
   //gProof->Exec("ROOT::Cintex::Cintex::Enable()");
   //gProof->Exec("gSystem->Load(\"/home/mgv4ce/testing/MySel.so\")");
   //proof->Load("MySel.C+");
   proof->Load(TString::Format("%s/MySel.so", gSystem->WorkingDirectory()));
   inTree->SetProof(proof);

   MySel *s = new MySel();
   //s->Begin(mode, channel, inTree);
   //s->SlaveBegin();
   Bool_t status = (Bool_t)inTree->Process("MySel");//"MySel.C+");
   cout << "reporting " << status << " for Process call" << endl;
   //s->SlaveTerminate();
   //s->Terminate();
   gSystem->Exit(0);
   return 0;
}

The makefile

ROOTLDFLAGS :=$(shell $(ROOTSYS)/bin/root-config --ldflags)
ROOTCFLAGS  :=$(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS    :=$(shell $(ROOTSYS)/bin/root-config --libs) 
ROOTCFLAGS  += -DUSE_ROOT
ROOTCFLAGS  += -DHAVE_ZLIB
ROOTCFLAGS  += -DUSE_TREE
ROOTCFLAGS  += -DUSE_HISTO
ROOTLINK = $(ROOTLIBS) $(ROOTCFLAGS) $(ROOTLDFLAGS) 
ROOTLIBS    += -lFoam -lProof -lProofPlayer
#ROOTLINK    := -L$(ROOTLIBDIR) $(ROOTLDFLAGS) $(ROOTCFLAGS)
endif
#--------configure compiler----------#
CXX = g++
CXXFLAGS  := $(ROOTCFLAGS) # -lquadmath -D_GLIBCXX_PARALLEL -fopenmp
CXXFLAGS  += -O2 -fPIC -Wall -Wno-write-strings 
LIBS     = $(ROOTLIBS) -Llib -lRIO -lNet -lHist -lMatrix -lThread -lCore -lCint -lMathCore  -lTree -ldl -rdynamic -lm -lz -lutil -lnsl -lpthread
MYSELLIB  = $(shell pwd)/$(SUBASO)

.SUFFIXES: .cc,.C,.cpp

default: all
all: ClassDict.cxx ClassDict.o MySel.o MySel.so selector

ClassDict.cxx: MySel.h LinkDef.h
	@echo "Generating dictionary $@..."
	@rootcint -f $@ -c -p MySel.h LinkDef.h 
	@echo "$@ done"
	@echo "-------------------------------"

ClassDict.o: ClassDict.cxx ClassDict.h 
	@echo "Compiling $@"
	$(CXX) $(CXXFLAGS) -c $<
	@echo "-----------------------------------------------------"

MySel.o: MySel.C MySel.h 
	@echo "Compiling $@"
	$(CXX) $(CXXFLAGS) -c MySel.C \
	$(LIBS) -fopenmp -Wno-deprecated
	@echo "-------------------------------"

MySel.so: MySel.o
	@echo "compiling $@"
	$(LD) $(SOFLAGS) $(LDFLAGS) -fPIC $^ $(OutPutOpt) $@ $(EXPLLINKLIBS) $(LIBS)
	@echo "$@ done"
	@echo "----------------------------------"

selector: main.cpp
	@echo "Compiling $@"
	$(CXX) $(CXXFLAGS) -o selector main.cpp $(LIBS) ClassDict.o MySel.o MySel.so \

clean:
	rm -f selector
	rm -f *.o
	rm -f *.so
	rm -f ClassDict.cxx
	rm -f *~

MySel.h (1.98 KB)
makefile.txt (1.79 KB)
main.cpp (997 Bytes)
MySel.C (931 Bytes)

I was able to solve the problem of the library not being loaded (there was a problem with my makefile). And everything executes fine.

But the Process command returns false when I call it–it never executes the code in the body of the method. So, when I source, compile and run the source files in the previous post, I get

 +++ Starting PROOF-Lite with 8 workers +++
Opening connections to workers: OK (8 workers)                 
Setting up worker servers: OK (8 workers)                 
PROOF set to parallel mode (8 workers)
12:46:54 30075 Wrk-0.0 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30077 Wrk-0.1 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30079 Wrk-0.2 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30085 Wrk-0.5 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30083 Wrk-0.4 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30081 Wrk-0.3 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30089 Wrk-0.7 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
12:46:54 30087 Wrk-0.6 | Info in <TProofServLite::HandleCache>: loading macro MySel.so ...
reporting 0 for Process call

Help is much appreciated!