From: Ovidiu Mircescu Date: Tue, 20 Oct 2015 08:39:57 +0000 (+0200) Subject: Merge branch 'omu/update_doc_77' X-Git-Tag: V8_0_pre~8 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f31c1aa1cf3481bf51166f0c4e3dd118bc3ab43b;hp=2d7ef9f9768a58b0f6ccbfa403d39ecf8b7356a3;p=modules%2Fyacs.git Merge branch 'omu/update_doc_77' --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f37f1ce7..82f642d86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,11 +30,11 @@ CMAKE_POLICY(SET CMP0003 NEW) STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 6) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 7) 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}) -SET(${PROJECT_NAME_UC}_VERSION_DEV 1) +SET(${PROJECT_NAME_UC}_VERSION_DEV 0) # Find KERNEL (optional) # ============== diff --git a/src/engine/AbstractPoint.cxx b/src/engine/AbstractPoint.cxx new file mode 100644 index 000000000..e5baa1bbc --- /dev/null +++ b/src/engine/AbstractPoint.cxx @@ -0,0 +1,335 @@ +// Copyright (C) 2015 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 "AbstractPoint.hxx" +#include "LinkedBlocPoint.hxx" +#include "ForkBlocPoint.hxx" +#include "SetOfPoints.hxx" +#include "Node.hxx" + +using namespace YACS::ENGINE; + +AbstractPoint::~AbstractPoint() +{ +} + +AbstractPoint *AbstractPoint::getGodFather() +{ + if(_father==0) + return this; + else + return _father->getGodFather(); +} + +bool AbstractPoint::isBegin() +{ + Node *beg(getFirstNode()); + InGate *ing(beg->getInGate()); + return ing->getBackLinks().empty(); +} + +bool AbstractPoint::isLast() +{ + Node *endd(getLastNode()); + OutGate *oug(endd->getOutGate()); + return oug->edSetInGate().empty(); +} + +bool AbstractPoint::isSimplyLinkedBeforeAfter(BlocPoint *sop) +{ + Node *beg(getFirstNode()),*endd(getLastNode()); + return isSimplyLinkedBefore(sop,beg) && isSimplyLinkedAfter(sop,endd); +} + +bool AbstractPoint::isSimplyLinkedAfterNullBefore(BlocPoint *sop) +{ + Node *beg(getFirstNode()),*endd(getLastNode()); + return IsNoLinksBefore(beg) && isSimplyLinkedAfter(sop,endd); +} + +bool AbstractPoint::isSimplyLinkedBeforeNullAfter(BlocPoint *sop) +{ + Node *beg(getFirstNode()),*endd(getLastNode()); + return IsNoLinksAfter(endd) && isSimplyLinkedBefore(sop,beg); +} + +/*! + * precondition : isSimplyLinkedBeforeAfter must return true on \a this. + */ +LinkedBlocPoint *AbstractPoint::tryAsLink(BlocPoint *sop) +{ + Node *bb(getFirstNode()),*ee(getLastNode()); + std::list l; l.push_back(this); + AbstractPoint *cur2(0); + // + cur2=sop->getNodeB4(bb); + while(cur2) + { + Node *cur3(cur2->getFirstNode()); + if(cur2->isSimplyLinkedBeforeAfter(sop)) + { + l.push_front(cur2); + cur2=sop->getNodeB4(cur3); + continue; + } + else if(IsGatherB4Ext(cur3) && isSimplyLinkedAfter(sop,cur2->getLastNode())) + { + l.push_front(cur2); + break; + } + else + break; + } + // + cur2=sop->getNodeAfter(ee); + while(cur2) + { + Node *cur3(cur2->getLastNode()); + if(cur2->isSimplyLinkedBeforeAfter(sop)) + { + l.push_back(cur2); + cur2=sop->getNodeAfter(cur3); + continue; + } + else if(IsScatterAfterExt(cur3) && isSimplyLinkedBefore(sop,cur2->getFirstNode())) + { + l.push_back(cur2); + break; + } + else + break; + } + if(l.size()>1) + { + return new LinkedBlocPoint(l,getFather()); + } + else + return 0; +} + +/*! + * precondition : isSimplyLinkedBeforeAfter must return true on \a this. + */ +ForkBlocPoint *AbstractPoint::tryAsFork(BlocPoint *sop) +{ + Node *bb(GetNodeB4(getFirstNode())),*ee(GetNodeAfter(getLastNode())); + AbstractPoint *bb2(sop->findPointWithNode(bb)),*ee2(sop->findPointWithNode(ee)); + // + const std::list& lp(sop->getListOfPoints()); + std::list l; l.push_back(this); + for(std::list::const_iterator it=lp.begin();it!=lp.end();it++) + { + if(*it==this) + continue; + Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode()); + if(!IsSimplyLinkedBeforeExt(curFirst) || !IsSimplyLinkedAfterExt(curEnd)) + continue; + Node *curbb(GetNodeB4(curFirst)),*curee(GetNodeAfter(curEnd)); + AbstractPoint *bb3(sop->findPointWithNode(curbb)),*ee3(sop->findPointWithNode(curee)); + if(bb2==bb3 && ee2==ee3) + l.push_back(*it); + } + if(l.size()>1) + { + return new ForkBlocPoint(l,getFather()); + } + else + return 0; +} + +ForkBlocPoint *AbstractPoint::tryAsForkBis(BlocPoint *sop) +{ + Node *bb(GetNodeB4(getFirstNode())),*ee(GetNodeAfter(getLastNode())); + AbstractPoint *ee2(sop->findPointWithNode(ee)); + // + const std::list& lp(sop->getListOfPoints()); + std::list l; l.push_back(this); + for(std::list::const_iterator it=lp.begin();it!=lp.end();it++) + { + if(*it==this) + continue; + Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode()); + if(!IsNoLinksBefore(curFirst) || !IsSimplyLinkedAfterExt(curEnd)) + continue; + Node *curee(GetNodeAfter(curEnd)); + AbstractPoint *ee3(sop->findPointWithNode(curee)); + if(ee2==ee3) + l.push_back(*it); + } + if(l.size()>1) + { + return new ForkBlocPoint(l,getFather()); + } + else + return 0; +} + +ForkBlocPoint *AbstractPoint::tryAsForkTer(BlocPoint *sop) +{ + Node *bb(GetNodeB4(getFirstNode())),*ee(GetNodeAfter(getLastNode())); + AbstractPoint *bb2(sop->findPointWithNode(bb)); + // + const std::list& lp(sop->getListOfPoints()); + std::list l; l.push_back(this); + for(std::list::const_iterator it=lp.begin();it!=lp.end();it++) + { + if(*it==this) + continue; + Node *curFirst((*it)->getFirstNode()),*curEnd((*it)->getLastNode()); + if(!IsSimplyLinkedBeforeExt(curFirst) || !IsNoLinksAfter(curEnd)) + continue; + Node *curbb(GetNodeB4(curFirst)); + AbstractPoint *bb3(sop->findPointWithNode(curbb)); + if(bb2==bb3) + l.push_back(*it); + } + if(l.size()>1) + { + return new ForkBlocPoint(l,getFather()); + } + else + return 0; +} + +bool AbstractPoint::IsGatherB4Ext(Node *node) +{ + InGate *ing(node->getInGate()); + return ing->getBackLinks().size()!=1; +} + +bool AbstractPoint::isSimplyLinkedAfter(BlocPoint *sop, Node *node) +{ + OutGate *oug(node->getOutGate()); + std::list ings(oug->edSetInGate()); + if(ings.size()==1) + return true; + if(ings.size()==0) + return false; + AbstractPoint *dummy=0; + return IsCommonDirectSonOf(sop,ings,dummy); +} + +bool AbstractPoint::IsSimplyLinkedAfterExt(Node *node) +{ + OutGate *oug(node->getOutGate()); + return oug->edSetInGate().size()<=1; +} + +bool AbstractPoint::IsScatterAfterExt(Node *node) +{ + OutGate *oug(node->getOutGate()); + return oug->edSetInGate().size()!=1; +} + +bool AbstractPoint::isSimplyLinkedBefore(BlocPoint *sop, Node *node) +{ + InGate *ing(node->getInGate()); + std::list outgs(ing->getBackLinks()); + if(outgs.size()==1) + return true; + if(outgs.size()==0) + return false; + AbstractPoint *dummy=0; + return IsCommonDirectSonOf(sop,outgs,dummy); +} + +bool AbstractPoint::IsSimplyLinkedBeforeExt(Node *node) +{ + InGate *ing(node->getInGate()); + return ing->getBackLinks().size()<=1; +} + +bool AbstractPoint::IsNoLinksBefore(Node *node) +{ + InGate *ing(node->getInGate()); + return ing->getBackLinks().size()==0; +} + +bool AbstractPoint::IsNoLinksAfter(Node *node) +{ + OutGate *oug(node->getOutGate()); + return oug->edSetInGate().size()==0; +} + +Node *AbstractPoint::GetNodeB4(Node *node) +{ + InGate *ing(node->getInGate()); + std::list bl(ing->getBackLinks()); + if(bl.size()>1) + throw Exception("AbstractPoint::GetNodeB4 : precond not OK !"); + if(bl.size()==0) + return 0; + return bl.front()->getNode(); +} + +Node *AbstractPoint::GetNodeAfter(Node *node) +{ + OutGate *oug(node->getOutGate()); + std::list fl(oug->edSetInGate()); + if(fl.size()>1) + throw Exception("AbstractPoint::GetNodeAfter : precond not OK !"); + if(fl.size()==0) + return 0; + return (*fl.begin())->getNode(); +} + +AbstractPoint *AbstractPoint::GetDirectSonOf(AbstractPoint *refFather, AbstractPoint *sonOrLittleSon) +{ + AbstractPoint *curFath(sonOrLittleSon->getFather()),*cur(sonOrLittleSon); + while(curFath && curFath!=refFather) + { + cur=curFath; + curFath=cur->getFather(); + } + if(!curFath) + throw YACS::Exception("AbstractPoint::GetDirectSonOf : not in the same family !"); + return cur; +} + +bool AbstractPoint::IsCommonDirectSonOf(AbstractPoint *refFather, const std::list& outgs, AbstractPoint *&ret) +{ + if(outgs.size()<1) + throw YACS::Exception("AbstractPoint::GetCommonDirectSonOf1 : not enough !"); + std::list::const_iterator it(outgs.begin()); + OutGate *ref(*(it++)); + AbstractPoint *ref2(GetDirectSonOf(refFather,refFather->findPointWithNode(ref->getNode()))); + for(;it!=outgs.end();it++) + { + if(!ref2->contains((*it)->getNode())) + return false; + } + ret=ref2; + return true; +} + +bool AbstractPoint::IsCommonDirectSonOf(AbstractPoint *refFather, const std::list& ings, AbstractPoint *&ret) +{ + if(ings.size()<1) + throw YACS::Exception("AbstractPoint::GetCommonDirectSonOf2 : not enough !"); + std::list::const_iterator it(ings.begin()); + InGate *ref(*(it++)); + AbstractPoint *ref2(GetDirectSonOf(refFather,refFather->findPointWithNode(ref->getNode()))); + for(;it!=ings.end();it++) + { + if(!ref2->contains((*it)->getNode())) + return false; + } + ret=ref2; + return true; +} diff --git a/src/engine/AbstractPoint.hxx b/src/engine/AbstractPoint.hxx new file mode 100644 index 000000000..11ddee6c2 --- /dev/null +++ b/src/engine/AbstractPoint.hxx @@ -0,0 +1,89 @@ +// Copyright (C) 2015 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 __ABSTRACTPOINT_HXX__ +#define __ABSTRACTPOINT_HXX__ + +#include "YACSlibEngineExport.hxx" + +#include +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class Node; + class InGate; + class OutGate; + class BlocPoint; + class ForkBlocPoint; + class LinkedBlocPoint; + + class YACSLIBENGINE_EXPORT AbstractPoint + { + public: + AbstractPoint(AbstractPoint *father):_father(father) { } + AbstractPoint *getFather() const { return _father; } + AbstractPoint *getGodFather(); + bool amIGod() { return getGodFather()==0; } + void setFather(AbstractPoint *father) { _father=father; } + // + bool isBegin(); + bool isLast(); + bool isSimplyLinkedBeforeAfter(BlocPoint *sop); + bool isSimplyLinkedAfterNullBefore(BlocPoint *sop); + bool isSimplyLinkedBeforeNullAfter(BlocPoint *sop); + // + LinkedBlocPoint *tryAsLink(BlocPoint *sop); + ForkBlocPoint *tryAsFork(BlocPoint *sop); + ForkBlocPoint *tryAsForkBis(BlocPoint *sop); + ForkBlocPoint *tryAsForkTer(BlocPoint *sop); + // + virtual Node *getFirstNode() = 0; + virtual Node *getLastNode() = 0; + virtual AbstractPoint *findPointWithNode(Node *node) = 0; + virtual bool contains(Node *node) = 0; + virtual int getNumberOfNodes() const = 0; + virtual int getMaxLevelOfParallelism() const = 0; + virtual std::string getRepr() const = 0; + virtual ~AbstractPoint(); + public: + static bool IsGatherB4Ext(Node *node); + bool isSimplyLinkedAfter(BlocPoint *sop, Node *node); + static bool IsSimplyLinkedAfterExt(Node *node); + static bool IsScatterAfterExt(Node *node); + bool isSimplyLinkedBefore(BlocPoint *sop, Node *node); + static bool IsSimplyLinkedBeforeExt(Node *node); + static bool IsNoLinksBefore(Node *node); + static bool IsNoLinksAfter(Node *node); + static Node *GetNodeB4(Node *node); + static Node *GetNodeAfter(Node *node); + static AbstractPoint *GetDirectSonOf(AbstractPoint *refFather, AbstractPoint *sonOrLittleSon); + static bool IsCommonDirectSonOf(AbstractPoint *refFather, const std::list& outgs, AbstractPoint *&ret); + static bool IsCommonDirectSonOf(AbstractPoint *refFather, const std::list& ings, AbstractPoint *&ret); + protected: + AbstractPoint *_father; + }; + } +} + + +#endif diff --git a/src/engine/AnyInputPort.hxx b/src/engine/AnyInputPort.hxx index 7978410c5..d329635c8 100644 --- a/src/engine/AnyInputPort.hxx +++ b/src/engine/AnyInputPort.hxx @@ -39,7 +39,7 @@ namespace YACS void exSaveInit(); void exRestoreInit(); Any *getValue() const { return _value; } - int getIntValue() const { return _value->getIntValue(); } + int getIntValue() const { return _value ? _value->getIntValue():0; } void put(Any *data); void *get() const; virtual std::string getAsString(); diff --git a/src/engine/BagPoint.cxx b/src/engine/BagPoint.cxx new file mode 100644 index 000000000..89e3c2d10 --- /dev/null +++ b/src/engine/BagPoint.cxx @@ -0,0 +1,149 @@ +// Copyright (C) 2015 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 "BagPoint.hxx" +#include "Exception.hxx" +#include "LinkedBlocPoint.hxx" +#include "ForkBlocPoint.hxx" + +#include +#include + +using namespace YACS::ENGINE; + +BagPoint::BagPoint(const std::list& nodes, AbstractPoint *father):BlocPoint(nodes,father) +{ +} + +Node *BagPoint::getFirstNode() +{ + if(_nodes.size()!=1) + throw YACS::Exception("BagPoint::getFirstNode : invalid call !"); + else + return (*_nodes.begin())->getFirstNode(); +} + +Node *BagPoint::getLastNode() +{ + if(_nodes.size()!=1) + throw YACS::Exception("BagPoint::getLastNode : invalid call !"); + else + return (*_nodes.begin())->getLastNode(); +} + +int BagPoint::getMaxLevelOfParallelism() const +{ + if(_nodes.size()!=1) + throw YACS::Exception("BagPoint::getMaxLevelOfParallelism : invalid call !"); + else + return (*_nodes.begin())->getMaxLevelOfParallelism(); +} + +std::string BagPoint::getRepr() const +{ + std::ostringstream oss; + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++) + oss << (*it)->getRepr() << " - "; + return oss.str(); +} + +#include + +void BagPoint::replaceInMe(BlocPoint *aSet) +{ + const std::list& pts(aSet->getListOfPoints()); + for(std::list::const_iterator it0=pts.begin();it0!=pts.end();it0++) + { + std::list::iterator it1(std::find(_nodes.begin(),_nodes.end(),*it0)); + if(it1==_nodes.end()) + throw Exception("SetOfPoints::replaceInMe : internal error !"); + _nodes.erase(it1); + } + _nodes.push_back(aSet); +} + +void BagPoint::deal1(bool& somethingDone) +{ + somethingDone=false; + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + { + if(!(*it)->isSimplyLinkedBeforeAfter(this)) + if(!(*it)->isSimplyLinkedAfterNullBefore(this) && !(*it)->isSimplyLinkedBeforeNullAfter(this)) + continue; + LinkedBlocPoint *try0((*it)->tryAsLink(this)); + if(try0) + { + replaceInMe(try0); + somethingDone=true; + break; + } + } +} + +void BagPoint::deal2(bool& somethingDone) +{ + somethingDone=false; + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + { + if(!(*it)->isSimplyLinkedBeforeAfter(this)) + continue; + ForkBlocPoint *try1((*it)->tryAsFork(this)); + if(try1) + { + replaceInMe(try1); + somethingDone=true; + break; + } + } +} + +void BagPoint::deal2Bis(bool& somethingDone) +{ + somethingDone=false; + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + { + if(!(*it)->isSimplyLinkedAfterNullBefore(this)) + continue; + ForkBlocPoint *try1((*it)->tryAsForkBis(this)); + if(try1) + { + replaceInMe(try1); + somethingDone=true; + break; + } + } +} + +void BagPoint::deal2Ter(bool& somethingDone) +{ + somethingDone=false; + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + { + if(!(*it)->isSimplyLinkedBeforeNullAfter(this)) + continue; + ForkBlocPoint *try1((*it)->tryAsForkTer(this)); + if(try1) + { + replaceInMe(try1); + somethingDone=true; + break; + } + } +} + diff --git a/src/engine/BagPoint.hxx b/src/engine/BagPoint.hxx new file mode 100644 index 000000000..3ad8c32c5 --- /dev/null +++ b/src/engine/BagPoint.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2015 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 __BAGPOINT_HXX__ +#define __BAGPOINT_HXX__ + +#include "YACSlibEngineExport.hxx" +#include "BlocPoint.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class YACSLIBENGINE_EXPORT BagPoint : public BlocPoint + { + public: + BagPoint(const std::list& nodes, AbstractPoint *father); + public://overloading + Node *getFirstNode(); + Node *getLastNode(); + int getMaxLevelOfParallelism() const; + std::string getRepr() const; + public: + int size() const { return (int)_nodes.size(); } + void replaceInMe(BlocPoint *aSet); + void deal1(bool& somethingDone); + void deal2(bool& somethingDone); + void deal2Bis(bool& somethingDone); + void deal2Ter(bool& somethingDone); + }; + } +} + + +#endif diff --git a/src/engine/Bloc.cxx b/src/engine/Bloc.cxx index a2def0cc0..e7fa7f74c 100644 --- a/src/engine/Bloc.cxx +++ b/src/engine/Bloc.cxx @@ -25,7 +25,9 @@ #include "OutputDataStreamPort.hxx" #include "ElementaryNode.hxx" #include "Visitor.hxx" +#include "SetOfPoints.hxx" +#include #include #include @@ -224,6 +226,54 @@ void Bloc::edRemoveChild(Node *node) throw(YACS::Exception) } } +std::vector< std::list > Bloc::splitIntoIndependantGraph() const +{ + std::size_t sz(_setOfNode.size()); + list::const_iterator it=_setOfNode.begin(); + for(;it!=_setOfNode.end();it++) + (*it)->_colour=White; + it=_setOfNode.begin(); + std::vector< list > ret; + while(it!=_setOfNode.end()) + { + Node *start(*it); start->_colour=Grey; + ret.push_back(list()); + list& ll(ret.back()); + std::queue fifo; fifo.push(start); + while(!fifo.empty()) + { + Node *cur(fifo.front()); fifo.pop(); + ll.push_back(cur); + // + OutGate *og(cur->getOutGate()); + list og2(og->edSetInGate()); + for(list::const_iterator it2=og2.begin();it2!=og2.end();it2++) + { + Node *cur2((*it2)->getNode()); + if(cur2->_colour==White) + { + cur2->_colour=Grey; + fifo.push(cur2); + } + } + // + InGate *ig(cur->getInGate()); + list bl(ig->getBackLinks()); + for(list::const_iterator it3=bl.begin();it3!=bl.end();it3++) + { + Node *cur3((*it3)->getNode()); + if(cur3->_colour==White) + { + cur3->_colour=Grey; + fifo.push(cur3); + } + } + } + for(it=_setOfNode.begin();it!=_setOfNode.end() && (*it)->_colour!=White;it++); + } + return ret; +} + Node *Bloc::getChildByShortName(const std::string& name) const throw(YACS::Exception) { for (list::const_iterator iter = _setOfNode.begin(); iter != _setOfNode.end(); iter++) @@ -269,8 +319,8 @@ bool Bloc::isNameAlreadyUsed(const std::string& name) const bool insertNodeChildrenInSet(Node *node, std::set& nodeSet) { bool verdict=true; - set outNodes=node->getOutNodes(); - for (set::iterator iter=outNodes.begin();iter!=outNodes.end(); iter++) + list outNodes=node->getOutNodes(); + for (list::iterator iter=outNodes.begin();iter!=outNodes.end(); iter++) { verdict=(nodeSet.insert(*iter)).second; if (verdict) verdict = insertNodeChildrenInSet((*iter),nodeSet); @@ -300,8 +350,8 @@ std::vector< std::pair > Bloc::getSetOfInternalCFLinks() co vector< pair > ret; for(list::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) { - set outCFLinksOfCurNode=(*iter)->_outGate.edSetInGate(); - for(set::iterator iter2=outCFLinksOfCurNode.begin();iter2!=outCFLinksOfCurNode.end();iter2++) + list outCFLinksOfCurNode=(*iter)->_outGate.edSetInGate(); + for(list::iterator iter2=outCFLinksOfCurNode.begin();iter2!=outCFLinksOfCurNode.end();iter2++) ret.push_back(pair(&(*iter)->_outGate,*iter2)); } return ret; @@ -370,26 +420,26 @@ YACS::Event Bloc::updateStateOnFailedEventFrom(Node *node, const Executor *execI void Bloc::writeDot(std::ostream &os) const { - os << " subgraph cluster_" << getId() << " {\n" ; - listnodes=getChildren(); - for(list::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) + os << " subgraph cluster_" << getId() << " {\n" ; + listnodes=getChildren(); + for(list::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) { - (*iter)->writeDot(os); - string p=(*iter)->getId(); - //not connected node - if((*iter)->_inGate._backLinks.size() == 0) os << getId() << " -> " << p << ";\n"; - setoutnodes = (*iter)->getOutNodes(); - for(set::const_iterator itout=outnodes.begin();itout!=outnodes.end();itout++) + (*iter)->writeDot(os); + string p=(*iter)->getId(); + //not connected node + if((*iter)->_inGate._backLinks.size() == 0) os << getId() << " -> " << p << ";\n"; + listoutnodes = (*iter)->getOutNodes(); + for(list::const_iterator itout=outnodes.begin();itout!=outnodes.end();itout++) { - os << p << " -> " << (*itout)->getId() << ";\n"; + os << p << " -> " << (*itout)->getId() << ";\n"; } } - os << "}\n" ; - os << getId() << "[fillcolor=\"" ; - YACS::StatesForNode state=getEffectiveState(); - os << getColorState(state); - os << "\" label=\"" << "Bloc:" ; - os << getQualifiedName() <<"\"];\n"; + os << "}\n" ; + os << getId() << "[fillcolor=\"" ; + YACS::StatesForNode state=getEffectiveState(); + os << getColorState(state); + os << "\" label=\"" << "Bloc:" ; + os << getQualifiedName() <<"\"];\n"; } void Bloc::accept(Visitor* visitor) @@ -403,37 +453,15 @@ void Bloc::accept(Visitor* visitor) */ int Bloc::getMaxLevelOfParallelism() const { - std::set s(_setOfNode.begin(),_setOfNode.end()); - for(std::set::const_iterator it=s.begin();it!=s.end();it++) - (*it)->_colour=White; - std::vector levs; - while(!s.empty()) + std::vector< std::list > r(splitIntoIndependantGraph()); + int ret(0); + for(std::vector< std::list >::const_iterator it=r.begin();it!=r.end();it++) { - Node *seed(*(s.begin())); - int myCurLev(0); - while(seed) - { - s.erase(seed); - std::set ingates(seed->getOutGate()->edSetInGate()); - int myCurLev2(seed->getMaxLevelOfParallelism()); - for(std::set::const_iterator it=ingates.begin();it!=ingates.end();it++) - { - Node *curNode((*it)->getNode()); - curNode->_colour=Grey; - myCurLev2=std::max(curNode->getMaxLevelOfParallelism(),myCurLev2); - } - myCurLev=std::max(myCurLev,myCurLev2); - seed=0; - for(std::set::const_iterator it=s.begin();it!=s.end();it++) - if((*it)->_colour==Grey) - { - seed=*it; - break; - } - } - levs.push_back(myCurLev); + SetOfPoints sop(*it); + sop.simplify(); + ret+=sop.getMaxLevelOfParallelism(); } - return std::accumulate(levs.begin(),levs.end(),0); + return ret; } /*! @@ -462,8 +490,8 @@ void Bloc::performCFComputations(LinkInfo& info) const for(list::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++) { Node* n1=*iter; - std::set ingates=n1->getOutGate()->edSetInGate(); - for(std::set::const_iterator it2=ingates.begin();it2!=ingates.end();it2++) + std::list ingates=n1->getOutGate()->edSetInGate(); + for(std::list::const_iterator it2=ingates.begin();it2!=ingates.end();it2++) { //CF link : n1 -> (*it2)->getNode() Node* n2=(*it2)->getNode(); @@ -828,9 +856,8 @@ void Bloc::findUselessLinksIn(const std::list< std::vector >& res , Link set searcher(iter2+1,(*whereToPeerAt).end());//to boost research for(;iter2!=((*whereToPeerAt).end()-2);iter2++) { - map::iterator iter4; - map& nexts=(*iter2)->getOutGate()->edMapInGate(); - for(iter4=nexts.begin();iter4!=nexts.end();iter4++) + list< pair >& nexts=(*iter2)->getOutGate()->edMapInGate(); + for(list< pair >::iterator iter4=nexts.begin();iter4!=nexts.end();iter4++) if((*iter4).first->getNode()!=*(iter2+1)) if(searcher.find((*iter4).first->getNode())!=searcher.end()) info.pushUselessCFLink(*iter2,(*iter4).first->getNode()); diff --git a/src/engine/Bloc.hxx b/src/engine/Bloc.hxx index 0bd35120d..a46ae682c 100644 --- a/src/engine/Bloc.hxx +++ b/src/engine/Bloc.hxx @@ -51,6 +51,7 @@ namespace YACS void edRemoveChild(Node *node) throw(Exception); std::list getChildren() const { return _setOfNode; } std::list edGetDirectDescendants() const { return _setOfNode; } + std::vector< std::list > splitIntoIndependantGraph() const; Node *getChildByShortName(const std::string& name) const throw(Exception); virtual void writeDot(std::ostream &os) const; void accept(Visitor *visitor); @@ -100,8 +101,8 @@ namespace YACS template<> struct CFDirectionVisTraits { - typedef std::map::iterator Iterator; - typedef std::map& Nexts; + typedef std::list< std::pair >::iterator Iterator; + typedef std::list< std::pair >& Nexts; static Nexts getNexts(Node *node) { return node->getOutGate()->edMapInGate(); } }; @@ -109,8 +110,8 @@ namespace YACS template<> struct CFDirectionVisTraits { - typedef std::map::iterator Iterator; - typedef std::map& Nexts; + typedef std::list< std::pair >::iterator Iterator; + typedef std::list< std::pair >& Nexts; static Nexts getNexts(Node *node) { return node->getInGate()->edMapOutGate(); } }; diff --git a/src/engine/BlocPoint.cxx b/src/engine/BlocPoint.cxx new file mode 100644 index 000000000..9678e09e3 --- /dev/null +++ b/src/engine/BlocPoint.cxx @@ -0,0 +1,92 @@ +// Copyright (C) 2015 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 "BlocPoint.hxx" +#include "Node.hxx" + +using namespace YACS::ENGINE; + +BlocPoint::BlocPoint(const std::list& nodes, AbstractPoint *father):AbstractPoint(father),_nodes(nodes) +{ + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++) + (*it)->setFather(this); +} + +AbstractPoint *BlocPoint::findPointWithNode(Node *node) +{ + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + { + AbstractPoint *ret((*it)->findPointWithNode(node)); + if(ret) + return AbstractPoint::GetDirectSonOf(this,ret); + } + return 0; +} + +AbstractPoint *BlocPoint::getNodeAfter(Node *node) +{ + OutGate *oug(node->getOutGate()); + std::list fl(oug->edSetInGate()); + if(fl.size()>=1) + { + AbstractPoint *ret(0); + IsCommonDirectSonOf(this,fl,ret); + return ret; + } + else + return 0; +} + +AbstractPoint *BlocPoint::getNodeB4(Node *node) +{ + InGate *ing(node->getInGate()); + std::list bl(ing->getBackLinks()); + if(bl.size()>=1) + { + AbstractPoint *ret(0); + IsCommonDirectSonOf(this,bl,ret); + return ret; + } + else + return 0; +} + +bool BlocPoint::contains(Node *node) +{ + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + { + if((*it)->contains(node)) + return true; + } + return false; +} + +int BlocPoint::getNumberOfNodes() const +{ + int ret(0); + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++) + ret+=(*it)->getNumberOfNodes(); + return ret; +} + +BlocPoint::~BlocPoint() +{ + for(std::list::iterator it=_nodes.begin();it!=_nodes.end();it++) + delete *it; +} diff --git a/src/engine/BlocPoint.hxx b/src/engine/BlocPoint.hxx new file mode 100644 index 000000000..52d2a715e --- /dev/null +++ b/src/engine/BlocPoint.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2015 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 __BLOCPOINT_HXX__ +#define __BLOCPOINT_HXX__ + +#include "YACSlibEngineExport.hxx" +#include "AbstractPoint.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class YACSLIBENGINE_EXPORT BlocPoint : public AbstractPoint + { + protected: + std::list _nodes; + public: + BlocPoint(const std::list& nodes, AbstractPoint *father); + AbstractPoint *findPointWithNode(Node *node); + AbstractPoint *getNodeAfter(Node *node); + AbstractPoint *getNodeB4(Node *node); + bool contains(Node *node); + int getNumberOfNodes() const; + const std::list& getListOfPoints() const { return _nodes; } + virtual ~BlocPoint(); + }; + } +} + + +#endif diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index 28c6fde49..a8a477e1e 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -99,6 +99,13 @@ SET(YACSlibEngine_HEADERS AnyOutputPort.hxx ServerNode.hxx InPropertyPort.hxx + AbstractPoint.hxx + BlocPoint.hxx + BagPoint.hxx + ForkBlocPoint.hxx + LinkedBlocPoint.hxx + ElementaryPoint.hxx + SetOfPoints.hxx ) # --- sources --- @@ -164,6 +171,13 @@ SET(YACSlibEngine_SOURCES Task.cxx Scheduler.cxx InPropertyPort.cxx + AbstractPoint.cxx + BlocPoint.cxx + BagPoint.cxx + ForkBlocPoint.cxx + LinkedBlocPoint.cxx + ElementaryPoint.cxx + SetOfPoints.cxx ) # --- rules --- diff --git a/src/engine/ComposedNode.cxx b/src/engine/ComposedNode.cxx index 31424ad25..69870fa47 100644 --- a/src/engine/ComposedNode.cxx +++ b/src/engine/ComposedNode.cxx @@ -28,7 +28,6 @@ #include "DataStreamPort.hxx" #include "ElementaryNode.hxx" #include "ComponentInstance.hxx" -#include "ForEachLoop.hxx" #include #include @@ -1135,43 +1134,18 @@ list ComposedNode::getAllRecursiveNodes() //! Get the progress weight for all elementary nodes /*! - * Only elementary nodes have weight. If a node is in a for each loop, his weight is modified by the size of the loop - * + * Only elementary nodes have weight. A simple composed node only sum up weight of all his descendants + * (working is different for loop or switch nodes) */ -list > ComposedNode::getProgressWeight() -{ - list > ret; - list setOfNode=edGetDirectDescendants(); - int elemDone, elemTotal; - for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) - { - if ( dynamic_cast (*iter) ) - { - elemDone=((ForEachLoop*)(*iter))->getCurrentIndex(); - elemTotal=((ForEachLoop*)(*iter))->getNbOfElementsToBeProcessed(); - list > myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight(); - myCurrentSet.pop_front(); - myCurrentSet.pop_back(); - for(list >::iterator iter=myCurrentSet.begin();iter!=myCurrentSet.end();iter++) - { - (*iter).first=(*iter).second*elemDone; - (*iter).second*=elemTotal; - } - ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); - } - else if ( dynamic_cast (*iter) ) - { - list > myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight(); - ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); - } - else - { - if ((*iter)->getState() == YACS::DONE) - ret.push_back(pair(1,1)); - else - ret.push_back(pair(0,1)); - } - } +list ComposedNode::getProgressWeight() const +{ + list ret; + list setOfNode=edGetDirectDescendants(); + for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + list myCurrentSet=((ComposedNode*)(*iter))->getProgressWeight(); + ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); + } return ret; } diff --git a/src/engine/ComposedNode.hxx b/src/engine/ComposedNode.hxx index 84e4d5555..aadd2804c 100644 --- a/src/engine/ComposedNode.hxx +++ b/src/engine/ComposedNode.hxx @@ -80,7 +80,7 @@ namespace YACS std::list getRecursiveConstituents() const; std::list getAllRecursiveNodes(); virtual std::list getAllRecursiveConstituents(); // first implementation - std::list > getProgressWeight(); + std::list getProgressWeight() const; std::string getInPortName(const InPort *) const throw (Exception); std::string getOutPortName(const OutPort *) const throw (Exception); // diff --git a/src/engine/DataPort.cxx b/src/engine/DataPort.cxx index be0c2eb5d..895b0cb35 100644 --- a/src/engine/DataPort.cxx +++ b/src/engine/DataPort.cxx @@ -28,17 +28,20 @@ const char DataPort::NAME[]="DataPort"; DataPort::~DataPort() { - _type->decrRef(); + if(_type) + _type->decrRef(); } DataPort::DataPort(const std::string& name, Node *node, TypeCode* type):Port(node),_name(name),_type(type) { - _type->incrRef(); + if(_type) + _type->incrRef(); } DataPort::DataPort(const DataPort& other, Node *newHelder):Port(other,newHelder),_name(other._name),_type(other._type) { - _type->incrRef(); + if(_type) + _type->incrRef(); } void DataPort::edSetType(TypeCode* type) diff --git a/src/engine/DynParaLoop.cxx b/src/engine/DynParaLoop.cxx index e94638190..71a5fe368 100644 --- a/src/engine/DynParaLoop.cxx +++ b/src/engine/DynParaLoop.cxx @@ -480,7 +480,7 @@ void DynParaLoop::checkControlDependancy(OutPort *start, InPort *end, bool cross } void DynParaLoop::checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, - InPort *end, const std::list& pointsOfViewEnd) throw(Exception) + InPort *end, const std::list& pointsOfViewEnd) throw(YACS::Exception) { ComposedNode::checkLinkPossibility(start, pointsOfViewStart, end, pointsOfViewEnd); Node * startNode = isInMyDescendance(start->getNode()); diff --git a/src/engine/ElementaryNode.cxx b/src/engine/ElementaryNode.cxx index 52b4e6eee..a2dd127df 100644 --- a/src/engine/ElementaryNode.cxx +++ b/src/engine/ElementaryNode.cxx @@ -547,6 +547,24 @@ list ElementaryNode::getRecursiveConstituents() const return ret; } +//! Get the progress weight for all elementary nodes +/*! + * Only elementary nodes have weight. At this stage weight is 0 or 1 (it can be modified later following + * the kind of father) + */ +list ElementaryNode::getProgressWeight() const +{ + list ret; + ProgressWeight myWeight; + myWeight.weightTotal=1; + if (getState() == YACS::DONE) + myWeight.weightDone=1; + else + myWeight.weightDone=0; + ret.push_back(myWeight); + return ret; +} + Node *ElementaryNode::getChildByName(const std::string& name) const throw(YACS::Exception) { string what("ElementaryNode does not agregate any nodes particullary node with name "); what+=name; diff --git a/src/engine/ElementaryNode.hxx b/src/engine/ElementaryNode.hxx index 843de41e1..07fe8a485 100644 --- a/src/engine/ElementaryNode.hxx +++ b/src/engine/ElementaryNode.hxx @@ -69,6 +69,7 @@ namespace YACS void getReadyTasks(std::vector& tasks); void edRemovePort(Port *port) throw(Exception); std::list getRecursiveConstituents() const; + std::list getProgressWeight() const; Node *getChildByName(const std::string& name) const throw(Exception); virtual void checkBasicConsistency() const throw(Exception); ComposedNode *getDynClonerIfExists(const ComposedNode *levelToStop) const; diff --git a/src/engine/ElementaryPoint.cxx b/src/engine/ElementaryPoint.cxx new file mode 100644 index 000000000..e8cedfc7c --- /dev/null +++ b/src/engine/ElementaryPoint.cxx @@ -0,0 +1,65 @@ +// Copyright (C) 2015 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 "ElementaryPoint.hxx" +#include "Node.hxx" + +using namespace YACS::ENGINE; + +ElementaryPoint::~ElementaryPoint() +{ +} + +AbstractPoint *ElementaryPoint::findPointWithNode(Node *node) +{ + if(node==_node) + return this; + else + return 0; +} + +bool ElementaryPoint::contains(Node *node) +{ + return _node==node; +} + +Node *ElementaryPoint::getFirstNode() +{ + return _node; +} + +Node *ElementaryPoint::getLastNode() +{ + return _node; +} + +int ElementaryPoint::getNumberOfNodes() const +{ + return 1; +} + +int ElementaryPoint::getMaxLevelOfParallelism() const +{ + return _node->getMaxLevelOfParallelism(); +} + +std::string ElementaryPoint::getRepr() const +{ + return _node->getName(); +} diff --git a/src/engine/ElementaryPoint.hxx b/src/engine/ElementaryPoint.hxx new file mode 100644 index 000000000..127704aaa --- /dev/null +++ b/src/engine/ElementaryPoint.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2015 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 __ELEMENTARYPOINT_HXX__ +#define __ELEMENTARYPOINT_HXX__ + +#include "YACSlibEngineExport.hxx" +#include "AbstractPoint.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class Node; + + class YACSLIBENGINE_EXPORT ElementaryPoint : public AbstractPoint + { + private: + Node *_node; + public: + ElementaryPoint(Node *node):AbstractPoint(0),_node(node) { } + AbstractPoint *findPointWithNode(Node *node); + bool contains(Node *node); + Node *getFirstNode(); + Node *getLastNode(); + int getNumberOfNodes() const; + int getMaxLevelOfParallelism() const; + std::string getRepr() const; + virtual ~ElementaryPoint(); + }; + } +} + + +#endif diff --git a/src/engine/Executor.cxx b/src/engine/Executor.cxx index daa578be6..456caf6d3 100644 --- a/src/engine/Executor.cxx +++ b/src/engine/Executor.cxx @@ -649,11 +649,18 @@ void Executor::stopExecution() bool Executor::saveState(const std::string& xmlFile) { DEBTRACE("Executor::saveState() in " << xmlFile); - YACS::ENGINE::VisitorSaveState vst(_root); - vst.openFileDump(xmlFile.c_str()); - _root->accept(&vst); - vst.closeFileDump(); - return true; + bool result = false; + try { + YACS::ENGINE::VisitorSaveState vst(_root); + vst.openFileDump(xmlFile.c_str()); + _root->accept(&vst); + vst.closeFileDump(); + result = true; + } + catch(Exception& ex) { + std::cerr << ex.what() << std::endl; + } + return result; } //! not yet implemented diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx index b753f22e6..3b9dec62c 100644 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@ -741,6 +741,7 @@ YACS::Event ForEachLoop::updateStateForInitNodeOnFinishedEventFrom(Node *node, u _execNodes[id]->exUpdateState(); _nbOfEltConsumed++; _initializingCounter--; + _currentIndex++; if (_initializingCounter == 0) _initNode->setState(DONE); return YACS::NOEVENT; @@ -1103,9 +1104,36 @@ std::string ForEachLoop::getProgress() const return aProgress.str(); } +//! Get the progress weight for all elementary nodes +/*! + * Only elementary nodes have weight. For each node in the loop, the weight done is multiplied + * by the number of elements done and the weight total by the number total of elements + */ +list ForEachLoop::getProgressWeight() const +{ + list ret; + list setOfNode=edGetDirectDescendants(); + int elemDone=getCurrentIndex(); + int elemTotal=getNbOfElementsToBeProcessed(); + for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + list myCurrentSet=(*iter)->getProgressWeight(); + for(list::iterator iter=myCurrentSet.begin();iter!=myCurrentSet.end();iter++) + { + (*iter).weightDone=((*iter).weightTotal) * elemDone; + (*iter).weightTotal*=elemTotal; + } + ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); + } + return ret; +} + int ForEachLoop::getNbOfElementsToBeProcessed() const { - return _splitterNode.getNumberOfElements(); + int nbBranches = _nbOfBranches.getIntValue(); + return _splitterNode.getNumberOfElements() + + (_initNode ? nbBranches:0) + + (_finalizeNode ? nbBranches:0) ; } /*! diff --git a/src/engine/ForEachLoop.hxx b/src/engine/ForEachLoop.hxx index 1e0655409..d70259618 100644 --- a/src/engine/ForEachLoop.hxx +++ b/src/engine/ForEachLoop.hxx @@ -192,6 +192,7 @@ namespace YACS virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";} virtual void resetState(int level); std::string getProgress() const; + std::list getProgressWeight() const; int getCurrentIndex() const { return _currentIndex; } int getNbOfElementsToBeProcessed() const; #ifndef SWIG diff --git a/src/engine/ForLoop.cxx b/src/engine/ForLoop.cxx index fe4564490..140a94982 100644 --- a/src/engine/ForLoop.cxx +++ b/src/engine/ForLoop.cxx @@ -265,17 +265,51 @@ std::list ForLoop::getSetOfOutputPort() const return ret; } + +int ForLoop::getNbSteps() const +{ + AnyInputPort* aNbStepsPort = (AnyInputPort*)&_nbOfTimesPort; + int nbSteps = 0; + if (aNbStepsPort && !aNbStepsPort->isEmpty()) + nbSteps = aNbStepsPort->getIntValue(); + return nbSteps; +} + std::string ForLoop::getProgress() const { std::stringstream aProgress; aProgress << "0"; - AnyInputPort* aNbStepsPort = (AnyInputPort*)&_nbOfTimesPort; - if (aNbStepsPort && !aNbStepsPort->isEmpty()) { - int nbSteps = aNbStepsPort->getIntValue(); - if (nbSteps > 0 && _nbOfTurns >= 0) { + int nbSteps = getNbSteps(); + if (nbSteps > 0 && _nbOfTurns >= 0) + { aProgress.str(""); aProgress << _nbOfTurns << "/" << nbSteps; } - } return aProgress.str(); } + +//! Get the progress weight for all elementary nodes +/*! + * Only elementary nodes have weight. For each node in the loop, the weight done is multiplied + * by the number of steps done and the weight total by the number total of steps + * + */ +list ForLoop::getProgressWeight() const +{ + list ret; + list setOfNode=edGetDirectDescendants(); + int nbStepsDone=getNbOfTurns(); + int nbStepsTotal=getNbSteps(); + for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + list myCurrentSet=(*iter)->getProgressWeight(); + for(list::iterator iter=myCurrentSet.begin();iter!=myCurrentSet.end();iter++) + { + (*iter).weightDone=((*iter).weightTotal) * nbStepsDone; + (*iter).weightTotal*=nbStepsTotal; + } + ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); + } + return ret; +} + diff --git a/src/engine/ForLoop.hxx b/src/engine/ForLoop.hxx index e00c271ba..3d33e0626 100644 --- a/src/engine/ForLoop.hxx +++ b/src/engine/ForLoop.hxx @@ -55,6 +55,9 @@ namespace YACS OutputPort *edGetIndexPort() { return &_indexPort; } virtual std::string typeName() {return "YACS__ENGINE__ForLoop";} std::string getProgress() const; + std::list getProgressWeight() const; + int getNbSteps() const; + protected: YACS::Event updateStateOnFinishedEventFrom(Node *node); void checkCFLinks(const std::list& starts, InputPort *end, unsigned char& alreadyFed, diff --git a/src/engine/ForkBlocPoint.cxx b/src/engine/ForkBlocPoint.cxx new file mode 100644 index 000000000..1275183e3 --- /dev/null +++ b/src/engine/ForkBlocPoint.cxx @@ -0,0 +1,74 @@ +// Copyright (C) 2015 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 "ForkBlocPoint.hxx" +#include "Exception.hxx" + +#include + +using namespace YACS::ENGINE; + +ForkBlocPoint::ForkBlocPoint(const std::list& nodes, AbstractPoint *father):BlocPoint(nodes,father) +{ +} + +ForkBlocPoint::~ForkBlocPoint() +{ +} + +Node *ForkBlocPoint::getFirstNode() +{ + if(_nodes.empty()) + throw Exception("ForkBlocPoint::getFirstNode : error no branches !"); + return _nodes.front()->getFirstNode(); +} + +Node *ForkBlocPoint::getLastNode() +{ + if(_nodes.empty()) + throw Exception("ForkBlocPoint::getLastNode : error no branches !"); + return _nodes.front()->getLastNode();//not a bug - seen from the outside only first branch exists ! +} + +int ForkBlocPoint::getMaxLevelOfParallelism() const +{ + int ret(0); + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++) + ret+=(*it)->getMaxLevelOfParallelism(); + return ret; +} + +std::string ForkBlocPoint::getRepr() const +{ + std::size_t sz(_nodes.size()),ii(0); + std::string ret("["); + std::vector elts(sz); + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++,ii++) + elts[ii]=(*it)->getRepr(); + std::sort(elts.begin(),elts.end()); + ii=0; + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++,ii++) + { + ret+=elts[ii]; + if(ii!=sz-1) + ret+="*"; + } + ret+="]"; + return ret; +} diff --git a/src/engine/ForkBlocPoint.hxx b/src/engine/ForkBlocPoint.hxx new file mode 100644 index 000000000..e7fd79ddf --- /dev/null +++ b/src/engine/ForkBlocPoint.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2015 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 __FORKBLOCPOINT_HXX__ +#define __BLOKBLOCPOINT_HXX__ + +#include "YACSlibEngineExport.hxx" +#include "BlocPoint.hxx" + +namespace YACS +{ + namespace ENGINE + { + class YACSLIBENGINE_EXPORT ForkBlocPoint : public BlocPoint + { + public: + ForkBlocPoint(const std::list& nodes, AbstractPoint *father); + Node *getFirstNode(); + Node *getLastNode(); + int getMaxLevelOfParallelism() const; + std::string getRepr() const; + virtual ~ForkBlocPoint(); + }; + } +} + + +#endif diff --git a/src/engine/InGate.cxx b/src/engine/InGate.cxx index 49eb3abb5..7a85b6e98 100644 --- a/src/engine/InGate.cxx +++ b/src/engine/InGate.cxx @@ -23,6 +23,8 @@ //#define _DEVDEBUG_ #include "YacsTrace.hxx" +#include + using namespace YACS::ENGINE; using namespace std; @@ -43,11 +45,20 @@ string InGate::getNameOfTypeOfCurrentInstance() const void InGate::edDisconnectAllLinksToMe() { - for(map::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) + for(list< std::pair >::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) ((*iter).first)->edRemoveInGate(this,false); _backLinks.clear(); } +class ItemCmp +{ +private: + OutGate *_itf; +public: + ItemCmp(OutGate *itf):_itf(itf) { } + bool operator()(const std::pair& elt) const { return elt.first==_itf; } +}; + //! Notify this port that an upstream node connected by a control flow link is finished /*! * Calls the node's gate method : Node::exUpdateState @@ -57,7 +68,9 @@ void InGate::edDisconnectAllLinksToMe() void InGate::exNotifyFromPrecursor(OutGate *from) { DEBTRACE("InGate::exNotifyFromPrecursor"); - map< OutGate *, bool >::iterator iter=_backLinks.find(from); + list< pair >::iterator iter(std::find_if(_backLinks.begin(),_backLinks.end(),ItemCmp(from))); + if(iter==_backLinks.end()) + throw YACS::Exception("InGate::exNotifyFromPrecursor : precursor not found !"); (*iter).second=true; if(exIsReady()) _node->exUpdateState(); @@ -69,7 +82,8 @@ void InGate::exNotifyFromPrecursor(OutGate *from) */ void InGate::exNotifyFailed() { - if(_node) _node->exFailedState(); + if(_node) + _node->exFailedState(); } //! Notify this port that an upstream node connected by a control flow link has been disabled @@ -84,12 +98,18 @@ void InGate::exNotifyDisabled() void InGate::edAppendPrecursor(OutGate *from) { - _backLinks[from]=false; + list< pair >::iterator iter(std::find_if(_backLinks.begin(),_backLinks.end(),ItemCmp(from))); + if(iter!=_backLinks.end()) + (*iter).second=false; + else + _backLinks.push_back(pair(from,false)); } void InGate::edRemovePrecursor(OutGate *from) { - _backLinks.erase(from); + list< pair >::iterator iter(std::find_if(_backLinks.begin(),_backLinks.end(),ItemCmp(from))); + if(iter!=_backLinks.end()) + _backLinks.erase(iter); } int InGate::getNumberOfBackLinks() const @@ -99,14 +119,14 @@ int InGate::getNumberOfBackLinks() const void InGate::exReset() { - for(map::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) + for(list< std::pair >::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) (*iter).second=false; } bool InGate::exIsReady() const { - bool isReady=true; - for(map::const_iterator iter=_backLinks.begin();iter!=_backLinks.end() && isReady;iter++) + bool isReady(true); + for(list< std::pair >::const_iterator iter=_backLinks.begin();iter!=_backLinks.end() && isReady;iter++) isReady=(*iter).second; return isReady; } @@ -114,13 +134,16 @@ bool InGate::exIsReady() const std::list InGate::getBackLinks() { list listo; - for(map::iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) + for(list< std::pair >::const_iterator iter=_backLinks.begin();iter!=_backLinks.end();iter++) listo.push_back(iter->first); - return listo; + return listo; } void InGate::setPrecursorDone(OutGate *from) { - map< OutGate *, bool >::iterator iter=_backLinks.find(from); - (*iter).second=true; + list< std::pair >::iterator iter(std::find_if(_backLinks.begin(),_backLinks.end(),ItemCmp(from))); + if(iter!=_backLinks.end()) + (*iter).second=true; + else + throw YACS::Exception("InGate::setPrecursorDone : precursor not found !"); } diff --git a/src/engine/InGate.hxx b/src/engine/InGate.hxx index 3ac671fcc..b3186bf3d 100644 --- a/src/engine/InGate.hxx +++ b/src/engine/InGate.hxx @@ -24,7 +24,6 @@ #include "Port.hxx" #include "define.hxx" -#include #include namespace YACS @@ -40,13 +39,13 @@ namespace YACS protected: static const char NAME[]; private: - std::map< OutGate *, bool > _backLinks; + std::list< std::pair > _backLinks; public: InGate(Node *node); virtual ~InGate(); std::string getNameOfTypeOfCurrentInstance() const; void exNotifyFromPrecursor(OutGate *fromgate); - std::map& edMapOutGate() { return _backLinks; } + std::list< std::pair >& edMapOutGate() { return _backLinks; } void edAppendPrecursor(OutGate *fromgate); void edRemovePrecursor(OutGate *fromgate); int getNumberOfBackLinks() const; diff --git a/src/engine/LinkedBlocPoint.cxx b/src/engine/LinkedBlocPoint.cxx new file mode 100644 index 000000000..edeecca4f --- /dev/null +++ b/src/engine/LinkedBlocPoint.cxx @@ -0,0 +1,67 @@ +// Copyright (C) 2015 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 "LinkedBlocPoint.hxx" +#include "Exception.hxx" + +using namespace YACS::ENGINE; + +LinkedBlocPoint::LinkedBlocPoint(const std::list& nodes, AbstractPoint *father):BlocPoint(nodes,father) +{ +} + +Node *LinkedBlocPoint::getFirstNode() +{ + if(_nodes.empty()) + throw Exception("LinkedBlocPoint::getFirstNode : error no branches !"); + return _nodes.front()->getFirstNode(); +} + +Node *LinkedBlocPoint::getLastNode() +{ + if(_nodes.empty()) + throw Exception("LinkedBlocPoint::getFirstNode : error no branches !"); + return _nodes.back()->getLastNode(); +} + +int LinkedBlocPoint::getMaxLevelOfParallelism() const +{ + int ret(0); + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++) + ret=std::max(ret,(*it)->getMaxLevelOfParallelism()); + return ret; +} + +std::string LinkedBlocPoint::getRepr() const +{ + std::size_t sz(_nodes.size()),ii(0); + std::string ret("("); + for(std::list::const_iterator it=_nodes.begin();it!=_nodes.end();it++,ii++) + { + ret+=(*it)->getRepr(); + if(ii!=sz-1) + ret+="+"; + } + ret+=")"; + return ret; +} + +LinkedBlocPoint::~LinkedBlocPoint() +{ +} diff --git a/src/engine/LinkedBlocPoint.hxx b/src/engine/LinkedBlocPoint.hxx new file mode 100644 index 000000000..b080b3238 --- /dev/null +++ b/src/engine/LinkedBlocPoint.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2015 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 __LINKEDBLOCPOINT_HXX__ +#define __LINKEDBLOCPOINT_HXX__ + +#include "YACSlibEngineExport.hxx" +#include "BlocPoint.hxx" + +#include + +namespace YACS +{ + namespace ENGINE + { + class YACSLIBENGINE_EXPORT LinkedBlocPoint : public BlocPoint + { + public: + LinkedBlocPoint(const std::list& nodes, AbstractPoint *father); + Node *getFirstNode(); + Node *getLastNode(); + int getMaxLevelOfParallelism() const; + std::string getRepr() const; + virtual ~LinkedBlocPoint(); + }; + } +} + + +#endif diff --git a/src/engine/Node.cxx b/src/engine/Node.cxx index 008d3fc49..774e670e0 100644 --- a/src/engine/Node.cxx +++ b/src/engine/Node.cxx @@ -177,12 +177,12 @@ void Node::setName(const std::string& name) * get the set of all nodes connected to the outGate */ -set Node::getOutNodes() const +list Node::getOutNodes() const { - set ret; - set inGates=_outGate.edSetInGate(); - for(set::iterator iter=inGates.begin();iter!=inGates.end();iter++) - ret.insert((*iter)->getNode()); + list ret; + list inGates=_outGate.edSetInGate(); + for(list::iterator iter=inGates.begin();iter!=inGates.end();iter++) + ret.push_back((*iter)->getNode()); return ret; } @@ -771,7 +771,7 @@ void Node::cleanNodes() void Node::resetState(int level) { DEBTRACE("Node::resetState " << getName() << "," << level << "," << _state); - if(_state==YACS::ERROR || _state==YACS::FAILED) + if(_state==YACS::ERROR || _state==YACS::FAILED || _state==YACS::ACTIVATED) { setState(YACS::READY); InGate* inGate = getInGate(); diff --git a/src/engine/Node.hxx b/src/engine/Node.hxx index c724fb605..92a632317 100644 --- a/src/engine/Node.hxx +++ b/src/engine/Node.hxx @@ -52,6 +52,12 @@ namespace YACS class OutputDataStreamPort; class Visitor; + struct ProgressWeight + { + int weightDone; + int weightTotal; + }; + class YACSLIBENGINE_EXPORT NodeStateNameMap : public std::map { public: @@ -118,13 +124,14 @@ namespace YACS ComposedNode * getFather() const { return _father; } const std::string getId() const; bool exIsControlReady() const; - std::set getOutNodes() const; + std::list getOutNodes() const; virtual void writeDot(std::ostream &os) const; virtual void exUpdateState(); virtual void exFailedState(); virtual void exDisabledState(); virtual void getReadyTasks(std::vector& tasks) = 0; virtual std::list getRecursiveConstituents() const = 0; + virtual std::list getProgressWeight() const = 0; virtual int getNumberOfInputPorts() const = 0; virtual int getNumberOfOutputPorts() const = 0; std::list getSetOfInPort() const; diff --git a/src/engine/OptimizerLoop.cxx b/src/engine/OptimizerLoop.cxx index df634a0fb..83d9dce36 100644 --- a/src/engine/OptimizerLoop.cxx +++ b/src/engine/OptimizerLoop.cxx @@ -522,14 +522,14 @@ void OptimizerLoop::checkCFLinks(const std::list& starts, InputPort * } void OptimizerLoop::checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, - InPort *end, const std::list& pointsOfViewEnd) throw(Exception) + InPort *end, const std::list& pointsOfViewEnd) throw(YACS::Exception) { DynParaLoop::checkLinkPossibility(start, pointsOfViewStart, end, pointsOfViewEnd); std::string linkName("("); linkName += start->getName()+" to "+end->getName()+")"; // Yes, it should be possible to link back the result port to any input port of the loop. - if(end == &_nbOfBranches or end == &_algoInitPort) + if(end == &_nbOfBranches || end == &_algoInitPort) if(start != &_algoResultPort) throw Exception(std::string("Illegal OptimizerLoop link.") + linkName); else @@ -539,7 +539,7 @@ void OptimizerLoop::checkLinkPossibility(OutPort *start, const std::listgetNode())!=_node) + if(end == &_retPortForOutPool && isInMyDescendance(start->getNode())!=_node) throw Exception(std::string("Illegal OptimizerLoop link: \ The 'evalResults' port can only be linked to the working node.") + linkName); } diff --git a/src/engine/OutGate.cxx b/src/engine/OutGate.cxx index d2efbefba..3daf4fac8 100644 --- a/src/engine/OutGate.cxx +++ b/src/engine/OutGate.cxx @@ -23,6 +23,8 @@ //#define _DEVDEBUG_ #include "YacsTrace.hxx" +#include + using namespace YACS::ENGINE; using namespace std; @@ -39,7 +41,7 @@ string OutGate::getNameOfTypeOfCurrentInstance() const void OutGate::exReset() { - for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + for(list< pair< InGate *, bool> >::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) (*iter).second=false; } @@ -53,7 +55,7 @@ void OutGate::exReset() void OutGate::exNotifyDone() { DEBTRACE("OutGate::exNotifyDone"); - for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + for(list< pair >::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) (*iter).first->exNotifyFromPrecursor(this); } @@ -63,7 +65,7 @@ void OutGate::exNotifyDone() */ void OutGate::exNotifyFailed() { - for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + for(list< pair >::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) (*iter).first->exNotifyFailed(); } @@ -73,23 +75,32 @@ void OutGate::exNotifyFailed() */ void OutGate::exNotifyDisabled() { - for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + for(list< pair >::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) (*iter).first->exNotifyDisabled(); } void OutGate::edDisconnectAllLinksFromMe() { - for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + for(list< pair >::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) (*iter).first->edRemovePrecursor(this); _setOfInGate.clear(); } +class ItemCmp +{ +private: + InGate *_itf; +public: + ItemCmp(InGate *itf):_itf(itf) { } + bool operator()(const std::pair& elt) const { return elt.first==_itf; } +}; + bool OutGate::edAddInGate(InGate *inGate) { if(!isAlreadyInSet(inGate)) { inGate->edAppendPrecursor(this); - _setOfInGate[inGate]=false; + _setOfInGate.push_back(std::pair(inGate,false)); modified(); inGate->modified(); return true; @@ -98,17 +109,17 @@ bool OutGate::edAddInGate(InGate *inGate) return false; } -std::set OutGate::edSetInGate() const +std::list OutGate::edSetInGate() const { - set ret; - for(map::const_iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) - ret.insert((*iter).first); + list ret; + for(list< pair >::const_iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end();iter++) + ret.push_back((*iter).first); return ret; } void OutGate::edRemoveInGate(InGate *inGate, bool coherenceWithInGate) throw(YACS::Exception) { - std::map< InGate* , bool >::iterator iter=_setOfInGate.find(inGate); + std::list< pair >::iterator iter(std::find_if(_setOfInGate.begin(),_setOfInGate.end(),ItemCmp(inGate))); if(iter==_setOfInGate.end()) throw Exception("InGate not already connected to OutGate"); else @@ -125,7 +136,7 @@ void OutGate::edRemoveInGate(InGate *inGate, bool coherenceWithInGate) throw(YAC void OutGate::edRemoveInGateOneWay(InGate *inGate) { bool found=false; - for(map::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) + for(list< pair >::iterator iter=_setOfInGate.begin();iter!=_setOfInGate.end() && !found;iter++) if((*iter).first==inGate) { _setOfInGate.erase(iter); @@ -138,7 +149,7 @@ void OutGate::edRemoveInGateOneWay(InGate *inGate) bool OutGate::isAlreadyInSet(InGate *inGate) const { - return _setOfInGate.find(inGate)!=_setOfInGate.end(); + return find_if(_setOfInGate.begin(),_setOfInGate.end(),ItemCmp(inGate))!=_setOfInGate.end(); } int OutGate::getNbOfInGatesConnected() const diff --git a/src/engine/OutGate.hxx b/src/engine/OutGate.hxx index 869125af7..af0ea241e 100644 --- a/src/engine/OutGate.hxx +++ b/src/engine/OutGate.hxx @@ -24,8 +24,7 @@ #include "Port.hxx" #include "Exception.hxx" -#include -#include +#include namespace YACS { @@ -38,7 +37,7 @@ namespace YACS { friend class ElementaryNode; protected: - std::map _setOfInGate; + std::list< std::pair< InGate *, bool > > _setOfInGate; public: static const char NAME[]; public: @@ -50,8 +49,8 @@ namespace YACS void exNotifyDisabled(); void edDisconnectAllLinksFromMe(); bool edAddInGate(InGate *inGate); - std::map& edMapInGate() { return _setOfInGate; } - std::set edSetInGate() const; + std::list< std::pair< InGate *, bool> >& edMapInGate() { return _setOfInGate; } + std::list edSetInGate() const; void edRemoveInGate(InGate *inGate, bool coherenceWithInGate=true) throw(Exception); int getNbOfInGatesConnected() const; bool isAlreadyInSet(InGate *inGate) const; diff --git a/src/engine/Proc.cxx b/src/engine/Proc.cxx index 4cb742955..2eaaddaeb 100644 --- a/src/engine/Proc.cxx +++ b/src/engine/Proc.cxx @@ -232,17 +232,17 @@ std::string Proc::getNodeProgress(int numId) int Proc::getGlobalProgressPercent() { - list > weightList = getProgressWeight(); - int weightDone = 0; - int weightTotal = 0; - int progressPercent = 0; - for(list >::const_iterator iter=weightList.begin();iter!=weightList.end();iter++) - { - weightDone += (*iter).first; - weightTotal += (*iter).second; - } + list weightList = getProgressWeight(); + int weightDone = 0; + int weightTotal = 0; + int progressPercent = 0; + for(list::const_iterator iter=weightList.begin();iter!=weightList.end();iter++) + { + weightDone += (*iter).weightDone; + weightTotal += (*iter).weightTotal; + } if (weightTotal > 0) - progressPercent = int(float(weightDone) / float(weightTotal) * 100); + progressPercent = int(float(weightDone) / float(weightTotal) * 100); return progressPercent; } diff --git a/src/engine/Runtime.cxx b/src/engine/Runtime.cxx index c54ce5925..91775a2c8 100644 --- a/src/engine/Runtime.cxx +++ b/src/engine/Runtime.cxx @@ -86,15 +86,10 @@ Runtime::Runtime() DEBTRACE( "_tc_stringpair refcnt: " << Runtime::_tc_stringpair->getRefCnt() ); DEBTRACE( "_tc_propvec refcnt: " << Runtime::_tc_propvec->getRefCnt() ); _builtinCatalog = new Catalog("builtins"); - _builtinCatalog->_composednodeMap["Bloc"]=createBloc("Bloc"); - _builtinCatalog->_composednodeMap["Switch"]=createSwitch("Switch"); - _builtinCatalog->_composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop"); - _builtinCatalog->_composednodeMap["ForLoop"]=createForLoop("ForLoop"); - _builtinCatalog->_composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double); - _builtinCatalog->_composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string); - _builtinCatalog->_composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int); - _builtinCatalog->_composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool); std::map& typeMap=_builtinCatalog->_typeMap; + /* All composed node creations are moved to RuntimeSALOME::initBuiltins. + It is not safe to have all those calls to virtual functions (create*) + in the constructor. */ Runtime::_tc_double->incrRef(); typeMap["double"]=Runtime::_tc_double; Runtime::_tc_int->incrRef(); @@ -255,7 +250,9 @@ ForLoop* Runtime::createForLoop(const std::string& name) ForEachLoop* Runtime::createForEachLoop(const std::string& name,TypeCode *type) { - return new ForEachLoop(name,type); + ForEachLoop* ret = new ForEachLoop(name,type); + ret->edGetNbOfBranchesPort()->edInit(1); + return ret; } OptimizerLoop* Runtime::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,bool algInitOnFile, diff --git a/src/engine/SetOfPoints.cxx b/src/engine/SetOfPoints.cxx new file mode 100644 index 000000000..dd2158163 --- /dev/null +++ b/src/engine/SetOfPoints.cxx @@ -0,0 +1,88 @@ +// Copyright (C) 2015 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 "SetOfPoints.hxx" +#include "BagPoint.hxx" +#include "LinkedBlocPoint.hxx" +#include "ForkBlocPoint.hxx" +#include "ElementaryPoint.hxx" +#include "Exception.hxx" + +#include + +using namespace YACS::ENGINE; + +SetOfPoints::SetOfPoints(const std::list& nodes):_bp(0) +{ + std::list nodes2; + for(std::list::const_iterator it=nodes.begin();it!=nodes.end();it++) + { + nodes2.push_back(new ElementaryPoint(*it)); + } + _bp=new BagPoint(nodes2,0); +} + +SetOfPoints::~SetOfPoints() +{ + if(!_bp) + return; + delete _bp; +} + +void SetOfPoints::simplify() +{ + while(_bp->size()>1) + { + bool somethingDone(false); + _bp->deal1(somethingDone); + if(somethingDone) + continue; + _bp->deal2(somethingDone); + if(somethingDone) + continue; + _bp->deal2Bis(somethingDone); + if(somethingDone) + continue; + _bp->deal2Ter(somethingDone); + if(!somethingDone) + throw Exception("SetOfPoints::simplify : not implemented yet !"); + } +} + +std::string SetOfPoints::getRepr() const +{ + return _bp->getRepr(); +} + +AbstractPoint *SetOfPoints::findPointWithNode(Node *node) +{ + if(node==0) + return 0; + return _bp->findPointWithNode(node); +} + +const std::list& SetOfPoints::getListOfPoints() const +{ + return _bp->getListOfPoints(); +} + +int SetOfPoints::getMaxLevelOfParallelism() const +{ + return _bp->getMaxLevelOfParallelism(); +} diff --git a/src/engine/SetOfPoints.hxx b/src/engine/SetOfPoints.hxx new file mode 100644 index 000000000..ade89ae66 --- /dev/null +++ b/src/engine/SetOfPoints.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2015 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 __SETOFPOINTS_HXX__ +#define __SETOFPOINTS_HXX__ + +#include "YACSlibEngineExport.hxx" + +#include +#include + +namespace YACS +{ + namespace ENGINE + { + class Node; + class BagPoint; + class AbstractPoint; + + class YACSLIBENGINE_EXPORT SetOfPoints + { + public: + SetOfPoints(const std::list& nodes); + ~SetOfPoints(); + void simplify(); + std::string getRepr() const; + AbstractPoint *findPointWithNode(Node *node); + const std::list& getListOfPoints() const; + int getMaxLevelOfParallelism() const; + private: + BagPoint *_bp; + }; + } +} + + +#endif diff --git a/src/engine/Switch.cxx b/src/engine/Switch.cxx index f06d6d86b..571d6a126 100644 --- a/src/engine/Switch.cxx +++ b/src/engine/Switch.cxx @@ -580,6 +580,34 @@ int Switch::getMaxCase() return aCase; } +//! Get the progress weight of the graph +/*! + * Only elementary nodes have weight. If the switch node is not done, we add the weight of all his descendants, + * otherwise only the weight of the used case count. + */ +list Switch::getProgressWeight() const +{ + list ret; + list setOfNode=edGetDirectDescendants(); + if (getState() == YACS::DONE) + { + for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + if (getEffectiveState(*iter) == YACS::DONE) + ret=(*iter)->getProgressWeight(); + } + } + else + { + for(list::const_iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++) + { + list myCurrentSet=(*iter)->getProgressWeight(); + ret.insert(ret.end(),myCurrentSet.begin(),myCurrentSet.end()); + } + } + return ret; +} + bool Switch::edAddChild(Node *node) throw(YACS::Exception) { int aCase = getMaxCase() + 1; diff --git a/src/engine/Switch.hxx b/src/engine/Switch.hxx index 4d6670d13..cc1471309 100644 --- a/src/engine/Switch.hxx +++ b/src/engine/Switch.hxx @@ -129,6 +129,7 @@ namespace YACS virtual void accept(Visitor *visitor); int getRankOfNode(Node *node) const; virtual std::string typeName() {return "YACS__ENGINE__Switch";} + std::list getProgressWeight() const; protected: YACS::Event updateStateOnFinishedEventFrom(Node *node); Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; diff --git a/src/engine/Test/engineTest.cxx b/src/engine/Test/engineTest.cxx index cc823cc17..d374b11e5 100644 --- a/src/engine/Test/engineTest.cxx +++ b/src/engine/Test/engineTest.cxx @@ -26,6 +26,7 @@ #include "Loop.hxx" #include "Switch.hxx" #include "VisitorSaveState.hxx" +#include "SetOfPoints.hxx" #include "SharedPtr.hxx" #include "RuntimeForEngineTest.hxx" @@ -1072,3 +1073,177 @@ void EngineTest::checkLogger() CPPUNIT_ASSERT(logger->getStr()==expected2); delete proc; } + +void EngineTest::checkGraphAnalyser0() +{ + { + static const int N=2; + Bloc *t[N]; + Bloc proc("proc"); + for(int i=0;i > r(proc.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)r.size()); + CPPUNIT_ASSERT_EQUAL(N,(int)r[0].size()); + SetOfPoints sop(r[0]); + sop.simplify(); + CPPUNIT_ASSERT(sop.getRepr()=="(n1+n2) - "); + } +} + +void EngineTest::checkGraphAnalyser1() +{ + { + static const int N=24; + Bloc *t[N]; + Bloc proc("proc"); + for(int i=0;i > r(proc.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)r.size()); + CPPUNIT_ASSERT_EQUAL(N,(int)r[0].size()); + SetOfPoints sop(r[0]); + sop.simplify(); + CPPUNIT_ASSERT(sop.getRepr()=="([n21*n23]+(n22+n16+[((n13+n12)+[n10*n11]+(n9+n8+n7))*((n17+n18+n20)+[n19*n3*n4]+n5)*(n15+[(n1+n2+n24)*n14])]+n6)) - "); + } + // + { + static const int N=10; + Bloc *t[N]; + Bloc proc("proc"); + for(int i=0;i > r(proc.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)r.size()); + CPPUNIT_ASSERT_EQUAL(N,(int)r[0].size()); + SetOfPoints sop(r[0]); + sop.simplify(); + CPPUNIT_ASSERT(sop.getRepr()=="((n10+n1)+[([(n9+n4)*n3]+n5)*(n2+n7+n8)]+n6) - "); + } +} + +void EngineTest::checkGraphAnalyser2() +{ + { + static const int N=8; + Bloc *t[N]; + Bloc proc("proc"); + for(int i=0;i > r(proc.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)r.size()); + CPPUNIT_ASSERT_EQUAL(N,(int)r[0].size()); + SetOfPoints sop(r[0]); + sop.simplify(); + CPPUNIT_ASSERT(sop.getRepr()=="((n8+n5)+[(n1+n2)*(n3+n4)]+(n6+n7)) - "); + } + // + { + static const int NN=6; + Bloc *tt[NN]; + Bloc proc2("proc2"); + tt[0]=new Bloc("n21") ; tt[1]=new Bloc("n22") ; tt[2]=new Bloc("n23") ; tt[3]=new Bloc("n16"); tt[4]=new Bloc("n21@1"); tt[5]=new Bloc("n23@1"); + for(int i=0;i > rr(proc2.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)rr.size()); + CPPUNIT_ASSERT_EQUAL(NN,(int)rr[0].size()); + SetOfPoints sop2(rr[0]); + sop2.simplify(); + CPPUNIT_ASSERT(sop2.getRepr()=="([(n21+n21@1)*(n23+n23@1)]+(n22+n16)) - "); + } + // + { + static const int NNN=6; + Bloc *ttt[NNN]; + Bloc proc3("proc3"); + ttt[0]=new Bloc("n21") ; ttt[1]=new Bloc("n22") ; ttt[2]=new Bloc("n23") ; ttt[3]=new Bloc("n16"); ttt[4]=new Bloc("n21@1"); ttt[5]=new Bloc("n23@1"); + for(int i=0;i > rrr(proc3.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)rrr.size()); + CPPUNIT_ASSERT_EQUAL(NNN,(int)rrr[0].size()); + SetOfPoints sop3(rrr[0]); + sop3.simplify(); + CPPUNIT_ASSERT(sop3.getRepr()=="((n22+n16)+[(n21+n21@1)*(n23+n23@1)]) - "); + } +} + +void EngineTest::checkGraphAnalyser3() +{ + { + static const int NNN=6; + Bloc *ttt[NNN]; + Bloc proc3("proc3"); + for(int i=0;i > rrr(proc3.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)rrr.size()); + CPPUNIT_ASSERT_EQUAL(NNN,(int)rrr[0].size()); + SetOfPoints sop3(rrr[0]); + //sop3.simplify(); + //std:cerr << std::endl << sop3.getRepr() << std::endl; + //CPPUNIT_ASSERT(sop3.getRepr()=="((n22+n16)+[(n21+n21@1)*(n23+n23@1)]) - "); + } +} + +void EngineTest::checkGraphAnalyser4() +{ + { + static const int NNN=3; + Bloc *ttt[NNN]; + Bloc proc3("proc"); + for(int i=0;i > rrr(proc3.splitIntoIndependantGraph()); + CPPUNIT_ASSERT_EQUAL(1,(int)rrr.size()); + CPPUNIT_ASSERT_EQUAL(NNN,(int)rrr[0].size()); + SetOfPoints sop(rrr[0]); + sop.simplify(); + CPPUNIT_ASSERT(sop.getRepr()=="(n3+n2+n1) - "); + } +} diff --git a/src/engine/Test/engineTest.hxx b/src/engine/Test/engineTest.hxx index 3bdd05139..bd5cbca3a 100644 --- a/src/engine/Test/engineTest.hxx +++ b/src/engine/Test/engineTest.hxx @@ -59,6 +59,11 @@ namespace YACS CPPUNIT_TEST(RecursiveBlocs_removeNodes ); CPPUNIT_TEST(cleanUp); CPPUNIT_TEST(checkLogger); + CPPUNIT_TEST(checkGraphAnalyser0); + CPPUNIT_TEST(checkGraphAnalyser1); + CPPUNIT_TEST(checkGraphAnalyser2); + CPPUNIT_TEST(checkGraphAnalyser3); + CPPUNIT_TEST(checkGraphAnalyser4); CPPUNIT_TEST_SUITE_END(); public: @@ -93,7 +98,11 @@ namespace YACS void RecursiveBlocs_multipleRecursion(); void RecursiveBlocs_removeNodes(); void checkLogger(); - + void checkGraphAnalyser0(); + void checkGraphAnalyser1(); + void checkGraphAnalyser2(); + void checkGraphAnalyser3(); + void checkGraphAnalyser4(); protected: static std::map _nodeMap; static std::map _compoMap; diff --git a/src/engine/VisitorSaveSchema.cxx b/src/engine/VisitorSaveSchema.cxx index c6dc7c1c3..5df4abe35 100644 --- a/src/engine/VisitorSaveSchema.cxx +++ b/src/engine/VisitorSaveSchema.cxx @@ -797,8 +797,8 @@ void VisitorSaveSchema::writeControls(ComposedNode *node) for (list::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic) { // --- Control links from direct descendant to nodes inside the bloc - set setOfInGates = (*ic)->getOutGate()->edSetInGate(); - for (set::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig) + list setOfInGates = (*ic)->getOutGate()->edSetInGate(); + for (list::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig) { Node *to = (*ig)->getNode(); if (node->isInMyDescendance(to)) diff --git a/src/evalyfx/YACSEvalPort.cxx b/src/evalyfx/YACSEvalPort.cxx index 86cd5dfc1..190fa1ef2 100644 --- a/src/evalyfx/YACSEvalPort.cxx +++ b/src/evalyfx/YACSEvalPort.cxx @@ -66,6 +66,29 @@ YACSEvalAnyInt *YACSEvalAnyInt::deepCpy() const return new YACSEvalAnyInt(*this); } +bool YACSEvalPort::IsInputPortPublishable(const YACS::ENGINE::InputPort *port) +{ + YACS::ENGINE::TypeCode *tc(port->edGetType()); + if(!tc) + throw YACS::Exception("YACSEvalPort::IsInPortPublishable : null type code !"); + if(tc->kind()==YACS::ENGINE::Double || tc->kind()==YACS::ENGINE::Int) + return true; + if(tc->kind()==YACS::ENGINE::String) + { + if(port->edIsManuallyInitialized()) + return false; + } + return true; +} + +bool YACSEvalPort::IsOutputPortPublishable(const YACS::ENGINE::OutputPort *port) +{ + YACS::ENGINE::TypeCode *tc(port->edGetType()); + if(!tc) + throw YACS::Exception("YACSEvalPort::IsOutputPortPublishable : null type code !"); + return tc->kind()==YACS::ENGINE::Double || tc->kind()==YACS::ENGINE::Int; +} + std::string YACSEvalPort::GetTypeOfData(const YACS::ENGINE::DataPort *port) { YACS::ENGINE::TypeCode *tc(port->edGetType()); diff --git a/src/evalyfx/YACSEvalPort.hxx b/src/evalyfx/YACSEvalPort.hxx index 6244f1332..eeb4ecf99 100644 --- a/src/evalyfx/YACSEvalPort.hxx +++ b/src/evalyfx/YACSEvalPort.hxx @@ -84,6 +84,9 @@ class YACSEvalPort public: YACSEVALYFX_EXPORT virtual std::string getTypeOfData() const = 0; YACSEVALYFX_EXPORT virtual ~YACSEvalPort() { } +public: + YACSEVALYFX_EXPORT static bool IsInputPortPublishable(const YACS::ENGINE::InputPort *port); + YACSEVALYFX_EXPORT static bool IsOutputPortPublishable(const YACS::ENGINE::OutputPort *port); protected: YACSEVALYFX_EXPORT static std::string GetTypeOfData(const YACS::ENGINE::DataPort *port); }; diff --git a/src/evalyfx/YACSEvalYFX.cxx b/src/evalyfx/YACSEvalYFX.cxx index aba327e74..b3fcb25e3 100644 --- a/src/evalyfx/YACSEvalYFX.cxx +++ b/src/evalyfx/YACSEvalYFX.cxx @@ -147,6 +147,16 @@ YACS::ENGINE::Proc *YACSEvalYFX::getUndergroundGeneratedGraph() const return _pattern->getUndergroundGeneratedGraph(); } +void YACSEvalYFX::setParallelizeStatus(bool newVal) +{ + _pattern->setParallelizeStatus(newVal); +} + +bool YACSEvalYFX::getParallelizeStatus() const +{ + return _pattern->getParallelizeStatus(); +} + YACSEvalYFX::YACSEvalYFX(YACS::ENGINE::Proc *scheme, bool ownScheme):_pattern(0) { _pattern=YACSEvalYFXPattern::FindPatternFrom(this,scheme,ownScheme); diff --git a/src/evalyfx/YACSEvalYFX.hxx b/src/evalyfx/YACSEvalYFX.hxx index a25d10e08..14dcc9573 100644 --- a/src/evalyfx/YACSEvalYFX.hxx +++ b/src/evalyfx/YACSEvalYFX.hxx @@ -61,6 +61,8 @@ public: YACSEVALYFX_EXPORT std::vector getResults() const; // YACSEVALYFX_EXPORT YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const; + YACSEVALYFX_EXPORT void setParallelizeStatus(bool newVal); + YACSEVALYFX_EXPORT bool getParallelizeStatus() const; YACSEVALYFX_EXPORT ~YACSEvalYFX(); private: YACSEvalYFX(YACS::ENGINE::Proc *scheme, bool ownScheme); diff --git a/src/evalyfx/YACSEvalYFXPattern.cxx b/src/evalyfx/YACSEvalYFXPattern.cxx index f27e1f527..1feacd39c 100644 --- a/src/evalyfx/YACSEvalYFXPattern.cxx +++ b/src/evalyfx/YACSEvalYFXPattern.cxx @@ -161,7 +161,7 @@ void YACSEvalYFXPattern::registerObserver(YACSEvalObserver *observer) _observer->incrRef(); } -YACSEvalYFXPattern::YACSEvalYFXPattern(YACSEvalYFX *boss, YACS::ENGINE::Proc *scheme, bool ownScheme):_boss(boss),_scheme(scheme),_ownScheme(ownScheme),_rm(new ResourcesManager_cpp),_res(0),_observer(0) +YACSEvalYFXPattern::YACSEvalYFXPattern(YACSEvalYFX *boss, YACS::ENGINE::Proc *scheme, bool ownScheme):_boss(boss),_scheme(scheme),_ownScheme(ownScheme),_parallelizeStatus(true),_rm(new ResourcesManager_cpp),_res(0),_observer(0) { } @@ -399,8 +399,12 @@ int YACSEvalYFXRunOnlyPattern::assignNbOfBranches() throw YACS::Exception("YACSEvalYFXRunOnlyPattern::assignNbOfBranches : internal error 2 !"); unsigned int nbProcsDeclared(getResourcesInternal()->getNumberOfProcsDeclared()); nbProcsDeclared=std::max(nbProcsDeclared,4u); - int nbOfBranch(nbProcsDeclared/getResourcesInternal()->getMaxLevelOfParallelism()); - nbOfBranch=std::max(nbOfBranch,1); + int nbOfBranch=1; + if(getParallelizeStatus()) + { + nbOfBranch=(nbProcsDeclared/getResourcesInternal()->getMaxLevelOfParallelism()); + nbOfBranch=std::max(nbOfBranch,1); + } YACS::ENGINE::InputPort *zeInputToSet(zeMainNode->edGetNbOfBranchesPort()); YACS::ENGINE::AnyInputPort *zeInputToSetC(dynamic_cast(zeInputToSet)); if(!zeInputToSetC) @@ -519,16 +523,19 @@ void YACSEvalYFXRunOnlyPattern::buildInputPorts() std::set bls(elt->edSetOutPort()); if(bls.empty()) { - std::string inpName(elt->getName()); - if(inpName.empty()) - throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildInputPorts : an input has empty name ! Should not !"); - _inputs.push_back(YACSEvalInputPort(elt)); - if(std::find(allNames.begin(),allNames.end(),inpName)!=allNames.end()) + if(YACSEvalPort::IsInputPortPublishable(elt)) { - std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildInputPorts : input name \"" << inpName << "\" appears more than once !"; - throw YACS::Exception(oss.str()); + std::string inpName(elt->getName()); + if(inpName.empty()) + throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildInputPorts : an input has empty name ! Should not !"); + _inputs.push_back(YACSEvalInputPort(elt)); + if(std::find(allNames.begin(),allNames.end(),inpName)!=allNames.end()) + { + std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildInputPorts : input name \"" << inpName << "\" appears more than once !"; + throw YACS::Exception(oss.str()); + } + allNames.push_back(inpName); } - allNames.push_back(inpName); } } } @@ -541,17 +548,20 @@ void YACSEvalYFXRunOnlyPattern::buildOutputPorts() for(std::list< YACS::ENGINE::OutputPort *>::const_iterator it=allOutputPorts.begin();it!=allOutputPorts.end();it++) { YACS::ENGINE::OutputPort *elt(*it); - if(!elt) - throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : presence of null output !"); - std::string outpName(elt->getName()); - if(outpName.empty()) - throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : an output has empty name ! Should not !"); - if(std::find(allNames.begin(),allNames.end(),outpName)!=allNames.end()) + if(YACSEvalPort::IsOutputPortPublishable(elt)) { - std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildOutputPorts : output name \"" << outpName << "\" appears more than once !"; - throw YACS::Exception(oss.str()); + if(!elt) + throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : presence of null output !"); + std::string outpName(elt->getName()); + if(outpName.empty()) + throw YACS::Exception("YACSEvalYFXRunOnlyPattern::buildOutputPorts : an output has empty name ! Should not !"); + if(std::find(allNames.begin(),allNames.end(),outpName)!=allNames.end()) + { + std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::buildOutputPorts : output name \"" << outpName << "\" appears more than once !"; + throw YACS::Exception(oss.str()); + } + _outputs.push_back(YACSEvalOutputPort(*it)); } - _outputs.push_back(YACSEvalOutputPort(*it)); } } diff --git a/src/evalyfx/YACSEvalYFXPattern.hxx b/src/evalyfx/YACSEvalYFXPattern.hxx index 110f22b90..ea3c4d4fa 100644 --- a/src/evalyfx/YACSEvalYFXPattern.hxx +++ b/src/evalyfx/YACSEvalYFXPattern.hxx @@ -54,6 +54,8 @@ public: std::vector< YACSEvalInputPort *> getFreeInputPorts() const; std::vector< YACSEvalOutputPort *> getFreeOutputPorts() const; static YACSEvalYFXPattern *FindPatternFrom(YACSEvalYFX *boss, YACS::ENGINE::Proc *scheme, bool ownScheme); + void setParallelizeStatus(bool newVal) { _parallelizeStatus=newVal; } + bool getParallelizeStatus() const { return _parallelizeStatus; } bool isAlreadyComputedResources() const; void checkNonAlreadyComputedResources() const; void checkAlreadyComputedResources() const; @@ -89,6 +91,7 @@ private: private: YACSEvalYFX *_boss; bool _ownScheme; + bool _parallelizeStatus; YACS::ENGINE::Proc *_scheme; ResourcesManager_cpp *_rm; YACSEvalListOfResources *_res; diff --git a/src/evalyfx_swig/evalyfx.i b/src/evalyfx_swig/evalyfx.i index 4395e90dd..89668a64e 100644 --- a/src/evalyfx_swig/evalyfx.i +++ b/src/evalyfx_swig/evalyfx.i @@ -351,6 +351,8 @@ public: bool isLocked() const; YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const; YACSEvalListOfResources *giveResources(); + void setParallelizeStatus(bool newVal); + bool getParallelizeStatus() const; //void registerObserver(YACSEvalObserver *observer); %extend { diff --git a/src/genericgui/GuiExecutor.cxx b/src/genericgui/GuiExecutor.cxx index 8a1e1a12d..4bd977c69 100644 --- a/src/genericgui/GuiExecutor.cxx +++ b/src/genericgui/GuiExecutor.cxx @@ -279,8 +279,12 @@ void GuiExecutor::saveState(const std::string& xmlFile) bool StartFinish = (getExecutorState() == YACS::NOTYETINITIALIZED || getExecutorState() == YACS::FINISHED); if ( _isRunning || - !(CORBA::is_nil(_procRef)) && StartFinish ) - _procRef->saveState(xmlFile.c_str()); + !(CORBA::is_nil(_procRef)) && StartFinish ) { + if ( !_procRef->saveState(xmlFile.c_str()) ) { + string what = "Impossible to open file for writing: " + xmlFile; + throw Exception(what); + } + } } void GuiExecutor::setLoadStateFile(std::string xmlFile) diff --git a/src/genericgui/SceneBlocItem.cxx b/src/genericgui/SceneBlocItem.cxx index 265ebad34..329bd38e8 100644 --- a/src/genericgui/SceneBlocItem.cxx +++ b/src/genericgui/SceneBlocItem.cxx @@ -228,8 +228,8 @@ void SceneBlocItem::getNodesInfo(YACS::ENGINE::ComposedNode *cnode) { OutGate *outGate = outNode->getOutGate(); - set setOfInGate = outGate->edSetInGate(); - set::const_iterator itin = setOfInGate.begin(); + list setOfInGate = outGate->edSetInGate(); + list::const_iterator itin = setOfInGate.begin(); for (; itin != setOfInGate.end(); ++itin) { Node *inNode = (*itin)->getNode(); diff --git a/src/hmi/guiObservers.cxx b/src/hmi/guiObservers.cxx index 786d8f4d0..84f1c5a54 100644 --- a/src/hmi/guiObservers.cxx +++ b/src/hmi/guiObservers.cxx @@ -902,7 +902,7 @@ void SubjectNode::saveLinks() Node* n2=_node; DEBTRACE(n1->getName()<< " " << n2->getName()); } - std::set::const_iterator iti; + std::list::const_iterator iti; for(iti=singate.begin();iti != singate.end();iti++) { Node* n1=_node; @@ -1076,7 +1076,7 @@ void SubjectNode::restoreLinks() } } - std::set::const_iterator it2; + std::list::const_iterator it2; for(it2=singate.begin();it2 != singate.end();it2++) { Node* n1=_node; @@ -1649,8 +1649,8 @@ void SubjectComposedNode::loadLinks() { SubjectNode* sno = GuiContext::getCurrent()->_mapOfSubjectNode[*itn]; OutGate* outgate = (*itn)->getOutGate(); - std::set setIngate = outgate->edSetInGate(); - std::set::const_iterator itg; + std::list setIngate = outgate->edSetInGate(); + std::list::const_iterator itg; for(itg = setIngate.begin(); itg != setIngate.end(); ++itg) { Node* inNode = (*itg)->getNode(); diff --git a/src/hmi/guiObservers.hxx b/src/hmi/guiObservers.hxx index acc9eb4aa..cf277eb36 100644 --- a/src/hmi/guiObservers.hxx +++ b/src/hmi/guiObservers.hxx @@ -339,7 +339,7 @@ namespace YACS std::list _listSubjectControlLink; int _execState; std::list loutgate; - std::set singate; + std::list singate; std::vector< std::pair > dataLinks; std::vector< std::pair > dataflowLinks; }; diff --git a/src/runtime/DistributedPythonNode.cxx b/src/runtime/DistributedPythonNode.cxx index 96263202d..7e5a60788 100644 --- a/src/runtime/DistributedPythonNode.cxx +++ b/src/runtime/DistributedPythonNode.cxx @@ -134,7 +134,7 @@ void DistributedPythonNode::load() } else { - Engines::PyNode_var dftPyScript(objContainer->getDefaultPyNode()); + Engines::PyNode_var dftPyScript(objContainer->getDefaultPyNode(getName().c_str())); if(CORBA::is_nil(dftPyScript)) _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); else diff --git a/src/runtime/PythonNode.cxx b/src/runtime/PythonNode.cxx index 7c23295e3..3a448d3f6 100644 --- a/src/runtime/PythonNode.cxx +++ b/src/runtime/PythonNode.cxx @@ -649,7 +649,7 @@ void PythonNode::createRemoteAdaptedPyInterpretor(Engines::Container_ptr objCont Engines::PyNodeBase_var PythonNode::retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const { - Engines::PyScriptNode_var ret(objContainer->getDefaultPyScriptNode()); + Engines::PyScriptNode_var ret(objContainer->getDefaultPyScriptNode(getName().c_str())); if(!CORBA::is_nil(ret)) { ret->Register(); @@ -1117,7 +1117,7 @@ void PyFuncNode::createRemoteAdaptedPyInterpretor(Engines::Container_ptr objCont Engines::PyNodeBase_var PyFuncNode::retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const { - Engines::PyNode_var ret(objContainer->getDefaultPyNode()); + Engines::PyNode_var ret(objContainer->getDefaultPyNode(getName().c_str())); if(!CORBA::is_nil(ret)) { ret->Register(); diff --git a/src/runtime/RuntimeSALOME.cxx b/src/runtime/RuntimeSALOME.cxx index 1727e6426..0ac34e183 100644 --- a/src/runtime/RuntimeSALOME.cxx +++ b/src/runtime/RuntimeSALOME.cxx @@ -43,6 +43,7 @@ #include "PresetPorts.hxx" #include "InputDataStreamPort.hxx" #include "OutputDataStreamPort.hxx" +#include "Switch.hxx" #include "SalomeProc.hxx" #include "PyStdout.hxx" //Catalog Loaders @@ -181,6 +182,14 @@ void RuntimeSALOME::initBuiltins() std::list ltc; typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc); typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]); + composednodeMap["Bloc"]=createBloc("Bloc"); + composednodeMap["Switch"]=createSwitch("Switch"); + composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop"); + composednodeMap["ForLoop"]=createForLoop("ForLoop"); + composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double); + composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string); + composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int); + composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool); composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);; ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref"); t->addMember("ref",_tc_string); diff --git a/src/runtime/Test/CMakeLists.txt b/src/runtime/Test/CMakeLists.txt index 3589502f8..506be0e11 100644 --- a/src/runtime/Test/CMakeLists.txt +++ b/src/runtime/Test/CMakeLists.txt @@ -117,10 +117,10 @@ IF(NOT WIN32) SALOME_CONFIGURE_FILE(xmlrun_orig.sh xmlrun.sh) ADD_TEST(NAME runtimeTest COMMAND ${SHELL} ${CMAKE_CURRENT_SOURCE_DIR}/runtimeTest.sh) SET_TESTS_PROPERTIES(runtimeTest PROPERTIES ENVIRONMENT "${tests_env}") + INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/xmlrun.sh DESTINATION ${LOCAL_TEST_DIR}) ENDIF() INSTALL(PROGRAMS runtimeTest.sh DESTINATION ${LOCAL_TEST_DIR}) -INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/xmlrun.sh DESTINATION ${LOCAL_TEST_DIR}) INSTALL(TARGETS runtime_echo DESTINATION ${SALOME_YACS_INSTALL_TEST_LIB}) INSTALL(TARGETS TestRuntime DESTINATION ${LOCAL_TEST_DIR}) INSTALL(TARGETS runtimeTestEchoSrv DESTINATION ${LOCAL_TEST_DIR}) diff --git a/src/runtime/TypeConversions.cxx b/src/runtime/TypeConversions.cxx index 9958f5473..9f5b145d8 100644 --- a/src/runtime/TypeConversions.cxx +++ b/src/runtime/TypeConversions.cxx @@ -257,6 +257,17 @@ namespace YACS if( t1->isA(t2->id()) ) return 1; } + else if(t1->kind() == Sequence) + { + const TypeCodeSeq *t1c(dynamic_cast(t1)); + if(!t1c) + return 0; + const TypeCode *t1cc(t1c->contentType()); + if(t1cc==t2) + return 1; + if(t1cc->kind() == Objref && std::string(t1cc->id())==std::string(t2->id())) + return 1; + } return 0; } }; diff --git a/src/salomegui/resources/YACS_msg_ja.ts b/src/salomegui/resources/YACS_msg_ja.ts index a8508990e..238430cb9 100644 --- a/src/salomegui/resources/YACS_msg_ja.ts +++ b/src/salomegui/resources/YACS_msg_ja.ts @@ -543,7 +543,7 @@ Put Graph Content in Node - ノード内のグラフの内容を置く + ノード内のグラフの内容を置く arrange nodes on that bloc level, without recursion @@ -595,11 +595,11 @@ shrink or expand direct children of the selected node - 選択中のノードを展開または縮小 + 選択中のノードを展開または縮小 shrink or expand elementary nodes of the selected node recursively - 選択中のノードを展開または縮小 + 選択中のノードを展開または縮小 shrink/expand @@ -607,11 +607,11 @@ shrink/expand children - 展開/縮小 + 展開/縮小 shrink/expand elementary - 展開/縮小 + 展開/縮小 draw straight or orthogonal links diff --git a/src/yacsloader/Test/CMakeLists.txt b/src/yacsloader/Test/CMakeLists.txt index 8c5f73d14..4eb22cd41 100644 --- a/src/yacsloader/Test/CMakeLists.txt +++ b/src/yacsloader/Test/CMakeLists.txt @@ -135,7 +135,15 @@ IF(NOT WIN32) DESTINATION ${LOCAL_TEST_DIR}) INSTALL(PROGRAMS runYacsLoaderTest.sh ${CMAKE_CURRENT_BINARY_DIR}/xmlrun.sh DESTINATION ${LOCAL_TEST_DIR}) + # Use relative path for symbolic links in order to allow the copy of the directory. + # REL_PATH_TO_INSTALL goes to CMAKE_INSTALL_PREFIX from ${CMAKE_INSTALL_PREFIX}/${LOCAL_TEST_DIR} + IF(IS_ABSOLUTE ${SALOME_YACS_INSTALL_SAMPLES}) + SET(SAMPLES_LINK_TARGET ${SALOME_YACS_INSTALL_SAMPLES}) + ELSE() + STRING(REGEX REPLACE [^/]+ ".." REL_PATH_TO_INSTALL ${LOCAL_TEST_DIR}) + SET(SAMPLES_LINK_TARGET ${REL_PATH_TO_INSTALL}/${SALOME_YACS_INSTALL_SAMPLES}) + ENDIF() INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E create_symlink - ${CMAKE_INSTALL_PREFIX}/${SALOME_YACS_INSTALL_SAMPLES} + ${SAMPLES_LINK_TARGET} ${CMAKE_INSTALL_PREFIX}/${LOCAL_TEST_DIR}/samples )" ) ENDIF() diff --git a/src/yacsloader_swig/Test/CMakeLists.txt b/src/yacsloader_swig/Test/CMakeLists.txt index 4af457d6f..6cbef482e 100644 --- a/src/yacsloader_swig/Test/CMakeLists.txt +++ b/src/yacsloader_swig/Test/CMakeLists.txt @@ -43,6 +43,7 @@ IF(NOT WIN32) testSaveLoadRun.py optim_plugin.py testValidationChecks.py + testProgress.py ) INSTALL(FILES ${LOCAL_TEST_FILES} DESTINATION ${LOCAL_TEST_DIR}) @@ -51,7 +52,15 @@ IF(NOT WIN32) INSTALL(FILES CTestTestfileInstall.cmake DESTINATION ${LOCAL_TEST_DIR} RENAME CTestTestfile.cmake) + # Use relative path for symbolic links in order to allow the copy of the directory. + # REL_PATH_TO_INSTALL goes to CMAKE_INSTALL_PREFIX from ${CMAKE_INSTALL_PREFIX}/${LOCAL_TEST_DIR} + IF(IS_ABSOLUTE ${SALOME_YACS_INSTALL_SAMPLES}) + SET(SAMPLES_LINK_TARGET ${SALOME_YACS_INSTALL_SAMPLES}) + ELSE() + STRING(REGEX REPLACE [^/]+ ".." REL_PATH_TO_INSTALL ${LOCAL_TEST_DIR}) + SET(SAMPLES_LINK_TARGET ${REL_PATH_TO_INSTALL}/${SALOME_YACS_INSTALL_SAMPLES}) + ENDIF() INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E create_symlink - ${CMAKE_INSTALL_PREFIX}/${SALOME_YACS_INSTALL_SAMPLES} + ${SAMPLES_LINK_TARGET} ${CMAKE_INSTALL_PREFIX}/${LOCAL_TEST_DIR}/samples )" ) ENDIF() diff --git a/src/yacsloader_swig/Test/YacsLoaderInSessionTest.sh.in b/src/yacsloader_swig/Test/YacsLoaderInSessionTest.sh.in index 0229f6d41..edaad8e53 100644 --- a/src/yacsloader_swig/Test/YacsLoaderInSessionTest.sh.in +++ b/src/yacsloader_swig/Test/YacsLoaderInSessionTest.sh.in @@ -88,7 +88,14 @@ if [ $ret6 -gt 0 ]; then exit $ret6 fi -let ret=$ret0+$ret1+$ret2+$ret3+$ret4+$ret5+$ret6 +python @CMAKE_CURRENT_SOURCE_DIR@/testProgress.py +ret7=$? +if [ $ret7 -gt 0 ]; then + echo "exec status testProgress : " $ret7 + exit $ret7 +fi + +let ret=$ret0+$ret1+$ret2+$ret3+$ret4+$ret5+$ret6+$ret7 # --- return unit tests status diff --git a/src/yacsloader_swig/Test/testProgress.py b/src/yacsloader_swig/Test/testProgress.py new file mode 100755 index 000000000..ca8cee59b --- /dev/null +++ b/src/yacsloader_swig/Test/testProgress.py @@ -0,0 +1,141 @@ +# 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 +# + +import sys +import pilot +import SALOMERuntime +import loader +import unittest + +class TestEdit(unittest.TestCase): + + def setUp(self): + SALOMERuntime.RuntimeSALOME_setRuntime() + self.r = pilot.getRuntime() + self.l = loader.YACSLoader() + self.e = pilot.ExecutorSwig() + pass + + def test_progress(self): + + p=self.r.createProc("pr") + ti=p.getTypeCode("int") + td=p.getTypeCode("double") + ts=p.getTypeCode("string") + + #BLOC + b=self.r.createBloc("b1") + p.edAddChild(b) + n1=self.r.createScriptNode("","node1") + b.edAddChild(n1) + n1.setScript("p1=p1+10") + n1.edAddInputPort("p1",ti) + n1.edAddOutputPort("p1",ti) + n2=self.r.createScriptNode("","node2") + b.edAddChild(n2) + n2.setScript("p1=2*p1") + n2.edAddInputPort("p1",ti) + n2.edAddOutputPort("p1",ti) + b.edAddDFLink(n1.getOutputPort("p1"),n2.getInputPort("p1")) + #initialisation ports + n1.getInputPort("p1").edInitPy(5) + + #FOR LOOP + loop=self.r.createForLoop("l1") + p.edAddChild(loop) + ip=loop.getInputPort("nsteps") + ip.edInitPy(3) + n10=self.r.createScriptNode("","node10") + loop.edSetNode(n10) + n10.setScript("p1=p1+10") + n10.edAddInputPort("p1",ti) + n10.edAddOutputPort("p1",ti) + n10.getInputPort("p1").edInitPy(5) + + + #WHILE LOOP + wh=self.r.createWhileLoop("w1") + p.edAddChild(wh) + n20=self.r.createScriptNode("","node3") + n20.setScript("p1=0") + n20.edAddOutputPort("p1",ti) + wh.edSetNode(n20) + cport=wh.getInputPort("condition") + cport.edInitBool(True) + p.edAddLink(n20.getOutputPort("p1"),cport) + + + #FOR EACH LOOP + fe=self.r.createForEachLoop("fe1",td) + p.edAddChild(fe) + n30=self.r.createScriptNode("","node3") + n30.setScript("import time \ntime.sleep(1) \np1=p1+3.\n") + n30.edAddInputPort("p1",td) + n30.edAddOutputPort("p1",td) + fe.edSetNode(n30) + p.edAddLink(fe.getOutputPort("evalSamples"),n30.getInputPort("p1")) + fe.getInputPort("nbBranches").edInitPy(2) + fe.getInputPort("SmplsCollection").edInitPy([1.,2.,3.,4.,5.,6.]) + + #SWITCH + n40=self.r.createScriptNode("","node3") + n40.setScript("p1=3.5") + n40.edAddOutputPort("p1",td) + p.edAddChild(n40) + #switch + sw=self.r.createSwitch("sw1") + p.edAddChild(sw) + nk1=self.r.createScriptNode("","ncas1") + nk1.setScript("p1=p1+3.") + nk1.edAddInputPort("p1",td) + nk1.edAddOutputPort("p1",td) + sw.edSetNode(1,nk1) + ndef=self.r.createScriptNode("","ndefault") + ndef.setScript("p1=p1+5.") + ndef.edAddInputPort("p1",td) + ndef.edAddOutputPort("p1",td) + sw.edSetDefaultNode(ndef) + #initialise the select port + sw.getInputPort("select").edInitPy(1) + #connection of internal nodes + p.edAddDFLink(n40.getOutputPort("p1"),nk1.getInputPort("p1")) + p.edAddDFLink(n40.getOutputPort("p1"),ndef.getInputPort("p1")) + + import time + import threading + self.assertEqual(p.getGlobalProgressPercent(),0) + self.assertEqual(p.getState(),pilot.READY) + myRun = threading.Thread(None, self.e.RunW, None, (p,0)) + myRun.start() + time.sleep(1.5) + self.assertGreater(p.getGlobalProgressPercent(),0) + self.assertLess(p.getGlobalProgressPercent(),100) + myRun.join() + self.assertEqual(p.getState(),pilot.DONE) + self.assertEqual(p.getGlobalProgressPercent(),100) + +if __name__ == '__main__': + import os + U = os.getenv('USER') + f=open("/tmp/" + U + "/UnitTestsResult", 'a') + f.write(" --- TEST src/yacsloader: testProgress.py\n") + suite = unittest.makeSuite(TestEdit) + result=unittest.TextTestRunner(f, descriptions=1, verbosity=3).run(suite) + f.close() + sys.exit(not result.wasSuccessful()) diff --git a/src/yacsloader_swig/Test/testSaveLoadRun.py b/src/yacsloader_swig/Test/testSaveLoadRun.py index ffe817d8e..a2c68da53 100755 --- a/src/yacsloader_swig/Test/testSaveLoadRun.py +++ b/src/yacsloader_swig/Test/testSaveLoadRun.py @@ -1213,6 +1213,94 @@ for i in i8: self.assertEqual(p.getChildByName("test23/main.test23/check").getOutputPort("o1").getPyObj(),[3,4,5,6,7,8,9,10,11,12]) pass + def test15(self): + fname="BugInConcurrentLaunchDftCont.xml" + p=self.r.createProc("pr") + ti=p.createType("int","int") + cont=p.createContainer("DefaultContainer","Salome") + cont.setProperty("container_name","FactoryServer") + b=self.r.createBloc("Bloc") ; p.edAddChild(b) + # + nb=4 + outs=[] + for i in xrange(nb): + node=self.r.createScriptNode("Salome","node%d"%i) + node.setExecutionMode("remote") + node.setContainer(cont) + outs.append(node.edAddOutputPort("i",ti)) + node.setScript("i=%d"%i) + b.edAddChild(node) + # + node=self.r.createScriptNode("Salome","nodeEnd") + node.setExecutionMode("remote") + node.setContainer(cont) + res=node.edAddOutputPort("res",ti) + p.edAddChild(node) + l=[] + for i in xrange(nb): + elt="i%d"%i + inp=node.edAddInputPort(elt,ti) ; l.append(elt) + p.edAddChild(node) + p.edAddLink(outs[i],inp) + node.setScript("res="+"+".join(l)) + p.edAddCFLink(b,node) + # + for i in xrange(10): + p.init() + ex = pilot.ExecutorSwig() + self.assertEqual(p.getState(),pilot.READY) + ex.RunW(p,0) + self.assertEqual(res.get(),6) + self.assertEqual(p.getState(),pilot.DONE) + pass + + def test16(self): + """ Test to check that a list[pyobj] outputport linked to pyobj inputport is OK.""" + SALOMERuntime.RuntimeSALOME_setRuntime() + self.r=pilot.getRuntime() + n0=self.r.createProc("test16/zeRun") + tp=n0.createInterfaceTc("python:obj:1.0","pyobj",[]) + tp2=n0.createSequenceTc("list[pyobj]","list[pyobj]",tp) + + n00=self.r.createScriptNode("Salome","n00") ; n0.edAddChild(n00) + o0=n00.edAddOutputPort("o0",tp2) + n00.setScript("o0=[[i+1] for i in xrange(8)]") + n01=self.r.createScriptNode("Salome","n01") ; n0.edAddChild(n01) + i1=n01.edAddInputPort("i1",tp) + n01.setScript("assert(i1==[[1], [2], [3], [4], [5], [6], [7], [8]])") + n0.edAddCFLink(n00,n01) + n0.edAddLink(o0,i1) + # + ex=pilot.ExecutorSwig() + self.assertEqual(n0.getState(),pilot.READY) + ex.RunW(n0,0) + self.assertEqual(n0.getState(),pilot.DONE) + pass + + def test17(self): + """ Same as test16 except that tp2 is not list of tp but a list of copy of tp""" + SALOMERuntime.RuntimeSALOME_setRuntime() + self.r=pilot.getRuntime() + n0=self.r.createProc("test17/zeRun") + tp=n0.createInterfaceTc("python:obj:1.0","pyobj",[]) + tpp=n0.createInterfaceTc("python:obj:1.0","pyobj",[]) # diff is here + tp2=n0.createSequenceTc("list[pyobj]","list[pyobj]",tpp) + + n00=self.r.createScriptNode("Salome","n00") ; n0.edAddChild(n00) + o0=n00.edAddOutputPort("o0",tp2) + n00.setScript("o0=[[i+1] for i in xrange(8)]") + n01=self.r.createScriptNode("Salome","n01") ; n0.edAddChild(n01) + i1=n01.edAddInputPort("i1",tp) + n01.setScript("assert(i1==[[1], [2], [3], [4], [5], [6], [7], [8]])") + n0.edAddCFLink(n00,n01) + n0.edAddLink(o0,i1) + # + ex=pilot.ExecutorSwig() + self.assertEqual(n0.getState(),pilot.READY) + ex.RunW(n0,0) + self.assertEqual(n0.getState(),pilot.DONE) + pass + pass if __name__ == '__main__':