Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooRealMPFE.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 /**
18 \file RooRealMPFE.cxx
19 \class RooRealMPFE
20 \ingroup Roofitcore
21 
22 RooRealMPFE is the multi-processor front-end for parallel calculation
23 of RooAbsReal objects. Each RooRealMPFE forks a process that calculates
24 the value of the proxies RooAbsReal object. The (re)calculation of
25 the proxied object is started asynchronously with the calculate() option.
26 A subsequent call to getVal() will return the calculated value when available
27 If the calculation is still in progress when getVal() is called it blocks
28 the calling process until the calculation is done. The forked calculation process
29 is terminated when the front-end object is deleted
30 Simple use demonstration
31 
32 ~~~{.cpp}
33 RooAbsReal* slowFunc ;
34 
35 Double_t val = slowFunc->getVal() // Evaluate slowFunc in current process
36 
37 RooRealMPFE mpfe("mpfe","frontend to slowFunc",*slowFunc) ;
38 mpfe.calculate() ; // Start calculation of slow-func in remote process
39  // .. do other stuff here ..
40 Double_t val = mpfe.getVal() // Wait for remote calculation to finish and retrieve value
41 ~~~
42 
43 For general multiprocessing in ROOT, please refer to the TProcessExecutor class.
44 
45 **/
46 
47 #include "Riostream.h"
48 #include "RooFit.h"
49 
50 #ifndef _WIN32
51 #include "BidirMMapPipe.h"
52 #endif
53 
54 #include <cstdlib>
55 #include <sstream>
56 #include "RooRealMPFE.h"
57 #include "RooArgSet.h"
58 #include "RooAbsCategory.h"
59 #include "RooRealVar.h"
60 #include "RooCategory.h"
61 #include "RooMPSentinel.h"
62 #include "RooMsgService.h"
63 #include "RooNLLVar.h"
64 #include "RooTrace.h"
65 
66 #include "TSystem.h"
67 
68 RooMPSentinel RooRealMPFE::_sentinel ;
69 
70 using namespace std;
71 using namespace RooFit;
72 
73 ClassImp(RooRealMPFE);
74  ;
75 
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 /// Construct front-end object for object 'arg' whose evaluation will be calculated
79 /// asynchronously in a separate process. If calcInline is true the value of 'arg'
80 /// is calculate synchronously in the current process.
81 
82 RooRealMPFE::RooRealMPFE(const char *name, const char *title, RooAbsReal& arg, Bool_t calcInline) :
83  RooAbsReal(name,title),
84  _state(Initialize),
85  _arg("arg","arg",this,arg),
86  _vars("vars","vars",this),
87  _calcInProgress(kFALSE),
88  _verboseClient(kFALSE),
89  _verboseServer(kFALSE),
90  _inlineMode(calcInline),
91  _remoteEvalErrorLoggingState(RooAbsReal::PrintErrors),
92  _pipe(0),
93  _updateMaster(0),
94  _retrieveDispatched(kFALSE), _evalCarry(0.)
95 {
96 #ifdef _WIN32
97  _inlineMode = kTRUE;
98 #endif
99  initVars() ;
100  _sentinel.add(*this) ;
101 
102 }
103 
104 
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Copy constructor. Initializes in clean state so that upon eval
108 /// this instance will create its own server processes
109 
110 RooRealMPFE::RooRealMPFE(const RooRealMPFE& other, const char* name) :
111  RooAbsReal(other, name),
112  _state(Initialize),
113  _arg("arg",this,other._arg),
114  _vars("vars",this,other._vars),
115  _calcInProgress(kFALSE),
116  _verboseClient(other._verboseClient),
117  _verboseServer(other._verboseServer),
118  _inlineMode(other._inlineMode),
119  _forceCalc(other._forceCalc),
120  _remoteEvalErrorLoggingState(other._remoteEvalErrorLoggingState),
121  _pipe(0),
122  _updateMaster(0),
123  _retrieveDispatched(kFALSE), _evalCarry(other._evalCarry)
124 {
125  initVars() ;
126  _sentinel.add(*this) ;
127 }
128 
129 
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 /// Destructor
133 
134 RooRealMPFE::~RooRealMPFE()
135 {
136  if (_state==Client) standby();
137  _sentinel.remove(*this);
138 }
139 
140 
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Initialize list of variables of front-end argument 'arg'
144 
145 void RooRealMPFE::initVars()
146 {
147  // Empty current lists
148  _vars.removeAll() ;
149  _saveVars.removeAll() ;
150 
151  // Retrieve non-constant parameters
152  RooArgSet* vars = _arg.arg().getParameters(RooArgSet()) ;
153  //RooArgSet* ncVars = (RooArgSet*) vars->selectByAttrib("Constant",kFALSE) ;
154  RooArgList varList(*vars) ;
155 
156  // Save in lists
157  _vars.add(varList) ;
158  _saveVars.addClone(varList) ;
159  _valueChanged.resize(_vars.getSize()) ;
160  _constChanged.resize(_vars.getSize()) ;
161 
162  // Force next calculation
163  _forceCalc = kTRUE ;
164 
165  delete vars ;
166  //delete ncVars ;
167 }
168 
169 Double_t RooRealMPFE::getCarry() const
170 {
171  if (_inlineMode) {
172  RooAbsTestStatistic* tmp = dynamic_cast<RooAbsTestStatistic*>(_arg.absArg());
173  if (tmp) return tmp->getCarry();
174  else return 0.;
175  } else {
176  return _evalCarry;
177  }
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// Initialize the remote process and message passing
182 /// pipes between current process and remote process
183 
184 void RooRealMPFE::initialize()
185 {
186  // Trivial case: Inline mode
187  if (_inlineMode) {
188  _state = Inline ;
189  return ;
190  }
191 
192 #ifndef _WIN32
193  // Clear eval error log prior to forking
194  // to avoid confusions...
195  clearEvalErrorLog() ;
196  // Fork server process and setup IPC
197  _pipe = new BidirMMapPipe();
198 
199  if (_pipe->isChild()) {
200  // Start server loop
201  RooTrace::callgrind_zero() ;
202  _state = Server ;
203  serverLoop();
204 
205  // Kill server at end of service
206  if (_verboseServer) ccoutD(Minimization) << "RooRealMPFE::initialize(" <<
207  GetName() << ") server process terminating" << endl ;
208 
209  delete _arg.absArg();
210  delete _pipe;
211  _exit(0) ;
212  } else {
213  // Client process - fork successul
214  if (_verboseClient) ccoutD(Minimization) << "RooRealMPFE::initialize(" <<
215  GetName() << ") successfully forked server process " <<
216  _pipe->pidOtherEnd() << endl ;
217  _state = Client ;
218  _calcInProgress = kFALSE ;
219  }
220 #endif // _WIN32
221 }
222 
223 
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// Server loop of remote processes. This function will return
227 /// only when an incoming TERMINATE message is received.
228 
229 void RooRealMPFE::serverLoop()
230 {
231 #ifndef _WIN32
232  int msg ;
233 
234  Int_t idx, index, numErrors ;
235  Double_t value ;
236  Bool_t isConst ;
237 
238  clearEvalErrorLog() ;
239 
240  while(*_pipe && !_pipe->eof()) {
241  *_pipe >> msg;
242  if (Terminate == msg) {
243  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
244  << ") IPC fromClient> Terminate" << endl;
245  // send terminate acknowledged to client
246  *_pipe << msg << BidirMMapPipe::flush;
247  break;
248  }
249 
250  switch (msg) {
251  case SendReal:
252  {
253  *_pipe >> idx >> value >> isConst;
254  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
255  << ") IPC fromClient> SendReal [" << idx << "]=" << value << endl ;
256  RooRealVar* rvar = (RooRealVar*)_vars.at(idx) ;
257  rvar->setVal(value) ;
258  if (rvar->isConstant() != isConst) {
259  rvar->setConstant(isConst) ;
260  }
261  }
262  break ;
263 
264  case SendCat:
265  {
266  *_pipe >> idx >> index;
267  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
268  << ") IPC fromClient> SendCat [" << idx << "]=" << index << endl ;
269  ((RooCategory*)_vars.at(idx))->setIndex(index) ;
270  }
271  break ;
272 
273  case Calculate:
274  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
275  << ") IPC fromClient> Calculate" << endl ;
276  _value = _arg ;
277  break ;
278 
279  case CalculateNoOffset:
280  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
281  << ") IPC fromClient> Calculate" << endl ;
282 
283  RooAbsReal::setHideOffset(kFALSE) ;
284  _value = _arg ;
285  RooAbsReal::setHideOffset(kTRUE) ;
286  break ;
287 
288  case Retrieve:
289  {
290  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
291  << ") IPC fromClient> Retrieve" << endl ;
292  msg = ReturnValue;
293  numErrors = numEvalErrors();
294  *_pipe << msg << _value << getCarry() << numErrors;
295 
296  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
297  << ") IPC toClient> ReturnValue " << _value << " NumError " << numErrors << endl ;
298 
299  if (numErrors) {
300  // Loop over errors
301  std::string objidstr;
302  {
303  ostringstream oss2;
304  // Format string with object identity as this cannot be evaluated on the other side
305  oss2 << "PID" << gSystem->GetPid() << "/";
306  printStream(oss2,kName|kClassName|kArgs,kInline);
307  objidstr = oss2.str();
308  }
309  std::map<const RooAbsArg*,pair<string,list<EvalError> > >::const_iterator iter = evalErrorIter();
310  const RooAbsArg* ptr = 0;
311  for (int i = 0; i < numEvalErrorItems(); ++i) {
312  list<EvalError>::const_iterator iter2 = iter->second.second.begin();
313  for (; iter->second.second.end() != iter2; ++iter2) {
314  ptr = iter->first;
315  *_pipe << ptr << iter2->_msg << iter2->_srvval << objidstr;
316  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
317  << ") IPC toClient> sending error log Arg " << iter->first << " Msg " << iter2->_msg << endl ;
318  }
319  }
320  // let other end know that we're done with the list of errors
321  ptr = 0;
322  *_pipe << ptr;
323  // Clear error list on local side
324  clearEvalErrorLog();
325  }
326  *_pipe << BidirMMapPipe::flush;
327  }
328  break;
329 
330  case ConstOpt:
331  {
332  Bool_t doTrack ;
333  int code;
334  *_pipe >> code >> doTrack;
335  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
336  << ") IPC fromClient> ConstOpt " << code << " doTrack = " << (doTrack?"T":"F") << endl ;
337  ((RooAbsReal&)_arg.arg()).constOptimizeTestStatistic(static_cast<RooAbsArg::ConstOpCode>(code),doTrack) ;
338  break ;
339  }
340 
341  case Verbose:
342  {
343  Bool_t flag ;
344  *_pipe >> flag;
345  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
346  << ") IPC fromClient> Verbose " << (flag?1:0) << endl ;
347  _verboseServer = flag ;
348  }
349  break ;
350 
351 
352  case ApplyNLLW2:
353  {
354  Bool_t flag ;
355  *_pipe >> flag;
356  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
357  << ") IPC fromClient> ApplyNLLW2 " << (flag?1:0) << endl ;
358 
359  // Do application of weight-squared here
360  doApplyNLLW2(flag) ;
361  }
362  break ;
363 
364  case EnableOffset:
365  {
366  Bool_t flag ;
367  *_pipe >> flag;
368  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
369  << ") IPC fromClient> EnableOffset " << (flag?1:0) << endl ;
370 
371  // Enable likelihoof offsetting here
372  ((RooAbsReal&)_arg.arg()).enableOffsetting(flag) ;
373  }
374  break ;
375 
376  case LogEvalError:
377  {
378  int iflag2;
379  *_pipe >> iflag2;
380  RooAbsReal::ErrorLoggingMode flag2 = static_cast<RooAbsReal::ErrorLoggingMode>(iflag2);
381  RooAbsReal::setEvalErrorLoggingMode(flag2) ;
382  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
383  << ") IPC fromClient> LogEvalError flag = " << flag2 << endl ;
384  }
385  break ;
386 
387 
388  default:
389  if (_verboseServer) cout << "RooRealMPFE::serverLoop(" << GetName()
390  << ") IPC fromClient> Unknown message (code = " << msg << ")" << endl ;
391  break ;
392  }
393  }
394 
395 #endif // _WIN32
396 }
397 
398 
399 
400 ////////////////////////////////////////////////////////////////////////////////
401 /// Client-side function that instructs server process to start
402 /// asynchronuous (re)calculation of function value. This function
403 /// returns immediately. The calculated value can be retrieved
404 /// using getVal()
405 
406 void RooRealMPFE::calculate() const
407 {
408 
409  // Start asynchronous calculation of arg value
410  if (_state==Initialize) {
411  // cout << "RooRealMPFE::calculate(" << GetName() << ") initializing" << endl ;
412  const_cast<RooRealMPFE*>(this)->initialize() ;
413  }
414 
415  // Inline mode -- Calculate value now
416  if (_state==Inline) {
417  // cout << "RooRealMPFE::calculate(" << GetName() << ") performing Inline calculation NOW" << endl ;
418  _value = _arg ;
419  clearValueDirty() ;
420  }
421 
422 #ifndef _WIN32
423  // Compare current value of variables with saved values and send changes to server
424  if (_state==Client) {
425  // cout << "RooRealMPFE::calculate(" << GetName() << ") state is Client trigger remote calculation" << endl ;
426  Int_t i(0) ;
427  RooFIter viter = _vars.fwdIterator() ;
428  RooFIter siter = _saveVars.fwdIterator() ;
429 
430  //for (i=0 ; i<_vars.getSize() ; i++) {
431  RooAbsArg *var, *saveVar ;
432  while((var = viter.next())) {
433  saveVar = siter.next() ;
434 
435  //Bool_t valChanged = !(*var==*saveVar) ;
436  Bool_t valChanged,constChanged ;
437  if (!_updateMaster) {
438  valChanged = !var->isIdentical(*saveVar,kTRUE) ;
439  constChanged = (var->isConstant() != saveVar->isConstant()) ;
440  _valueChanged[i] = valChanged ;
441  _constChanged[i] = constChanged ;
442  } else {
443  valChanged = _updateMaster->_valueChanged[i] ;
444  constChanged = _updateMaster->_constChanged[i] ;
445  }
446 
447  if ( valChanged || constChanged || _forceCalc) {
448  //cout << "RooRealMPFE::calculate(" << GetName() << " variable " << var->GetName() << " changed " << endl ;
449  if (_verboseClient) cout << "RooRealMPFE::calculate(" << GetName()
450  << ") variable " << _vars.at(i)->GetName() << " changed" << endl ;
451  if (constChanged) {
452  ((RooRealVar*)saveVar)->setConstant(var->isConstant()) ;
453  }
454  saveVar->copyCache(var) ;
455 
456  // send message to server
457  if (dynamic_cast<RooAbsReal*>(var)) {
458  int msg = SendReal ;
459  Double_t val = ((RooAbsReal*)var)->getVal() ;
460  Bool_t isC = var->isConstant() ;
461  *_pipe << msg << i << val << isC;
462 
463  if (_verboseServer) cout << "RooRealMPFE::calculate(" << GetName()
464  << ") IPC toServer> SendReal [" << i << "]=" << val << (isC?" (Constant)":"") << endl ;
465  } else if (dynamic_cast<RooAbsCategory*>(var)) {
466  int msg = SendCat ;
467  UInt_t idx = ((RooAbsCategory*)var)->getIndex() ;
468  *_pipe << msg << i << idx;
469  if (_verboseServer) cout << "RooRealMPFE::calculate(" << GetName()
470  << ") IPC toServer> SendCat [" << i << "]=" << idx << endl ;
471  }
472  }
473  i++ ;
474  }
475 
476  int msg = hideOffset() ? Calculate : CalculateNoOffset;
477  *_pipe << msg;
478  if (_verboseServer) cout << "RooRealMPFE::calculate(" << GetName()
479  << ") IPC toServer> Calculate " << endl ;
480 
481  // Clear dirty state and mark that calculation request was dispatched
482  clearValueDirty() ;
483  _calcInProgress = kTRUE ;
484  _forceCalc = kFALSE ;
485 
486  msg = Retrieve ;
487  *_pipe << msg << BidirMMapPipe::flush;
488  if (_verboseServer) cout << "RooRealMPFE::evaluate(" << GetName()
489  << ") IPC toServer> Retrieve " << endl ;
490  _retrieveDispatched = kTRUE ;
491 
492  } else if (_state!=Inline) {
493  cout << "RooRealMPFE::calculate(" << GetName()
494  << ") ERROR not in Client or Inline mode" << endl ;
495  }
496 
497 
498 #endif // _WIN32
499 }
500 
501 
502 
503 
504 ////////////////////////////////////////////////////////////////////////////////
505 /// If value needs recalculation and calculation has not beed started
506 /// with a call to calculate() start it now. This function blocks
507 /// until remote process has finished calculation and returns
508 /// remote value
509 
510 Double_t RooRealMPFE::getValV(const RooArgSet* /*nset*/) const
511 {
512 
513  if (isValueDirty()) {
514  // Cache is dirty, no calculation has been started yet
515  //cout << "RooRealMPFE::getValF(" << GetName() << ") cache is dirty, caling calculate and evaluate" << endl ;
516  calculate() ;
517  _value = evaluate() ;
518  } else if (_calcInProgress) {
519  //cout << "RooRealMPFE::getValF(" << GetName() << ") calculation in progress, calling evaluate" << endl ;
520  // Cache is clean and calculation is in progress
521  _value = evaluate() ;
522  } else {
523  //cout << "RooRealMPFE::getValF(" << GetName() << ") cache is clean, doing nothing" << endl ;
524  // Cache is clean and calculated value is in cache
525  }
526 
527 // cout << "RooRealMPFE::getValV(" << GetName() << ") value = " << Form("%5.10f",_value) << endl ;
528  return _value ;
529 }
530 
531 
532 
533 ////////////////////////////////////////////////////////////////////////////////
534 /// Send message to server process to retrieve output value
535 /// If error were logged use logEvalError() on remote side
536 /// transfer those errors to the local eval error queue.
537 
538 Double_t RooRealMPFE::evaluate() const
539 {
540  // Retrieve value of arg
541  Double_t return_value = 0;
542  if (_state==Inline) {
543  return_value = _arg ;
544  } else if (_state==Client) {
545 #ifndef _WIN32
546  bool needflush = false;
547  int msg;
548  Double_t value;
549 
550  // If current error loggin state is not the same as remote state
551  // update the remote state
552  if (evalErrorLoggingMode() != _remoteEvalErrorLoggingState) {
553  msg = LogEvalError ;
554  RooAbsReal::ErrorLoggingMode flag = evalErrorLoggingMode() ;
555  *_pipe << msg << flag;
556  needflush = true;
557  _remoteEvalErrorLoggingState = evalErrorLoggingMode() ;
558  }
559 
560  if (!_retrieveDispatched) {
561  msg = Retrieve ;
562  *_pipe << msg;
563  needflush = true;
564  if (_verboseServer) cout << "RooRealMPFE::evaluate(" << GetName()
565  << ") IPC toServer> Retrieve " << endl ;
566  }
567  if (needflush) *_pipe << BidirMMapPipe::flush;
568  _retrieveDispatched = kFALSE ;
569 
570 
571  Int_t numError;
572 
573  *_pipe >> msg >> value >> _evalCarry >> numError;
574 
575  if (msg!=ReturnValue) {
576  cout << "RooRealMPFE::evaluate(" << GetName()
577  << ") ERROR: unexpected message from server process: " << msg << endl ;
578  return 0 ;
579  }
580  if (_verboseServer) cout << "RooRealMPFE::evaluate(" << GetName()
581  << ") IPC fromServer> ReturnValue " << value << endl ;
582 
583  if (_verboseServer) cout << "RooRealMPFE::evaluate(" << GetName()
584  << ") IPC fromServer> NumErrors " << numError << endl ;
585  if (numError) {
586  // Retrieve remote errors and feed into local error queue
587  char *msgbuf1 = 0, *msgbuf2 = 0, *msgbuf3 = 0;
588  RooAbsArg *ptr = 0;
589  while (true) {
590  *_pipe >> ptr;
591  if (!ptr) break;
592  *_pipe >> msgbuf1 >> msgbuf2 >> msgbuf3;
593  if (_verboseServer) cout << "RooRealMPFE::evaluate(" << GetName()
594  << ") IPC fromServer> retrieving error log Arg " << ptr << " Msg " << msgbuf1 << endl ;
595 
596  logEvalError(reinterpret_cast<RooAbsReal*>(ptr),msgbuf3,msgbuf1,msgbuf2) ;
597  }
598  std::free(msgbuf1);
599  std::free(msgbuf2);
600  std::free(msgbuf3);
601  }
602 
603  // Mark end of calculation in progress
604  _calcInProgress = kFALSE ;
605  return_value = value ;
606 #endif // _WIN32
607  }
608 
609  return return_value;
610 }
611 
612 
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 /// Terminate remote server process and return front-end class
616 /// to standby mode. Calls to calculate() or evaluate() after
617 /// this call will automatically recreated the server process.
618 
619 void RooRealMPFE::standby()
620 {
621 #ifndef _WIN32
622  if (_state==Client) {
623  if (_pipe->good()) {
624  // Terminate server process ;
625  if (_verboseServer) cout << "RooRealMPFE::standby(" << GetName()
626  << ") IPC toServer> Terminate " << endl;
627  int msg = Terminate;
628  *_pipe << msg << BidirMMapPipe::flush;
629  // read handshake
630  msg = 0;
631  *_pipe >> msg;
632  if (Terminate != msg || 0 != _pipe->close()) {
633  std::cerr << "In " << __func__ << "(" << __FILE__ ", " << __LINE__ <<
634  "): Server shutdown failed." << std::endl;
635  }
636  } else {
637  if (_verboseServer) {
638  std::cerr << "In " << __func__ << "(" << __FILE__ ", " <<
639  __LINE__ << "): Pipe has already shut down, not sending "
640  "Terminate to server." << std::endl;
641  }
642  }
643  // Close pipes
644  delete _pipe;
645  _pipe = 0;
646 
647  // Revert to initialize state
648  _state = Initialize;
649  }
650 #endif // _WIN32
651 }
652 
653 
654 
655 ////////////////////////////////////////////////////////////////////////////////
656 /// Intercept call to optimize constant term in test statistics
657 /// and forward it to object on server side.
658 
659 void RooRealMPFE::constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTracking)
660 {
661 #ifndef _WIN32
662  if (_state==Client) {
663 
664  int msg = ConstOpt ;
665  int op = opcode;
666  *_pipe << msg << op << doAlsoTracking;
667  if (_verboseServer) cout << "RooRealMPFE::constOptimize(" << GetName()
668  << ") IPC toServer> ConstOpt " << opcode << endl ;
669 
670  initVars() ;
671  }
672 #endif // _WIN32
673 
674  if (_state==Inline) {
675  ((RooAbsReal&)_arg.arg()).constOptimizeTestStatistic(opcode,doAlsoTracking) ;
676  }
677 }
678 
679 
680 
681 ////////////////////////////////////////////////////////////////////////////////
682 /// Control verbose messaging related to inter process communication
683 /// on both client and server side
684 
685 void RooRealMPFE::setVerbose(Bool_t clientFlag, Bool_t serverFlag)
686 {
687 #ifndef _WIN32
688  if (_state==Client) {
689  int msg = Verbose ;
690  *_pipe << msg << serverFlag;
691  if (_verboseServer) cout << "RooRealMPFE::setVerbose(" << GetName()
692  << ") IPC toServer> Verbose " << (serverFlag?1:0) << endl ;
693  }
694 #endif // _WIN32
695  _verboseClient = clientFlag ; _verboseServer = serverFlag ;
696 }
697 
698 
699 ////////////////////////////////////////////////////////////////////////////////
700 /// Control verbose messaging related to inter process communication
701 /// on both client and server side
702 
703 void RooRealMPFE::applyNLLWeightSquared(Bool_t flag)
704 {
705 #ifndef _WIN32
706  if (_state==Client) {
707  int msg = ApplyNLLW2 ;
708  *_pipe << msg << flag;
709  if (_verboseServer) cout << "RooRealMPFE::applyNLLWeightSquared(" << GetName()
710  << ") IPC toServer> ApplyNLLW2 " << (flag?1:0) << endl ;
711  }
712 #endif // _WIN32
713  doApplyNLLW2(flag) ;
714 }
715 
716 
717 ////////////////////////////////////////////////////////////////////////////////
718 
719 void RooRealMPFE::doApplyNLLW2(Bool_t flag)
720 {
721  RooNLLVar* nll = dynamic_cast<RooNLLVar*>(_arg.absArg()) ;
722  if (nll) {
723  nll->applyWeightSquared(flag) ;
724  }
725 }
726 
727 
728 ////////////////////////////////////////////////////////////////////////////////
729 /// Control verbose messaging related to inter process communication
730 /// on both client and server side
731 
732 void RooRealMPFE::enableOffsetting(Bool_t flag)
733 {
734 #ifndef _WIN32
735  if (_state==Client) {
736  int msg = EnableOffset ;
737  *_pipe << msg << flag;
738  if (_verboseServer) cout << "RooRealMPFE::enableOffsetting(" << GetName()
739  << ") IPC toServer> EnableOffset " << (flag?1:0) << endl ;
740  }
741 #endif // _WIN32
742  ((RooAbsReal&)_arg.arg()).enableOffsetting(flag) ;
743 }
744 
745 
746