1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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"
34 #include "YacsTrace.hxx"
37 using namespace YACS::ENGINE;
39 const char DynParaLoop::NAME_OF_SPLITTED_SEQ_OUT[] = "evalSamples";
40 const char DynParaLoop::OLD_NAME_OF_SPLITTED_SEQ_OUT[] = "SmplPrt"; // For backward compatibility with 5.1.4
42 const char DynParaLoop::NAME_OF_NUMBER_OF_BRANCHES[]="nbBranches";
44 DynParaLoop::DynParaLoop(const std::string& name, TypeCode *typeOfDataSplitted)
45 : ComposedNode(name),_node(0),_initNode(0),_finalizeNode(0),_nbOfEltConsumed(0),
46 _nbOfBranches(NAME_OF_NUMBER_OF_BRANCHES,this,Runtime::_tc_int),
47 _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted)
51 DynParaLoop::~DynParaLoop()
58 DynParaLoop::DynParaLoop(const DynParaLoop& other, ComposedNode *father, bool editionOnly)
59 : ComposedNode(other,father), _nbOfBranches(other._nbOfBranches,this),
60 _splittedPort(other._splittedPort,this), _node(0), _initNode(0), _finalizeNode(0),
64 _node=other._node->clone(this,editionOnly);
66 _initNode=other._initNode->clone(this,editionOnly);
67 if(other._finalizeNode)
68 _finalizeNode = other._finalizeNode->clone(this,editionOnly);
69 const AnyOutputPort& startOfLinksToReproduce=other._splittedPort;
70 set<InPort *> endsOfLinksToReproduce=startOfLinksToReproduce.edSetInPort();
71 for(set<InPort *>::iterator iter=endsOfLinksToReproduce.begin();iter!=endsOfLinksToReproduce.end();iter++)
72 edAddLink(&_splittedPort,getInPort(other.getPortName(*iter)));
75 Node *DynParaLoop::edSetNode(Node *node)
77 return checkConsistencyAndSetNode(_node, node);
80 //! This method is used to factorize methods edSetNode, edSetInitNode and edSetFinalizeNode
81 Node * DynParaLoop::checkConsistencyAndSetNode(Node* &nodeToReplace, Node* node)
83 if (node == NULL || nodeToReplace == node)
86 throw Exception(string("Can't set node: node ") + node->getName() + " is not orphan.");
87 if (_node && _node != nodeToReplace && _node->getName() == node->getName())
88 throw Exception(string("Can't set node: node ") + node->getName() +
89 " has the same name than exec node already in " + _name + ".");
90 if (_initNode && _initNode != nodeToReplace && _initNode->getName() == node->getName())
91 throw Exception(string("Can't set node: node ") + node->getName() +
92 " has the same name than init node already in " + _name + ".");
93 if (_finalizeNode && _finalizeNode != nodeToReplace && _finalizeNode->getName() == node->getName())
94 throw Exception(string("Can't set node: node ") + node->getName() +
95 " has the same name than finalize node already in " + _name + ".");
96 checkNoCrossHierachyWith(node);
97 ComposedNode::edRemoveChild(nodeToReplace);
98 Node * ret = nodeToReplace;
100 nodeToReplace->_father = this;
101 // set _modified flag so that edUpdateState can refresh state
106 void DynParaLoop::init(bool start)
108 ComposedNode::init(start);
111 string what("DynParaLoop::init : no node specified for ForEachLoop with name "); what +=_name;
112 throw Exception(what);
115 if (_initNode) _initNode->init(start);
116 if (_finalizeNode) _finalizeNode->init(start);
117 _nbOfBranches.exInit(start);
118 _splittedPort.exInit();
122 Node *DynParaLoop::edSetInitNode(Node *node)
124 return checkConsistencyAndSetNode(_initNode, node);
127 Node * DynParaLoop::edSetFinalizeNode(Node * node)
129 return checkConsistencyAndSetNode(_finalizeNode, node);
132 //! Connect an OutPort to an InPort and add control link if necessary
134 * Connect the ports with a data link (edAddLink)
135 * In a Loop don't add control flow link : use this only to add data back links
137 * \param start : the OutPort to connect
138 * \param end : the InPort to connect
139 * \return true if a new link has been created, false otherwise.
141 bool DynParaLoop::edAddDFLink(OutPort *start, InPort *end) throw(YACS::Exception)
143 return edAddLink(start,end);
146 int DynParaLoop::getNumberOfInputPorts() const
148 return ComposedNode::getNumberOfInputPorts()+1;
151 int DynParaLoop::getNumberOfOutputPorts() const
153 return ComposedNode::getNumberOfOutputPorts()+1;
156 std::list<OutputPort *> DynParaLoop::getSetOfOutputPort() const
158 list<OutputPort *> ret=ComposedNode::getSetOfOutputPort();
159 ret.push_back((OutputPort *)&_splittedPort);
163 std::list<OutputPort *> DynParaLoop::getLocalOutputPorts() const
165 list<OutputPort *> ret=ComposedNode::getLocalOutputPorts();
166 ret.push_back((OutputPort *)&_splittedPort);
170 OutPort *DynParaLoop::getOutPort(const std::string& name) const throw(YACS::Exception)
172 if (name == NAME_OF_SPLITTED_SEQ_OUT || name == OLD_NAME_OF_SPLITTED_SEQ_OUT)
173 return (OutPort *)&_splittedPort;
174 return ComposedNode::getOutPort(name);
178 OutputPort *DynParaLoop::getOutputPort(const std::string& name) const throw(YACS::Exception)
180 if (name == NAME_OF_SPLITTED_SEQ_OUT || name == OLD_NAME_OF_SPLITTED_SEQ_OUT)
181 return (OutputPort *)&_splittedPort;
182 return ComposedNode::getOutputPort(name);
185 bool DynParaLoop::isPlacementPredictableB4Run() const
190 Node *DynParaLoop::edRemoveNode()
192 return removeNode(_node);
195 //! This method is used to factorize methods edRemoveNode, edRemoveInitNode and edRemoveFinalizeNode
196 Node * DynParaLoop::removeNode(Node* &nodeToRemove)
200 ComposedNode::edRemoveChild(nodeToRemove);
201 Node * ret = nodeToRemove;
207 Node *DynParaLoop::edRemoveInitNode()
209 return removeNode(_initNode);
212 Node * DynParaLoop::edRemoveFinalizeNode()
214 return removeNode(_finalizeNode);
217 void DynParaLoop::edRemoveChild(Node *node) throw(YACS::Exception)
219 ComposedNode::edRemoveChild(node);
224 if(node==_finalizeNode)
229 bool DynParaLoop::edAddChild(Node *node) throw(YACS::Exception)
231 return edSetNode(node);
234 std::list<Node *> DynParaLoop::edGetDirectDescendants() const
238 ret.push_back(_node);
240 ret.push_back(_initNode);
242 ret.push_back(_finalizeNode);
246 std::list<InputPort *> DynParaLoop::getSetOfInputPort() const
248 list<InputPort *> ret=ComposedNode::getSetOfInputPort();
249 ret.push_back((InputPort *)&_nbOfBranches);
253 InputPort *DynParaLoop::getInputPort(const std::string& name) const throw(YACS::Exception)
255 if(name==NAME_OF_NUMBER_OF_BRANCHES)
256 return (InputPort *)&_nbOfBranches;
257 return ComposedNode::getInputPort(name);
260 std::list<InputPort *> DynParaLoop::getLocalInputPorts() const
262 list<InputPort *> ret=ComposedNode::getLocalInputPorts();
263 ret.push_back((InputPort *)&_nbOfBranches);
267 unsigned DynParaLoop::getNumberOfBranchesCreatedDyn() const throw(YACS::Exception)
269 if(_execNodes.empty())
270 throw Exception("ForEachLoop::getNumberOfBranches : No branches created dynamically ! - ForEachLoop needs to run or to be runned to call getNumberOfBranches");
272 return _execNodes.size();
275 Node *DynParaLoop::getChildByShortName(const std::string& name) const throw(YACS::Exception)
277 if (_node && name == _node->getName())
279 if (_initNode && name == _initNode->getName())
281 if (_finalizeNode && name == _finalizeNode->getName())
282 return _finalizeNode;
283 std::string what("node "); what+= name ; what+=" is not a child of DynParaLoop node "; what += getName();
284 throw Exception(what);
287 Node *DynParaLoop::getChildByNameExec(const std::string& name, unsigned id) const throw(YACS::Exception)
289 if(id>=getNumberOfBranchesCreatedDyn())
290 throw Exception("ForEachLoop::getChildByNameExec : invalid id - too large compared with dynamically created branches.");
291 if (_node && name == _node->getName())
292 return _execNodes[id];
293 if (_initNode && name == _initNode->getName())
294 return _execInitNodes[id];
295 if (_finalizeNode && name == _finalizeNode->getName())
296 return _execFinalizeNodes[id];
297 std::string what("node "); what+= name ; what+=" is not a child of DynParaLoop node "; what += getName();
298 throw Exception(what);
301 void DynParaLoop::cleanDynGraph()
303 vector<Node *>::iterator iter;
304 for(iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++)
307 for(iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++)
309 _execInitNodes.clear();
310 for(iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++)
312 _execFinalizeNodes.clear();
316 * This method applies on newly cloned on exec nodes (_execNodes/_execInitNodes)
317 * the setting of input ports coming from outside of 'this'
319 void DynParaLoop::prepareInputsFromOutOfScope(int branchNb)
321 set< InPort * > portsToSetVals=getAllInPortsComingFromOutsideOfCurrentScope();
323 // This tweak is to fix problems with nested dynamic loops where links are not cloned properly
324 list<InPort *> temp = getSetOfInPort();
325 for(list<InPort *>::iterator iter2=temp.begin();iter2!=temp.end();iter2++)
327 if ((*iter2)->edSetOutPort().size() == 1 && *(*iter2)->edSetOutPort().begin() == NULL)
329 portsToSetVals.insert(*iter2);
333 // local input ports are not candidates for dynamically duplicated inport.
334 list<InputPort *> localPorts = getLocalInputPorts();
335 for(list<InputPort *>::iterator iter = localPorts.begin() ; iter != localPorts.end() ; iter++)
336 portsToSetVals.erase(*iter);
337 for(set< InPort * >::iterator iter=portsToSetVals.begin();iter!=portsToSetVals.end();iter++)
339 InputPort *curPortCasted=(InputPort *) *iter;//Cast granted by ForEachLoop::buildDelegateOf(InPort)
340 void *val=curPortCasted->get();
341 InputPort *portToSet=getDynInputPortByAbsName(branchNb,getInPortName(*iter),true);
342 if(portToSet)//portToSet==0 in case of portToSet==_splitterNode._dataPortToDispatch of ForEach
344 portToSet->put((const void *)val);
345 portToSet->edNotifyReferencedBy(0);//This is to indicate that somewhere somebody deals with this inputport
346 //even if no direct physical link exists. This exclusively for _execNodes[branchNb]::init on the next turn of loop.
351 void DynParaLoop::putValueOnBranch(Any *val, unsigned branchId, bool first)
353 bool isDispatched = false;
354 set<InPort *> inPrtLkdWthSplttdPrt=_splittedPort.edSetInPort();
355 for(set<InPort *>::iterator iter=inPrtLkdWthSplttdPrt.begin();iter!=inPrtLkdWthSplttdPrt.end();iter++)
357 std::string portNameOnCurPrt=getPortName(*iter);
358 InputPort *portOnGivenBranch=getDynInputPortByAbsName(branchId,portNameOnCurPrt,first);//Cast granted because impossible to have cross protocol with _splittedPort
359 //see OptimizerLoop::buildDelegateOf
360 if(portOnGivenBranch)
363 portOnGivenBranch->edNotifyReferencedBy(0);
364 InputPort *traducer=getRuntime()->adapt(portOnGivenBranch,
365 Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME,_splittedPort.edGetType());
366 traducer->put((const void *)val);
368 if(traducer!=portOnGivenBranch)
374 Any *tmp=val->clone();
375 _splittedPort.setValue(tmp);
380 DynParaLoop::TypeOfNode DynParaLoop::getIdentityOfNotifyerNode(const Node *node, unsigned& id)
382 vector<Node *>::iterator iter;
384 for (iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++,id++)
388 for (iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++,id++)
392 for (iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++,id++)
394 return FINALIZE_NODE;
397 bool DynParaLoop::isMultiplicitySpecified(unsigned& value) const
399 if(_nbOfBranches.edIsManuallyInitialized())
400 if(_nbOfBranches.edGetNumberOfLinks()==0)
402 value=_nbOfBranches.getIntValue();
408 void DynParaLoop::forceMultiplicity(unsigned value)
410 _nbOfBranches.edRemoveAllLinksLinkedWithMe();
411 _nbOfBranches.edInit((int)value);
414 void DynParaLoop::buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView)
416 string typeOfPortInstance=port->getNameOfTypeOfCurrentInstance();
417 if(typeOfPortInstance!=InputPort::NAME)
418 throw Exception("DynParaLoop::buildDelegateOf : A link with datastream end inside DynParaLoop this is not possible");
421 void DynParaLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
424 if(isInMyDescendance(port.first->getNode())==_initNode)
425 throw Exception("DynParaLoop::buildDelegateOf : uncorrect ForEach link : a link starting from init node can't leave the scope of ForEachLoop node it belongs to.");
426 if(port.first==&_splittedPort)
427 throw Exception("DynParaLoop::buildDelegateOf : uncorrect ForEach link : splitted port must be link within the scope of ForEachLoop node it belongs to.");
430 void DynParaLoop::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
432 const char what[]="DynParaLoop::checkCFLinks : internal error.";
433 //First dealing checkCFLinks forwarding...
434 if(isInMyDescendance(end->getNode())==0)//no chance that _splittedPort is in starts due to buildDelegate.
435 solveObviousOrDelegateCFLinks(starts,end,alreadyFed,direction,info);
437 {//no forwarding here.
439 throw Exception(what);
440 //ASSERT(direction) : see DynParaLoop::checkControlDependancy only 'fw' filled.
441 if(*(starts.begin())!=&_splittedPort)
442 throw Exception(what);
443 if(alreadyFed==FREE_ST)
445 else if(alreadyFed==FED_ST)
446 {//Shame ! splittedPort fills a port already fed...
447 info.pushInfoLink(*(starts.begin()),end,I_USELESS);
453 * \param start : start port
454 * \param end : end port
455 * \param cross indicates if start -> end link is a DS link behind.
456 * \param fw out parameter.
457 * \param fwCross out parameter storing links where a cross has been detected.
458 * \param bw out parameter where backward links are stored.
459 * \param info : collected information
461 void DynParaLoop::checkControlDependancy(OutPort *start, InPort *end, bool cross,
462 std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
463 std::vector<OutPort *>& fwCross,
464 std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
465 LinkInfo& info) const
467 if(start==&_splittedPort)
468 fw[(ComposedNode *)this].push_back(start);
470 throw Exception("DynParaLoop::checkControlDependancy : Internal error occured - should never been called !");
474 * \note : For a given name 'name' of port in absolute form from this, returns the corresponding InputPort
475 * instance of the port for the branch # 'branchNb'.
476 * The port can be part of _node or _initNode if it exists (if 'initNodeAdmitted' is true).
477 * \b WARNING : no check performed on 'branchNb' value to see if it is compatible with size of '_execNodes'.
478 * This method is called to dispatch value on each InputPort linked to this->._splitterNode._splittedPort
480 InputPort *DynParaLoop::getDynInputPortByAbsName(int branchNb, const std::string& name, bool initNodeAdmitted)
482 string portName, nodeName;
483 splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,true);
484 Node *staticChild = getChildByName(nodeName);
485 Node *desc=isInMyDescendance(staticChild);
488 splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false);
489 return _execNodes[branchNb]->getInputPort(portName);
491 else if(desc==_initNode)
494 splitNamesBySep(name,Node::SEP_CHAR_IN_PORT,nodeName,portName,false);
495 return _execInitNodes[branchNb]->getInputPort(portName);
500 void DynParaLoop::checkBasicConsistency() const throw(YACS::Exception)
502 DEBTRACE("DynParaLoop::checkBasicConsistency");
503 ComposedNode::checkBasicConsistency();
505 throw Exception("For a dynamic loop, internal node is mandatory");
508 std::string DynParaLoop::getErrorReport()
510 DEBTRACE("DynParaLoop::getErrorReport: " << getName() << " " << _state);
511 YACS::StatesForNode effectiveState=getEffectiveState();
513 if(effectiveState != YACS::INVALID && effectiveState != YACS::ERROR && effectiveState != YACS::FAILED)
516 std::string report="<error node= " + getName();
517 switch(effectiveState)
520 report=report+" state= INVALID";
523 report=report+" state= ERROR";
526 report=report+" state= FAILED";
531 report=report + ">\n" ;
532 if(_errorDetails != "")
533 report=report+_errorDetails+"\n";
535 if(_execNodes.empty())
538 list<Node *> constituents=edGetDirectDescendants();
539 for(list<Node *>::iterator iter=constituents.begin(); iter!=constituents.end(); iter++)
541 std::string rep=(*iter)->getErrorReport();
544 report=report+rep+"\n";
551 for(vector<Node *>::iterator iter=_execInitNodes.begin();iter!=_execInitNodes.end();iter++)
553 std::string rep=(*iter)->getErrorReport();
556 report=report+rep+"\n";
559 for(vector<Node *>::iterator iter=_execNodes.begin();iter!=_execNodes.end();iter++)
561 std::string rep=(*iter)->getErrorReport();
564 report=report+rep+"\n";
567 for(vector<Node *>::iterator iter=_execFinalizeNodes.begin();iter!=_execFinalizeNodes.end();iter++)
569 std::string rep=(*iter)->getErrorReport();
572 report=report+rep+"\n";
577 report=report+"</error>";
581 void DynParaLoop::forwardExecStateToOriginalBody(Node *execNode)
584 Node * origNode = NULL;
585 switch (getIdentityOfNotifyerNode(execNode,id))
589 origNode = _initNode;
599 origNode = _finalizeNode;
606 YASSERT(origNode != NULL)
607 origNode->setState(execNode->getState());
608 origNode->setErrorDetails(execNode->getErrorDetails());
610 ComposedNode* compNode = dynamic_cast<ComposedNode*>(origNode);
611 ComposedNode* compNodeExe = dynamic_cast<ComposedNode*>(execNode);
612 if (compNode && compNodeExe)
614 list<Node *> aChldn = compNodeExe->getAllRecursiveConstituents();
615 list<Node *>::iterator iter=aChldn.begin();
616 for(;iter!=aChldn.end();iter++)
618 Node* node=compNode->getChildByName(compNodeExe->getChildName(*iter));
619 node->setState((*iter)->getState());
620 node->setErrorDetails((*iter)->getErrorDetails());
625 //! Method used to notify the node that a child node has failed
627 * Update the current state and return the change state
629 * \param node : the child node that has failed
630 * \return the state change
632 YACS::Event DynParaLoop::updateStateOnFailedEventFrom(Node *node)
634 DEBTRACE("DynParaLoop::updateStateOnFailedEventFrom " << node->getName());
635 setState(YACS::FAILED);
636 forwardExecStateToOriginalBody(node);
638 switch (getIdentityOfNotifyerNode(node,id))
642 _node->setState(YACS::FAILED);
643 if (_finalizeNode != NULL) _finalizeNode->setState(YACS::FAILED);
648 if (_finalizeNode != NULL) _finalizeNode->setState(YACS::FAILED);
655 //! Clone nodes and make their placement consistent with the placement of the original ones.
657 * For instance, if two original nodes are placed on a component comp1 in a container cont1
658 * and a third one is placed on a component comp2 in the container cont1, the clones of the two
659 * first nodes will be placed on a component comp3 in a container cont2 and the third clone
660 * will be placed on a component comp4 in the container cont2.
662 vector<Node *> DynParaLoop::cloneAndPlaceNodesCoherently(const vector<Node *> & origNodes)
664 DEBTRACE("Begin cloneAndPlaceNodesCoherently")
665 vector<Node *> clones;
666 DeploymentTree treeToDup;
667 vector<list<ElementaryNode *> > origElemNodeList;
668 for (int i=0 ; i<origNodes.size() ; i++)
670 DEBTRACE("Cloning node " << i)
671 if (origNodes[i] == NULL)
673 DEBTRACE("Cloning node " << i << ", NULL" )
674 clones.push_back(NULL);
675 origElemNodeList.push_back(list<ElementaryNode *>());
679 DEBTRACE("Cloning node " << i << "," << origNodes[i]->getName())
680 clones.push_back(origNodes[i]->simpleClone(this, false));
681 list<ElementaryNode *> tasks = origNodes[i]->getRecursiveConstituents();
682 origElemNodeList.push_back(tasks);
683 for (list< ElementaryNode *>::iterator iter=tasks.begin() ; iter!=tasks.end() ; iter++)
684 treeToDup.appendTask(*iter, (*iter)->getDynClonerIfExists(this));
688 DEBTRACE("Placing nodes...")
689 vector<Container *> conts=treeToDup.getAllContainers();
691 //iterate on all containers
692 for(vector<Container *>::iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
694 DEBTRACE("Container " << ((*iterCt)?(*iterCt)->getName():"NULL"))
695 vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
696 Container *contCloned=0;
698 contCloned=(*iterCt)->clone();
700 //iterate on all component instances linked to the container
701 for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
703 DEBTRACE("Component " << (*iterCp)->getCompoName())
704 vector<Task *> tasks=treeToDup.getTasksLinkedToComponent(*iterCp);
705 ComponentInstance *curCloned=(*iterCp)->clone();
706 DEBTRACE("Assign container " << (*iterCp)->getCompoName())
707 curCloned->setContainer(contCloned);
708 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
710 DEBTRACE("Task " << ((ElementaryNode *)(*iterT))->getName())
712 ElementaryNode * origElemNode = NULL;
713 for (i=0 ; i<origNodes.size() ; i++)
714 if (origNodes[i] != NULL)
716 DEBTRACE("Looking in original node " << i)
717 list<ElementaryNode *>::iterator res=find(origElemNodeList[i].begin(),
718 origElemNodeList[i].end(),
719 (ElementaryNode *)(*iterT));
720 if (res != origElemNodeList[i].end()) {
726 YASSERT(origElemNode != NULL)
727 DEBTRACE("Found task in node " << i)
728 ServiceNode * nodeC = NULL;
729 if (origNodes[i] == origElemNode)
730 nodeC = (ServiceNode *)clones[i];
733 string childName = ((ComposedNode *)origNodes[i])->getChildName(origElemNode);
734 nodeC = (ServiceNode *)clones[i]->getChildByName(childName);
736 DEBTRACE("Assign component: " << (*iterCp)->getCompoName() << "," << nodeC->getName())
737 nodeC->setComponent(curCloned);
739 curCloned->decrRef();
742 // iterate on all tasks linked to the container
743 vector<Task *> tasks=treeToDup.getTasksLinkedToContainer(*iterCt);
744 for(vector<Task *>::iterator iterT=tasks.begin();iterT!=tasks.end();iterT++)
746 DEBTRACE("Task " << ((ElementaryNode *)(*iterT))->getName())
748 ElementaryNode * origElemNode = NULL;
749 for (i=0 ; i<origNodes.size() ; i++)
750 if (origNodes[i] != NULL)
752 DEBTRACE("Looking in original node " << i)
753 list<ElementaryNode *>::iterator res=find(origElemNodeList[i].begin(),
754 origElemNodeList[i].end(),
755 (ElementaryNode *)(*iterT));
756 if (res != origElemNodeList[i].end())
762 YASSERT(origElemNode != NULL)
763 DEBTRACE("Found task in node " << i)
764 InlineFuncNode * nodeC = NULL;
765 if (origNodes[i] == origElemNode)
767 nodeC = (InlineFuncNode *)clones[i];
771 string childName = ((ComposedNode *)origNodes[i])->getChildName(origElemNode);
772 nodeC = (InlineFuncNode *)clones[i]->getChildByName(childName);
774 DEBTRACE("Assign container " << nodeC->getName() << "," << contCloned->getName())
775 nodeC->setContainer(contCloned);
778 // ended with current container
780 contCloned->decrRef();
783 DEBTRACE("End cloneAndPlaceNodesCoherently")
787 void DynParaLoop::accept(Visitor *visitor)
789 visitor->visitDynParaLoop(this);
792 Node * DynParaLoop::getInitNode()
797 Node * DynParaLoop::getExecNode()
802 Node * DynParaLoop::getFinalizeNode()
804 return _finalizeNode;
807 void DynParaLoop::shutdown(int level)
812 std::vector<Node *>::iterator iter;
813 for (iter=_execNodes.begin() ; iter!=_execNodes.end() ; iter++)
814 (*iter)->shutdown(level);
815 for (iter=_execInitNodes.begin() ; iter!=_execInitNodes.end() ; iter++)
816 (*iter)->shutdown(level);
817 for (iter=_execFinalizeNodes.begin() ; iter!=_execFinalizeNodes.end() ; iter++)
818 (*iter)->shutdown(level);