00001 enum {kCtr =1,kClear = 2,kMake = 3,
00002 startClear=2,contClear=12,endClear=22,
00003 startMake =3,contMake =13,endMake =23,
00004 kMaxMake=100,kMaxMakeSQ = kMaxMake*kMaxMake,
00005 kMaxData =kMaxMake+3
00006 };
00007
00008 class ReadLog {
00009 public:
00010 int fNMakers;
00011 FILE *inp;
00012 THashList hash;
00013 TObjArray mArray;
00014 char line[500];
00015
00016 ReadLog(const char *file) {inp = fopen(file,"r");fNMakers=0;}
00017 const char *Name(int idx) {
00018 if (!idx) return "__ALL__";
00019 TObject *tn = mArray.At(idx); return (tn)? tn->GetName():0;}
00020
00021 const char *Next(int &kind,int &idx,double &exe,double &heap,double &free,double &inc) {
00022 if(!inp) return 0;
00023 kind=0;idx=0;exe=0;heap=0;free=0,inc=0;
00024 TString ts;
00025 char *endMaker,*clear,*ctr,*doPs,*fr,*to,*and;
00026 while(fgets(line,500,inp)) {
00027 doPs = strstr(line,"doPs for");
00028 if (!doPs) continue;
00029 endMaker = strstr(line,"EndMaker");
00030 clear = strstr(line,"Clear");
00031 ctr = strstr(line,"constructor");
00032 kind = 0;
00033 if (ctr ) kind = 1;
00034 if (clear ) kind = 2;
00035 if (endMaker) kind = 3;
00036 if (!kind) continue;
00037 fr = doPs+8 +strspn(doPs+8," \t");
00038 to = strstr(fr,":");
00039 ts = ""; ts.Append(fr,to-fr);
00040 if (!ts.Length()) continue;
00041 fr = strstr(fr,"total"); if (!fr) continue;
00042 fr = strstr(fr,"=" ); if (!fr) continue;
00043 exe = atof(fr+1);
00044 fr = strstr(fr,"heap" ); if (!fr) continue;
00045 fr = strstr(fr,"=" ); if (!fr) continue;
00046 heap = atof(fr+1);
00047 and = strstr(fr,"and");
00048 if (and) free = atof(and+3);
00049 fr = strstr(fr,"(" ); if (!fr) continue;
00050 inc = atof(fr+1);
00051 if (kind==1) continue;
00052 TNamed *tn = (TNamed*)hash.FindObject(ts.Data());
00053 if (!tn) {
00054 tn = new TNamed(ts.Data(),"");
00055 hash.Add(tn);
00056 fNMakers++;
00057 tn->SetUniqueID((UInt_t)fNMakers);
00058 mArray.AddAtAndExpand(tn,fNMakers);
00059 }
00060 idx = tn->GetUniqueID();
00061 return tn->GetName();
00062 }
00063 fclose(inp); inp = 0;
00064 return 0;
00065 }};
00066
00067 class Data4Fit
00068 {
00069 public:
00070
00071 Data4Fit(ReadLog &rr);
00072 int fNEvts;
00073 int fNMk;
00074 TArrayD fDat;
00075
00076 double *GetDat(int evt) {return fDat.GetArray()+evt*(kMaxData);}
00077 double *GetEvt(int evt) {return GetDat(evt)+2;}
00078 double &GetEvtRes(int evt) {return GetEvt(evt)[-1];}
00079 double &GetEvtSiz(int evt) {return GetEvt(evt)[-2];}
00080 };
00081
00082 Data4Fit::Data4Fit(ReadLog &rr)
00083 {
00084 double QQ[kMaxData];
00085 memset(QQ,0,sizeof(double)*kMaxData);
00086 double *Q = QQ+2;
00087 const char *name;
00088 int kind,idx; double exe,heap,free,inc;
00089 fNEvts=0,fNMk=0;
00090 int nkind[4] = {0,0,0,0};
00091 int kase = 0,oldKind=0,num = 0,nmk=0,narr;
00092
00093 while ((name = rr.Next(kind,idx,exe,heap,free,inc))) {
00094 nkind[kind]++;
00095 if (kind<kClear) continue;
00096 num++;
00097
00098
00099 if (!oldKind) { kase = kind; }
00100 else if (kind==oldKind) { kase = kind +10;}
00101 else { kase = oldKind+20;}
00102 fNMk = rr.fNMakers;
00103 SWIT: switch (kase) {
00104
00105 case startClear:
00106 kase = contClear;
00107
00108 case contClear:
00109 if (!nmk) break;
00110 Q[-1] +=inc;
00111 break;
00112
00113 case endClear:
00114 kase = startMake;
00115 if(!nmk) goto SWIT;
00116 narr = fDat.GetSize();
00117 if (narr< (fNEvts+1)*kMaxData) fDat.Set((fNEvts+10)*kMaxData*2);
00118
00119
00120 memcpy(GetDat(fNEvts),QQ,kMaxData*sizeof(double));
00121
00122 fNEvts++;
00123
00124 case startMake:
00125 memset(QQ,0,sizeof(double)*kMaxData);
00126 Q[0]=1.;
00127 kase = contMake;
00128
00129 case contMake:
00130 nmk++;
00131 Q[idx] = inc;
00132 Q[-1 ] += inc;
00133 Q[-2 ] += inc;
00134 break;
00135
00136 case endMake:
00137 kase = startClear;
00138 goto SWIT;
00139
00140 }
00141 oldKind = kind;
00142 }
00143 fNMk = rr.fNMakers;
00144 }
00145
00146 void LeakGraph(char *file);
00147 void LeakFit (char *file);
00148
00149 void LeakFinder(char *file,int kase=1,const char *par1=0)
00150 {
00151 switch (kase) {
00152 case 0: LeakGraph(file); break;
00153 case 1: if (!TClassTable::GetDict("TCL")) {gSystem->Load("libTable");}
00154 LeakFit (file); break;
00155 case 2: LeakCount(file,par1); break;
00156 }
00157 }
00158
00159
00160 void LeakGraph(char *file)
00161 {
00162 TArrayF X[4],XX[2];
00163
00164 ReadLog rr(file);
00165 const char *name;
00166 int kind,idx; double exe,heap,free,inc;
00167 int num = 0,nXX=0;
00168 float yMax =0, yMin = 1000000.,xMax;
00169 while ((name = rr.Next(kind,idx,exe,heap,free,inc))) {
00170
00171 if (kind==kCtr) continue;
00172
00173 int n = X[0].GetSize();
00174 if (num>=n) { for (int i=0;i<4;i++){X[i].Set(n*2+10);}}
00175 X[0][num] = num;
00176 if (yMax < exe ) yMax = exe;
00177 if (yMax < heap) yMax = heap;
00178 if (yMax < free) yMax = free;
00179 if (yMin > exe ) yMin = exe;
00180 if (yMin > heap) yMin = heap;
00181 if (yMin > free) yMin = free;
00182 X[1][num] = exe;
00183 X[2][num] = heap;
00184 X[3][num] = free;
00185
00186 num++;
00187
00188 if (kind!=kClear) continue;
00189 if (strcmp("bfc",name)) continue;
00190 n = XX[0].GetSize();
00191 if (nXX>=n) { for (int i=0;i<2;i++){XX[i].Set(n*2+10);}}
00192 XX[0][nXX]=num;
00193 XX[1][nXX]=heap;
00194 nXX++;
00195 }
00196 int nPoints = num;
00197 yMax *=1.1;
00198 yMin -=0.1*yMax;
00199 xMax = nPoints;
00200 float fact = float(nXX)/nPoints;
00201 xMax = nPoints*fact;
00202 for (int i=0;i<num;i++) {X [0][i] = X [0][i]*fact;}
00203 for (int i=0;i<nXX;i++) {XX[0][i] = XX[0][i]*fact;}
00204
00205 TCanvas *C1 = new TCanvas("LEAK","Memory grow",1);
00206 TGraph *pl[4];
00207 for (int i=0;i<3;i++){pl[i] = new TGraph(nPoints, X[0].GetArray(), X[i+1].GetArray());}
00208 pl[3] = new TGraph(nXX ,XX[0].GetArray(),XX[1 ].GetArray());
00209 pl[0]->SetLineColor(kBlack);
00210 pl[1]->SetLineColor(kBlue );
00211 pl[2]->SetLineColor(kGreen);
00212 pl[3]->SetLineColor(kRed );
00213
00214 pl[0]->SetName("Exe");
00215 pl[1]->SetName("Heap");
00216 pl[2]->SetName("Free");
00217 pl[3]->SetName("Clear");
00218
00219 C1->DrawFrame(0.,yMin,xMax,yMax);
00220 pl[3]->Draw("LP");
00221
00222 for (int i=0;i<3;i++) {if (pl[i]) pl[i]->Draw("LP");}
00223 C1->Modified();
00224 C1->Update();
00225
00226 }
00227
00228
00229 void LeakFit(char *file)
00230 {
00231
00232 int ignore[kMaxMake];
00233 memset(ignore,0,kMaxMake*sizeof(int));
00234 double A[kMaxMake][kMaxMake],B[kMaxMake],Q[kMaxMake],V[kMaxMake];
00235 TCL::vzero(A[0],(kMaxMake)*(kMaxMake));
00236 TCL::vzero(B ,kMaxMake);
00237 TCL::vzero(V ,kMaxMake);
00238
00239 double Corr[5][kMaxMake];
00240 TCL::vzero(Corr[0],5*(kMaxMake));
00241 int nCorr=0;
00242
00243 TCanvas *C1 = new TCanvas("LeakPlot","Leak vs Size",1);
00244 C1->Divide(1,2);
00245
00246 TH2F *H1 = new TH2F("LeakPlot", "Leak vs Size", 100, 0, 50., 100, -0.1, 3.);
00247 TH2F *H2 = new TH2F("LeagPlot", "Leag vs Size", 100, 0, 50., 100, -0.1, 3.);
00248
00249 C1->cd(1); H1->Draw();
00250 C1->cd(2); H2->Draw();
00251
00252 ReadLog RR(file);
00253 Data4Fit FF(RR);
00254 const char *name;
00255 int num = 0,nEvents=0,nMk=0,nFill=0,iWeight=0;
00256
00257 double emptySize = 10;
00258 int skipEvents = 10;
00259 iWeight=0;
00260 nMk = FF.fNMk;
00261 nEvents = FF.fNEvts;
00262 for (int ievt=0;ievt<nEvents;ievt++) {
00263 double diff = FF.GetEvtRes(ievt);
00264 double eSize = FF.GetEvtSiz(ievt);
00265 if (ievt<=skipEvents) continue;
00266 H1->Fill(eSize,diff);
00267 if (eSize < emptySize+0.1) continue;
00268 nFill++;
00269 TCL::ucopy(FF.GetEvt(ievt),Q,nMk+1);
00270
00271 TCL::vadd(V,Q,V,nMk+1);
00272 double Qmax = 0;
00273 for (int i=1;i<=nMk;i++){
00274 if (fabs(Q[i])>Qmax) Qmax=fabs(Q[i]);
00275 if (Q[i]< 0.1*diff) Q[i]=0.;
00276 };
00277
00278 double wt = 1;
00279 if (iWeight==1) wt =1./pow(diff,2);
00280 if (iWeight==2) wt =1./pow(eSize-emptySize,2);
00281 if (iWeight==3) wt =1./pow(Qmax,2);
00282
00283 for (int i1=0;i1<=nMk;i1++){
00284 B[i1]+= diff*Q[i1]*wt;
00285
00286 for (int i2=0;i2<=nMk;i2++){ A[i1][i2] += Q[i1]*Q[i2]*wt;}
00287 }
00288
00289 nCorr++;
00290 for (int i=1;i<=nMk;i++) {
00291 Corr[0][i] += Q[i];
00292 Corr[1][i] += diff;
00293 Corr[2][i] += Q[i]*Q[i];
00294 Corr[3][i] += diff*diff;
00295 Corr[4][i] += diff*Q[i];
00296 }
00297 #
00298
00299 }
00300 int nX = nMk+1;
00301 double scale = 1./nFill;
00302 TCL::vscale(B,scale,B,nX);
00303 TCL::vscale(A[0],scale,A[0],(kMaxMake)*(kMaxMake));
00304
00305
00306 int nneg=1;
00307
00308 while (nneg) {
00309 printf("%d makers %d events filled %d times\n\n",nMk,nEvents,nFill);
00310
00311 for (int ign=0;ign<nX;ign++) {
00312 if(!ignore[ign]) continue;
00313 if(ignore[ign]>0) {
00314 for (int i=0;i<nX;i++) B[i]-=A[i][ign];
00315 for (int i=0;i<nX;i++) {A[i][ign]=0;A[ign][i]=0;}
00316 A[ign][ign]=1; B[ign]=1;
00317 } else {
00318 for (int i=0;i<nX;i++) {A[i][ign]=0;A[ign][i]=0;}
00319 A[ign][ign]=1; B[ign]=0;
00320 }
00321 }
00322 double reg = 0;
00323 for (int i=0;i<nX;i++) {
00324 if (ignore[i]) continue;
00325 if (A[i][i]>reg) reg = A[i][i];
00326 }
00327 reg /=10000.;
00328
00329 TArrayD AA(nX*nX),BB(nX);
00330 for (int i1=0;i1<nX;i1++) {
00331
00332 BB[i1] = B[i1];
00333 for (int i2=0;i2<nX;i2++) {
00334
00335 AA[i1+nX*i2] = A[i1][i2];
00336 if(i1==i2) AA[i1+nX*i2]+=reg;
00337
00338 }}
00339 TCL::trsequ(AA.GetArray(),nX,BB.GetArray(), 1);
00340 nneg=0;
00341 for (int i=1;i<nX;i++) {
00342 if (ignore[i]) continue;
00343 double bj = BB[i];
00344 if (bj < 0.01) {nneg++; ignore[i]=-1;}
00345 if (bj > 1.00) {nneg++; ignore[i]= 1;}
00346 }
00347 }
00348
00349 for (int i=1;i<nX;i++) {
00350 if (ignore[i]<0) continue;
00351 double bj = BB[i];
00352 double est = bj*V[i];
00353 if (fabs(bj ) <= 0.0) continue;
00354 if (fabs(est) <= 0.0) continue;
00355
00356
00357 printf ("Maker(%d) %s \tCorr =%g \tLeak =%g\n",i,RR.Name(i),bj,est);
00358 }
00359
00360
00361
00362 for (int ievt=0;ievt<nEvents;ievt++) {
00363 double diff = FF.GetEvtRes(ievt);
00364 double eSize = FF.GetEvtSiz(ievt);
00365 if (ievt<=skipEvents) continue;
00366 double dot = TCL::vdot(FF.GetEvt(ievt),BB.GetArray(),nX);
00367 H2->Fill(eSize,diff-dot);
00368
00369 }
00370
00371
00372
00373
00374 for (int i=1;i<=nMk;i++) {
00375 for (int j=0;j<5;j++) {Corr[j][i]/=nCorr;}
00376 double x = Corr[0][i];
00377 double r = Corr[1][i];
00378 double xx = Corr[2][i];
00379 double rr = Corr[3][i];
00380 double xr = Corr[4][i];
00381 Corr[2][i]=1.e+10;
00382
00383 double Dxx = xx - x*x;
00384 if (Dxx< 1.e-10) continue;
00385 double Drr = rr - r*r;
00386 double Dxr = xr - x*r;
00387 double chisq = 1.e+10;
00388 double b = Dxr/Dxx;
00389 double a = r-b*x;
00390 double chisq = a*a+b*b*xx+rr+2.*a*b*x-2*a*r-2*b*xr;
00391 Corr[0][i]=a;
00392 Corr[1][i]=b;
00393 if (b<0. || b> 1.2) chisq+=1.e+6;
00394 Corr[2][i]=chisq;
00395 }
00396 int *Idx= (int*)Corr[5];
00397 double *bb = Corr[1];
00398 double *sq = Corr[2];
00399 TMath::Sort(nMk,sq+1,Idx+1,0);
00400 int j;double leak;
00401 for (int i=1;i<=nMk;i++) {
00402 j = Idx[i]+1;
00403 assert(j>0 && j<=nMk);
00404 if (sq[j]>=1.e+10) break;
00405 leak = V[j]*bb[j]/nFill;
00406 printf("%4d - %12s(%d) Chisq =%g Corr = %g Leak=%g\n",i,RR.Name(j),j,sq[j],bb[j],leak);
00407 }
00408 printf("===================End Of LeakFit========================");
00409
00410 }
00411
00412 void LeakCount(char *file, const char *sele)
00413 {
00414
00415 ReadLog rr(file);
00416 const char *name;
00417 int kind,idx; double exe,heap,free,inc;
00418 int num = 0;
00419 double summ = 0;
00420
00421
00422 while ((name = rr.Next(kind,idx,exe,heap,free,inc))) {
00423 if (kind<2) continue;
00424 if (sele && *sele && strcmp(name,sele)) continue;
00425 num++;
00426 summ +=inc;
00427 printf("%4d - %20s \t%d %d \t %12.6f %12.6f %+12.6f\t%12.6f\n",num,name,kind,idx,exe,heap,inc,summ);
00428 }
00429
00430 printf("%s = %d %g\n",sele,num,summ);
00431 }