Version: 9.16.0
OptimizerLoop.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 CEA, EDF
2//
3// This library is free software; you can redistribute it and/or
4// modify it under the terms of the GNU Lesser General Public
5// License as published by the Free Software Foundation; either
6// version 2.1 of the License, or (at your option) any later version.
7//
8// This library is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11// Lesser General Public License for more details.
12//
13// You should have received a copy of the GNU Lesser General Public
14// License along with this library; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18//
19
20#include "OptimizerLoop.hxx"
21#include "OutputPort.hxx"
22#include "Visitor.hxx"
23
24#include <iostream>
25
26//#define _DEVDEBUG_
27#include "YacsTrace.hxx"
28
29using namespace YACS::ENGINE;
30using namespace std;
31
32const char FakeNodeForOptimizerLoop::NAME[]="thisIsAFakeNode";
33
34const int OptimizerLoop::NOT_RUNNING_BRANCH_ID=-1973012217;
35const int OptimizerLoop::NOT_INITIALIZED_BRANCH_ID=-1973;
36
37const char OptimizerLoop::NAME_OF_ALGO_INIT_PORT[] = "algoInit";
38const char OptimizerLoop::NAME_OF_OUT_POOL_INPUT[] = "evalResults";
39const char OptimizerLoop::NAME_OF_ALGO_RESULT_PORT[] = "algoResults";
40
41
42FakeNodeForOptimizerLoop::FakeNodeForOptimizerLoop(OptimizerLoop *loop, bool normal, std::string message)
43 : ElementaryNode(NAME), _loop(loop), _normal(normal), _message(message)
44{
47}
48
50 : ElementaryNode(other), _loop(0), _normal(other._normal), _message(other._message)
51{
52}
53
55{
56 return new FakeNodeForOptimizerLoop(*this);
57}
58
60{
62}
63
65{
67}
68
70{
71 DEBTRACE("FakeNodeForOptimizerLoop::execute: " << _message)
72 if (!_normal) {
74 throw Exception(_message);
75 }
76 else
77 {
79 }
80}
81
83{
85}
86
88{
90}
91
98OptimizerLoop::OptimizerLoop(const std::string& name, const std::string& algLibWthOutExt,
99 const std::string& symbolNameToOptimizerAlgBaseInstanceFactory,
100 bool algInitOnFile,bool initAlgo, Proc * procForTypes):
101 DynParaLoop(name,Runtime::_tc_string,std::unique_ptr<NbBranchesAbstract>(new NbBranches(this))),_algInitOnFile(algInitOnFile),_alglib(algLibWthOutExt),
102 _algoInitPort(NAME_OF_ALGO_INIT_PORT, this, Runtime::_tc_string, true),
103 _loader(NULL),_alg(0),_convergenceReachedWithOtherCalc(false),
104 _retPortForOutPool(NAME_OF_OUT_POOL_INPUT,this,Runtime::_tc_string),
105 _nodeForSpecialCases(0), _algoResultPort(NAME_OF_ALGO_RESULT_PORT, this, Runtime::_tc_string)
106{
107 //We need this because calling a virtual method in a constructor does not call the most derived method but the method of the class
108 //A derived class must take care to manage that
109 if(initAlgo)
110 setAlgorithm(algLibWthOutExt,symbolNameToOptimizerAlgBaseInstanceFactory, procForTypes);
111}
112
113OptimizerLoop::OptimizerLoop(const OptimizerLoop& other, ComposedNode *father, bool editionOnly):
114 DynParaLoop(other,father,editionOnly),_algInitOnFile(other._algInitOnFile),_alglib(other._alglib),
115 _convergenceReachedWithOtherCalc(false),_loader(NULL),_alg(0),_algoInitPort(other._algoInitPort,this),
116 _retPortForOutPool(other._retPortForOutPool,this),_nodeForSpecialCases(0),
117 _algoResultPort(other._algoResultPort, this)
118{
119 //Don't call setAlgorithm here because it will be called several times if the class is derived. Call it in simpleClone for cloning
120
121 // Create the links to evalResults port
122 set<OutPort *> fromPortsToReproduce=other._retPortForOutPool.edSetOutPort();
123 for(set<OutPort *>::iterator iter=fromPortsToReproduce.begin();iter!=fromPortsToReproduce.end();iter++)
125}
126
128{
129 if(_alg)
130 _alg->decrRef();
133 delete _loader;
135}
136
137Node *OptimizerLoop::simpleClone(ComposedNode *father, bool editionOnly) const
138{
139 OptimizerLoop* ol=new OptimizerLoop(*this,father,editionOnly);
140 // TODO: Remove this const_cast (find a better design to get the type codes from the original node)
141 Proc * procForTypes = ol->getProc();
142 if (procForTypes == NULL) {
143 const Proc * origProc = getProc();
144 procForTypes = const_cast<Proc *>(origProc);
145 }
146 ol->setAlgorithm(_alglib, _symbol, false, procForTypes);
147 return ol;
148}
149
150void OptimizerLoop::init(bool start)
151{
152 DynParaLoop::init(start);
153 _algoInitPort.exInit(start);
159}
160
162{
164 return;
167 try
168 {
169 if(_inGate.exIsReady())
170 {
172 // Force termination in case the previous algorithm did not finish properly (manual stop)
173 _alg->finishProxy();
175
176 // Initialize and launch the algorithm
178 if (_alg->hasError()) {
179 string error = _alg->getError();
180 _alg->finishProxy();
181 throw Exception(error);
182 }
183
184 //internal graph update
185 int i;
186 int nbOfBr=_nbOfBranches->getIntValue();
187 _alg->setNbOfBranches(nbOfBr);
188
189 _alg->startProxy();
190 if (_alg->hasError()) {
191 string error = _alg->getError();
192 _alg->finishProxy();
193 throw Exception(error);
194 }
195
196 if(nbOfBr==0)
197 {
198 // A number of branches of 0 is acceptable if there are no output ports
199 // leaving OptimizerLoop
200 bool normal = getAllOutPortsLeavingCurrentScope().empty();
202 "OptimizerLoop has no branch to run the internal node(s)");
203 return;
204 }
205 _execNodes.resize(nbOfBr);
206 _execIds.resize(nbOfBr);
207 if(_initNode)
208 {
209 _execInitNodes.resize(nbOfBr);
210 _initNodeUpdated.resize(nbOfBr);
211 for(i=0;i<nbOfBr;i++)
212 _initNodeUpdated[i]=false;
213 }
215 if (_finalizeNode)
216 _execFinalizeNodes.resize(nbOfBr);
217 vector<Node *> origNodes;
218 origNodes.push_back(_initNode);
219 origNodes.push_back(_node);
220 origNodes.push_back(_finalizeNode);
221 for(i=0;i<nbOfBr;i++)
222 {
224 vector<Node *> clonedNodes = cloneAndPlaceNodesCoherently(origNodes);
225 if(_initNode)
226 _execInitNodes[i] = clonedNodes[0];
227 _execNodes[i] = clonedNodes[1];
228 if(_finalizeNode)
229 _execFinalizeNodes[i] = clonedNodes[2];
231 }
232 initInterceptors(nbOfBr);
233 int id;
234 unsigned char priority;
236 if(!val)
237 {
238 // It is acceptable to have no sample to launch if there are no output ports
239 // leaving OptimizerLoop
240 std::set<OutPort *> setOutPort = getAllOutPortsLeavingCurrentScope();
241 // Special in the special
242 // We do not check algoResult
243 setOutPort.erase(&_algoResultPort);
244 bool normal = setOutPort.empty();
246 string("The algorithm of OptimizerLoop with name ") + _name +
247 " returns no sample to launch");
248 _alg->finishProxy();
249 return;
250 }
251 launchMaxOfSamples(true);
252 }
253 }
254 catch (const exception & e)
255 {
257 string("An error happened in the control algorithm of OptimizerLoop \"") + _name +
258 "\": " + e.what());
259 }
260}
261
263{
265}
266
267InputPort *OptimizerLoop::getInputPort(const std::string& name) const
268{
269 if (name == NAME_OF_ALGO_INIT_PORT)
270 return (InputPort *)&_algoInitPort;
271 else if (name == NAME_OF_OUT_POOL_INPUT)
272 return (InputPort *)&_retPortForOutPool;
273 else
274 return DynParaLoop::getInputPort(name);
275}
276
277std::list<InputPort *> OptimizerLoop::getSetOfInputPort() const
278{
279 list<InputPort *> ret=DynParaLoop::getSetOfInputPort();
280 ret.push_back((InputPort *)&_algoInitPort);
281 ret.push_back((InputPort *)&_retPortForOutPool);
282 return ret;
283}
284
285std::list<InputPort *> OptimizerLoop::getLocalInputPorts() const
286{
287 list<InputPort *> ret=DynParaLoop::getLocalInputPorts();
288 ret.push_back((InputPort *)&_algoInitPort);
289 ret.push_back((InputPort *)&_retPortForOutPool);
290 return ret;
291}
292
293void OptimizerLoop::selectRunnableTasks(std::vector<Task *>& tasks)
294{
295}
296
297void OptimizerLoop::getReadyTasks(std::vector<Task *>& tasks)
298{
299 if(!_node)
300 return;
302 {
304 {
306 return ;
307 }
308 vector<Node *>::iterator iter;
309 for (iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++)
310 (*iter)->getReadyTasks(tasks);
311 for (iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++)
312 (*iter)->getReadyTasks(tasks);
313 for (iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++)
314 (*iter)->getReadyTasks(tasks);
315 }
316}
317
319{
320 if (getState() == YACS::FAILED)
321 {
322 // This happens when a valid computation on a branch finishes after an error on another branch.
323 // In this case we just ignore the new result because the algorithm has already been terminated.
324 return YACS::NOEVENT;
325 }
326 unsigned int id;
327 switch(getIdentityOfNotifyerNode(node,id))
328 {
329 case INIT_NODE:
330 {
331 _execNodes[id]->exUpdateState();
335 break;
336 }
337 case WORK_NODE:
338 {
340 { //This case happens when alg has reached its convergence whereas other calculations still compute
342 if(!isFullyLazy())
343 return YACS::NOEVENT;
344 else
345 return finalize();
346 }
350 if (_alg->hasError()) {
351 _errorDetails = string("An error happened in the control algorithm of optimizer loop: ") +
352 _alg->getError();
353 _alg->finishProxy();
355 return YACS::ABORT;
356 }
357
359 if(_myPool.empty())
360 {
363 if(!isFullyLazy())
364 {// This case happens when the hand is returned to continue, whereas some other are working in parallel for nothing.
366 return YACS::NOEVENT;
367 }
368 return finalize();
369 }
371 int newId;
372 unsigned char priority;
373 Any *val=_myPool.getNextSampleWithHighestPriority(newId, priority);
374 if(!val)
375 {
376 bool isFinished=true;
377 for(int i=0;i<_execIds.size() && isFinished;i++)
379 if(isFinished)
380 {
381 std::cerr <<"OptimizerLoop::updateStateOnFinishedEventFrom: Alg has not inserted more cases whereas last element has been calculated !" << std::endl;
384 _alg->finishProxy();
385 return YACS::FINISH;
386 }
387 return YACS::NOEVENT;
388 }
389 launchMaxOfSamples(false);
390 break;
391 }
392 case FINALIZE_NODE:
393 {
395 if (_unfinishedCounter == 0)
396 {
399 return YACS::FINISH;
400 }
401 else
402 return YACS::NOEVENT;
403 break;
404 }
405 default:
406 YASSERT(false);
407 }
408 return YACS::NOEVENT;
409}
410
412{
413 //update internal node (definition node) state
414 if (_node)
415 {
417 ComposedNode* compNode = dynamic_cast<ComposedNode*>(_node);
418 if (compNode)
419 {
420 std::list<Node *> aChldn = compNode->getAllRecursiveConstituents();
421 std::list<Node *>::iterator iter=aChldn.begin();
422 for(;iter!=aChldn.end();iter++)
423 (*iter)->setState(YACS::DONE);
424 }
425 }
427 _alg->finishProxy();
428 if (_finalizeNode == NULL)
429 {
430 // No finalize node, we just finish OptimizerLoop at the end of exec nodes execution
432 return YACS::FINISH;
433 }
434 else
435 {
436 // Run the finalize nodes, the OptimizerLoop will be done only when they all finish
437 _unfinishedCounter = 0; // This counter indicates how many branches are not finished
438 for (int i=0 ; i<_nbOfBranches->getIntValue() ; i++)
440 {
441 DEBTRACE("Launching finalize node for branch " << i)
442 _execFinalizeNodes[i]->exUpdateState();
444 }
445 else
446 // There should not be any running branch at this point
448 return YACS::NOEVENT;
449 }
450}
451
453
461{
462 DEBTRACE("OptimizerLoop::updateStateOnFailedEventFrom " << node->getName());
463 _alg->setError(string("Error during the execution of YACS node ") + node->getName() +
464 ": " + node->getErrorReport());
465 _alg->finishProxy();
467 DEBTRACE("OptimizerLoop::updateStateOnFailedEventFrom: returned from error notification.");
468 return DynParaLoop::updateStateOnFailedEventFrom(node,execInst);
469}
470
472{
473}
474
475void OptimizerLoop::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
476{
477 DynParaLoop::buildDelegateOf(port,initialStart,pointsOfView);
478 if(port==&_retPortForOutPool)
479 {
480 std::string linkName("(");
481 linkName += initialStart->getName()+" to "+port->getName()+")";
482 throw Exception(std::string("Illegal OptimizerLoop link: \
483The 'evalResults' port must be linked within the scope of the loop.")
484 + linkName);
485 }
486}
487
488void OptimizerLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
489{
490 DynParaLoop::buildDelegateOf(port,finalTarget,pointsOfView);
491 if(port.first != &_algoResultPort)
492 {
493 std::string linkName("(");
494 linkName += port.first->getName()+" to "+finalTarget->getName()+")";
495 throw Exception(std::string("Illegal OptimizerLoop link: \
496Only the algorithm result port can be linked to a port outside the scope of the loop.")
497 + linkName);
498 }
499
500 string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance();
501 if(typeOfPortInstance!=OutputPort::NAME)
502 throw Exception("OptimizerLoop::buildDelegateOf : not implemented for DS because not specified ");
503}
504
506 std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
507 std::vector<OutPort *>& fwCross,
508 std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
509 LinkInfo& info) const
510{
511 if(end==&_retPortForOutPool)
512 fw[(ComposedNode *)this].push_back(start);
513 else
514 DynParaLoop::checkControlDependancy(start,end,cross,fw,fwCross,bw,info);
515}
516
517void OptimizerLoop::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
518{
519 if(end==&_retPortForOutPool)
520 solveObviousOrDelegateCFLinks(starts,end,alreadyFed,direction,info);
521 else
522 DynParaLoop::checkCFLinks(starts,end,alreadyFed,direction,info);
523}
524
525void OptimizerLoop::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
526 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd)
527{
528 DynParaLoop::checkLinkPossibility(start, pointsOfViewStart, end, pointsOfViewEnd);
529 std::string linkName("(");
530 linkName += start->getName()+" to "+end->getName()+")";
531
532 // Yes, it should be possible to link back the result port to any input port of the loop.
533 if(end == _nbOfBranches->getPort() || end == &_algoInitPort)
534 if(start != &_algoResultPort)
535 throw Exception(std::string("Illegal OptimizerLoop link.") + linkName);
536 else
537 return;
538
539 if(start == &_algoResultPort)
540 throw Exception(std::string("Illegal OptimizerLoop link: \
541The 'algoResult' port can't be linked within the scope of the loop.") + linkName);
542
543 if(end == &_retPortForOutPool && isInMyDescendance(start->getNode())!=_node)
544 throw Exception(std::string("Illegal OptimizerLoop link: \
545The 'evalResults' port can only be linked to the working node.") + linkName);
546}
547
549{
550 // At this point all garanties taken let's clean all.
551 map<InputPort *,vector<InputPort *> >::iterator iter=_interceptors.begin();
552 for(;iter!=_interceptors.end();iter++)
553 for(vector<InputPort *>::iterator iter2=(*iter).second.begin();iter2!=(*iter).second.end();iter2++)
554 delete (*iter2);
555 _interceptors.clear();
556 for(vector<AnyInputPort *>::iterator iter3=_interceptorsForOutPool.begin();iter3!=_interceptorsForOutPool.end();iter3++)
557 delete (*iter3);
559}
560
562{
563 int id;
564 unsigned char priority;
565 Any *val;
566 unsigned i;
567 for (val = _myPool.getNextSampleWithHighestPriority(id, priority);
568 !isFullyBusy(i) && val;
569 val = _myPool.getNextSampleWithHighestPriority(id, priority))
570 {
572 first=true; // node is not initialized (first pass)
573 else
574 first=false; // node is initialized (second pass)
575 _execIds[i]=id;
578 {
579 putValueOnBranch(val,i,first);
580 _execInitNodes[i]->exUpdateState();
581 _initNodeUpdated[i]=true;
583 }
584 else
585 {
586 if(!first)
587 _execNodes[i]->init(first);
588 putValueOnBranch(val,i,first);
589 _execNodes[i]->exUpdateState();
591 }
592 }
593}
594
596{
597 bool isLazy=true;
598 for(unsigned i=0;i<_execIds.size() && isLazy;i++)
600 return isLazy;
601}
602
607bool OptimizerLoop::isFullyBusy(unsigned& branchId) const
608{
609 bool isFinished=true;
610 unsigned i;
611 for(i=0;i<_execIds.size() && isFinished;i++)
613 if(!isFinished)
614 branchId=i-1;
615 return isFinished;
616}
617
622{
623 //For all classical outputports leaving 'this'
624 set<OutPort *> portsToIntercept=getAllOutPortsLeavingCurrentScope();
625 portsToIntercept.erase(&_algoResultPort);
626 for(set<OutPort *>::iterator iter=portsToIntercept.begin();iter!=portsToIntercept.end();iter++)
627 {
628 OutputPort *portC=(OutputPort *)(*iter);//Warrantied by OptimizerLoop::buildDelegateOf
629 const set<InputPort *>& links=portC->getSetOfPhyLinks();
630 for(set<InputPort *>::const_iterator iter2=links.begin();iter2!=links.end();iter2++)
631 {
632#ifdef NOCOVARIANT
633 InputPort *reprCur=dynamic_cast<InputPort *>((*iter2)->getPublicRepresentant());
634#else
635 InputPort *reprCur=(*iter2)->getPublicRepresentant();
636#endif
637 if(!isInMyDescendance(reprCur->getNode()))
638 {//here we've got an out of scope link : Let's intercept it
639 if(_interceptors.find(reprCur)==_interceptors.end())
640 {
641 _interceptors[reprCur].resize(nbOfBr);
642 for(unsigned i=0;i<nbOfBr;i++)
643 {
645 InputPort *clone=reprCur->clone(0);
646 _interceptors[reprCur][i]=clone;
647 portExecC->edAddInputPort(clone);
648 }
649 }
650 else
651 {
652 for(unsigned i=0;i<nbOfBr;i++)
653 {
655 portExecC->edAddInputPort(_interceptors[reprCur][i]);
656 }
657 }
658 }
659 }
660 }
661 // For out pool
662 _interceptorsForOutPool.resize(nbOfBr);
663 set< OutPort * > links=_retPortForOutPool.edSetOutPort();
664 for(unsigned i=0;i<nbOfBr;i++)
666 for(set<OutPort *>::iterator iter2=links.begin();iter2!=links.end();iter2++)
667 for(unsigned j=0;j<nbOfBr;j++)
668 {
669 OutPort *portExec;
670 Node *whatType=isInMyDescendance((*iter2)->getNode());
671 if(whatType==_node)
672 {
673 portExec=_execNodes[j]->getOutPort(_node->getOutPortName(*iter2));
675 }
676 else if(whatType==_initNode && whatType!=0)//This case should never happend. Useless !
677 {
678 portExec=_execInitNodes[j]->getOutPort(_node->getOutPortName(*iter2));
680 }
681 }
682}
683
689{
690 map<InputPort *, std::vector<InputPort *> >::iterator iter;
691 for(iter=_interceptors.begin();iter!=_interceptors.end();iter++)
692 (*iter).first->put((*iter).second[branchId]->get());
693}
694
696{
697 visitor->visitOptimizerLoop(this);
698}
699
701
704void OptimizerLoop::setAlgorithm(const std::string& alglib, const std::string& symbol,
705 bool checkLinks, Proc * procForTypes)
706{
707 if(checkLinks)
708 {
713 throw Exception("The OptimizerLoop node must be disconnected before setting the algorithm");
714 }
715
716 _symbol = symbol;
717 _alglib = alglib;
718
719 if (_alg) {
720 _alg->decrRef();
721 _alg = NULL;
722 }
723
725
726 if(_alg)
727 {
728 _alg->setProc((procForTypes == NULL) ? getProc() : procForTypes);
729
730 // Delete the values in the input ports if they were initialized
731 _retPortForOutPool.put((Any *)NULL);
732 _algoInitPort.put((Any *)NULL);
733
734 // Change the type of the ports
739 }
740
741 modified();
742}
743
744TypeCode * OptimizerLoop::checkTypeCode(TypeCode * tc, const char * portName)
745{
746 if (tc == NULL) {
747 ostringstream errorMsg;
748 errorMsg << "The algorithm specified for OptimizerLoop node \"" << getName() <<
749 "\" provided an invalid type for port \"" << portName << "\"";
750 throw Exception(errorMsg.str());
751 }
752 return tc;
753}
754
756
760{
761 YASSERT(_alg == NULL)
762
763 if (_loader != NULL) {
764 delete _loader;
765 _loader = NULL;
766 }
767 _loader = new YACS::BASES::DynLibLoader(_alglib);
768 OptimizerAlgBaseFactory algFactory = NULL;
769
770 if (_alglib != "" && _symbol != "")
771 {
772 try
773 {
774 _errorDetails = "";
775 algFactory = (OptimizerAlgBaseFactory)_loader->getHandleOnSymbolWithName(_symbol);
776 }
777 catch (YACS::Exception& e)
778 {
779 _errorDetails = e.what();
780 modified();
781 throw;
782 }
783 }
784
785 if (algFactory != NULL)
786 _alg = algFactory(&_myPool);
787}
788
790
793std::string OptimizerLoop::getAlgLib() const
794{
795 return _alglib;
796}
797
799
803{
804 DEBTRACE("OptimizerLoop::checkBasicConsistency");
805 if (_alglib == "")
806 throw Exception("No library specified for the OptimizerLoop control algorithm");
807 if (_symbol == "")
808 throw Exception("No symbol specified for the OptimizerLoop control algorithm");
809 if(_alg == NULL)
810 throw YACS::Exception("Problem during library loading: "+_errorDetails);
811
813}
814
816{
818}
819
820std::list<OutputPort *> OptimizerLoop::getSetOfOutputPort() const
821{
822 list<OutputPort *> ret = DynParaLoop::getSetOfOutputPort();
823 ret.push_back((OutputPort *)&_algoResultPort);
824 return ret;
825}
826
827std::list<OutputPort *> OptimizerLoop::getLocalOutputPorts() const
828{
829 list<OutputPort *> ret = DynParaLoop::getLocalOutputPorts();
830 ret.push_front((OutputPort *)&_algoResultPort);
831 return ret;
832}
833
834OutPort * OptimizerLoop::getOutPort(const std::string& name) const
835{
836 return (name == NAME_OF_ALGO_RESULT_PORT) ? (OutPort *)&_algoResultPort :
838}
839
840
841OutputPort * OptimizerLoop::getOutputPort(const std::string& name) const
842{
845}
#define YASSERT(val)
YASSERT macro is always defined, used like assert, but throw a YACS::Exception instead of abort.
Definition: YacsTrace.hxx:59
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
InputPort * clone(Node *newHelder) const
virtual void put(const void *data)
: Interface for management of storage of data formated dynamically in its TypeCode....
Definition: Any.hxx:79
Base class for all composed nodes.
std::string getName() const
void solveObviousOrDelegateCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
virtual std::list< Node * > getAllRecursiveConstituents()
Idem getAllRecursiveNodes, but this node is NOT included.
std::set< OutPort * > getAllOutPortsLeavingCurrentScope() const
List all output ports of children nodes that are linked to out of scope input ports.
std::string getPortName(const PORT *port) const
bool edAddLink(OutPort *start, InPort *end)
Add a dataflow link between two data ports.
Node * isInMyDescendance(Node *nodeToTest) const
Returns the parent of a node that is the direct child of this node.
void edSetType(TypeCode *type)
Definition: DataPort.cxx:47
std::string getName() const
Definition: DataPort.hxx:55
Base class for dynamically (fully or semifully) built graphs.
Definition: DynParaLoop.hxx:41
InputPort * getInputPort(const std::string &name) const
Get an input port given its name.
std::list< OutputPort * > getLocalOutputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
int getNumberOfInputPorts() const
virtual void checkLinkPossibility(OutPort *start, const std::list< ComposedNode * > &pointsOfViewStart, InPort *end, const std::list< ComposedNode * > &pointsOfViewEnd)
std::unique_ptr< NbBranchesAbstract > _nbOfBranches
Definition: DynParaLoop.hxx:56
std::list< OutputPort * > getSetOfOutputPort() const
std::vector< Node * > _execNodes
Definition: DynParaLoop.hxx:58
static const char NAME_OF_SPLITTED_SEQ_OUT[]
Definition: DynParaLoop.hxx:67
std::vector< Node * > cloneAndPlaceNodesCoherently(const std::vector< Node * > &origNodes)
Clone nodes and make their placement consistent with the placement of the original ones.
void buildDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
OutputPort * getOutputPort(const std::string &name) const
Get an output port given its name.
OutPort * getOutPort(const std::string &name) const
std::vector< int > _execIds
Definition: DynParaLoop.hxx:54
void checkControlDependancy(OutPort *start, InPort *end, bool cross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &fw, std::vector< OutPort * > &fwCross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &bw, LinkInfo &info) const
virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst)
Method used to notify the node that a child node has failed.
std::list< InputPort * > getLocalInputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
void init(bool start=true)
std::vector< Node * > _execFinalizeNodes
Definition: DynParaLoop.hxx:60
int getNumberOfOutputPorts() const
void prepareInputsFromOutOfScope(int branchNb)
virtual void cleanDynGraph()
void checkCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
check control flow links
void putValueOnBranch(Any *val, unsigned branchId, bool first)
AnyOutputPort _splittedPort
Definition: DynParaLoop.hxx:57
std::vector< Node * > _execInitNodes
Definition: DynParaLoop.hxx:59
std::list< InputPort * > getSetOfInputPort() const
TypeOfNode getIdentityOfNotifyerNode(const Node *node, unsigned &id)
virtual void checkBasicConsistency() const
Base class for all calculation nodes.
void getReadyTasks(std::vector< Task * > &tasks)
Threaded Executor.
Definition: Executor.hxx:63
Node * simpleClone(ComposedNode *father, bool editionOnly) const
FakeNodeForOptimizerLoop(OptimizerLoop *loop, bool normal, std::string message)
bool exIsReady() const
Definition: InGate.cxx:126
virtual std::set< OutPort * > edSetOutPort() const
Returns physical backlinks NOT user backlinks.
Definition: InPort.cxx:65
virtual int edGetNumberOfLinks() const
Returns number of physical backlinks NOT number of user backlinks.
Definition: InPort.cxx:45
Base class for Input Ports.
Definition: InputPort.hxx:44
virtual InputPort * clone(Node *newHelder) const =0
virtual void exInit(bool start)
Definition: InputPort.cxx:63
virtual InputPort * getPublicRepresentant()
returns the final physical port behind 'this'.
Definition: InputPort.hxx:57
Class that deal with list of semantics links for high level analysis.
Definition: LinkInfo.hxx:83
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
virtual void exForwardFinished()
Definition: Node.cxx:386
ComposedNode * _father
Definition: Node.hxx:90
InGate _inGate
Definition: Node.hxx:86
const std::string & getName() const
Definition: Node.hxx:125
ComposedNode * getFather() const
Definition: Node.hxx:127
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
virtual std::string getOutPortName(const OutPort *) const =0
Node * clone(ComposedNode *father, bool editionOnly=true) const
This method MUST NEVER BE VIRTUAL
Definition: Node.cxx:131
void setState(YACS::StatesForNode theState)
Sets the given state for node.
Definition: Node.cxx:652
virtual std::string getErrorReport()
returns a string that contains an error report if the node is in error
Definition: Node.cxx:755
virtual YACS::StatesForNode getState() const
Definition: Node.hxx:118
virtual void exForwardFailed()
Definition: Node.cxx:378
std::string _errorDetails
Definition: Node.hxx:93
YACS::StatesForNode _state
Definition: Node.hxx:91
virtual Proc * getProc()
Definition: Node.cxx:401
virtual TypeCode * getTCForInProxy() const
virtual TypeCode * getTCForAlgoInitProxy() const
virtual Any * getAlgoResultProxy()
virtual void setError(const std::string &message)
virtual void setProc(Proc *proc)
virtual void initializeProxy(const Any *input)
virtual TypeCode * getTCForAlgoResultProxy() const
virtual const std::string & getError() const
virtual bool hasError() const
void setNbOfBranches(int nbOfBranches)
virtual TypeCode * getTCForOutProxy() const
class to build optimization loops
void buildDelegateOf(InPort *&port, OutPort *initialStart, const std::list< ComposedNode * > &pointsOfView)
virtual std::string getAlgLib() const
Return the name of the algorithm library.
void exUpdateState()
Update the node state.
std::map< InputPort *, std::vector< InputPort * > > _interceptors
outputports interceptors leaving current scope.
InputPort * getInputPort(const std::string &name) const
Get an input port given its name.
friend class FakeNodeForOptimizerLoop
void initInterceptors(unsigned nbOfBr)
virtual void accept(Visitor *visitor)
static const char NAME_OF_OUT_POOL_INPUT[]
bool isFullyBusy(unsigned &branchId) const
OutputPort * getOutputPort(const std::string &name) const
Get an output port given its name.
std::list< OutputPort * > getLocalOutputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
YACS::Event updateStateOnFinishedEventFrom(Node *node)
virtual void setAlgorithm(const std::string &alglib, const std::string &symbol, bool checkLinks=true, Proc *procForTypes=NULL)
Set the algorithm library name and factory name (symbol in library) to create the algorithm and chang...
std::list< OutputPort * > getSetOfOutputPort() const
static const int NOT_RUNNING_BRANCH_ID
void checkControlDependancy(OutPort *start, InPort *end, bool cross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &fw, std::vector< OutPort * > &fwCross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &bw, LinkInfo &info) const
FakeNodeForOptimizerLoop * _nodeForSpecialCases
static const char NAME_OF_ALGO_INIT_PORT[]
void pushValueOutOfScopeForCase(unsigned branchId)
void checkCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
check control flow links
Node * simpleClone(ComposedNode *father, bool editionOnly=true) const
void getReadyTasks(std::vector< Task * > &tasks)
void selectRunnableTasks(std::vector< Task * > &tasks)
static const int NOT_INITIALIZED_BRANCH_ID
OptimizerLoop(const std::string &name, const std::string &algLibWthOutExt, const std::string &symbolNameToOptimizerAlgBaseInstanceFactory, bool algInitOnFile, bool initAlgo=true, Proc *procForTypes=NULL)
std::list< InputPort * > getLocalInputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
void init(bool start=true)
OutPort * getOutPort(const std::string &name) const
::YACS::BASES::DynLibLoader * _loader
static const char NAME_OF_ALGO_RESULT_PORT[]
TypeCode * checkTypeCode(TypeCode *tc, const char *portName)
virtual void loadAlgorithm()
Load the algorithm from the dynamic library.
std::vector< AnyInputPort * > _interceptorsForOutPool
void checkLinkPossibility(OutPort *start, const std::list< ComposedNode * > &pointsOfViewStart, InPort *end, const std::list< ComposedNode * > &pointsOfViewEnd)
void launchMaxOfSamples(bool first)
std::vector< bool > _initNodeUpdated
virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst)
Method used to notify the node that a child node has failed.
void checkNoCyclePassingThrough(Node *node)
std::list< InputPort * > getSetOfInputPort() const
virtual void checkBasicConsistency() const
Check validity for the node.
virtual bool addInPort(InPort *inPort)=0
virtual int edGetNumberOfOutLinks() const
Definition: OutPort.cxx:50
virtual bool edAddInputPort(InputPort *phyPort)
Definition: OutputPort.cxx:75
const std::set< InputPort * > & getSetOfPhyLinks() const
Returns physical links linked to this. Contrary to edSetInPort that returns semantic links.
Definition: OutputPort.cxx:255
static const char NAME[]
Definition: OutputPort.hxx:79
virtual void exInit()
Definition: OutputPort.cxx:62
void destroyCurrentCase()
Definition: Pool.cxx:127
void destroyAll()
Definition: Pool.cxx:122
bool empty() const
Definition: Pool.cxx:246
void setCurrentId(int id)
Definition: Pool.cxx:159
void putOutSampleAt(int id, Any *outValue)
Definition: Pool.cxx:180
void markIdAsInUse(int id)
Definition: Pool.cxx:232
Any * getNextSampleWithHighestPriority(int &id, unsigned char &priority) const
Definition: Pool.cxx:204
Node * getNode() const
Definition: Port.hxx:46
Base class for all schema objects.
Definition: Proc.hxx:44
Base class for all type objects.
Definition: TypeCode.hxx:68
virtual void visitOptimizerLoop(OptimizerLoop *node)=0
const char * what(void) const noexcept
Definition: Exception.cxx:50
OptimizerAlgBase *(* OptimizerAlgBaseFactory)(Pool *pool)
Event
Definition: define.hxx:56
@ ABORT
Definition: define.hxx:60
@ NOEVENT
Definition: define.hxx:57
@ FINISH
Definition: define.hxx:59
@ FAILED
Definition: define.hxx:51
@ ACTIVATED
Definition: define.hxx:41
@ DONE
Definition: define.hxx:43
@ TOACTIVATE
Definition: define.hxx:40
@ DISABLED
Definition: define.hxx:50
@ ERROR
Definition: define.hxx:52