1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "RuntimeSALOME.hxx"
21 #include "PythonNode.hxx"
22 #include "PythonPorts.hxx"
23 #include "TypeCode.hxx"
24 #include "Container.hxx"
25 #include "SalomeContainer.hxx"
26 #include "ConversionException.hxx"
28 #include "PyStdout.hxx"
35 #define getpid _getpid
38 #if PY_VERSION_HEX < 0x02050000
39 typedef int Py_ssize_t;
43 #include "YacsTrace.hxx"
45 using namespace YACS::ENGINE;
48 const char PythonNode::IMPL_NAME[]="Python";
49 const char PythonNode::KIND[]="Python";
51 PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father)
53 _implementation=IMPL_NAME;
54 PyGILState_STATE gstate=PyGILState_Ensure();
55 _context=PyDict_New();
56 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
59 msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
60 PyGILState_Release(gstate);
61 _errorDetails=msg.str();
62 throw Exception(msg.str());
64 PyGILState_Release(gstate);
67 PythonNode::PythonNode(const std::string& name):InlineNode(name)
69 _implementation=IMPL_NAME;
70 PyGILState_STATE gstate = PyGILState_Ensure();
71 _context=PyDict_New();
72 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
75 msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__;
76 PyGILState_Release(gstate);
77 _errorDetails=msg.str();
78 throw Exception(msg.str());
80 PyGILState_Release(gstate);
83 PythonNode::~PythonNode()
85 PyGILState_STATE gstate = PyGILState_Ensure();
86 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
88 PyGILState_Release(gstate);
91 void PythonNode::checkBasicConsistency() const throw(YACS::Exception)
93 DEBTRACE("checkBasicConsistency");
94 InlineNode::checkBasicConsistency();
96 PyGILState_STATE gstate = PyGILState_Ensure();
98 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
101 std::string error="";
102 PyObject* new_stderr = newPyStdOut(error);
103 PySys_SetObject((char*)"stderr", new_stderr);
105 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
106 Py_DECREF(new_stderr);
107 PyGILState_Release(gstate);
108 throw Exception(error);
112 PyGILState_Release(gstate);
115 void PythonNode::load()
117 DEBTRACE( "---------------PyNode::load function---------------" );
124 void PythonNode::loadLocal()
126 DEBTRACE( "---------------PyNode::loadLocal function---------------" );
130 void PythonNode::loadRemote()
132 DEBTRACE( "---------------PyNode::loadRemote function---------------" );
135 if(!_container->isAlreadyStarted(0))
139 _container->start(0);
143 _errorDetails=e.what();
150 std::string what("PyNode::loadRemote : a load operation requested on \"");
151 what+=_name; what+="\" with no container specified.";
153 throw Exception(what);
156 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
160 _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str());
162 catch( const SALOME::SALOME_Exception& ex )
164 std::string msg="Exception on remote python node creation ";
166 msg += ex.details.text.in();
168 throw Exception(msg);
171 PyGILState_STATE gstate = PyGILState_Ensure();
172 const char picklizeScript[]="import cPickle\n"
173 "def pickleForDistPyth2009(kws):\n"
174 " return cPickle.dumps(((),kws),-1)\n"
176 "def unPickleForDistPyth2009(st):\n"
177 " args=cPickle.loads(st)\n"
179 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
183 PyObject* new_stderr = newPyStdOut(_errorDetails);
184 PySys_SetObject((char*)"stderr", new_stderr);
186 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
187 Py_DECREF(new_stderr);
189 PyGILState_Release(gstate);
190 throw Exception("Error during load");
194 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
195 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
196 if(_pyfuncSer == NULL)
199 PyObject* new_stderr = newPyStdOut(_errorDetails);
200 PySys_SetObject((char*)"stderr", new_stderr);
202 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
203 Py_DECREF(new_stderr);
205 PyGILState_Release(gstate);
206 throw Exception("Error during load");
208 if(_pyfuncUnser == NULL)
211 PyObject* new_stderr = newPyStdOut(_errorDetails);
212 PySys_SetObject((char*)"stderr", new_stderr);
214 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
215 Py_DECREF(new_stderr);
217 PyGILState_Release(gstate);
218 throw Exception("Error during load");
220 DEBTRACE( "---------------End PyNode::loadRemote function---------------" );
221 PyGILState_Release(gstate);
225 void PythonNode::execute()
233 void PythonNode::executeRemote()
235 DEBTRACE( "++++++++++++++ PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
237 throw Exception("DistributedPythonNode badly loaded");
238 PyGILState_STATE gstate = PyGILState_Ensure();
240 //===========================================================================
241 // Get inputs in input ports, build a Python dict and pickle it
242 //===========================================================================
244 PyObject* args = PyDict_New();
245 std::list<InputPort *>::iterator iter2;
247 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
249 InputPyPort *p=(InputPyPort *)*iter2;
251 PyDict_SetItemString(args,p->getName().c_str(),ob);
255 PyObject_Print(args,stderr,Py_PRINT_RAW);
258 PyObject *serializationInput=PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL);
259 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
260 char* serializationInputC;
262 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
264 PyGILState_Release(gstate);
265 throw Exception("DistributedPythonNode problem in python pickle");
267 PyGILState_Release(gstate);
269 Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
270 serializationInputCorba->length(len);
271 for(int i=0; i < len ; i++)
272 serializationInputCorba[i]=serializationInputC[i];
274 //get the list of output argument names
275 std::list<OutputPort *>::iterator iter;
276 Engines::listofstring myseq;
277 myseq.length(getNumberOfOutputPorts());
279 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
281 OutputPyPort *p=(OutputPyPort *)*iter;
282 myseq[pos]=p->getName().c_str();
283 DEBTRACE( "port name: " << p->getName() );
284 DEBTRACE( "port kind: " << p->edGetType()->kind() );
285 DEBTRACE( "port pos : " << pos );
288 //===========================================================================
289 // Execute in remote Python node
290 //===========================================================================
291 DEBTRACE( "-----------------starting remote python invocation-----------------" );
292 Engines::pickledArgs_var resultCorba;
295 //pass outargsname and dict serialized
296 resultCorba=_pynode->execute(myseq,serializationInputCorba);
298 catch( const SALOME::SALOME_Exception& ex )
300 std::string msg="Exception on remote python invocation";
302 msg += ex.details.text.in();
304 throw Exception(msg);
306 DEBTRACE( "-----------------end of remote python invocation-----------------" );
307 //===========================================================================
308 // Get results, unpickle and put them in output ports
309 //===========================================================================
310 char *resultCorbaC=new char[resultCorba->length()+1];
311 resultCorbaC[resultCorba->length()]='\0';
312 for(int i=0;i<resultCorba->length();i++)
313 resultCorbaC[i]=resultCorba[i];
315 gstate = PyGILState_Ensure();
317 PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
318 delete [] resultCorbaC;
319 args = PyTuple_New(1);
320 PyTuple_SetItem(args,0,resultPython);
321 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
324 if (finalResult == NULL)
326 std::stringstream msg;
327 msg << "Conversion with pickle of output ports failed !";
328 msg << " : " << __FILE__ << ":" << __LINE__;
329 PyGILState_Release(gstate);
330 _errorDetails=msg.str();
331 throw YACS::ENGINE::ConversionException(msg.str());
334 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
336 if(finalResult == Py_None)
338 else if(PyTuple_Check(finalResult))
339 nres=PyTuple_Size(finalResult);
341 if(getNumberOfOutputPorts() != nres)
343 std::string msg="Number of output arguments : Mismatch between definition and execution";
344 Py_DECREF(finalResult);
345 PyGILState_Release(gstate);
347 throw Exception(msg);
353 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
355 OutputPyPort *p=(OutputPyPort *)*iter;
356 DEBTRACE( "port name: " << p->getName() );
357 DEBTRACE( "port kind: " << p->edGetType()->kind() );
358 DEBTRACE( "port pos : " << pos );
359 if(PyTuple_Check(finalResult))
360 ob=PyTuple_GetItem(finalResult,pos) ;
363 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
367 Py_DECREF(finalResult);
369 catch(ConversionException& ex)
371 Py_DECREF(finalResult);
372 PyGILState_Release(gstate);
373 _errorDetails=ex.what();
377 PyGILState_Release(gstate);
379 DEBTRACE( "++++++++++++++ ENDOF PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
382 void PythonNode::executeLocal()
384 DEBTRACE( "++++++++++++++ PyNode::executeLocal: " << getName() << " ++++++++++++++++++++" );
385 PyGILState_STATE gstate = PyGILState_Ensure();
387 DEBTRACE( "---------------PyNode::inputs---------------" );
388 list<InputPort *>::iterator iter2;
389 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
391 InputPyPort *p=(InputPyPort *)*iter2;
392 DEBTRACE( "port name: " << p->getName() );
393 DEBTRACE( "port kind: " << p->edGetType()->kind() );
394 PyObject* ob=p->getPyObj();
395 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
397 PyObject_Print(ob,stderr,Py_PRINT_RAW);
400 int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob);
401 DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt );
404 DEBTRACE( "---------------End PyNode::inputs---------------" );
407 DEBTRACE( "----------------PyNode::calculation---------------" );
409 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
411 std::ostringstream stream;
412 stream << "/tmp/PythonNode_";
415 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
419 PyObject* new_stderr = newPyStdOut(_errorDetails);
420 PySys_SetObject((char*)"stderr", new_stderr);
422 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
423 Py_DECREF(new_stderr);
424 PyGILState_Release(gstate);
425 throw Exception("Error during execution");
427 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
431 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
434 if(PyErr_Occurred ())
437 PyObject* new_stderr = newPyStdOut(_errorDetails);
438 PySys_SetObject((char*)"stderr", new_stderr);
439 ofstream errorfile(stream.str().c_str());
440 if (errorfile.is_open())
442 errorfile << _script;
446 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
447 Py_DECREF(new_stderr);
449 PyGILState_Release(gstate);
450 throw Exception("Error during execution");
453 DEBTRACE( "-----------------PyNode::outputs-----------------" );
454 list<OutputPort *>::iterator iter;
457 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
459 OutputPyPort *p=(OutputPyPort *)*iter;
460 DEBTRACE( "port name: " << p->getName() );
461 DEBTRACE( "port kind: " << p->edGetType()->kind() );
462 PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
464 PyGILState_Release(gstate);
465 std::string msg="Error during execution: there is no variable ";
466 msg=msg+p->getName()+" in node context";
468 throw Exception(msg);
470 DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
472 PyObject_Print(ob,stderr,Py_PRINT_RAW);
478 catch(ConversionException& ex)
480 PyGILState_Release(gstate);
481 _errorDetails=ex.what();
485 DEBTRACE( "-----------------End PyNode::outputs-----------------" );
486 PyGILState_Release(gstate);
487 DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" );
490 std::string PythonNode::getContainerLog()
492 if(_mode=="local")return "";
497 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
498 CORBA::String_var logname = objContainer->logfilename();
501 std::string::size_type pos = msg.find(":");
502 msg=msg.substr(pos+1);
506 msg = "Container no longer reachable";
511 void PythonNode::shutdown(int level)
513 DEBTRACE("PythonNode::shutdown " << level);
514 if(_mode=="local")return;
517 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
518 _pynode=Engines::PyScriptNode::_nil();
519 _container->shutdown(level);
523 Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
525 return new PythonNode(*this,father);
528 //! Create a new node of same type with a given name
529 PythonNode* PythonNode::cloneNode(const std::string& name)
531 PythonNode* n=new PythonNode(name);
532 n->setScript(_script);
533 list<InputPort *>::iterator iter;
534 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
536 InputPyPort *p=(InputPyPort *)*iter;
537 DEBTRACE( "port name: " << p->getName() );
538 DEBTRACE( "port kind: " << p->edGetType()->kind() );
539 n->edAddInputPort(p->getName(),p->edGetType());
541 list<OutputPort *>::iterator iter2;
542 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
544 OutputPyPort *p=(OutputPyPort *)*iter2;
545 DEBTRACE( "port name: " << p->getName() );
546 DEBTRACE( "port kind: " << p->edGetType()->kind() );
547 n->edAddOutputPort(p->getName(),p->edGetType());
552 PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0)
554 _implementation = PythonNode::IMPL_NAME;
555 PyGILState_STATE gstate = PyGILState_Ensure();
556 _context=PyDict_New();
557 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
558 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
561 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
562 _errorDetails=msg.str();
563 PyGILState_Release(gstate);
564 throw Exception(msg.str());
566 PyGILState_Release(gstate);
569 PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
572 _implementation = PythonNode::IMPL_NAME;
573 DEBTRACE( "PyFuncNode::PyFuncNode " << name );
574 PyGILState_STATE gstate = PyGILState_Ensure();
575 _context=PyDict_New();
576 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
577 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
580 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
581 _errorDetails=msg.str();
582 PyGILState_Release(gstate);
583 throw Exception(msg.str());
585 PyGILState_Release(gstate);
588 PyFuncNode::~PyFuncNode()
590 DEBTRACE( getName() );
591 PyGILState_STATE gstate = PyGILState_Ensure();
592 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
593 if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
595 PyGILState_Release(gstate);
596 if(!CORBA::is_nil(_pynode))
598 _pynode->UnRegister();
602 void PyFuncNode::checkBasicConsistency() const throw(YACS::Exception)
604 DEBTRACE("checkBasicConsistency");
605 InlineFuncNode::checkBasicConsistency();
607 PyGILState_STATE gstate = PyGILState_Ensure();
609 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
612 std::string error="";
613 PyObject* new_stderr = newPyStdOut(error);
614 PySys_SetObject((char*)"stderr", new_stderr);
616 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
617 Py_DECREF(new_stderr);
618 PyGILState_Release(gstate);
619 throw Exception(error);
623 PyGILState_Release(gstate);
626 void PyFuncNode::load()
628 DEBTRACE( "---------------PyfuncNode::load function---------------" );
635 void PyFuncNode::loadRemote()
637 DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" );
640 if(!_container->isAlreadyStarted(0))
644 _container->start(0);
648 _errorDetails=e.what();
655 std::string what("PyFuncNode::loadRemote : a load operation requested on \"");
656 what+=_name; what+="\" with no container specified.";
658 throw Exception(what);
661 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
664 _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
666 catch( const SALOME::SALOME_Exception& ex )
668 std::string msg="Exception on remote python node creation ";
670 msg += ex.details.text.in();
672 throw Exception(msg);
675 PyGILState_STATE gstate = PyGILState_Ensure();
676 const char picklizeScript[]="import cPickle\n"
677 "def pickleForDistPyth2009(*args,**kws):\n"
678 " return cPickle.dumps((args,kws),-1)\n"
680 "def unPickleForDistPyth2009(st):\n"
681 " args=cPickle.loads(st)\n"
683 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
687 PyObject* new_stderr = newPyStdOut(_errorDetails);
688 PySys_SetObject((char*)"stderr", new_stderr);
690 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
691 Py_DECREF(new_stderr);
693 PyGILState_Release(gstate);
694 throw Exception("Error during load");
698 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
699 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
700 if(_pyfuncSer == NULL)
703 PyObject* new_stderr = newPyStdOut(_errorDetails);
704 PySys_SetObject((char*)"stderr", new_stderr);
706 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
707 Py_DECREF(new_stderr);
709 PyGILState_Release(gstate);
710 throw Exception("Error during load");
712 if(_pyfuncUnser == NULL)
715 PyObject* new_stderr = newPyStdOut(_errorDetails);
716 PySys_SetObject((char*)"stderr", new_stderr);
718 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
719 Py_DECREF(new_stderr);
721 PyGILState_Release(gstate);
722 throw Exception("Error during load");
724 DEBTRACE( "---------------End PyfuncNode::loadRemote function---------------" );
725 PyGILState_Release(gstate);
728 void PyFuncNode::loadLocal()
730 DEBTRACE( "---------------PyFuncNode::load function " << getName() << " ---------------" );
734 list<OutputPort *>::iterator iter;
735 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
737 OutputPyPort *p=(OutputPyPort *)*iter;
738 DEBTRACE( "port name: " << p->getName() );
739 DEBTRACE( "port kind: " << p->edGetType()->kind() );
743 PyGILState_STATE gstate = PyGILState_Ensure();
744 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
746 std::ostringstream stream;
747 stream << "/tmp/PythonNode_";
750 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
754 PyObject* new_stderr = newPyStdOut(_errorDetails);
755 PySys_SetObject((char*)"stderr", new_stderr);
757 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
758 Py_DECREF(new_stderr);
759 PyGILState_Release(gstate);
760 throw Exception("Error during execution");
762 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
766 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
767 if(PyErr_Occurred ())
770 PyObject* new_stderr = newPyStdOut(_errorDetails);
771 PySys_SetObject((char*)"stderr", new_stderr);
772 ofstream errorfile(stream.str().c_str());
773 if (errorfile.is_open())
775 errorfile << _script;
779 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
780 Py_DECREF(new_stderr);
782 PyGILState_Release(gstate);
783 throw Exception("Error during execution");
786 _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
787 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
791 PyObject* new_stderr = newPyStdOut(_errorDetails);
792 PySys_SetObject((char*)"stderr", new_stderr);
794 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
795 Py_DECREF(new_stderr);
797 PyGILState_Release(gstate);
798 throw Exception("Error during execution");
800 DEBTRACE( "---------------End PyFuncNode::load function---------------" );
801 PyGILState_Release(gstate);
804 void PyFuncNode::execute()
812 void PyFuncNode::executeRemote()
814 DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
816 throw Exception("DistributedPythonNode badly loaded");
817 PyGILState_STATE gstate = PyGILState_Ensure();
819 //===========================================================================
820 // Get inputs in input ports, build a Python tuple and pickle it
821 //===========================================================================
823 PyObject* args = PyTuple_New(getNumberOfInputPorts());
824 std::list<InputPort *>::iterator iter2;
826 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
828 InputPyPort *p=(InputPyPort *)*iter2;
831 PyTuple_SetItem(args,pos,ob);
835 PyObject_Print(args,stderr,Py_PRINT_RAW);
838 PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
839 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
840 char* serializationInputC;
842 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
844 PyGILState_Release(gstate);
845 throw Exception("DistributedPythonNode problem in python pickle");
847 PyGILState_Release(gstate);
849 Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
850 serializationInputCorba->length(len);
851 for(int i=0; i < len ; i++)
852 serializationInputCorba[i]=serializationInputC[i];
854 //===========================================================================
855 // Execute in remote Python node
856 //===========================================================================
857 DEBTRACE( "-----------------starting remote python invocation-----------------" );
858 Engines::pickledArgs_var resultCorba;
861 resultCorba=_pynode->execute(getFname().c_str(),serializationInputCorba);
863 catch( const SALOME::SALOME_Exception& ex )
865 std::string msg="Exception on remote python invocation";
867 msg += ex.details.text.in();
869 throw Exception(msg);
871 DEBTRACE( "-----------------end of remote python invocation-----------------" );
872 //===========================================================================
873 // Get results, unpickle and put them in output ports
874 //===========================================================================
875 char *resultCorbaC=new char[resultCorba->length()+1];
876 resultCorbaC[resultCorba->length()]='\0';
877 for(int i=0;i<resultCorba->length();i++)
878 resultCorbaC[i]=resultCorba[i];
880 gstate = PyGILState_Ensure();
882 PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
883 delete [] resultCorbaC;
884 args = PyTuple_New(1);
885 PyTuple_SetItem(args,0,resultPython);
886 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
889 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
891 if(finalResult == Py_None)
893 else if(PyTuple_Check(finalResult))
894 nres=PyTuple_Size(finalResult);
896 if(getNumberOfOutputPorts() != nres)
898 std::string msg="Number of output arguments : Mismatch between definition and execution";
899 Py_DECREF(finalResult);
900 PyGILState_Release(gstate);
902 throw Exception(msg);
906 std::list<OutputPort *>::iterator iter;
909 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
911 OutputPyPort *p=(OutputPyPort *)*iter;
912 DEBTRACE( "port name: " << p->getName() );
913 DEBTRACE( "port kind: " << p->edGetType()->kind() );
914 DEBTRACE( "port pos : " << pos );
915 if(PyTuple_Check(finalResult))
916 ob=PyTuple_GetItem(finalResult,pos) ;
919 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
923 Py_DECREF(finalResult);
925 catch(ConversionException& ex)
927 Py_DECREF(finalResult);
928 PyGILState_Release(gstate);
929 _errorDetails=ex.what();
933 PyGILState_Release(gstate);
935 DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
938 void PyFuncNode::executeLocal()
940 DEBTRACE( "++++++++++++++ PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
944 if(!_pyfunc)throw Exception("PyFuncNode badly loaded");
945 PyGILState_STATE gstate = PyGILState_Ensure();
947 DEBTRACE( "---------------PyFuncNode::inputs---------------" );
948 PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
949 list<InputPort *>::iterator iter2;
950 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
952 InputPyPort *p=(InputPyPort *)*iter2;
953 DEBTRACE( "port name: " << p->getName() );
954 DEBTRACE( "port kind: " << p->edGetType()->kind() );
957 PyObject_Print(ob,stderr,Py_PRINT_RAW);
960 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
962 PyTuple_SetItem(args,pos,ob);
963 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
966 DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
968 DEBTRACE( "----------------PyFuncNode::calculation---------------" );
970 PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
972 PyObject_Print(args,stderr,Py_PRINT_RAW);
975 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
976 PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
977 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
984 PyObject* new_stderr = newPyStdOut(_errorDetails);
985 PySys_SetObject((char*)"stderr", new_stderr);
986 std::ostringstream stream;
987 stream << "/tmp/PythonNode_";
989 ofstream errorfile(stream.str().c_str());
990 if (errorfile.is_open())
992 errorfile << _script;
996 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
997 Py_DECREF(new_stderr);
999 PyGILState_Release(gstate);
1000 throw Exception("Error during execution");
1002 DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
1004 DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
1006 if(result == Py_None)
1008 else if(PyTuple_Check(result))
1009 nres=PyTuple_Size(result);
1011 if(getNumberOfOutputPorts() != nres)
1013 std::string msg="Number of output arguments : Mismatch between definition and execution";
1015 PyGILState_Release(gstate);
1017 throw Exception(msg);
1022 PyObject_Print(result,stderr,Py_PRINT_RAW);
1025 list<OutputPort *>::iterator iter;
1028 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
1030 OutputPyPort *p=(OutputPyPort *)*iter;
1031 DEBTRACE( "port name: " << p->getName() );
1032 DEBTRACE( "port kind: " << p->edGetType()->kind() );
1033 DEBTRACE( "port pos : " << pos );
1034 if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
1036 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
1038 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1045 catch(ConversionException& ex)
1048 PyGILState_Release(gstate);
1049 _errorDetails=ex.what();
1052 DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
1055 PyGILState_Release(gstate);
1056 DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
1059 Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const
1061 return new PyFuncNode(*this,father);
1064 //! Create a new node of same type with a given name
1065 PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
1067 PyFuncNode* n=new PyFuncNode(name);
1068 n->setScript(_script);
1069 n->setFname(_fname);
1070 list<InputPort *>::iterator iter;
1071 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
1073 InputPyPort *p=(InputPyPort *)*iter;
1074 n->edAddInputPort(p->getName(),p->edGetType());
1076 list<OutputPort *>::iterator iter2;
1077 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
1079 OutputPyPort *p=(OutputPyPort *)*iter2;
1080 n->edAddOutputPort(p->getName(),p->edGetType());
1085 std::string PyFuncNode::getContainerLog()
1087 if(_mode=="local")return "";
1092 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
1093 CORBA::String_var logname = objContainer->logfilename();
1096 std::string::size_type pos = msg.find(":");
1097 msg=msg.substr(pos+1);
1101 msg = "Container no longer reachable";
1106 void PyFuncNode::shutdown(int level)
1108 DEBTRACE("PyFuncNode::shutdown " << level);
1109 if(_mode=="local")return;
1112 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
1113 _pynode=Engines::PyNode::_nil();
1114 _container->shutdown(level);