Version: 9.16.0
DynParaLoop.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 "DynParaLoop.hxx"
21#include "LinkInfo.hxx"
22#include "OutPort.hxx"
23#include "Container.hxx"
24#include "ComponentInstance.hxx"
25#include "ServiceNode.hxx"
26#include "InlineNode.hxx"
27#include "ElementaryNode.hxx"
28#include "Visitor.hxx"
29
30#include <list>
31#include <vector>
32
33//#define _DEVDEBUG_
34#include "YacsTrace.hxx"
35
36using namespace std;
37using namespace YACS::ENGINE;
38
39const char DynParaLoop::NAME_OF_SPLITTED_SEQ_OUT[] = "evalSamples";
40const char DynParaLoop::OLD_NAME_OF_SPLITTED_SEQ_OUT[] = "SmplPrt"; // For backward compatibility with 5.1.4
41
42DynParaLoop::DynParaLoop(const std::string& name, TypeCode *typeOfDataSplitted, std::unique_ptr<NbBranchesAbstract>&& branchManager)
43 : ComposedNode(name),_node(0),_initNode(0),_finalizeNode(0),_nbOfEltConsumed(0),
44 _nbOfBranches(std::move(branchManager)),
45 _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(), _loopWeight(0)
46{
48}
49
51{
52 delete _node;
53 delete _initNode;
54 delete _finalizeNode;
55}
56
57DynParaLoop::DynParaLoop(const DynParaLoop& other, ComposedNode *father, bool editionOnly)
58 : ComposedNode(other,father),_nbOfBranches(other._nbOfBranches->copy(this)),
59 _splittedPort(other._splittedPort,this), _node(0), _initNode(0), _finalizeNode(0),
60 _nbOfEltConsumed(0),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(other._weight), _loopWeight(other._loopWeight)
61{
62 if(other._node)
63 _node=other._node->clone(this,editionOnly);
64 if(other._initNode)
65 _initNode=other._initNode->clone(this,editionOnly);
66 if(other._finalizeNode)
67 _finalizeNode = other._finalizeNode->clone(this,editionOnly);
68 const AnyOutputPort& startOfLinksToReproduce=other._splittedPort;
69 set<InPort *> endsOfLinksToReproduce=startOfLinksToReproduce.edSetInPort();
70 for(set<InPort *>::iterator iter=endsOfLinksToReproduce.begin();iter!=endsOfLinksToReproduce.end();iter++)
72}
73
75{
77}
78
81{
82 if (node == NULL || nodeToReplace == node)
83 return 0;
84 if (node->_father)
85 throw Exception(string("Can't set node: node ") + node->getName() + " is not orphan.");
86 if (_node && _node != nodeToReplace && _node->getName() == node->getName())
87 throw Exception(string("Can't set node: node ") + node->getName() +
88 " has the same name than exec node already in " + _name + ".");
89 if (_initNode && _initNode != nodeToReplace && _initNode->getName() == node->getName())
90 throw Exception(string("Can't set node: node ") + node->getName() +
91 " has the same name than init node already in " + _name + ".");
92 if (_finalizeNode && _finalizeNode != nodeToReplace && _finalizeNode->getName() == node->getName())
93 throw Exception(string("Can't set node: node ") + node->getName() +
94 " has the same name than finalize node already in " + _name + ".");
96 ComposedNode::edRemoveChild(nodeToReplace);
97 Node * ret = nodeToReplace;
98 nodeToReplace = node;
99 nodeToReplace->_father = this;
100 // set _modified flag so that edUpdateState can refresh state
101 modified();
102 return ret;
103}
104
105void DynParaLoop::init(bool start)
106{
107 ComposedNode::init(start);
108 if(!_node)
109 {
110 string what("DynParaLoop::init : no node specified for ForEachLoop with name "); what +=_name;
111 throw Exception(what);
112 }
113 _node->init(start);
114 if (_initNode) _initNode->init(start);
115 if (_finalizeNode) _finalizeNode->init(start);
116 _nbOfBranches->exInit(start);
120}
121
123{
125}
126
128{
130}
131
133
142{
143 return edAddLink(start,end);
144}
145
147{
149}
150
152{
154}
155
162{
163 if(_node)
164 {
165 for(std::vector<Node *>::const_iterator it=_execNodes.begin();it!=_execNodes.end();it++)
166 if(node==*it)
167 return std::distance(_execNodes.begin(),it);
168 }
169 if(_finalizeNode)
170 {
171 for(std::vector<Node *>::const_iterator it=_execFinalizeNodes.begin();it!=_execFinalizeNodes.end();it++)
172 if(node==*it)
173 return std::distance(_execFinalizeNodes.begin(),it);
174 }
175 if(_initNode)
176 {
177 for(std::vector<Node *>::const_iterator it=_execInitNodes.begin();it!=_execInitNodes.end();it++)
178 if(node==*it)
179 return std::distance(_execInitNodes.begin(),it);
180 }
181 return -1;
182}
183
184std::list<OutputPort *> DynParaLoop::getSetOfOutputPort() const
185{
186 list<OutputPort *> ret=ComposedNode::getSetOfOutputPort();
187 ret.push_back((OutputPort *)&_splittedPort);
188 return ret;
189}
190
191std::list<OutputPort *> DynParaLoop::getLocalOutputPorts() const
192{
193 list<OutputPort *> ret=ComposedNode::getLocalOutputPorts();
194 ret.push_back((OutputPort *)&_splittedPort);
195 return ret;
196}
197
198OutPort *DynParaLoop::getOutPort(const std::string& name) const
199{
201 return (OutPort *)&_splittedPort;
202 return ComposedNode::getOutPort(name);
203}
204
205
206OutputPort *DynParaLoop::getOutputPort(const std::string& name) const
207{
209 return (OutputPort *)&_splittedPort;
210 return ComposedNode::getOutputPort(name);
211}
212
214{
215 return false;
216}
217
219{
220 return removeNode(_node);
221}
222
225{
226 if (!nodeToRemove)
227 return NULL;
228 ComposedNode::edRemoveChild(nodeToRemove);
229 Node * ret = nodeToRemove;
230 nodeToRemove = NULL;
231 modified();
232 return ret;
233}
234
236{
237 return removeNode(_initNode);
238}
239
241{
243}
244
246{
248 if(node==_node)
249 _node=0;
250 if(node==_initNode)
251 _initNode=0;
252 if(node==_finalizeNode)
254 modified();
255}
256
258{
259 return edSetNode(DISOWNnode);
260}
261
262std::list<Node *> DynParaLoop::edGetDirectDescendants() const
263{
264 list<Node *> ret;
265 if(_node)
266 ret.push_back(_node);
267 if(_initNode)
268 ret.push_back(_initNode);
269 if(_finalizeNode)
270 ret.push_back(_finalizeNode);
271 return ret;
272}
273
274std::list<InputPort *> DynParaLoop::getSetOfInputPort() const
275{
276 list<InputPort *> ret=ComposedNode::getSetOfInputPort();
277 InputPort *port(_nbOfBranches->getPort());
278 if(port)
279 ret.push_back(port);
280 return ret;
281}
282
283InputPort *DynParaLoop::getInputPort(const std::string& name) const
284{
285 if(_nbOfBranches->isMyName(name))
286 return _nbOfBranches->getPort();
287 return ComposedNode::getInputPort(name);
288}
289
290std::list<InputPort *> DynParaLoop::getLocalInputPorts() const
291{
292 list<InputPort *> ret=ComposedNode::getLocalInputPorts();
293 InputPort *port(_nbOfBranches->getPort());
294 if(port)
295 ret.push_back(port);
296 return ret;
297}
298
300{
301 if(_execNodes.empty())
302 throw Exception("ForEachLoop::getNumberOfBranches : No branches created dynamically ! - ForEachLoop needs to run or to be runned to call getNumberOfBranches");
303 else
304 return _execNodes.size();
305}
306
307Node *DynParaLoop::getChildByShortName(const std::string& name) const
308{
309 if (_node && name == _node->getName())
310 return _node;
311 if (_initNode && name == _initNode->getName())
312 return _initNode;
313 if (_finalizeNode && name == _finalizeNode->getName())
314 return _finalizeNode;
315 std::string what("node "); what+= name ; what+=" is not a child of DynParaLoop node "; what += getName();
316 throw Exception(what);
317}
318
319Node *DynParaLoop::getChildByNameExec(const std::string& name, unsigned id) const
320{
322 throw Exception("ForEachLoop::getChildByNameExec : invalid id - too large compared with dynamically created branches.");
323 if (_node && name == _node->getName())
324 return _execNodes[id];
325 if (_initNode && name == _initNode->getName())
326 return _execInitNodes[id];
327 if (_finalizeNode && name == _finalizeNode->getName())
328 return _execFinalizeNodes[id];
329 std::string what("node "); what+= name ; what+=" is not a child of DynParaLoop node "; what += getName();
330 throw Exception(what);
331}
332
334{
335 vector<Node *>::iterator iter;
336 for(iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++)
337 delete *iter;
338 _execNodes.clear();
339 for(iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++)
340 delete *iter;
341 _execInitNodes.clear();
342 for(iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++)
343 delete *iter;
344 _execFinalizeNodes.clear();
345}
346
352{
353 set< InPort * > portsToSetVals=getAllInPortsComingFromOutsideOfCurrentScope();
354
355 // This tweak is to fix problems with nested dynamic loops where links are not cloned properly
356 list<InPort *> temp = getSetOfInPort();
357 for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
358 {
359 if ((*iter2)->edSetOutPort().size() == 1 && *(*iter2)->edSetOutPort().begin() == NULL)
360 {
361 portsToSetVals.insert(*iter2);
362 }
363 }
364
365 // local input ports are not candidates for dynamically duplicated inport.
366 list<InputPort *> localPorts = getLocalInputPorts();
367 for(list<InputPort *>::iterator iter = localPorts.begin() ; iter != localPorts.end() ; iter++)
368 portsToSetVals.erase(*iter);
369 for(set< InPort * >::iterator iter=portsToSetVals.begin();iter!=portsToSetVals.end();iter++)
370 {
371 InputPort *curPortCasted=(InputPort *) *iter;//Cast granted by ForEachLoop::buildDelegateOf(InPort)
372 void *val=curPortCasted->get();
373 InputPort *portToSet=getDynInputPortByAbsName(branchNb,getInPortName(*iter),true);
374 if(portToSet)//portToSet==0 in case of portToSet==_splitterNode._dataPortToDispatch of ForEach
375 {
376 portToSet->put((const void *)val);
377 portToSet->edNotifyReferencedBy(nullptr,false);//This is to indicate that somewhere somebody deals with this inputport
378 //even if no direct physical link exists. This exclusively for _execNodes[branchNb]::init on the next turn of loop.
379 //false is put as 2nd parameter to tell to portToSet, do not touch to the data in case of squeezeMemory.
380 }
381 }
382}
383
384void DynParaLoop::putValueOnBranch(Any *val, unsigned branchId, bool first)
385{
386 bool isDispatched = false;
387 set<InPort *> inPrtLkdWthSplttdPrt=_splittedPort.edSetInPort();
388 for(set<InPort *>::iterator iter=inPrtLkdWthSplttdPrt.begin();iter!=inPrtLkdWthSplttdPrt.end();iter++)
389 {
390 std::string portNameOnCurPrt=getPortName(*iter);
391 InputPort *portOnGivenBranch=getDynInputPortByAbsName(branchId,portNameOnCurPrt,first);//Cast granted because impossible to have cross protocol with _splittedPort
392 //see OptimizerLoop::buildDelegateOf
393 if(portOnGivenBranch)
394 {
395 if(first)
396 portOnGivenBranch->edNotifyReferencedBy(0);
397 InputPort *traducer=getRuntime()->adapt(portOnGivenBranch,
399 traducer->put((const void *)val);
400 isDispatched = true;
401 if(traducer!=portOnGivenBranch)
402 delete traducer;
403 }
404 }
405 if ( isDispatched )
406 {
407 Any *tmp=val->clone();
409 tmp->decrRef();
410 }
411}
412
414{
415 vector<Node *>::iterator iter;
416 id=0;
417 for (iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++,id++)
418 if (*iter==node)
419 return WORK_NODE;
420 id=0;
421 for (iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++,id++)
422 if (*iter==node)
423 return INIT_NODE;
424 id=0;
425 for (iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++,id++)
426 if (*iter==node)
427 return FINALIZE_NODE;
428 throw Exception("DynParaLoop::getIdentityOfNotifyerNode: unrecognized node !");
429}
430
431void DynParaLoop::setWeight(double loopWeight)
432{
433 if(loopWeight<=0.)
434 throw Exception("DynParaLoop::setWeight : invalid input value !");
435 _loopWeight=loopWeight;
436}
437
439{
440 if (_loopWeight>0.)
441 _weight.setLoopWeight(_loopWeight, _node->getMaxLevelOfParallelism()); // not done in setWeight because _node can be null at that time
442 return &_weight;
443}
444
445bool DynParaLoop::isMultiplicitySpecified(unsigned& value) const
446{
447 return _nbOfBranches->isMultiplicitySpecified(value);
448}
449
451{
452 _nbOfBranches->forceMultiplicity(value);
453}
454
455void DynParaLoop::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
456{
457 string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
458 if(typeOfPortInstance!=InputPort::NAME)
459 throw Exception("DynParaLoop::buildDelegateOf : A link with datastream end inside DynParaLoop is not possible");
460}
461
462void DynParaLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
463{
464 std::string linkName("(");
465 linkName += port.first->getName()+" to "+finalTarget->getName()+")";
466 if(_initNode)
467 if(isInMyDescendance(port.first->getNode())==_initNode)
468 throw Exception(std::string("Illegal link within a parallel loop: \
469a link starting from the init node can't leave the scope of the loop.")
470 + linkName);
471
472 if(_finalizeNode)
473 if(isInMyDescendance(port.first->getNode())==_finalizeNode)
474 throw Exception(std::string("Illegal link within a parallel loop: \
475an output port of the finalize node can't be linked.")
476 + linkName);
477
478 if(port.first==&_splittedPort)
479 throw Exception(std::string("Illegal link within a parallel loop: \
480the 'evalSamples' port must be linked within the scope of the loop.")
481 + linkName);
482}
483
484void DynParaLoop::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
485{
486 const char what[]="DynParaLoop::checkCFLinks : internal error.";
487 //First dealing checkCFLinks forwarding...
488 if(isInMyDescendance(end->getNode())==0)//no chance that _splittedPort is in starts due to buildDelegate.
489 solveObviousOrDelegateCFLinks(starts,end,alreadyFed,direction,info);
490 else
491 {//no forwarding here.
492 if(starts.size()!=1)
493 throw Exception(what);
494 //ASSERT(direction) : see DynParaLoop::checkControlDependancy only 'fw' filled.
495 if(alreadyFed==FREE_ST)
496 alreadyFed=FED_ST;
497 else if(alreadyFed==FED_ST)
498 {//Shame ! splittedPort fills a port already fed...
499 info.pushInfoLink(*(starts.begin()),end,I_USELESS);
500 }
501 }
502}
503
514 std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
515 std::vector<OutPort *>& fwCross,
516 std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
517 LinkInfo& info) const
518{
519 fw[(ComposedNode *)this].push_back(start);
520}
521
522void DynParaLoop::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
523 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd)
524{
525 ComposedNode::checkLinkPossibility(start, pointsOfViewStart, end, pointsOfViewEnd);
526 Node * startNode = isInMyDescendance(start->getNode());
527 Node * endNode = isInMyDescendance(end->getNode());
528 std::string linkName("(");
529 linkName += start->getName()+" to "+end->getName()+")";
530
531 if(start == &_splittedPort && endNode != _node)
532 throw Exception(std::string("Illegal link within a parallel loop: \
533the 'evalSamples' port can only be connected to the working node of the loop.")
534 + linkName);
535
536 if(_finalizeNode && _finalizeNode == startNode)
537 throw Exception(std::string("Illegal link within a parallel loop: \
538the finalize node can't be the origin of a link.")
539 + linkName);
540
541 if(_initNode && _node == startNode && _initNode == endNode)
542 throw Exception(std::string("Illegal link within a parallel loop: \
543can't make a link from the working node to the init node.")
544 + linkName);
545
546 if(_finalizeNode && _node == startNode && _finalizeNode == endNode)
547 throw Exception(std::string("Illegal link within a parallel loop: \
548can't make a link from the working node to the finalize node.")
549 + linkName);
550}
551
559InputPort *DynParaLoop::getDynInputPortByAbsName(int branchNb, const std::string& name, bool initNodeAdmitted)
560{
561 string portName, nodeName;
562 splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true);
563 Node *staticChild = getChildByName(nodeName);
564 Node *desc=isInMyDescendance(staticChild);
565 if(desc==_node)
566 {
567 splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false);
568 return _execNodes[branchNb]->getInputPort(portName);
569 }
570 else if(desc==_initNode)
571 if(initNodeAdmitted)
572 {
573 splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false);
574 return _execInitNodes[branchNb]->getInputPort(portName);
575 }
576 return 0;
577}
578
580{
581 DEBTRACE("DynParaLoop::checkBasicConsistency");
583 if(!_node)
584 throw Exception("For a dynamic loop, internal node is mandatory");
585}
586
588{
589 DEBTRACE("DynParaLoop::getErrorReport: " << getName() << " " << _state);
590 YACS::StatesForNode effectiveState=getEffectiveState();
591
592 if(effectiveState != YACS::INVALID && effectiveState != YACS::ERROR && effectiveState != YACS::FAILED)
593 return "";
594
595 std::string report="<error node= " + getName();
596 switch(effectiveState)
597 {
598 case YACS::INVALID:
599 report=report+" state= INVALID";
600 break;
601 case YACS::ERROR:
602 report=report+" state= ERROR";
603 break;
604 case YACS::FAILED:
605 report=report+" state= FAILED";
606 break;
607 default:
608 break;
609 }
610 report=report + ">\n" ;
611 if(_errorDetails != "")
612 report=report+_errorDetails+"\n";
613
614 if(_execNodes.empty())
615 {
616 // edition node
617 list<Node *> constituents=edGetDirectDescendants();
618 for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
619 {
620 std::string rep=(*iter)->getErrorReport();
621 if(rep != "")
622 {
623 report=report+rep+"\n";
624 }
625 }
626 }
627 else
628 {
629 // execution nodes
630 for(vector<Node *>::iterator iter=_execInitNodes.begin();iter!=_execInitNodes.end();iter++)
631 {
632 std::string rep=(*iter)->getErrorReport();
633 if(rep != "")
634 {
635 report=report+rep+"\n";
636 }
637 }
638 for(vector<Node *>::iterator iter=_execNodes.begin();iter!=_execNodes.end();iter++)
639 {
640 if(*iter)
641 {
642 std::string rep=(*iter)->getErrorReport();
643 if(rep != "")
644 {
645 report=report+rep+"\n";
646 }
647 }
648 }
649 for(vector<Node *>::iterator iter=_execFinalizeNodes.begin();iter!=_execFinalizeNodes.end();iter++)
650 {
651 std::string rep=(*iter)->getErrorReport();
652 if(rep != "")
653 {
654 report=report+rep+"\n";
655 }
656 }
657 }
658
659 report=report+"</error>";
660 return report;
661}
662
664{
665 unsigned int id;
666 Node * origNode = NULL;
667 switch (getIdentityOfNotifyerNode(execNode,id))
668 {
669 case INIT_NODE:
670 {
671 origNode = _initNode;
672 break;
673 }
674 case WORK_NODE:
675 {
676 origNode = _node;
677 break;
678 }
679 case FINALIZE_NODE:
680 {
681 origNode = _finalizeNode;
682 break;
683 }
684 default:
685 YASSERT(false)
686 }
687
688 YASSERT(origNode != NULL)
689 origNode->setState(execNode->getState());
690 origNode->setErrorDetails(execNode->getErrorDetails());
691
692 ComposedNode* compNode = dynamic_cast<ComposedNode*>(origNode);
693 ComposedNode* compNodeExe = dynamic_cast<ComposedNode*>(execNode);
694 if (compNode && compNodeExe)
695 {
696 list<Node *> aChldn = compNodeExe->getAllRecursiveConstituents();
697 list<Node *>::iterator iter=aChldn.begin();
698 for(;iter!=aChldn.end();iter++)
699 {
700 Node* node=compNode->getChildByName(compNodeExe->getChildName(*iter));
701 node->setState((*iter)->getState());
702 node->setErrorDetails((*iter)->getErrorDetails());
703 }
704 }
705}
706
708
715{
716 DEBTRACE("DynParaLoop::updateStateOnFailedEventFrom " << node->getName());
719 unsigned int id;
720 switch (getIdentityOfNotifyerNode(node,id))
721 {
722 case INIT_NODE:
723 {
726 break;
727 }
728 case WORK_NODE:
729 {
731 break;
732 }
733 }
734 return YACS::ABORT;
735}
736
738
744vector<Node *> DynParaLoop::cloneAndPlaceNodesCoherently(const vector<Node *> & origNodes)
745{
746 DEBTRACE("Begin cloneAndPlaceNodesCoherently")
747 vector<Node *> clones;
748 DeploymentTree treeToDup;
749 vector<list<ElementaryNode *> > origElemNodeList;
750 for (int i=0 ; i<origNodes.size() ; i++)
751 {
752 DEBTRACE("Cloning node " << i)
753 if (origNodes[i] == NULL)
754 {
755 DEBTRACE("Cloning node " << i << ", NULL" )
756 clones.push_back(NULL);
757 origElemNodeList.push_back(list<ElementaryNode *>());
758 }
759 else
760 {
761 DEBTRACE("Cloning node " << i << "," << origNodes[i]->getName())
762 clones.push_back(origNodes[i]->simpleClone(this, false));
763 list<ElementaryNode *> tasks = origNodes[i]->getRecursiveConstituents();
764 origElemNodeList.push_back(tasks);
765 for (list< ElementaryNode *>::iterator iter=tasks.begin() ; iter!=tasks.end() ; iter++)
766 treeToDup.appendTask(*iter, (*iter)->getDynClonerIfExists(this));
767 }
768 }
769
770 // Build the links between clones.
771 // Only the links starting from initNode are possible.
772 if(_initNode)
773 {
774 std::vector< std::pair<OutPort *, InPort *> > outLinks = _initNode->getSetOfLinksLeavingCurrentScope();
775 std::vector< std::pair<OutPort *, InPort *> >::const_iterator it;
776 for(it=outLinks.begin(); it!=outLinks.end(); it++)
777 {
778 OutPort *startPort = it->first;
779 InPort *endPort = it->second;
780 Node* destNode = isInMyDescendance(endPort->getNode());
781 if(destNode == _node)
782 edAddLink(clones[0]->getOutPort(startPort->getName()),
783 clones[1]->getInPort(endPort->getName()));
784 if(destNode == _finalizeNode)
785 edAddLink(clones[0]->getOutPort(startPort->getName()),
786 clones[2]->getInPort(endPort->getName()));
787 }
788 }
789
790 DEBTRACE("Placing nodes...")
791 vector<Container *> conts=treeToDup.getAllContainers();
792
793 //iterate on all containers
794 for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
795 {
796 DEBTRACE("Container " << ((*iterCt)?(*iterCt)->getName():"NULL"))
797 vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
798 Container *contCloned=0;
799 if((*iterCt))
800 contCloned=(*iterCt)->clone();
801
802 //iterate on all component instances linked to the container
803 for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
804 {
805 DEBTRACE("Component " << (*iterCp)->getCompoName())
806 vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
807 ComponentInstance *curCloned=(*iterCp)->clone();
808 DEBTRACE("Assign container " << (*iterCp)->getCompoName())
809 curCloned->setContainer(contCloned);
810 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
811 {
812 DEBTRACE("Task " << ((ElementaryNode *)(*iterT))->getName())
813 int i = 0;
814 ElementaryNode * origElemNode = NULL;
815 for (i=0 ; i<origNodes.size() ; i++)
816 if (origNodes[i] != NULL)
817 {
818 DEBTRACE("Looking in original node " << i)
819 list<ElementaryNode *>::iterator res=find(origElemNodeList[i].begin(),
820 origElemNodeList[i].end(),
821 (ElementaryNode *)(*iterT));
822 if (res != origElemNodeList[i].end()) {
823 origElemNode = *res;
824 break;
825 }
826 }
827
828 YASSERT(origElemNode != NULL)
829 DEBTRACE("Found task in node " << i)
830 ServiceNode * nodeC = NULL;
831 if (origNodes[i] == origElemNode)
832 nodeC = (ServiceNode *)clones[i];
833 else
834 {
835 string childName = ((ComposedNode *)origNodes[i])->getChildName(origElemNode);
836 nodeC = (ServiceNode *)clones[i]->getChildByName(childName);
837 }
838 DEBTRACE("Assign component: " << (*iterCp)->getCompoName() << "," << nodeC->getName())
839 nodeC->setComponent(curCloned);
840 }
841 curCloned->decrRef();
842 }
843
844 // iterate on all tasks linked to the container
845 vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
846 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
847 {
848 DEBTRACE("Task " << ((ElementaryNode *)(*iterT))->getName())
849 int i = 0;
850 ElementaryNode * origElemNode = NULL;
851 for (i=0 ; i<origNodes.size() ; i++)
852 if (origNodes[i] != NULL)
853 {
854 DEBTRACE("Looking in original node " << i)
855 list<ElementaryNode *>::iterator res=find(origElemNodeList[i].begin(),
856 origElemNodeList[i].end(),
857 (ElementaryNode *)(*iterT));
858 if (res != origElemNodeList[i].end())
859 {
860 origElemNode = *res;
861 break;
862 }
863 }
864 YASSERT(origElemNode != NULL)
865 DEBTRACE("Found task in node " << i)
866 InlineFuncNode * nodeC = NULL;
867 if (origNodes[i] == origElemNode)
868 {
869 nodeC = (InlineFuncNode *)clones[i];
870 }
871 else
872 {
873 string childName = ((ComposedNode *)origNodes[i])->getChildName(origElemNode);
874 nodeC = (InlineFuncNode *)clones[i]->getChildByName(childName);
875 }
876 DEBTRACE("Assign container " << nodeC->getName() << "," << contCloned->getName())
877 nodeC->setContainer(contCloned);
878 }
879
880 // ended with current container
881 if(contCloned)
882 contCloned->decrRef();
883 }
884
885 DEBTRACE("End cloneAndPlaceNodesCoherently")
886 return clones;
887}
888
890{
891 visitor->visitDynParaLoop(this);
892}
893
895{
896 return _initNode;
897}
898
900{
901 return _node;
902}
903
905{
906 return _finalizeNode;
907}
908
910{
911 return _nbOfBranches->getIntValue() * _node->getMaxLevelOfParallelism();
912}
913
915{
917 zeMap[this]=pd2;
918 if(_node)
919 _node->partitionRegardingDPL(pd,zeMap);
920}
921
923{
924 if(level==0)return;
925 if(!_node) return;
926
927 std::vector<Node *>::iterator iter;
928 for (iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++)
929 (*iter)->shutdown(level);
930 for (iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++)
931 (*iter)->shutdown(level);
932 for (iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++)
933 (*iter)->shutdown(level);
934}
#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
virtual void setValue(Any *data)
store the current dispatched value
: Interface for management of storage of data formated dynamically in its TypeCode....
Definition: Any.hxx:79
virtual Any * clone() const =0
void setLoopWeight(double loopWeight, int nbCoresByIteration)
Base class for all component instances.
virtual bool setContainer(Container *cont)
virtual ComponentInstance * clone() const =0
Base class for all composed nodes.
std::string getChildName(const Node *node) const
Node * getChildByName(const std::string &name) const
static const unsigned char FREE_ST
std::list< InputPort * > getSetOfInputPort() const
std::list< OutputPort * > getLocalOutputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
OutPort * getOutPort(const std::string &name) const
void checkNoCrossHierachyWith(Node *node) const
std::string getName() const
void solveObviousOrDelegateCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
OutputPort * getOutputPort(const std::string &name) const
Get an output port given its name.
InputPort * getInputPort(const std::string &name) const
Get an input port given its name.
virtual std::list< Node * > getAllRecursiveConstituents()
Idem getAllRecursiveNodes, but this node is NOT included.
std::list< OutputPort * > getSetOfOutputPort() const
std::list< InputPort * > getLocalInputPorts() const
redefined on derived class of ComposedNode. by default a ComposedNode has no port by itself
virtual void edRemoveChild(Node *node)
Remove a child node.
virtual void checkBasicConsistency() const
std::string getPortName(const PORT *port) const
static bool splitNamesBySep(const std::string &globalName, const char separator[], std::string &firstPart, std::string &lastPart, bool priority)
Splits name globalName in 2 parts using separator.
static const unsigned char FED_ST
std::string getInPortName(const InPort *) const
Get the input port name.
std::set< InPort * > getAllInPortsComingFromOutsideOfCurrentScope() const
List all input ports that are linked to out of scope ports.
void init(bool start=true)
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.
virtual void checkLinkPossibility(OutPort *start, const std::list< ComposedNode * > &pointsOfViewStart, InPort *end, const std::list< ComposedNode * > &pointsOfViewEnd)
virtual Container * clone() const =0
WARNING ! clone behaviour MUST be in coherence with what is returned by isAttachedOnCloning() method
virtual std::string getName() const
Definition: Container.hxx:81
TypeCode * edGetType() const
Definition: DataPort.hxx:53
std::string getNameOfTypeOfCurrentInstance() const
Definition: DataPort.cxx:56
std::string getName() const
Definition: DataPort.hxx:55
std::vector< Task * > getTasksLinkedToComponent(ComponentInstance *comp) const
std::vector< ComponentInstance * > getComponentsLinkedToContainer(Container *cont) const
std::vector< Task * > getTasksLinkedToContainer(Container *cont) const
unsigned char appendTask(Task *task, Scheduler *cloner)
std::vector< Container * > getAllContainers() const
Base class for dynamically (fully or semifully) built graphs.
Definition: DynParaLoop.hxx:41
Node * getChildByShortName(const std::string &name) const
Node * getChildByNameExec(const std::string &name, unsigned id) const
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 bool edAddChild(Node *DISOWNnode)
virtual void checkLinkPossibility(OutPort *start, const std::list< ComposedNode * > &pointsOfViewStart, InPort *end, const std::list< ComposedNode * > &pointsOfViewEnd)
Node * removeNode(Node *&nodeToRemove)
This method is used to factorize methods edRemoveNode, edRemoveInitNode and edRemoveFinalizeNode.
std::unique_ptr< NbBranchesAbstract > _nbOfBranches
Definition: DynParaLoop.hxx:56
static const char OLD_NAME_OF_SPLITTED_SEQ_OUT[]
Definition: DynParaLoop.hxx:68
bool isMultiplicitySpecified(unsigned &value) const
virtual bool edAddDFLink(OutPort *start, InPort *end)
Connect an OutPort to an InPort and add control link if necessary.
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 setWeight(double loopWeight)
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.
unsigned getNumberOfBranchesCreatedDyn() const
OutPort * getOutPort(const std::string &name) const
bool isPlacementPredictableB4Run() const
For the moment false is returned : impovement about it coming soon.
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
std::list< Node * > edGetDirectDescendants() const
virtual std::string getErrorReport()
returns a string that contains an error report if the node is in error
virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst)
Method used to notify the node that a child node has failed.
int getBranchIDOfNode(Node *node) const
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)
void edRemoveChild(Node *node)
Remove a child node.
Node * edSetFinalizeNode(Node *DISOWNnode)
ComplexWeight * getWeight()
std::vector< Node * > _execFinalizeNodes
Definition: DynParaLoop.hxx:60
virtual void shutdown(int level)
Stop all pending activities of the composed node.
Node * edSetNode(Node *DISOWNnode)
Definition: DynParaLoop.cxx:74
int getNumberOfOutputPorts() const
void prepareInputsFromOutOfScope(int branchNb)
int getMaxLevelOfParallelism() const
virtual void cleanDynGraph()
void checkCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
check control flow links
Node * checkConsistencyAndSetNode(Node *&nodeToReplace, Node *DISOWNnode)
This method is used to factorize methods edSetNode, edSetInitNode and edSetFinalizeNode.
Definition: DynParaLoop.cxx:80
virtual void forwardExecStateToOriginalBody(Node *execNode)
Node * edSetInitNode(Node *DISOWNnode)
void putValueOnBranch(Any *val, unsigned branchId, bool first)
AnyOutputPort _splittedPort
Definition: DynParaLoop.hxx:57
std::vector< Node * > _execInitNodes
Definition: DynParaLoop.hxx:59
void accept(Visitor *visitor)
void forceMultiplicity(unsigned value)
std::list< InputPort * > getSetOfInputPort() const
InputPort * getDynInputPortByAbsName(int branchNb, const std::string &name, bool initNodeAdmitted)
void partitionRegardingDPL(const PartDefinition *pd, std::map< ComposedNode *, YACS::BASES::AutoRefCnt< PartDefinition > > &zeMap)
TypeOfNode getIdentityOfNotifyerNode(const Node *node, unsigned &id)
virtual void checkBasicConsistency() const
Base class for all calculation nodes.
Threaded Executor.
Definition: Executor.hxx:63
virtual void edNotifyReferencedBy(OutPort *fromPort, bool isLoopProof=true)
Definition: InPort.cxx:93
Class for calculation node (function) inlined (and executed) in the schema.
Definition: InlineNode.hxx:93
virtual void setContainer(Container *container)
Definition: InlineNode.cxx:105
Base class for Input Ports.
Definition: InputPort.hxx:44
virtual void put(const void *data)=0
static const char NAME[]
Definition: InputPort.hxx:48
virtual void * get() const =0
Class that deal with list of semantics links for high level analysis.
Definition: LinkInfo.hxx:83
void pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason)
Definition: LinkInfo.cxx:71
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
virtual std::vector< std::pair< OutPort *, InPort * > > getSetOfLinksLeavingCurrentScope() const =0
virtual int getMaxLevelOfParallelism() const =0
virtual void setErrorDetails(const std::string &error)
Definition: Node.hxx:191
ComposedNode * _father
Definition: Node.hxx:90
const std::string & getName() const
Definition: Node.hxx:125
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
Node * clone(ComposedNode *father, bool editionOnly=true) const
This method MUST NEVER BE VIRTUAL
Definition: Node.cxx:131
virtual void init(bool start=true)
Definition: Node.cxx:102
virtual Node * simpleClone(ComposedNode *father, bool editionOnly=true) const =0
friend class DynParaLoop
Definition: Node.hxx:77
std::list< InPort * > getSetOfInPort() const
Definition: Node.cxx:289
void setState(YACS::StatesForNode theState)
Sets the given state for node.
Definition: Node.cxx:652
virtual std::string getErrorDetails() const
Definition: Node.hxx:190
virtual YACS::StatesForNode getState() const
Definition: Node.hxx:118
static const char SEP_CHAR_IN_PORT[]
Definition: Node.hxx:94
InPort * getInPort(const std::string &name) const
Definition: Node.cxx:239
std::string _errorDetails
Definition: Node.hxx:93
virtual YACS::StatesForNode getEffectiveState() const
Return the node state in the context of its father.
Definition: Node.cxx:538
YACS::StatesForNode _state
Definition: Node.hxx:91
virtual void partitionRegardingDPL(const PartDefinition *pd, std::map< ComposedNode *, YACS::BASES::AutoRefCnt< PartDefinition > > &zeMap)=0
std::set< InPort * > edSetInPort() const
Definition: OutputPort.cxx:239
virtual void exInit()
Definition: OutputPort.cxx:62
virtual PartDefinition * copy() const =0
Node * getNode() const
Definition: Port.hxx:46
static const char RUNTIME_ENGINE_INTERACTION_IMPL_NAME[]
Definition: Runtime.hxx:135
virtual InputPort * adapt(InputPort *source, const std::string &impl, TypeCode *type, bool init=false)=0
Class for calculation node associated with a component service.
Definition: ServiceNode.hxx:35
virtual void setComponent(ComponentInstance *compo)
Associate an existing component instance to this service node AND check the consistency regarding the...
Base class for all type objects.
Definition: TypeCode.hxx:68
virtual void visitDynParaLoop(DynParaLoop *node)=0
YACSLIBENGINE_EXPORT Runtime * getRuntime()
Definition: Runtime.cxx:61
Event
Definition: define.hxx:56
@ ABORT
Definition: define.hxx:60
StatesForNode
Definition: define.hxx:34
@ INVALID
Definition: define.hxx:36
@ FAILED
Definition: define.hxx:51
@ ERROR
Definition: define.hxx:52
def distance(node, new_node)
Definition: graph.py:275