Salome HOME
Merge branch 'omu/update_doc_77'
[modules/yacs.git] / src / evalyfx / YACSEvalYFX.cxx
1 // Copyright (C) 2012-2015  CEA/DEN, EDF R&D
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 // Author : Anthony Geay (EDF R&D)
20
21 #include "YACSEvalYFX.hxx"
22 #include "YACSEvalYFXPattern.hxx"
23 #include "YACSEvalAutoPtr.hxx"
24 #include "YACSEvalResource.hxx"
25 #include "YACSEvalSession.hxx"
26 #include "YACSEvalPort.hxx"
27 #include "RuntimeSALOME.hxx"
28 #include "Executor.hxx"
29 #include "Proc.hxx"
30 #include "Exception.hxx"
31 #include "parsers.hxx"
32
33 #include <algorithm>
34 #include <sstream>
35 #include <limits>
36 #include <set>
37
38 #include <Python.h>
39
40 class MyAutoThreadSaver
41 {
42 public:
43   MyAutoThreadSaver():_save(PyEval_SaveThread()) { }
44   ~MyAutoThreadSaver() { PyEval_RestoreThread(_save); }
45 private:
46   PyThreadState *_save;
47 };
48
49 YACSEvalYFX *YACSEvalYFX::BuildFromFile(const std::string& xmlOfScheme)
50 {
51   YACS::ENGINE::RuntimeSALOME::setRuntime();
52   YACS::YACSLoader l;
53   YACS::ENGINE::Proc *scheme(l.load(xmlOfScheme.c_str()));
54   return new YACSEvalYFX(scheme,true);
55 }
56
57 YACSEvalYFX *YACSEvalYFX::BuildFromScheme(YACS::ENGINE::Proc *scheme)
58 {
59   return new YACSEvalYFX(scheme,false);
60 }
61
62 std::vector< YACSEvalInputPort * > YACSEvalYFX::getFreeInputPorts() const
63 {
64   return _pattern->getFreeInputPorts();
65 }
66
67 std::vector< YACSEvalOutputPort * > YACSEvalYFX::getFreeOutputPorts() const
68 {
69   return _pattern->getFreeOutputPorts();
70 }
71
72 void YACSEvalYFX::lockPortsForEvaluation(const std::vector< YACSEvalInputPort * >& inputsOfInterest, const std::vector< YACSEvalOutputPort * >& outputsOfInterest)
73 {
74   checkPortsForEvaluation(inputsOfInterest,outputsOfInterest);
75   _pattern->setOutPortsOfInterestForEvaluation(outputsOfInterest);
76   _pattern->generateGraph();
77 }
78
79 void YACSEvalYFX::unlockAll()
80 {
81   std::vector< YACSEvalInputPort * > allInputs(getFreeInputPorts());
82   for(std::vector< YACSEvalInputPort * >::const_iterator it=allInputs.begin();it!=allInputs.end();it++)
83     (*it)->unlock();
84   _pattern->resetOutputsOfInterest();
85   _pattern->resetGeneratedGraph();
86 }
87
88 bool YACSEvalYFX::isLocked() const
89 {
90   return _pattern->isLocked();
91 }
92
93 YACSEvalListOfResources *YACSEvalYFX::giveResources()
94 {
95   return _pattern->giveResources();
96 }
97
98 bool YACSEvalYFX::run(YACSEvalSession *session, int& nbOfBranches)
99 {
100   _pattern->assignRandomVarsInputs();
101   YACSEvalListOfResources *rss(giveResources());
102   if(!rss->isInteractive())
103     throw YACS::Exception("YACSEvalYFX::run : not implemented yet for non interactive !");
104   YACSEvalSession *mySession(session);
105   YACS::AutoCppPtr<YACSEvalSession> loc;
106   if(!session)
107     {
108       throw YACS::Exception("YACSEvalYFX::run : input session in null !");
109       /*loc=new YACSEvalSession;
110       mySession=loc;*/
111     }
112   rss->apply();
113   nbOfBranches=_pattern->assignNbOfBranches();
114   mySession->launch();
115   YACS::ENGINE::Executor exe;
116   exe.setKeepGoingProperty(!_params.getStopASAPAfterErrorStatus());
117   //
118   _pattern->emitStart();
119   {
120     MyAutoThreadSaver locker;
121     exe.RunW(getUndergroundGeneratedGraph());
122   }
123   return getUndergroundGeneratedGraph()->getState()==YACS::DONE;
124 }
125
126 void YACSEvalYFX::registerObserver(YACSEvalObserver *observer)
127 {
128   if(!_pattern)
129     throw YACS::Exception("YACSEvalYFX::registerObserver : no pattern !");
130   _pattern->registerObserver(observer);
131 }
132
133 YACSEvalObserver *YACSEvalYFX::getObserver()
134 {
135   if(!_pattern)
136     throw YACS::Exception("YACSEvalYFX::getObserver : no pattern !");
137   return _pattern->getObserver();
138 }
139
140 std::vector<YACSEvalSeqAny *> YACSEvalYFX::getResults() const
141 {
142   return _pattern->getResults();
143 }
144
145 YACS::ENGINE::Proc *YACSEvalYFX::getUndergroundGeneratedGraph() const
146 {
147   return _pattern->getUndergroundGeneratedGraph();
148 }
149
150 void YACSEvalYFX::setParallelizeStatus(bool newVal)
151 {
152   _pattern->setParallelizeStatus(newVal);
153 }
154
155 bool YACSEvalYFX::getParallelizeStatus() const
156 {
157   return _pattern->getParallelizeStatus();
158 }
159
160 YACSEvalYFX::YACSEvalYFX(YACS::ENGINE::Proc *scheme, bool ownScheme):_pattern(0)
161 {
162   _pattern=YACSEvalYFXPattern::FindPatternFrom(this,scheme,ownScheme);
163 }
164
165 void YACSEvalYFX::checkPortsForEvaluation(const std::vector< YACSEvalInputPort * >& inputs, const std::vector< YACSEvalOutputPort * >& outputs) const
166 {
167   std::set<YACSEvalInputPort * > inputs2(inputs.begin(),inputs.end());
168   std::vector< YACSEvalInputPort * > allInputs(getFreeInputPorts());
169   std::vector< YACSEvalOutputPort * > allOutputs(getFreeOutputPorts());
170   for(std::vector< YACSEvalInputPort * >::const_iterator it=allInputs.begin();it!=allInputs.end();it++)
171     {
172       if(inputs2.find(*it)==inputs2.end())
173         {
174           if(!(*it)->isOKForLock())
175             {
176               std::ostringstream oss; oss << "YACSEvalYFX::checkPortsForEvaluation : input port with name \"" << (*it)->getName() << "\" is not set properly !";
177               throw YACS::Exception(oss.str());
178             }
179         }
180     }
181   for(std::vector< YACSEvalOutputPort * >::const_iterator it=outputs.begin();it!=outputs.end();it++)
182     if(std::find(allOutputs.begin(),allOutputs.end(),*it)==allOutputs.end())
183       throw YACS::Exception("YACSEvalYFX::lockPortsForEvaluation : one of output is not part of this !");
184   std::set< YACSEvalOutputPort * > soutputs(outputs.begin(),outputs.end());
185   if(soutputs.size()!=outputs.size())
186     throw YACS::Exception("YACSEvalYFX::lockPortsForEvaluation : each elt in outputs must appear once !");
187   for(std::vector< YACSEvalInputPort * >::const_iterator it=allInputs.begin();it!=allInputs.end();it++)
188     {
189       (*it)->declareRandomnessStatus(inputs2.find(*it)!=inputs2.end());
190       (*it)->lock();
191     }
192 }
193
194 YACSEvalYFX::~YACSEvalYFX()
195 {
196   delete _pattern;
197 }