From 3699a56026f27b2de384de5944b20e2d27fdda44 Mon Sep 17 00:00:00 2001 From: Ovidiu Mircescu Date: Mon, 18 Apr 2016 11:26:31 +0200 Subject: [PATCH] Work in progress save and load state. --- src/engine/Bloc.cxx | 2 +- src/engine/Bloc.hxx | 2 +- src/engine/ComposedNode.cxx | 14 ++- src/engine/ComposedNode.hxx | 6 +- src/engine/DynParaLoop.cxx | 2 +- src/engine/DynParaLoop.hxx | 2 +- src/engine/Executor.cxx | 15 +-- src/engine/ForEachLoop.cxx | 48 ++++++++- src/engine/ForEachLoop.hxx | 9 +- src/engine/OptimizerLoop.cxx | 4 +- src/engine/OptimizerLoop.hxx | 2 +- src/engine/Scheduler.hxx | 3 +- src/engine/VisitorSaveState.cxx | 2 +- src/runtime/CMakeLists.txt | 2 + src/runtime/VisitorSalomeSaveState.cxx | 115 ++++++++++++++++++++ src/runtime/VisitorSalomeSaveState.hxx | 51 +++++++++ src/runtime_swig/CMakeLists.txt | 1 + src/runtime_swig/SALOMERuntime.i | 16 +++ src/yacsloader/LoadState.cxx | 144 +++++++++++++++++++++++++ src/yacsloader/LoadState.hxx | 27 +++++ src/yacsloader/driver.cxx | 8 +- 21 files changed, 438 insertions(+), 37 deletions(-) create mode 100644 src/runtime/VisitorSalomeSaveState.cxx create mode 100644 src/runtime/VisitorSalomeSaveState.hxx diff --git a/src/engine/Bloc.cxx b/src/engine/Bloc.cxx index c91c76172..4df68b4a6 100644 --- a/src/engine/Bloc.cxx +++ b/src/engine/Bloc.cxx @@ -403,7 +403,7 @@ YACS::Event Bloc::updateStateOnFinishedEventFrom(Node *node) * \param node : node that has emitted the event * \return the event to notify to bloc's father */ -YACS::Event Bloc::updateStateOnFailedEventFrom(Node *node, const Executor *execInst) +YACS::Event Bloc::updateStateOnFailedEventFrom(Node *node) { node->exForwardFailed(); if(areAllSubNodesFinished()) diff --git a/src/engine/Bloc.hxx b/src/engine/Bloc.hxx index 2e81f0890..190b36054 100644 --- a/src/engine/Bloc.hxx +++ b/src/engine/Bloc.hxx @@ -69,7 +69,7 @@ namespace YACS void checkNoCyclePassingThrough(Node *node) throw(Exception); std::vector< std::pair > getSetOfInternalCFLinks() const; YACS::Event updateStateOnFinishedEventFrom(Node *node); - YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst); + YACS::Event updateStateOnFailedEventFrom(Node *node); void initComputation() const; void performCFComputationsOnlyOneLevel(LinkInfo& info) const; void performCFComputations(LinkInfo& info) const; diff --git a/src/engine/ComposedNode.cxx b/src/engine/ComposedNode.cxx index 09134bdb0..71576cd2b 100644 --- a/src/engine/ComposedNode.cxx +++ b/src/engine/ComposedNode.cxx @@ -241,8 +241,7 @@ std::vector ComposedNode::getNextTasks(bool& isMore) * Calls ComposedNode::updateStateFrom to update state from task to root node */ void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event - YACS::Event event, //* I : event emitted - const Executor *execInst + YACS::Event event //* I : event emitted ) { DEBTRACE("ComposedNode::notifyFrom " << event); @@ -252,12 +251,12 @@ void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event ComposedNode *curLevelNode=taskTyped->_father; if(!curLevelNode)//Specific case of loop when 0 turn is specified without any enclosing bloc. return ; - curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent,execInst); + curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent); while(curEvent!=YACS::NOEVENT && curLevelNode!=this) { lminus1LevelNode=curLevelNode; curLevelNode=curLevelNode->_father; - curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent,execInst); + curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent); } } @@ -1376,8 +1375,7 @@ OutputDataStreamPort *ComposedNode::getOutputDataStreamPort(const std::string& n * Called by ComposedNode::notifyFrom */ YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event - YACS::Event event, //* I : event emitted - const Executor *execInst + YACS::Event event //* I : event emitted ) { DEBTRACE("updateStateFrom: " << node->getName() << " " << event); @@ -1392,7 +1390,7 @@ YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitti return updateStateOnFinishedEventFrom(node); break; case YACS::ABORT: - return updateStateOnFailedEventFrom(node,execInst); + return updateStateOnFailedEventFrom(node); break; default: return YACS::NOEVENT;//TODO unexpected type of event @@ -1434,7 +1432,7 @@ YACS::Event ComposedNode::updateStateOnStartEventFrom(Node *node) } //! Method used to notify the node that a child node has failed -YACS::Event ComposedNode::updateStateOnFailedEventFrom(Node *node, const Executor *execInst) +YACS::Event ComposedNode::updateStateOnFailedEventFrom(Node *node) { setState(YACS::FAILED); return YACS::ABORT; diff --git a/src/engine/ComposedNode.hxx b/src/engine/ComposedNode.hxx index b3d8e2e6c..a4a06626e 100644 --- a/src/engine/ComposedNode.hxx +++ b/src/engine/ComposedNode.hxx @@ -64,7 +64,7 @@ namespace YACS DeploymentTree checkDeploymentTree(bool deep) const throw(Exception); std::vector getNextTasks(bool& isMore); virtual bool isPlacementPredictableB4Run() const = 0; - void notifyFrom(const Task *sender, YACS::Event event, const Executor *execInst); + void notifyFrom(const Task *sender, YACS::Event event); bool edAddLink(OutPort *start, InPort *end) throw(Exception); virtual bool edAddDFLink(OutPort *start, InPort *end) throw(Exception); //Node* DISOWNnode is a SWIG notation to indicate that the ownership of the node is transfered to C++ @@ -136,10 +136,10 @@ namespace YACS static bool splitNamesBySep(const std::string& globalName, const char separator[], std::string& firstPart, std::string& lastPart, bool priority) throw(Exception); virtual Node *getChildByShortName(const std::string& name) const throw(Exception) = 0; - YACS::Event updateStateFrom(Node *node, YACS::Event event, const Executor *execInst);//update the state of this. Precondition : node->_father == this + YACS::Event updateStateFrom(Node *node, YACS::Event event);//update the state of this. Precondition : node->_father == this virtual YACS::Event updateStateOnStartEventFrom(Node *node);//transition 3 doc P.R virtual YACS::Event updateStateOnFinishedEventFrom(Node *node) = 0;//transition 9 doc P.R. - virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);//transition 9 doc P.R. + virtual YACS::Event updateStateOnFailedEventFrom(Node *node);//transition 9 doc P.R. virtual void checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, InPort *end, const std::list& pointsOfViewEnd) throw(Exception); virtual void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list& pointsOfView); diff --git a/src/engine/DynParaLoop.cxx b/src/engine/DynParaLoop.cxx index db101aeba..97ed761fe 100644 --- a/src/engine/DynParaLoop.cxx +++ b/src/engine/DynParaLoop.cxx @@ -696,7 +696,7 @@ void DynParaLoop::forwardExecStateToOriginalBody(Node *execNode) * \param node : the child node that has failed * \return the state change */ -YACS::Event DynParaLoop::updateStateOnFailedEventFrom(Node *node, const Executor *execInst) +YACS::Event DynParaLoop::updateStateOnFailedEventFrom(Node *node) { DEBTRACE("DynParaLoop::updateStateOnFailedEventFrom " << node->getName()); setState(YACS::FAILED); diff --git a/src/engine/DynParaLoop.hxx b/src/engine/DynParaLoop.hxx index 86c9e8399..513b0153a 100644 --- a/src/engine/DynParaLoop.hxx +++ b/src/engine/DynParaLoop.hxx @@ -124,7 +124,7 @@ namespace YACS TypeOfNode getIdentityOfNotifyerNode(const Node *node, unsigned& id); InputPort *getDynInputPortByAbsName(int branchNb, const std::string& name, bool initNodeAdmitted); virtual void forwardExecStateToOriginalBody(Node *execNode); - virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst); + virtual YACS::Event updateStateOnFailedEventFrom(Node *node); std::vector cloneAndPlaceNodesCoherently(const std::vector & origNodes); Node * checkConsistencyAndSetNode(Node* &nodeToReplace, Node* DISOWNnode); Node * removeNode(Node* &nodeToRemove); diff --git a/src/engine/Executor.cxx b/src/engine/Executor.cxx index 1130df735..213b0bacf 100644 --- a/src/engine/Executor.cxx +++ b/src/engine/Executor.cxx @@ -651,6 +651,7 @@ bool Executor::saveState(const std::string& xmlFile) DEBTRACE("Executor::saveState() in " << xmlFile); bool result = false; try { + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); YACS::ENGINE::VisitorSaveState vst(_root); vst.openFileDump(xmlFile.c_str()); _root->accept(&vst); @@ -828,7 +829,7 @@ void Executor::loadTask(Task *task, const Executor *execInst) traceExec(task, "state:TOLOAD", ComputePlacement(task)); {//Critical section YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); - _mainSched->notifyFrom(task,YACS::START,execInst); + _mainSched->notifyFrom(task,YACS::START); }//End of critical section try { @@ -843,7 +844,7 @@ void Executor::loadTask(Task *task, const Executor *execInst) {//Critical section YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); task->aborted(); - _mainSched->notifyFrom(task,YACS::ABORT,execInst); + _mainSched->notifyFrom(task,YACS::ABORT); traceExec(task, "state:"+Node::getStateName(task->getState()), ComputePlacement(task)); }//End of critical section } @@ -853,7 +854,7 @@ void Executor::loadTask(Task *task, const Executor *execInst) {//Critical section YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); task->aborted(); - _mainSched->notifyFrom(task,YACS::ABORT,execInst); + _mainSched->notifyFrom(task,YACS::ABORT); traceExec(task, "state:"+Node::getStateName(task->getState()), ComputePlacement(task)); }//End of critical section } @@ -926,7 +927,7 @@ void Executor::launchTasks(const std::vector& tasks) {//Critical section YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); (*iter)->aborted(); - _mainSched->notifyFrom(*iter,YACS::ABORT,this); + _mainSched->notifyFrom(*iter,YACS::ABORT); }//End of critical section } catch(...) @@ -945,7 +946,7 @@ void Executor::launchTasks(const std::vector& tasks) {//Critical section YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); (*iter)->aborted(); - _mainSched->notifyFrom(*iter,YACS::ABORT,this); + _mainSched->notifyFrom(*iter,YACS::ABORT); }//End of critical section } if((*iter)->getState() == YACS::ERROR) @@ -971,7 +972,7 @@ void Executor::launchTasks(const std::vector& tasks) {//Critical section YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); t->aborted(); - _mainSched->notifyFrom(t,YACS::ABORT,this); + _mainSched->notifyFrom(t,YACS::ABORT); }//End of critical section traceExec(t, "state:"+Node::getStateName(t->getState()),ComputePlacement(*iter)); } @@ -1224,7 +1225,7 @@ void *Executor::functionForTaskExecution(void *arg) task->aborted(); } execInst->traceExec(task, "state:"+Node::getStateName(task->getState()),placement); - sched->notifyFrom(task,ev,execInst); + sched->notifyFrom(task,ev); } catch(Exception& ex) { diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx index 303cc1492..4c767b5b7 100644 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@ -318,6 +318,14 @@ ForEachLoopPassedData::ForEachLoopPassedData(const std::vector& pa } } +ForEachLoopPassedData::ForEachLoopPassedData(const ForEachLoopPassedData& copy) +: _passedIds(copy._passedIds), + _passedOutputs(copy._passedOutputs), + _nameOfOutputs(copy._nameOfOutputs), + _flagsIds(copy._flagsIds) +{ +} + ForEachLoopPassedData::~ForEachLoopPassedData() { for(std::vector::iterator it=_passedOutputs.begin();it!=_passedOutputs.end();it++) @@ -866,12 +874,14 @@ YACS::Event ForEachLoop::updateStateForFinalizeNodeOnFinishedEventFrom(Node *nod return YACS::NOEVENT; } -YACS::Event ForEachLoop::updateStateOnFailedEventFrom(Node *node, const Executor *execInst) +YACS::Event ForEachLoop::updateStateOnFailedEventFrom(Node *node) { unsigned int id; DynParaLoop::TypeOfNode ton(getIdentityOfNotifyerNode(node,id)); - if(ton!=WORK_NODE || !execInst->getKeepGoingProperty()) - return DynParaLoop::updateStateOnFailedEventFrom(node,execInst); + // TODO: deal with keepgoing + // if(ton!=WORK_NODE || !execInst->getKeepGoingProperty()) + if(ton!=WORK_NODE ) + return DynParaLoop::updateStateOnFailedEventFrom(node); else { _failedCounter++; @@ -1163,7 +1173,9 @@ std::vector ForEachLoop::getPassedResults(Executor *execut, std::v return std::vector(); if(_execOutGoingPorts.empty()) return std::vector(); - std::size_t sz(_execVals.size()); outputs.resize(sz); nameOfOutputs.resize(sz); + std::size_t sz(_execVals.size()); + outputs.resize(sz); + nameOfOutputs.resize(sz); const std::vector& ports(_execOutGoingPorts[0]); for(std::size_t i=0;i& passedIds _passedData=new ForEachLoopPassedData(passedIds,passedOutputs,nameOfOutputs); } +/*! + * This method is used to obtain the values already processed by the ForEachLoop. + * A new ForEachLoopPassedData object is returned. You have to delete it. + */ +ForEachLoopPassedData* ForEachLoop::getProcessedData()const +{ + std::vector outputs; + std::vector nameOfOutputs; + if(_execVals.empty() || _execOutGoingPorts.empty()) + return new ForEachLoopPassedData(std::vector(), outputs, nameOfOutputs); + std::size_t sz(_execVals.size()); + outputs.resize(sz); + nameOfOutputs.resize(sz); + const std::vector& ports(_execOutGoingPorts[0]); + for(std::size_t i=0;iremoveUnsetItemsFromThis(); + nameOfOutputs[i]=ports[i]->getName(); + } + return new ForEachLoopPassedData(_execVals[0]->getSetItems(), outputs, nameOfOutputs); +} + +void ForEachLoop::setProcessedData(ForEachLoopPassedData* processedData) +{ + if(_passedData) + delete _passedData; + _passedData = processedData; +} diff --git a/src/engine/ForEachLoop.hxx b/src/engine/ForEachLoop.hxx index efb9888fb..875b900fa 100644 --- a/src/engine/ForEachLoop.hxx +++ b/src/engine/ForEachLoop.hxx @@ -127,6 +127,7 @@ namespace YACS { public: ForEachLoopPassedData(const std::vector& passedIds, const std::vector& passedOutputs, const std::vector& nameOfOutputs); + ForEachLoopPassedData(const ForEachLoopPassedData& copy); ~ForEachLoopPassedData(); void init(); void checkCompatibilyWithNb(int nbOfElts) const; @@ -136,6 +137,10 @@ namespace YACS int toAbsIdNot(int localId) const; int getNumberOfElementsToDo() const; void assignAlreadyDone(const std::vector& execVals) const; + const std::vector& getIds()const {return _passedIds;} + const std::vector& getOutputs()const {return _passedOutputs;} + const std::vector& getOutputNames()const {return _nameOfOutputs;} + //const std::vector& getFlags()const {return _flagsIds;} private: std::vector _passedIds; std::vector _passedOutputs; @@ -196,6 +201,8 @@ namespace YACS int getCurrentIndex() const { return _currentIndex; } int getNbOfElementsToBeProcessed() const; #ifndef SWIG + ForEachLoopPassedData* getProcessedData()const; + void setProcessedData(ForEachLoopPassedData* processedData); std::vector getPassedResults(Executor *execut, std::vector& outputs, std::vector& nameOfOutputs) const; void assignPassedResults(const std::vector& passedIds, const std::vector& passedOutputs, const std::vector& nameOfOutputs); #endif @@ -207,7 +214,7 @@ namespace YACS YACS::Event updateStateForInitNodeOnFinishedEventFrom(Node *node, unsigned int id); YACS::Event updateStateForWorkNodeOnFinishedEventFrom(Node *node, unsigned int id, bool isNormalFinish); YACS::Event updateStateForFinalizeNodeOnFinishedEventFrom(Node *node, unsigned int id); - YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst); + YACS::Event updateStateOnFailedEventFrom(Node *node); void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView); void getDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView) throw(Exception); void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list& pointsOfView) throw(Exception); diff --git a/src/engine/OptimizerLoop.cxx b/src/engine/OptimizerLoop.cxx index 83d9dce36..ddb2ac508 100644 --- a/src/engine/OptimizerLoop.cxx +++ b/src/engine/OptimizerLoop.cxx @@ -456,7 +456,7 @@ YACS::Event OptimizerLoop::finalize() * \param node : the child node that has failed * \return the state change */ -YACS::Event OptimizerLoop::updateStateOnFailedEventFrom(Node *node, const Executor *execInst) +YACS::Event OptimizerLoop::updateStateOnFailedEventFrom(Node *node) { DEBTRACE("OptimizerLoop::updateStateOnFailedEventFrom " << node->getName()); _alg->setError(string("Error during the execution of YACS node ") + node->getName() + @@ -464,7 +464,7 @@ YACS::Event OptimizerLoop::updateStateOnFailedEventFrom(Node *node, const Execut _alg->finishProxy(); _myPool.destroyAll(); DEBTRACE("OptimizerLoop::updateStateOnFailedEventFrom: returned from error notification."); - return DynParaLoop::updateStateOnFailedEventFrom(node,execInst); + return DynParaLoop::updateStateOnFailedEventFrom(node); } void OptimizerLoop::checkNoCyclePassingThrough(Node *node) throw(YACS::Exception) diff --git a/src/engine/OptimizerLoop.hxx b/src/engine/OptimizerLoop.hxx index b489ee576..2a098438a 100644 --- a/src/engine/OptimizerLoop.hxx +++ b/src/engine/OptimizerLoop.hxx @@ -107,7 +107,7 @@ namespace YACS YACS::Event finalize(); protected: - virtual YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst); + virtual YACS::Event updateStateOnFailedEventFrom(Node *node); void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list& pointsOfView); void buildDelegateOf(std::pair& port, InPort *finalTarget, const std::list& pointsOfView); void checkControlDependancy(OutPort *start, InPort *end, bool cross, diff --git a/src/engine/Scheduler.hxx b/src/engine/Scheduler.hxx index 1b39f8850..a326f67b6 100644 --- a/src/engine/Scheduler.hxx +++ b/src/engine/Scheduler.hxx @@ -31,7 +31,6 @@ namespace YACS namespace ENGINE { class Task; - class Executor; class Scheduler { @@ -43,7 +42,7 @@ namespace YACS virtual std::string getTaskName(Task *task) const = 0; virtual std::vector getNextTasks(bool& isMore) = 0; virtual void selectRunnableTasks(std::vector& tasks) = 0; - virtual void notifyFrom(const Task *sender, YACS::Event event, const Executor *execInst) = 0; + virtual void notifyFrom(const Task *sender, YACS::Event event) = 0; //Placement methods virtual DeploymentTree getDeploymentTree() const = 0; virtual bool isPlacementPredictableB4Run() const = 0; diff --git a/src/engine/VisitorSaveState.cxx b/src/engine/VisitorSaveState.cxx index 8c27bbca6..47178e2db 100644 --- a/src/engine/VisitorSaveState.cxx +++ b/src/engine/VisitorSaveState.cxx @@ -325,4 +325,4 @@ void VisitorSaveState::visitStudyInNode(DataNode *node) void VisitorSaveState::visitStudyOutNode(DataNode *node) { visitElementaryNode(node); -} +} \ No newline at end of file diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index de103b4e6..a61b05b3f 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -144,6 +144,7 @@ SET(YACSRuntimeSALOME_HEADERS SalomeOptimizerLoop.hxx DistributedPythonNode.hxx PyOptimizerAlg.hxx + VisitorSalomeSaveState.hxx ) # --- sources --- @@ -210,6 +211,7 @@ SET(YACSRuntimeSALOME_SOURCES PyStdout.cxx SalomeOptimizerLoop.cxx PyOptimizerAlg.cxx + VisitorSalomeSaveState.cxx ) # --- rules --- diff --git a/src/runtime/VisitorSalomeSaveState.cxx b/src/runtime/VisitorSalomeSaveState.cxx new file mode 100644 index 000000000..0c95368aa --- /dev/null +++ b/src/runtime/VisitorSalomeSaveState.cxx @@ -0,0 +1,115 @@ +// Copyright (C) 2006-2015 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "VisitorSalomeSaveState.hxx" +#include "TypeConversions.hxx" +#include "ForEachLoop.hxx" +#include "Proc.hxx" +#include "Executor.hxx" +#include "AutoLocker.hxx" + +#include "YacsTrace.hxx" + +using namespace YACS::ENGINE; + +VisitorSalomeSaveState::VisitorSalomeSaveState(ComposedNode *root) +:VisitorSaveState(root) +{ +} + +VisitorSalomeSaveState::~VisitorSalomeSaveState() +{ +} + +void VisitorSalomeSaveState::visitForEachLoop(ForEachLoop *node) +{ + node->ComposedNode::accept(this); + if (!_out) throw Exception("No file open for dump state"); + std::string name = _root->getName(); + if (static_cast(node) != _root) name = _root->getChildName(node); + DEBTRACE("VisitorSaveState::visitForEachLoop ------ " << name); + _out << " " << std::endl; + _out << " " << name << "" << std::endl; + _out << " " << _nodeStateName[node->getState()] << "" << std::endl; +// VisitorSaveState::visitForEachLoop(node); + StatesForNode state = node->getState(); + if(YACS::LOADED == state or + YACS::ACTIVATED == state or + YACS::SUSPENDED == state or + YACS::EXECFAILED == state or + YACS::PAUSE == state or + YACS::TORECONNECT == state or + YACS::INTERNALERR == state or + YACS::FAILED == state or + YACS::ERROR == state) + { + ForEachLoopPassedData* processedData = node->getProcessedData(); + if(processedData) + { + const std::vector& processedIndexes = processedData->getIds(); + std::vector::const_iterator it_outputs; + std::vector::const_iterator it_names; + + for(it_outputs = processedData->getOutputs().begin(), it_names = processedData->getOutputNames().begin(); + it_names != processedData->getOutputNames().end(); + it_outputs++, it_names++) + { + _out << " " << std::endl; + _out << " " << (*it_names) << "" << std::endl; + for(unsigned int i = 0; i < (*it_outputs)->size(); i++) + { + AnyPtr value = (*(*it_outputs))[i]; + _out << " " << processedIndexes[i]<< ""; + if(value) + _out << convertNeutralXml(value->getType(), value); + else + _out << "None"; + _out << " " << std::endl; + } + _out << " " << std::endl; + } + + delete processedData; + processedData = NULL; + } + } + _out << " " << std::endl; +} + + +SchemaSaveState::SchemaSaveState(Proc* proc, Executor* exec) +: _p(proc), + _exec(exec) +{ + YASSERT(_p); + YASSERT(_exec); +} + +SchemaSaveState::~SchemaSaveState() +{ +} + +void SchemaSaveState::save(std::string xmlSchemaFile) +{ + YACS::BASES::AutoLocker alck(&(_exec->getTheMutexForSchedulerUpdate())); + VisitorSalomeSaveState vss(_p); + vss.openFileDump(xmlSchemaFile); + _p->accept(&vss); + vss.closeFileDump(); +} diff --git a/src/runtime/VisitorSalomeSaveState.hxx b/src/runtime/VisitorSalomeSaveState.hxx new file mode 100644 index 000000000..a979f39a7 --- /dev/null +++ b/src/runtime/VisitorSalomeSaveState.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2006-2015 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef VISITORSALOMESAVESTATE_HXX +#define VISITORSALOMESAVESTATE_HXX + +#include "VisitorSaveState.hxx" +#include "YACSRuntimeSALOMEExport.hxx" + +namespace YACS +{ + namespace ENGINE + { + class Executor; + class YACSRUNTIMESALOME_EXPORT VisitorSalomeSaveState : public VisitorSaveState + { + public: + VisitorSalomeSaveState(ComposedNode *root); + virtual ~VisitorSalomeSaveState(); + virtual void visitForEachLoop(ForEachLoop *node); + }; + + class YACSLIBENGINE_EXPORT SchemaSaveState + { + public: + SchemaSaveState(Proc* proc, Executor* exec); + virtual ~SchemaSaveState(); + virtual void save(std::string xmlSchemaFile); + private: + Proc* _p; + Executor* _exec; + }; + } +} +#endif // VISITORSALOMESAVESTATE_HXX diff --git a/src/runtime_swig/CMakeLists.txt b/src/runtime_swig/CMakeLists.txt index 4ee93c076..879620de2 100644 --- a/src/runtime_swig/CMakeLists.txt +++ b/src/runtime_swig/CMakeLists.txt @@ -92,6 +92,7 @@ SET(SWIGINCLUDES ${PROJECT_SOURCE_DIR}/src/runtime/CORBAPorts.hxx ${PROJECT_SOURCE_DIR}/src/runtime/TypeConversions.hxx ${PROJECT_SOURCE_DIR}/src/runtime/SalomeOptimizerLoop.hxx + ${PROJECT_SOURCE_DIR}/src/runtime/VisitorSalomeSaveState.hxx ) SWIG_ADD_MODULE(SALOMERuntime python SALOMERuntime.i) ADD_DEPENDENCIES(_SALOMERuntime diff --git a/src/runtime_swig/SALOMERuntime.i b/src/runtime_swig/SALOMERuntime.i index d7f7c8700..258904c9d 100644 --- a/src/runtime_swig/SALOMERuntime.i +++ b/src/runtime_swig/SALOMERuntime.i @@ -59,10 +59,12 @@ #include "TypeConversions.hxx" #include "TypeCode.hxx" #include "VisitorSaveSalomeSchema.hxx" +#include "VisitorSalomeSaveState.hxx" #include "SalomeOptimizerLoop.hxx" #include "DistributedPythonNode.hxx" #include "PyOptimizerAlg.hxx" #include "PyStdout.hxx" +#include "ExecutorSwig.hxx" #include %} @@ -134,6 +136,20 @@ %include "SalomeOptimizerLoop.hxx" %include "DistributedPythonNode.hxx" +namespace YACS +{ + namespace ENGINE + { + class SchemaSaveState + { + public: + SchemaSaveState(Proc* proc, Executor* exec); + virtual void save(std::string xmlSchemaFile); + }; + } +} + + %extend YACS::ENGINE::OutputPresetPort { void setDataPy(PyObject *ob) diff --git a/src/yacsloader/LoadState.cxx b/src/yacsloader/LoadState.cxx index be6cb4591..f4222f10c 100644 --- a/src/yacsloader/LoadState.cxx +++ b/src/yacsloader/LoadState.cxx @@ -27,6 +27,8 @@ #include "Runtime.hxx" #include "InputPort.hxx" #include "ElementaryNode.hxx" +#include "ForEachLoop.hxx" +#include "Any.hxx" #include #include @@ -249,6 +251,7 @@ void nodeParser::onStart (const XML_Char* elem, const xmlChar** p) else if (element == "nbdone") parser = new attrParser(); else if (element == "condition") parser = new attrParser(); else if (element == "outputPort") parser = new outputParser(); + else if (element == "loopOutputPort") parser = new loopPortParser(); else { _what = "expected name, state or inputPort, got <" + element + ">"; @@ -659,7 +662,148 @@ void simpleTypeParser::charData(std::string data) _data = _data + data; } +// ---------------------------------------------------------------------------- + +void loopPortParser::init(const xmlChar** p, xmlParserBase* father) +{ + DEBTRACE("loopPortParser::init()"); + _state = XMLINPORT; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} + +void loopPortParser::onStart(const XML_Char* elem, const xmlChar** p) +{ + DEBTRACE("loopPortParser::onStart" << elem); + string element(elem); + stateParser *parser = 0; + if (element == "name") parser = new attrParser(); + else if (element == "sample") parser = new sampleParser(); + else + { + _what = "expected name or sample, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void loopPortParser::onEnd(const XML_Char* name) +{ + string portName = _mapAttrib["name"]; + string nodeName = _father->getAttribute("name"); + string nodeType = _father->getAttribute("type"); + Node *node = _p->getChildByName(nodeName); + if (nodeType != "forEachLoop") + { + _what = "loopOutputPort attribute is not valid for node <" + nodeName + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } +} + +void loopPortParser::charData(std::string data) +{ +} + +// ---------------------------------------------------------------------------- + +void sampleParser::init(const xmlChar** p, xmlParserBase* father) +{ + DEBTRACE("sampleParser::init()"); + _state = XMLINPORT; + _father = father; + _stackState.push(_state); + if (p) getAttributes(p); +} +void sampleParser::onStart(const XML_Char* elem, const xmlChar** p) +{ + DEBTRACE("sampleParser::onStart" << elem); + string element(elem); + stateParser *parser = 0; + if (element == "index") parser = new attrParser(); + else if (element == "value") parser = new valueParser(); + else + { + _what = "expected index or value, got <" + element + ">"; + _state = XMLFATALERROR; + stopParse(_what); + } + if (parser) + { + _stackParser.push(parser); + XML_SetUserData(_xmlParser, parser); + parser->init(p, this); + } +} + +void sampleParser::onEnd(const XML_Char* name) +{ + if (_mapAttrib.find("index") == _mapAttrib.end()) + { + _what = "no attribute index in sample "; + _state = XMLFATALERROR; + stopParse(_what); + } + int index = atoi(_mapAttrib["index"].c_str()); + Any * value; + value = xmlToAny(); +} + +void sampleParser::charData(std::string data) +{ +} + +Any* sampleParser::xmlToAny() throw(ConversionException) +{ + xmlDocPtr doc; + xmlNodePtr cur; + YACS::ENGINE::Any *ob=NULL; + { + doc = xmlParseMemory(_data.c_str(), _data.length()); + if (doc == NULL ) + { + stringstream msg; + msg << "Problem in conversion: XML Document not parsed successfully "; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + stringstream msg; + msg << "Problem in conversion: empty XML Document"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"value"))) + { + ob=convertXmlNeutral(edGetType(),doc,cur); + break; + } + cur = cur->next; + } + xmlFreeDoc(doc); + if(ob==NULL) + { + stringstream msg; + msg << "Problem in conversion: incorrect XML value"; + msg << " (" << __FILE__ << ":" << __LINE__ << ")"; + throw ConversionException(msg.str()); + } + } + return ob; +} // ---------------------------------------------------------------------------- diff --git a/src/yacsloader/LoadState.hxx b/src/yacsloader/LoadState.hxx index ea318eb6c..16e423442 100644 --- a/src/yacsloader/LoadState.hxx +++ b/src/yacsloader/LoadState.hxx @@ -22,9 +22,11 @@ #include "YACSloaderExport.hxx" #include "xmlParserBase.hxx" +#include "InputPort.hxx" #include "define.hxx" #include "Exception.hxx" +#include namespace YACS { @@ -32,6 +34,8 @@ namespace YACS { class Proc; class Runtime; + class SequenceAny; + class Any; //! Load state from a file into a Proc /*! @@ -172,6 +176,29 @@ namespace YACS virtual void charData(std::string data); }; + class YACSLOADER_EXPORT loopPortParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData(std::string data); + std::vector _ids; + std::vector _outputValues; + std::vector _outputNames; + }; + + class YACSLOADER_EXPORT sampleParser: public stateParser + { + public: + virtual void init(const xmlChar** p, xmlParserBase* father=0); + virtual void onStart (const XML_Char* elem, const xmlChar** p); + virtual void onEnd (const XML_Char* name); + virtual void charData(std::string data); + protected: + Any* xmlToAny()throw(ConversionException); + }; + } } #endif diff --git a/src/yacsloader/driver.cxx b/src/yacsloader/driver.cxx index ffdc95e79..f71028e60 100644 --- a/src/yacsloader/driver.cxx +++ b/src/yacsloader/driver.cxx @@ -24,7 +24,7 @@ #include "Exception.hxx" #include "Executor.hxx" #include "parsers.hxx" -#include "VisitorSaveState.hxx" +#include "VisitorSalomeSaveState.hxx" #include "VisitorSaveSalomeSchema.hxx" #include "LoadState.hxx" #include "Dispatcher.hxx" @@ -216,7 +216,7 @@ void Handler(int theSigId) bool isFinalDump = (strlen(myArgs.finalDump) != 0); if (isFinalDump) { - YACS::ENGINE::VisitorSaveState vst(p); + YACS::ENGINE::VisitorSalomeSaveState vst(p); vst.openFileDump(myArgs.finalDump); p->accept(&vst); vst.closeFileDump(); @@ -252,7 +252,7 @@ void * dumpState(void *arg) #endif string cmd = "touch " + st->lockFile; system(cmd.c_str()); - YACS::ENGINE::VisitorSaveState vst(p); + YACS::ENGINE::VisitorSalomeSaveState vst(p); vst.openFileDump(st->dumpFile); p->accept(&vst); vst.closeFileDump(); @@ -544,7 +544,7 @@ int main (int argc, char* argv[]) bool isFinalDump = (strlen(myArgs.finalDump) != 0); if (isFinalDump) { - YACS::ENGINE::VisitorSaveState vst(p); + YACS::ENGINE::VisitorSalomeSaveState vst(p); vst.openFileDump(myArgs.finalDump); p->accept(&vst); vst.closeFileDump(); -- 2.39.2