STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 1)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
SET(${PROJECT_NAME_UC}_VERSION
${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
ENDIF()
ENDIF()
IF(SALOME_YACS_BUILD_GUI)
- SET_AND_CHECK(GUI_ROOT_DIR_EXP "@PACKAGE_GUI_ROOT_DIR@")
+ SET_AND_CHECK(GUI_ROOT_DIR "@PACKAGE_GUI_ROOT_DIR@")
LIST(APPEND YACS_DEFINITIONS "@GUI_DEFINITIONS@")
ENDIF()
IF(SALOME_YACS_BUILD_GUI)
# Include GUI targets if they were not already loaded:
+ FIND_PACKAGE(SalomeGUI)
IF(NOT (TARGET Event))
- INCLUDE("${GUI_ROOT_DIR_EXP}/${SALOME_INSTALL_CMAKE_LOCAL}/SalomeGUITargets.cmake")
+ INCLUDE("${GUI_ROOT_DIR}/adm_local/cmake_files/SalomeGUITargets.cmake")
ENDIF()
ELSE(SALOME_YACS_BUILD_GUI)
IF(SALOME_YACS_USE_KERNEL)
# Include KERNEL targets if they were not already loaded:
IF(NOT (TARGET SALOMEBasics))
- INCLUDE("${KERNEL_ROOT_DIR_EXP}/${SALOME_INSTALL_CMAKE}/SalomeKERNELTargets.cmake")
+ INCLUDE("${KERNEL_ROOT_DIR_EXP}/salome_adm/cmake_files/SalomeKERNELTargets.cmake")
ENDIF()
ENDIF(SALOME_YACS_USE_KERNEL)
ENDIF(SALOME_YACS_BUILD_GUI)
# General information about the project.
project = 'yacs'
-copyright = '2007-2016 CEA/DEN, EDF R&D.'
+copyright = '2007-2017 CEA/DEN, EDF R&D.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
def __init__(self, orb, poa, this, containerName,
instanceName, interfaceName):
SALOME_ComponentPy_i.__init__(self, orb, poa, this, containerName,
- instanceName, interfaceName, 0)
+ instanceName, interfaceName, False)
self.F = FreeFem.FreeFem();
def Bords(self, b):
instanceName, interfaceName):
SALOME_ComponentPy_i.__init__(self, orb, poa, this,
containerName, instanceName,
- interfaceName, 0)
+ interfaceName, False)
Enable supervision of the component
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
instanceName, interfaceName):
SALOME_ComponentPy_i.__init__(self, orb, poa, this,
containerName, instanceName,
- interfaceName, 1)
+ interfaceName, True)
in which the parameter “1” is added to the end of the call to the ``SALOME_ComponentPy_i`` of the constructor.
The component can then use the following instruction::
<ul>
$navpath
<li class="footer">
- Copyright © 2006-2016 CEA/DEN, EDF R&D<br>
+ Copyright © 2006-2017 CEA/DEN, EDF R&D<br>
</li>
</ul>
</div>
# KERNEL
##
IF(SALOME_YACS_USE_KERNEL)
- SET(SUBDIRS_KERNEL runtime yacsloader evalyfx)
+ SET(SUBDIRS_KERNEL runtime yacsloader evalyfx py2yacs)
ENDIF(SALOME_YACS_USE_KERNEL)
##
SUBDIRS(
bases
engine
+ engine_swig
runtime
pmml
yacsloader
yacsloader_swig
+ py2yacs
)
AutoRefCnt(const AutoRefCnt& other):_ptr(0) { referPtr(other._ptr); }
AutoRefCnt(T *ptr=0):_ptr(ptr) { }
~AutoRefCnt() { destroyPtr(); }
+ bool isNull() const { return _ptr==0; }
+ bool isNotNull() const { return !isNull(); }
+ void nullify() { destroyPtr(); _ptr=0; }
bool operator==(const AutoRefCnt& other) const { return _ptr==other._ptr; }
bool operator==(const T *other) const { return _ptr==other; }
AutoRefCnt &operator=(const AutoRefCnt& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; }
operator T *() { return _ptr; }
operator const T *() const { return _ptr; }
T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; }
+ void takeRef(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; if(_ptr) _ptr->incrRef(); } }
private:
void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); }
void destroyPtr() { if(_ptr) _ptr->decrRef(); }
T *_ptr;
};
+ template<class T>
+ class AutoConstRefCnt
+ {
+ public:
+ AutoConstRefCnt(const AutoConstRefCnt& other):_ptr(0) { referPtr(other._ptr); }
+ AutoConstRefCnt(const T *ptr=0):_ptr(ptr) { }
+ ~AutoConstRefCnt() { destroyPtr(); }
+ bool isNull() const { return _ptr==0; }
+ bool isNotNull() const { return !isNull(); }
+ void nullify() { destroyPtr(); _ptr=0; }
+ bool operator==(const AutoConstRefCnt& other) const { return _ptr==other._ptr; }
+ bool operator==(const T *other) const { return _ptr==other; }
+ AutoConstRefCnt &operator=(const AutoConstRefCnt& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; }
+ AutoConstRefCnt &operator=(const T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+ const T *operator->() const { return _ptr; }
+ const T& operator*() const { return *_ptr; }
+ operator const T *() const { return _ptr; }
+ const T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; }
+ void takeRef(const T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; if(_ptr) _ptr->incrRef(); } }
+ private:
+ void referPtr(const T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); }
+ void destroyPtr() { if(_ptr) _ptr->decrRef(); }
+ private:
+ const T *_ptr;
+ };
+
template<class T, class U>
typename YACS::BASES::AutoRefCnt<U> DynamicCast(typename YACS::BASES::AutoRefCnt<T>& autoSubPtr) throw()
{
using namespace YACS::BASES;
+#if defined(__APPLE__)
+const char DynLibLoaderGNU::_extForDynLib[]=".dylib";
+#else
const char DynLibLoaderGNU::_extForDynLib[]=".so";
+#endif
DynLibLoaderGNU::DynLibLoaderGNU(const std::string& libNameWithoutExtension):_libName(libNameWithoutExtension),
_handleOnLoadedLib(0)
-chrono::chrono(int i) : _ctr(i), _run(true)
+salome_chrono::salome_chrono(int i) : _ctr(i), _run(true)
{
- //DEBTRACE("chrono::chrono " << _ctr << " " << _run);
+ //DEBTRACE("salome_chrono::salome_chrono " << _ctr << " " << _run);
_start = clock();
}
-chrono::~chrono()
+salome_chrono::~salome_chrono()
{
if (_run) stop();
}
-void chrono::stop()
+void salome_chrono::stop()
{
- //DEBTRACE("chrono::stop " << _ctr << " " << _run);
+ //DEBTRACE("salome_chrono::stop " << _ctr << " " << _run);
if (_run)
{
_run = false;
int _nbChrono;
};
-class YACSBASES_EXPORT chrono
+class YACSBASES_EXPORT salome_chrono
{
public:
- chrono(int i);
- ~chrono();
+ salome_chrono(int i);
+ ~salome_chrono();
void stop();
protected:
bool _run;
#ifdef CHRONODEF
#define CHRONO(i) counters::_ctrs[i]._ctrNames = (char *)__FILE__; \
counters::_ctrs[i]._ctrLines = __LINE__; \
- chrono aChrono##i(i);
+ salome_chrono aChrono##i(i);
#define CHRONOSTOP(i) aChrono##i.stop();
#define __ABSTRACTPOINT_HXX__
#include "YACSlibEngineExport.hxx"
+#include "PlayGround.hxx"
+#include "AutoRefCnt.hxx"
+#include <map>
#include <list>
#include <vector>
#include <string>
class InGate;
class OutGate;
class BlocPoint;
+ class ComposedNode;
class ForkBlocPoint;
class LinkedBlocPoint;
virtual bool contains(Node *node) = 0;
virtual int getNumberOfNodes() const = 0;
virtual int getMaxLevelOfParallelism() const = 0;
+ virtual double getWeightRegardingDPL() const = 0;
+ virtual void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const = 0;
virtual std::string getRepr() const = 0;
virtual ~AbstractPoint();
public:
{
}
-Node *BagPoint::getFirstNode()
+AbstractPoint *BagPoint::getUnique()
{
if(_nodes.size()!=1)
- throw YACS::Exception("BagPoint::getFirstNode : invalid call !");
+ throw YACS::Exception("BagPoint::getUnique : invalid call !");
else
- return (*_nodes.begin())->getFirstNode();
+ {
+ AbstractPoint *ret(*_nodes.begin());
+ if(!ret)
+ throw YACS::Exception("BagPoint::getUnique : Ooops !");
+ return ret;
+ }
}
-Node *BagPoint::getLastNode()
+const AbstractPoint *BagPoint::getUnique() const
{
if(_nodes.size()!=1)
- throw YACS::Exception("BagPoint::getLastNode : invalid call !");
+ throw YACS::Exception("BagPoint::getUnique const : invalid call !");
else
- return (*_nodes.begin())->getLastNode();
+ {
+ AbstractPoint *ret(*_nodes.begin());
+ if(!ret)
+ throw YACS::Exception("BagPoint::getUnique : Ooops !");
+ return ret;
+ }
+}
+
+AbstractPoint *BagPoint::getUniqueAndReleaseIt()
+{
+ AbstractPoint *ret(getUnique());
+ getOutPoint(ret);
+ return ret;
+}
+
+Node *BagPoint::getFirstNode()
+{
+ return getUnique()->getFirstNode();
+}
+
+Node *BagPoint::getLastNode()
+{
+ return getUnique()->getLastNode();
}
int BagPoint::getMaxLevelOfParallelism() const
{
- if(_nodes.size()!=1)
- throw YACS::Exception("BagPoint::getMaxLevelOfParallelism : invalid call !");
- else
- return (*_nodes.begin())->getMaxLevelOfParallelism();
+ return getUnique()->getMaxLevelOfParallelism();
+}
+
+double BagPoint::getWeightRegardingDPL() const
+{
+ return getUnique()->getWeightRegardingDPL();
+}
+
+void BagPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
+{
+ getUnique()->partitionRegardingDPL(pd,zeMap);
}
std::string BagPoint::getRepr() const
Node *getFirstNode();
Node *getLastNode();
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
std::string getRepr() const;
+ AbstractPoint *getUniqueAndReleaseIt();
public:
int size() const { return (int)_nodes.size(); }
void replaceInMe(BlocPoint *aSet);
void deal2(bool& somethingDone);
void deal2Bis(bool& somethingDone);
void deal2Ter(bool& somethingDone);
+ private:
+ AbstractPoint *getUnique();
+ const AbstractPoint *getUnique() const;
};
}
}
#include "OutputDataStreamPort.hxx"
#include "ElementaryNode.hxx"
#include "Visitor.hxx"
+#include "ForkBlocPoint.hxx"
#include "SetOfPoints.hxx"
+#include "PlayGround.hxx"
#include <queue>
#include <iostream>
* for all concurrent branches in \a this.
*/
int Bloc::getMaxLevelOfParallelism() const
+{
+ std::list< AbstractPoint * > pts(analyzeParallelism());
+ ForkBlocPoint fbp(pts,NULL);
+ return fbp.getMaxLevelOfParallelism();
+}
+
+std::list< AbstractPoint * > Bloc::analyzeParallelism() const
{
std::vector< std::list<Node *> > r(splitIntoIndependantGraph());
- int ret(0);
+ std::list< AbstractPoint * > pts;
for(std::vector< std::list<Node *> >::const_iterator it=r.begin();it!=r.end();it++)
{
SetOfPoints sop(*it);
sop.simplify();
- ret+=sop.getMaxLevelOfParallelism();
+ pts.push_back(sop.getUniqueAndReleaseIt());
}
- return ret;
+ return pts;
+}
+
+double Bloc::getWeightRegardingDPL() const
+{
+ std::list< AbstractPoint * > pts(analyzeParallelism());
+ ForkBlocPoint fbp(pts,NULL);
+ return fbp.getWeightRegardingDPL();
}
void Bloc::removeRecursivelyRedundantCL()
destructCFComputations(info);
}
+void Bloc::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
+{
+ if(!pd)
+ throw Exception("Bloc::partitionRegardingDPL : NULL pointer !");
+ std::list< AbstractPoint * > pts(analyzeParallelism());
+ ForkBlocPoint fbp(pts,NULL);
+ fbp.partitionRegardingDPL(pd,zeMap);
+}
+
void Bloc::performCFComputationsOnlyOneLevel(LinkInfo& info) const
{
delete _fwLinks;//Normally useless
#include "YACSlibEngineExport.hxx"
#include "StaticDefinedComposedNode.hxx"
+#include "AutoRefCnt.hxx"
namespace YACS
{
namespace ENGINE
{
+ class PartDefinition;
+ class DynParaLoop;
+ class AbstractPoint;
+ class PlayGround;
class YACSLIBENGINE_EXPORT Bloc : public StaticDefinedComposedNode
{
protected:
void findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const;
virtual std::string typeName() { return "YACS__ENGINE__Bloc"; }
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
void removeRecursivelyRedundantCL();
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
+ void fitToPlayGround(const PlayGround *pg);
protected:
bool areAllSubNodesFinished() const;
bool areAllSubNodesDone() const;
void seekOkAndUseless1(std::vector<Node *>& okAndUseless1, std::set<Node *>& allNodes) const;
void seekUseless2(std::vector<Node *>& useless2, std::set<Node *>& allNodes) const;
private:
+ std::list< AbstractPoint * > analyzeParallelism() const;
static void findUselessLinksIn(const std::list< std::vector<Node *> >& res , LinkInfo& info);
template<bool direction>
static unsigned appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder);
#include "BlocPoint.hxx"
#include "Node.hxx"
+#include <algorithm>
+
using namespace YACS::ENGINE;
BlocPoint::BlocPoint(const std::list<AbstractPoint *>& nodes, AbstractPoint *father):AbstractPoint(father),_nodes(nodes)
(*it)->setFather(this);
}
+void BlocPoint::getOutPoint(AbstractPoint *node)
+{
+ std::list<AbstractPoint *>::iterator it(std::find(_nodes.begin(),_nodes.end(),node));
+ if(it==_nodes.end())
+ throw YACS::Exception("BlocPoint::getOutPoint : node not in this !");
+ _nodes.erase(it);
+ node->setFather(NULL);
+}
+
AbstractPoint *BlocPoint::findPointWithNode(Node *node)
{
for(std::list<AbstractPoint *>::iterator it=_nodes.begin();it!=_nodes.end();it++)
int getNumberOfNodes() const;
const std::list<AbstractPoint *>& getListOfPoints() const { return _nodes; }
virtual ~BlocPoint();
+ protected:
+ void getOutPoint(AbstractPoint *node);
};
}
}
--- /dev/null
+// 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
+// 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 "Bloc.hxx"
+#include "Proc.hxx"
+#include "Visitor.hxx"
+#include "ForEachLoop.hxx"
+#include "InlineNode.hxx"
+#include "HomogeneousPoolContainer.hxx"
+
+using namespace YACS::ENGINE;
+
+void Bloc::fitToPlayGround(const PlayGround *pg)
+{
+ static const char MSG[]="Bloc::fitToPlayGround : Not implemented yet for this type of node !";
+ class MyVisitor : public Visitor
+ {
+ public:
+ MyVisitor(ComposedNode *root):Visitor(root),_lev(0),_max_lev(0) { }
+ void visitBloc(Bloc *node) { node->ComposedNode::accept(this); }
+ void visitElementaryNode(ElementaryNode *node) { }
+ void visitForEachLoop(ForEachLoop *node)
+ {
+ _max_lev=std::max(_max_lev,_lev);
+ {
+ _lev++;
+ node->ComposedNode::accept(this);
+ _lev--;
+ }
+ node->edGetNbOfBranchesPort()->edInit(1);
+ if(_lev==_max_lev)
+ {
+ _fes.push_back(node);// locate all leaves ForEach
+ }
+ if(_lev==0)
+ _max_lev=0;
+ }
+ void visitOptimizerLoop(OptimizerLoop *node) { throw YACS::Exception(MSG); }
+ void visitDynParaLoop(DynParaLoop *node) { throw YACS::Exception(MSG); }
+ void visitForLoop(ForLoop *node) { throw YACS::Exception(MSG); }
+ void visitInlineNode(InlineNode *node)
+ {
+ Container *cont(node->getContainer());
+ HomogeneousPoolContainer *cont2(dynamic_cast<HomogeneousPoolContainer *>(cont));
+ if(!cont2)
+ return ;
+ _cont.push_back(cont2);
+ HomogeneousPoolContainer *cont3(cont2->getDirectFather());
+ if(cont3)
+ _cont2.insert(cont3);
+ }
+ void visitInlineFuncNode(InlineFuncNode *node) { throw YACS::Exception(MSG); }
+ void visitLoop(Loop *node) { throw YACS::Exception(MSG); }
+ void visitProc(Proc *node) { node->ComposedNode::accept(this); }
+ void visitServiceNode(ServiceNode *node) { throw YACS::Exception(MSG); }
+ void visitServerNode(ServerNode *node) { throw YACS::Exception(MSG); }
+ void visitServiceInlineNode(ServiceInlineNode *node) { throw YACS::Exception(MSG); }
+ void visitSwitch(Switch *node) { throw YACS::Exception(MSG); }
+ void visitWhileLoop(WhileLoop *node) { throw YACS::Exception(MSG); }
+ void visitPresetNode(DataNode *node) { throw YACS::Exception(MSG); }
+ void visitOutNode(DataNode *node) { throw YACS::Exception(MSG); }
+ void visitStudyInNode(DataNode *node) { throw YACS::Exception(MSG); }
+ void visitStudyOutNode(DataNode *node) { throw YACS::Exception(MSG); }
+ public:
+ std::list<ForEachLoop *> _fes;
+ std::list< HomogeneousPoolContainer *> _cont;
+ std::set< HomogeneousPoolContainer * > _cont2;
+ int _lev;
+ int _max_lev;
+ };
+ YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg,1));
+ std::map<ComposedNode *,YACS::BASES::AutoRefCnt<PartDefinition> > zeMap;
+ this->partitionRegardingDPL(pd,zeMap);
+ MyVisitor vis(this);
+ this->accept(&vis);
+ for(std::list<ForEachLoop *>::const_iterator it=vis._fes.begin();it!=vis._fes.end();it++)
+ {
+ std::map<ComposedNode *,YACS::BASES::AutoRefCnt<PartDefinition> >::iterator it2(zeMap.find(*it));
+ if(it2==zeMap.end())
+ throw YACS::Exception("Bloc::fitToPlayGround : internal error !");
+ int maxLev((*it)->getExecNode()->getMaxLevelOfParallelism());
+ int a((*it2).second->getNumberOfCoresConsumed());
+ int res(a/maxLev);
+ if(a%maxLev!=0)
+ res++;
+ (*it)->edGetNbOfBranchesPort()->edInit(res);
+ }
+ for(std::set< HomogeneousPoolContainer * >::const_iterator it=vis._cont2.begin();it!=vis._cont2.end();it++)
+ (*it)->setSizeOfPool(pg->getNumberOfWorkers((*it)->getNumberOfCoresPerWorker()));
+ for(std::list< HomogeneousPoolContainer *>::const_iterator it=vis._cont.begin();it!=vis._cont.end();it++)
+ (*it)->prepareMaskForExecution();
+}
LinkedBlocPoint.hxx
ElementaryPoint.hxx
SetOfPoints.hxx
+ PlayGround.hxx
)
# --- sources ---
ServiceInlineNode.cxx
StaticDefinedComposedNode.cxx
Bloc.cxx
+ Bloc_impl.cxx
Proc.cxx
Loop.cxx
ForLoop.cxx
LinkedBlocPoint.cxx
ElementaryPoint.cxx
SetOfPoints.cxx
+ PlayGround.cxx
)
SET(YACSlibEngine_HEADERS ${YACSlibEngine_HEADERS} PARENT_SCOPE) # Make it visible to src/engine_swig to handle dependencies
* 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
+ YACS::Event event, //* I : event emitted
const Executor *execInst
)
{
* Called by ComposedNode::notifyFrom
*/
YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event
- YACS::Event event, //* I : event emitted
+ YACS::Event event, //* I : event emitted
const Executor *execInst
)
{
virtual std::map<std::string,std::string> getProperties() const = 0;
virtual std::map<std::string,std::string> getResourceProperties(const std::string& name) const = 0;
virtual void setProperties(const std::map<std::string,std::string>& properties);
- std::string getName() const { return _name; }
+ virtual std::string getName() const { return _name; }
//! \b WARNING ! name is used in edition to identify different containers, it is not the runtime name of the container
void setName(std::string name) { _name = name; }
void setProc(Proc* proc) { _proc = proc; }
void Dispatcher::dispatch(Node* object, const std::string& event)
{
DEBTRACE("Dispatcher::dispatch " << event );
- typedef std::set<Observer*>::iterator jt;
std::pair<Node*,std::string> key(object,event);
- if(_observers.count(key) != 0)
+ std::map< std::pair<Node*,std::string> , std::set<Observer*> >::const_iterator it(_observers.find(key));
+ if(it!=_observers.end())
{
- for(jt iter=_observers[key].begin();iter!=_observers[key].end();iter++)
+ for(std::set<Observer*>::const_iterator iter=(*it).second.begin();iter!=(*it).second.end();iter++)
{
(*iter)->notifyObserver(object,event);
}
void Dispatcher::dispatch2(Node* object,const std::string& event, void *something)
{
- typedef std::set<Observer*>::iterator jt;
std::pair<Node*,std::string> key(object,event);
- if(_observers.count(key) != 0)
+ std::map< std::pair<Node*,std::string> , std::set<Observer*> >::const_iterator it(_observers.find(key));
+ if(it!=_observers.end())
{
- for(jt iter=_observers[key].begin();iter!=_observers[key].end();iter++)
+ for(std::set<Observer*>::const_iterator iter=(*it).second.begin();iter!=(*it).second.end();iter++)
{
(*iter)->notifyObserver2(object,event,something);
}
virtual ~Dispatcher();
protected:
std::map< std::pair<Node*,std::string> , std::set<Observer*> > _observers;
- std::map< std::pair<Executor*,std::string> , std::set<Observer*> > _observExec;
static Dispatcher* _singleton;
};
DynParaLoop::DynParaLoop(const std::string& name, TypeCode *typeOfDataSplitted)
: ComposedNode(name),_node(0),_initNode(0),_finalizeNode(0),_nbOfEltConsumed(0),
_nbOfBranches(NAME_OF_NUMBER_OF_BRANCHES,this,Runtime::_tc_int),
- _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0)
+ _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(1.)
{
}
DynParaLoop::DynParaLoop(const DynParaLoop& other, ComposedNode *father, bool editionOnly)
: ComposedNode(other,father), _nbOfBranches(other._nbOfBranches,this),
_splittedPort(other._splittedPort,this), _node(0), _initNode(0), _finalizeNode(0),
- _nbOfEltConsumed(0),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0)
+ _nbOfEltConsumed(0),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(1.)
{
if(other._node)
_node=other._node->clone(this,editionOnly);
return FINALIZE_NODE;
}
+void DynParaLoop::setWeight(double newVal)
+{
+ if(newVal<=0.)
+ throw Exception("DynParaLoop::setWeight : invalid input value !");
+ _weight=newVal;
+}
+
bool DynParaLoop::isMultiplicitySpecified(unsigned& value) const
{
if(_nbOfBranches.edIsManuallyInitialized())
return _nbOfBranches.getIntValue() * _node->getMaxLevelOfParallelism();
}
+void DynParaLoop::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
+{
+ YACS::BASES::AutoRefCnt<PartDefinition> pd2(pd->copy());
+ zeMap[this]=pd2;
+ if(_node)
+ _node->partitionRegardingDPL(pd,zeMap);
+}
+
void DynParaLoop::shutdown(int level)
{
if(level==0)return;
int _initializingCounter;
int _unfinishedCounter;
int _failedCounter;
+ double _weight;
protected:
static const char NAME_OF_SPLITTED_SEQ_OUT[];
static const char OLD_NAME_OF_SPLITTED_SEQ_OUT[];
Node *getChildByShortName(const std::string& name) const throw(Exception);
Node *getChildByNameExec(const std::string& name, unsigned id) const throw(Exception);
std::vector<Node *> getNodes() const { return _execNodes; } // need to use in GUI part for adding observers for clone nodes
+ double getWeight() const { return _weight; }
+ void setWeight(double newVal);
+ double getWeightRegardingDPL() const { return getWeight(); }
bool isMultiplicitySpecified(unsigned& value) const;
void forceMultiplicity(unsigned value);
virtual void checkBasicConsistency() const throw(Exception);
Node * getExecNode();
Node * getFinalizeNode();
int getMaxLevelOfParallelism() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
protected:
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);
virtual void ensureLoading();
int getMaxLevelOfParallelism() const { return 1; }
-
+ double getWeightRegardingDPL() const { return 0.; }
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) { }
+
//run part
void begin();
bool isReady();
return _node->getMaxLevelOfParallelism();
}
+double ElementaryPoint::getWeightRegardingDPL() const
+{
+ return _node->getWeightRegardingDPL();
+}
+
+void ElementaryPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
+{
+ _node->partitionRegardingDPL(pd,zeMap);
+}
+
std::string ElementaryPoint::getRepr() const
{
return _node->getName();
Node *getLastNode();
int getNumberOfNodes() const;
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
std::string getRepr() const;
virtual ~ElementaryPoint();
};
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);
}
}
+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++)
{
unsigned int id;
DynParaLoop::TypeOfNode ton(getIdentityOfNotifyerNode(node,id));
+ // TODO: deal with keepgoing without the dependency to Executor
if(ton!=WORK_NODE || !execInst->getKeepGoingProperty())
return DynParaLoop::updateStateOnFailedEventFrom(node,execInst);
else
}
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;
+}
{
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,
return ret;
}
+double ForkBlocPoint::getWeightRegardingDPL() const
+{
+ double ret(0.);
+ for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++)
+ ret+=(*it)->getWeightRegardingDPL();
+ return ret;
+}
+
+void ForkBlocPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
+{
+ std::vector< std::pair<const PartDefinition *,double> > parts,parts2;
+ std::vector<std::size_t> v,v2;
+ std::size_t ii(0);
+ for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++,ii++)
+ {
+ double w((*it)->getWeightRegardingDPL());
+ if(w!=0.)
+ {
+ parts.push_back(std::pair<const PartDefinition *,double >(pd,w));
+ v.push_back(ii);
+ }
+ else
+ {
+ parts2.push_back(std::pair<const PartDefinition *,double >(pd,1.));
+ v2.push_back(ii);
+ }
+ }
+ std::vector<AbstractPoint *> nodes2(_nodes.begin(),_nodes.end());
+ if(!parts.empty())
+ {
+ const PlayGround *pg(pd->getPlayGround());
+ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > pds(pg->partition(parts));
+ ii=0;
+ for(std::vector<std::size_t>::const_iterator iter=v.begin();iter!=v.end();iter++,ii++)
+ nodes2[*iter]->partitionRegardingDPL(pds[ii],zeMap);
+ }
+ if(!parts2.empty())
+ {
+ const PlayGround *pg(pd->getPlayGround());
+ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > pds(pg->partition(parts2));
+ ii=0;
+ for(std::vector<std::size_t>::const_iterator iter=v2.begin();iter!=v2.end();iter++,ii++)
+ nodes2[*iter]->partitionRegardingDPL(pds[ii],zeMap);
+ }
+}
+
std::string ForkBlocPoint::getRepr() const
{
std::size_t sz(_nodes.size()),ii(0);
Node *getFirstNode();
Node *getLastNode();
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
std::string getRepr() const;
virtual ~ForkBlocPoint();
};
#include "YACSlibEngineExport.hxx"
#include "Exception.hxx"
#include "Container.hxx"
+#include "PlayGround.hxx"
#include <vector>
{
namespace ENGINE
{
+ class ForTestOmlyHPContCls;
+
/*!
* This is an abstract class, that represents a set of fixed number of worker "kernelcontainers" homegenous in the sense that can be used indifferently each other.
* But each of those worker pool can be used once at a time.
virtual std::size_t getNumberOfFreePlace() const = 0;
virtual void allocateFor(const std::vector<const Task *>& nodes) = 0;
virtual void release(const Task *node) = 0;
+ virtual YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> decorate(YACS::BASES::AutoConstRefCnt<PartDefinition> pd) = 0;
+ virtual HomogeneousPoolContainer *getDirectFather() = 0;
+ virtual const HomogeneousPoolContainer *getDirectFather() const = 0;
+ virtual int getNumberOfCoresPerWorker() const = 0;
+ virtual void prepareMaskForExecution() const = 0;
+ virtual void forYourTestsOnly(ForTestOmlyHPContCls *data) const = 0;
static const char SIZE_OF_POOL_KEY[];
static const char INITIALIZE_SCRIPT_KEY[];
protected:
#include "InlineNode.hxx"
#include "Visitor.hxx"
#include "Container.hxx"
+#include "HomogeneousPoolContainer.hxx"
#include <iostream>
#define _DEVDEBUG_
return ret;
}
+void InlineNode::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
+{
+ if(!isDeployable())
+ return ;
+ if(!_container)
+ return ;
+ HomogeneousPoolContainer *contC(dynamic_cast<HomogeneousPoolContainer *>(_container));
+ if(!contC)
+ return ;
+ YACS::BASES::AutoConstRefCnt<PartDefinition> zePd;
+ zePd.takeRef(pd);
+ YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> zeCont(contC->decorate(zePd));
+ setContainer(zeCont);
+}
void performShallowDuplicationOfPlacement(const Node& other);
bool isDeployable() const;
int getMaxLevelOfParallelism() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
public:
static const char LOCAL_STR[];
static const char REMOTE_STR[];
return ret;
}
+double LinkedBlocPoint::getWeightRegardingDPL() const
+{
+ double ret(0.);
+ for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++)
+ ret=std::max(ret,(*it)->getWeightRegardingDPL());
+ return ret;
+}
+
+void LinkedBlocPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
+{
+ for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++)
+ (*it)->partitionRegardingDPL(pd,zeMap);
+}
+
std::string LinkedBlocPoint::getRepr() const
{
std::size_t sz(_nodes.size()),ii(0);
Node *getFirstNode();
Node *getLastNode();
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
std::string getRepr() const;
virtual ~LinkedBlocPoint();
};
return _node->getMaxLevelOfParallelism();
}
+double Loop::getWeightRegardingDPL() const
+{
+ if(!_node)
+ return 0.;
+ return _node->getWeightRegardingDPL();
+}
+
+void Loop::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
+{
+ if(_node)
+ _node->partitionRegardingDPL(pd,zeMap);
+}
+
Node *Loop::getChildByShortName(const std::string& name) const throw(YACS::Exception)
{
if (_node)
std::list<InputPort *> getSetOfInputPort() const;
int getNumberOfInputPorts() const;
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
Node *getChildByShortName(const std::string& name) const throw(Exception);
static TypeCode* MappingDF2DS(TypeCode* type) throw(Exception);
static TypeCode* MappingDS2DF(TypeCode* type) throw(Exception);
return _father->getProc();
}
+DynParaLoop *Node::getClosestDPLAmongAncestors() const
+{
+ if(!_father)
+ return NULL;
+ ComposedNode *iter(_father);
+ do
+ {
+ DynParaLoop *iter2(dynamic_cast<DynParaLoop *>(iter));
+ if(iter2)
+ return iter2;
+ iter=iter->_father;
+ }
+ while(iter);
+ return NULL;
+}
+
ComposedNode *Node::getRootNode() const throw(YACS::Exception)
{
if(!_father)
#define __NODE_HXX__
#include "YACSlibEngineExport.hxx"
+#include "PlayGround.hxx"
+#include "AutoRefCnt.hxx"
#include "InGate.hxx"
#include "OutGate.hxx"
#include "Exception.hxx"
class InputPort;
class OutputPort;
class InPropertyPort;
- class DynParaLoop;
class ForEachLoop;
+ class DynParaLoop;
class ComposedNode;
class Proc;
class ElementaryNode;
bool operator>(const Node& other) const;
bool operator<(const Node& other) const;
std::string getImplementation() const;
+ DynParaLoop *getClosestDPLAmongAncestors() const;
virtual ComposedNode *getRootNode() const throw(Exception);
virtual void setProperty(const std::string& name,const std::string& value);
virtual std::string getProperty(const std::string& name);
virtual const Proc *getProc() const;
virtual void accept(Visitor *visitor) = 0;
virtual int getMaxLevelOfParallelism() const = 0;
+ virtual double getWeightRegardingDPL() const = 0;
+ virtual void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) = 0;
std::string getQualifiedName() const;
int getNumId();
std::vector<std::pair<std::string,int> > getDPLScopeInfo(ComposedNode *gfn);
virtual void checkConsistency(LinkInfo& info) const;
virtual int edGetNumberOfOutLinks() const;
virtual std::set<InPort *> edSetInPort() const = 0;
- virtual bool isAlreadyLinkedWith(InPort *with) const = 0;
+ virtual bool isAlreadyLinkedWith(InPort *withp) const = 0;
virtual void getAllRepresented(std::set<OutPort *>& represented) const;
virtual bool addInPort(InPort *inPort) throw(Exception) = 0;
virtual int removeInPort(InPort *inPort, bool forward) throw(Exception) = 0;
virtual ~OutputDataStreamPort();
virtual OutputDataStreamPort *clone(Node *newHelder) const;
std::set<InPort *> edSetInPort() const;
- bool isAlreadyLinkedWith(InPort *with) const;
+ bool isAlreadyLinkedWith(InPort *withp) const;
virtual std::string getNameOfTypeOfCurrentInstance() const;
virtual bool addInPort(InPort *inPort) throw(Exception);
virtual bool edAddInputDataStreamPort(InputDataStreamPort *port) throw(ConversionException);
public:
virtual ~OutputPort();
std::set<InPort *> edSetInPort() const;
- bool isAlreadyLinkedWith(InPort *with) const;
+ bool isAlreadyLinkedWith(InPort *withp) const;
bool isAlreadyInSet(InputPort *inputPort) const;
bool isConnected() const;
std::string getNameOfTypeOfCurrentInstance() const;
--- /dev/null
+// Copyright (C) 2006-2017 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 "PlayGround.hxx"
+#include "Runtime.hxx"
+
+#include <set>
+#include <map>
+#include <sstream>
+#include <iomanip>
+#include <numeric>
+#include <algorithm>
+
+using namespace YACS::ENGINE;
+
+std::string PlayGround::printSelf() const
+{
+ std::ostringstream oss;
+ std::size_t sz(0);
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ sz=std::max(sz,(*it).first.length());
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ {
+ oss << " - " << std::setw(10) << (*it).first << " : " << (*it).second << std::endl;
+ }
+ return oss.str();
+}
+
+void PlayGround::loadFromKernelCatalog()
+{
+ Runtime *r(getRuntime());
+ if(!r)
+ throw Exception("PlayGround::loadFromKernelCatalog : no runtime !");
+ std::vector< std::pair<std::string,int> > data(r->getCatalogOfComputeNodes());
+ setData(data);
+}
+
+void PlayGround::setData(const std::vector< std::pair<std::string,int> >& defOfRes)
+{
+ _data=defOfRes;
+ checkCoherentInfo();
+}
+
+int PlayGround::getNumberOfCoresAvailable() const
+{
+ int ret(0);
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ ret+=(*it).second;
+ return ret;
+}
+
+int PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const
+{
+ if(nbCoresPerCont<1)
+ throw Exception("PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap : invalid nbCoresPerCont. Must be >=1 !");
+ int ret(0);
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ ret+=(*it).second/nbCoresPerCont;
+ return ret;
+}
+
+std::vector<int> PlayGround::computeOffsets() const
+{
+ std::size_t sz(_data.size()),i(0);
+ std::vector<int> ret(sz+1); ret[0]=0;
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++,i++)
+ ret[i+1]=ret[i]+(*it).second;
+ return ret;
+}
+
+void PlayGround::checkCoherentInfo() const
+{
+ std::set<std::string> s;
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ {
+ s.insert((*it).first);
+ if((*it).second<0)
+ throw Exception("Presence of negative int value !");
+ }
+ if(s.size()!=_data.size())
+ throw Exception("host names entries must be different each other !");
+}
+
+std::vector<bool> PlayGround::FromUItoVB(unsigned int sz, unsigned int v)
+{
+ std::vector<bool> ret(sz);
+ unsigned int p(1);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ ret[i]=p&v;
+ p<<=1;
+ }
+ return ret;
+}
+
+unsigned int PlayGround::FromVBtoUI(const std::vector<bool>& v)
+{
+ std::size_t sz(v.size());
+ unsigned int ret(0);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ if(v[i])
+ ret+=1u<<i;
+ }
+ return ret;
+}
+
+std::vector<int> PlayGround::GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat)
+{
+ std::vector<int> ret;
+ std::size_t szp(pat.size());
+ std::size_t sz(bigArr.size()/szp);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ std::vector<bool> t(bigArr.begin()+i*szp,bigArr.begin()+(i+1)*szp);
+ if(t==pat)
+ ret.push_back(i);
+ }
+ return ret;
+}
+
+std::vector<int> PlayGround::BuildVectOfIdsFromVecBool(const std::vector<bool>& v)
+{
+ std::size_t sz(std::count(v.begin(),v.end(),true)),i(0);
+ std::vector<int> ret(sz);
+ std::vector<bool>::const_iterator it(v.begin());
+ while(i<sz)
+ {
+ it=std::find(it,v.end(),true);
+ ret[i++]=std::distance(v.begin(),it);
+ it++;
+ }
+ return ret;
+}
+
+void PlayGround::highlightOnIds(const std::vector<int>& coreIds, std::vector<bool>& v) const
+{
+ if(v.size()!=getNumberOfCoresAvailable())
+ throw Exception("PlayGround::highlightOnIds : oops ! invalid size !");
+ for(std::vector<int>::const_iterator it=coreIds.begin();it!=coreIds.end();it++)
+ v[*it]=true;
+}
+
+/*!
+ * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
+ */
+std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
+{
+ int nbCores(getNumberOfCoresAvailable());
+ std::vector<bool> ret(nbCores,false);
+ if(nbCoresPerWorker==1)
+ std::fill(ret.begin(),ret.end(),true);
+ else
+ {
+ std::size_t posBg(0);
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ {
+ int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
+ std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
+ posBg+=(*it).second;
+ }
+ }
+ return ret;
+}
+/*!
+ * follow getMaxNumberOfContainersCanBeHostedWithoutOverlap method
+ */
+std::vector<std::size_t> PlayGround::getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector<bool>& coreFlags) const
+{
+ std::size_t posBg(0),posWorker(0);
+ std::vector<std::size_t> ret;
+ for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+ {
+ int nbWorker((*it).second/nbCoresPerComp);
+ for(int j=0;j<nbWorker;j++,posWorker++)
+ {
+ std::vector<bool>::const_iterator it2(std::find(coreFlags.begin()+posBg+j*nbCoresPerComp,coreFlags.begin()+posBg+(j+1)*nbCoresPerComp,false));
+ if(it2==coreFlags.begin()+posBg+(j+1)*nbCoresPerComp)
+ ret.push_back(posWorker);
+ }
+ posBg+=(*it).second;
+ }
+ return ret;
+}
+
+std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *,double> >& parts) const
+{
+ std::size_t sz(parts.size()),szs(getNumberOfCoresAvailable());
+ if(sz==0)
+ return std::vector< YACS::BASES::AutoRefCnt<PartDefinition> >();
+ if(sz==1)
+ {
+ const PartDefinition *pd(parts[0].first);
+ if(!pd)
+ throw Exception("Presence of null pointer as part def 0 !");
+ YACS::BASES::AutoRefCnt<PartDefinition> ret(pd->copy());
+ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret2(1,ret);
+ return ret2;
+ }
+ if(sz>31)
+ throw Exception("PlayGround::partition : not implemented yet for more than 31 ! You need to pay for it :)");
+ std::vector<bool> zeArr(szs*sz,false);
+ std::size_t i(0);
+ for(std::vector< std::pair<const PartDefinition *,double> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
+ {
+ const PartDefinition *pd((*it).first);
+ if(!pd)
+ throw Exception("Presence of null pointer as part def !");
+ if(pd->getPlayGround()!=this)
+ throw Exception("Presence of non homogeneous playground !");
+ if((*it).second<=0.)
+ throw Exception("Invalid weight !");
+ std::vector<bool> bs(pd->getCoresOn());
+ for(std::size_t j=0;j<szs;j++)
+ zeArr[j*sz+i]=bs[j];
+ }
+ std::set<unsigned int> ss;
+ for(std::size_t i=0;i<szs;i++)
+ {
+ std::vector<bool> vb(zeArr.begin()+i*sz,zeArr.begin()+(i+1)*sz);
+ ss.insert(FromVBtoUI(vb));
+ }
+ std::vector< std::vector<int> > retIds(sz);
+ for(std::set<unsigned int>::const_iterator i=ss.begin();i!=ss.end();i++)
+ {
+ std::vector<bool> code(FromUItoVB(sz,*i));// for this configuration which parts are considered
+ std::vector<int> locIds(GetIdsMatching(zeArr,code));
+ std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));
+ if(partsIds.empty())
+ continue;
+ std::vector<double> wg;
+ std::vector<int> nbCores2;
+ for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++)
+ {
+ wg.push_back(parts[*it].second);
+ nbCores2.push_back(parts[*it].first->getNbCoresPerCompo());
+ }
+ std::vector< std::vector<int> > ress(splitIntoParts(locIds,nbCores2,wg));
+ std::size_t k(0);
+ for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++,k++)
+ {
+ retIds[*it].insert(retIds[*it].end(),ress[k].begin(),ress[k].end());
+ }
+ }
+ //
+ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ std::set<int> s(retIds[i].begin(),retIds[i].end());
+ std::vector<int> v(s.begin(),s.end());
+ ret[i]=PartDefinition::BuildFrom(this,(parts[i].first)->getNbCoresPerCompo(),v);
+ }
+ return ret;
+}
+
+std::vector<int> sortArr(const std::vector<int>& v)
+{
+ std::multimap<int,int> m;
+ int i(v.size()-1);
+ for(std::vector<int>::const_reverse_iterator it=v.rbegin();it!=v.rend();it++)
+ m.insert(std::pair<int,int>(*it,i--));
+ std::vector<int> ret(m.size());
+ i=0;
+ for(std::multimap<int,int>::const_reverse_iterator it=m.rbegin();it!=m.rend();it++)// reverse -> sort from biggest to the finest
+ ret[i++]=(*it).second;
+ return ret;
+}
+
+std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector<int>& nbCoresConso, const std::vector<double>& weights) const
+{
+ double wgs(std::accumulate(weights.begin(),weights.end(),0.));
+ std::size_t sz(nbCoresConso.size());
+ if(sz!=weights.size())
+ throw Exception("PlayGround::splitIntoParts : internal error !");
+ if(sz==0)
+ return std::vector< std::vector<int> >();
+ int totalSpace(coreIds.size());
+ std::vector< std::vector<int> > ret(sz);
+ std::vector<int> fromBigToTiny(sortArr(nbCoresConso));// start to treat the coarse grain to finish with fine grain
+ std::vector<bool> zeArr(getNumberOfCoresAvailable(),false);
+ highlightOnIds(coreIds,zeArr);
+ int nbOfCoresToSplit(coreIds.size());
+ std::size_t ii(fromBigToTiny.size());
+ for(std::vector<int>::const_iterator it=fromBigToTiny.begin();it!=fromBigToTiny.end();it++,ii--)
+ {
+ int maxNbOfCores((int)(totalSpace*weights[*it]/wgs));// now try to find in zeArr at most maxNbOfCores cores
+ ret[*it]=takePlace(maxNbOfCores,nbCoresConso[*it],zeArr,ii==1);
+ }
+ return ret;
+}
+
+std::vector<int> PlayGround::takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne) const
+{
+ if(maxNbOfCoresToAlloc<1)
+ throw Exception("PlayGround::takePlace : internal error ! no space to alloc !");
+ int tmpMaxNbOfCoresToAlloc(maxNbOfCoresToAlloc);
+ if(lastOne)
+ tmpMaxNbOfCoresToAlloc=std::max(tmpMaxNbOfCoresToAlloc,(int)std::count(distributionOfCores.begin(),distributionOfCores.end(),true));
+ std::vector<int> ret;
+ std::vector<int> offsets(computeOffsets());
+ int nbFullItem(0);
+ std::size_t sz(offsets.size()-1);
+ for(std::size_t i=0;i<sz && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;i++)
+ {
+ int d(offsets[i+1]-offsets[i]);
+ if(nbCoresPerShot>d)
+ continue;
+ std::vector<bool> target(nbCoresPerShot,true);
+ for(int j=0;j<=d-nbCoresPerShot && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;)
+ {
+ std::vector<bool> t(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+nbCoresPerShot);
+ if(t==target)
+ {
+ nbFullItem++;
+ tmpMaxNbOfCoresToAlloc-=nbCoresPerShot;
+ std::fill(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+nbCoresPerShot,false);
+ for(int k=offsets[i]+j;k<offsets[i]+j+nbCoresPerShot;k++)
+ ret.push_back(k);
+ j+=nbCoresPerShot;
+ }
+ else
+ j++;
+ }
+ }
+ if(nbFullItem>0)
+ return ret;
+ if(nbCoresPerShot<=1)
+ throw Exception("PlayGround::takePlace : internal error !");
+ // not enough contiguous place. Find the first wider contiguous place
+ for(int kk=std::min(nbCoresPerShot-1,tmpMaxNbOfCoresToAlloc);kk>=1;kk--)
+ {
+ for(std::size_t i=0;i<sz && tmpMaxNbOfCoresToAlloc>=kk;i++)
+ {
+ int d(offsets[i+1]-offsets[i]);
+ if(kk>d)
+ continue;
+ std::vector<bool> target(kk,true);
+ for(int j=0;j<=d-kk && tmpMaxNbOfCoresToAlloc>=kk;)
+ {
+ std::vector<bool> t(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+kk);
+ if(t==target)
+ {
+ nbFullItem++;
+ tmpMaxNbOfCoresToAlloc-=kk;
+ std::fill(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+kk,false);
+ for(int k=offsets[i]+j;k<offsets[i]+j+kk;k++)
+ ret.push_back(k);
+ return ret;
+ }
+ else
+ j++;
+ }
+ }
+ }
+ throw Exception("PlayGround::takePlace : internal error ! All cores are occupied !");
+}
+
+int PlayGround::fromWorkerIdToResId(int workerId, int nbProcPerNode) const
+{
+ std::size_t sz2(_data.size());
+ std::vector<int> deltas(sz2+1); deltas[0]=0;
+ for(std::size_t i=0;i<sz2;i++)
+ deltas[i+1]=deltas[i]+(_data[i].second)/nbProcPerNode;
+ int zePos(0);
+ while(zePos<sz2 && (workerId<deltas[zePos] || workerId>=deltas[zePos+1]))
+ zePos++;
+ if(zePos==sz2)
+ zePos=workerId%sz2;
+ return zePos;
+}
+
+/*!
+ * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
+ */
+std::string PlayGround::deduceMachineFrom(int workerId, int nbProcPerNode) const
+{
+ int zePos(fromWorkerIdToResId(workerId,nbProcPerNode));
+ return _data[zePos].first;
+}
+
+/*!
+ * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, PlayGround::getFetchedCores and PartDefinition::computeWorkerIdsCovered
+ */
+int PlayGround::getNumberOfWorkers(int nbCoresPerWorker) const
+{
+ return getMaxNumberOfContainersCanBeHostedWithoutOverlap(nbCoresPerWorker);
+}
+
+PlayGround::~PlayGround()
+{
+}
+
+//////////////////////
+
+PartDefinition::PartDefinition(const PlayGround *pg, int nbOfCoresPerComp):_nbOfCoresPerComp(nbOfCoresPerComp)
+{
+ _pg.takeRef(pg);
+}
+
+PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg),_nbOfCoresPerComp(other._nbOfCoresPerComp)
+{
+}
+
+PartDefinition::~PartDefinition()
+{
+}
+
+std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< double >& wgs) const
+{
+ std::size_t sz(wgs.size());
+ std::vector< std::pair<const PartDefinition *,double> > elts(sz);
+ for(std::size_t i=0;i<sz;i++)
+ elts[i]=std::pair<const PartDefinition *,double>(this,wgs[i]);
+ return getPlayGround()->partition(elts);
+}
+
+YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& coreIds)
+{
+ int spaceSz(pg->getNumberOfCoresAvailable()),sz(coreIds.size());
+ if(sz>spaceSz)
+ throw Exception("PartDefinition::BuildFrom : error 1 !");
+ if(sz==0)
+ throw Exception("PartDefinition::BuildFrom : error 2 !");
+ int zeStart(coreIds.front()),zeEnd(coreIds.back());
+ if(zeStart<0 || zeEnd<zeStart)
+ throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK !");
+ for(std::size_t i=0;i<sz-1;i++)
+ if(coreIds[i+1]<coreIds[i])
+ throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK 2 !");
+ if(zeEnd-zeStart+1!=sz)
+ {
+ YACS::BASES::AutoRefCnt<PartDefinition> pd(new NonContigPartDefinition(pg,nbOfCoresPerComp,coreIds));
+ return pd;
+ }
+ if(sz==spaceSz)
+ {
+ YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg,nbOfCoresPerComp));
+ return pd;
+ }
+ YACS::BASES::AutoRefCnt<PartDefinition> pd(new ContigPartDefinition(pg,nbOfCoresPerComp,zeStart,zeEnd+1));
+ return pd;
+}
+
+void PartDefinition::stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt<PartDefinition>& pdStashed, YACS::BASES::AutoRefCnt<PartDefinition>& pdRemain) const
+{
+ if(nbCoresStashed<=0)
+ throw Exception("stashPart : Invalid nbCoresStashed value !");
+ if(weightOfRemain<=0.)
+ throw Exception("stashPart : Invalid weight !");
+ std::vector<bool> coresOn(getCoresOn());
+ int nbCoresAvailable(std::count(coresOn.begin(),coresOn.end(),true));
+ std::vector<int> ids(PlayGround::BuildVectOfIdsFromVecBool(coresOn));
+ if(nbCoresAvailable==0)
+ throw Exception("PartDefinition::stashPart : no available cores !");
+ if(nbCoresAvailable<=nbCoresStashed)
+ {
+ int n0((int)(1./(1.+weightOfRemain)*nbCoresAvailable)); n0=std::max(n0,1);
+ int n1(nbCoresAvailable-n0);
+ if(n1<=0)
+ {
+ pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids);
+ pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids);
+ }
+ else
+ {
+ std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
+ pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
+ pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
+ }
+ }
+ else
+ {
+ std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
+ pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
+ pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
+ }
+}
+
+/*!
+ * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
+ */
+std::vector<std::size_t> PartDefinition::computeWorkerIdsCovered(int nbCoresPerComp) const
+{
+ std::vector<bool> coresOn(getCoresOn());
+ return _pg->getWorkerIdsFullyFetchedBy(nbCoresPerComp,coresOn);
+}
+
+//////////////////////
+
+ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop):PartDefinition(pg,nbOfCoresPerComp),_start(zeStart),_stop(zeStop)
+{
+ if(_start<0 || _stop<_start || _stop>getSpaceSize())
+ throw Exception("ContigPartDefinition constructor : Invalid input values");
+}
+
+ContigPartDefinition::ContigPartDefinition(const ContigPartDefinition& other):PartDefinition(other),_start(other._start),_stop(other._stop)
+{
+}
+
+std::string ContigPartDefinition::printSelf() const
+{
+ std::ostringstream oss;
+ oss << "Contiguous : start=" << _start << " stop=" << _stop;
+ return oss.str();
+}
+
+std::vector<bool> ContigPartDefinition::getCoresOn() const
+{
+ std::vector<bool> ret(getSpaceSize(),false);
+ for(int i=_start;i<_stop;i++)
+ ret[i]=true;
+ return ret;
+}
+
+ContigPartDefinition *ContigPartDefinition::copy() const
+{
+ return new ContigPartDefinition(*this);
+}
+
+int ContigPartDefinition::getNumberOfCoresConsumed() const
+{
+ return _stop-_start;
+}
+
+//////////////////////
+
+NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids):PartDefinition(pg,nbOfCoresPerComp),_ids(ids)
+{
+ checkOKIds();
+}
+
+NonContigPartDefinition::NonContigPartDefinition(const ContigPartDefinition& other):PartDefinition(other)
+{
+}
+
+std::string NonContigPartDefinition::printSelf() const
+{
+ std::ostringstream oss;
+ oss << "Non contiguous : ";
+ for(std::vector<int>::const_iterator it=_ids.begin();it!=_ids.end();it++)
+ oss << *it << ", ";
+ return oss.str();
+}
+
+std::vector<bool> NonContigPartDefinition::getCoresOn() const
+{
+ std::vector<bool> ret(getSpaceSize(),false);
+ for(std::vector<int>::const_iterator it=_ids.begin();it!=_ids.end();it++)
+ ret[*it]=true;
+ return ret;
+}
+
+NonContigPartDefinition *NonContigPartDefinition::copy() const
+{
+ return new NonContigPartDefinition(*this);
+}
+
+int NonContigPartDefinition::getNumberOfCoresConsumed() const
+{
+ return _ids.size();
+}
+
+void NonContigPartDefinition::checkOKIds() const
+{
+ int maxVal(getSpaceSize());
+ if(_ids.empty())
+ return;
+ int val(_ids.front());
+ if(val<0 || val>=maxVal)
+ throw Exception("checkOKIds : error 2 !");
+ std::size_t sz(_ids.size());
+ for(std::size_t i=0;i<sz-1;i++)
+ {
+ if(_ids[i+1]<=_ids[i])
+ throw Exception("checkOKIds : error 1 !");
+ if(_ids[i+1]>=maxVal)
+ throw Exception("checkOKIds : error 3 !");
+ }
+}
+
+//////////////////////
+
+AllPartDefinition::AllPartDefinition(const AllPartDefinition& other):PartDefinition(other)
+{
+}
+
+std::string AllPartDefinition::printSelf() const
+{
+ std::ostringstream oss;
+ oss << "All";
+ return oss.str();
+}
+
+std::vector<bool> AllPartDefinition::getCoresOn() const
+{
+ std::vector<bool> ret(getSpaceSize(),true);
+ return ret;
+}
+
+AllPartDefinition *AllPartDefinition::copy() const
+{
+ return new AllPartDefinition(*this);
+}
+
+int AllPartDefinition::getNumberOfCoresConsumed() const
+{
+ return getSpaceSize();
+}
+
+//////////////////////
+
+ std::vector<int> ForTestOmlyHPContCls::getIDS() const
+ {
+ std::size_t sz(_ids.size());
+ std::vector<int> ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ ret[i]=_ids[i];
+ return ret;
+ }
--- /dev/null
+// Copyright (C) 2006-2017 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 __PLAYGROUND_HXX__
+#define __PLAYGROUND_HXX__
+
+#include "YACSlibEngineExport.hxx"
+#include "RefCounter.hxx"
+#include "AutoRefCnt.hxx"
+
+#include <vector>
+#include <string>
+
+namespace YACS
+{
+ namespace ENGINE
+ {
+ class PartDefinition;
+
+ class YACSLIBENGINE_EXPORT PlayGround : public RefCounter
+ {
+ public:
+ PlayGround(const std::vector< std::pair<std::string,int> >& defOfRes):_data(defOfRes) { checkCoherentInfo(); }
+ PlayGround() { }
+ std::string printSelf() const;
+ void loadFromKernelCatalog();
+ std::vector< std::pair<std::string,int> > getData() const { return _data; }
+ void setData(const std::vector< std::pair<std::string,int> >& defOfRes);
+ int getNumberOfCoresAvailable() const;
+ int getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const;
+ std::vector<int> computeOffsets() const;
+ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > partition(const std::vector< std::pair<const PartDefinition *,double> >& parts) const;
+ int fromWorkerIdToResId(int workerId, int nbProcPerNode) const;
+ std::string deduceMachineFrom(int workerId, int nbProcPerNode) const;
+ int getNumberOfWorkers(int nbCoresPerWorker) const;
+ void highlightOnIds(const std::vector<int>& coreIds, std::vector<bool>& v) const;
+ std::vector<bool> getFetchedCores(int nbCoresPerWorker) const;
+ std::vector<std::size_t> getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector<bool>& coreFlags) const;
+ static std::vector<int> BuildVectOfIdsFromVecBool(const std::vector<bool>& v);
+ static std::vector<int> GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat);
+ static std::vector<bool> FromUItoVB(unsigned int sz, unsigned int v);
+ static unsigned int FromVBtoUI(const std::vector<bool>& v);
+ private:
+ std::vector< std::vector<int> > splitIntoParts(const std::vector<int>& coreIds, const std::vector<int>& nbCoresConso, const std::vector<double>& weights) const;
+ std::vector<int> takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne=false) const;
+ private:
+ void checkCoherentInfo() const;
+ private:
+ ~PlayGround();
+ private:
+ std::vector< std::pair<std::string,int> > _data;
+ };
+
+ class YACSLIBENGINE_EXPORT PartDefinition : public RefCounter
+ {
+ protected:
+ PartDefinition(const PlayGround *pg, int nbOfCoresPerComp);
+ PartDefinition(const PartDefinition& other);
+ virtual ~PartDefinition();
+ public:
+ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > partition(const std::vector< double >& wgs) const;
+ static YACS::BASES::AutoRefCnt<PartDefinition> BuildFrom(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& coreIds);
+ const PlayGround *getPlayGround() const { return _pg; }
+ int getNbCoresPerCompo() const { return _nbOfCoresPerComp; }
+ void setNbCoresPerCompo(int newNbCores) { _nbOfCoresPerComp=newNbCores; }
+ int getSpaceSize() const { return _pg->getNumberOfCoresAvailable(); }
+ void stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt<PartDefinition>& pdStashed, YACS::BASES::AutoRefCnt<PartDefinition>& pdRemain) const;
+ std::vector<std::size_t> computeWorkerIdsCovered(int nbCoresPerComp) const;
+ virtual std::string printSelf() const = 0;
+ virtual std::vector<bool> getCoresOn() const = 0;
+ virtual PartDefinition *copy() const = 0;
+ virtual int getNumberOfCoresConsumed() const = 0;
+ private:
+ YACS::BASES::AutoConstRefCnt<PlayGround> _pg;
+ int _nbOfCoresPerComp;
+ };
+
+ class YACSLIBENGINE_EXPORT ContigPartDefinition : public PartDefinition
+ {
+ public:
+ ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop);
+ ContigPartDefinition(const ContigPartDefinition& other);
+ std::string printSelf() const;
+ std::vector<bool> getCoresOn() const;
+ int getStart() const { return _start; }
+ int getStop() const { return _stop; }
+ ContigPartDefinition *copy() const;
+ int getNumberOfCoresConsumed() const;
+ private:
+ ~ContigPartDefinition() { }
+ private:
+ int _start;
+ int _stop;
+ };
+
+ class YACSLIBENGINE_EXPORT NonContigPartDefinition : public PartDefinition
+ {
+ public:
+ NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids);
+ NonContigPartDefinition(const ContigPartDefinition& other);
+ std::string printSelf() const;
+ std::vector<bool> getCoresOn() const;
+ std::vector<int> getIDs() const { return _ids; }
+ NonContigPartDefinition *copy() const;
+ int getNumberOfCoresConsumed() const;
+ private:
+ void checkOKIds() const;
+ ~NonContigPartDefinition() { }
+ private:
+ std::vector<int> _ids;
+ };
+
+ class AllPartDefinition : public PartDefinition
+ {
+ public:
+ AllPartDefinition(const PlayGround *pg, int nbOfCoresPerComp):PartDefinition(pg,nbOfCoresPerComp) { }
+ AllPartDefinition(const AllPartDefinition& other);
+ std::string printSelf() const;
+ std::vector<bool> getCoresOn() const;
+ AllPartDefinition *copy() const;
+ int getNumberOfCoresConsumed() const;
+ private:
+ ~AllPartDefinition() { }
+ };
+
+ class ForTestOmlyHPContCls
+ {
+ public:
+
+#ifndef SWIG
+ void setContainerType(const std::string& ct) { _container_type=ct; }
+ void setPD(YACS::BASES::AutoConstRefCnt<PartDefinition> pd) { _pd=pd; }
+ void setIDS(const std::vector<std::size_t>& ids) { _ids=ids; }
+#endif
+ std::string getContainerType() const { return _container_type; }
+ const PartDefinition *getPD() const { return _pd; }
+ std::vector<int> getIDS() const;
+ private:
+ std::string _container_type;
+ YACS::BASES::AutoConstRefCnt<PartDefinition> _pd;
+ std::vector<std::size_t> _ids;
+ };
+ }
+}
+
+#endif
virtual void setEdition(bool edition);
virtual void modified();
virtual void saveSchema(const std::string& xmlSchemaFile);
+ //! deprecated. See VisitorSalomeSaveState and schemaSaveState in order
+ //! to deal with the execution state of ForEachLoop.
virtual void saveState(const std::string& xmlStateFile);
protected:
void removeContainers();
_globalMutexForTS.unLock();
}
-bool RefCounter::decrRef()
+bool RefCounter::decrRef() const
{
_globalMutexForTS.lock();
#ifdef REFCNT
public:
unsigned int getRefCnt() const { return _cnt; }
void incrRef() const;
- bool decrRef();
+ bool decrRef() const;
static unsigned int _totalCnt;
protected:
RefCounter();
public:
virtual void init() { }
virtual void fini() { }
-
+ virtual std::vector< std::pair<std::string,int> > getCatalogOfComputeNodes() const = 0;
virtual Catalog* loadCatalog(const std::string& sourceKind,const std::string& path);
virtual InlineFuncNode* createFuncNode(const std::string& kind,const std::string& name);
virtual InlineNode* createScriptNode(const std::string& kind,const std::string& name);
{
return _bp->getMaxLevelOfParallelism();
}
+
+double SetOfPoints::getWeightRegardingDPL() const
+{
+ return _bp->getWeightRegardingDPL();
+}
+
+void SetOfPoints::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
+{
+ _bp->partitionRegardingDPL(pd,zeMap);
+}
+
+AbstractPoint *SetOfPoints::getUniqueAndReleaseIt() const
+{
+ return _bp->getUniqueAndReleaseIt();
+}
#define __SETOFPOINTS_HXX__
#include "YACSlibEngineExport.hxx"
+#include "PlayGround.hxx"
+#include "AutoRefCnt.hxx"
+#include <map>
#include <list>
#include <string>
class Node;
class BagPoint;
class AbstractPoint;
-
+ class ComposedNode;
+
class YACSLIBENGINE_EXPORT SetOfPoints
{
public:
AbstractPoint *findPointWithNode(Node *node);
const std::list<AbstractPoint *>& getListOfPoints() const;
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
+ AbstractPoint *getUniqueAndReleaseIt() const;
private:
BagPoint *_bp;
};
return ret;
}
+double Switch::getWeightRegardingDPL() const
+{
+ double ret(0);
+ for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
+ ret=std::max(ret,((*it).second)->getWeightRegardingDPL());
+ return ret;
+}
+
+void Switch::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
+{
+ for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
+ (*it).second->partitionRegardingDPL(pd,zeMap);
+}
+
void Switch::edRemoveChild(Node *node) throw(YACS::Exception)
{
map< int , Node * >::iterator iter=_mapOfNode.begin();
private:
int edGetNumberOfOutLinks() const;
std::set<InPort *> edSetInPort() const;
- bool isAlreadyLinkedWith(InPort *with) const;
+ bool isAlreadyLinkedWith(InPort *withp) const;
std::string getNameOfTypeOfCurrentInstance() const;
void edRemoveAllLinksLinkedWithMe() throw(Exception);
TypeOfChannel getTypeOfChannel() const;
void writeDot(std::ostream &os) const;
int getNumberOfInputPorts() const;
int getMaxLevelOfParallelism() const;
+ double getWeightRegardingDPL() const;
+ void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
void edRemoveChild(Node *node) throw(Exception);
std::list<InputPort *> getSetOfInputPort() const;
std::list<InputPort *> getLocalInputPorts() const;
Runtime::_singleton = new RuntimeForEngineIntegrationTest;
}
+std::vector< std::pair<std::string,int> > RuntimeForEngineIntegrationTest::getCatalogOfComputeNodes() const
+{
+ throw Exception("RuntimeForEngineIntegrationTest not implemented !");
+}
+
ElementaryNode* RuntimeForEngineIntegrationTest::createNode(const std::string& implementation, const std::string& name) throw (YACS::Exception)
{
if (implementation == ToyNode::MY_IMPL_NAME)
{
public:
static void setRuntime();
+ std::vector< std::pair<std::string,int> > getCatalogOfComputeNodes() const;
ElementaryNode* createNode(const std::string& implementation, const std::string& name) throw(Exception);
InputPort* createInputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type);
OutputPort* createOutputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type);
Runtime::_singleton = new RuntimeForEngineTest;
}
+std::vector< std::pair<std::string,int> > RuntimeForEngineTest::getCatalogOfComputeNodes() const
+{
+ throw Exception("RuntimeForEngineTest::getCatalogOfComputeNodes : not implemented !");
+}
+
ElementaryNode* RuntimeForEngineTest::createNode(const string& implementation, const string& name) throw(YACS::Exception)
{
return new TestElemNode(name);
{
public:
static void setRuntime();
+ std::vector< std::pair<std::string,int> > getCatalogOfComputeNodes() const;
ElementaryNode* createNode(const std::string& implementation, const std::string& name) throw(Exception);
InputPort* createInputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type);
OutputPort* createOutputPort(const std::string& name, const std::string& impl, Node * node, TypeCode * type);
}
}
+std::string TypeCode::getPrintStr() const
+{
+ return id();
+}
+
//! Check if this TypeCode can be used in place of tc
/*!
* this TypeCode is equivalent to tc if they have the same kind
return KIND_STR_REPR[(int)kind];
}
+const TypeCode *TypeCode::subContentType(int lev) const
+{
+ if(lev<0)
+ throw YACS::Exception("subContentType: Invalid input val !");
+ if(lev==0)
+ return this;
+ const TypeCode *ret(this);
+ for(int i=0;i<lev;i++)
+ {
+ const TypeCode *cand(ret->contentType());
+ if(!cand)
+ throw YACS::Exception("subContentType : Invalid input val 2 !");
+ ret=cand;
+ }
+ return ret;
+}
+
const char * TypeCode::getKindRepr() const
{
return KIND_STR_REPR[(int)_kind];
return _shortName.c_str();
}
+std::string TypeCodeSeq::getPrintStr() const
+{
+ std::ostringstream oss; oss << "seq[" << contentType()->getPrintStr() << "]";
+ return oss.str();
+}
+
const TypeCode * TypeCodeSeq::contentType() const throw(YACS::Exception)
{
return _content;
DynType kind() const;
const char * getKindRepr() const;
-
+ const TypeCode *subContentType(int lev) const;
virtual TypeCode *clone() const;
virtual void putReprAtPlace(char *pt, const char *val, bool deepCpy) const;
virtual void destroyZippedAny(char *data) const;
virtual int isAdaptable(const TypeCode* tc) const;
virtual int isEquivalent(const TypeCode* tc) const;
virtual unsigned getSizeInByteOfAnyReprInSeq() const;
+ virtual std::string getPrintStr() const;
static const char *getKindRepr(DynType kind);
static TypeCode * interfaceTc(const char* id, const char* name);
const char * id() const throw(Exception);
const char * name() const throw(Exception);
const char * shortName() const;
+ virtual std::string getPrintStr() const;
virtual const TypeCode * contentType() const throw(Exception);
virtual int isA(const TypeCode* tc) const ;
_out << " state=\"disabled\"";
if (!nbranch->isEmpty())
_out << " nbranch=\"" << nbranch->getIntValue() << "\"";
+ _out << " weight=\"" << node->getWeight() << "\"";
if (node->edGetSamplePort())
_out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
_out << ">" << endl;
_out << " state=\"disabled\"";
if (!nbranch->isEmpty())
_out << " nbranch=\"" << nbranch->getIntValue() << "\"";
+ _out << " weight=\"" << node->getWeight() << "\"";
_out << " lib=\"" << node->getAlgLib() << "\"";
_out << " entry=\"" << node->getSymbol() << "\"";
_out << ">" << endl;
SET(SWIG_MODULE_pilot_EXTRA_DEPS engtypemaps.i ${SWIGINCLUDES})
SWIG_ADD_MODULE(pilot python pilot.i ExecutorSwig.cxx)
+SWIG_CHECK_GENERATION(pilot)
SET(SWIG_MODULE_pypilot_EXTRA_DEPS pilot.i engtypemaps.i _pilot ${SWIGINCLUDES})
SWIG_ADD_MODULE(pypilot python pypilot.i)
INSTALL(TARGETS ${SWIG_MODULE_pilot_REAL_NAME} ${SWIG_MODULE_pypilot_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON})
SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${SALOME_INSTALL_PYTHON})
+
+### Test
+
+SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
+ADD_TEST(NAME PlayGround0 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/testPlayGround0.py)
+SET_TESTS_PROPERTIES(PlayGround0 PROPERTIES ENVIRONMENT "${tests_env}")
+SET(LOCAL_TEST_DIR ${SALOME_YACS_INSTALL_TEST}/engine_swig)
+SET(LOCAL_TEST_FILES testPlayGround0.py)
+INSTALL(FILES ${LOCAL_TEST_FILES} DESTINATION ${LOCAL_TEST_DIR})
+INSTALL(FILES CTestTestfileInstall.cmake DESTINATION ${LOCAL_TEST_DIR} RENAME CTestTestfile.cmake)
--- /dev/null
+# Copyright (C) 2015-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
+# 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
+#
+
+IF(NOT WIN32)
+ SET(TEST_NAME ${COMPONENT_NAME}_PlayGround0)
+ ADD_TEST(${TEST_NAME} python testPlayGround0.py)
+ SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
+ENDIF()
--- /dev/null
+// 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
+// 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
+//
+
+%template() std::pair< YACS::ENGINE::PartDefinition *, double>;
+%template(vecppdd) std::vector< std::pair< YACS::ENGINE::PartDefinition *, double> >;
+
+%newobject YACS::ENGINE::PlayGround::copy;
+
+%{
+PyObject *convertPartDefinition(YACS::ENGINE::PartDefinition *pd)
+{
+ if(!pd)
+ return SWIG_NewPointerObj(SWIG_as_voidptr(pd),SWIGTYPE_p_YACS__ENGINE__PartDefinition, SWIG_POINTER_OWN | 0 );
+ YACS::ENGINE::ContigPartDefinition *pd1(dynamic_cast<YACS::ENGINE::ContigPartDefinition *>(pd));
+ if(pd1)
+ return SWIG_NewPointerObj(SWIG_as_voidptr(pd1),SWIGTYPE_p_YACS__ENGINE__ContigPartDefinition, SWIG_POINTER_OWN | 0 );
+ YACS::ENGINE::NonContigPartDefinition *pd2(dynamic_cast<YACS::ENGINE::NonContigPartDefinition *>(pd));
+ if(pd2)
+ return SWIG_NewPointerObj(SWIG_as_voidptr(pd2),SWIGTYPE_p_YACS__ENGINE__NonContigPartDefinition, SWIG_POINTER_OWN | 0 );
+ YACS::ENGINE::AllPartDefinition *pd3(dynamic_cast<YACS::ENGINE::AllPartDefinition *>(pd));
+ if(pd3)
+ return SWIG_NewPointerObj(SWIG_as_voidptr(pd3),SWIGTYPE_p_YACS__ENGINE__AllPartDefinition, SWIG_POINTER_OWN | 0 );
+ return SWIG_NewPointerObj(SWIG_as_voidptr(pd),SWIGTYPE_p_YACS__ENGINE__PartDefinition, SWIG_POINTER_OWN | 0 );
+
+}
+%}
+
+%typemap(out) std::vector< YACS::BASES::AutoRefCnt<YACS::ENGINE::PartDefinition> >
+{
+ std::size_t sz($1.size());
+ std::vector< YACS::BASES::AutoRefCnt<YACS::ENGINE::PartDefinition> >::iterator it($1.begin());
+ $result = PyList_New($1.size());
+ for (std::size_t i=0; i<sz; i++,it++)
+ PyList_SetItem($result,i,convertPartDefinition((*it).retn()));
+}
+
+namespace YACS
+{
+ namespace ENGINE
+ {
+ class PartDefinition;
+
+ class PlayGround : public RefCounter
+ {
+ public:
+ PlayGround();
+ void loadFromKernelCatalog();
+ PlayGround(const std::vector< std::pair<std::string,int> >& defOfRes);
+ std::string printSelf() const;
+ std::vector< std::pair<std::string,int> > getData() const;
+ void setData(const std::vector< std::pair<std::string,int> >& defOfRes);
+ int getNumberOfCoresAvailable() const;
+ int getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const;
+ std::string deduceMachineFrom(int workerId, int nbProcPerNode) const;
+ %extend
+ {
+ std::string __str__() const
+ {
+ return self->printSelf();
+ }
+
+ std::vector< YACS::BASES::AutoRefCnt<YACS::ENGINE::PartDefinition> > partition(const std::vector< std::pair< YACS::ENGINE::PartDefinition *,double> >& parts) const
+ {
+ std::size_t sz(parts.size());
+ std::vector< std::pair< const YACS::ENGINE::PartDefinition *,double> > partsCpp(sz);
+ for(std::size_t i=0;i<sz;i++)
+ partsCpp[i]=std::pair<const YACS::ENGINE::PartDefinition *,double >(parts[i].first,parts[i].second);
+ return self->partition(partsCpp);
+ }
+ }
+ private:
+ ~PlayGround();
+ };
+
+ class PartDefinition : public RefCounter
+ {
+ public:
+ virtual PartDefinition *copy() const;
+ virtual std::string printSelf() const;
+ virtual int getNumberOfCoresConsumed() const;
+ protected:
+ PartDefinition();
+ ~PartDefinition();
+ };
+
+ class ContigPartDefinition : public PartDefinition
+ {
+ public:
+ ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop);
+ int getStart() const;
+ int getStop() const;
+ %extend
+ {
+ std::string __str__() const
+ {
+ return self->printSelf();
+ }
+ }
+ private:
+ ~ContigPartDefinition();
+ };
+
+ class NonContigPartDefinition : public PartDefinition
+ {
+ public:
+ NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids);
+ std::vector<int> getIDs() const;
+ %extend
+ {
+ std::string __str__() const
+ {
+ return self->printSelf();
+ }
+ }
+ private:
+ ~NonContigPartDefinition();
+ };
+
+ class AllPartDefinition : public PartDefinition
+ {
+ public:
+ AllPartDefinition(const PlayGround *pg, int nbOfCoresPerComp);
+ %extend
+ {
+ std::string __str__() const
+ {
+ return self->printSelf();
+ }
+ }
+ private:
+ ~AllPartDefinition();
+ };
+
+ class PartDefinition;
+
+ class ForTestOmlyHPContCls
+ {
+ public:
+ std::string getContainerType() const;
+ std::vector<int> getIDS() const;
+ %extend
+ {
+ PyObject *getPD() const
+ {
+ const PartDefinition *ret(self->getPD());
+ if(ret)
+ ret->incrRef();
+ return convertPartDefinition(const_cast<PartDefinition *>(ret));
+ }
+ }
+ };
+ }
+}
#include "DeploymentTree.hxx"
#include "ComponentInstance.hxx"
#include "DataNode.hxx"
-
+#include "PlayGround.hxx"
+
using namespace YACS::ENGINE;
%}
%template() std::pair<std::string, YACS::ENGINE::Container *>;
%template() std::pair<YACS::ENGINE::OutPort *,YACS::ENGINE::InPort *>;
%template() std::pair<YACS::ENGINE::InPort *,YACS::ENGINE::OutPort *>;
+%template() std::pair< std::string, int >;
//%template(TCmap) std::map<std::string, YACS::ENGINE::TypeCode *>;
REFCOUNT_TEMPLATE(TCmap,YACS::ENGINE::TypeCode)
%template(NODEmap) std::map<std::string, YACS::ENGINE::Node *>;
REFCOUNT_TEMPLATE(CONTAINmap,YACS::ENGINE::Container)
%template(strvec) std::vector<std::string>;
%template(uivec) std::vector<unsigned int>;
+%template(ivec) std::vector<int>;
%template(linksvec) std::vector< std::pair<YACS::ENGINE::OutPort *,YACS::ENGINE::InPort *> >;
%template(linkvec) std::vector< std::pair<YACS::ENGINE::InPort *,YACS::ENGINE::OutPort *> >;
%template(instreamlist) std::list<YACS::ENGINE::InputDataStreamPort *>;
%template(outstreamlist) std::list<YACS::ENGINE::OutputDataStreamPort *>;
-
+%template(vpsi) std::vector< std::pair< std::string, int > >;
+
%template() std::pair<std::string, YACS::ENGINE::CatalogLoader *>;
%template(loadermap) std::map<std::string,YACS::ENGINE::CatalogLoader *>;
%template() std::pair<std::string, YACS::ENGINE::ComposedNode *>;
// OptimizerAlgASync in module SALOMERuntime
%ignore YACS::ENGINE::OptimizerAlgASync;
%include <OptimizerAlg.hxx>
+%include "PlayGround.i"
%extend YACS::ENGINE::ConditionInputPort
{
--- /dev/null
+# Copyright (C) 2006-2017 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
+#
+
+import pilot
+import unittest
+
+class TestPlayGround0(unittest.TestCase):
+ def test0(self):
+ pg=pilot.PlayGround([("a0",28),("a1",28),("a2",28)])
+ pd=pilot.ContigPartDefinition(pg,4,0,3*28)
+ res=pg.partition([(pd,1.),(pd,1.)])
+ assert(len(res)==2)
+ assert(isinstance(res[0],pilot.ContigPartDefinition))
+ assert(isinstance(res[1],pilot.ContigPartDefinition))
+ assert(res[0].getStart()==0 and res[0].getStop()==40)
+ assert(res[1].getStart()==40 and res[1].getStop()==84)
+ assert(sum([elt.getNumberOfCoresConsumed() for elt in res])==pg.getNumberOfCoresAvailable())
+ pd2=pilot.AllPartDefinition(pg,4)
+ assert(pd2.getNumberOfCoresConsumed()==84)
+ res=pg.partition([(pd2,1.),(pd2,1.),(pd2,1.)])
+ assert(len(res)==3)
+ assert(isinstance(res[0],pilot.ContigPartDefinition))
+ assert(isinstance(res[1],pilot.ContigPartDefinition))
+ assert(isinstance(res[2],pilot.ContigPartDefinition))
+ assert(res[0].getStart()==0 and res[0].getStop()==28)
+ assert(res[1].getStart()==28 and res[1].getStop()==56)
+ assert(res[2].getStart()==56 and res[2].getStop()==84)
+ #
+ pg.setData([("a0",2),("a1",8),("a2",8)])
+ res=pg.partition([(pilot.AllPartDefinition(pg,4),1.),(pilot.AllPartDefinition(pg,1),1.)])
+ assert(len(res)==2)
+ assert(isinstance(res[0],pilot.ContigPartDefinition))
+ assert(isinstance(res[1],pilot.NonContigPartDefinition))
+ assert(res[0].getStart()==2 and res[0].getStop()==10)
+ assert(res[1].getIDs()==(0,1,10,11,12,13,14,15,16,17))
+ pass
+
+ def test1(self):
+ """ test focused on complicated cut due to lack of cores"""
+ pg=pilot.PlayGround([("a0",13)])
+ pd=pilot.ContigPartDefinition(pg,4,0,13)
+ res=pg.partition([(pd,1.),(pd,1.)])
+ assert(len(res)==2)
+ assert(isinstance(res[0],pilot.ContigPartDefinition) and isinstance(res[1],pilot.ContigPartDefinition))
+ assert(res[0].getStart()==0 and res[0].getStop()==4)
+ assert(res[1].getStart()==4 and res[1].getStop()==12)# 1 core lost
+ #
+ pg=pilot.PlayGround([("a0",2),("a1",11)])
+ pd=pilot.ContigPartDefinition(pg,4,0,13)
+ res=pg.partition([(pd,1.),(pd,1.)])
+ assert(len(res)==2)
+ assert(isinstance(res[0],pilot.ContigPartDefinition) and isinstance(res[1],pilot.ContigPartDefinition))
+ assert(res[0].getStart()==2 and res[0].getStop()==6)
+ assert(res[1].getStart()==6 and res[1].getStop()==10)# 5 cores lost
+ pass
+
+ pass
+
+if __name__ == '__main__':
+ unittest.main()
throw YACS::Exception("YACSEvalSeqAny::BuildEmptyFromType : Only int and double are actualy managed !");
}
-template<class T>
-std::size_t YACSEvalSeqAnyInternal<T>::size() const
-{
- if(!_arr)
- throw YACS::Exception("YACSEvalSeqAnyDouble<T>::size : empty array !");
- return _arr->size();
-}
-
YACSEvalSeqAnyDouble::YACSEvalSeqAnyDouble(const std::vector<double>& arr):_arr(0)
{
std::vector<double> *zeArr(new std::vector<double>(arr));
YACSEvalSeqAnyInternal<int> *_arr;
};
+template<class T>
+std::size_t YACSEvalSeqAnyInternal<T>::size() const
+{
+ if(!_arr)
+ throw YACS::Exception("YACSEvalSeqAnyDouble<T>::size : empty array !");
+ return _arr->size();
+}
+
#endif
YACSEvalSession::YACSEvalSession():_isAttached(false),_isLaunched(false),_isForcedPyThreadSaved(false),_port(-1),_salomeInstanceModule(0),_salomeInstance(0),_internal(new YACSEvalSessionInternal)
{
- if(!Py_IsInitialized())
- Py_Initialize();
- //
- {
- YACS::ENGINE::AutoGIL gal;
- _salomeInstanceModule=PyImport_ImportModule(const_cast<char *>("salome_instance"));
- }
+ YACS::ENGINE::AutoGIL gal;
+ _salomeInstanceModule=PyImport_ImportModule(const_cast<char *>("salome_instance"));
}
YACSEvalSession::~YACSEvalSession()
bool YACSEvalSession::isAlreadyPyThreadSaved() const
{
- if(!_isForcedPyThreadSaved)
- return isAttached();
- else
- return true;
+ return _isForcedPyThreadSaved;
}
void YACSEvalSession::checkLaunched() const
class MyAutoThreadSaver
{
public:
- MyAutoThreadSaver(bool isToSave):_isToSave(isToSave),_save(0) { if(_isToSave) _save=PyEval_SaveThread(); }
- ~MyAutoThreadSaver() { if(_isToSave) PyEval_RestoreThread(_save); }
+ MyAutoThreadSaver(bool isToSave):_isToSave(isToSave),_save(0)
+ {
+ if(_isToSave)
+ {
+ PyThreadState *save(PyThreadState_Swap(NULL));// safe call of PyEval_SaveThread()
+ if(save)
+ {
+ _save=save;
+ PyEval_ReleaseLock();
+ }
+ }
+ }
+ ~MyAutoThreadSaver() { if(_isToSave) if(_save) { PyEval_AcquireLock(); PyThreadState_Swap(_save); /*safe call of PyEval_RestoreThread*/ } }
private:
bool _isToSave;
PyThreadState *_save;
SWIG_ADD_MODULE(evalyfx python evalyfx.i)
SWIG_LINK_LIBRARIES(evalyfx ${_link_LIBRARIES})
+SWIG_CHECK_GENERATION(evalyfx)
IF(WIN32)
SET_TARGET_PROPERTIES(_evalyfx PROPERTIES DEBUG_OUTPUT_NAME _evalyfx_d)
ENDIF(WIN32)
#include <iostream>
#include <fstream>
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
#include <fpu_control.h>
#endif
int main(int argc, char* argv[])
{
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
fpu_control_t cw = _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
_FPU_SETCW(cw);
#endif
controller.addListener( &result );
// --- Add a listener that print dots as test run.
-#ifdef WIN32
+#if !defined WIN32 && !defined __APPLE__
CPPUNIT_NS::TextTestProgressListener progress;
#else
CPPUNIT_NS::BriefTestProgressListener progress;
<ul>
$navpath
<li class="footer">
- Copyright © 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE<br>
+ Copyright © 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE<br>
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS<br>
</li>
</ul>
SET_SOURCE_FILES_PROPERTIES(PMMLsalome.i PROPERTIES SWIG_MODULE_NAME PMML)
SWIG_ADD_MODULE(PMML python PMMLsalome.i)
SWIG_LINK_LIBRARIES(PMML ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} pmmlLib)
-
+SWIG_CHECK_GENERATION(PMML)
# _ABR_ Ensure dependency mechanism on all SWIG files and headers
IF(WIN32)
--- /dev/null
+# 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
+# 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_DIRECTORIES(
+ ${PYTHON_INCLUDE_DIR}
+ ${SALOME_INCL_PATH}
+ ${PROJECT_SOURCE_DIR}/src/bases
+ ${PROJECT_SOURCE_DIR}/src/engine
+ ${PROJECT_SOURCE_DIR}/src/runtime
+ ${PROJECT_SOURCE_DIR}
+ )
+
+ADD_DEFINITIONS(
+ ${PYTHON_DEFINITIONS}
+ ${OMNIORB_DEFINITIONS}
+ )
+
+IF(SALOME_BUILD_TESTS)
+ ADD_SUBDIRECTORY(Test)
+ENDIF(SALOME_BUILD_TESTS)
+
+SET(_link_LIBRARIES
+ ${PYTHON_LIBRARIES}
+ YACSRuntimeSALOME
+ )
+
+SET(_py2yacs_sources
+ py2yacs.cxx
+ )
+
+SET(_py2yacs_headers
+ py2yacs.hxx
+ )
+
+ADD_LIBRARY(py2yacslib ${_py2yacs_sources})
+TARGET_LINK_LIBRARIES(py2yacslib ${_link_LIBRARIES})
+
+INSTALL(TARGETS py2yacslib EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
+INSTALL(FILES ${_py2yacs_headers} DESTINATION ${SALOME_INSTALL_HEADERS})
+
+SET( _py_SCRIPTS
+ py2yacs.py
+ )
+
+SALOME_INSTALL_SCRIPTS("${_py_SCRIPTS}" ${SALOME_INSTALL_PYTHON})
--- /dev/null
+# 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
+# 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_DIRECTORIES(
+ ${CPPUNIT_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+SET(_link_LIBRARIES
+ ${CPPUNIT_LIBRARIES}
+ py2yacslib
+)
+
+SET(Py2yacsTest_SOURCES
+ TestPy2yacs.cxx
+ Py2yacsTest.cxx
+ Py2yacsTest.hxx
+)
+
+ADD_EXECUTABLE(TestPy2yacs ${Py2yacsTest_SOURCES})
+TARGET_LINK_LIBRARIES(TestPy2yacs ${_link_LIBRARIES})
+
+ADD_EXECUTABLE(test_py2yacs test_py2yacs.cxx)
+TARGET_LINK_LIBRARIES(test_py2yacs py2yacslib)
+
+# For salome test
+IF(NOT WIN32)
+ ADD_TEST(TestPy2yacs TestPy2yacs)
+ SET_TESTS_PROPERTIES(TestPy2yacs PROPERTIES
+ ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_CURRENT_SOURCE_DIR}/..:$ENV{PYTHONPATH}"
+ )
+
+ SET(LOCAL_TEST_DIR ${SALOME_YACS_INSTALL_TEST}/py2yacs)
+ SET(LOCAL_TEST_FILES
+ bad_parsers.py
+ err_py2yacs_invalid.py
+ )
+ INSTALL(FILES ${LOCAL_TEST_FILES}
+ DESTINATION ${LOCAL_TEST_DIR})
+ INSTALL(FILES CTestTestfileInstall.cmake
+ DESTINATION ${LOCAL_TEST_DIR}
+ RENAME CTestTestfile.cmake)
+ INSTALL(TARGETS TestPy2yacs test_py2yacs
+ DESTINATION ${LOCAL_TEST_DIR})
+
+ENDIF()
\ No newline at end of file
--- /dev/null
+# 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
+# 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
+#
+
+IF(NOT WIN32)
+ SET(TEST_NAME ${COMPONENT_NAME}_Py2YacsTest)
+ # No need of a salome session for this test
+ ADD_TEST(${TEST_NAME} TestPy2yacs)
+ SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES
+ LABELS "${COMPONENT_NAME}"
+ )
+
+ENDIF()
--- /dev/null
+// 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
+// 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 <Python.h>
+#include <fstream>
+#include <string>
+#include <sstream>
+
+#include "Py2yacsTest.hxx"
+#include "py2yacs.hxx"
+#include "Proc.hxx"
+#include "Executor.hxx"
+
+#include "RuntimeSALOME.hxx"
+#include "PythonPorts.hxx"
+#include "InputPort.hxx"
+//#include "parsers.hxx"
+
+void Py2yacsTest::setUp()
+{
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ //YACS::ENGINE::getRuntime()->init();
+}
+
+void Py2yacsTest::tearDown()
+{
+ //YACS::ENGINE::getRuntime()->fini();
+}
+
+static
+void verifyCorrectPycode(const char * code_py, const char * function_name,
+ int nbInputPorts, const char** input_ports,
+ int nbOutputPorts, const char** output_ports)
+{
+ std::cerr << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << code_py << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << "Function :" << function_name << std::endl;
+ Py2yacs parser;
+ try
+ {
+ parser.load(code_py);
+ }
+ catch(Py2yacsException& e)
+ {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch(...)
+ {
+ CPPUNIT_FAIL("Unknown exception");
+ }
+ YACS::ENGINE::Proc* p = parser.createProc(function_name);
+ CPPUNIT_ASSERT( p != NULL);
+ YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
+ CPPUNIT_ASSERT( n != NULL);
+ CPPUNIT_ASSERT( n->getNumberOfInputPorts() == nbInputPorts);
+ for(int i = 0; i < nbInputPorts; i++)
+ CPPUNIT_ASSERT( n->getInputPort(input_ports[i]) != NULL);
+ CPPUNIT_ASSERT( n->getNumberOfOutputPorts() == nbOutputPorts);
+ for(int i = 0; i < nbOutputPorts; i++)
+ CPPUNIT_ASSERT( n->getOutputPort(output_ports[i]) != NULL);
+ delete p;
+}
+
+static
+void verifyWrongPycode(const char* code_py, const char* function_name,
+ const char* error_message)
+{
+ Py2yacs parser;
+ try
+ {
+ parser.load(code_py);
+ YACS::ENGINE::Proc* p = parser.createProc(function_name);
+ CPPUNIT_FAIL("Exception expected and no exception occured.");
+ }
+ catch(Py2yacsException& e)
+ {
+ std::string what = e.what();
+ std::cerr << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << code_py << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << "Function :" << function_name << std::endl;
+ std::cerr << "==========EXCEPTION TEXT=======================" << std::endl;
+ std::cerr << what << std::endl;
+ std::cerr << "===============================================" << std::endl;
+ CPPUNIT_ASSERT(what.find(error_message) != std::string::npos);
+ }
+}
+
+static
+void verifyWrongParser(const char* parser_module, const char* parser_function,
+ const char* error_message)
+{
+ const char* code_py = "def f():\n"
+ " return\n";
+ Py2yacs parser(parser_module, parser_function);
+ try
+ {
+ parser.load(code_py);
+ CPPUNIT_FAIL("Exception expected and no exception occured.");
+ }
+ catch(Py2yacsException& e)
+ {
+ std::string what = e.what();
+ std::cerr << std::endl;
+ std::cerr << "==========EXCEPTION TEXT=======================" << std::endl;
+ std::cerr << what << std::endl;
+ std::cerr << "===============================================" << std::endl;
+ CPPUNIT_ASSERT(what.find(error_message) != std::string::npos);
+ }
+}
+
+void Py2yacsTest::t1()
+{
+ const char * code_py = "def f1(a, b, c):\n"
+ " y = a*b + c\n"
+ " return y\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char* output_ports[] = {"y"};
+ verifyCorrectPycode(code_py, "f1", 3, input_ports, 1, output_ports);
+}
+
+void Py2yacsTest::t2()
+{
+ const char * code_py = "def f1(a, b, c):\n"
+ " x = a + b + c\n"
+ " y = a*b + c\n"
+ " z = a*b*c\n"
+ " return x, y, z\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char* output_ports[] = {"x", "y", "z"};
+ verifyCorrectPycode(code_py, "f1", 3, input_ports, 3, output_ports);
+}
+
+void Py2yacsTest::t3()
+{
+ const char * code_py = "def f1(a, b, c):\n"
+ " print a\n"
+ " print b\n"
+ " print c\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char** output_ports;
+ verifyCorrectPycode(code_py, "f1", 3, input_ports, 0, output_ports);
+}
+
+void Py2yacsTest::t4()
+{
+ const char * code_py = "def f1():\n"
+ " print 'toto'\n"
+ " return\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char** output_ports;
+ verifyCorrectPycode(code_py, "f1", 0, input_ports, 0, output_ports);
+}
+
+void Py2yacsTest::t5()
+{
+ const char * code_py = "def f1(a):\n"
+ " x = -a\n"
+ " if a > 0:\n"
+ " return a\n"
+ " else:\n"
+ " return x\n"
+ "class ignoremoi:\n"
+ " def ignoreF(t):\n"
+ " return t+1\n"
+ "def f2(v):\n"
+ " ret = f1(v)\n"
+ " return ret\n";
+ const char* input_ports[] = {"v"};
+ const char* output_ports[] = {"ret"};
+ verifyCorrectPycode(code_py, "f2", 1, input_ports, 1, output_ports);
+}
+
+void Py2yacsTest::no_multiple_returns()
+{
+ const char * code_py = "def f(a):\n"
+ " x = -a\n"
+ " if a > 0:\n"
+ " return a\n"
+ " else:\n"
+ " return x\n";
+ verifyWrongPycode(code_py, "f", "multiple returns.");
+}
+
+void Py2yacsTest::unaccepted_statement()
+{
+ const char * code_py = "def f(a):\n"
+ " return a\n"
+ "x=5\n";
+ verifyWrongPycode(code_py, "f", "not accepted statement");
+}
+
+void Py2yacsTest::unaccepted_statement2()
+{
+ const char * code_py = "def f(a):\n"
+ " return a\n"
+ "if __name__ == '__main__':"
+ " print 'toto'\n";
+ verifyWrongPycode(code_py, "f", "not accepted statement");
+}
+
+void Py2yacsTest::unaccepted_return()
+{
+ const char * code_py = "def f(a):\n"
+ " return 7\n";
+ verifyWrongPycode(code_py, "f", "invalid type returned");
+}
+
+void Py2yacsTest::unaccepted_return2()
+{
+ const char * code_py = "def f1(a):\n"
+ " return 7\n"
+ "def f2(x):\n"
+ " return f1(x)\n";
+ verifyWrongPycode(code_py, "f2", "invalid type returned");
+}
+
+void Py2yacsTest::syntaxError()
+{
+ const char * code_py = "bla bla bla\n"
+ " return f1(x)\n";
+ verifyWrongPycode(code_py, "f2", "SyntaxError");
+}
+
+void Py2yacsTest::badFunctionName()
+{
+ const char * code_py = "def f1(a):\n"
+ " x=7\n"
+ " return x\n"
+ "def f2(x):\n"
+ " y=8\n"
+ " return y\n";
+ verifyWrongPycode(code_py, "nonexistant", "Function not found:");
+}
+
+void Py2yacsTest::schemaExec()
+{
+ const char * code_py = "def f(a):\n"
+ " x = a\n"
+ " return x\n";
+ Py2yacs parser;
+ try
+ {
+ parser.load(code_py);
+ }
+ catch(Py2yacsException& e)
+ {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch(...)
+ {
+ CPPUNIT_FAIL("Unknown exception");
+ }
+ YACS::ENGINE::Proc* p = parser.createProc("f");
+ CPPUNIT_ASSERT( p != NULL);
+ YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
+ CPPUNIT_ASSERT( n != NULL);
+ CPPUNIT_ASSERT( n->getInputPort("a") != NULL);
+ CPPUNIT_ASSERT( n->getOutputPort("x") != NULL);
+ // run the schema
+ n->getInputPort("a")->edInit(42.);
+ YACS::ENGINE::Executor executor;
+ executor.RunW(p, 0);
+ // verify the output port value
+ YACS::ENGINE::OutputPyPort* var = dynamic_cast<YACS::ENGINE::OutputPyPort*>(n->getOutputPort("x"));
+ CPPUNIT_ASSERT(var);
+ PyObject* pyVal = var->get();
+ CPPUNIT_ASSERT(pyVal);
+ CPPUNIT_ASSERT(PyFloat_Check(pyVal));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(42., PyFloat_AsDouble(pyVal), 1.E-12);
+}
+
+// Test the behaviour when there is an error in the python parser
+void Py2yacsTest::parserErrors()
+{
+ verifyWrongParser("bad_parsers", "p1", "argument");
+ verifyWrongParser("bad_parsers", "p2", "Attribute 'name' not found");
+ verifyWrongParser("bad_parsers", "p3", "should be a python list");
+ verifyWrongParser("bad_parsers", "p4", "Traceback");
+ verifyWrongParser("bad_parsers", "f", "Cannot find the parsing function");
+ verifyWrongParser("err_py2yacs_invalid", "get_properties", "invalid syntax");
+ verifyWrongParser("no_file", "f", "Failed to load");
+ verifyWrongParser("bad_parsers", "p5", " ");
+ verifyWrongParser("bad_parsers", "p6", " ");
+ verifyWrongParser("bad_parsers", "p7", " ");
+ verifyWrongParser("bad_parsers", "p8", "Attribute 'name' should be a string.");
+ verifyWrongParser("bad_parsers", "p9", " ");
+ verifyWrongParser("bad_parsers", "p10", " ");
+}
+
+void Py2yacsTest::globalVerification()
+{
+ std::ifstream file_stream("exemple_py2yacs.py");
+ if(!file_stream)
+ return;
+
+ std::stringstream buffer;
+ buffer << file_stream.rdbuf();
+ Py2yacs parser;
+ parser.load(buffer.str());
+ std::list<FunctionProperties>::const_iterator it_fp;
+ const std::list<FunctionProperties>& functions = parser.getFunctionProperties();
+ for(it_fp=functions.begin();it_fp!=functions.end();it_fp++)
+ {
+ std::cerr << "Function :" << it_fp->_name << std::endl;
+ std::list<std::string>::const_iterator it;
+ std::cerr << "Input ports :" ;
+ for(it=it_fp->_input_ports.begin();it!=it_fp->_input_ports.end();it++)
+ std::cerr << *it << ",";
+ std::cerr << std::endl;
+ std::cerr << "Output ports :" ;
+ for(it=it_fp->_output_ports.begin();it!=it_fp->_output_ports.end();it++)
+ std::cerr << *it << ",";
+ std::cerr << std::endl;
+ std::cerr << "Imports :" ;
+ for(it=it_fp->_imports.begin();it!=it_fp->_imports.end();it++)
+ std::cerr << *it << ",";
+ std::cerr << std::endl;
+ std::cerr << "Errors :" ;
+ for(it=it_fp->_errors.begin();it!=it_fp->_errors.end();it++)
+ std::cerr << *it << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "-----------------------------------------" << std::endl;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+// 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
+// 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 _Py2yacsTest_hxx_
+#define _Py2yacsTest_hxx_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Py2yacsTest: public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(Py2yacsTest);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST(t4);
+ CPPUNIT_TEST(t5);
+ CPPUNIT_TEST(no_multiple_returns);
+ CPPUNIT_TEST(unaccepted_statement);
+ CPPUNIT_TEST(unaccepted_statement2);
+ CPPUNIT_TEST(unaccepted_return);
+ CPPUNIT_TEST(unaccepted_return2);
+ CPPUNIT_TEST(syntaxError);
+ CPPUNIT_TEST(badFunctionName);
+ CPPUNIT_TEST(schemaExec);
+ CPPUNIT_TEST(parserErrors);
+ CPPUNIT_TEST(globalVerification);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ void tearDown();
+
+ void t1();
+ void t2();
+ void t3();
+ void t4();
+ void t5();
+ void no_multiple_returns();
+ void unaccepted_statement();
+ void unaccepted_statement2();
+ void unaccepted_return();
+ void unaccepted_return2();
+ void syntaxError();
+ void badFunctionName();
+ void schemaExec();
+ void parserErrors();
+ void globalVerification();
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+// 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
+// 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 "Py2yacsTest.hxx"
+#define UNIT_TEST_HEADER " --- TEST Py2yacsTest"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( Py2yacsTest );
+
+#include "BasicMainTest.hxx"
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# 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
+#
+def p1():
+ return ["a"], ["b"]
+
+def p2(x):
+ return ["a"], ["b"]
+
+def p3(x):
+ return 5, 6
+
+def p4(a):
+ x= a / 0
+ return ["a"], ["b"]
+
+class FunctionProperties:
+ def __init__(self, function_name):
+ self.name = function_name
+ self.inputs=[]
+ self.outputs=None
+ self.errors=[]
+ self.imports=[]
+ pass
+
+def p5(f):
+ fp = FunctionProperties("boo")
+ fp.inputs=["a", 5]
+ return [fp], ["a", "b", "c"]
+
+def p6(f):
+ fp = FunctionProperties("boo")
+ fp.outputs=[7, 5]
+ return [fp], ["a", "b", "c"]
+
+def p7(f):
+ fp = FunctionProperties("boo")
+ fp.errors=[7, 5]
+ return [fp], ["a", "b", "c"]
+
+def p8(f):
+ fp = FunctionProperties("boo")
+ fp.name=[5]
+ return [fp], ["a", "b", "c"]
+
+def p9(f):
+ fp = FunctionProperties("boo")
+ return [fp], "a"
+
+def p10(f):
+ fp = FunctionProperties("boo")
+ return [fp], ["a", fp, "c"]
+
--- /dev/null
+invalid python file
+{
+}
+x += 4;
+return
\ No newline at end of file
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cerrno>
+#include "py2yacs.hxx"
+#include "RuntimeSALOME.hxx"
+
+/*
+#include "Proc.hxx"
+#include "Node.hxx"
+#include "CORBAPorts.hxx"
+#include "InputPort.hxx"
+#include "Executor.hxx"
+*/
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4)
+ {
+ std::cerr << "Usage: " << argv[0] << " pythonfile funcname outfile" << std::endl;
+ return 1;
+ }
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ //Py_Initialize();
+ Py2yacs parser;
+ std::ifstream file_stream(argv[1]);
+ if(!file_stream)
+ {
+ std::cerr << "Error when opening file " << argv[1]
+ << ": " << strerror(errno)
+ << std::endl;
+ return 1;
+ }
+ std::stringstream buffer;
+ buffer << file_stream.rdbuf();
+ try
+ {
+ parser.load(buffer.str());
+ parser.save(argv[3], argv[2]);
+
+ /*
+ YACS::ENGINE::Proc* p = parser.createProc(argv[2]);
+ //p->setInPortValue("Schema.default_name", "a", "42.");
+ YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
+ //YACS::ENGINE::Node* n = p->nodeMap["default_name"];
+ if(!n)
+ std::cerr << "Node not found." << std::endl;
+ else
+ n->getInputPort("a")->edInit(42.);
+ p->saveSchema(argv[3]);
+
+ YACS::ENGINE::Executor executor;
+ executor.RunW(p, 0);
+ n->getOutputPort("x")->dump();
+ */
+ }
+ catch(Py2yacsException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+ YACS::ENGINE::getRuntime()->fini();
+ //Py_Finalize();
+}
\ No newline at end of file
--- /dev/null
+// 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
+// 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 <Python.h>
+#include <sstream>
+#include "py2yacs.hxx"
+#include "RuntimeSALOME.hxx"
+#include "Proc.hxx"
+#include "InlineNode.hxx"
+#include "AutoGIL.hxx"
+
+Py2yacsException::Py2yacsException(const std::string& what)
+: std::exception(),
+ _what(what)
+{
+}
+
+Py2yacsException::~Py2yacsException()throw ()
+{
+}
+
+const char * Py2yacsException::what() const throw ()
+{
+ return _what.c_str();
+}
+
+
+Py2yacs::Py2yacs()
+: _python_parser_module("py2yacs"),
+ _python_parser_function("get_properties"),
+ _functions(),
+ _global_errors(),
+ _python_code()
+{
+}
+
+Py2yacs::Py2yacs(const std::string& python_parser_module,
+ const std::string& python_parser_function)
+: _python_parser_module(python_parser_module),
+ _python_parser_function(python_parser_function),
+ _functions(),
+ _global_errors(),
+ _python_code()
+{
+}
+
+const std::list<std::string>& Py2yacs::getGlobalErrors() const
+{
+ return _global_errors;
+}
+
+const std::list<FunctionProperties>& Py2yacs::getFunctionProperties()const
+{
+ return _functions;
+}
+
+// Copy a python list of strings to a c++ list of strings.
+// Return an error string. An empty string means no error.
+static
+std::string copyList(PyObject *pyList, std::list<std::string>& cppList)
+{
+ std::string error;
+ if(!PyList_Check(pyList))
+ {
+ error = "Not a python list.\n";
+ //throw Py2yacsException("Not a python list.");
+ }
+ else
+ {
+ int n = PyList_Size(pyList);
+ for(int i=0; i<n; i++)
+ {
+ PyObject *elem = PyList_GetItem(pyList,i);
+ if(!PyString_Check(elem))
+ {
+ std::stringstream message;
+ message << "List element number " << i << " is not a string.\n";
+ error += message.str();
+ // throw Py2yacsException(message.str());
+ }
+ else
+ {
+ const char * portName = PyString_AsString(elem);
+ cppList.push_back(portName);
+ }
+ }
+ }
+ return error;
+}
+
+static
+std::string getPyErrorText()
+{
+ std::string result="";
+ if (PyErr_Occurred())
+ {
+ PyObject *ptype, *pvalue, *ptraceback;
+ PyObject *pystr, *module_name, *pyth_module, *pyth_func;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ pystr = PyObject_Str(pvalue);
+ result = PyString_AsString(pystr);
+ result += "\n";
+ Py_DECREF(pystr);
+
+ /* See if we can get a full traceback */
+ if(ptraceback)
+ {
+ module_name = PyString_FromString("traceback");
+ pyth_module = PyImport_Import(module_name);
+ Py_DECREF(module_name);
+ if (pyth_module)
+ {
+ pyth_func = PyObject_GetAttrString(pyth_module, "format_exception");
+ if (pyth_func && PyCallable_Check(pyth_func))
+ {
+ PyObject *pyList;
+ pyList = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL);
+ if(pyList)
+ {
+ int n = PyList_Size(pyList);
+ for(int i=0; i<n; i++)
+ {
+ pystr = PyList_GetItem(pyList,i);
+ result += PyString_AsString(pystr);
+ }
+ Py_DECREF(pyList);
+ }
+ }
+ Py_XDECREF(pyth_func);
+ Py_DECREF(pyth_module);
+ }
+ }
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ }
+ return result;
+}
+
+static
+PyObject* checkAndGetAttribute(PyObject *p,
+ const char* attribute,
+ std::string& error)
+{
+ PyObject *pAttribute = PyObject_GetAttrString(p, attribute);
+ if(!pAttribute)
+ {
+ error += "Attribute '";
+ error += attribute;
+ error += "' not found in the returned value of the parsing function.\n";
+ error += getPyErrorText();
+ }
+ return pAttribute;
+}
+
+void Py2yacs::load(const std::string& python_code)
+{
+ PyObject *pModule, *pDict, *pFunc;
+ PyObject *pArgs, *pValue;
+ int i;
+ std::string errorMessage="";
+ _python_code = python_code;
+ _functions.clear();
+ _global_errors.clear();
+
+ // Py_Initialize();
+ YACS::ENGINE::AutoGIL agil;
+ pValue = PyString_FromString(_python_parser_module.c_str());
+ pModule = PyImport_Import(pValue);
+ Py_DECREF(pValue);
+
+ if (!pModule)
+ {
+ errorMessage = getPyErrorText();
+ errorMessage += "\nFailed to load ";
+ errorMessage += _python_parser_module;
+ errorMessage += ".\n";
+ }
+ else
+ {
+ pFunc = PyObject_GetAttrString(pModule, _python_parser_function.c_str());
+
+ if (pFunc && PyCallable_Check(pFunc))
+ {
+ pArgs = PyTuple_New(1);
+ pValue = PyString_FromString(python_code.c_str());
+ PyTuple_SetItem(pArgs, 0, pValue);
+
+ pValue = PyObject_CallObject(pFunc, pArgs);
+ Py_DECREF(pArgs);
+ if (!pValue)
+ errorMessage = getPyErrorText();
+ else
+ {
+ if (!PyTuple_Check(pValue))
+ {
+ errorMessage += "Parsing function should return a tuple of two string lists.\n";
+ }
+ int n = PyTuple_Size(pValue);
+ if(n != 2)
+ {
+ errorMessage += "Parsing function should return two string lists.\n";
+ }
+ PyObject *pyList = PyTuple_GetItem(pValue, 0);
+ if(!PyList_Check(pyList))
+ {
+ errorMessage += "The first returned value of the parsing function"
+ " should be a python list.\n";
+ }
+ else
+ {
+ n = PyList_Size(pyList);
+ for(int i=0; i<n; i++)
+ {
+ PyObject *fpy = PyList_GetItem(pyList,i);
+ PyObject *pAttribute;
+
+ if(pAttribute = checkAndGetAttribute(fpy, "name", errorMessage))
+ {
+ if(!PyString_Check(pAttribute))
+ {
+ errorMessage += "Attribute 'name' should be a string.\n";
+ Py_DECREF(pAttribute);
+ }
+ else
+ {
+ _functions.push_back(FunctionProperties());
+ FunctionProperties& fcpp = _functions.back();
+ fcpp._name=PyString_AsString(pAttribute);
+ Py_DECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "inputs", errorMessage))
+ errorMessage += copyList(pAttribute, fcpp._input_ports);
+ Py_XDECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "outputs", errorMessage))
+ // None value means no return statement in the function
+ if(pAttribute != Py_None)
+ errorMessage += copyList(pAttribute,fcpp._output_ports);
+ Py_XDECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "errors", errorMessage))
+ errorMessage += copyList(pAttribute, fcpp._errors);
+ Py_XDECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "imports", errorMessage))
+ errorMessage += copyList(pAttribute, fcpp._imports);
+ Py_XDECREF(pAttribute);
+ }
+ }
+ }
+ }
+ errorMessage += copyList(PyTuple_GetItem(pValue, 1), _global_errors);
+ Py_DECREF(pValue);
+ }
+ }
+ else
+ {
+ errorMessage = getPyErrorText();
+ errorMessage += "\nCannot find the parsing function '";
+ errorMessage += _python_parser_function;
+ errorMessage += "' in python module '";
+ errorMessage += _python_parser_module;
+ errorMessage += "'.\n";
+ }
+ Py_XDECREF(pFunc);
+ Py_DECREF(pModule);
+ }
+
+ if(!errorMessage.empty())
+ throw Py2yacsException(errorMessage);
+ // Py_Finalize();
+}
+
+void Py2yacs::save(const std::string& file_path,
+ const std::string& python_function)const
+{
+ YACS::ENGINE::Proc* schema = createProc(python_function);
+ schema->saveSchema(file_path);
+ delete schema;
+}
+
+YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
+{
+ if(!_global_errors.empty())
+ {
+ std::string error_message = "The python script contains errors.\n";
+ std::list<std::string>::const_iterator it;
+ for(it = _global_errors.begin(); it != _global_errors.end(); it++)
+ error_message += (*it) + "\n";
+ throw Py2yacsException(error_message);
+ }
+
+ // find function properties
+ std::list<FunctionProperties>::const_iterator fn_prop = _functions.begin();
+ while(fn_prop != _functions.end() && fn_prop->_name != python_function)
+ fn_prop++;
+
+ if(fn_prop == _functions.end())
+ {
+ throw Py2yacsException(std::string("Function not found: ")+python_function);
+ }
+
+ if(!fn_prop->_errors.empty())
+ {
+ std::string error_message = "Function contains errors.\n";
+ std::list<std::string>::const_iterator it;
+ for(it = fn_prop->_errors.begin(); it != fn_prop->_errors.end(); it++)
+ error_message += (*it) + "\n";
+ throw Py2yacsException(error_message);
+ }
+
+ // add the call to the function at the end of the script
+ std::stringstream fn_call;
+ fn_call << std::endl;
+ std::list<std::string>::const_iterator it;
+ bool first = true;
+ for(it=fn_prop->_output_ports.begin();
+ it!=fn_prop->_output_ports.end();
+ it++)
+ {
+ if (!first)
+ fn_call << ",";
+ first = false;
+ fn_call << *it;
+ }
+ fn_call << "=" << python_function << "(";
+ first = true;
+ for(it = fn_prop->_input_ports.begin();
+ it != fn_prop->_input_ports.end();
+ it++)
+ {
+ if (!first)
+ fn_call << ",";
+ first = false;
+ fn_call << *it;
+ }
+ fn_call << ")" << std::endl;
+ std::string node_body = _python_code + fn_call.str();
+
+ YACS::ENGINE::Proc* schema;
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ YACS::ENGINE::RuntimeSALOME* runtime = YACS::ENGINE::getSALOMERuntime();
+
+ // build the YACS schema
+ const char * node_name = "default_name";
+ schema = runtime->createProc("Schema");
+ YACS::ENGINE::InlineNode* node = runtime->createScriptNode("", node_name);
+ schema->edAddChild(node);
+ node->setScript(node_body);
+ YACS::ENGINE::TypeCode *tc_double = runtime->getTypeCode("double");
+
+ for(it = fn_prop->_input_ports.begin();
+ it != fn_prop->_input_ports.end();
+ it++)
+ node->edAddInputPort(*it, tc_double);
+
+ for(it = fn_prop->_output_ports.begin();
+ it != fn_prop->_output_ports.end();
+ it++)
+ node->edAddOutputPort(*it, tc_double);
+
+ return schema;
+}
\ No newline at end of file
--- /dev/null
+// 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
+// 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 _PY2YACS_H_
+#define _PY2YACS_H_
+
+#ifdef WIN32
+# if defined py2yacslib_EXPORTS
+# define PY2YACSLIB_EXPORT __declspec( dllexport )
+# else
+# define PY2YACSLIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define PY2YACSLIB_EXPORT
+#endif
+
+
+#include <string>
+#include <list>
+#include <exception>
+
+class PY2YACSLIB_EXPORT Py2yacsException: std::exception
+{
+ public:
+ Py2yacsException(const std::string& what);
+ virtual ~Py2yacsException()throw ();
+ virtual const char *what() const throw ();
+ private:
+ std::string _what;
+};
+
+namespace YACS
+{
+ namespace ENGINE
+ {
+ class Proc;
+ };
+};
+
+struct PY2YACSLIB_EXPORT FunctionProperties
+{
+ public:
+ std::string _name;
+ std::list<std::string> _input_ports;
+ std::list<std::string> _output_ports;
+ std::list<std::string> _errors;
+ std::list<std::string> _imports;
+};
+
+/*! \brief Converter of a python script to a yacs schema.
+ * This class converts a string containing a python script to a yacs schema
+ * containing a python script node.
+ */
+class PY2YACSLIB_EXPORT Py2yacs
+{
+ public:
+ Py2yacs();
+
+ /*!
+ * This constructor can be used if you want to define your own python parser.
+ * The parser function should be a python function and return a tuple of
+ * two lists.
+ * The first list contains the properties of all the functions in the script
+ * and the second one contains global errors.
+ * \param python_parser_module: name of the parser module
+ * \param python_parser_function: name of the parser function
+ */
+ Py2yacs(const std::string& python_parser_module,
+ const std::string& python_parser_function);
+
+ /*!
+ * \param python_code: contains the python code that will be converted
+ * to a yacs schema.
+ */
+ void load(const std::string& python_code);
+
+ /*!
+ * \param file_path: path to the xml file where to save the yacs schema.
+ * \param python_function: function defined in the python code that will be
+ * called in the yacs node.
+ */
+ void save(const std::string& file_path,
+ const std::string& python_function)const;
+
+ /*!
+ * A new schema is created.
+ * \param python_function: function defined in the python code that will be
+ * called in the yacs node.
+ */
+ YACS::ENGINE::Proc* createProc(const std::string& python_function)const;
+
+ const std::list<std::string>& getGlobalErrors() const;
+ const std::list<FunctionProperties>& getFunctionProperties()const;
+
+ private:
+ std::string _python_parser_module;
+ std::string _python_parser_function;
+ std::list<FunctionProperties> _functions;
+ std::list<std::string> _global_errors;
+ std::string _python_code;
+};
+
+#endif //_PY2YACS_H_
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 *-
+# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# 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
+#
+import ast
+
+class FunctionProperties:
+ def __init__(self, function_name):
+ self.name = function_name
+ self.inputs=[]
+ self.outputs=None
+ self.errors=[]
+ self.imports=[]
+ pass
+ def __str__(self):
+ result = "Function:" + self.name + "\n"
+ result+= " Inputs:" + str(self.inputs) + "\n"
+ result+= " Outputs:"+ str(self.outputs) + "\n"
+ result+= " Errors:" + str(self.errors) + "\n"
+ result+= " Imports:"+ str(self.imports) + "\n"
+ return result
+
+class v(ast.NodeVisitor):
+ def visit_Module(self, node):
+ #print type(node).__name__, ":"
+ accepted_tokens = ["Import", "ImportFrom", "FunctionDef", "ClassDef"]
+ #print "module body:"
+ self.global_errors=[]
+ for e in node.body:
+ type_name = type(e).__name__
+ if type_name not in accepted_tokens:
+ error="py2yacs error at line %s: not accepted statement '%s'." % (
+ e.lineno, type_name)
+ self.global_errors.append(error)
+ #print type_name
+ #print "------------------------------------------------------------------"
+ self.functions=[]
+ self.lastfn=""
+ self.infunc=False
+ self.inargs=False
+ self.generic_visit(node)
+ pass
+ def visit_FunctionDef(self, node):
+ #print type(node).__name__, ":", node.name
+ if not self.infunc:
+ self.lastfn = FunctionProperties(node.name)
+ self.functions.append(self.lastfn)
+ self.infunc=True
+ #
+ self.generic_visit(node)
+ #
+ self.lastfn = None
+ self.infunc=False
+ pass
+ def visit_arguments(self, node):
+ #print type(node).__name__, ":"
+ self.inargs=True
+ self.generic_visit(node)
+ self.inargs=False
+ pass
+ def visit_Name(self, node):
+ if self.inargs :
+ #print type(node).__name__, ":", node.id
+ self.lastname=node.id
+ self.generic_visit(node)
+ pass
+ def visit_Param(self, node):
+ #print type(node).__name__, ":", self.lastname
+ self.lastfn.inputs.append(self.lastname)
+ pass
+ def visit_Return(self, node):
+ #print type(node).__name__, ":", node.value
+ if self.lastfn.outputs is not None :
+ error="py2yacs error at line %s: multiple returns." % node.lineno
+ self.lastfn.errors.append(error)
+ return
+ self.lastfn.outputs = []
+ if node.value is None :
+ pass
+ elif 'Tuple' == type(node.value).__name__ :
+ for e in node.value.elts:
+ if 'Name' == type(e).__name__ :
+ self.lastfn.outputs.append(e.id)
+ else :
+ error="py2yacs error at line %s: invalid type returned '%s'." % (
+ node.lineno, type(e).__name__)
+ self.lastfn.errors.append(error)
+ else:
+ if 'Name' == type(node.value).__name__ :
+ self.lastfn.outputs.append(node.value.id)
+ else :
+ error="py2yacs error at line %s: invalid type returned '%s'." %(
+ node.lineno, type(node.value).__name__)
+ self.lastfn.errors.append(error)
+ pass
+ pass
+ pass
+
+ def visit_ClassDef(self, node):
+ # just ignore classes
+ pass
+
+ def visit_Import(self, node):
+ if self.infunc:
+ for n in node.names:
+ self.lastfn.imports.append(n.name)
+ def visit_ImportFrom(self, node):
+ if self.infunc:
+ m=node.module
+ for n in node.names:
+ self.lastfn.imports.append(m+"."+n.name)
+
+class vtest(ast.NodeVisitor):
+ def generic_visit(self, node):
+ #print type(node).__name__
+ ast.NodeVisitor.generic_visit(self, node)
+
+def create_yacs_schema(text, fn_name, fn_args, fn_returns, file_name):
+ import pilot
+ import SALOMERuntime
+ #import loader
+ SALOMERuntime.RuntimeSALOME_setRuntime()
+ runtime = pilot.getRuntime()
+ schema = runtime.createProc("schema")
+ node = runtime.createFuncNode("", "default_name")
+ schema.edAddChild(node)
+ fncall = "\n%s=%s(%s)\n"%(",".join(fn_returns),
+ fn_name,
+ ",".join(fn_args))
+ node.setScript(text+fncall)
+ node.setFname(fn_name)
+ td=schema.getTypeCode("double")
+ for p in fn_args:
+ node.edAddInputPort(p, td)
+ for p in fn_returns:
+ node.edAddOutputPort(p, td)
+ schema.saveSchema(file_name)
+
+def get_properties(text_file):
+ bt=ast.parse(text_file)
+ w=v()
+ w.visit(bt)
+ return w.functions, w.global_errors
+
+if __name__ == '__main__':
+ import argparse
+ parser = argparse.ArgumentParser(description="Generate a YACS schema from a python file containing a function to run.")
+ parser.add_argument("file", help='Path to the python file')
+ parser.add_argument("-o","--output",
+ help='Path to the output file (yacs_schema.xml by default)',
+ default='yacs_schema.xml')
+ parser.add_argument("-d","--def_name",
+ help='Name of the function to call in the yacs node (_exec by default)',
+ default='_exec')
+ args = parser.parse_args()
+ with open(args.file, 'r') as f:
+ text_file = f.read()
+ #bt=ast.parse(text_file)
+ #w=vtest()
+ #w=v()
+ #w.visit(bt)
+ #print "global errors:", w.global_errors
+ #for f in w.functions:
+ # print f
+
+ fn_name = args.def_name
+ functions,errors = get_properties(text_file)
+ print "global errors:", errors
+ for f in functions:
+ print f
+
+ fn_properties = next((f for f in functions if f.name == fn_name), None)
+ if fn_properties is not None :
+ if not fn_properties.errors :
+ create_yacs_schema(text_file, fn_name,
+ fn_properties.inputs, fn_properties.outputs,
+ args.output)
+ else:
+ print "\n".join(fn_properties.errors)
+ else:
+ print "Function not found:", fn_name
+
\ No newline at end of file
SalomeOptimizerLoop.hxx
DistributedPythonNode.hxx
PyOptimizerAlg.hxx
+ VisitorSalomeSaveState.hxx
)
# --- sources ---
PyStdout.cxx
SalomeOptimizerLoop.cxx
PyOptimizerAlg.cxx
+ VisitorSalomeSaveState.cxx
)
# --- rules ---
}
#ifndef WIN32
+#ifdef __APPLE__
+ std::string impl_name = std::string ("lib") + aCompName + std::string("Local.dylib");
+#else
std::string impl_name = std::string ("lib") + aCompName + std::string("Local.so");
+#endif
if(sprefix != "")
impl_name = sprefix + std::string("/") + impl_name;
#else
if(!_container)
throw Exception("No container specified !");
SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(_container));
- SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(_container));
+ SalomeHPContainerBase *containerCast1(dynamic_cast<SalomeHPContainerBase *>(_container));
if(containerCast0)
objContainer=containerCast0->getContainerPtr(this);
else if(containerCast1)
{
- YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,this));
- objContainer=tmpCont->getContainerPtr(this);
+ objContainer=containerCast1->getContainerPtr(this);
}
else
throw Exception("Unrecognized type of container ! Salome one is expected !");
if(!container)
throw Exception("No container specified !");
SalomeContainer *containerCast0(dynamic_cast<SalomeContainer *>(container));
- SalomeHPContainer *containerCast1(dynamic_cast<SalomeHPContainer *>(container));
+ SalomeHPContainerBase *containerCast1(dynamic_cast<SalomeHPContainerBase *>(container));
if(containerCast0)
objContainer=containerCast0->getContainerPtr(reqNode);
else if(containerCast1)
{
- YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,reqNode));
- objContainer=tmpCont->getContainerPtr(reqNode);
+ objContainer=containerCast1->getContainerPtr(reqNode);
}
else
throw Exception("Unrecognized type of container ! Salome one is expected for PythonNode/PyFuncNode !");
#ifdef SALOME_KERNEL
#include "SALOME_NamingService.hxx"
#include "SALOME_LifeCycleCORBA.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOME_ResourcesManager.hxx"
+#include "SALOME_ContainerManager.hxx"
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
+
#endif
#include <libxml/parser.h>
RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
{
- YASSERT(Runtime::_singleton);
- return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
+ YASSERT(RuntimeSALOME::getSingleton());
+ return dynamic_cast< RuntimeSALOME* >(RuntimeSALOME::getSingleton());
}
/**
}
}
+std::vector< std::pair<std::string,int> > RuntimeSALOME::getCatalogOfComputeNodes() const
+{
+ CORBA::ORB_ptr orb(getOrb());
+ SALOME_NamingService namingService;
+ try
+ {
+ namingService.init_orb(orb);
+ }
+ catch(SALOME_Exception& e)
+ {
+ throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Unable to contact the SALOME Naming Service");
+ }
+ CORBA::Object_var obj(namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS));
+ if(CORBA::is_nil(obj))
+ throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Unable to access to the resource manager !");
+ Engines::ResourcesManager_var resManager(Engines::ResourcesManager::_narrow(obj));
+ if(CORBA::is_nil(resManager))
+ throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Internal error ! The entry attached to the res manager in NS does not have right type !");
+ std::vector< std::pair<std::string,int> > ret;
+ {
+ Engines::ResourceList *rl(0);
+ Engines::IntegerList *il(0);
+ resManager->ListAllAvailableResources(rl,il);
+ int sz(rl->length());
+ if(il->length()!=sz)
+ throw Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Internal error ! Invalid size !");
+ ret.resize(sz);
+ for(int i=0;i<sz;i++)
+ {
+ std::string s((*rl)[i]);
+ ret[i]=std::pair<std::string,int>(s,(*il)[i]);
+ }
+ delete rl;
+ delete il;
+ }
+ return ret;
+}
+
std::string RuntimeSALOME::getVersion() const
{
#ifdef YACS_DEVELOPMENT
//convertible type
return new PyNeutral(inport);
}
+ //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268)
+ else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref)
+ {
+ return new PyNeutral(inport);
+ }
//non convertible type
stringstream msg;
msg << "Cannot connect Python output port with type: " << type->id() ;
// return result;
// }
-CORBA::ORB_ptr RuntimeSALOME::getOrb()
+CORBA::ORB_ptr RuntimeSALOME::getOrb() const
{
return _orb;
}
-PyObject * RuntimeSALOME::getPyOrb()
+PyObject * RuntimeSALOME::getPyOrb() const
{
return _pyorb;
}
-PyObject * RuntimeSALOME::getBuiltins()
+PyObject * RuntimeSALOME::getBuiltins() const
{
return _bltins;
}
-DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
+DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() const
{
return _dynFactory;
}
class YACSRUNTIMESALOME_EXPORT RuntimeSALOME: public Runtime
{
+ static Runtime* getSingleton() { return Runtime::_singleton; }
+
public:
enum
virtual void init(long flags, int argc, char* argv[]);
virtual void fini();
-
+ virtual std::vector< std::pair<std::string,int> > getCatalogOfComputeNodes() const;
virtual InputPort* createInputPort(const std::string& name,
const std::string& impl,
Node * node,
virtual ServiceInlineNode *createSInlineNode(const std::string& kind, const std::string& name);
virtual ComponentInstance* createComponentInstance(const std::string& name,
const std::string& kind="");
+#ifndef SWIG
virtual Container *createContainer(const std::string& kind="");
+#endif
virtual WhileLoop* createWhileLoop(const std::string& name);
virtual ForLoop* createForLoop(const std::string& name);
virtual OptimizerLoop* createOptimizerLoop(const std::string& name,const std::string& algLib,
virtual ~RuntimeSALOME();
- CORBA::ORB_ptr getOrb();
- PyObject * getPyOrb();
- PyObject * getBuiltins();
- DynamicAny::DynAnyFactory_ptr getDynFactory();
+ CORBA::ORB_ptr getOrb() const;
+ PyObject * getPyOrb() const;
+ PyObject * getBuiltins() const;
+ DynamicAny::DynAnyFactory_ptr getDynFactory() const;
omniORBpyAPI* getApi();
PyObject * get_omnipy();
#endif
}
+bool SalomeContainerMonoHelper::isKernelContNull() const
+{
+ return CORBA::is_nil(_trueCont);
+}
+
void SalomeContainerMonoHelper::shutdown()
{
+ if(CORBA::is_nil(_trueCont))
+ return ;
try
{
DEBTRACE("shutdown SALOME container: " );
_trueCont=Engines::Container::_nil();
}
+std::string SalomeContainerMonoHelper::getKernelContainerName() const
+{
+ if(CORBA::is_nil(_trueCont))
+ return std::string("NULL");
+ CORBA::String_var containerName(_trueCont->name());
+ std::string ret(containerName);
+ return ret;
+}
+
SalomeContainerMonoHelper::~SalomeContainerMonoHelper()
{
}
Engines::Container_var getContainer(const Task *askingNode) const;
bool isAlreadyStarted(const Task *askingNode) const;
void setContainer(const Task *askingNode, Engines::Container_var cont);
+ bool isKernelContNull() const;
void shutdown();
+ std::string getKernelContainerName() const;
private:
~SalomeContainerMonoHelper();
public:
#include "ServiceNode.hxx"
#include "ComponentInstance.hxx"
#include "SalomeContainerHelper.hxx"
+#include "SalomeHPContainerTools.hxx"
#include "RuntimeSALOME.hxx"
#include "Exception.hxx"
using namespace YACS::ENGINE;
-SalomeContainerTools::SalomeContainerTools()
+/*!
+ * \param [in] compoNames
+ * \param [in,out] shutdownLevel
+ */
+void SalomeContainerToolsBase::Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerToolsBase& sct, int& shutdownLevel, const Container *cont, const Task *askingNode)
{
- /* Init ContainerParameters */
- SALOME_LifeCycleCORBA::preSet(_params);
+ CORBA::ORB_ptr orb(getSALOMERuntime()->getOrb());
+ SALOME_NamingService ns;
+ try
+ {
+ ns.init_orb(orb);
+ }
+ catch(SALOME_Exception& e)
+ {
+ throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
+ }
+ CORBA::Object_var obj(ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS));
+ Engines::ContainerManager_var contManager(Engines::ContainerManager::_narrow(obj));
+
+ bool isEmptyName;
+ std::string str(sct.getNotNullContainerName(cont,askingNode,isEmptyName));
+ DEBTRACE("SalomeContainer::start " << str <<";"<< sct.getHostName() <<";"<< schelp->getType());
+
+ // Finalize parameters with components found in the container
+
+ for(std::vector<std::string>::const_iterator iter=compoNames.begin();iter!=compoNames.end();iter++)
+ sct.addToComponentList(*iter);
+
+ Engines::ContainerParameters myparams(sct.getParameters());
+ {
+ std::string dftLauchMode(schelp->getDftLaunchMode());
+ myparams.mode=CORBA::string_dup(dftLauchMode.c_str());
+ }
+
+ //If a container_name is given try to find an already existing container in naming service
+ //If not found start a new container with the given parameters
+ if (dynamic_cast<SalomeContainerMonoHelper *>(schelp) && !isEmptyName)
+ {
+ myparams.mode=CORBA::string_dup("getorstart");
+ }
+
+ if (isEmptyName)
+ {
+ shutdownLevel=1;
+ }
+ //sct.setContainerName(str);
+ SetContainerNameOf(myparams,str);
+ Engines::Container_var trueCont(Engines::Container::_nil());
+ if(!isEmptyName && shutdownLevel==999)
+ {
+ //Make this only the first time start is called (_shutdownLevel==999)
+ //If the container is named, first try to get an existing container
+ //If there is an existing container use it and set the shutdown level to 3
+ //If there is no existing container, try to launch a new one and set the shutdown level to 2
+ myparams.mode="get";
+ try
+ {
+ trueCont=contManager->GiveContainer(myparams);
+ }
+ catch( const SALOME::SALOME_Exception& ex )
+ {
+ std::string msg="SalomeContainer::start : no existing container : ";
+ msg += '\n';
+ msg += ex.details.text.in();
+ DEBTRACE( msg );
+ }
+ catch(...)
+ {
+ }
+
+ if(!CORBA::is_nil(trueCont))
+ {
+ shutdownLevel=3;
+ DEBTRACE( "container found: " << str << " " << _shutdownLevel );
+ }
+ else
+ {
+ shutdownLevel=2;
+ myparams.mode="start";
+ DEBTRACE( "container not found: " << str << " " << _shutdownLevel);
+ }
+ }
+
+ if(CORBA::is_nil(trueCont))
+ try
+ {
+ // --- GiveContainer is used in batch mode to retreive launched containers,
+ // and is equivalent to StartContainer when not in batch.
+ trueCont=contManager->GiveContainer(myparams);
+ }
+ catch( const SALOME::SALOME_Exception& ex )
+ {
+ std::string msg="SalomeContainer::start : Unable to launch container in Salome : ";
+ msg += '\n';
+ msg += ex.details.text.in();
+ throw Exception(msg);
+ }
+ catch(CORBA::COMM_FAILURE&)
+ {
+ throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
+ }
+ catch(CORBA::Exception&)
+ {
+ throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
+ }
+
+ if(CORBA::is_nil(trueCont))
+ throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
+
+ schelp->setContainer(askingNode,trueCont);
+
+ CORBA::String_var containerName(trueCont->name()),hostName(trueCont->getHostName());
+ std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << trueCont->getPID() << std::endl;
}
-SalomeContainerTools::SalomeContainerTools(const SalomeContainerTools& other):_params(other._params),_propertyMap(other._propertyMap)
+CORBA::Object_ptr SalomeContainerToolsBase::LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode)
{
+ DEBTRACE("SalomeContainer::loadComponent ");
+ const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
+ {
+ YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
+ if(!cont->isAlreadyStarted(askingNode))
+ cont->start(askingNode);
+ }
+ if(!inst)
+ throw Exception("SalomeContainerTools::LoadComponent : no instance of component in the task requesting for a load of its component !");
+ CORBA::Object_ptr objComponent=CORBA::Object::_nil();
+ {
+ YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
+ std::string compoName(inst->getCompoName());
+ Engines::Container_var container(launchModeType->getContainer(askingNode));
+
+ char *reason;
+ bool isLoadable(container->load_component_Library(compoName.c_str(), reason));
+ if(isLoadable)
+ objComponent=CreateComponentInstance(cont,container,inst);
+ }
+ return objComponent;
}
-void SalomeContainerTools::clearProperties()
+CORBA::Object_ptr SalomeContainerToolsBase::CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst)
+{
+ if(!inst)
+ throw Exception("SalomeContainerTools::CreateComponentInstance : no instance of component in the task requesting for a load of its component !");
+ char *reason(0);
+ std::string compoName(inst->getCompoName());
+ CORBA::Object_ptr objComponent=CORBA::Object::_nil();
+ int studyid(1);
+ Proc* p(cont->getProc());
+ if(p)
+ {
+ std::string value(p->getProperty("DefaultStudyID"));
+ if(!value.empty())
+ studyid= atoi(value.c_str());
+ }
+ // prepare component instance properties
+ Engines::FieldsDict_var env(new Engines::FieldsDict);
+ std::map<std::string, std::string> properties(inst->getProperties());
+ if(p)
+ {
+ std::map<std::string,std::string> procMap=p->getProperties();
+ properties.insert(procMap.begin(),procMap.end());
+ }
+
+ std::map<std::string, std::string>::const_iterator itm;
+ env->length(properties.size());
+ int item=0;
+ for(itm = properties.begin(); itm != properties.end(); ++itm, item++)
+ {
+ DEBTRACE("envname="<<itm->first<<" envvalue="<< itm->second);
+ env[item].key= CORBA::string_dup(itm->first.c_str());
+ env[item].value <<= itm->second.c_str();
+ }
+
+ objComponent=contPtr->create_component_instance_env(compoName.c_str(), env, reason);
+ if(CORBA::is_nil(objComponent))
+ {
+ std::string text="Error while trying to create a new component: component '"+ compoName;
+ text=text+"' is not installed or it's a wrong name";
+ text += '\n';
+ text += reason;
+ CORBA::string_free(reason);
+ throw Exception(text);
+ }
+ return objComponent;
+}
+
+std::string SalomeContainerToolsBase::GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
+{
+ if(cont->isAlreadyStarted(askingNode))
+ {
+ Engines::Container_var container(launchModeType->getContainer(askingNode));
+ const char *what="/";
+ CORBA::String_var corbaStr(container->name());
+ std::string ret(corbaStr);
+
+ //Salome FOREVER ...
+ std::string::size_type i=ret.find_first_of(what,0);
+ i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
+ if(i!=std::string::npos)
+ return ret.substr(i+1);
+ return ret;
+ }
+ else
+ return "Not placed yet !!!";
+}
+
+std::string SalomeContainerToolsBase::GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
+{
+ if(cont->isAlreadyStarted(askingNode))
+ {
+ Engines::Container_var container(launchModeType->getContainer(askingNode));
+ try
+ {
+ CORBA::String_var corbaStr(container->name());
+ std::string ret(corbaStr);
+ return ret;
+ }
+ catch(...)
+ {
+ return "Unknown_placement";
+ }
+ }
+ else
+ return "Not_placed_yet";
+}
+
+void SalomeContainerToolsBase::SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name)
+{
+ params.container_name=CORBA::string_dup(name.c_str());
+}
+
+
+/////////////////////////////////
+
+SalomeContainerToolsInter::SalomeContainerToolsInter(const SalomeContainerToolsInter& other):_propertyMap(other._propertyMap)
+{
+}
+
+void SalomeContainerToolsInter::clearProperties()
{
_propertyMap.clear();
- _params=Engines::ContainerParameters();
}
-std::string SalomeContainerTools::getProperty(const std::string& name) const
+std::string SalomeContainerToolsInter::getProperty(const std::string& name) const
{
std::map<std::string,std::string>::const_iterator it(_propertyMap.find(name));
if(it!=_propertyMap.end())
return std::string();
}
+std::map<std::string,std::string> SalomeContainerToolsInter::getResourceProperties(const std::string& name) const
+{
+ std::map<std::string,std::string> properties;
+
+ YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
+ CORBA::ORB_ptr orb = runTime->getOrb();
+ if (!orb) return properties;
+ SALOME_NamingService namingService(orb);
+ SALOME_LifeCycleCORBA lcc(&namingService);
+ CORBA::Object_var obj = namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
+ if (CORBA::is_nil(obj))
+ return properties;
+ Engines::ResourcesManager_var resManager = Engines::ResourcesManager::_narrow(obj);
+ if (CORBA::is_nil(resManager))
+ return properties;
+
+ std::ostringstream value;
+ Engines::ResourceDefinition_var resource_definition = resManager->GetResourceDefinition(name.c_str());
+ properties["hostname"]=resource_definition->hostname.in();
+ properties["OS"]=resource_definition->OS.in();
+ value.str(""); value << resource_definition->mem_mb;
+ properties["mem_mb"]=value.str();
+ value.str(""); value << resource_definition->cpu_clock;
+ properties["cpu_clock"]=value.str();
+ value.str(""); value << resource_definition->nb_node;
+ properties["nb_node"]=value.str();
+ value.str(""); value << resource_definition->nb_proc_per_node;
+ properties["nb_proc_per_node"]=value.str();
+ /*
+ properties["component_list"]="";
+ for(CORBA::ULong i=0; i < resource_definition->componentList.length(); i++)
+ {
+ if(i > 0)
+ properties["component_list"]=properties["component_list"]+",";
+ properties["component_list"]=properties["component_list"]+resource_definition->componentList[i].in();
+ }
+ */
+ return properties;
+}
+
+////////////////////////
+
+SalomeContainerTools::SalomeContainerTools()
+{
+ /* Init ContainerParameters */
+ SALOME_LifeCycleCORBA::preSet(_params);
+}
+
+SalomeContainerTools::SalomeContainerTools(const SalomeContainerTools& other):SalomeContainerToolsInter(other),_params(other._params)
+{
+}
+
+int SalomeContainerTools::getNumberOfCoresPerWorker() const
+{
+ return _params.resource_params.nb_proc_per_node;
+}
+
+void SalomeContainerTools::clearProperties()
+{
+ SalomeContainerToolsInter::clearProperties();
+ _params=Engines::ContainerParameters();
+}
+
void SalomeContainerTools::setProperty(const std::string& name, const std::string& value)
{
//DEBTRACE("SalomeContainer::setProperty : " << name << " ; " << value);
SetContainerNameOf(_params,name);
}
+std::string SalomeContainerTools::getHostName() const
+{
+ return std::string(_params.resource_params.hostname);
+}
+
std::string SalomeContainerTools::getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const
{
isEmpty=true;
}
}
-std::string SalomeContainerTools::getHostName() const
+//////////////////////////
+
+std::string SalomeContainerToolsDecoratorBase::getProperty(const std::string& name) const
{
- return std::string(_params.resource_params.hostname);
+ return _sct->getProperty(name);
}
-void SalomeContainerTools::SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name)
+void SalomeContainerToolsDecoratorBase::setProperty(const std::string& name, const std::string& value)
{
- params.container_name=CORBA::string_dup(name.c_str());
+ _sct->setProperty(name,value);
}
-std::map<std::string,std::string> SalomeContainerTools::getResourceProperties(const std::string& name) const
+const std::map<std::string,std::string>& SalomeContainerToolsDecoratorBase::getProperties() const
{
- std::map<std::string,std::string> properties;
-
- YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
- CORBA::ORB_ptr orb = runTime->getOrb();
- if (!orb) return properties;
- SALOME_NamingService namingService(orb);
- SALOME_LifeCycleCORBA lcc(&namingService);
- CORBA::Object_var obj = namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
- if (CORBA::is_nil(obj))
- return properties;
- Engines::ResourcesManager_var resManager = Engines::ResourcesManager::_narrow(obj);
- if (CORBA::is_nil(resManager))
- return properties;
-
- std::ostringstream value;
- Engines::ResourceDefinition_var resource_definition = resManager->GetResourceDefinition(name.c_str());
- properties["hostname"]=resource_definition->hostname.in();
- properties["OS"]=resource_definition->OS.in();
- value.str(""); value << resource_definition->mem_mb;
- properties["mem_mb"]=value.str();
- value.str(""); value << resource_definition->cpu_clock;
- properties["cpu_clock"]=value.str();
- value.str(""); value << resource_definition->nb_node;
- properties["nb_node"]=value.str();
- value.str(""); value << resource_definition->nb_proc_per_node;
- properties["nb_proc_per_node"]=value.str();
- /*
- properties["component_list"]="";
- for(CORBA::ULong i=0; i < resource_definition->componentList.length(); i++)
- {
- if(i > 0)
- properties["component_list"]=properties["component_list"]+",";
- properties["component_list"]=properties["component_list"]+resource_definition->componentList[i].in();
- }
- */
- return properties;
+ return _sct->getProperties();
}
-/*!
- * \param [in] compoNames
- * \param [in,out] shutdownLevel
- */
-void SalomeContainerTools::Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerTools& sct, int& shutdownLevel, const Container *cont, const Task *askingNode)
+void SalomeContainerToolsDecoratorBase::clearProperties()
{
- CORBA::ORB_ptr orb(getSALOMERuntime()->getOrb());
- SALOME_NamingService ns;
- try
- {
- ns.init_orb(orb);
- }
- catch(SALOME_Exception& e)
- {
- throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
- }
- CORBA::Object_var obj(ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS));
- Engines::ContainerManager_var contManager(Engines::ContainerManager::_narrow(obj));
-
- bool isEmptyName;
- std::string str(sct.getNotNullContainerName(cont,askingNode,isEmptyName));
- DEBTRACE("SalomeContainer::start " << str <<";"<< _sct.getHostName() <<";"<<_type);
-
- // Finalize parameters with components found in the container
-
- for(std::vector<std::string>::const_iterator iter=compoNames.begin();iter!=compoNames.end();iter++)
- sct.addToComponentList(*iter);
-
- Engines::ContainerParameters myparams(sct.getParameters());
- {
- std::string dftLauchMode(schelp->getDftLaunchMode());
- myparams.mode=CORBA::string_dup(dftLauchMode.c_str());
- }
-
- //If a container_name is given try to find an already existing container in naming service
- //If not found start a new container with the given parameters
- if (dynamic_cast<SalomeContainerMonoHelper *>(schelp) && !isEmptyName)
- {
- myparams.mode=CORBA::string_dup("getorstart");
- }
-
- if (isEmptyName)
- {
- shutdownLevel=1;
- }
- //sct.setContainerName(str);
- SetContainerNameOf(myparams,str);
- Engines::Container_var trueCont(Engines::Container::_nil());
- if(!isEmptyName && shutdownLevel==999)
- {
- //Make this only the first time start is called (_shutdownLevel==999)
- //If the container is named, first try to get an existing container
- //If there is an existing container use it and set the shutdown level to 3
- //If there is no existing container, try to launch a new one and set the shutdown level to 2
- myparams.mode="get";
- try
- {
- trueCont=contManager->GiveContainer(myparams);
- }
- catch( const SALOME::SALOME_Exception& ex )
- {
- std::string msg="SalomeContainer::start : no existing container : ";
- msg += '\n';
- msg += ex.details.text.in();
- DEBTRACE( msg );
- }
- catch(...)
- {
- }
-
- if(!CORBA::is_nil(trueCont))
- {
- shutdownLevel=3;
- DEBTRACE( "container found: " << str << " " << _shutdownLevel );
- }
- else
- {
- shutdownLevel=2;
- myparams.mode="start";
- DEBTRACE( "container not found: " << str << " " << _shutdownLevel);
- }
- }
-
- if(CORBA::is_nil(trueCont))
- try
- {
- // --- GiveContainer is used in batch mode to retreive launched containers,
- // and is equivalent to StartContainer when not in batch.
- trueCont=contManager->GiveContainer(myparams);
- }
- catch( const SALOME::SALOME_Exception& ex )
- {
- std::string msg="SalomeContainer::start : Unable to launch container in Salome : ";
- msg += '\n';
- msg += ex.details.text.in();
- throw Exception(msg);
- }
- catch(CORBA::COMM_FAILURE&)
- {
- throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
- }
- catch(CORBA::Exception&)
- {
- throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
- }
-
- if(CORBA::is_nil(trueCont))
- throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
-
- schelp->setContainer(askingNode,trueCont);
+ _sct->clearProperties();
+}
- CORBA::String_var containerName(trueCont->name()),hostName(trueCont->getHostName());
- std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << trueCont->getPID() << std::endl;
+std::map<std::string,std::string> SalomeContainerToolsDecoratorBase::getResourceProperties(const std::string& name) const
+{
+ return _sct->getResourceProperties(name);
}
-CORBA::Object_ptr SalomeContainerTools::LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode)
+void SalomeContainerToolsDecoratorBase::addToComponentList(const std::string& name)
{
- DEBTRACE("SalomeContainer::loadComponent ");
- const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
- {
- YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
- if(!cont->isAlreadyStarted(askingNode))
- cont->start(askingNode);
- }
- if(!inst)
- throw Exception("SalomeContainerTools::LoadComponent : no instance of component in the task requesting for a load of its component !");
- CORBA::Object_ptr objComponent=CORBA::Object::_nil();
- {
- YACS::BASES::AutoLocker<Container> alck(cont);//To be sure
- std::string compoName(inst->getCompoName());
- Engines::Container_var container(launchModeType->getContainer(askingNode));
+ _sct->addToComponentList(name);
+}
- char *reason;
- bool isLoadable(container->load_component_Library(compoName.c_str(), reason));
- if(isLoadable)
- objComponent=CreateComponentInstance(cont,container,inst);
- }
- return objComponent;
+void SalomeContainerToolsDecoratorBase::addToResourceList(const std::string& name)
+{
+ _sct->addToResourceList(name);
}
-CORBA::Object_ptr SalomeContainerTools::CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst)
+Engines::ContainerParameters SalomeContainerToolsDecoratorBase::getParameters() const
{
- if(!inst)
- throw Exception("SalomeContainerTools::CreateComponentInstance : no instance of component in the task requesting for a load of its component !");
- char *reason(0);
- std::string compoName(inst->getCompoName());
- CORBA::Object_ptr objComponent=CORBA::Object::_nil();
- Proc* p(cont->getProc());
- // prepare component instance properties
- Engines::FieldsDict_var env(new Engines::FieldsDict);
- std::map<std::string, std::string> properties(inst->getProperties());
- if(p)
- {
- std::map<std::string,std::string> procMap=p->getProperties();
- properties.insert(procMap.begin(),procMap.end());
- }
+ return _sct->getParameters();
+}
- std::map<std::string, std::string>::const_iterator itm;
- env->length(properties.size());
- int item=0;
- for(itm = properties.begin(); itm != properties.end(); ++itm, item++)
- {
- DEBTRACE("envname="<<itm->first<<" envvalue="<< itm->second);
- env[item].key= CORBA::string_dup(itm->first.c_str());
- env[item].value <<= itm->second.c_str();
- }
+std::string SalomeContainerToolsDecoratorBase::getContainerName() const
+{
+ return _sct->getContainerName();
+}
- objComponent=contPtr->create_component_instance_env(compoName.c_str(), env, reason);
- if(CORBA::is_nil(objComponent))
- {
- std::string text="Error while trying to create a new component: component '"+ compoName;
- text=text+"' is not installed or it's a wrong name";
- text += '\n';
- text += reason;
- CORBA::string_free(reason);
- throw Exception(text);
- }
- return objComponent;
+void SalomeContainerToolsDecoratorBase::setContainerName(const std::string& name)
+{
+ _sct->setContainerName(name);
}
-std::string SalomeContainerTools::GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
+std::string SalomeContainerToolsDecoratorBase::getHostName() const
{
- if(cont->isAlreadyStarted(askingNode))
- {
- Engines::Container_var container(launchModeType->getContainer(askingNode));
- const char *what="/";
- CORBA::String_var corbaStr(container->name());
- std::string ret(corbaStr);
+ return _sct->getHostName();
+}
- //Salome FOREVER ...
- std::string::size_type i=ret.find_first_of(what,0);
- i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
- if(i!=std::string::npos)
- return ret.substr(i+1);
- return ret;
- }
- else
- return "Not placed yet !!!";
+
+std::string SalomeContainerToolsDecoratorBase::getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const
+{
+ return _sct->getNotNullContainerName(contPtr,askingNode,isEmpty);
}
-std::string SalomeContainerTools::GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
+//////////////////////////////
+
+Engines::ContainerParameters SalomeContainerToolsSpreadOverTheResDecorator::getParameters() const
{
- if(cont->isAlreadyStarted(askingNode))
- {
- Engines::Container_var container(launchModeType->getContainer(askingNode));
- try
- {
- CORBA::String_var corbaStr(container->name());
- std::string ret(corbaStr);
- return ret;
- }
- catch(...)
- {
- return "Unknown_placement";
- }
- }
- else
- return "Not_placed_yet";
+ Engines::ContainerParameters ret(getWorker()->getParameters());
+ std::string st(ret.resource_params.hostname);
+ if(!st.empty())
+ return ret;
+ int nbProcPerNode(ret.resource_params.nb_proc_per_node);
+ std::size_t iPos(_vh->locateTask(_node)),nPos(_vh->size());
+ if(_vh->size()!=_pg->getNumberOfWorkers(nbProcPerNode))
+ throw YACS::Exception("SalomeContainerToolsSpreadOverTheResDecorator::getParameters : Internal error !");
+ std::string zeMachine(_pg->deduceMachineFrom(iPos,nbProcPerNode));
+ ret.resource_params.hostname=CORBA::string_dup(zeMachine.c_str());
+ return ret;
}
class ComponentInstance;
class SalomeContainerHelper;
- class YACSRUNTIMESALOME_EXPORT SalomeContainerTools
+ class YACSRUNTIMESALOME_EXPORT SalomeContainerToolsBase
+ {
+ public:
+ virtual ~SalomeContainerToolsBase() { }
+ virtual std::string getProperty(const std::string& name) const = 0;
+ virtual void setProperty(const std::string& name, const std::string& value) = 0;
+ virtual const std::map<std::string,std::string>& getProperties() const = 0;
+ virtual void clearProperties() = 0;
+ virtual std::map<std::string,std::string> getResourceProperties(const std::string& name) const = 0;
+ virtual void addToComponentList(const std::string& name) = 0;
+ virtual void addToResourceList(const std::string& name) = 0;
+ virtual Engines::ContainerParameters getParameters() const = 0;
+ virtual std::string getContainerName() const = 0;
+ virtual void setContainerName(const std::string& name) = 0;
+ virtual std::string getHostName() const = 0;
+ virtual std::string getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const = 0;
+ public:
+ static void Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerToolsBase& sct, int& shutdownLevel, const Container *cont, const Task *askingNode);
+ static CORBA::Object_ptr LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode);
+ static CORBA::Object_ptr CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst);
+ static std::string GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode);
+ static std::string GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode);
+ static void SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name);
+ };
+
+ class YACSRUNTIMESALOME_EXPORT SalomeContainerToolsInter : public SalomeContainerToolsBase
+ {
+ public:
+ SalomeContainerToolsInter() { }
+ SalomeContainerToolsInter(const SalomeContainerToolsInter& other);
+ std::string getProperty(const std::string& name) const;
+ const std::map<std::string,std::string>& getProperties() const { return _propertyMap; }
+ void clearProperties();
+ std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
+ protected:
+ std::map<std::string,std::string> _propertyMap;
+ };
+
+ class YACSRUNTIMESALOME_EXPORT SalomeContainerTools : public SalomeContainerToolsInter
{
public:
SalomeContainerTools();
SalomeContainerTools(const SalomeContainerTools& other);
+ int getNumberOfCoresPerWorker() const;
+ public:
+ Engines::ContainerParameters getParameters() const { return _params; }
+ void clearProperties();
+ void setProperty(const std::string& name, const std::string& value);
+ void addToComponentList(const std::string& name);
+ void addToResourceList(const std::string& name);
+ std::string getContainerName() const;
+ void setContainerName(const std::string& name);
+ std::string getHostName() const;
+ std::string getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const;
+ protected:
+ Engines::ContainerParameters _params;
+ };
+
+ class PlayGround;
+
+ class YACSRUNTIMESALOME_EXPORT SalomeContainerToolsDecoratorBase : public SalomeContainerToolsBase
+ {
+ protected:
+ SalomeContainerToolsDecoratorBase(SalomeContainerToolsBase *sct):_sct(sct) { }
+ SalomeContainerToolsBase *getWorker() { return _sct; }
+ const SalomeContainerToolsBase *getWorker() const { return _sct; }
+ public:
std::string getProperty(const std::string& name) const;
void setProperty(const std::string& name, const std::string& value);
- const std::map<std::string,std::string>& getProperties() const { return _propertyMap; }
+ const std::map<std::string,std::string>& getProperties() const;
void clearProperties();
std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
void addToComponentList(const std::string& name);
void addToResourceList(const std::string& name);
- public:
+ Engines::ContainerParameters getParameters() const;
std::string getContainerName() const;
void setContainerName(const std::string& name);
- std::string getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const;
std::string getHostName() const;
- Engines::ContainerParameters getParameters() const { return _params; }
- static void SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name);
+ std::string getNotNullContainerName(const Container *contPtr, const Task *askingNode, bool& isEmpty) const;
+ private:
+ SalomeContainerToolsBase *_sct;
+ };
+
+ class SalomeHPContainerVectOfHelper;
+
+ class YACSRUNTIMESALOME_EXPORT SalomeContainerToolsSpreadOverTheResDecorator : public SalomeContainerToolsDecoratorBase
+ {
public:
- static void Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerTools& sct, int& shutdownLevel, const Container *cont, const Task *askingNode);
- static CORBA::Object_ptr LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode);
- static CORBA::Object_ptr CreateComponentInstance(Container *cont, Engines::Container_ptr contPtr, const ComponentInstance *inst);
- static std::string GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode);
- static std::string GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode);
- protected:
- std::map<std::string,std::string> _propertyMap;
- Engines::ContainerParameters _params;
+ SalomeContainerToolsSpreadOverTheResDecorator(SalomeContainerToolsBase *sct, const PlayGround *pg, const SalomeHPContainerVectOfHelper *vh, const Task *node):SalomeContainerToolsDecoratorBase(sct),_pg(pg),_vh(vh),_node(node) { }
+ Engines::ContainerParameters getParameters() const;
+ private:
+ static std::string DeduceMachineFrom(const std::vector< std::pair<std::string,int> >& allResInfo, int iPos, int sz, int nbProcPerNode);
+ private:
+ const PlayGround *_pg;
+ const SalomeHPContainerVectOfHelper *_vh;
+ const Task *_node;
};
}
}
#include "SalomeHPComponent.hxx"
#include "SalomeContainerTmpForHP.hxx"
#include "AutoLocker.hxx"
+#include "AutoRefCnt.hxx"
#include <algorithm>
const char SalomeHPContainer::KIND[]="HPSalome";
-SalomeHPContainer::SalomeHPContainer():_shutdownLevel(999)
+SalomeHPContainerBase::SalomeHPContainerBase(SalomeHPContainerVectOfHelper *resShared):_launchModeType(resShared),_shutdownLevel(999)
{
}
-SalomeHPContainer::SalomeHPContainer(const SalomeHPContainer& other):_componentNames(other._componentNames),_shutdownLevel(999),_sct(other._sct),_initScript(other._initScript)
+SalomeHPContainerBase::SalomeHPContainerBase(const SalomeHPContainerBase& other):_shutdownLevel(999),_launchModeType(new SalomeHPContainerVectOfHelper),_initScript(other._initScript)
{
}
-void SalomeHPContainer::setSizeOfPool(int sz)
+SalomeHPContainer *SalomeHPContainerBase::getTheBoss()
{
- _launchModeType.resize(sz);
+ HomogeneousPoolContainer *ret(this);
+ while(ret->getDirectFather())
+ ret=ret->getDirectFather();
+ SalomeHPContainer *retC(dynamic_cast<SalomeHPContainer *>(ret));
+ if(!retC)
+ throw Exception("SalomeHPContainerBase::getTheBoss : unexpected type of object !");
+ return retC;
}
-int SalomeHPContainer::getSizeOfPool() const
+const SalomeHPContainer *SalomeHPContainerBase::getTheBoss() const
{
- return _launchModeType.size();
+ const HomogeneousPoolContainer *ret(this);
+ while(ret->getDirectFather())
+ ret=ret->getDirectFather();
+ const SalomeHPContainer *retC(dynamic_cast<const SalomeHPContainer *>(ret));
+ if(!retC)
+ throw Exception("SalomeHPContainerBase::getTheBoss : unexpected type of object !");
+ return retC;
}
-std::size_t SalomeHPContainer::getNumberOfFreePlace() const
+void SalomeHPContainerBase::startInternal(const Task *askingNode, SalomeContainerToolsBase& sct, const std::vector<std::string>& compoNames)
{
- return _launchModeType.getNumberOfFreePlace();
+ SalomeContainerMonoHelper *helper(_launchModeType->getHelperOfTaskThreadSafe(askingNode));
+ SalomeContainerTools::Start(compoNames,helper,sct,_shutdownLevel,this,askingNode);
}
-void SalomeHPContainer::allocateFor(const std::vector<const Task *>& nodes)
+void SalomeHPContainerBase::shutdown(int level)
{
- _launchModeType.allocateFor(nodes);
+ if(level < _shutdownLevel)
+ return;
+ _shutdownLevel=999;
+ _launchModeType->shutdown();
}
-void SalomeHPContainer::release(const Task *node)
+SalomeHPContainerBase::SalomeHPContainerBase(SalomeHPContainerVectOfHelper *resShared, bool isRefEaten):_launchModeType(resShared)
{
- _launchModeType.release(node);
+ if(!isRefEaten)
+ if(_launchModeType.isNotNull())
+ _launchModeType->incrRef();
}
-SalomeHPContainer::~SalomeHPContainer()
+bool SalomeHPContainerBase::isAlreadyStarted(const Task *askingNode) const
{
+ const SalomeContainerMonoHelper *helper(_launchModeType->getHelperOfTaskThreadSafe(askingNode));
+ return helper->isAlreadyStarted(askingNode);
}
-void SalomeHPContainer::lock()
+void SalomeHPContainerBase::release(const Task *node)
{
- _mutex.lock();
+ _launchModeType->release(node);
}
-void SalomeHPContainer::unLock()
+void SalomeHPContainerBase::lock()
{
- _mutex.unLock();
+ _launchModeType->lock();
}
-std::string SalomeHPContainer::getKind() const
+void SalomeHPContainerBase::unLock()
{
- return KIND;
+ _launchModeType->unLock();
}
-std::string SalomeHPContainer::getDiscreminantStrOfThis(const Task *askingNode) const
+void SalomeHPContainerBase::setSizeOfPool(int sz)
{
- YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(this,askingNode));
- return tmpCont->getDiscreminantStrOfThis(askingNode);
+ _launchModeType->resize(sz);
}
-bool SalomeHPContainer::isAlreadyStarted(const Task *askingNode) const
+int SalomeHPContainerBase::getSizeOfPool() const
{
- const SalomeContainerMonoHelper *helper(_launchModeType.getHelperOfTaskThreadSafe(this,askingNode));
- return helper->isAlreadyStarted(askingNode);
+ return _launchModeType->size();
}
-void SalomeHPContainer::start(const Task *askingNode) throw(YACS::Exception)
+void SalomeHPContainerBase::setProperty(const std::string& name,const std::string& value)
{
- SalomeContainerMonoHelper *helper(_launchModeType.getHelperOfTaskThreadSafe(this,askingNode));
- SalomeContainerTools::Start(_componentNames,helper,_sct,_shutdownLevel,this,askingNode);
+ if(name==AOC_ENTRY)//no sense to set it ! It is always true ! ignore it !
+ return ;
+ else if(name==SIZE_OF_POOL_KEY)
+ {
+ std::istringstream iss(value);
+ int val(0);
+ iss >> val;
+ setSizeOfPool(val);
+ }
+ else if(name==INITIALIZE_SCRIPT_KEY)
+ {
+ _initScript=value;
+ }
+ else
+ getTheBoss()->getContainerInfo().setProperty(name,value);
}
-void SalomeHPContainer::shutdown(int level)
+std::string SalomeHPContainerBase::getProperty(const std::string& name) const
{
- if(level < _shutdownLevel)
- return;
- _shutdownLevel=999;
- for(std::size_t i=0;i<_launchModeType.size();i++)
+ if(name==AOC_ENTRY)
{
- SalomeContainerMonoHelper *helper(_launchModeType.at(i));
- helper->shutdown();
+ return std::string("1");
}
+ else if(name==SIZE_OF_POOL_KEY)
+ {
+ std::ostringstream oss; oss << getSizeOfPool();
+ return oss.str();
+ }
+ else if(name==INITIALIZE_SCRIPT_KEY)
+ {
+ return _initScript;
+ }
+ else
+ return getTheBoss()->getContainerInfo().getProperty(name);
+}
+
+std::map<std::string,std::string> SalomeHPContainerBase::getProperties() const
+{
+ std::map<std::string,std::string> ret(getTheBoss()->getContainerInfo().getProperties());
+ std::ostringstream oss; oss << getSizeOfPool();
+ ret[SIZE_OF_POOL_KEY]=oss.str();
+ if(!_initScript.empty())
+ ret[INITIALIZE_SCRIPT_KEY]=_initScript;
+ return ret;
+}
+
+void SalomeHPContainerBase::clearProperties()
+{
+ _initScript.clear();
+ getTheBoss()->getContainerInfo().clearProperties();
}
-std::string SalomeHPContainer::getPlacementId(const Task *askingNode) const
+std::string SalomeHPContainerBase::getPlacementId(const Task *askingNode) const
{
const SalomeContainerMonoHelper *helper(0);
{
- YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainer *>(this));
- helper=_launchModeType.getHelperOfTask(askingNode);
+ YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainerBase *>(this));
+ helper=_launchModeType->getHelperOfTask(askingNode);
}
return SalomeContainerTools::GetPlacementId(helper,this,askingNode);
}
-std::string SalomeHPContainer::getFullPlacementId(const Task *askingNode) const
+std::string SalomeHPContainerBase::getFullPlacementId(const Task *askingNode) const
{
const SalomeContainerMonoHelper *helper(0);
{
- YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainer *>(this));
- helper=_launchModeType.getHelperOfTask(askingNode);
+ YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainerBase *>(this));
+ helper=_launchModeType->getHelperOfTask(askingNode);
}
return SalomeContainerTools::GetFullPlacementId(helper,this,askingNode);
}
+std::map<std::string,std::string> SalomeHPContainerBase::getResourceProperties(const std::string& name) const
+{
+ return getTheBoss()->getResourceProperties(name);
+}
+
+void SalomeHPContainerBase::addComponentName(const std::string& name)
+{
+ getTheBoss()->addComponentNameSpe(name);
+}
+
+void SalomeHPContainerBase::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception)
+{
+ getTheBoss()->checkCapabilityToDealWith(inst);
+}
+
+YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> SalomeHPContainerBase::decorate(YACS::BASES::AutoConstRefCnt<PartDefinition> pd)
+{
+ YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> ret(new SalomeHPContainerShared(pd,_launchModeType,this));
+ return ret;
+}
+
+Engines::Container_var SalomeHPContainerBase::getContainerPtr(const Task *askingNode) const
+{
+ const SalomeContainerMonoHelper *helper(0);
+ {
+ YACS::BASES::AutoLocker<SalomeHPContainerBase> alck(const_cast<SalomeHPContainerBase *>(this));
+ helper=_launchModeType->getHelperOfTask(askingNode);
+ }
+ return helper->getContainer(NULL);
+}
+
+std::vector<std::string> SalomeHPContainerBase::getKernelContainerNames() const
+{
+ return _launchModeType->getKernelContainerNames();
+}
+
+////////////////
+
+SalomeHPContainer::SalomeHPContainer():SalomeHPContainerBase(new SalomeHPContainerVectOfHelper)
+{
+}
+
+SalomeHPContainer::SalomeHPContainer(const SalomeHPContainer& other):SalomeHPContainerBase(other),_sct(other._sct),_componentNames(other._componentNames)
+{
+}
+
+std::size_t SalomeHPContainer::getNumberOfFreePlace() const
+{
+ return _launchModeType->getNumberOfFreePlace();
+}
+
+void SalomeHPContainer::allocateFor(const std::vector<const Task *>& nodes)
+{
+ _launchModeType->allocateFor(nodes);
+}
+
+SalomeHPContainer::~SalomeHPContainer()
+{
+}
+
+std::string SalomeHPContainer::getKind() const
+{
+ return KIND;
+}
+
+std::string SalomeHPContainer::getDiscreminantStrOfThis(const Task *askingNode) const
+{
+ YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(this,askingNode));
+ return tmpCont->getDiscreminantStrOfThis(askingNode);
+}
+
+void SalomeHPContainer::start(const Task *askingNode) throw(Exception)
+{
+ startInternal(askingNode,_sct,_componentNames);
+}
+
/*!
* It is not a bug here ! clone for homogeneous container is not supposed to be copied !
*/
return new SalomeHPContainer(*this);
}
-void SalomeHPContainer::setProperty(const std::string& name,const std::string& value)
+int SalomeHPContainer::getNumberOfCoresPerWorker() const
{
- if(name==AOC_ENTRY)//no sense to set it ! It is always true ! ignore it !
- return ;
- else if(name==SIZE_OF_POOL_KEY)
- {
- std::istringstream iss(value);
- int val(0);
- iss >> val;
- setSizeOfPool(val);
- }
- else if(name==INITIALIZE_SCRIPT_KEY)
- {
- _initScript=value;
- }
- else
- _sct.setProperty(name,value);
+ return _sct.getNumberOfCoresPerWorker();
}
-std::string SalomeHPContainer::getProperty(const std::string& name) const
+std::map<std::string,std::string> SalomeHPContainer::getResourcePropertiesSpe(const std::string& name) const
{
- if(name==AOC_ENTRY)
- {
- return std::string("1");
- }
- else if(name==SIZE_OF_POOL_KEY)
- {
- std::ostringstream oss; oss << getSizeOfPool();
- return oss.str();
- }
- else if(name==INITIALIZE_SCRIPT_KEY)
- {
- return _initScript;
- }
- else
- return _sct.getProperty(name);
+ return _sct.getResourceProperties(name);
}
-void SalomeHPContainer::clearProperties()
+void SalomeHPContainer::addComponentNameSpe(const std::string& name)
{
- _initScript.clear();
- _sct.clearProperties();
+ _componentNames.push_back(name);
}
-void SalomeHPContainer::addComponentName(const std::string& name)
+void SalomeHPContainer::checkCapabilityToDealWithSpe(const ComponentInstance *inst) const throw(YACS::Exception)
{
- _componentNames.push_back(name);
+ if(inst->getKind()!=SalomeHPComponent::KIND)
+ throw Exception("SalomeHPContainer::checkCapabilityToDealWithSpe : SalomeContainer is not able to deal with this type of ComponentInstance.");
}
-std::map<std::string,std::string> SalomeHPContainer::getProperties() const
+void SalomeHPContainer::forYourTestsOnly(ForTestOmlyHPContCls *data) const
{
- std::map<std::string,std::string> ret(_sct.getProperties());
- std::ostringstream oss; oss << getSizeOfPool();
- ret[SIZE_OF_POOL_KEY]=oss.str();
- if(!_initScript.empty())
- ret[INITIALIZE_SCRIPT_KEY]=_initScript;
- return ret;
+ data->setContainerType("HPContainer");
}
-std::map<std::string,std::string> SalomeHPContainer::getResourceProperties(const std::string& name) const
+//////////////////////////////////
+
+SalomeHPContainerShared::SalomeHPContainerShared(YACS::BASES::AutoConstRefCnt<PartDefinition> pd, SalomeHPContainerVectOfHelper *resShared, SalomeHPContainerBase *directFather):SalomeHPContainerBase(resShared,false),_pd(pd)
{
- return _sct.getResourceProperties(name);
+ if(!directFather)
+ throw Exception("SalomeHPContainerShared : NULL pointer not allowed !");
+ _directFather.takeRef(directFather);
}
-void SalomeHPContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception)
+std::string SalomeHPContainerShared::getKind() const
{
- if(inst->getKind()!=SalomeHPComponent::KIND)
- throw Exception("SalomeHPContainer::checkCapabilityToDealWith : SalomeContainer is not able to deal with this type of ComponentInstance.");
+ return SalomeHPContainer::KIND;
}
+
+void SalomeHPContainerShared::prepareMaskForExecution() const
+{
+ _idsOfKernelContainers=_pd->computeWorkerIdsCovered(getNumberOfCoresPerWorker());
+}
+
+/*!
+ * It is not a bug here ! clone for homogeneous container is not supposed to be copied !
+ */
+Container *SalomeHPContainerShared::clone() const
+{
+ incrRef();
+ return const_cast<SalomeHPContainerShared*>(this);
+}
+
+Container *SalomeHPContainerShared::cloneAlways() const
+{
+ throw Exception("SalomeHPContainerShared::cloneAlways : you are not supposed to be in this situation ! This type of container has only existence during execution !");
+}
+
+std::string SalomeHPContainerShared::getName() const
+{
+ return getTheBoss()->getName();
+}
+
+std::string SalomeHPContainerShared::getDiscreminantStrOfThis(const Task *askingNode) const
+{
+ return getTheBoss()->getDiscreminantStrOfThis(askingNode);
+}
+
+void SalomeHPContainerShared::start(const Task *askingNode) throw(Exception)
+{
+ SalomeContainerToolsSpreadOverTheResDecorator sct(&getTheBoss()->getContainerInfo(),_pd->getPlayGround(),_launchModeType,askingNode);
+ startInternal(askingNode,sct,getTheBoss()->getComponentNames());
+}
+
+void SalomeHPContainerShared::allocateFor(const std::vector<const Task *>& nodes)
+{
+ _launchModeType->allocateForAmong(_idsOfKernelContainers,nodes);
+}
+
+std::size_t SalomeHPContainerShared::getNumberOfFreePlace() const
+{
+ return _launchModeType->getNumberOfFreePlaceAmong(_idsOfKernelContainers);
+}
+
+void SalomeHPContainerShared::forYourTestsOnly(ForTestOmlyHPContCls *data) const
+{
+ data->setContainerType("HPContainerShared");
+ data->setPD(_pd);
+ data->setIDS(_idsOfKernelContainers);
+}
+
+/*
+ * SalomeHPContainerVectOfHelper is an holder of vector of SalomeContainerMonoHelper (holding itself a Kernel Container)
+ * SalomeContainerTools is a Engines::ContainerParameters holder. It is the data keeper for GiveContainer invokation.
+ *
+ */
#include "SalomeContainerHelper.hxx"
#include "SalomeContainerTools.hxx"
#include "SalomeHPContainerTools.hxx"
+#include "PlayGround.hxx"
+
#include "Mutex.hxx"
+#include "AutoRefCnt.hxx"
+
#include <string>
#include <vector>
#include <map>
{
class Task;
class SalomeComponent;
-
- class YACSRUNTIMESALOME_EXPORT SalomeHPContainer : public HomogeneousPoolContainer
+ class SalomeHPContainer;
+
+ class YACSRUNTIMESALOME_EXPORT SalomeHPContainerBase : public HomogeneousPoolContainer
{
+ protected:
+ SalomeHPContainerBase(SalomeHPContainerVectOfHelper *resShared);
+ SalomeHPContainerBase(SalomeHPContainerVectOfHelper *resShared, bool isRefEaten);
+ SalomeHPContainerBase(const SalomeHPContainerBase& other);
+ void startInternal(const Task *askingNode, SalomeContainerToolsBase& sct, const std::vector<std::string>& compoNames);
+ SalomeHPContainer *getTheBoss();
+ const SalomeHPContainer *getTheBoss() const;
public:
- SalomeHPContainer();
- SalomeHPContainer(const SalomeHPContainer& other);
- //HP specific part
- void setSizeOfPool(int sz);
- int getSizeOfPool() const;
- std::size_t getNumberOfFreePlace() const;
- void allocateFor(const std::vector<const Task *>& nodes);
void release(const Task *node);
+ //
+ bool isAlreadyStarted(const Task *askingNode) const;
+ void shutdown(int level);
//! For thread safety for concurrent load operation on same Container.
void lock();
//! For thread safety for concurrent load operation on same Container.
void unLock();
+ void setSizeOfPool(int sz);
+ int getSizeOfPool() const;
+ void setProperty(const std::string& name,const std::string& value);
+ std::string getProperty(const std::string& name) const;
+ std::map<std::string,std::string> getProperties() const;
+ void clearProperties();
+ std::string getPlacementId(const Task *askingNode) const;
+ std::string getFullPlacementId(const Task *askingNode) const;
+ std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
+ void addComponentName(const std::string& name);
+ void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception);
+ Engines::Container_var getContainerPtr(const Task *askingNode) const;
+ std::vector<std::string> getKernelContainerNames() const;
+ public:
+ int getShutdownLev() const { return _shutdownLevel; }
+ YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> decorate(YACS::BASES::AutoConstRefCnt<PartDefinition> pd);
+#ifndef SWIG
+ const SalomeHPContainerVectOfHelper *getDirectAccessToVecOfCont() const { return _launchModeType; }
+#endif
+ protected:
+ int _shutdownLevel;
+ YACS::BASES::AutoRefCnt<SalomeHPContainerVectOfHelper> _launchModeType;
+ std::string _initScript;
+ };
+
+ class YACSRUNTIMESALOME_EXPORT SalomeHPContainer : public SalomeHPContainerBase
+ {
+ public:
+ SalomeHPContainer();
+ SalomeHPContainer(const SalomeHPContainer& other);
+ //HP specific part
+ std::size_t getNumberOfFreePlace() const;
+ void allocateFor(const std::vector<const Task *>& nodes);
//
std::string getKind() const;
std::string getDiscreminantStrOfThis(const Task *askingNode) const;
- bool isAlreadyStarted(const Task *askingNode) const;
void start(const Task *askingNode) throw(Exception);
- void shutdown(int level);
- std::string getPlacementId(const Task *askingNode) const;
- std::string getFullPlacementId(const Task *askingNode) const;
Container *clone() const;
Container *cloneAlways() const;
- void setProperty(const std::string& name,const std::string& value);
- std::string getProperty(const std::string& name) const;
- void clearProperties();
- void addComponentName(const std::string& name);
- std::map<std::string,std::string> getProperties() const;
- std::map<std::string,std::string> getResourceProperties(const std::string& name) const;
- void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception);
+ int getNumberOfCoresPerWorker() const;
+ //! do nothing. because no special actions to do. Only for decorators
+ void prepareMaskForExecution() const { }
//
#ifndef SWIG
- std::size_t locateTask(const Task *askingNode) const { return _launchModeType.locateTask(askingNode); }
+ void forYourTestsOnly(ForTestOmlyHPContCls *data) const;
+ std::map<std::string,std::string> getResourcePropertiesSpe(const std::string& name) const;
+ void addComponentNameSpe(const std::string& name);
+ void checkCapabilityToDealWithSpe(const ComponentInstance *inst) const throw(YACS::Exception);
+ std::size_t locateTask(const Task *askingNode) const { return _launchModeType->locateTask(askingNode); }
const SalomeContainerTools &getContainerInfo() const { return _sct; }
+ SalomeContainerTools &getContainerInfo() { return _sct; }
std::vector<std::string> getComponentNames() const { return _componentNames; }
- int getShutdownLev() const { return _shutdownLevel; }
- SalomeContainerMonoHelper *getHelperOfTask(const Task *node) { return _launchModeType.getHelperOfTask(node); }
- const SalomeContainerMonoHelper *getHelperOfTask(const Task *node) const { return _launchModeType.getHelperOfTask(node); }
+ SalomeContainerMonoHelper *getHelperOfTask(const Task *node) { return _launchModeType->getHelperOfTask(node); }
+ const SalomeContainerMonoHelper *getHelperOfTask(const Task *node) const { return _launchModeType->getHelperOfTask(node); }
//
- YACS::BASES::Mutex& getLocker() { return _mutex; }
+ HomogeneousPoolContainer *getDirectFather() { return NULL; }
+ const HomogeneousPoolContainer *getDirectFather() const { return NULL; }
#endif
public:
static const char KIND[];
~SalomeHPContainer();
#endif
protected:
- int _shutdownLevel;
SalomeContainerTools _sct;
- YACS::BASES::Mutex _mutex;
std::vector<std::string> _componentNames;
+ };
+
+#ifndef SWIG
+ class YACSRUNTIMESALOME_EXPORT SalomeHPContainerShared : public SalomeHPContainerBase
+ {
+ public:
+ SalomeHPContainerShared(YACS::BASES::AutoConstRefCnt<PartDefinition> pd, SalomeHPContainerVectOfHelper *resShared, SalomeHPContainerBase *directFather);
+ HomogeneousPoolContainer *getDirectFather() { return _directFather; }
+ const HomogeneousPoolContainer *getDirectFather() const { return _directFather; }
+ int getNumberOfCoresPerWorker() const { return _directFather->getNumberOfCoresPerWorker(); }
+ std::string getProperty(const std::string& name) const { return _directFather->getProperty(name); }
+ void prepareMaskForExecution() const;
+ void forYourTestsOnly(ForTestOmlyHPContCls *data) const;
+ std::string getName() const;
+ std::string getDiscreminantStrOfThis(const Task *askingNode) const;
+ public:
+ std::string getKind() const;
+ void start(const Task *askingNode) throw(Exception);
+ Container *clone() const;
+ Container *cloneAlways() const;
//
- SalomeHPContainerVectOfHelper _launchModeType;
- std::string _initScript;
+ void allocateFor(const std::vector<const Task *>& nodes);
+ std::size_t getNumberOfFreePlace() const;
+ private:
+ YACS::BASES::AutoRefCnt<SalomeHPContainerBase> _directFather;
+ YACS::BASES::AutoConstRefCnt<PartDefinition> _pd;
+ //! ids in _launchModeType covered by _pd.
+ mutable std::vector<std::size_t> _idsOfKernelContainers;
};
+#endif
}
}
#include "Exception.hxx"
#include <algorithm>
+#include <limits>
using namespace YACS::ENGINE;
return std::count(_whichOccupied.begin(),_whichOccupied.end(),false);
}
+std::size_t SalomeHPContainerVectOfHelper::getNumberOfFreePlaceAmong(const std::vector<std::size_t>& idsOfKernelContainers) const
+{
+ std::size_t ret;
+ for(std::vector<std::size_t>::const_iterator it=idsOfKernelContainers.begin();it!=idsOfKernelContainers.end();it++)
+ if(!_whichOccupied[*it])
+ ret++;
+ return ret;
+}
+
void SalomeHPContainerVectOfHelper::allocateFor(const std::vector<const Task *>& nodes)
{
for(std::vector<const Task *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
}
}
+void SalomeHPContainerVectOfHelper::allocateForAmong(const std::vector<std::size_t>& idsOfKernelContainers, const std::vector<const Task *>& nodes)
+{
+ for(std::vector<const Task *>::const_iterator it=nodes.begin();it!=nodes.end();it++)
+ {
+ if(!(*it))
+ continue;
+ if(_currentlyWorking.find(*it)!=_currentlyWorking.end())
+ throw Exception("Searching 2 to allocate for a ServiceNode instance already declared as allocated !");
+ std::size_t it2(std::numeric_limits<std::size_t>::max());
+ for(std::vector<std::size_t>::const_iterator it=idsOfKernelContainers.begin();it!=idsOfKernelContainers.end();it++)
+ if(!_whichOccupied[*it])
+ {
+ it2=*it;
+ break;
+ }
+ if(it2==std::numeric_limits<std::size_t>::max())
+ throw Exception("All 2 ressources are already occupied ! You are expected to wait for released resources !");
+ _currentlyWorking[*it]=it2; _whichOccupied[it2]=true;
+ }
+}
+
void SalomeHPContainerVectOfHelper::release(const Task *node)
{
if(!node)
return ret;
}
-const SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTaskThreadSafe(const SalomeHPContainer *cont, const Task *node) const
+const SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTaskThreadSafe(const Task *node) const
{
- YACS::BASES::AutoLocker<Container> alck(const_cast<SalomeHPContainer *>(cont));
+ YACS::BASES::AutoLocker<SalomeHPContainerVectOfHelper> alck(const_cast<SalomeHPContainerVectOfHelper *>(this));
return _launchModeType[locateTask(node)];
}
return _launchModeType[locateTask(node)];
}
-SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTaskThreadSafe(SalomeHPContainer *cont, const Task *node)
+SalomeContainerMonoHelper *SalomeHPContainerVectOfHelper::getHelperOfTaskThreadSafe(const Task *node)
{
- YACS::BASES::AutoLocker<Container> alck(cont);
+ YACS::BASES::AutoLocker<SalomeHPContainerVectOfHelper> alck(this);
return _launchModeType[locateTask(node)];
}
if(pos<0 || pos>=_launchModeType.size())
throw Exception("The task has been found, but its id is not in the correct range ! resize of of container size during run ?");
}
+
+void SalomeHPContainerVectOfHelper::shutdown()
+{
+ for(std::vector< BASES::AutoRefCnt<YACS::ENGINE::SalomeContainerMonoHelper> >::iterator it=_launchModeType.begin();it!=_launchModeType.end();it++)
+ if((*it).isNotNull())
+ if(!(*it)->isKernelContNull())
+ (*it)->shutdown();
+}
+
+std::vector<std::string> SalomeHPContainerVectOfHelper::getKernelContainerNames() const
+{
+ std::vector<std::string> ret;
+ {
+ YACS::BASES::AutoLocker<SalomeHPContainerVectOfHelper> alck(const_cast<SalomeHPContainerVectOfHelper *>(this));
+ std::size_t sz(_launchModeType.size());
+ ret.resize(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ ret[i]=_launchModeType[i]->getKernelContainerName();
+ }
+ }
+ return ret;
+}
+
+void SalomeHPContainerVectOfHelper::lock()
+{
+ _mutex.lock();
+}
+
+void SalomeHPContainerVectOfHelper::unLock()
+{
+ _mutex.unLock();
+}
#include "YACSRuntimeSALOMEExport.hxx"
#include "SalomeContainerHelper.hxx"
+#include "RefCounter.hxx"
+
+#include "Mutex.hxx"
#include "AutoRefCnt.hxx"
#include <map>
class SalomeComponent;
class SalomeHPContainer;
class SalomeContainerMonoHelper;
- class SalomeHPContainerVectOfHelper
+ class SalomeHPContainerVectOfHelper : public RefCounter
{
public:
std::size_t size() const { return _launchModeType.size(); }
void resize(std::size_t sz);
std::size_t getNumberOfFreePlace() const;
+ std::size_t getNumberOfFreePlaceAmong(const std::vector<std::size_t>& idsOfKernelContainers) const;
void allocateFor(const std::vector<const Task *>& nodes);
+ void allocateForAmong(const std::vector<std::size_t>& idsOfKernelContainers, const std::vector<const Task *>& nodes);
void release(const Task *node);
std::size_t locateTask(const Task *node) const;
const SalomeContainerMonoHelper *at(std::size_t pos) const { checkPosInVec(pos); return _launchModeType[pos]; }
SalomeContainerMonoHelper *at(std::size_t pos) { checkPosInVec(pos); return _launchModeType[pos]; }
- const SalomeContainerMonoHelper *getHelperOfTaskThreadSafe(const SalomeHPContainer *cont, const Task *node) const;
+ const SalomeContainerMonoHelper *getHelperOfTaskThreadSafe(const Task *node) const;
const SalomeContainerMonoHelper *getHelperOfTask(const Task *node) const;
- SalomeContainerMonoHelper *getHelperOfTaskThreadSafe(SalomeHPContainer *cont, const Task *node);
+ SalomeContainerMonoHelper *getHelperOfTaskThreadSafe(const Task *node);
SalomeContainerMonoHelper *getHelperOfTask(const Task *node);
+ void shutdown();
+ //! For thread safety for concurrent load operation on same Container.
+ void lock();
+ //! For thread safety for concurrent load operation on same Container.
+ void unLock();
+ public:
+ std::vector<std::string> getKernelContainerNames() const;
private:
+ ~SalomeHPContainerVectOfHelper() { }
void checkNoCurrentWork() const;
void checkPosInVec(std::size_t pos) const;
private:
+ YACS::BASES::Mutex _mutex;
std::vector<bool> _whichOccupied;
std::vector< BASES::AutoRefCnt<YACS::ENGINE::SalomeContainerMonoHelper> > _launchModeType;
std::map<const Task *,std::size_t > _currentlyWorking;
class TypeCode;
class Any;
- CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t);
+ YACSRUNTIMESALOME_EXPORT CORBA::TypeCode_ptr getCorbaTC(const TypeCode *t);
- int isAdaptableCorbaPyObject(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableCorbaNeutral(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableCorbaCorba(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableCorbaPyObject(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableCorbaNeutral(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableCorbaCorba(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableNeutralCorba(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableNeutralNeutral(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralCorba(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralNeutral(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralXml(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableNeutralPyObject(const TypeCode * t1, const TypeCode * t2);
- int isAdaptablePyObjectPyObject(const TypeCode * t1, const TypeCode * t2);
- int isAdaptablePyObjectCorba(const TypeCode * t1, const TypeCode * t2);
- int isAdaptablePyObjectNeutral(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptablePyObjectPyObject(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptablePyObjectCorba(const TypeCode * t1, const TypeCode * t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptablePyObjectNeutral(const TypeCode * t1, const TypeCode * t2);
- int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2);
- int isAdaptableXmlCorba(const TypeCode *t1, const TypeCode *t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableXmlNeutral(const TypeCode *t1,const TypeCode *t2);
+ YACSRUNTIMESALOME_EXPORT int isAdaptableXmlCorba(const TypeCode *t1, const TypeCode *t2);
- PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
- CORBA::Any *convertCorbaCorba(const TypeCode * t,CORBA::Any* ob);
- YACS::ENGINE::Any *convertCorbaNeutral(const TypeCode *t,CORBA::Any* ob);
- std::string convertCorbaXml(const TypeCode * t,CORBA::Any* ob);
+ YACSRUNTIMESALOME_EXPORT PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
+ YACSRUNTIMESALOME_EXPORT PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
+ YACSRUNTIMESALOME_EXPORT PyObject *convertCorbaPyObject(const TypeCode * t,CORBA::Any* ob);
+ YACSRUNTIMESALOME_EXPORT CORBA::Any *convertCorbaCorba(const TypeCode * t,CORBA::Any* ob);
+ YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertCorbaNeutral(const TypeCode *t,CORBA::Any* ob);
+ YACSRUNTIMESALOME_EXPORT std::string convertCorbaXml(const TypeCode * t,CORBA::Any* ob);
- CORBA::Any *convertPyObjectCorba(const TypeCode *t,PyObject *ob);
+ YACSRUNTIMESALOME_EXPORT CORBA::Any *convertPyObjectCorba(const TypeCode *t,PyObject *ob);
YACSRUNTIMESALOME_EXPORT std::string convertPyObjectXml(const TypeCode * t,PyObject* ob);
- YACS::ENGINE::Any *convertPyObjectNeutral(const TypeCode *t,PyObject* ob);
- PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *ob);
- std::string convertPyObjectToString(PyObject* ob);
- bool checkPyObject(const TypeCode *t,PyObject* ob);
-
- PyObject *convertXmlPyObject(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
- PyObject *convertXmlStrPyObject(const TypeCode * t,std::string data );
- CORBA::Any *convertXmlCorba(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
- YACS::ENGINE::Any *convertXmlNeutral(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
-
- PyObject *convertNeutralPyObject(const TypeCode * t,YACS::ENGINE::Any* ob);
- std::string convertNeutralXml(const TypeCode * t,YACS::ENGINE::Any* ob);
- CORBA::Any *convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any *ob);
- YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* ob);
+ YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertPyObjectNeutral(const TypeCode *t,PyObject* ob);
+ YACSRUNTIMESALOME_EXPORT PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *ob);
+ YACSRUNTIMESALOME_EXPORT std::string convertPyObjectToString(PyObject* ob);
+ YACSRUNTIMESALOME_EXPORT bool checkPyObject(const TypeCode *t,PyObject* ob);
+
+ YACSRUNTIMESALOME_EXPORT PyObject *convertXmlPyObject(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
+ YACSRUNTIMESALOME_EXPORT PyObject *convertXmlStrPyObject(const TypeCode * t,std::string data );
+ YACSRUNTIMESALOME_EXPORT CORBA::Any *convertXmlCorba(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
+ YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertXmlNeutral(const TypeCode * t,xmlDocPtr doc,xmlNodePtr cur );
+
+ YACSRUNTIMESALOME_EXPORT PyObject *convertNeutralPyObject(const TypeCode * t,YACS::ENGINE::Any* ob);
+ YACSRUNTIMESALOME_EXPORT std::string convertNeutralXml(const TypeCode * t,YACS::ENGINE::Any* ob);
+ YACSRUNTIMESALOME_EXPORT CORBA::Any *convertNeutralCorba(const TypeCode *t,YACS::ENGINE::Any *ob);
+ YACSRUNTIMESALOME_EXPORT YACS::ENGINE::Any *convertNeutralNeutral(const TypeCode *t, YACS::ENGINE::Any* ob);
}
}
--- /dev/null
+// 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<ComposedNode*>(node) != _root) name = _root->getChildName(node);
+ DEBTRACE("VisitorSaveState::visitForEachLoop ------ " << name);
+ _out << " <node type='forEachLoop'>" << std::endl;
+ _out << " <name>" << name << "</name>" << std::endl;
+ _out << " <state>" << _nodeStateName[node->getState()] << "</state>" << std::endl;
+// VisitorSaveState::visitForEachLoop(node);
+ std::list<InputPort *> setOfInputPort = node->getLocalInputPorts();
+ std::list<InputPort *>::iterator iter;
+ for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); iter++)
+ {
+ _out << " <inputPort>" << std::endl;
+ _out << " <name>" << (*iter)->getName() << "</name>" << std::endl;
+ try
+ {
+ _out << " ";
+ _out << (*iter)->dump();
+ }
+ catch (YACS::Exception &e)
+ {
+ DEBTRACE("caught YACS:Exception: " << e.what());
+ _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << std::endl;
+ }
+ _out << " </inputPort>" << std::endl;
+ }
+
+ StatesForNode state = node->getState();
+ if(YACS::LOADED == state ||
+ YACS::ACTIVATED == state ||
+ YACS::SUSPENDED == state ||
+ YACS::EXECFAILED == state ||
+ YACS::PAUSE == state ||
+ YACS::TORECONNECT == state ||
+ YACS::INTERNALERR == state ||
+ YACS::FAILED == state ||
+ YACS::ERROR == state)
+ {
+ ForEachLoopPassedData* processedData = node->getProcessedData();
+ if(processedData)
+ {
+ const std::vector<unsigned int>& processedIndexes = processedData->getIds();
+ std::vector<SequenceAny *>::const_iterator it_outputs;
+ std::vector<std::string>::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 << " <loopOutputPort>" << std::endl;
+ _out << " <name>" << (*it_names) << "</name>" << std::endl;
+ for(unsigned int i = 0; i < (*it_outputs)->size(); i++)
+ {
+ AnyPtr value = (*(*it_outputs))[i];
+ _out << " <sample><index>" << processedIndexes[i]<< "</index>";
+ if(value)
+ _out << convertNeutralXml(value->getType(), value);
+ else
+ _out << "<value>None</value>";
+ _out << " </sample>" << std::endl;
+ }
+ _out << " </loopOutputPort>" << std::endl;
+ }
+
+ delete processedData;
+ processedData = NULL;
+ }
+ }
+ _out << " </node>" << std::endl;
+}
+
+void YACS::ENGINE::schemaSaveState(Proc* proc,
+ Executor* exec,
+ const std::string& xmlSchemaFile)
+{
+ YACS::BASES::AutoLocker<YACS::BASES::Mutex> alck(&(exec->getTheMutexForSchedulerUpdate()));
+ VisitorSalomeSaveState vss(proc);
+ vss.openFileDump(xmlSchemaFile);
+ proc->accept(&vss);
+ vss.closeFileDump();
+}
--- /dev/null
+// 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);
+ };
+
+ YACSLIBENGINE_EXPORT void schemaSaveState(Proc* proc,
+ Executor* exec,
+ const std::string& xmlSchemaFile);
+ }
+}
+#endif // VISITORSALOMESAVESTATE_HXX
#include <io.h>
#define chmod _chmod
#endif
+#ifdef __APPLE__
+#include <unistd.h> // for mkdtemp
+#endif
//#define _DEVDEBUG_
#include "YacsTrace.hxx"
${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
SWIG_ADD_MODULE(SALOMERuntime python SALOMERuntime.i)
SWIG_LINK_LIBRARIES(SALOMERuntime ${_link_LIBRARIES})
+SWIG_CHECK_GENERATION(SALOMERuntime)
IF(WIN32)
SET_TARGET_PROPERTIES(_SALOMERuntime PROPERTIES DEBUG_OUTPUT_NAME _SALOMERuntime_d)
ENDIF(WIN32)
#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>
%}
Py_DECREF(pyapi);
%}
+%{
+static PyObject *convertContainer2(YACS::ENGINE::Container *cont, int owner=0)
+{
+ if(!cont)
+ return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
+ if(dynamic_cast<YACS::ENGINE::SalomeHPContainer *>(cont))
+ {
+ return SWIG_NewPointerObj((void*)dynamic_cast<YACS::ENGINE::SalomeHPContainer *>(cont),SWIGTYPE_p_YACS__ENGINE__SalomeHPContainer, owner);
+ }
+ if(dynamic_cast<YACS::ENGINE::SalomeContainer *>(cont))
+ {
+ return SWIG_NewPointerObj((void*)dynamic_cast<YACS::ENGINE::SalomeContainer *>(cont),SWIGTYPE_p_YACS__ENGINE__SalomeContainer, owner);
+ }
+ return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner);
+}
+%}
+
// ----------------------------------------------------------------------------
#ifdef SWIGPYTHON
%include "SalomeOptimizerLoop.hxx"
%include "DistributedPythonNode.hxx"
+namespace YACS
+{
+ namespace ENGINE
+ {
+ void schemaSaveState(Proc* proc,
+ Executor* exec,
+ const std::string& xmlSchemaFile);
+ }
+}
+
+
%extend YACS::ENGINE::OutputPresetPort
{
void setDataPy(PyObject *ob)
%rename(OptimizerAlgSync) YACS::ENGINE::PyOptimizerAlgBase;
%rename(OptimizerAlgASync) YACS::ENGINE::PyOptimizerAlgASync;
%include "PyOptimizerAlg.hxx"
+
+%extend YACS::ENGINE::RuntimeSALOME
+{
+ PyObject *createContainer(const std::string& kind="")
+ {
+ YACS::ENGINE::Container *ret(self->createContainer(kind));
+ return convertContainer2(ret,SWIG_POINTER_OWN | 0);
+ }
+}
SWIG_ADD_MODULE(libYACS_Swig python libYACS_Swig.i YACSGUI_Swig.cxx)
SWIG_LINK_LIBRARIES(libYACS_Swig "${_link_LIBRARIES}")
+SWIG_CHECK_GENERATION(libYACS_Swig)
IF(WIN32)
SET_TARGET_PROPERTIES(_libYACS_Swig PROPERTIES DEBUG_OUTPUT_NAME _libYACS_Swig_d)
ENDIF(WIN32)
${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})
--- /dev/null
+// Copyright (C) 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
+// 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
+//
+//
+// Author : Anthony Geay (EDF R&D)
+
+
+// This is an example of plugin implementation you can write to intercept events sent by YACS engine during execution
+// 1 - Build your shared library with 2 symboles defined : DefineCustomObservers and CleanUpObservers (warning respect the API !).
+// 2 - At run time set YACS_DRIVER_PLUGIN_PATH in your environement to the shared library
+
+#include "Dispatcher.hxx"
+#include "ForEachLoop.hxx"
+
+#include <iostream>
+#include <sstream>
+
+class PluginObserver : public YACS::ENGINE::Observer
+{
+public:
+ PluginObserver(YACS::ENGINE::ForEachLoop *fe):_fe(fe) { }
+private:
+ void notifyObserver(YACS::ENGINE::Node* object,const std::string& event);
+ void notifyObserver2(YACS::ENGINE::Node* object,const std::string& event, void *something);
+private:
+ YACS::ENGINE::ForEachLoop *_fe;
+};
+
+void PluginObserver::notifyObserver(YACS::ENGINE::Node* object,const std::string& event)
+{// Customize here !
+ std::cerr << "------------" << event << std::endl;
+}
+
+void PluginObserver::notifyObserver2(YACS::ENGINE::Node* object,const std::string& event, void *something)
+{// Customize here !
+ std::ostringstream oss;
+ if(event=="progress_ok")
+ {
+ int itemOk(*reinterpret_cast<int *>(something));
+ oss << event << " " << itemOk;
+ std::cerr << oss.str() << std::endl;
+ }
+}
+
+class PluginObserverKeeper
+{
+public:
+ ~PluginObserverKeeper() { clean(); }
+ void clean() { for(std::vector<YACS::ENGINE::Observer *>::iterator it=_observers.begin();it!=_observers.end();it++) delete *it; _observers.clear(); }
+ void registerObserver(YACS::ENGINE::Observer *newObs) { _observers.push_back(newObs); }
+private:
+ std::vector<YACS::ENGINE::Observer *> _observers;
+};
+
+PluginObserverKeeper pok;
+
+#include "ForEachLoop.hxx"
+
+extern "C"
+{
+ void DefineCustomObservers(YACS::ENGINE::Dispatcher *disp, YACS::ENGINE::ComposedNode *rootNode, YACS::ENGINE::Executor *executor)
+ {// Customize here !
+ YACS::ENGINE::Node *n(rootNode->getChildByName("ForEachLoop_pyobj1"));
+ YACS::ENGINE::ForEachLoop *nc(dynamic_cast<YACS::ENGINE::ForEachLoop *>(n));
+ if(!nc)
+ throw YACS::Exception("Expect to have a ForEach node called ForEachLoop_pyobj1 !");
+ PluginObserver *myCustomObsever(new PluginObserver(nc));
+ pok.registerObserver(myCustomObsever);
+ disp->addObserver(myCustomObsever,nc,"progress_ok");
+ }
+
+ void CleanUpObservers()
+ {// Customize here !
+ pok.clean();
+ }
+}
+
#include "Runtime.hxx"
#include "InputPort.hxx"
#include "ElementaryNode.hxx"
+#include "ForEachLoop.hxx"
+#include "Any.hxx"
+#include "TypeConversions.hxx"
#include <iostream>
#include <string>
_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")
+ {
+ 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)
what += " in node " + nodeName + " of type " + nodeType;
throw Exception(what);
}
- else if (nodeType == "foreachLoop")
+ else if (nodeType == "forEachLoop")
{
- string what="no way to set a port value on port " + _mapAttrib["name"];
- what += " in node " + nodeName + " of type " + nodeType;
- throw Exception(what);
+ ForEachLoop* eNode = dynamic_cast<ForEachLoop*>(node);
+ YASSERT(eNode);
+ InputPort *port = eNode->getInputPort(_mapAttrib["name"]);
+ if(_data != "")
+ port->edInit("XML",_data.c_str());
}
else
{
_data = _data + data;
}
+// ----------------------------------------------------------------------------
+
+void loopPortParser::init(const xmlChar** p, xmlParserBase* father)
+{
+ DEBTRACE("loopPortParser::init()");
+ //_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();
+ 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)
+{
+}
+
+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()");
+ //_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());
+ _sampleFather->addSample(index, _data);
+ stateParser::onEnd(name);
+}
+
+void sampleParser::charData(std::string data)
+{
+ _data = _data + data;
+}
// ----------------------------------------------------------------------------
#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
/*!
static std::map<std::string, YACS::StatesForNode> _nodeStates;
};
+#ifndef SWIG
class YACSLOADER_EXPORT graphParser: public stateParser
{
public:
};
+ 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);
};
+ 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;
+ 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
}
}
#endif
#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];
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)
if(std::string(attr[i]) == "name")name(attr[i+1]);
if(std::string(attr[i]) == "state")this->state(attr[i+1]);
if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
+ if(std::string(attr[i]) == "weight")weight(atof(attr[i+1]));
if(std::string(attr[i]) == "type")datatype(attr[i+1]);
}
postAttr();
virtual void pre ()
{
_nbranch=0;
+ _weight=1;
this->looptypeParser<T>::pre();
}
virtual void name (const std::string& name)
DEBTRACE("foreach_nbranch: " << n )
_nbranch=n;
}
+ virtual void weight (const double& x)
+ {
+ DEBTRACE("foreach_weight: " << x )
+ _weight=x;
+ }
virtual void datatype (const std::string& type)
{
DEBTRACE("foreach_datatype: "<< type)
this->_cnode=theRuntime->createForEachLoop(_name,currentProc->typeMap[_datatype]);
//set number of branches
if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
+ this->_cnode->setWeight(_weight);
this->_cnodes.push_back(this->_cnode);
currentProc->names.push_back(_fullname + '.');
}
return b;
}
int _nbranch;
+ double _weight;
std::string _fullname;
std::string _name;
std::string _datatype;
if(std::string(attr[i]) == "name")name(attr[i+1]);
if(std::string(attr[i]) == "state")this->state(attr[i+1]);
if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
+ if(std::string(attr[i]) == "weight")weight(atof(attr[i+1]));
if(std::string(attr[i]) == "lib")lib(attr[i+1]);
if(std::string(attr[i]) == "entry")entry(attr[i+1]);
if(std::string(attr[i]) == "kind")kind(attr[i+1]);
virtual void pre ()
{
_nbranch=0;
+ _weight=1;
this->looptypeParser<T>::pre();
}
virtual void name (const std::string& name)
DEBTRACE("optimizer_nbranch: " << n )
_nbranch=n;
}
+ virtual void weight (const double& x)
+ {
+ DEBTRACE("foreach_weight: " << x )
+ _weight=x;
+ }
virtual void kind (const std::string& name)
{
_kind=name;
this->_cnode=theRuntime->createOptimizerLoop(_name,_lib,_entry,true,_kind, currentProc);
//set number of branches
if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
+ this->_cnode->setWeight(_weight);
this->_cnodes.push_back(this->_cnode);
currentProc->names.push_back(_fullname + '.');
}
}
int _nbranch;
+ double _weight;
std::string _fullname;
std::string _name;
std::string _entry;
#include <iostream>
#include <fstream>
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
#include <fpu_control.h>
#endif
int main(int argc, char* argv[])
{
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
fpu_control_t cw = _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
_FPU_SETCW(cw);
#endif
controller.addListener( &result );
// --- Add a listener that print dots as test run.
-#ifdef WIN32
+#if defined WIN32 || defined __APPLE__
CPPUNIT_NS::TextTestProgressListener progress;
#else
CPPUNIT_NS::BriefTestProgressListener progress;
SWIG_ADD_MODULE(loader python loader.i)
SWIG_LINK_LIBRARIES(loader ${_link_LIBRARIES})
+SWIG_CHECK_GENERATION(loader)
IF(WIN32)
SET_TARGET_PROPERTIES(_loader PROPERTIES DEBUG_OUTPUT_NAME _loader_d)
ENDIF(WIN32)
testResume.py
testSave.py
testSaveLoadRun.py
+ testHPDecorator.py
optim_plugin.py
testValidationChecks.py
testProgress.py
ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} python StdAloneYacsLoaderTest1.py)
SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES
LABELS "${COMPONENT_NAME}"
- )
+ )
+
ENDIF()
self.assertEqual(n.getState(),pilot.DISABLED) # <- test is here.
pass
+ def test5(self):
+ """ Test focusing P13268. If I connect a list[pyobj] output inside a ForEach to a list[pyobj] outside a foreach it works now."""
+ #self.assertTrue(False)
+ fname="testP1328.xml"
+ p=self.r.createProc("testP1328")
+ tc0=p.createInterfaceTc("python:obj:1.0","pyobj",[])
+ tc1=p.createSequenceTc("list[pyobj]","list[pyobj]",tc0)
+ n0=self.r.createScriptNode("","n0")
+ n1=self.r.createForEachLoop("n1",tc0)
+ n10=self.r.createScriptNode("","n10")
+ n2=self.r.createScriptNode("","n2")
+ p.edAddChild(n0) ; p.edAddChild(n1) ; p.edAddChild(n2) ; n1.edAddChild(n10)
+ n0.setScript("o2=[[elt] for elt in range(10)]")
+ n10.setScript("o6=2*i5")
+ n2.setScript("assert(i8==[[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9]])")
+ o2=n0.edAddOutputPort("o2",tc1)
+ i5=n10.edAddInputPort("i5",tc0)
+ o6=n10.edAddOutputPort("o6",tc1) # the goal of test is here ! tc1 NOT tc0 !
+ i8=n2.edAddInputPort("i8",tc1)
+ #
+ p.edAddCFLink(n0,n1)
+ p.edAddCFLink(n1,n2)
+ #
+ p.edAddLink(o2,n1.edGetSeqOfSamplesPort())
+ p.edAddLink(n1.edGetSamplePort(),i5)
+ p.edAddLink(o6,i8) # important link for the test !
+ #
+ n1.edGetNbOfBranchesPort().edInitInt(1)
+ #
+ p.saveSchema(fname)
+ #
+ ex=pilot.ExecutorSwig()
+ self.assertEqual(p.getState(),pilot.READY)
+ ex.RunW(p,0)
+ self.assertEqual(p.getState(),pilot.DONE)
+ self.assertEqual(p.getChildByName("n2").getInputPort("i8").getPyObj(),[[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9]])
+ pass
+
+ def test6(self):
+ """ Test focusing on P13766. Test of a connection of 2 foreach at same level where the output pyobj is connected to the list[pyobj] input samples of the 2nd foreach"""
+ fname="testP13766.xml"
+ p=self.r.createProc("testP13766")
+ tc0=p.createInterfaceTc("python:obj:1.0","pyobj",[])
+ tc1=p.createSequenceTc("list[pyobj]","list[pyobj]",tc0)
+ n0=self.r.createScriptNode("","n0")
+ n1=self.r.createForEachLoop("n1",tc0)
+ n2=self.r.createForEachLoop("n2",tc0)
+ n10=self.r.createScriptNode("","n10")
+ n20=self.r.createScriptNode("","n20")
+ n3=self.r.createScriptNode("","n3")
+ p.edAddChild(n0) ; p.edAddChild(n1) ; p.edAddChild(n2) ; p.edAddChild(n3) ; n1.edAddChild(n10) ; n2.edAddChild(n20)
+ n0.setScript("o2=[[elt] for elt in range(10)]")
+ n10.setScript("o6=3*i5")
+ n3.setScript("assert(i8==[[0,0,0,0,0,0],[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3],[4,4,4,4,4,4],[5,5,5,5,5,5],[6,6,6,6,6,6],[7,7,7,7,7,7],[8,8,8,8,8,8],[9,9,9,9,9,9]])")
+ n20.setScript("o10=2*i9")
+ o2=n0.edAddOutputPort("o2",tc1)
+ i5=n10.edAddInputPort("i5",tc0)
+ o6=n10.edAddOutputPort("o6",tc0)
+ i9=n20.edAddInputPort("i9",tc0)
+ o10=n20.edAddOutputPort("o10",tc0)
+ i8=n3.edAddInputPort("i8",tc1)
+ #
+ p.edAddCFLink(n0,n1)
+ p.edAddCFLink(n1,n2)
+ p.edAddCFLink(n2,n3)
+ #
+ p.edAddLink(o2,n1.edGetSeqOfSamplesPort())
+ p.edAddLink(o6,n2.edGetSeqOfSamplesPort())# test is here !
+ p.edAddLink(n1.edGetSamplePort(),i5)
+ p.edAddLink(n2.edGetSamplePort(),i9)
+ p.edAddLink(o10,i8)
+ #
+ n1.edGetNbOfBranchesPort().edInitInt(1)
+ n2.edGetNbOfBranchesPort().edInitInt(1)
+ #
+ p.saveSchema(fname)
+ #
+ ex=pilot.ExecutorSwig()
+ self.assertEqual(p.getState(),pilot.READY)
+ ex.RunW(p,0)
+ self.assertEqual(p.getState(),pilot.DONE)
+ self.assertEqual(p.getChildByName("n3").getInputPort("i8").getPyObj(),[[0,0,0,0,0,0],[1,1,1,1,1,1],[2,2,2,2,2,2],[3,3,3,3,3,3],[4,4,4,4,4,4],[5,5,5,5,5,5],[6,6,6,6,6,6],[7,7,7,7,7,7],[8,8,8,8,8,8],[9,9,9,9,9,9]])
+ pass
+
def tearDown(self):
del self.r
del self.l
exit $ret7
fi
-let ret=$ret0+$ret1+$ret2+$ret3+$ret4+$ret5+$ret6+$ret7
+python @CMAKE_CURRENT_SOURCE_DIR@/testHPDecorator.py
+ret8=$?
+if [ $ret8 -gt 0 ]; then
+ echo "exec status testProgress : " $ret8
+ exit $ret8
+fi
+
+let ret=$ret0+$ret1+$ret2+$ret3+$ret4+$ret5+$ret6+$ret7+$ret8
# --- return unit tests status
--- /dev/null
+# 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
+# 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
+#
+
+import pilot
+import SALOMERuntime
+import unittest
+
+class TestHPDecortator(unittest.TestCase):
+ def test0(self):
+ """ First test coming from the big boss."""
+ SALOMERuntime.RuntimeSALOME.setRuntime()
+ r=SALOMERuntime.getSALOMERuntime()
+ pg=pilot.PlayGround()
+ pg.loadFromKernelCatalog()
+ assert(len(pg.getData())!=0)
+ p=r.createProc("p0")
+ td=p.createType("double","double")
+ tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+ hp1=p.createContainer("HP1","HPSalome")
+ hp4=p.createContainer("HP4","HPSalome")
+ #
+ n0=r.createScriptNode("Salome","n0")
+ n0.setExecutionMode("remote")
+ out0_0=n0.edAddOutputPort("o1",tdd)
+ n0.setScript("""o1=[float(i)+0.1 for i in range(1000)]""")
+ n0.setContainer(hp4)
+ p.edAddChild(n0)
+ #
+ n1_0=r.createForEachLoop("n1_0",td)
+ p.edAddChild(n1_0)
+ p.edAddCFLink(n0,n1_0)
+ p.edAddLink(out0_0,n1_0.edGetSeqOfSamplesPort())
+ ##
+ n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
+ n1_0.edAddChild(n1_0_sc)
+ n1_0_sc.setExecutionMode("remote")
+ n1_0_sc.setScript("""2*i1""")
+ i1_0_sc=n1_0_sc.edAddInputPort("i1",td)
+ p.edAddLink(n1_0.edGetSamplePort(),i1_0_sc)
+ n1_0_sc.setContainer(hp4)
+ ##
+ #
+ n1_1=r.createForEachLoop("n1_1",td)
+ p.edAddChild(n1_1)
+ p.edAddCFLink(n0,n1_1)
+ p.edAddLink(out0_0,n1_1.edGetSeqOfSamplesPort())
+ ##
+ n1_1_sc=r.createScriptNode("Salome","n1_1_sc")
+ n1_1.edAddChild(n1_1_sc)
+ n1_1_sc.setExecutionMode("remote")
+ n1_1_sc.setScript("""3*i1""")
+ i1_1_sc=n1_1_sc.edAddInputPort("i1",td)
+ p.edAddLink(n1_1.edGetSamplePort(),i1_1_sc)
+ n1_1_sc.setContainer(hp1)
+ ##
+ hp1.setProperty("nb_proc_per_node","1")
+ hp4.setProperty("nb_proc_per_node","4")
+ pg.setData([("m0",8),("m1",8),("m2",8),("m3",8)]) # virtual machine with 32 cores spread over 4 nodes
+ assert(n1_0.getWeight()==1.)
+ assert(n1_1.getWeight()==1.)
+ p.fitToPlayGround(pg)########### ZE CALL
+ fyto=pilot.ForTestOmlyHPContCls()
+ assert(hp4.getSizeOfPool()==8)# 32/4
+ n1_0_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==0 and pd.getStop()==16)
+ assert(fyto.getIDS()==(0,1,2,3))
+ #
+ assert(hp1.getSizeOfPool()==32)# 32/1
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_1_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==16 and pd.getStop()==32)
+ assert(fyto.getIDS()==(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31))
+ assert(n1_0.edGetNbOfBranchesPort().getPyObj()==4)
+ assert(n1_1.edGetNbOfBranchesPort().getPyObj()==16)
+ #
+ fyto=pilot.ForTestOmlyHPContCls()
+ n0.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.AllPartDefinition))
+ assert(list(fyto.getIDS())==range(8))
+ #############################
+ # Change weight of ForEach #
+ #############################
+ n1_0.setWeight(2)
+ p.fitToPlayGround(pg)########### ZE CALL
+ assert(hp4.getSizeOfPool()==8)# 32/4
+ n1_0_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==0 and pd.getStop()==21)
+ assert(fyto.getIDS()==(0,1,2,3,4))
+ assert(hp1.getSizeOfPool()==32)# 32/1
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_1_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==21 and pd.getStop()==32)
+ assert(fyto.getIDS()==(21,22,23,24,25,26,27,28,29,30,31))
+ assert(n1_0.edGetNbOfBranchesPort().getPyObj()==6)
+ assert(n1_1.edGetNbOfBranchesPort().getPyObj()==11)
+ #
+ fyto=pilot.ForTestOmlyHPContCls()
+ n0.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.AllPartDefinition))
+ assert(list(fyto.getIDS())==range(8))
+ pass
+
+ def test1(self):
+ """ Second test as test0 + script node in // with 2 FE"""
+ SALOMERuntime.RuntimeSALOME.setRuntime()
+ r=SALOMERuntime.getSALOMERuntime()
+ pg=pilot.PlayGround()
+ pg.loadFromKernelCatalog()
+ assert(len(pg.getData())!=0)
+ p=r.createProc("p0")
+ td=p.createType("double","double")
+ tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+ hp1=p.createContainer("HP1","HPSalome")
+ hp4=p.createContainer("HP4","HPSalome")
+ #
+ n0=r.createScriptNode("Salome","n0")
+ n0.setExecutionMode("remote")
+ out0_0=n0.edAddOutputPort("o1",tdd)
+ n0.setScript("""o1=[float(i)+0.1 for i in range(1000)]""")
+ n0.setContainer(hp4)
+ p.edAddChild(n0)
+ #
+ n1_0=r.createForEachLoop("n1_0",td)
+ p.edAddChild(n1_0)
+ p.edAddCFLink(n0,n1_0)
+ p.edAddLink(out0_0,n1_0.edGetSeqOfSamplesPort())
+ ##
+ n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
+ n1_0.edAddChild(n1_0_sc)
+ n1_0_sc.setExecutionMode("remote")
+ n1_0_sc.setScript("""2*i1""")
+ i1_0_sc=n1_0_sc.edAddInputPort("i1",td)
+ p.edAddLink(n1_0.edGetSamplePort(),i1_0_sc)
+ n1_0_sc.setContainer(hp4)
+ ##
+ #
+ n1_1=r.createForEachLoop("n1_1",td)
+ p.edAddChild(n1_1)
+ p.edAddCFLink(n0,n1_1)
+ p.edAddLink(out0_0,n1_1.edGetSeqOfSamplesPort())
+ ##
+ n1_1_sc=r.createScriptNode("Salome","n1_1_sc")
+ n1_1.edAddChild(n1_1_sc)
+ n1_1_sc.setExecutionMode("remote")
+ n1_1_sc.setScript("""3*i1""")
+ i1_1_sc=n1_1_sc.edAddInputPort("i1",td)
+ p.edAddLink(n1_1.edGetSamplePort(),i1_1_sc)
+ n1_1_sc.setContainer(hp1)
+ #
+ n1_2=r.createScriptNode("Salome","n1_2")
+ p.edAddChild(n1_2)
+ n1_2.setExecutionMode("remote")
+ n1_2.setContainer(hp4)
+ n1_2.setScript("""my_container""")
+ p.edAddCFLink(n0,n1_2)
+ ##
+ hp1.setProperty("nb_proc_per_node","1")
+ hp4.setProperty("nb_proc_per_node","4")
+ pg.setData([("m0",8),("m1",8),("m2",8),("m3",8)]) # virtual machine with 32 cores spread over 4 nodes
+ assert(n1_0.getWeight()==1.)
+ assert(n1_1.getWeight()==1.)
+ p.fitToPlayGround(pg)########### ZE CALL
+ assert(hp4.getSizeOfPool()==8)# 32/4
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_0_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==0 and pd.getStop()==16)
+ assert(fyto.getIDS()==(0,1,2,3))
+ #
+ assert(hp1.getSizeOfPool()==32)# 32/1
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_1_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==16 and pd.getStop()==32)
+ assert(fyto.getIDS()==(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31))
+ assert(n1_0.edGetNbOfBranchesPort().getPyObj()==4)
+ assert(n1_1.edGetNbOfBranchesPort().getPyObj()==16)
+ #
+ fyto=pilot.ForTestOmlyHPContCls()
+ n0.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.AllPartDefinition))
+ assert(list(fyto.getIDS())==range(8))
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_2.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.AllPartDefinition))
+ assert(list(fyto.getIDS())==range(8))
+ pass
+
+ @unittest.skip("requires 2 machines in catalog")
+ def test2(self):
+ """ This test is desactivated because it requires multi nodes. To be moved at the right place to support this.
+ This test is not launched here because it requires 2 machines in catalog"""
+ m1="dsp0764200"
+ m2="dsp0764412"
+ SALOMERuntime.RuntimeSALOME.setRuntime()
+ r=SALOMERuntime.getSALOMERuntime()
+ pg=pilot.PlayGround()
+ pg.loadFromKernelCatalog()
+ assert(len(pg.getData())!=0)
+ p=r.createProc("p0")
+ td=p.createType("double","double")
+ tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+ hp1=p.createContainer("HP1","HPSalome")
+ #
+ n0=r.createScriptNode("Salome","n0")
+ n0.setExecutionMode("remote")
+ out0_0=n0.edAddOutputPort("o1",tdd)
+ n0.setScript("""o1=[float(i)+0.1 for i in range(1000)]""")
+ n0.setContainer(hp1)
+ p.edAddChild(n0)
+ ##
+ n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
+ p.edAddChild(n1_0_sc)
+ p.edAddCFLink(n0,n1_0_sc)
+ n1_0_sc.setExecutionMode("remote")
+ n1_0_sc.setScript("""assert(my_container.getHostName()=="%s")"""%m1)
+ n1_0_sc.setContainer(hp1)
+ ##
+ n1_1_sc=r.createScriptNode("Salome","n1_1_sc")
+ p.edAddChild(n1_1_sc)
+ p.edAddCFLink(n0,n1_1_sc)
+ n1_1_sc.setExecutionMode("remote")
+ n1_1_sc.setScript("""assert(my_container.getHostName()=="%s")"""%m2)
+ n1_1_sc.setContainer(hp1)
+ ##
+ hp1.setProperty("nb_proc_per_node","1")
+ pg.setData([(m1,8),(m2,8)])
+ p.fitToPlayGround(pg)########### ZE CALL
+ assert(hp1.getSizeOfPool()==16)# 16/1
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_0_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==0 and pd.getStop()==8)
+ assert(fyto.getIDS()==(0,1,2,3,4,5,6,7))
+ #
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_1_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.ContigPartDefinition))
+ assert(pd.getStart()==8 and pd.getStop()==16)
+ assert(fyto.getIDS()==(8,9,10,11,12,13,14,15))
+ #
+ exe=pilot.ExecutorSwig()
+ assert(p.getState()==pilot.READY)
+ exe.RunW(p,0)
+ assert(p.getState()==pilot.DONE)
+ pass
+
+ def test3(self):
+ """ First test coming from the big boss."""
+ SALOMERuntime.RuntimeSALOME.setRuntime()
+ r=SALOMERuntime.getSALOMERuntime()
+ pg=pilot.PlayGround()
+ pg.loadFromKernelCatalog()
+ assert(len(pg.getData())!=0)
+ p=r.createProc("p0")
+ td=p.createType("double","double")
+ tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+ hp1=r.createContainer("HPSalome") ; hp1.setName("HP1")
+ #
+ n0=r.createScriptNode("Salome","n0")
+ n0.setExecutionMode("local")
+ out0_0=n0.edAddOutputPort("o1",tdd)
+ n0.setScript("""o1=[float(i)+0.1 for i in range(1000)]""")
+ p.edAddChild(n0)
+ #
+ n1_0=r.createForEachLoop("n1_0",td)
+ n2_0=r.createForEachLoop("n2_0",td)
+ p.edAddChild(n1_0)
+ p.edAddChild(n2_0)
+ p.edAddCFLink(n0,n1_0)
+ p.edAddCFLink(n1_0,n2_0)
+ p.edAddLink(out0_0,n1_0.edGetSeqOfSamplesPort())
+ p.edAddLink(out0_0,n2_0.edGetSeqOfSamplesPort())
+ ##
+ n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
+ n1_0.edAddChild(n1_0_sc)
+ n1_0_sc.setExecutionMode("remote")
+ n1_0_sc.setScript("""2*i1""")
+ i1_0_sc=n1_0_sc.edAddInputPort("i1",td)
+ p.edAddLink(n1_0.edGetSamplePort(),i1_0_sc)
+ n1_0_sc.setContainer(hp1)
+ ##
+ n2_0_sc=r.createScriptNode("Salome","n2_0_sc")
+ n2_0.edAddChild(n2_0_sc)
+ n2_0_sc.setExecutionMode("remote")
+ n2_0_sc.setScript("""2*i1""")
+ i2_0_sc=n2_0_sc.edAddInputPort("i1",td)
+ p.edAddLink(n2_0.edGetSamplePort(),i2_0_sc)
+ n2_0_sc.setContainer(hp1)
+ ##
+ hp1.setProperty("nb_proc_per_node","1")
+ pg.setData([("localhost",3)])
+ p.fitToPlayGround(pg)########### ZE CALL
+ assert(hp1.getSizeOfPool()==3)
+ fyto=pilot.ForTestOmlyHPContCls()
+ n1_0_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.AllPartDefinition))
+ assert(fyto.getIDS()==(0,1,2))
+ fyto=pilot.ForTestOmlyHPContCls()
+ n2_0_sc.getContainer().forYourTestsOnly(fyto)
+ assert(fyto.getContainerType()=="HPContainerShared")
+ pd=fyto.getPD()
+ assert(isinstance(pd,pilot.AllPartDefinition))
+ assert(fyto.getIDS()==(0,1,2))
+ assert(n1_0.edGetNbOfBranchesPort().getPyObj()==3)
+ assert(n2_0.edGetNbOfBranchesPort().getPyObj()==3)
+ #
+ exe=pilot.ExecutorSwig()
+ assert(p.getState()==pilot.READY)
+ exe.RunW(p,0)
+ assert(len(set(hp1.getKernelContainerNames()))==3)
+ pass
+
+ pass
+
+if __name__ == '__main__':
+ unittest.main()
sl.parse('dumpPartialBloc2.xml')
#self.e.displayDot(self.p)
self.e.setExecMode(0) # YACS::CONTINUE
- run2 = threading.Thread(None, self.e.RunPy, "loadState", (self.p,0,1,1))
+ run2 = threading.Thread(None, self.e.RunPy, "loadState", (self.p,0,True,True))
run2.start()
time.sleep(0.1)
self.e.waitPause()
suite = unittest.makeSuite(TestResume)
result=unittest.TextTestRunner(f, descriptions=1, verbosity=1).run(suite)
f.close()
- sys.exit(not result.wasSuccessful())
\ No newline at end of file
+ sys.exit(not result.wasSuccessful())
node2000.setScript("o6=2+i5")
p.edAddLink(node200.edGetSamplePort(),i5)
#
- node3=self.r.createForEachLoop("node3",td)
+ node3=self.r.createForEachLoop("node3",td2)
p.edAddChild(node3)
p.edAddCFLink(node2,node3)
p.edAddLink(o6,node3.edGetSeqOfSamplesPort())
node2000.setScript("def ff(x):\n return 2+x")
p.edAddLink(node200.edGetSamplePort(),i5)
#
- node3=self.r.createForEachLoop("node3",td)
+ node3=self.r.createForEachLoop("node3",td2)
p.edAddChild(node3)
p.edAddCFLink(node2,node3)
p.edAddLink(o6,node3.edGetSeqOfSamplesPort())
pass
+ def test21(self):
+ "test if we restart from a saved state in a foreach loop"
+ fname="test21.xml"
+ xmlStateFileName="saveState21.xml"
+ from datetime import datetime
+ p=self.r.createProc("prTest21")
+ cont=p.createContainer("gg","Salome")
+ cont.setProperty("name","localhost")
+ cont.setProperty("hostname","localhost")
+ cont.setProperty("type","multi")
+ td=p.createType("double","double")
+ ti=p.createType("int","int")
+ tsi=p.createSequenceTc("seqint","seqint",ti)
+ tsd=p.createSequenceTc("seqdbl","seqdbl",td)
+ n0=self.r.createScriptNode("","n0")
+ o0=n0.edAddOutputPort("o0",tsi)
+ n0.setScript("o0=[ elt for elt in range(6) ]")
+ p.edAddChild(n0)
+ n1=self.r.createForEachLoop("n1",ti)
+ n10=self.r.createScriptNode("","n10")
+ n10.setExecutionMode("remote")
+ n10.setContainer(cont)
+ n1.edAddChild(n10)
+ n10.setScript("""
+import time
+time.sleep(2)
+o2=2*i1
+""")
+ i1=n10.edAddInputPort("i1",ti)
+ o2=n10.edAddOutputPort("o2",ti)
+ p.edAddChild(n1)
+ p.edAddLink(o0,n1.edGetSeqOfSamplesPort())
+ p.edAddLink(n1.edGetSamplePort(),i1)
+ p.edAddCFLink(n0,n1)
+ n1.edGetNbOfBranchesPort().edInitPy(2)
+ n2=self.r.createScriptNode("","n2")
+ n2.setScript("o4=i3")
+ i3=n2.edAddInputPort("i3",tsi)
+ o4=n2.edAddOutputPort("o4",tsi)
+ n2.setScript("o4=i3")
+ p.edAddChild(n2)
+ p.edAddCFLink(n1,n2)
+ p.edAddLink(o2,i3)
+ p.saveSchema(fname)
+ #
+ l=loader.YACSLoader()
+ p=l.load(fname)
+ n1=p.getChildByName("n1")
+ ex=pilot.ExecutorSwig()
+ ex.setKeepGoingProperty(True)
+ #
+ startt=datetime.now()
+ import threading
+ myRun=threading.Thread(None, ex.RunW, None, (p,0))
+ myRun.start()
+ import time
+ time.sleep(5)
+ SALOMERuntime.schemaSaveState(p, ex, xmlStateFileName)
+ a,b,c=n1.getPassedResults(ex)
+ myRun.join()
+ t0=datetime.now()-startt
+ #
+ self.assertEqual(p.getState(),pilot.DONE)
+ self.assertEqual(n1.getState(),pilot.DONE)
+ self.assertEqual(a,[0,1])
+ self.assertEqual([elt.getPyObj() for elt in b],[[0L,2L]])
+ #
+ p.getChildByName("n0").setScript("o0=[ 3*elt for elt in range(6) ]")
+ p.getChildByName("n1").getChildByName("n10").setScript("""
+import time
+time.sleep(0.1)
+o2=5*i1
+""")
+ loader.loadState(p, xmlStateFileName)
+ p.resetState(1)
+ p.getChildByName("n1").assignPassedResults(a,b,c)
+ p.exUpdateState();
+ #
+ startt=datetime.now()
+ ex.RunW(p,0,False)
+ t1=datetime.now()-startt
+ #
+ self.assertEqual(n1.getState(),pilot.DONE)
+ self.assertEqual(p.getState(),pilot.DONE)
+ self.assertEqual(p.getChildByName("n2").getOutputPort("o4").getPyObj(),[0L,2L,10L,15L,20L,25L])
+ pass
+ pass
+
+ def test22(self):
+ """Restart from a saved state in a foreach loop without using assignPassedResults.
+ This test uses the files test21.xml and saveState21.xml produced by test21.
+ """
+ fname="test21.xml"
+ xmlStateFileName="saveState21.xml"
+
+ ex=pilot.ExecutorSwig()
+ l=loader.YACSLoader()
+ q=l.load(fname)
+ q.getChildByName("n0").setScript("o0=[ 3*elt for elt in range(6) ]")
+ q.getChildByName("n1").getChildByName("n10").setScript("""
+import time
+time.sleep(0.1)
+print "execution n10:", i1
+o2=5*i1
+""")
+ q.getChildByName("n2").setScript("""
+print "execution n2:", i3
+o4=i3
+""")
+ loader.loadState(q, xmlStateFileName)
+ q.resetState(1)
+ q.exUpdateState()
+ #
+ ex.RunW(q,0,False)
+ #
+ self.assertEqual(q.getChildByName("n1").getState(),pilot.DONE)
+ self.assertEqual(q.getState(),pilot.DONE)
+ self.assertEqual(q.getChildByName("n2").getOutputPort("o4").getPyObj(),[0L,2L,10L,15L,20L,25L])
+ pass
+
+ def test23(self):
+ """ test focused on weight attribut after a dump and reload from a xml file
+ """
+ fname="test23.xml"
+ xmlStateFileName="saveState23.xml"
+ from datetime import datetime
+ p=self.r.createProc("prTest23")
+ cont=p.createContainer("gg","Salome")
+ cont.setProperty("name","localhost")
+ cont.setProperty("hostname","localhost")
+ cont.setProperty("type","multi")
+ td=p.createType("double","double")
+ ti=p.createType("int","int")
+ tsi=p.createSequenceTc("seqint","seqint",ti)
+ tsd=p.createSequenceTc("seqdbl","seqdbl",td)
+ n0=self.r.createScriptNode("","n0")
+ o0=n0.edAddOutputPort("o0",tsi)
+ n0.setScript("o0=[ elt for elt in range(6) ]")
+ p.edAddChild(n0)
+ n1=self.r.createForEachLoop("n1",ti)
+ n1.setWeight(3)
+ n10=self.r.createScriptNode("","n10")
+ n10.setExecutionMode("remote")
+ n10.setContainer(cont)
+ n1.edAddChild(n10)
+ n10.setScript("""
+import time
+time.sleep(2)
+o2=2*i1
+""")
+ i1=n10.edAddInputPort("i1",ti)
+ o2=n10.edAddOutputPort("o2",ti)
+ p.edAddChild(n1)
+ p.edAddLink(o0,n1.edGetSeqOfSamplesPort())
+ p.edAddLink(n1.edGetSamplePort(),i1)
+ p.edAddCFLink(n0,n1)
+ n1.edGetNbOfBranchesPort().edInitPy(2)
+ n2=self.r.createScriptNode("","n2")
+ n2.setScript("o4=i3")
+ i3=n2.edAddInputPort("i3",tsi)
+ o4=n2.edAddOutputPort("o4",tsi)
+ n2.setScript("o4=i3")
+ p.edAddChild(n2)
+ p.edAddCFLink(n1,n2)
+ p.edAddLink(o2,i3)
+ p.saveSchema(fname)
+ #
+ l=loader.YACSLoader()
+ p=l.load(fname)
+ self.assertEqual(p.getChildByName("n1").getWeight(),3.0)
+ pass
+
+ pass
+
if __name__ == '__main__':
import os,sys
U = os.getenv('USER')
self.run1 = None
if self.run1 is None:
- self.run1 = threading.Thread(None, self.runProc, "CORBAExec", (0,1,1))
+ self.run1 = threading.Thread(None, self.runProc, "CORBAExec", (0,True,True))
self.run1.start()
def RunFromState(self, xmlFile):
return
if self.run1 is None:
- self.run1 = threading.Thread(None, self.runProc, "CORBAExec", (0,1,0))
+ self.run1 = threading.Thread(None, self.runProc, "CORBAExec", (0,True,False))
self.run1.start()
def RestartFromState(self, xmlFile):
pass
if self.run1 is None:
- self.run1 = threading.Thread(None, self.runProc, "CORBAExec", (0,1,0))
+ self.run1 = threading.Thread(None, self.runProc, "CORBAExec", (0,True,False))
self.run1.start()
def addObserver(self, obs, numid, event):
print "YACS.__init__: ", containerName, ';', instanceName
SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, contID,
containerName, instanceName,
- interfaceName, 0)
+ interfaceName, False)
SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
# --- store a naming service interface instance in _naming_service atribute