// @(#)root/proofplayer:$Id$
// Author: Long Tran-Thanh    22/07/07
// Revised: G. Ganis, May 2011

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TPacketizerUnit                                                      //
//                                                                      //
// This packetizer generates packets of generic units, representing the //
// number of times an operation cycle has to be repeated by the worker  //
// node, e.g. the number of Monte carlo events to be generated.         //
// Packets sizes are generated taking into account the performance of   //
// worker nodes, based on the time needed to process previous packets,  //
// with the goal of having all workers ending at the same time.         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


#include "TPacketizerUnit.h"

#include "Riostream.h"
#include "TDSet.h"
#include "TError.h"
#include "TEventList.h"
#include "TMap.h"
#include "TMessage.h"
#include "TMonitor.h"
#include "TNtupleD.h"
#include "TObject.h"
#include "TParameter.h"
#include "TPerfStats.h"
#include "TProofDebug.h"
#include "TProof.h"
#include "TProofPlayer.h"
#include "TProofServ.h"
#include "TSlave.h"
#include "TSocket.h"
#include "TStopwatch.h"
#include "TTimer.h"
#include "TUrl.h"
#include "TClass.h"
#include "TMath.h"
#include "TObjString.h"


using namespace TMath;
//
// The following utility class manage the state of the
// work to be performed and the slaves involved in the process.
//
// The list of TSlaveStat(s) keep track of the work (being) done
// by each slave
//

//------------------------------------------------------------------------------

class TPacketizerUnit::TSlaveStat : public TVirtualPacketizer::TVirtualSlaveStat {

friend class TPacketizerUnit;

private:
   Long64_t  fLastProcessed; // Number of processed entries of the last packet
   Double_t  fRate;         // Estimated processing rate averaged over circularity
   Double_t  fTimeInstant;   // Starting time of the current packet
   TNtupleD *fCircNtp;       // Keeps circular info for speed calculations
   Long_t    fCircLvl;       // Circularity level

public:
   TSlaveStat(TSlave *sl, TList *input);
   ~TSlaveStat();

//   void        GetCurrentTime();

   void        UpdatePerformance(Double_t time);
   TProofProgressStatus *AddProcessed(TProofProgressStatus *st);

//   ClassDef(TPacketizerUnit::TSlaveStat, 0);
};

//______________________________________________________________________________
TPacketizerUnit::TSlaveStat::TSlaveStat(TSlave *slave, TList *input)
                            : fLastProcessed(0),
                              fRate(0), fTimeInstant(0), fCircLvl(5)
{
   // Main constructor

   // Initialize the circularity ntple for speed calculations
   fCircNtp = new TNtupleD("Speed Circ Ntp", "Circular process info","tm:ev");
   fCircNtp->SetDirectory(0);
   TProof::GetParameter(input, "PROOF_TPacketizerUnitCircularity", fCircLvl);
   fCircLvl = (fCircLvl > 0) ? fCircLvl : 5;
   fCircNtp->SetCircular(fCircLvl);
   fSlave = slave;
   fStatus = new TProofProgressStatus();
}

//______________________________________________________________________________
TPacketizerUnit::TSlaveStat::~TSlaveStat()
{
   // Destructor

   SafeDelete(fCircNtp);
}

//______________________________________________________________________________
void TPacketizerUnit::TSlaveStat::UpdatePerformance(Double_t time)
{
   // Update the circular ntple

   Double_t ttot = time;
   Double_t *ar = fCircNtp->GetArgs();
   Int_t ne = fCircNtp->GetEntries();
   if (ne <= 0) {
      // First call: just fill one ref entry and return
      fCircNtp->Fill(0., 0);
      fRate = 0.;
      return;
   }
   // Fill the entry
   fCircNtp->GetEntry(ne-1);
   ttot = ar[0] + time;
   fCircNtp->Fill(ttot, GetEntriesProcessed());

   // Calculate the speed
   fCircNtp->GetEntry(0);
   Double_t dtime = (ttot > ar[0]) ? ttot - ar[0] : ne+1 ;
   Long64_t nevts = GetEntriesProcessed() - (Long64_t)ar[1];
   fRate = nevts / dtime;
   PDB(kPacketizer,2)
      Info("UpdatePerformance", "time:%f, dtime:%f, nevts:%lld, speed: %f",
                                time, dtime, nevts, fRate);

}

//______________________________________________________________________________
TProofProgressStatus *TPacketizerUnit::TSlaveStat::AddProcessed(TProofProgressStatus *st)
{
   // Update the status info to the 'st'.
   // return the difference (*st - *fStatus)

   if (st) {
      // The entriesis not correct in 'st'
      Long64_t lastEntries = st->GetEntries() - fStatus->GetEntries();
      // The last proc time should not be added
      fStatus->SetLastProcTime(0.);
      // Get the diff
      TProofProgressStatus *diff = new TProofProgressStatus(*st - *fStatus);
      *fStatus += *diff;
      // Set the correct value
      fStatus->SetLastEntries(lastEntries);
      return diff;
   } else {
      Error("AddProcessed", "status arg undefined");
      return 0;
   }
}

//------------------------------------------------------------------------------

ClassImp(TPacketizerUnit)

//______________________________________________________________________________
TPacketizerUnit::TPacketizerUnit(TList *slaves, Long64_t num, TList *input,
                                 TProofProgressStatus *st)
                : TVirtualPacketizer(input, st)
{
   // Constructor

   PDB(kPacketizer,1) Info("TPacketizerUnit", "enter (num %lld)", num);

   // Init pointer members
   fWrkStats = 0;
   fPackets = 0;
   fInput = input;

   fFixedNum = kFALSE;
   Int_t fixednum = -1;
   if (TProof::GetParameter(input, "PROOF_PacketizerFixedNum", fixednum) != 0 || fixednum <= 0) {
      fFixedNum = kFALSE;
   }
   else {
      Info("TPacketizerUnit", "forcing the same cycles on each worker");
      fFixedNum = kTRUE;
   }

   fCalibFrac = 0.01;
   if (TProof::GetParameter(input, "PROOF_PacketizerCalibFrac", fCalibFrac) != 0 || fCalibFrac <= 0)
      fCalibFrac = 0.01;
   PDB(kPacketizer,1)
      Info("TPacketizerUnit", "size of the calibration packets: %.2f %% of average number per worker", fCalibFrac);

   fMaxPacketTime = 3.;
   Double_t timeLimit = -1;
   if (TProof::GetParameter(input, "PROOF_PacketizerTimeLimit", timeLimit) == 0) {
      fMaxPacketTime = timeLimit;
      Warning("TPacketizerUnit", "PROOF_PacketizerTimeLimit is deprecated: use PROOF_MaxPacketTime instead");
   }
   PDB(kPacketizer,1)
      Info("TPacketizerUnit", "time limit is %lf", fMaxPacketTime);

   // Different default for min packet time
   fMinPacketTime = 1;
   Double_t minPacketTime = 0;
   if (TProof::GetParameter(input, "PROOF_MinPacketTime", minPacketTime) == 0) fMinPacketTime = minPacketTime;
   TParameter<Double_t> *mpt = (TParameter<Double_t> *) fConfigParams->FindObject("PROOF_MinPacketTime");
   if (mpt) {
      mpt->SetVal(fMinPacketTime);
   } else {
      fConfigParams->Add(new TParameter<Double_t>("PROOF_MinPacketTime", fMinPacketTime));
   }

   fProcessing = 0;
   fAssigned = 0;
   fPacketSeq = 0;

   fStopwatch = new TStopwatch();

   fPackets = new TList;
   fPackets->SetOwner();

   fWrkStats = new TMap;
   fWrkStats->SetOwner(kFALSE);
   fWrkExcluded = 0;

   TSlave *slave;
   TIter si(slaves);
   while ((slave = (TSlave*) si.Next())) {
      if (slave->GetParallel() > 0) {
         fWrkStats->Add(slave, new TSlaveStat(slave, input));
      } else {
         if (!fWrkExcluded) {
            fWrkExcluded = new TList;
            fWrkExcluded->SetOwner(kFALSE);
         }
         PDB(kPacketizer,2)
            Info("TPacketizerUnit", "node '%s' has NO active worker: excluded from work distribution", slave->GetOrdinal());
         fWrkExcluded->Add(slave);
      }
   }

   fTotalEntries = 0;
   fNumPerWorker = -1;
   if (num > 0 && AssignWork(0,0,num) != 0)
      Warning("TPacketizerUnit", "some problems assigning work");

   // Save the config parameters in the dedicated list so that they will be saved
   // in the outputlist and therefore in the relevant TQueryResult
   fConfigParams->Add(new TParameter<Float_t>("PROOF_PacketizerCalibFrac", fCalibFrac));

   fStopwatch->Start();
   PDB(kPacketizer,1) Info("TPacketizerUnit", "return");
}

//______________________________________________________________________________
Int_t TPacketizerUnit::AssignWork(TDSet *, Long64_t, Long64_t num)
{
   // Assign work to be done to this packetizer

   if (num < 0) {
      Error("AssignWork", "assigned a negative number (%lld) of cycles - protocol error?", num);
      return -1;
   }

   fTotalEntries += num;
   PDB(kPacketizer,1)
      Info("AssignWork", "assigned %lld additional cycles (new total: %lld)", num, fTotalEntries);

   // Update fixed number counter
   if (fFixedNum && fWrkStats->GetSize() > 0) {
      // Approximate number: the exact number is determined in GetNextPacket
      fNumPerWorker = fTotalEntries / fWrkStats->GetSize();
      if (fNumPerWorker == 0) fNumPerWorker = 1;
   }

   // Update/Save the config parameters in the dedicated list so that they will be saved
   // in the outputlist and therefore in the relevant TQueryResult
   TParameter<Long64_t> *fn =
      (TParameter<Long64_t> *) fConfigParams->FindObject("PROOF_PacketizerFixedNum");
   if (fn) {
      fn->SetVal(fNumPerWorker);
   } else {
      fConfigParams->Add(new TParameter<Long64_t>("PROOF_PacketizerFixedNum", fNumPerWorker));
   }

   // Done
   return 0;
}

//______________________________________________________________________________
TPacketizerUnit::~TPacketizerUnit()
{
   // Destructor.

   if (fWrkStats)
      fWrkStats->DeleteValues();
   SafeDelete(fWrkStats);
   SafeDelete(fWrkExcluded);
   SafeDelete(fPackets);
   SafeDelete(fStopwatch);
}

//______________________________________________________________________________
Double_t TPacketizerUnit::GetCurrentTime()
{
   // Get current time

   Double_t retValue = fStopwatch->RealTime();
   fStopwatch->Continue();
   return retValue;
}

//______________________________________________________________________________
Float_t TPacketizerUnit::GetCurrentRate(Bool_t &all)
{
   // Get Estimation of the current rate; just summing the current rates of
   // the active workers

   all = kTRUE;
   // Loop over the workers
   Float_t currate = 0.;
   if (fWrkStats && fWrkStats->GetSize() > 0) {
      TIter nxw(fWrkStats);
      TObject *key;
      while ((key = nxw()) != 0) {
         TSlaveStat *slstat = (TSlaveStat *) fWrkStats->GetValue(key);
         if (slstat && slstat->GetProgressStatus() && slstat->GetEntriesProcessed() > 0) {
            // Sum-up the current rates
            currate += slstat->GetProgressStatus()->GetCurrentRate();
         } else {
            all = kFALSE;
         }
      }
   }
   // Done
   return currate;
}

//______________________________________________________________________________
TDSetElement *TPacketizerUnit::GetNextPacket(TSlave *sl, TMessage *r)
{
   // Get next packet

   if (!fValid)
      return 0;

   // Find slave
   TSlaveStat *slstat = (TSlaveStat*) fWrkStats->GetValue(sl);
   if (!slstat) {
      Warning("GetNextPacket", "Received a packet request from an unknown slave: %s:%s",
         sl->GetName(), sl->GetOrdinal());
      return 0;
   }

   PDB(kPacketizer,2)
      Info("GetNextPacket","worker-%s: fAssigned %lld\t", sl->GetOrdinal(), fAssigned);

   // Update stats & free old element
   Double_t latency = 0., proctime = 0., proccpu = 0.;
   Long64_t bytesRead = -1;
   Long64_t totalEntries = -1; // used only to read an old message type
   Long64_t totev = 0;
   Long64_t numev = -1;

   TProofProgressStatus *status = 0;
   if (sl->GetProtocol() > 18) {
      (*r) >> latency;
      (*r) >> status;

      // Calculate the progress made in the last packet
      TProofProgressStatus *progress = 0;
      if (status) {
         // update the worker status
         numev = status->GetEntries() - slstat->GetEntriesProcessed();
         progress = slstat->AddProcessed(status);
         if (progress) {
            // (*fProgressStatus) += *progress;
            proctime = progress->GetProcTime();
            proccpu  = progress->GetCPUTime();
            totev  = status->GetEntries(); // for backward compatibility
            bytesRead  = progress->GetBytesRead();
            delete progress;
         }
         delete status;
      } else
          Error("GetNextPacket", "no status came in the kPROOF_GETPACKET message");
   } else {

      (*r) >> latency >> proctime >> proccpu;

      // only read new info if available
      if (r->BufferSize() > r->Length()) (*r) >> bytesRead;
      if (r->BufferSize() > r->Length()) (*r) >> totalEntries;
      if (r->BufferSize() > r->Length()) (*r) >> totev;

      numev = totev - slstat->GetEntriesProcessed();
      slstat->GetProgressStatus()->IncEntries(numev);
      slstat->GetProgressStatus()->SetLastUpdate();
   }

   fProgressStatus->IncEntries(numev);
   fProgressStatus->SetLastUpdate();

   fProcessing = 0;

   PDB(kPacketizer,2)
      Info("GetNextPacket","worker-%s (%s): %lld %7.3lf %7.3lf %7.3lf %lld",
                           sl->GetOrdinal(), sl->GetName(),
                           numev, latency, proctime, proccpu, bytesRead);

   if (gPerfStats != 0) {
      gPerfStats->PacketEvent(sl->GetOrdinal(), sl->GetName(), "", numev,
                              latency, proctime, proccpu, bytesRead);
   }

   if (fNumPerWorker > 0 && slstat->GetEntriesProcessed() >= fNumPerWorker) {
      PDB(kPacketizer,2)
         Info("GetNextPacket","worker-%s (%s) is done (%lld cycles)",
                           sl->GetOrdinal(), sl->GetName(), slstat->GetEntriesProcessed());
      return 0;
   }

   if (fAssigned == fTotalEntries) {
      Bool_t done = kTRUE;
      // If we are on a submaster, check if there is something else to do
      if (gProofServ && gProofServ->IsMaster() && !gProofServ->IsTopMaster()) {
         TDSetElement *nxe = gProofServ->GetNextPacket();
         if (nxe) {
            if (AssignWork(0,0,nxe->GetNum()) == 0) {
               if (fAssigned < fTotalEntries) done = kFALSE;
            } else {
               Error("GetNextPacket", "problems assigning additional work: stop");
            }
            SafeDelete(nxe);
         }
      }
      if (done) {
         // Send last timer message
         HandleTimer(0);
         return 0;
      }
   }

   if (fStop) {
      // Send last timer message
      HandleTimer(0);
      return 0;
   }


   Long64_t num;

   // Get the current time
   Double_t cTime = GetCurrentTime();

   if (slstat->fCircNtp->GetEntries() <= 0) {
      // The calibration phase
      Long64_t avg = fTotalEntries / fWrkStats->GetSize();
      num = (Long64_t) (fCalibFrac * avg);
      if (num < 1) num = (avg >= 1) ? avg : 1;
      PDB(kPacketizer,2)
         Info("GetNextPacket", "calibration: total entries %lld, workers %d, frac: %.1f %%, raw num: %lld",
                               fTotalEntries, fWrkStats->GetSize(), fCalibFrac * 100., num);

      // Create a reference entry
      slstat->UpdatePerformance(0.);

   } else {

      if (fNumPerWorker < 0) {

         // Schedule tasks for workers based on the currently estimated processing speeds

         // Update performances
         // slstat->fStatus was updated before;
         slstat->UpdatePerformance(proctime);

         // We need to estimate the total instantaneous rate: for the workers not having yet
         // one we assume the average of those having a measurement
         // The optimal number for worker j is
         //
         //                      n_j =  r_j / Sum r_i * N_left
         //

         Int_t nrm = 0;
         Double_t sumRate = 0.;
         TIter nxwrk(fWrkStats);
         TSlaveStat *wrkStat = 0;
         TSlave *tmpWrk = 0;
         while ((tmpWrk = (TSlave *)nxwrk())) {
            if ((wrkStat = dynamic_cast<TSlaveStat *>(fWrkStats->GetValue(tmpWrk)))) {
               if (wrkStat->fRate > 0) {
                  nrm++;
                  sumRate += wrkStat->fRate;
               }
               PDB(kPacketizer,3)
                  Info("GetNextPacket", "%d: worker-%s: rate %lf /s (sum: %lf /s)",
                                          nrm, tmpWrk->GetOrdinal(), wrkStat->fRate, sumRate);
            } else {
               Warning("GetNextPacket", "dynamic_cast<TSlaveStat *> failing on value for '%s (%s)'! Skipping",
                                        tmpWrk->GetName(), tmpWrk->GetOrdinal());
            }
         }

         // Check consistency
         if (nrm <= 0) {
            Error("GetNextPacket", "no worker has consistent information: stop processing!");
            return (TDSetElement *)0;
         }

         Double_t avgRate = sumRate / nrm;
         // Check if all workers had meaningful rate information
         if (nrm < fWrkStats->GetSize()) {
            // For some workers the measurement is missing: use the average
            sumRate += (fWrkStats->GetSize() - nrm) * avgRate;
         }
         PDB(kPacketizer,2)
            Info("GetNextPacket", "rate: avg: %lf /s/wrk - sum: %lf /s (measurements %d out of %d)",
                                   avgRate, sumRate, nrm, fWrkStats->GetSize());

         // Packet size for this worker
         Double_t wrkRate = (slstat->fRate > 0.) ? slstat->fRate : avgRate ;
         num = (Long64_t) ((fTotalEntries - fAssigned) * wrkRate / sumRate);
         PDB(kPacketizer,2)
            Info("GetNextPacket", "worker-%s (%s): raw packet size: %lld", sl->GetOrdinal(), sl->GetName(), num);

         // Apply time-per-packet limits
         Double_t packTime = num / wrkRate;
         if (fMaxPacketTime > 0. && packTime > fMaxPacketTime) {
            num = (Long64_t) (fMaxPacketTime * wrkRate) ;
            packTime = fMaxPacketTime;
            PDB(kPacketizer,2)
               Info("GetNextPacket", "worker-%s (%s): time-limited packet size: %lld (upper limit: %.2f secs)",
                                     sl->GetOrdinal(), sl->GetName(), num, fMaxPacketTime);
         }
         if (fMinPacketTime > 0. && packTime < fMinPacketTime) {
            num = (Long64_t) (fMinPacketTime * wrkRate);
            PDB(kPacketizer,2)
               Info("GetNextPacket", "worker-%s (%s): time-limited packet size: %lld (lower limit: %.2f secs)",
                                     sl->GetOrdinal(), sl->GetName(), num, fMinPacketTime);
         }

      } else {
         // Fixed number of cycles per worker
         num = fNumPerWorker - slstat->fLastProcessed;
         if (num > 1 && slstat->fRate > 0 && num / slstat->fRate > fMaxPacketTime) {
            num = (Long64_t) (slstat->fRate * fMaxPacketTime);
         }
      }
   }
   // Minimum packet size
   num = (num > 1) ? num : 1;
   fProcessing = (num < (fTotalEntries - fAssigned)) ? num
                                                     : (fTotalEntries - fAssigned);

   // Set the information of the current slave
   slstat->fLastProcessed = fProcessing;
   // Set the start time of the current packet
   slstat->fTimeInstant = cTime;

   // Update the sequential number
   fPacketSeq++;
   TString sseq = TString::Format("p%lld", fPacketSeq);

   PDB(kPacketizer,2)
      Info("GetNextPacket", "worker-%s: num %lld, processing %lld, remaining %lld",sl->GetOrdinal(),
                            num, fProcessing, (fTotalEntries - fAssigned - fProcessing));
   TDSetElement *elem = new TDSetElement(sseq, sseq, "", fAssigned, fProcessing);
   elem->SetBit(TDSetElement::kEmpty);

   // Update the total counter
   fAssigned += slstat->fLastProcessed;

   return elem;
}

//______________________________________________________________________________
Int_t TPacketizerUnit::AddWorkers(TList *workers)
{
   // Adds new workers. Returns the number of workers added, or -1 on failure.

   if (!workers) {
      Error("AddWorkers", "Null list of new workers!");
      return -1;
   }

   Int_t curNumOfWrks = fWrkStats->GetEntries();

   TSlave *sl;
   TIter next(workers);
   while (( sl = dynamic_cast<TSlave*>(next()) ))
      fWrkStats->Add(sl, new TSlaveStat(sl, fInput));

   fNumPerWorker = -1;
   if (fFixedNum && fWrkStats->GetSize() > 0) {
      // Approximate number: the exact number is determined in GetNextPacket
      fNumPerWorker = (fNumPerWorker * curNumOfWrks) / fWrkStats->GetSize();
      if (fNumPerWorker == 0) fNumPerWorker = 1;
   }

   fConfigParams->Add(new TParameter<Long64_t>("PROOF_PacketizerFixedNum", fNumPerWorker));

   return fWrkStats->GetEntries();
}
 TPacketizerUnit.cxx:1
 TPacketizerUnit.cxx:2
 TPacketizerUnit.cxx:3
 TPacketizerUnit.cxx:4
 TPacketizerUnit.cxx:5
 TPacketizerUnit.cxx:6
 TPacketizerUnit.cxx:7
 TPacketizerUnit.cxx:8
 TPacketizerUnit.cxx:9
 TPacketizerUnit.cxx:10
 TPacketizerUnit.cxx:11
 TPacketizerUnit.cxx:12
 TPacketizerUnit.cxx:13
 TPacketizerUnit.cxx:14
 TPacketizerUnit.cxx:15
 TPacketizerUnit.cxx:16
 TPacketizerUnit.cxx:17
 TPacketizerUnit.cxx:18
 TPacketizerUnit.cxx:19
 TPacketizerUnit.cxx:20
 TPacketizerUnit.cxx:21
 TPacketizerUnit.cxx:22
 TPacketizerUnit.cxx:23
 TPacketizerUnit.cxx:24
 TPacketizerUnit.cxx:25
 TPacketizerUnit.cxx:26
 TPacketizerUnit.cxx:27
 TPacketizerUnit.cxx:28
 TPacketizerUnit.cxx:29
 TPacketizerUnit.cxx:30
 TPacketizerUnit.cxx:31
 TPacketizerUnit.cxx:32
 TPacketizerUnit.cxx:33
 TPacketizerUnit.cxx:34
 TPacketizerUnit.cxx:35
 TPacketizerUnit.cxx:36
 TPacketizerUnit.cxx:37
 TPacketizerUnit.cxx:38
 TPacketizerUnit.cxx:39
 TPacketizerUnit.cxx:40
 TPacketizerUnit.cxx:41
 TPacketizerUnit.cxx:42
 TPacketizerUnit.cxx:43
 TPacketizerUnit.cxx:44
 TPacketizerUnit.cxx:45
 TPacketizerUnit.cxx:46
 TPacketizerUnit.cxx:47
 TPacketizerUnit.cxx:48
 TPacketizerUnit.cxx:49
 TPacketizerUnit.cxx:50
 TPacketizerUnit.cxx:51
 TPacketizerUnit.cxx:52
 TPacketizerUnit.cxx:53
 TPacketizerUnit.cxx:54
 TPacketizerUnit.cxx:55
 TPacketizerUnit.cxx:56
 TPacketizerUnit.cxx:57
 TPacketizerUnit.cxx:58
 TPacketizerUnit.cxx:59
 TPacketizerUnit.cxx:60
 TPacketizerUnit.cxx:61
 TPacketizerUnit.cxx:62
 TPacketizerUnit.cxx:63
 TPacketizerUnit.cxx:64
 TPacketizerUnit.cxx:65
 TPacketizerUnit.cxx:66
 TPacketizerUnit.cxx:67
 TPacketizerUnit.cxx:68
 TPacketizerUnit.cxx:69
 TPacketizerUnit.cxx:70
 TPacketizerUnit.cxx:71
 TPacketizerUnit.cxx:72
 TPacketizerUnit.cxx:73
 TPacketizerUnit.cxx:74
 TPacketizerUnit.cxx:75
 TPacketizerUnit.cxx:76
 TPacketizerUnit.cxx:77
 TPacketizerUnit.cxx:78
 TPacketizerUnit.cxx:79
 TPacketizerUnit.cxx:80
 TPacketizerUnit.cxx:81
 TPacketizerUnit.cxx:82
 TPacketizerUnit.cxx:83
 TPacketizerUnit.cxx:84
 TPacketizerUnit.cxx:85
 TPacketizerUnit.cxx:86
 TPacketizerUnit.cxx:87
 TPacketizerUnit.cxx:88
 TPacketizerUnit.cxx:89
 TPacketizerUnit.cxx:90
 TPacketizerUnit.cxx:91
 TPacketizerUnit.cxx:92
 TPacketizerUnit.cxx:93
 TPacketizerUnit.cxx:94
 TPacketizerUnit.cxx:95
 TPacketizerUnit.cxx:96
 TPacketizerUnit.cxx:97
 TPacketizerUnit.cxx:98
 TPacketizerUnit.cxx:99
 TPacketizerUnit.cxx:100
 TPacketizerUnit.cxx:101
 TPacketizerUnit.cxx:102
 TPacketizerUnit.cxx:103
 TPacketizerUnit.cxx:104
 TPacketizerUnit.cxx:105
 TPacketizerUnit.cxx:106
 TPacketizerUnit.cxx:107
 TPacketizerUnit.cxx:108
 TPacketizerUnit.cxx:109
 TPacketizerUnit.cxx:110
 TPacketizerUnit.cxx:111
 TPacketizerUnit.cxx:112
 TPacketizerUnit.cxx:113
 TPacketizerUnit.cxx:114
 TPacketizerUnit.cxx:115
 TPacketizerUnit.cxx:116
 TPacketizerUnit.cxx:117
 TPacketizerUnit.cxx:118
 TPacketizerUnit.cxx:119
 TPacketizerUnit.cxx:120
 TPacketizerUnit.cxx:121
 TPacketizerUnit.cxx:122
 TPacketizerUnit.cxx:123
 TPacketizerUnit.cxx:124
 TPacketizerUnit.cxx:125
 TPacketizerUnit.cxx:126
 TPacketizerUnit.cxx:127
 TPacketizerUnit.cxx:128
 TPacketizerUnit.cxx:129
 TPacketizerUnit.cxx:130
 TPacketizerUnit.cxx:131
 TPacketizerUnit.cxx:132
 TPacketizerUnit.cxx:133
 TPacketizerUnit.cxx:134
 TPacketizerUnit.cxx:135
 TPacketizerUnit.cxx:136
 TPacketizerUnit.cxx:137
 TPacketizerUnit.cxx:138
 TPacketizerUnit.cxx:139
 TPacketizerUnit.cxx:140
 TPacketizerUnit.cxx:141
 TPacketizerUnit.cxx:142
 TPacketizerUnit.cxx:143
 TPacketizerUnit.cxx:144
 TPacketizerUnit.cxx:145
 TPacketizerUnit.cxx:146
 TPacketizerUnit.cxx:147
 TPacketizerUnit.cxx:148
 TPacketizerUnit.cxx:149
 TPacketizerUnit.cxx:150
 TPacketizerUnit.cxx:151
 TPacketizerUnit.cxx:152
 TPacketizerUnit.cxx:153
 TPacketizerUnit.cxx:154
 TPacketizerUnit.cxx:155
 TPacketizerUnit.cxx:156
 TPacketizerUnit.cxx:157
 TPacketizerUnit.cxx:158
 TPacketizerUnit.cxx:159
 TPacketizerUnit.cxx:160
 TPacketizerUnit.cxx:161
 TPacketizerUnit.cxx:162
 TPacketizerUnit.cxx:163
 TPacketizerUnit.cxx:164
 TPacketizerUnit.cxx:165
 TPacketizerUnit.cxx:166
 TPacketizerUnit.cxx:167
 TPacketizerUnit.cxx:168
 TPacketizerUnit.cxx:169
 TPacketizerUnit.cxx:170
 TPacketizerUnit.cxx:171
 TPacketizerUnit.cxx:172
 TPacketizerUnit.cxx:173
 TPacketizerUnit.cxx:174
 TPacketizerUnit.cxx:175
 TPacketizerUnit.cxx:176
 TPacketizerUnit.cxx:177
 TPacketizerUnit.cxx:178
 TPacketizerUnit.cxx:179
 TPacketizerUnit.cxx:180
 TPacketizerUnit.cxx:181
 TPacketizerUnit.cxx:182
 TPacketizerUnit.cxx:183
 TPacketizerUnit.cxx:184
 TPacketizerUnit.cxx:185
 TPacketizerUnit.cxx:186
 TPacketizerUnit.cxx:187
 TPacketizerUnit.cxx:188
 TPacketizerUnit.cxx:189
 TPacketizerUnit.cxx:190
 TPacketizerUnit.cxx:191
 TPacketizerUnit.cxx:192
 TPacketizerUnit.cxx:193
 TPacketizerUnit.cxx:194
 TPacketizerUnit.cxx:195
 TPacketizerUnit.cxx:196
 TPacketizerUnit.cxx:197
 TPacketizerUnit.cxx:198
 TPacketizerUnit.cxx:199
 TPacketizerUnit.cxx:200
 TPacketizerUnit.cxx:201
 TPacketizerUnit.cxx:202
 TPacketizerUnit.cxx:203
 TPacketizerUnit.cxx:204
 TPacketizerUnit.cxx:205
 TPacketizerUnit.cxx:206
 TPacketizerUnit.cxx:207
 TPacketizerUnit.cxx:208
 TPacketizerUnit.cxx:209
 TPacketizerUnit.cxx:210
 TPacketizerUnit.cxx:211
 TPacketizerUnit.cxx:212
 TPacketizerUnit.cxx:213
 TPacketizerUnit.cxx:214
 TPacketizerUnit.cxx:215
 TPacketizerUnit.cxx:216
 TPacketizerUnit.cxx:217
 TPacketizerUnit.cxx:218
 TPacketizerUnit.cxx:219
 TPacketizerUnit.cxx:220
 TPacketizerUnit.cxx:221
 TPacketizerUnit.cxx:222
 TPacketizerUnit.cxx:223
 TPacketizerUnit.cxx:224
 TPacketizerUnit.cxx:225
 TPacketizerUnit.cxx:226
 TPacketizerUnit.cxx:227
 TPacketizerUnit.cxx:228
 TPacketizerUnit.cxx:229
 TPacketizerUnit.cxx:230
 TPacketizerUnit.cxx:231
 TPacketizerUnit.cxx:232
 TPacketizerUnit.cxx:233
 TPacketizerUnit.cxx:234
 TPacketizerUnit.cxx:235
 TPacketizerUnit.cxx:236
 TPacketizerUnit.cxx:237
 TPacketizerUnit.cxx:238
 TPacketizerUnit.cxx:239
 TPacketizerUnit.cxx:240
 TPacketizerUnit.cxx:241
 TPacketizerUnit.cxx:242
 TPacketizerUnit.cxx:243
 TPacketizerUnit.cxx:244
 TPacketizerUnit.cxx:245
 TPacketizerUnit.cxx:246
 TPacketizerUnit.cxx:247
 TPacketizerUnit.cxx:248
 TPacketizerUnit.cxx:249
 TPacketizerUnit.cxx:250
 TPacketizerUnit.cxx:251
 TPacketizerUnit.cxx:252
 TPacketizerUnit.cxx:253
 TPacketizerUnit.cxx:254
 TPacketizerUnit.cxx:255
 TPacketizerUnit.cxx:256
 TPacketizerUnit.cxx:257
 TPacketizerUnit.cxx:258
 TPacketizerUnit.cxx:259
 TPacketizerUnit.cxx:260
 TPacketizerUnit.cxx:261
 TPacketizerUnit.cxx:262
 TPacketizerUnit.cxx:263
 TPacketizerUnit.cxx:264
 TPacketizerUnit.cxx:265
 TPacketizerUnit.cxx:266
 TPacketizerUnit.cxx:267
 TPacketizerUnit.cxx:268
 TPacketizerUnit.cxx:269
 TPacketizerUnit.cxx:270
 TPacketizerUnit.cxx:271
 TPacketizerUnit.cxx:272
 TPacketizerUnit.cxx:273
 TPacketizerUnit.cxx:274
 TPacketizerUnit.cxx:275
 TPacketizerUnit.cxx:276
 TPacketizerUnit.cxx:277
 TPacketizerUnit.cxx:278
 TPacketizerUnit.cxx:279
 TPacketizerUnit.cxx:280
 TPacketizerUnit.cxx:281
 TPacketizerUnit.cxx:282
 TPacketizerUnit.cxx:283
 TPacketizerUnit.cxx:284
 TPacketizerUnit.cxx:285
 TPacketizerUnit.cxx:286
 TPacketizerUnit.cxx:287
 TPacketizerUnit.cxx:288
 TPacketizerUnit.cxx:289
 TPacketizerUnit.cxx:290
 TPacketizerUnit.cxx:291
 TPacketizerUnit.cxx:292
 TPacketizerUnit.cxx:293
 TPacketizerUnit.cxx:294
 TPacketizerUnit.cxx:295
 TPacketizerUnit.cxx:296
 TPacketizerUnit.cxx:297
 TPacketizerUnit.cxx:298
 TPacketizerUnit.cxx:299
 TPacketizerUnit.cxx:300
 TPacketizerUnit.cxx:301
 TPacketizerUnit.cxx:302
 TPacketizerUnit.cxx:303
 TPacketizerUnit.cxx:304
 TPacketizerUnit.cxx:305
 TPacketizerUnit.cxx:306
 TPacketizerUnit.cxx:307
 TPacketizerUnit.cxx:308
 TPacketizerUnit.cxx:309
 TPacketizerUnit.cxx:310
 TPacketizerUnit.cxx:311
 TPacketizerUnit.cxx:312
 TPacketizerUnit.cxx:313
 TPacketizerUnit.cxx:314
 TPacketizerUnit.cxx:315
 TPacketizerUnit.cxx:316
 TPacketizerUnit.cxx:317
 TPacketizerUnit.cxx:318
 TPacketizerUnit.cxx:319
 TPacketizerUnit.cxx:320
 TPacketizerUnit.cxx:321
 TPacketizerUnit.cxx:322
 TPacketizerUnit.cxx:323
 TPacketizerUnit.cxx:324
 TPacketizerUnit.cxx:325
 TPacketizerUnit.cxx:326
 TPacketizerUnit.cxx:327
 TPacketizerUnit.cxx:328
 TPacketizerUnit.cxx:329
 TPacketizerUnit.cxx:330
 TPacketizerUnit.cxx:331
 TPacketizerUnit.cxx:332
 TPacketizerUnit.cxx:333
 TPacketizerUnit.cxx:334
 TPacketizerUnit.cxx:335
 TPacketizerUnit.cxx:336
 TPacketizerUnit.cxx:337
 TPacketizerUnit.cxx:338
 TPacketizerUnit.cxx:339
 TPacketizerUnit.cxx:340
 TPacketizerUnit.cxx:341
 TPacketizerUnit.cxx:342
 TPacketizerUnit.cxx:343
 TPacketizerUnit.cxx:344
 TPacketizerUnit.cxx:345
 TPacketizerUnit.cxx:346
 TPacketizerUnit.cxx:347
 TPacketizerUnit.cxx:348
 TPacketizerUnit.cxx:349
 TPacketizerUnit.cxx:350
 TPacketizerUnit.cxx:351
 TPacketizerUnit.cxx:352
 TPacketizerUnit.cxx:353
 TPacketizerUnit.cxx:354
 TPacketizerUnit.cxx:355
 TPacketizerUnit.cxx:356
 TPacketizerUnit.cxx:357
 TPacketizerUnit.cxx:358
 TPacketizerUnit.cxx:359
 TPacketizerUnit.cxx:360
 TPacketizerUnit.cxx:361
 TPacketizerUnit.cxx:362
 TPacketizerUnit.cxx:363
 TPacketizerUnit.cxx:364
 TPacketizerUnit.cxx:365
 TPacketizerUnit.cxx:366
 TPacketizerUnit.cxx:367
 TPacketizerUnit.cxx:368
 TPacketizerUnit.cxx:369
 TPacketizerUnit.cxx:370
 TPacketizerUnit.cxx:371
 TPacketizerUnit.cxx:372
 TPacketizerUnit.cxx:373
 TPacketizerUnit.cxx:374
 TPacketizerUnit.cxx:375
 TPacketizerUnit.cxx:376
 TPacketizerUnit.cxx:377
 TPacketizerUnit.cxx:378
 TPacketizerUnit.cxx:379
 TPacketizerUnit.cxx:380
 TPacketizerUnit.cxx:381
 TPacketizerUnit.cxx:382
 TPacketizerUnit.cxx:383
 TPacketizerUnit.cxx:384
 TPacketizerUnit.cxx:385
 TPacketizerUnit.cxx:386
 TPacketizerUnit.cxx:387
 TPacketizerUnit.cxx:388
 TPacketizerUnit.cxx:389
 TPacketizerUnit.cxx:390
 TPacketizerUnit.cxx:391
 TPacketizerUnit.cxx:392
 TPacketizerUnit.cxx:393
 TPacketizerUnit.cxx:394
 TPacketizerUnit.cxx:395
 TPacketizerUnit.cxx:396
 TPacketizerUnit.cxx:397
 TPacketizerUnit.cxx:398
 TPacketizerUnit.cxx:399
 TPacketizerUnit.cxx:400
 TPacketizerUnit.cxx:401
 TPacketizerUnit.cxx:402
 TPacketizerUnit.cxx:403
 TPacketizerUnit.cxx:404
 TPacketizerUnit.cxx:405
 TPacketizerUnit.cxx:406
 TPacketizerUnit.cxx:407
 TPacketizerUnit.cxx:408
 TPacketizerUnit.cxx:409
 TPacketizerUnit.cxx:410
 TPacketizerUnit.cxx:411
 TPacketizerUnit.cxx:412
 TPacketizerUnit.cxx:413
 TPacketizerUnit.cxx:414
 TPacketizerUnit.cxx:415
 TPacketizerUnit.cxx:416
 TPacketizerUnit.cxx:417
 TPacketizerUnit.cxx:418
 TPacketizerUnit.cxx:419
 TPacketizerUnit.cxx:420
 TPacketizerUnit.cxx:421
 TPacketizerUnit.cxx:422
 TPacketizerUnit.cxx:423
 TPacketizerUnit.cxx:424
 TPacketizerUnit.cxx:425
 TPacketizerUnit.cxx:426
 TPacketizerUnit.cxx:427
 TPacketizerUnit.cxx:428
 TPacketizerUnit.cxx:429
 TPacketizerUnit.cxx:430
 TPacketizerUnit.cxx:431
 TPacketizerUnit.cxx:432
 TPacketizerUnit.cxx:433
 TPacketizerUnit.cxx:434
 TPacketizerUnit.cxx:435
 TPacketizerUnit.cxx:436
 TPacketizerUnit.cxx:437
 TPacketizerUnit.cxx:438
 TPacketizerUnit.cxx:439
 TPacketizerUnit.cxx:440
 TPacketizerUnit.cxx:441
 TPacketizerUnit.cxx:442
 TPacketizerUnit.cxx:443
 TPacketizerUnit.cxx:444
 TPacketizerUnit.cxx:445
 TPacketizerUnit.cxx:446
 TPacketizerUnit.cxx:447
 TPacketizerUnit.cxx:448
 TPacketizerUnit.cxx:449
 TPacketizerUnit.cxx:450
 TPacketizerUnit.cxx:451
 TPacketizerUnit.cxx:452
 TPacketizerUnit.cxx:453
 TPacketizerUnit.cxx:454
 TPacketizerUnit.cxx:455
 TPacketizerUnit.cxx:456
 TPacketizerUnit.cxx:457
 TPacketizerUnit.cxx:458
 TPacketizerUnit.cxx:459
 TPacketizerUnit.cxx:460
 TPacketizerUnit.cxx:461
 TPacketizerUnit.cxx:462
 TPacketizerUnit.cxx:463
 TPacketizerUnit.cxx:464
 TPacketizerUnit.cxx:465
 TPacketizerUnit.cxx:466
 TPacketizerUnit.cxx:467
 TPacketizerUnit.cxx:468
 TPacketizerUnit.cxx:469
 TPacketizerUnit.cxx:470
 TPacketizerUnit.cxx:471
 TPacketizerUnit.cxx:472
 TPacketizerUnit.cxx:473
 TPacketizerUnit.cxx:474
 TPacketizerUnit.cxx:475
 TPacketizerUnit.cxx:476
 TPacketizerUnit.cxx:477
 TPacketizerUnit.cxx:478
 TPacketizerUnit.cxx:479
 TPacketizerUnit.cxx:480
 TPacketizerUnit.cxx:481
 TPacketizerUnit.cxx:482
 TPacketizerUnit.cxx:483
 TPacketizerUnit.cxx:484
 TPacketizerUnit.cxx:485
 TPacketizerUnit.cxx:486
 TPacketizerUnit.cxx:487
 TPacketizerUnit.cxx:488
 TPacketizerUnit.cxx:489
 TPacketizerUnit.cxx:490
 TPacketizerUnit.cxx:491
 TPacketizerUnit.cxx:492
 TPacketizerUnit.cxx:493
 TPacketizerUnit.cxx:494
 TPacketizerUnit.cxx:495
 TPacketizerUnit.cxx:496
 TPacketizerUnit.cxx:497
 TPacketizerUnit.cxx:498
 TPacketizerUnit.cxx:499
 TPacketizerUnit.cxx:500
 TPacketizerUnit.cxx:501
 TPacketizerUnit.cxx:502
 TPacketizerUnit.cxx:503
 TPacketizerUnit.cxx:504
 TPacketizerUnit.cxx:505
 TPacketizerUnit.cxx:506
 TPacketizerUnit.cxx:507
 TPacketizerUnit.cxx:508
 TPacketizerUnit.cxx:509
 TPacketizerUnit.cxx:510
 TPacketizerUnit.cxx:511
 TPacketizerUnit.cxx:512
 TPacketizerUnit.cxx:513
 TPacketizerUnit.cxx:514
 TPacketizerUnit.cxx:515
 TPacketizerUnit.cxx:516
 TPacketizerUnit.cxx:517
 TPacketizerUnit.cxx:518
 TPacketizerUnit.cxx:519
 TPacketizerUnit.cxx:520
 TPacketizerUnit.cxx:521
 TPacketizerUnit.cxx:522
 TPacketizerUnit.cxx:523
 TPacketizerUnit.cxx:524
 TPacketizerUnit.cxx:525
 TPacketizerUnit.cxx:526
 TPacketizerUnit.cxx:527
 TPacketizerUnit.cxx:528
 TPacketizerUnit.cxx:529
 TPacketizerUnit.cxx:530
 TPacketizerUnit.cxx:531
 TPacketizerUnit.cxx:532
 TPacketizerUnit.cxx:533
 TPacketizerUnit.cxx:534
 TPacketizerUnit.cxx:535
 TPacketizerUnit.cxx:536
 TPacketizerUnit.cxx:537
 TPacketizerUnit.cxx:538
 TPacketizerUnit.cxx:539
 TPacketizerUnit.cxx:540
 TPacketizerUnit.cxx:541
 TPacketizerUnit.cxx:542
 TPacketizerUnit.cxx:543
 TPacketizerUnit.cxx:544
 TPacketizerUnit.cxx:545
 TPacketizerUnit.cxx:546
 TPacketizerUnit.cxx:547
 TPacketizerUnit.cxx:548
 TPacketizerUnit.cxx:549
 TPacketizerUnit.cxx:550
 TPacketizerUnit.cxx:551
 TPacketizerUnit.cxx:552
 TPacketizerUnit.cxx:553
 TPacketizerUnit.cxx:554
 TPacketizerUnit.cxx:555
 TPacketizerUnit.cxx:556
 TPacketizerUnit.cxx:557
 TPacketizerUnit.cxx:558
 TPacketizerUnit.cxx:559
 TPacketizerUnit.cxx:560
 TPacketizerUnit.cxx:561
 TPacketizerUnit.cxx:562
 TPacketizerUnit.cxx:563
 TPacketizerUnit.cxx:564
 TPacketizerUnit.cxx:565
 TPacketizerUnit.cxx:566
 TPacketizerUnit.cxx:567
 TPacketizerUnit.cxx:568
 TPacketizerUnit.cxx:569
 TPacketizerUnit.cxx:570
 TPacketizerUnit.cxx:571
 TPacketizerUnit.cxx:572
 TPacketizerUnit.cxx:573
 TPacketizerUnit.cxx:574
 TPacketizerUnit.cxx:575
 TPacketizerUnit.cxx:576
 TPacketizerUnit.cxx:577
 TPacketizerUnit.cxx:578
 TPacketizerUnit.cxx:579
 TPacketizerUnit.cxx:580
 TPacketizerUnit.cxx:581
 TPacketizerUnit.cxx:582
 TPacketizerUnit.cxx:583
 TPacketizerUnit.cxx:584
 TPacketizerUnit.cxx:585
 TPacketizerUnit.cxx:586
 TPacketizerUnit.cxx:587
 TPacketizerUnit.cxx:588
 TPacketizerUnit.cxx:589
 TPacketizerUnit.cxx:590
 TPacketizerUnit.cxx:591
 TPacketizerUnit.cxx:592
 TPacketizerUnit.cxx:593
 TPacketizerUnit.cxx:594
 TPacketizerUnit.cxx:595
 TPacketizerUnit.cxx:596
 TPacketizerUnit.cxx:597
 TPacketizerUnit.cxx:598
 TPacketizerUnit.cxx:599
 TPacketizerUnit.cxx:600
 TPacketizerUnit.cxx:601
 TPacketizerUnit.cxx:602
 TPacketizerUnit.cxx:603
 TPacketizerUnit.cxx:604
 TPacketizerUnit.cxx:605
 TPacketizerUnit.cxx:606
 TPacketizerUnit.cxx:607
 TPacketizerUnit.cxx:608
 TPacketizerUnit.cxx:609
 TPacketizerUnit.cxx:610
 TPacketizerUnit.cxx:611