-// 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
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<NbBranchesAbstract>(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),
_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<OutPort *> fromPortsToReproduce=other._retPortForOutPool.edSetOutPort();
+ for(set<OutPort *>::iterator iter=fromPortsToReproduce.begin();iter!=fromPortsToReproduce.end();iter++)
+ edAddLink(getOutPort(other.getPortName(*iter)),&_retPortForOutPool);
}
OptimizerLoop::~OptimizerLoop()
// Initialize and launch the algorithm
_alg->initializeProxy(_algoInitPort.getValue());
- _alg->startProxy();
if (_alg->hasError()) {
string error = _alg->getError();
_alg->finishProxy();
//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
_nodeForSpecialCases = new FakeNodeForOptimizerLoop(this, normal,
string("The algorithm of OptimizerLoop with name ") + _name +
" returns no sample to launch");
+ _alg->finishProxy();
return;
}
launchMaxOfSamples(true);
(*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
{
// 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)
* \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() +
_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)
{
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<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& 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 ");
DynParaLoop::checkCFLinks(starts,end,alreadyFed,direction,info);
}
+void OptimizerLoop::checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
+ InPort *end, const std::list<ComposedNode *>& 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.