1 // Copyright (C) 2012-2015 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
19 // Author : Anthony Geay (EDF R&D)
21 #include "YACSEvalYFXPattern.hxx"
22 #include "YACSEvalResource.hxx"
23 #include "YACSEvalSeqAny.hxx"
24 #include "YACSEvalObserver.hxx"
25 #include "YACSEvalAutoPtr.hxx"
27 #include "ElementaryNode.hxx"
28 #include "RuntimeSALOME.hxx"
29 #include "Dispatcher.hxx"
30 #include "Executor.hxx"
31 #include "InputPort.hxx"
32 #include "LinkInfo.hxx"
33 #include "TypeCode.hxx"
36 #include "PythonPorts.hxx"
37 #include "ForEachLoop.hxx"
38 #include "PythonNode.hxx"
39 #include "InlineNode.hxx"
40 #include "ServiceNode.hxx"
41 #include "PyStdout.hxx"
42 #include "AutoGIL.hxx"
44 #include "ResourcesManager.hxx"
55 const char YACSEvalYFXPattern::DFT_PROC_NAME[]="YFX";
57 const char YACSEvalYFXPattern::ST_OK[]="ALL_OK";
59 const char YACSEvalYFXPattern::ST_FAILED[]="SOME_SAMPLES_FAILED_AND_ALL_OF_THEM_FAILED_DETERMINISTICALLY";
61 const char YACSEvalYFXPattern::ST_ERROR[]="SOME_SAMPLES_FAILED_BUT_IMPOSSIBLE_TO_CONCLUDE_ON_THEM";
63 const std::size_t YACSEvalYFXPattern::MAX_LGTH_OF_INP_DUMP=10000;
65 const char YACSEvalYFXRunOnlyPattern::FIRST_FE_SUBNODE_NAME[]="Bloc";
67 const char YACSEvalYFXRunOnlyPattern::GATHER_NODE_NAME[]="__gather__";
69 class MyAutoThreadSaver
72 MyAutoThreadSaver():_save(PyEval_SaveThread()) { }
73 ~MyAutoThreadSaver() { PyEval_RestoreThread(_save); }
78 std::vector< YACSEvalInputPort *> YACSEvalYFXPattern::getFreeInputPorts() const
80 std::size_t sz(_inputs.size());
81 std::vector< YACSEvalInputPort *> ret;
82 std::vector< YACSEvalInputPort >::const_iterator it(_inputs.begin());
83 for(std::size_t i=0;i<sz;i++,it++)
84 ret.push_back(const_cast<YACSEvalInputPort *>(&(*it)));
88 std::vector< YACSEvalOutputPort *> YACSEvalYFXPattern::getFreeOutputPorts() const
90 std::size_t sz(_outputs.size());
91 std::vector< YACSEvalOutputPort *> ret;
92 std::vector< YACSEvalOutputPort >::const_iterator it(_outputs.begin());
93 for(std::size_t i=0;i<sz;i++,it++)
94 ret.push_back(const_cast<YACSEvalOutputPort *>(&(*it)));
98 YACSEvalYFXPattern *YACSEvalYFXPattern::FindPatternFrom(YACSEvalYFX *boss, YACS::ENGINE::Proc *scheme, bool ownScheme)
101 throw YACS::Exception("YACSEvalYFXPattern::FindPatternFrom : input scheme must be not null !");
103 YACS::ENGINE::ComposedNode *zeRunNode(0);
104 bool isMatchingRunOnlyPattern(YACSEvalYFXRunOnlyPattern::IsMatching(scheme,zeRunNode));
105 if(isMatchingRunOnlyPattern)
106 return new YACSEvalYFXRunOnlyPattern(boss,scheme,ownScheme,zeRunNode);
108 throw YACS::Exception("YACSEvalYFXPattern::FindPatternFrom : no pattern found for the input scheme !");
111 bool YACSEvalYFXPattern::isAlreadyComputedResources() const
116 void YACSEvalYFXPattern::checkNonAlreadyComputedResources() const
118 if(isAlreadyComputedResources())
119 throw YACS::Exception("checkNonAlreadyComputedResources : instance of computed resources already computed !");
122 void YACSEvalYFXPattern::checkAlreadyComputedResources() const
124 if(!isAlreadyComputedResources())
125 throw YACS::Exception("checkAlreadyComputedResources : instance of computed resources not already computed !");
128 void YACSEvalYFXPattern::checkLocked() const
131 throw YACS::Exception("YACSEvalYFXPattern::checkLocked : Pattern is not locked !");
134 void YACSEvalYFXPattern::checkNonLocked() const
137 throw YACS::Exception("YACSEvalYFXPattern::checkNonLocked : Pattern is locked !");
140 void YACSEvalYFXPattern::CheckNodeIsOK(YACS::ENGINE::ComposedNode *node)
142 /*YACS::ENGINE::LinkInfo info(YACS::ENGINE::LinkInfo::WARN_ONLY_DONT_STOP);
145 node->checkConsistency(info);
147 catch(YACS::Exception& e)
150 if(info.getNumberOfErrLinks(YACS::ENGINE::E_ALL)!=0)
151 throw YACS::Exception("YACSEvalYFXPattern::CheckNodeIsOK : found node is not OK !");
152 std::list<YACS::ENGINE::ElementaryNode *> allNodes(node->getRecursiveConstituents());
153 for(std::list<YACS::ENGINE::ElementaryNode *>::const_iterator it=allNodes.begin();it!=allNodes.end();it++)
155 YACS::ENGINE::ServiceNode *node0(dynamic_cast<YACS::ENGINE::ServiceNode *>(*it));
156 YACS::ENGINE::InlineNode *node1(dynamic_cast<YACS::ENGINE::InlineNode *>(*it));
159 YACS::ENGINE::Container *cont(node0->getContainer());
160 YACS::ENGINE::ComponentInstance *comp(node0->getComponent());
163 std::ostringstream oss; oss << "YACSEvalYFXPattern::CheckNodeIsOK : ServiceNode called \"" << node0->getName() << "\" is not correctly defined !";
164 throw YACS::Exception(oss.str());
169 YACS::ENGINE::Container *cont(node1->getContainer());
170 if(!cont && node1->getExecutionMode()==YACS::ENGINE::InlineNode::REMOTE_STR)
172 std::ostringstream oss; oss << "YACSEvalYFXPattern::CheckNodeIsOK : InlineNode called \"" << node1->getName() << "\" is not correctly defined !";
173 throw YACS::Exception(oss.str());
179 void YACSEvalYFXPattern::registerObserver(YACSEvalObserver *observer)
181 if(_observer==observer)
184 _observer->decrRef();
187 _observer->incrRef();
190 YACSEvalYFXPattern::YACSEvalYFXPattern(YACSEvalYFX *boss, YACS::ENGINE::Proc *scheme, bool ownScheme):_boss(boss),_scheme(scheme),_ownScheme(ownScheme),_parallelizeStatus(true),_rm(new ResourcesManager_cpp),_res(0),_observer(0)
194 YACS::ENGINE::TypeCode *YACSEvalYFXPattern::createSeqTypeCodeFrom(YACS::ENGINE::Proc *scheme, const std::string& zeType)
196 std::ostringstream oss; oss << "list[" << zeType << "]";
197 YACS::ENGINE::TypeCode *tc(scheme->getTypeCode(zeType));
198 return scheme->createSequenceTc(oss.str(),oss.str(),tc);
201 void YACSEvalYFXPattern::setResources(YACSEvalListOfResources *res)
203 checkNonAlreadyComputedResources();
209 void YACSEvalYFXPattern::resetResources()
215 YACSEvalSeqAny *YACSEvalYFXPattern::BuildValueInPort(YACS::ENGINE::InputPyPort *port)
218 throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : null input port !");
219 PyObject *obj(port->getPyObj());
220 YACS::ENGINE::TypeCode *tc(port->edGetType());
221 YACS::ENGINE::TypeCodeSeq *tcc(dynamic_cast<YACS::ENGINE::TypeCodeSeq *>(tc));
224 std::ostringstream oss; oss << "YACSEvalYFXPattern::GetValueInPort : internal error for tc of input \"" << port->getName() << "\"";
225 throw YACS::Exception(oss.str());
227 const YACS::ENGINE::TypeCode *tcct(tcc->contentType());
228 if(!PyList_Check(obj))
229 throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : internal error 2 !");
230 std::size_t sz(PyList_Size(obj));
231 if(tcct->kind()==YACS::ENGINE::Double)
233 std::vector<double> eltCpp(sz);
234 for(std::size_t i=0;i<sz;i++)
236 PyObject *elt(PyList_GetItem(obj,i));
237 eltCpp[i]=PyFloat_AsDouble(elt);
239 YACS::AutoCppPtr<YACSEvalSeqAnyDouble> elt(new YACSEvalSeqAnyDouble(eltCpp));
240 return elt.dettach();
242 else if(tcct->kind()==YACS::ENGINE::Int)
244 std::vector<int> eltCpp(sz);
245 for(std::size_t i=0;i<sz;i++)
247 PyObject *elt(PyList_GetItem(obj,i));
248 eltCpp[i]=PyInt_AsLong(elt);
250 YACS::AutoCppPtr<YACSEvalSeqAnyInt> elt(new YACSEvalSeqAnyInt(eltCpp));
251 return elt.dettach();
254 throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : not implemented yet for other than Double and Int !");
257 YACSEvalSeqAny *YACSEvalYFXPattern::BuildValueFromEngineFrmt(YACS::ENGINE::SequenceAny *data)
259 unsigned int sz(data->size());
260 std::vector<double> eltCpp(sz);
261 for(unsigned int ii=0;ii<sz;ii++)
263 YACS::ENGINE::AnyPtr elt((*data)[ii]);
264 YACS::ENGINE::Any *eltPtr((YACS::ENGINE::Any *)elt);
265 YACS::ENGINE::AtomAny *eltPtr2(dynamic_cast<YACS::ENGINE::AtomAny *>(eltPtr));
268 std::ostringstream oss; oss << "YACSEvalYFXPattern::BuildValueFromEngineFrmt : error at pos #" << ii << " ! It is not an AtomAny !";
269 throw YACS::Exception(oss.str());
271 eltCpp[ii]=eltPtr2->getDoubleValue();
273 return new YACSEvalSeqAnyDouble(eltCpp);
276 void YACSEvalYFXPattern::cleanScheme()
283 YACSEvalYFXPattern::~YACSEvalYFXPattern()
286 _observer->decrRef();
291 /////////////////////
293 class YACSEvalYFXRunOnlyPatternInternalObserver : public YACS::ENGINE::Observer
296 YACSEvalYFXRunOnlyPatternInternalObserver(YACSEvalYFXRunOnlyPattern *boss):_boss(boss) { if(!_boss) throw YACS::Exception("YACSEvalYFXRunOnlyPatternInternalObserver constructor : null boss not supported :)"); }
297 void notifyObserver(YACS::ENGINE::Node *object, const std::string& event);
299 YACSEvalYFXRunOnlyPattern *_boss;
302 void YACSEvalYFXRunOnlyPatternInternalObserver::notifyObserver(YACS::ENGINE::Node *object, const std::string& event)
304 YACS::ENGINE::ForEachLoop *object2(dynamic_cast<YACS::ENGINE::ForEachLoop *>(object));
307 YACSEvalObserver *obs(_boss->getObserver());
310 if(event=="progress")
311 obs->notifyNewNumberOfPassedItems(_boss->getBoss(),object2->getCurrentIndex());
314 /////////////////////
316 YACSEvalYFXRunOnlyPattern::YACSEvalYFXRunOnlyPattern(YACSEvalYFX *boss, YACS::ENGINE::Proc *scheme, bool ownScheme, YACS::ENGINE::ComposedNode *runNode):YACSEvalYFXPattern(boss,scheme,ownScheme),_runNode(runNode),_generatedGraph(0),_FEInGeneratedGraph(0),_obs(new YACSEvalYFXRunOnlyPatternInternalObserver(this))
319 throw YACS::Exception("YACSEvalYFXRunOnlyPattern : internal run node must be not null !");
324 YACSEvalYFXRunOnlyPattern::~YACSEvalYFXRunOnlyPattern()
329 void YACSEvalYFXRunOnlyPattern::setOutPortsOfInterestForEvaluation(const std::vector<YACSEvalOutputPort *>& outputsOfInterest)
332 _outputsOfInterest=outputsOfInterest;
335 void YACSEvalYFXRunOnlyPattern::resetOutputsOfInterest()
338 _outputsOfInterest.clear();
341 void YACSEvalYFXRunOnlyPattern::generateGraph()
343 static const char LISTPYOBJ_STR[]="list[pyobj]";
344 if(_outputsOfInterest.empty())
346 YACS::ENGINE::RuntimeSALOME::setRuntime();
347 YACS::ENGINE::RuntimeSALOME *r(YACS::ENGINE::getSALOMERuntime());
348 _generatedGraph=r->createProc(DFT_PROC_NAME);
349 YACS::ENGINE::TypeCode *pyobjTC(_generatedGraph->createInterfaceTc("python:obj:1.0","pyobj",std::list<YACS::ENGINE::TypeCodeObjref *>()));
350 std::ostringstream oss; oss << "Loop_" << _runNode->getName();
351 _generatedGraph->createType(YACSEvalAnyDouble::TYPE_REPR,"double");
352 _generatedGraph->createType(YACSEvalAnyInt::TYPE_REPR,"int");
354 YACS::ENGINE::InlineNode *n0(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__initializer__"));
355 _generatedGraph->edAddChild(n0);
356 YACS::ENGINE::TypeCode *listPyobjTC(_generatedGraph->createSequenceTc(LISTPYOBJ_STR,LISTPYOBJ_STR,pyobjTC));
357 YACS::ENGINE::OutputPort *sender(n0->edAddOutputPort("sender",listPyobjTC));
358 std::ostringstream var0;
359 for(std::vector< YACSEvalInputPort >::const_iterator it=_inputs.begin();it!=_inputs.end();it++)
361 if((*it).isRandomVar())
363 var0 << (*it).getName() << ",";
364 YACS::ENGINE::TypeCode *tc(createSeqTypeCodeFrom(_generatedGraph,(*it).getTypeOfData()));
365 YACS::ENGINE::InputPort *inp(n0->edAddInputPort((*it).getName(),tc));
366 YACS::ENGINE::InputPyPort *inpc(dynamic_cast<YACS::ENGINE::InputPyPort *>(inp));
368 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::generateGraph : internal error 1 !");
369 (*it).setUndergroundPortToBeSet(inpc);
372 std::ostringstream n0Script; n0Script << "sender=zip(" << var0.str() << ")\n";
373 n0->setScript(n0Script.str());
375 YACS::ENGINE::ForEachLoop *n1(r->createForEachLoop(oss.str(),pyobjTC));
376 _FEInGeneratedGraph=n1;
377 _generatedGraph->edAddChild(n1);
378 _generatedGraph->edAddCFLink(n0,n1);
379 _generatedGraph->edAddDFLink(sender,n1->edGetSeqOfSamplesPort());
380 YACS::ENGINE::InlineNode *n2(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,GATHER_NODE_NAME));
381 _generatedGraph->edAddChild(n2);
382 _generatedGraph->edAddCFLink(n1,n2);
384 YACS::ENGINE::Bloc *n10(r->createBloc(FIRST_FE_SUBNODE_NAME));
386 YACS::ENGINE::InlineNode *n100(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__dispatch__"));
387 YACS::ENGINE::Node *n101(_runNode->cloneWithoutCompAndContDeepCpy(0,true));
388 n10->edAddChild(n100);
389 n10->edAddChild(n101);
390 YACS::ENGINE::InputPort *dispatchIn(n100->edAddInputPort("i0",pyobjTC));
391 n10->edAddCFLink(n100,n101);
392 n1->edAddDFLink(n1->edGetSamplePort(),dispatchIn);
393 std::ostringstream var1;
394 for(std::vector< YACSEvalInputPort >::const_iterator it=_inputs.begin();it!=_inputs.end();it++)
396 if((*it).isRandomVar())
398 var1 << (*it).getName() << ",";
399 YACS::ENGINE::OutputPort *myOut(n100->edAddOutputPort((*it).getName(),_generatedGraph->getTypeCode((*it).getTypeOfData())));
400 std::string tmpPortName(_runNode->getInPortName((*it).getUndergroundPtr()));
401 YACS::ENGINE::InputPort *myIn(n101->getInputPort(tmpPortName));
402 n10->edAddDFLink(myOut,myIn);
405 std::ostringstream n100Script; n100Script << var1.str() << "=i0\n";
406 n100->setScript(n100Script.str());
407 for(std::vector< YACSEvalOutputPort * >::const_iterator it=_outputsOfInterest.begin();it!=_outputsOfInterest.end();it++)
409 YACS::ENGINE::TypeCode *tc(createSeqTypeCodeFrom(_generatedGraph,(*it)->getTypeOfData()));
410 YACS::ENGINE::InputPort *myIn(n2->edAddInputPort((*it)->getName(),tc));
411 std::string tmpPortName(_runNode->getOutPortName((*it)->getUndergroundPtr()));
412 YACS::ENGINE::OutputPort *myOut(n101->getOutputPort(tmpPortName));
413 _generatedGraph->edAddDFLink(myOut,myIn);
415 _generatedGraph->updateContainersAndComponents();
418 void YACSEvalYFXRunOnlyPattern::resetGeneratedGraph()
420 delete _generatedGraph;
425 int YACSEvalYFXRunOnlyPattern::assignNbOfBranches()
427 checkAlreadyComputedResources();
429 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : the generated graph has not been created !");
430 std::list<YACS::ENGINE::Node *> nodes(_generatedGraph->getChildren());
431 YACS::ENGINE::ForEachLoop *zeMainNode(0);
432 for(std::list<YACS::ENGINE::Node *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
434 YACS::ENGINE::ForEachLoop *isZeMainNode(dynamic_cast<YACS::ENGINE::ForEachLoop *>(*it));
438 zeMainNode=isZeMainNode;
440 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 1 !");
444 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 2 !");
445 unsigned int nbProcsDeclared(getResourcesInternal()->getNumberOfProcsDeclared());
446 nbProcsDeclared=std::max(nbProcsDeclared,4u);
448 if(getParallelizeStatus())
450 nbOfBranch=(nbProcsDeclared/getResourcesInternal()->getMaxLevelOfParallelism());
451 nbOfBranch=std::max(nbOfBranch,1);
453 YACS::ENGINE::InputPort *zeInputToSet(zeMainNode->edGetNbOfBranchesPort());
454 YACS::ENGINE::AnyInputPort *zeInputToSetC(dynamic_cast<YACS::ENGINE::AnyInputPort *>(zeInputToSet));
456 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 3 !");
457 YACS::ENGINE::Any *a(YACS::ENGINE::AtomAny::New(nbOfBranch));
458 zeInputToSetC->put(a);
459 zeInputToSetC->exSaveInit();
464 void YACSEvalYFXRunOnlyPattern::assignRandomVarsInputs()
466 std::size_t sz(std::numeric_limits<std::size_t>::max());
467 for(std::vector< YACSEvalInputPort >::const_iterator it=_inputs.begin();it!=_inputs.end();it++)
468 if((*it).isRandomVar())
470 std::size_t locSize((*it).initializeUndergroundWithSeq());
471 if(sz==std::numeric_limits<std::size_t>::max())
475 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignRandomVarsInputs : length of sequences in random vars must be the same !");
479 bool YACSEvalYFXRunOnlyPattern::isLocked() const
481 return _generatedGraph!=0;
484 YACSEvalListOfResources *YACSEvalYFXRunOnlyPattern::giveResources()
487 if(!isAlreadyComputedResources())
489 YACS::ENGINE::DeploymentTree dt(_runNode->getDeploymentTree());
490 _runNode->removeRecursivelyRedundantCL();
491 YACSEvalListOfResources *res(new YACSEvalListOfResources(_runNode->getMaxLevelOfParallelism(),getCatalogInAppli(),dt));
494 return getResourcesInternal();
497 YACS::ENGINE::Proc *YACSEvalYFXRunOnlyPattern::getUndergroundGeneratedGraph() const
499 return _generatedGraph;
502 std::string YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure() const
504 std::string st(getStatusOfRunStr());//test if a run has occurred.
506 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure : The execution of scheme has been carried out to the end without any problem !");
507 // All the problem can only comes from foreach -> scan it
508 YACS::ENGINE::ForEachLoop *fe(findTopForEach());
509 YACS::ENGINE::NodeStateNameMap nsm;
510 unsigned nbB(fe->getNumberOfBranchesCreatedDyn());
511 std::ostringstream oss;
512 for(unsigned j=0;j<nbB;j++)
514 YACS::ENGINE::Node *nn(fe->getChildByNameExec(FIRST_FE_SUBNODE_NAME,j));
515 YACS::ENGINE::Bloc *nnc(dynamic_cast<YACS::ENGINE::Bloc *>(nn));
517 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getErrorDetailsInCaseOfFailure : internal error 1 ! The direct son of main foreach is expected to be a Bloc !");
518 if(nnc->getState()==YACS::DONE)
520 std::list< YACS::ENGINE::ElementaryNode *> fec(nnc->getRecursiveConstituents());
521 for(std::list< YACS::ENGINE::ElementaryNode *>::reverse_iterator it=fec.rbegin();it!=fec.rend();it++)
523 YACS::StatesForNode st0((*it)->getState());
526 oss << "NODE = " << nnc->getChildName(*it) << std::endl;
527 oss << "STATUS = " << nsm[st0] << std::endl;
528 oss << "BRANCH ID = " << j << std::endl;
529 std::list<YACS::ENGINE::InputPort *> inps((*it)->getSetOfInputPort());
530 for(std::list<YACS::ENGINE::InputPort *>::const_iterator it=inps.begin();it!=inps.end();it++)
532 std::string d((*it)->getHumanRepr());
534 d=d.substr(0,MAX_LGTH_OF_INP_DUMP);
535 oss << "INPUT \"" << (*it)->getName() << "\" = " << d << std::endl;
537 oss << "DETAILS = " << std::endl;
538 oss << (*it)->getErrorDetails();
545 std::string YACSEvalYFXRunOnlyPattern::getStatusOfRunStr() const
547 YACS::StatesForNode st(_generatedGraph->getState());
553 case YACS::TOACTIVATE:
554 case YACS::ACTIVATED:
555 case YACS::SUSPENDED:
558 case YACS::DESACTIVATED:
560 std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getStatusOfRunStr : Unexpected state \"" << YACS::ENGINE::Node::getStateName(st) << "\" ! Did you invoke run ?";
561 throw YACS::Exception(oss.str());
563 case YACS::LOADFAILED:
564 case YACS::EXECFAILED:
566 case YACS::INTERNALERR:
567 return std::string(ST_ERROR);
569 return std::string(ST_FAILED);
571 return std::string(ST_OK);
574 std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getStatusOfRunStr : unrecognized and managed state \"" << YACS::ENGINE::Node::getStateName(st) << "\" !";
575 throw YACS::Exception(oss.str());
580 std::vector<YACSEvalSeqAny *> YACSEvalYFXRunOnlyPattern::getResults() const
582 if(_generatedGraph->getState()!=YACS::DONE)
583 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResults : the execution did not finished correctly ! getResults should not be called !");
584 std::vector<YACSEvalSeqAny *> ret(_outputsOfInterest.size());
585 YACS::ENGINE::Node *node(_generatedGraph->getChildByName(GATHER_NODE_NAME));
586 YACS::ENGINE::PythonNode *nodeC(dynamic_cast<YACS::ENGINE::PythonNode *>(node));
588 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResults : internal error !");
590 for(std::vector< YACSEvalOutputPort * >::const_iterator it=_outputsOfInterest.begin();it!=_outputsOfInterest.end();it++,ii++)
592 YACS::ENGINE::InPort *input(nodeC->getInPort((*it)->getName()));
593 YACS::ENGINE::InputPyPort *inputC(dynamic_cast<YACS::ENGINE::InputPyPort *>(input));
596 std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getResults : internal error for input \"" << (*it)->getName() << "\"";
597 throw YACS::Exception(oss.str());
599 ret[ii]=BuildValueInPort(inputC);
605 * This method works if run succeeded (true return) and also if graph has failed. Graph failed means soft error of evaluation due to error in evaluation (example 1/0 or a normal throw from one node)
606 * If a more serious error occured (SIGSEGV of a server or internal error in YACS engine, cluster error, loose of connection...) this method will throw an exception to warn the caller that the results may be
608 std::vector<YACSEvalSeqAny *> YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure(std::vector<unsigned int>& passedIds) const
610 YACS::StatesForNode st(_generatedGraph->getState());
614 std::vector<YACSEvalSeqAny *> ret(getResults());
618 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure : internal error ! The returned vector has a null pointer at pos #0 !");
619 std::size_t sz(ret[0]->size());
620 passedIds.resize(sz);
621 for(std::size_t i=0;i<sz;i++)
626 getStatusOfRunStr();// To check that the status is recognized.
627 std::list<YACS::ENGINE::Node *> lns(_generatedGraph->edGetDirectDescendants());
628 YACS::ENGINE::ForEachLoop *fe(findTopForEach());
630 YACS::ENGINE::Executor exe;
631 std::vector<YACS::ENGINE::SequenceAny *> outputs;
632 std::vector<std::string> nameOfOutputs;
633 passedIds=fe->getPassedResults(&exe,outputs,nameOfOutputs);//<- the key invokation is here.
634 std::size_t sz(passedIds.size()),ii(0);
635 std::vector<YACSEvalSeqAny *> ret(_outputsOfInterest.size());
636 for(std::vector<YACSEvalOutputPort *>::const_iterator it=_outputsOfInterest.begin();it!=_outputsOfInterest.end();it++,ii++)
638 YACS::ENGINE::OutputPort *p((*it)->getUndergroundPtr());
639 std::string st(_runNode->getOutPortName(p));
640 std::ostringstream oss; oss << FIRST_FE_SUBNODE_NAME << '.' << _runNode->getName() << '.' << st;
642 YACS::ENGINE::ForEachLoop::InterceptorizeNameOfPort(st);
643 std::vector<std::string>::iterator it(std::find(nameOfOutputs.begin(),nameOfOutputs.end(),st));
644 if(it==nameOfOutputs.end())
646 std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure : internal error 3 ! Unable to locate interceptor with name " << st << " ! Possibilities are : ";
647 std::copy(nameOfOutputs.begin(),nameOfOutputs.end(),std::ostream_iterator<std::string>(oss," "));
649 throw YACS::Exception(oss.str());
651 std::size_t pos(std::distance(nameOfOutputs.begin(),it));
652 ret[ii]=BuildValueFromEngineFrmt(outputs[pos]);
657 void YACSEvalYFXRunOnlyPattern::emitStart() const
659 YACSEvalObserver *obs(getObserver());
662 obs->notifyNumberOfSamplesToEval(getBoss(),_FEInGeneratedGraph->getNbOfElementsToBeProcessed());
665 bool YACSEvalYFXRunOnlyPattern::go(bool stopASAP) const
668 if(getResourcesInternal()->isInteractive())
670 YACS::ENGINE::Executor exe;
671 exe.setKeepGoingProperty(!stopASAP);
673 MyAutoThreadSaver locker;
674 exe.RunW(getUndergroundGeneratedGraph());
676 return getUndergroundGeneratedGraph()->getState()==YACS::DONE;
680 char EFXGenFileName[]="EFXGenFileName";
681 char EFXGenContent[]="import getpass,datetime,os\nn=datetime.datetime.now()\nreturn os.path.join(os.path.sep,\"tmp\",\"EvalYFX_%s_%s_%s.xml\"%(getpass.getuser(),n.strftime(\"%d%b%y\"),n.strftime(\"%H%M%S\")))";
683 YACS::ENGINE::AutoPyRef func(YACS::ENGINE::evalPy(EFXGenFileName,EFXGenContent));
684 YACS::ENGINE::AutoPyRef val(YACS::ENGINE::evalFuncPyWithNoParams(func));
685 std::string fn(PyString_AsString(val));
686 getUndergroundGeneratedGraph()->saveSchema(fn);
691 bool YACSEvalYFXRunOnlyPattern::IsMatching(YACS::ENGINE::Proc *scheme, YACS::ENGINE::ComposedNode *& runNode)
693 std::list<YACS::ENGINE::Node *> nodes(scheme->getChildren());
696 bool areAllElementary(true);
697 for(std::list<YACS::ENGINE::Node *>::const_iterator it=nodes.begin();it!=nodes.end() && areAllElementary;it++)
698 if(!dynamic_cast<YACS::ENGINE::ElementaryNode *>(*it))
699 areAllElementary=false;
703 CheckNodeIsOK(scheme);
709 YACS::ENGINE::ComposedNode *candidate(dynamic_cast<YACS::ENGINE::ComposedNode *>(nodes.front()));
712 CheckNodeIsOK(candidate);
716 void YACSEvalYFXRunOnlyPattern::buildInputPorts()
719 std::list< YACS::ENGINE::InputPort *> allInputPorts(_runNode->getSetOfInputPort());
720 std::vector<std::string> allNames;
721 for(std::list< YACS::ENGINE::InputPort *>::const_iterator it=allInputPorts.begin();it!=allInputPorts.end();it++)
723 YACS::ENGINE::InputPort *elt(*it);
725 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildInputPorts : presence of null input !");
726 std::set<YACS::ENGINE::OutPort *> bls(elt->edSetOutPort());
729 if(YACSEvalPort::IsInputPortPublishable(elt))
731 std::string inpName(elt->getName());
733 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildInputPorts : an input has empty name ! Should not !");
734 _inputs.push_back(YACSEvalInputPort(elt));
735 if(std::find(allNames.begin(),allNames.end(),inpName)!=allNames.end())
737 std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildInputPorts : input name \"" << inpName << "\" appears more than once !";
738 throw YACS::Exception(oss.str());
740 allNames.push_back(inpName);
746 void YACSEvalYFXRunOnlyPattern::buildOutputPorts()
749 std::list< YACS::ENGINE::OutputPort *> allOutputPorts(_runNode->getSetOfOutputPort());
750 std::vector<std::string> allNames;
751 for(std::list< YACS::ENGINE::OutputPort *>::const_iterator it=allOutputPorts.begin();it!=allOutputPorts.end();it++)
753 YACS::ENGINE::OutputPort *elt(*it);
754 if(YACSEvalPort::IsOutputPortPublishable(elt))
757 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : presence of null output !");
758 std::string outpName(elt->getName());
760 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : an output has empty name ! Should not !");
761 if(std::find(allNames.begin(),allNames.end(),outpName)!=allNames.end())
763 std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildOutputPorts : output name \"" << outpName << "\" appears more than once !";
764 throw YACS::Exception(oss.str());
766 _outputs.push_back(YACSEvalOutputPort(*it));
771 YACS::ENGINE::ForEachLoop *YACSEvalYFXRunOnlyPattern::findTopForEach() const
773 std::list<YACS::ENGINE::Node *> lns(_generatedGraph->edGetDirectDescendants());
774 YACS::ENGINE::ForEachLoop *fe(0);
775 for(std::list<YACS::ENGINE::Node *>::const_iterator it=lns.begin();it!=lns.end();it++)
777 fe=dynamic_cast<YACS::ENGINE::ForEachLoop *>(*it);
782 throw YACS::Exception("YACSEvalYFXRunOnlyPattern::findTopForEach : internal error 2 ! ForEach is not accessible !");