-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
* \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())
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
void checkNoCyclePassingThrough(Node *node) throw(Exception);
std::vector< std::pair<OutGate *, InGate *> > 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;
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
* 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);
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);
}
}
* 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);
return updateStateOnFinishedEventFrom(node);
break;
case YACS::ABORT:
- return updateStateOnFailedEventFrom(node,execInst);
+ return updateStateOnFailedEventFrom(node);
break;
default:
return YACS::NOEVENT;//TODO unexpected type of event
}
//! 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;
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
DeploymentTree checkDeploymentTree(bool deep) const throw(Exception);
std::vector<Task *> 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++
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<ComposedNode *>& pointsOfViewStart,
InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) throw(Exception);
virtual void buildDelegateOf(InPort * & port, OutPort *initialStart, const std::list<ComposedNode *>& pointsOfView);
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
* \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);
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
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<Node *> cloneAndPlaceNodesCoherently(const std::vector<Node *> & origNodes);
Node * checkConsistencyAndSetNode(Node* &nodeToReplace, Node* DISOWNnode);
Node * removeNode(Node* &nodeToRemove);
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
DEBTRACE("Executor::saveState() in " << xmlFile);
bool result = false;
try {
+ YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
YACS::ENGINE::VisitorSaveState vst(_root);
vst.openFileDump(xmlFile.c_str());
_root->accept(&vst);
traceExec(task, "state:TOLOAD", ComputePlacement(task));
{//Critical section
YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
- _mainSched->notifyFrom(task,YACS::START,execInst);
+ _mainSched->notifyFrom(task,YACS::START);
}//End of critical section
try
{
{//Critical section
YACS::BASES::AutoLocker<YACS::BASES::Mutex> 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
}
{//Critical section
YACS::BASES::AutoLocker<YACS::BASES::Mutex> 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
}
{//Critical section
YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
(*iter)->aborted();
- _mainSched->notifyFrom(*iter,YACS::ABORT,this);
+ _mainSched->notifyFrom(*iter,YACS::ABORT);
}//End of critical section
}
catch(...)
{//Critical section
YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&_mutexForSchedulerUpdate);
(*iter)->aborted();
- _mainSched->notifyFrom(*iter,YACS::ABORT,this);
+ _mainSched->notifyFrom(*iter,YACS::ABORT);
}//End of critical section
}
if((*iter)->getState() == YACS::ERROR)
{//Critical section
YACS::BASES::AutoLocker<YACS::BASES::Mutex> 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));
}
task->aborted();
}
execInst->traceExec(task, "state:"+Node::getStateName(task->getState()),placement);
- sched->notifyFrom(task,ev,execInst);
+ sched->notifyFrom(task,ev);
}
catch(Exception& ex)
{
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
#include <sstream>
#include <algorithm> // std::replace_if
--//#define _DEVDEBUG_
++#define _DEVDEBUG_
#include "YacsTrace.hxx"
using namespace YACS::ENGINE;
}
}
+ ForEachLoopPassedData::ForEachLoopPassedData(const ForEachLoopPassedData& copy)
+ : _passedIds(copy._passedIds),
+ _passedOutputs(copy._passedOutputs),
+ _nameOfOutputs(copy._nameOfOutputs),
+ _flagsIds(copy._flagsIds)
+ {
+ }
+
ForEachLoopPassedData::~ForEachLoopPassedData()
{
for(std::vector<SequenceAny *>::iterator it=_passedOutputs.begin();it!=_passedOutputs.end();it++)
int globalId(_execIds[id]);
if(_passedData)
globalId=_passedData->toAbsId(globalId);
+ sendEvent2("progress_ok",&globalId);
storeOutValsInSeqForOutOfScopeUse(globalId,id);
}
+ else
+ {
+ int globalId(_execIds[id]);
+ if(_passedData)
+ globalId=_passedData->toAbsId(globalId);
+ sendEvent2("progress_ko",&globalId);
+ }
//
if(_execCurrentId==getFinishedId())
{//No more elements of _dataPortToDispatch to treat
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++;
}
else
{
- TypeCodeSeq *newTc=(TypeCodeSeq *)TypeCode::sequenceTc("","",port.first->edGetType());
+ TypeCode *tcTrad((YACS::ENGINE::TypeCode*)finalTarget->edGetType()->subContentType(getFEDeltaBetween(port.first,finalTarget)));
+ TypeCodeSeq *newTc=(TypeCodeSeq *)TypeCode::sequenceTc("","",tcTrad);
// The out going ports belong to the ForEachLoop, whereas
// the delegated port belongs to a node child of the ForEachLoop.
// The name of the delegated port contains dots (bloc.node.outport),
std::string outputPortName(getPortName(port.first));
InterceptorizeNameOfPort(outputPortName);
AnySplitOutputPort *newPort(new AnySplitOutputPort(outputPortName,this,newTc));
- InterceptorInputPort *intercptor(new InterceptorInputPort(outputPortName + "_in",this,port.first->edGetType()));
+ InterceptorInputPort *intercptor(new InterceptorInputPort(outputPortName + "_in",this,tcTrad));
intercptor->setRepr(newPort);
newTc->decrRef();
newPort->addRepr(port.first,intercptor);
//AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,(*iter)->edGetType());
OutPort *portOut=getDynOutPortByAbsName(branchNb,getOutPortName(((*iter)->getRepr())));
DEBTRACE( portOut->getName() );
- AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,portOut->edGetType());
+ TypeCode *tc((TypeCode *)(*iter)->edGetType()->contentType());
+ AnyInputPort *interceptor=new AnyInputPort((*iter)->getName(),this,tc);
portOut->addInPort(interceptor);
_execOutGoingPorts[branchNb].push_back(interceptor);
}
return std::vector<unsigned int>();
if(_execOutGoingPorts.empty())
return std::vector<unsigned int>();
- 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<AnyInputPort *>& ports(_execOutGoingPorts[0]);
for(std::size_t i=0;i<sz;i++)
{
_passedData=new ForEachLoopPassedData(passedIds,passedOutputs,nameOfOutputs);
}
+int ForEachLoop::getFEDeltaBetween(OutPort *start, InPort *end)
+{
+ Node *ns(start->getNode()),*ne(end->getNode());
+ ComposedNode *co(getLowestCommonAncestor(ns,ne));
+ int ret(0);
+ Node *work(ns);
+ while(work!=co)
+ {
+ ForEachLoop *isFE(dynamic_cast<ForEachLoop *>(work));
+ if(isFE)
+ ret++;
+ work=work->getFather();
+ }
+ if(dynamic_cast<AnySplitOutputPort *>(start))
+ ret--;
+ return ret;
+}
++
+ /*!
+ * 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<SequenceAny *> outputs;
+ std::vector<std::string> nameOfOutputs;
+ if(_execVals.empty() || _execOutGoingPorts.empty())
+ return new ForEachLoopPassedData(std::vector<unsigned int>(), outputs, nameOfOutputs);
+ std::size_t sz(_execVals.size());
+ outputs.resize(sz);
+ nameOfOutputs.resize(sz);
+ const std::vector<AnyInputPort *>& ports(_execOutGoingPorts[0]);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ outputs[i]=_execVals[i]->removeUnsetItemsFromThis();
+ nameOfOutputs[i]=ports[i]->getName();
+ }
+ return new ForEachLoopPassedData(_execVals[0]->getSetItems(), outputs, nameOfOutputs);
+ }
+
+ void ForEachLoop::setProcessedData(ForEachLoopPassedData* processedData)
+ {
+ if(_passedData)
+ delete _passedData;
+ _passedData = processedData;
+ }
++
++/*!
++ * \param portName : "interceptorized" name of port.
++ */
++const YACS::ENGINE::TypeCode* ForEachLoop::getOutputPortType(const std::string& portName)const
++{
++ const YACS::ENGINE::TypeCode* ret=NULL;
++ vector<AnySplitOutputPort *>::const_iterator it;
++ for(it=_outGoingPorts.begin();it!=_outGoingPorts.end() && ret==NULL;it++)
++ {
++ std::string originalPortName(getPortName(*it));
++ //InterceptorizeNameOfPort(originalPortName);
++ DEBTRACE("ForEachLoop::getOutputPortType compare " << portName << " == " << originalPortName);
++ if(originalPortName == portName)
++ {
++ ret = (*it)->edGetType()->contentType();
++ }
++ }
++ return ret;
++}
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
{
public:
ForEachLoopPassedData(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
+ ForEachLoopPassedData(const ForEachLoopPassedData& copy);
~ForEachLoopPassedData();
void init();
void checkCompatibilyWithNb(int nbOfElts) const;
int toAbsIdNot(int localId) const;
int getNumberOfElementsToDo() const;
void assignAlreadyDone(const std::vector<SequenceAny *>& execVals) const;
+ const std::vector<unsigned int>& getIds()const {return _passedIds;}
+ const std::vector<SequenceAny *>& getOutputs()const {return _passedOutputs;}
+ const std::vector<std::string>& getOutputNames()const {return _nameOfOutputs;}
+ //const std::vector<bool>& getFlags()const {return _flagsIds;}
private:
std::vector<unsigned int> _passedIds;
std::vector<SequenceAny *> _passedOutputs;
std::list<ProgressWeight> getProgressWeight() const;
int getCurrentIndex() const { return _currentIndex; }
int getNbOfElementsToBeProcessed() const;
+ static int getFEDeltaBetween(OutPort *start, InPort *end);
#ifndef SWIG
+ ForEachLoopPassedData* getProcessedData()const;
+ void setProcessedData(ForEachLoopPassedData* processedData);
std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
#endif
++ const TypeCode* getOutputPortType(const std::string& portName)const;
protected:
Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
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<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) throw(Exception);
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
* \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() +
_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)
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
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<ComposedNode *>& pointsOfView);
void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
void checkControlDependancy(OutPort *start, InPort *end, bool cross,
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
namespace ENGINE
{
class Task;
- class Executor;
class Scheduler
{
virtual std::string getTaskName(Task *task) const = 0;
virtual std::vector<Task *> getNextTasks(bool& isMore) = 0;
virtual void selectRunnableTasks(std::vector<Task *>& 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;
-# Copyright (C) 2012-2015 CEA/DEN, EDF R&D
+# Copyright (C) 2012-2016 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
SalomeOptimizerLoop.hxx
DistributedPythonNode.hxx
PyOptimizerAlg.hxx
+ VisitorSalomeSaveState.hxx
)
# --- sources ---
PyStdout.cxx
SalomeOptimizerLoop.cxx
PyOptimizerAlg.cxx
+ VisitorSalomeSaveState.cxx
)
# --- rules ---
-# Copyright (C) 2012-2015 CEA/DEN, EDF R&D
+# Copyright (C) 2012-2016 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
${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
)
+SET(SWIG_MODULE_SALOMERuntime_EXTRA_DEPS
+ ${PROJECT_SOURCE_DIR}/src/engine_swig/pilot.i
+ ${PROJECT_SOURCE_DIR}/src/engine_swig/engtypemaps.i
+ ${SWIGINCLUDES})
SWIG_ADD_MODULE(SALOMERuntime python SALOMERuntime.i)
-ADD_DEPENDENCIES(_SALOMERuntime
- SALOMERuntime.i
- ${PROJECT_SOURCE_DIR}/src/engine_swig/pilot.i
- ${PROJECT_SOURCE_DIR}/src/engine_swig/engtypemaps.i
- docruntime.i
- ${SWIGINCLUDES})
SWIG_LINK_LIBRARIES(SALOMERuntime ${_link_LIBRARIES})
IF(WIN32)
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
#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 <sstream>
%}
%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)
-# Copyright (C) 2012-2015 CEA/DEN, EDF R&D
+# Copyright (C) 2012-2016 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
${OMNIORB_LIBRARIES}
${LIBXML2_LIBRARIES}
YACSlibEngine
++ YACSRuntimeSALOME
)
SET(_link_LIBRARIES
YACSloader
SET(debugger_SOURCES
debugger.cxx
)
+SET(ExampleOfObserversPluginForDriver_SOURCES
+ ExampleOfObserversPluginForDriver.cxx
+ )
# --- rules ---
TARGET_LINK_LIBRARIES(YACSloader ${YACSloader_LIBRARIES})
INSTALL(TARGETS YACSloader EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
+ADD_LIBRARY(ExampleOfObserversPluginForDriver ${ExampleOfObserversPluginForDriver_SOURCES})
+TARGET_LINK_LIBRARIES(ExampleOfObserversPluginForDriver ${_link_LIBRARIES})
+INSTALL(TARGETS ExampleOfObserversPluginForDriver DESTINATION ${SALOME_INSTALL_LIBS})
+
ADD_EXECUTABLE(driver ${driver_SOURCES})
TARGET_LINK_LIBRARIES(driver ${_link_LIBRARIES})
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
#include "Runtime.hxx"
#include "InputPort.hxx"
#include "ElementaryNode.hxx"
+ #include "ForEachLoop.hxx"
+ #include "Any.hxx"
++#include "TypeConversions.hxx"
#include <iostream>
#include <string>
#include <cstdarg>
#include <cassert>
--//#define _DEVDEBUG_
++#define _DEVDEBUG_
#include "YacsTrace.hxx"
using namespace YACS::ENGINE;
_nodeStateValue["DISABLED"] =YACS::DISABLED;
_nodeStateValue["FAILED"] =YACS::FAILED;
_nodeStateValue["ERROR"] =YACS::ERROR;
+ _nodeStates.clear();
}
void nodeParser::init(const xmlChar** p, xmlParserBase* father)
{
DEBTRACE("nodeParser::init()");
++ _loopSamples.clear();
_state = XMLINNODE;
_father = father;
_stackState.push(_state);
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 if (element == "loopOutputPort")
++ {
++ loopPortParser* sparser = new loopPortParser();
++ _loopSamples.push_back(sparser);
++ parser = sparser;
++ }
else
{
_what = "expected name, state or inputPort, got <" + element + ">";
}
mySwitch->edGetConditionPort()->edInit(condition);
}
++ else if (nodeType == "forEachLoop")
++ {
++ ForEachLoop* feNode = dynamic_cast<ForEachLoop*>(node);
++ if(!feNode)
++ {
++ _what = "node is not a ForEachLoop: " + _mapAttrib["name"];
++ _state = XMLFATALERROR;
++ stopParse(_what);
++ }
++ else
++ {
++ std::vector<unsigned int> passedIds;
++ std::vector<SequenceAny *> passedOutputs;
++ std::vector<std::string> nameOfOutputs;
++ bool firstPort = true;
++ std::list<loopPortParser*>::const_iterator itPort;
++ for(itPort=_loopSamples.begin(); itPort!=_loopSamples.end(); itPort++)
++ {
++ const std::string& portName =(*itPort)->getPortName();
++ nameOfOutputs.push_back(portName);
++ const YACS::ENGINE::TypeCode* tc = feNode->getOutputPortType(portName);
++ if(!tc)
++ {
++ _what = "Impossible to find the type of the port " + portName;
++ _state = XMLFATALERROR;
++ stopParse(_what);
++ return;
++ }
++ unsigned int nbSamples = (*itPort)->getNbSamples();
++ SequenceAny* seqValues = SequenceAny::New(tc, nbSamples);
++ passedOutputs.push_back(seqValues);
++ for(unsigned int i = 0; i < nbSamples; i++)
++ {
++ unsigned int sampleId = (*itPort)->getSampleId(i);
++ const std::string& sampleData = (*itPort)->getSampleData(i);
++ Any* value = xmlToAny(sampleData, tc);
++ if(firstPort)
++ {
++ passedIds.push_back(sampleId);
++ seqValues->setEltAtRank(i, value);
++ }
++ else
++ {
++ unsigned int pos = 0;
++ while(pos < passedIds.size() && sampleId != passedIds[pos])
++ pos++;
++ if(pos < passedIds.size())
++ seqValues->setEltAtRank(pos, value);
++ else
++ {
++ _what = "Inconsistent sample id in foreach node " + _mapAttrib["name"];
++ _state = XMLFATALERROR;
++ stopParse(_what);
++ itPort=_loopSamples.end();
++ return;
++ }
++ }
++ }
++ firstPort = false;
++ }
++ feNode->assignPassedResults(passedIds, passedOutputs, nameOfOutputs);
++ }
++ }
stateParser::onEnd(name);
}
++Any* nodeParser::xmlToAny(const std::string& data, const YACS::ENGINE::TypeCode* tc)const
++{
++ xmlDocPtr doc;
++ xmlNodePtr cur;
++ //YACS::ENGINE::Any *ob=YACS::ENGINE::AtomAny::New(0);
++ 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(tc,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;
++}
++
// ----------------------------------------------------------------------------
void attrParser::init(const xmlChar** p, xmlParserBase* father)
_data = _data + data;
}
- _state = XMLINPORT;
+ // ----------------------------------------------------------------------------
+
+ void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
+ {
+ DEBTRACE("loopPortParser::init()");
- else if (element == "sample") parser = new sampleParser();
++ //_state = XMLINPORT;
+ _father = father;
+ _stackState.push(_state);
++ _ids.clear();
++ _sampleData.clear();
+ 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();
- 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);
- }
++ else if (element == "sample") parser = new sampleParser(this);
+ 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)
+ {
++ stateParser::onEnd(name);
+ }
+
+ void loopPortParser::charData(std::string data)
+ {
+ }
- _state = XMLINPORT;
++void loopPortParser::addSample(int index, const std::string data)
++{
++ _ids.push_back(index);
++ _sampleData.push_back(data);
++}
++
++unsigned int loopPortParser::getNbSamples()const
++{
++ return _ids.size();
++}
++
++unsigned int loopPortParser::getSampleId(unsigned int i)const
++{
++ return _ids[i];
++}
++
++const std::string& loopPortParser::getSampleData(unsigned int i)const
++{
++ return _sampleData[i];
++}
++
++const std::string& loopPortParser::getPortName()const
++{
++ return _mapAttrib.at("name");
++}
++
+ // ----------------------------------------------------------------------------
+
++sampleParser::sampleParser(loopPortParser* father)
++: stateParser(),
++ _sampleFather(father)
++{
++}
++
+ void sampleParser::init(const xmlChar** p, xmlParserBase* father)
+ {
+ DEBTRACE("sampleParser::init()");
- Any * value;
- value = xmlToAny();
++ //_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* 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;
++ _sampleFather->addSample(index, _data);
++ stateParser::onEnd(name);
+ }
+
+ void sampleParser::charData(std::string data)
+ {
++ _data = _data + data;
+ }
// ----------------------------------------------------------------------------
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
#include "YACSloaderExport.hxx"
#include "xmlParserBase.hxx"
+ #include "InputPort.hxx"
#include "define.hxx"
#include "Exception.hxx"
+ #include <vector>
++#include <list>
namespace YACS
{
{
class Proc;
class Runtime;
+ class SequenceAny;
+ class Any;
++ class TypeCode;
//! Load state from a file into a Proc
/*!
};
++ class loopPortParser;
class YACSLOADER_EXPORT nodeParser: 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);
++ Any* xmlToAny(const std::string& data, const TypeCode* tc)const;
std::string _nodeName;
std::string _nodeState;
++ private:
++ std::list<loopPortParser*> _loopSamples;
};
class YACSLOADER_EXPORT attrParser: public stateParser
virtual void charData(std::string data);
};
- std::vector<SequenceAny *> _outputValues;
- std::vector<std::string> _outputNames;
+ 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);
++ void addSample(int index, const std::string data);
++ unsigned int getNbSamples()const;
++ unsigned int getSampleId(unsigned int i)const;
++ const std::string& getSampleData(unsigned int i)const;
++ const std::string& getPortName()const;
++ private:
+ std::vector<unsigned int> _ids;
- protected:
- Any* xmlToAny()throw(ConversionException);
++ std::vector<std::string> _sampleData;
+ };
+
+ class YACSLOADER_EXPORT sampleParser: public stateParser
+ {
+ public:
++ sampleParser(loopPortParser* father);
+ 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);
++ private:
++ loopPortParser* _sampleFather;
+ };
+
}
}
#endif
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
#include "Exception.hxx"
#include "Executor.hxx"
#include "parsers.hxx"
- #include "VisitorSaveState.hxx"
+ #include "VisitorSalomeSaveState.hxx"
#include "VisitorSaveSalomeSchema.hxx"
#include "LoadState.hxx"
#include "Dispatcher.hxx"
#include <signal.h>
#include <list>
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
#else
#include <argp.h>
#endif
static char doc[] ="driver -- a SALOME YACS graph executor";
static char args_doc[] = "graph.xml";
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
#else
static struct argp_option options[] =
{
string lockFile;
} thread_st;
-#ifdef WIN32
+#ifndef WIN32
+#include <dlfcn.h>
+#include <stdlib.h>
+#endif
+
+std::string LoadedDriverPluginLibrary;
+void *HandleOnLoadedPlugin=0;
+void (*DefineCustomObservers)(YACS::ENGINE::Dispatcher *, YACS::ENGINE::ComposedNode *, YACS::ENGINE::Executor *)=0;
+void (*CleanUpObservers) ()=0;
+
+void LoadObserversPluginIfAny(YACS::ENGINE::ComposedNode *rootNode, YACS::ENGINE::Executor *executor)
+{
+ static const char SYMBOLE_NAME_1[]="DefineCustomObservers";
+ static const char SYMBOLE_NAME_2[]="CleanUpObservers";
+#ifndef WIN32
+ Dispatcher *disp(Dispatcher::getDispatcher());
+ if(!disp)
+ throw YACS::Exception("Internal error ! No dispatcher !");
+ char *yacsDriverPluginPath(getenv("YACS_DRIVER_PLUGIN_PATH"));
+ if(!yacsDriverPluginPath)
+ return ;
+ void *handle(dlopen(yacsDriverPluginPath, RTLD_LAZY | RTLD_GLOBAL));
+ if(!handle)
+ {
+ std::string message(dlerror());
+ std::ostringstream oss; oss << "Error during load of \"" << yacsDriverPluginPath << "\" defined by the YACS_DRIVER_PLUGIN_PATH env var : " << message;
+ throw YACS::Exception(oss.str());
+ }
+ DefineCustomObservers=(void (*)(YACS::ENGINE::Dispatcher *, YACS::ENGINE::ComposedNode *, YACS::ENGINE::Executor *))(dlsym(handle,SYMBOLE_NAME_1));
+ if(!DefineCustomObservers)
+ {
+ std::ostringstream oss; oss << "Error during load of \"" << yacsDriverPluginPath << "\" ! Library has been correctly loaded but symbol " << SYMBOLE_NAME_1 << " does not exists !";
+ throw YACS::Exception(oss.str());
+ }
+ CleanUpObservers=(void (*)())(dlsym(handle,SYMBOLE_NAME_2));
+ if(!CleanUpObservers)
+ {
+ std::ostringstream oss; oss << "Error during load of \"" << yacsDriverPluginPath << "\" ! Library has been correctly loaded but symbol " << SYMBOLE_NAME_2 << " does not exists !";
+ throw YACS::Exception(oss.str());
+ }
+ HandleOnLoadedPlugin=handle;
+ DefineCustomObservers(disp,rootNode,executor);
+#endif
+}
+
+void UnLoadObserversPluginIfAny()
+{
+#ifndef WIN32
+ if(HandleOnLoadedPlugin)
+ {
+ CleanUpObservers();
+ dlclose(HandleOnLoadedPlugin);
+ }
+#endif
+}
+
+#if defined WIN32 || defined __APPLE__
static int
#else
static error_t
#endif
parse_opt (int key, char *arg, struct argp_state *state)
{
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
#else
// Get the input argument from argp_parse, which we
// know is a pointer to our arguments structure.
}
// Our argp parser.
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
#else
static struct argp argp = { options, parse_opt, args_doc, doc };
#endif
void timer(std::string msg)
{
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
#else
struct timeval tv;
gettimeofday(&tv,NULL);
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();
#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();
myArgs.init_ports.clear();
// Parse our arguments; every option seen by parse_opt will be reflected in arguments.
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
#else
argp_parse (&argp, argc, argv, 0, 0, &myArgs);
std::cerr << "graph = " << myArgs.args[0];
return 1;
}
// Initialize the ports
- for(it=myArgs.init_ports.begin(); it != myArgs.init_ports.end(); it++)
+ for(std::list<std::string>::iterator it=myArgs.init_ports.begin(); it != myArgs.init_ports.end(); it++)
{
std::string node, port, value;
if(parse_init_port((*it), node, port, value))
st->lockFile = rootFile + ".lock";
pthread_create(&th,NULL,&dumpState,(void*)st);
}
-
+ LoadObserversPluginIfAny(p,&executor);
cerr << "+++++++++++++++++++ start calculation +++++++++++++++++++" << endl;
executor.RunW(p,myArgs.display, fromScratch);
cerr << "+++++++++++++++++++ end calculation +++++++++++++++++++" << endl;
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();
r->fini();
delete r;
delete disp;
+ UnLoadObserversPluginIfAny();
return return_value;
}
catch (YACS::Exception& e)
-// Copyright (C) 2006-2015 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2016 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
%include "YACSloaderExport.hxx"
%include "parsers.hxx"
%import "xmlParserBase.hxx"
--%include "LoadState.hxx"
++//%include "LoadState.hxx"