Salome HOME
f53ef5e288a6258f04d278f80bf3dc2f44bd904a
[modules/yacs.git] / src / engine / ForEachLoop.hxx
1 // Copyright (C) 2006-2024  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #pragma once
21
22 #include "YACSlibEngineExport.hxx"
23 #include "ElementaryNode.hxx"
24 #include "DynParaLoop.hxx"
25 #include "OutputPort.hxx"
26 #include "InputPort.hxx"
27 #include "AnyInputPort.hxx"
28
29 namespace YACS
30 {
31   namespace ENGINE
32   {
33     class ForEachLoop;
34     class ForEachLoopGen;
35     class SplitterNode;
36     class AnySplitOutputPort;
37     class TypeCode;
38     class TypeCodeSeq;
39
40     class InterceptorInputPort : public AnyInputPort
41     {
42       friend class ForEachLoopGen;
43       friend class SplitterNode;
44     private:
45       AnySplitOutputPort *_repr;
46     private:
47       InterceptorInputPort(const std::string& name, Node *node, TypeCode* type);
48       InterceptorInputPort(const InterceptorInputPort& other, Node *newHelder);
49       void getAllRepresentants(std::set<InPort *>& repr) const;
50       InputPort *clone(Node *newHelder) const;
51       void setRepr(AnySplitOutputPort *repr);
52     };
53
54     class AnySplitOutputPort : public OutputPort
55     {
56       friend class ForEachLoopGen;
57       friend class SplitterNode;
58     private:
59       OutPort *_repr;
60       InterceptorInputPort *_intercptr;
61       mutable unsigned int _cnt;
62     private:
63       bool decrRef();
64       void incrRef() const;
65       AnySplitOutputPort(const std::string& name, Node *node, TypeCode *type);
66       AnySplitOutputPort(const AnySplitOutputPort& other, Node *newHelder);
67       bool addInPort(InPort *inPort) ;
68       void getAllRepresented(std::set<OutPort *>& represented) const;
69       int removeInPort(InPort *inPort, bool forward) ;
70       void addRepr(OutPort *repr, InterceptorInputPort *intercptr);
71       OutPort *getRepr() const { return _repr; }
72       OutputPort *clone(Node *newHelder) const;
73     };
74
75     class YACSLIBENGINE_EXPORT SeqAnyInputPort : public AnyInputPort
76     {
77       friend class ForEachLoopGen;
78       friend class SplitterNode;
79     public:
80       unsigned getNumberOfElements() const;
81       virtual std::string dump();
82     private:
83       SeqAnyInputPort(const std::string& name, Node *node, TypeCodeSeq* type);
84       SeqAnyInputPort(const SeqAnyInputPort& other, Node *newHelder);
85       InputPort *clone(Node *newHelder) const;
86       Any *getValueAtRank(int i) const;
87     };
88
89     class SplitterNode : public ElementaryNode
90     {
91       friend class ForEachLoopGen;
92     private:
93       static const char NAME_OF_SEQUENCE_INPUT[];
94     private:
95       SplitterNode(const std::string& name, TypeCode *typeOfData, ForEachLoopGen *father);
96       SplitterNode(const SplitterNode& other, ForEachLoopGen *father);
97       InputPort *getInputPort(const std::string& name) const ;
98       Node *simpleClone(ComposedNode *father, bool editionOnly) const;
99       unsigned getNumberOfElements() const;
100       void execute();
101       void init(bool start=true);
102       void putSplittedValueOnRankTo(int rankInSeq, int branch, bool first);
103     private:
104       SeqAnyInputPort _dataPortToDispatch;
105     };
106
107     class FakeNodeForForEachLoop : public ElementaryNode
108     {
109       friend class ForEachLoopGen;
110     private:
111       ForEachLoopGen *_loop;
112       bool _normalFinish;
113     private:
114       FakeNodeForForEachLoop(ForEachLoopGen *loop, bool normalFinish);
115       FakeNodeForForEachLoop(const FakeNodeForForEachLoop& other);
116       Node *simpleClone(ComposedNode *father, bool editionOnly) const;
117       void exForwardFailed();
118       void exForwardFinished();
119       void execute();
120       void aborted();
121       void finished();
122     private:
123       static const char NAME[];
124     };
125
126     class YACSLIBENGINE_EXPORT ForEachLoopPassedData
127     {
128     public:
129       ForEachLoopPassedData(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
130       ForEachLoopPassedData(const ForEachLoopPassedData& copy);
131       ~ForEachLoopPassedData();
132       void init();
133       void checkCompatibilyWithNb(int nbOfElts) const;
134       void checkLevel2(const std::vector<AnyInputPort *>& ports) const;
135       int getNumberOfEltsAlreadyDone() const { return (int)_passedIds.size(); }
136       int toAbsId(int localId) const;
137       int toAbsIdNot(int localId) const;
138       int getNumberOfElementsToDo() const;
139       void assignAlreadyDone(const std::vector<SequenceAny *>& execVals) const;
140       const std::vector<unsigned int>& getIds()const {return _passedIds;}
141       const std::vector<SequenceAny *>& getOutputs()const {return _passedOutputs;}
142       const std::vector<std::string>& getOutputNames()const {return _nameOfOutputs;}
143       //const std::vector<bool>& getFlags()const {return _flagsIds;}
144     private:
145       std::vector<unsigned int> _passedIds;
146       std::vector<SequenceAny *> _passedOutputs;
147       std::vector<std::string> _nameOfOutputs;
148       mutable std::vector<bool> _flagsIds;
149     };
150
151     class Executor;
152
153     class YACSLIBENGINE_EXPORT ForEachLoopGen : public DynParaLoop
154     {
155       friend class SplitterNode;
156       friend class FakeNodeForForEachLoop;
157
158     public:
159       static const char NAME_OF_SPLITTERNODE[];
160     protected:
161       static const int NOT_RUNNING_BRANCH_ID;
162     protected:
163       int _currentIndex;
164       SplitterNode _splitterNode;
165       FakeNodeForForEachLoop *_nodeForSpecialCases;
166       std::vector<AnySplitOutputPort *> _outGoingPorts;//! ports linked to node outside the current scope
167       std::vector<InterceptorInputPort *> _intecptrsForOutGoingPorts;//!ports created for TypeCodes correctness
168       //part of attributes defining graph dynamically built on control notification
169       unsigned _execCurrentId;
170       std::vector<SequenceAny *> _execVals;
171       std::vector< std::vector<AnyInputPort *> > _execOutGoingPorts;
172       ForEachLoopPassedData *_passedData;
173     public:
174       ForEachLoopGen(const std::string& name, TypeCode *typeOfDataSplitted, std::unique_ptr<NbBranchesAbstract>&& branchManager);
175       ForEachLoopGen(const ForEachLoopGen& other, ComposedNode *father, bool editionOnly);
176       ~ForEachLoopGen();
177       void init(bool start=true);
178       void exUpdateState();
179       void exUpdateProgress();
180       void getReadyTasks(std::vector<Task *>& tasks);
181       int getNumberOfInputPorts() const;
182       //
183       void checkNoCyclePassingThrough(Node *node) ;
184       void selectRunnableTasks(std::vector<Task *>& tasks);
185       //
186       unsigned getExecCurrentId() const { return _execCurrentId; } // for update progress bar on GUI part
187       std::list<InputPort *> getSetOfInputPort() const;
188       std::list<InputPort *> getLocalInputPorts() const;
189       InputPort *edGetSeqOfSamplesPort() { return &_splitterNode._dataPortToDispatch; }
190       InputPort *getInputPort(const std::string& name) const ;
191       OutPort *getOutPort(const std::string& name) const ;
192       OutputPort *getOutputPort(const std::string& name) const ;
193       Node *getChildByShortName(const std::string& name) const ;
194       std::list<OutputPort *> getLocalOutputPorts() const;
195       void writeDot(std::ostream &os) const;
196       virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";}
197       virtual void resetState(int level);
198       std::string getProgress() const;
199       std::list<ProgressWeight> getProgressWeight() const;
200       int getCurrentIndex() const { return _currentIndex; }
201       int getNbOfElementsToBeProcessed() const;
202       static int getFEDeltaBetween(OutPort *start, InPort *end);
203 #ifndef SWIG
204       ForEachLoopPassedData* getProcessedData()const;
205       void setProcessedData(ForEachLoopPassedData* processedData);
206       std::vector<unsigned int> getPassedResults(Executor *execut, std::vector<SequenceAny *>& outputs, std::vector<std::string>& nameOfOutputs) const;
207       void assignPassedResults(const std::vector<unsigned int>& passedIds, const std::vector<SequenceAny *>& passedOutputs, const std::vector<std::string>& nameOfOutputs);
208 #endif
209      const TypeCode* getOutputPortType(const std::string& portName)const;
210       void cleanDynGraph() override;
211     protected:
212       void checkLinkPossibility(OutPort *start, const std::list<ComposedNode *>& pointsOfViewStart,
213                                 InPort *end, const std::list<ComposedNode *>& pointsOfViewEnd) ;
214       YACS::Event updateStateOnFinishedEventFrom(Node *node);
215       YACS::Event updateStateForInitNodeOnFinishedEventFrom(Node *node, unsigned int id);
216       YACS::Event updateStateForWorkNodeOnFinishedEventFrom(Node *node, unsigned int id, bool isNormalFinish);
217       YACS::Event updateStateForFinalizeNodeOnFinishedEventFrom(Node *node, unsigned int id);
218       YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);
219       void buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView);
220       void getDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) ;
221       void releaseDelegateOf(OutPort *portDwn, OutPort *portUp, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView) ;
222     protected:
223       void pushAllSequenceValues();
224       void createOutputOutOfScopeInterceptors(int branchNb);
225       void prepareSequenceValues(int sizeOfSamples);
226       OutPort *getDynOutPortByAbsName(int branchNb, const std::string& name);
227       void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb);
228     private:
229       int getFinishedId();
230     public:
231       static void InterceptorizeNameOfPort(std::string& portName);
232       static const char INTERCEPTOR_STR[];
233     };
234
235     class YACSLIBENGINE_EXPORT ForEachLoop : public ForEachLoopGen
236     {
237     public:
238       ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted):ForEachLoopGen(name,typeOfDataSplitted,std::unique_ptr<NbBranchesAbstract>(new NbBranches(this))) { }
239       ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly):ForEachLoopGen(other,father,editionOnly) { }
240       ~ForEachLoop() { }
241       void accept(Visitor *visitor);
242     protected:
243       Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
244     };
245
246     class YACSLIBENGINE_EXPORT ForEachLoopDyn : public ForEachLoopGen
247     {
248     public:
249       ForEachLoopDyn(const std::string& name, TypeCode *typeOfDataSplitted):ForEachLoopGen(name,typeOfDataSplitted,std::unique_ptr<NbBranchesAbstract>(new NoNbBranches)) { }
250       ForEachLoopDyn(const ForEachLoopDyn& other, ComposedNode *father, bool editionOnly):ForEachLoopGen(other,father,editionOnly) { }
251       ~ForEachLoopDyn() { }
252       void accept(Visitor *visitor);
253     protected:
254       Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
255     };
256   }
257
258