Version: 9.15.0
SalomeOptimizerLoop.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2025 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 #include "SalomeOptimizerLoop.hxx"
21 
22 // rnv: avoid compilation warning on Linux : "_POSIX_C_SOURCE" and "_XOPEN_SOURCE" are redefined
23 #ifdef _POSIX_C_SOURCE
24 #undef _POSIX_C_SOURCE
25 #endif
26 
27 #ifdef _XOPEN_SOURCE
28 #undef _XOPEN_SOURCE
29 #endif
30 #include <Python.h>
31 #include "TypeCode.hxx"
32 #include "PyStdout.hxx"
33 
34 //#define _DEVDEBUG_
35 #include "YacsTrace.hxx"
36 
37 using namespace YACS::ENGINE;
38 using namespace std;
39 
40 
47 SalomeOptimizerLoop::SalomeOptimizerLoop(const std::string& name, const std::string& algLibWthOutExt,
48  const std::string& symbolNameToOptimizerAlgBaseInstanceFactory,
49  bool algInitOnFile,bool initAlgo, Proc * procForTypes):
50  OptimizerLoop(name,algLibWthOutExt,symbolNameToOptimizerAlgBaseInstanceFactory,algInitOnFile,false)
51 {
52  if(initAlgo)
53  {
54  //try
55  // {
56  setAlgorithm(algLibWthOutExt, symbolNameToOptimizerAlgBaseInstanceFactory, true, procForTypes);
57  // }
58  //catch(YACS::Exception& e)
59  // {
60  //ignore it
61  // }
62  }
63 }
64 
66  OptimizerLoop(other,father,editionOnly)
67 {
68 }
69 
71 {
72  Py_XDECREF(_pyAlgo);
73 }
74 
75 Node *SalomeOptimizerLoop::simpleClone(ComposedNode *father, bool editionOnly) const
76 {
77  SalomeOptimizerLoop* sol=new SalomeOptimizerLoop(*this,father,editionOnly);
78  // TODO: Remove this const_cast (find a better design to get the type codes from the original node)
79  Proc * procForTypes = sol->getProc();
80  if (procForTypes == NULL) {
81  const Proc * origProc = getProc();
82  procForTypes = const_cast<Proc *>(origProc);
83  }
84  sol->setAlgorithm(_alglib, _symbol, false, procForTypes);
85  return sol;
86 }
87 
89 
95 {
96  YASSERT(_alg == NULL)
97 
98  if(_alglib.size() > 3 && _alglib.substr(_alglib.size()-3,3)==".py")
99  {
100  //if alglib extension is .py try to import the corresponding python module
101  PyGILState_STATE gstate=PyGILState_Ensure();
102 
103  PyObject* mainmod = PyImport_AddModule("__main__");
104  PyObject* globals = PyModule_GetDict(mainmod);
105 
106  std::string pyscript;
107  pyscript="import sys\n"
108  "import SALOMERuntime\n"
109  "filename='";
110  pyscript=pyscript+_alglib+"'\nentry='"+_symbol+"'\n";
111  pyscript=pyscript+"import os\n"
112  "import pilot\n"
113  "rep,mod=os.path.split(os.path.splitext(filename)[0])\n"
114  "if rep != '':\n"
115  " sys.path.insert(0,rep)\n"
116  "algomodule=__import__(mod)\n"
117  "if rep != '':\n"
118  " del sys.path[0]\n"
119  "algoclass= getattr(algomodule,entry)\n"
120  "algo= algoclass()\n"
121  "swigalgo= algo.this\n"
122  "\n";
123 
124  PyObject* res=PyRun_String(pyscript.c_str(), Py_file_input, globals, globals );
125 
126  if(res == NULL)
127  {
128  //error during import
129  _errorDetails="";
130  PyObject* new_stderr = newPyStdOut(_errorDetails);
131  PySys_SetObject((char*)"stderr", new_stderr);
132  PyErr_Print();
133  PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
134  Py_DECREF(new_stderr);
135  modified();
136  PyGILState_Release(gstate);
138  }
139  else
140  {
141  Py_DECREF(res);
142 
143  typedef struct {
144  PyObject_HEAD
145  void *ptr;
146  void *ty;
147  int own;
148  PyObject *next;
149  } SwigPyObject;
150 
151  PyObject * _pyAlgo = PyDict_GetItemString(globals, "algo");
152  Py_XINCREF(_pyAlgo);
153  SwigPyObject* pyalgo = (SwigPyObject*)PyDict_GetItemString(globals, "swigalgo");
154  _alg=(OptimizerAlgBase*)pyalgo->ptr;
155  _alg->setPool(&_myPool);
156  }
157  PyGILState_Release(gstate);
158  }
159  else
160  {
161  //else try to load a dynamic library
163  }
164 }
#define YASSERT(val)
YASSERT macro is always defined, used like assert, but throw a YACS::Exception instead of abort.
Definition: YacsTrace.hxx:59
Base class for all composed nodes.
Base class for all nodes.
Definition: Node.hxx:70
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
std::string _errorDetails
Definition: Node.hxx:93
virtual Proc * getProc()
Definition: Node.cxx:401
Base class factorizing common methods for all algorithms interfaces.
virtual void setPool(Pool *pool)
class to build optimization loops
virtual void setAlgorithm(const std::string &alglib, const std::string &symbol, bool checkLinks=true, Proc *procForTypes=NULL)
Set the algorithm library name and factory name (symbol in library) to create the algorithm and chang...
virtual void loadAlgorithm()
Load the algorithm from the dynamic library.
Base class for all schema objects.
Definition: Proc.hxx:44
class to build optimization loops
SalomeOptimizerLoop(const std::string &name, const std::string &algLibWthOutExt, const std::string &symbolNameToOptimizerAlgBaseInstanceFactory, bool algInitOnFile, bool initAlgo=true, Proc *procForTypes=NULL)
Node * simpleClone(ComposedNode *father, bool editionOnly) const
virtual void loadAlgorithm()
Load the algorithm object from a Python module or a dynamic library.
PyObject * newPyStdOut(std::string &out)
Definition: PyStdout.cxx:129