X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fengine%2FOptimizerLoop.cxx;h=48fbf9abdc978081b130e494461704dd9d60a254;hb=c9208a8ef7f32a620d9650908588320ff159a167;hp=152b578f1c620d9dafb9698bbc1789373a84ae51;hpb=c81be9b5e74b26e207bd6efd0ccf68418ac536a3;p=modules%2Fyacs.git diff --git a/src/engine/OptimizerLoop.cxx b/src/engine/OptimizerLoop.cxx index 152b578f1..48fbf9abd 100644 --- a/src/engine/OptimizerLoop.cxx +++ b/src/engine/OptimizerLoop.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2006-2012 CEA/DEN, EDF R&D +// Copyright (C) 2006-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -98,7 +98,7 @@ void FakeNodeForOptimizerLoop::finished() OptimizerLoop::OptimizerLoop(const std::string& name, const std::string& algLibWthOutExt, const std::string& symbolNameToOptimizerAlgBaseInstanceFactory, bool algInitOnFile,bool initAlgo, Proc * procForTypes): - DynParaLoop(name,Runtime::_tc_string),_algInitOnFile(algInitOnFile),_alglib(algLibWthOutExt), + DynParaLoop(name,Runtime::_tc_string,std::unique_ptr(new NbBranches(this))),_algInitOnFile(algInitOnFile),_alglib(algLibWthOutExt), _algoInitPort(NAME_OF_ALGO_INIT_PORT, this, Runtime::_tc_string, true), _loader(NULL),_alg(0),_convergenceReachedWithOtherCalc(false), _retPortForOutPool(NAME_OF_OUT_POOL_INPUT,this,Runtime::_tc_string), @@ -117,6 +117,11 @@ OptimizerLoop::OptimizerLoop(const OptimizerLoop& other, ComposedNode *father, b _algoResultPort(other._algoResultPort, this) { //Don't call setAlgorithm here because it will be called several times if the class is derived. Call it in simpleClone for cloning + + // Create the links to evalResults port + set fromPortsToReproduce=other._retPortForOutPool.edSetOutPort(); + for(set::iterator iter=fromPortsToReproduce.begin();iter!=fromPortsToReproduce.end();iter++) + edAddLink(getOutPort(other.getPortName(*iter)),&_retPortForOutPool); } OptimizerLoop::~OptimizerLoop() @@ -170,7 +175,6 @@ void OptimizerLoop::exUpdateState() // Initialize and launch the algorithm _alg->initializeProxy(_algoInitPort.getValue()); - _alg->startProxy(); if (_alg->hasError()) { string error = _alg->getError(); _alg->finishProxy(); @@ -179,7 +183,16 @@ void OptimizerLoop::exUpdateState() //internal graph update int i; - int nbOfBr=_nbOfBranches.getIntValue(); + int nbOfBr=_nbOfBranches->getIntValue(); + _alg->setNbOfBranches(nbOfBr); + + _alg->startProxy(); + if (_alg->hasError()) { + string error = _alg->getError(); + _alg->finishProxy(); + throw Exception(error); + } + if(nbOfBr==0) { // A number of branches of 0 is acceptable if there are no output ports @@ -232,6 +245,7 @@ void OptimizerLoop::exUpdateState() _nodeForSpecialCases = new FakeNodeForOptimizerLoop(this, normal, string("The algorithm of OptimizerLoop with name ") + _name + " returns no sample to launch"); + _alg->finishProxy(); return; } launchMaxOfSamples(true); @@ -409,8 +423,8 @@ YACS::Event OptimizerLoop::finalize() (*iter)->setState(YACS::DONE); } } - _alg->finishProxy(); _algoResultPort.put(_alg->getAlgoResultProxy()); + _alg->finishProxy(); if (_finalizeNode == NULL) { // No finalize node, we just finish OptimizerLoop at the end of exec nodes execution @@ -421,7 +435,7 @@ YACS::Event OptimizerLoop::finalize() { // Run the finalize nodes, the OptimizerLoop will be done only when they all finish _unfinishedCounter = 0; // This counter indicates how many branches are not finished - for (int i=0 ; i<_nbOfBranches.getIntValue() ; i++) + for (int i=0 ; i<_nbOfBranches->getIntValue() ; i++) if (_execIds[i] == NOT_RUNNING_BRANCH_ID) { DEBTRACE("Launching finalize node for branch " << i) @@ -443,7 +457,7 @@ YACS::Event OptimizerLoop::finalize() * \param node : the child node that has failed * \return the state change */ -YACS::Event OptimizerLoop::updateStateOnFailedEventFrom(Node *node) +YACS::Event OptimizerLoop::updateStateOnFailedEventFrom(Node *node, const Executor *execInst) { DEBTRACE("OptimizerLoop::updateStateOnFailedEventFrom " << node->getName()); _alg->setError(string("Error during the execution of YACS node ") + node->getName() + @@ -451,7 +465,7 @@ YACS::Event OptimizerLoop::updateStateOnFailedEventFrom(Node *node) _alg->finishProxy(); _myPool.destroyAll(); DEBTRACE("OptimizerLoop::updateStateOnFailedEventFrom: returned from error notification."); - return DynParaLoop::updateStateOnFailedEventFrom(node); + return DynParaLoop::updateStateOnFailedEventFrom(node,execInst); } void OptimizerLoop::checkNoCyclePassingThrough(Node *node) throw(YACS::Exception) @@ -462,12 +476,27 @@ void OptimizerLoop::buildDelegateOf(InPort * & port, OutPort *initialStart, cons { DynParaLoop::buildDelegateOf(port,initialStart,pointsOfView); if(port==&_retPortForOutPool) - throw Exception("OptimizerLoop::buildDelegateOf : uncorrect OptimizerLoop link : out pool port must be linked within the scope of OptimizerLoop node it belongs to."); + { + std::string linkName("("); + linkName += initialStart->getName()+" to "+port->getName()+")"; + throw Exception(std::string("Illegal OptimizerLoop link: \ +The 'evalResults' port must be linked within the scope of the loop.") + + linkName); + } } void OptimizerLoop::buildDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView) { DynParaLoop::buildDelegateOf(port,finalTarget,pointsOfView); + if(port.first != &_algoResultPort) + { + std::string linkName("("); + linkName += port.first->getName()+" to "+finalTarget->getName()+")"; + throw Exception(std::string("Illegal OptimizerLoop link: \ +Only the algorithm result port can be linked to a port outside the scope of the loop.") + + linkName); + } + string typeOfPortInstance=(port.first)->getNameOfTypeOfCurrentInstance(); if(typeOfPortInstance!=OutputPort::NAME) throw Exception("OptimizerLoop::buildDelegateOf : not implemented for DS because not specified "); @@ -493,6 +522,29 @@ void OptimizerLoop::checkCFLinks(const std::list& starts, InputPort * DynParaLoop::checkCFLinks(starts,end,alreadyFed,direction,info); } +void OptimizerLoop::checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, + InPort *end, const std::list& pointsOfViewEnd) throw(YACS::Exception) +{ + DynParaLoop::checkLinkPossibility(start, pointsOfViewStart, end, pointsOfViewEnd); + std::string linkName("("); + linkName += start->getName()+" to "+end->getName()+")"; + + // Yes, it should be possible to link back the result port to any input port of the loop. + if(end == _nbOfBranches->getPort() || end == &_algoInitPort) + if(start != &_algoResultPort) + throw Exception(std::string("Illegal OptimizerLoop link.") + linkName); + else + return; + + if(start == &_algoResultPort) + throw Exception(std::string("Illegal OptimizerLoop link: \ +The 'algoResult' port can't be linked within the scope of the loop.") + linkName); + + if(end == &_retPortForOutPool && isInMyDescendance(start->getNode())!=_node) + throw Exception(std::string("Illegal OptimizerLoop link: \ +The 'evalResults' port can only be linked to the working node.") + linkName); +} + void OptimizerLoop::cleanInterceptors() { // At this point all garanties taken let's clean all.