1 // Copyright (C) 2006-2013 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.
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);
429 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
435 PyObject* new_stderr = newPyStdOut(_errorDetails);
436 PySys_SetObject((char*)"stderr", new_stderr);
437 ofstream errorfile(stream.str().c_str());
438 if (errorfile.is_open())
440 errorfile << _script;
444 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
445 Py_DECREF(new_stderr);
447 PyGILState_Release(gstate);
448 throw Exception("Error during execution");
452 DEBTRACE( "-----------------PyNode::outputs-----------------" );
453 list<OutputPort *>::iterator iter;
456 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
458 OutputPyPort *p=(OutputPyPort *)*iter;
459 DEBTRACE( "port name: " << p->getName() );
460 DEBTRACE( "port kind: " << p->edGetType()->kind() );
461 PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str());
463 PyGILState_Release(gstate);
464 std::string msg="Error during execution: there is no variable ";
465 msg=msg+p->getName()+" in node context";
467 throw Exception(msg);
469 DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt );
471 PyObject_Print(ob,stderr,Py_PRINT_RAW);
477 catch(ConversionException& ex)
479 PyGILState_Release(gstate);
480 _errorDetails=ex.what();
484 DEBTRACE( "-----------------End PyNode::outputs-----------------" );
485 PyGILState_Release(gstate);
486 DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" );
489 std::string PythonNode::getContainerLog()
491 if(_mode=="local")return "";
496 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
497 CORBA::String_var logname = objContainer->logfilename();
500 std::string::size_type pos = msg.find(":");
501 msg=msg.substr(pos+1);
505 msg = "Container no longer reachable";
510 void PythonNode::shutdown(int level)
512 DEBTRACE("PythonNode::shutdown " << level);
513 if(_mode=="local")return;
516 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
517 _pynode=Engines::PyScriptNode::_nil();
518 _container->shutdown(level);
522 Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const
524 return new PythonNode(*this,father);
527 //! Create a new node of same type with a given name
528 PythonNode* PythonNode::cloneNode(const std::string& name)
530 PythonNode* n=new PythonNode(name);
531 n->setScript(_script);
532 list<InputPort *>::iterator iter;
533 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
535 InputPyPort *p=(InputPyPort *)*iter;
536 DEBTRACE( "port name: " << p->getName() );
537 DEBTRACE( "port kind: " << p->edGetType()->kind() );
538 n->edAddInputPort(p->getName(),p->edGetType());
540 list<OutputPort *>::iterator iter2;
541 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
543 OutputPyPort *p=(OutputPyPort *)*iter2;
544 DEBTRACE( "port name: " << p->getName() );
545 DEBTRACE( "port kind: " << p->edGetType()->kind() );
546 n->edAddOutputPort(p->getName(),p->edGetType());
551 PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0)
553 _implementation = PythonNode::IMPL_NAME;
554 PyGILState_STATE gstate = PyGILState_Ensure();
555 _context=PyDict_New();
556 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
557 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
560 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
561 _errorDetails=msg.str();
562 PyGILState_Release(gstate);
563 throw Exception(msg.str());
565 PyGILState_Release(gstate);
568 PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0)
571 _implementation = PythonNode::IMPL_NAME;
572 DEBTRACE( "PyFuncNode::PyFuncNode " << name );
573 PyGILState_STATE gstate = PyGILState_Ensure();
574 _context=PyDict_New();
575 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
576 if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() ))
579 msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__;
580 _errorDetails=msg.str();
581 PyGILState_Release(gstate);
582 throw Exception(msg.str());
584 PyGILState_Release(gstate);
587 PyFuncNode::~PyFuncNode()
589 DEBTRACE( getName() );
590 PyGILState_STATE gstate = PyGILState_Ensure();
591 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
592 if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
594 PyGILState_Release(gstate);
595 if(!CORBA::is_nil(_pynode))
597 _pynode->UnRegister();
601 void PyFuncNode::checkBasicConsistency() const throw(YACS::Exception)
603 DEBTRACE("checkBasicConsistency");
604 InlineFuncNode::checkBasicConsistency();
606 PyGILState_STATE gstate = PyGILState_Ensure();
608 res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input);
611 std::string error="";
612 PyObject* new_stderr = newPyStdOut(error);
613 PySys_SetObject((char*)"stderr", new_stderr);
615 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
616 Py_DECREF(new_stderr);
617 PyGILState_Release(gstate);
618 throw Exception(error);
622 PyGILState_Release(gstate);
625 void PyFuncNode::load()
627 DEBTRACE( "---------------PyfuncNode::load function---------------" );
634 void PyFuncNode::loadRemote()
636 DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" );
639 if(!_container->isAlreadyStarted(0))
643 _container->start(0);
647 _errorDetails=e.what();
654 std::string what("PyFuncNode::loadRemote : a load operation requested on \"");
655 what+=_name; what+="\" with no container specified.";
657 throw Exception(what);
660 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
663 _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str());
665 catch( const SALOME::SALOME_Exception& ex )
667 std::string msg="Exception on remote python node creation ";
669 msg += ex.details.text.in();
671 throw Exception(msg);
674 PyGILState_STATE gstate = PyGILState_Ensure();
675 const char picklizeScript[]="import cPickle\n"
676 "def pickleForDistPyth2009(*args,**kws):\n"
677 " return cPickle.dumps((args,kws),-1)\n"
679 "def unPickleForDistPyth2009(st):\n"
680 " args=cPickle.loads(st)\n"
682 PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context);
686 PyObject* new_stderr = newPyStdOut(_errorDetails);
687 PySys_SetObject((char*)"stderr", new_stderr);
689 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
690 Py_DECREF(new_stderr);
692 PyGILState_Release(gstate);
693 throw Exception("Error during load");
697 _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009");
698 _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009");
699 if(_pyfuncSer == NULL)
702 PyObject* new_stderr = newPyStdOut(_errorDetails);
703 PySys_SetObject((char*)"stderr", new_stderr);
705 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
706 Py_DECREF(new_stderr);
708 PyGILState_Release(gstate);
709 throw Exception("Error during load");
711 if(_pyfuncUnser == NULL)
714 PyObject* new_stderr = newPyStdOut(_errorDetails);
715 PySys_SetObject((char*)"stderr", new_stderr);
717 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
718 Py_DECREF(new_stderr);
720 PyGILState_Release(gstate);
721 throw Exception("Error during load");
723 DEBTRACE( "---------------End PyfuncNode::loadRemote function---------------" );
724 PyGILState_Release(gstate);
727 void PyFuncNode::loadLocal()
729 DEBTRACE( "---------------PyFuncNode::load function " << getName() << " ---------------" );
733 list<OutputPort *>::iterator iter;
734 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
736 OutputPyPort *p=(OutputPyPort *)*iter;
737 DEBTRACE( "port name: " << p->getName() );
738 DEBTRACE( "port kind: " << p->edGetType()->kind() );
742 PyGILState_STATE gstate = PyGILState_Ensure();
743 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
745 std::ostringstream stream;
746 stream << "/tmp/PythonNode_";
749 PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input);
753 PyObject* new_stderr = newPyStdOut(_errorDetails);
754 PySys_SetObject((char*)"stderr", new_stderr);
756 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
757 Py_DECREF(new_stderr);
758 PyGILState_Release(gstate);
759 throw Exception("Error during execution");
761 PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context);
764 DEBTRACE( "_context refcnt: " << _context->ob_refcnt );
768 PyObject* new_stderr = newPyStdOut(_errorDetails);
769 PySys_SetObject((char*)"stderr", new_stderr);
770 ofstream errorfile(stream.str().c_str());
771 if (errorfile.is_open())
773 errorfile << _script;
777 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
778 Py_DECREF(new_stderr);
780 PyGILState_Release(gstate);
781 throw Exception("Error during execution");
785 _pyfunc=PyDict_GetItemString(_context,_fname.c_str());
786 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
790 PyObject* new_stderr = newPyStdOut(_errorDetails);
791 PySys_SetObject((char*)"stderr", new_stderr);
793 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
794 Py_DECREF(new_stderr);
796 PyGILState_Release(gstate);
797 throw Exception("Error during execution");
799 DEBTRACE( "---------------End PyFuncNode::load function---------------" );
800 PyGILState_Release(gstate);
803 void PyFuncNode::execute()
811 void PyFuncNode::executeRemote()
813 DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
815 throw Exception("DistributedPythonNode badly loaded");
816 PyGILState_STATE gstate = PyGILState_Ensure();
818 //===========================================================================
819 // Get inputs in input ports, build a Python tuple and pickle it
820 //===========================================================================
822 PyObject* args = PyTuple_New(getNumberOfInputPorts());
823 std::list<InputPort *>::iterator iter2;
825 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
827 InputPyPort *p=(InputPyPort *)*iter2;
830 PyTuple_SetItem(args,pos,ob);
834 PyObject_Print(args,stderr,Py_PRINT_RAW);
837 PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
838 //The pickled string may contain NULL characters so use PyString_AsStringAndSize
839 char* serializationInputC;
841 if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
843 PyGILState_Release(gstate);
844 throw Exception("DistributedPythonNode problem in python pickle");
846 PyGILState_Release(gstate);
848 Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
849 serializationInputCorba->length(len);
850 for(int i=0; i < len ; i++)
851 serializationInputCorba[i]=serializationInputC[i];
853 //===========================================================================
854 // Execute in remote Python node
855 //===========================================================================
856 DEBTRACE( "-----------------starting remote python invocation-----------------" );
857 Engines::pickledArgs_var resultCorba;
860 resultCorba=_pynode->execute(getFname().c_str(),serializationInputCorba);
862 catch( const SALOME::SALOME_Exception& ex )
864 std::string msg="Exception on remote python invocation";
866 msg += ex.details.text.in();
868 throw Exception(msg);
870 DEBTRACE( "-----------------end of remote python invocation-----------------" );
871 //===========================================================================
872 // Get results, unpickle and put them in output ports
873 //===========================================================================
874 char *resultCorbaC=new char[resultCorba->length()+1];
875 resultCorbaC[resultCorba->length()]='\0';
876 for(int i=0;i<resultCorba->length();i++)
877 resultCorbaC[i]=resultCorba[i];
879 gstate = PyGILState_Ensure();
881 PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
882 delete [] resultCorbaC;
883 args = PyTuple_New(1);
884 PyTuple_SetItem(args,0,resultPython);
885 PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
888 DEBTRACE( "-----------------PythonNode::outputs-----------------" );
890 if(finalResult == Py_None)
892 else if(PyTuple_Check(finalResult))
893 nres=PyTuple_Size(finalResult);
895 if(getNumberOfOutputPorts() != nres)
897 std::string msg="Number of output arguments : Mismatch between definition and execution";
898 Py_DECREF(finalResult);
899 PyGILState_Release(gstate);
901 throw Exception(msg);
905 std::list<OutputPort *>::iterator iter;
908 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
910 OutputPyPort *p=(OutputPyPort *)*iter;
911 DEBTRACE( "port name: " << p->getName() );
912 DEBTRACE( "port kind: " << p->edGetType()->kind() );
913 DEBTRACE( "port pos : " << pos );
914 if(PyTuple_Check(finalResult))
915 ob=PyTuple_GetItem(finalResult,pos) ;
918 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
922 Py_DECREF(finalResult);
924 catch(ConversionException& ex)
926 Py_DECREF(finalResult);
927 PyGILState_Release(gstate);
928 _errorDetails=ex.what();
932 PyGILState_Release(gstate);
934 DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
937 void PyFuncNode::executeLocal()
939 DEBTRACE( "++++++++++++++ PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
943 if(!_pyfunc)throw Exception("PyFuncNode badly loaded");
944 PyGILState_STATE gstate = PyGILState_Ensure();
946 DEBTRACE( "---------------PyFuncNode::inputs---------------" );
947 PyObject* args = PyTuple_New(getNumberOfInputPorts()) ;
948 list<InputPort *>::iterator iter2;
949 for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
951 InputPyPort *p=(InputPyPort *)*iter2;
952 DEBTRACE( "port name: " << p->getName() );
953 DEBTRACE( "port kind: " << p->edGetType()->kind() );
956 PyObject_Print(ob,stderr,Py_PRINT_RAW);
959 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
961 PyTuple_SetItem(args,pos,ob);
962 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
965 DEBTRACE( "---------------End PyFuncNode::inputs---------------" );
967 DEBTRACE( "----------------PyFuncNode::calculation---------------" );
969 PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW);
971 PyObject_Print(args,stderr,Py_PRINT_RAW);
974 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
975 PyObject* result = PyObject_CallObject( _pyfunc , args ) ;
976 DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt );
983 PyObject* new_stderr = newPyStdOut(_errorDetails);
984 PySys_SetObject((char*)"stderr", new_stderr);
985 std::ostringstream stream;
986 stream << "/tmp/PythonNode_";
988 ofstream errorfile(stream.str().c_str());
989 if (errorfile.is_open())
991 errorfile << _script;
995 PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
996 Py_DECREF(new_stderr);
998 PyGILState_Release(gstate);
999 throw Exception("Error during execution");
1001 DEBTRACE( "----------------End PyFuncNode::calculation---------------" );
1003 DEBTRACE( "-----------------PyFuncNode::outputs-----------------" );
1005 if(result == Py_None)
1007 else if(PyTuple_Check(result))
1008 nres=PyTuple_Size(result);
1010 if(getNumberOfOutputPorts() != nres)
1012 std::string msg="Number of output arguments : Mismatch between definition and execution";
1014 PyGILState_Release(gstate);
1016 throw Exception(msg);
1021 PyObject_Print(result,stderr,Py_PRINT_RAW);
1024 list<OutputPort *>::iterator iter;
1027 for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
1029 OutputPyPort *p=(OutputPyPort *)*iter;
1030 DEBTRACE( "port name: " << p->getName() );
1031 DEBTRACE( "port kind: " << p->edGetType()->kind() );
1032 DEBTRACE( "port pos : " << pos );
1033 if(PyTuple_Check(result))ob=PyTuple_GetItem(result,pos) ;
1035 DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
1037 PyObject_Print(ob,stderr,Py_PRINT_RAW);
1044 catch(ConversionException& ex)
1047 PyGILState_Release(gstate);
1048 _errorDetails=ex.what();
1051 DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" );
1054 PyGILState_Release(gstate);
1055 DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" );
1058 Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const
1060 return new PyFuncNode(*this,father);
1063 //! Create a new node of same type with a given name
1064 PyFuncNode* PyFuncNode::cloneNode(const std::string& name)
1066 PyFuncNode* n=new PyFuncNode(name);
1067 n->setScript(_script);
1068 n->setFname(_fname);
1069 list<InputPort *>::iterator iter;
1070 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
1072 InputPyPort *p=(InputPyPort *)*iter;
1073 n->edAddInputPort(p->getName(),p->edGetType());
1075 list<OutputPort *>::iterator iter2;
1076 for(iter2 = _setOfOutputPort.begin(); iter2 != _setOfOutputPort.end(); iter2++)
1078 OutputPyPort *p=(OutputPyPort *)*iter2;
1079 n->edAddOutputPort(p->getName(),p->edGetType());
1084 std::string PyFuncNode::getContainerLog()
1086 if(_mode=="local")return "";
1091 Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0);
1092 CORBA::String_var logname = objContainer->logfilename();
1095 std::string::size_type pos = msg.find(":");
1096 msg=msg.substr(pos+1);
1100 msg = "Container no longer reachable";
1105 void PyFuncNode::shutdown(int level)
1107 DEBTRACE("PyFuncNode::shutdown " << level);
1108 if(_mode=="local")return;
1111 if(!CORBA::is_nil(_pynode)) _pynode->UnRegister();
1112 _pynode=Engines::PyNode::_nil();
1113 _container->shutdown(level);