From: Ovidiu Mircescu Date: Fri, 8 Jan 2016 10:16:07 +0000 (+0100) Subject: Addition of MPIComponent X-Git-Tag: V8_1_0a1~8 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4c7c0d74db670e5b706e13966e368bdfbdaeedd4;p=tools%2Fyacsgen.git Addition of MPIComponent --- diff --git a/module_generator/__init__.py b/module_generator/__init__.py index 1485a36..1e91274 100644 --- a/module_generator/__init__.py +++ b/module_generator/__init__.py @@ -33,3 +33,4 @@ from hxxparacompo import HXX2SALOMEParaComponent from yacstypes import add_type from salomemodules import add_module from gener import Library +from mpicompo import MPIComponent diff --git a/module_generator/cata_tmpl.py b/module_generator/cata_tmpl.py index 2b48b43..14a88cf 100644 --- a/module_generator/cata_tmpl.py +++ b/module_generator/cata_tmpl.py @@ -28,12 +28,9 @@ idl=""" #ifndef _${module}_IDL_ #define _${module}_IDL_ -#include "DSC_Engines.idl" #include "SALOME_Exception.idl" -#include "SALOME_PACOExtension.idl" #include "SALOME_Component.idl" #include "SALOME_Comm.idl" -#include "SALOME_Parametric.idl" ${idldefs} diff --git a/module_generator/cpp_tmpl.py b/module_generator/cpp_tmpl.py index 6c937e1..ad2c65c 100644 --- a/module_generator/cpp_tmpl.py +++ b/module_generator/cpp_tmpl.py @@ -444,11 +444,6 @@ SET(_link_LIBRARIES $${KERNEL_SalomeIDLKernel} $${KERNEL_OpUtil} $${KERNEL_SalomeContainer} - $${KERNEL_SalomeDSCContainer} - $${KERNEL_SalomeDSCSuperv} - $${KERNEL_SalomeDatastream} - $${KERNEL_SalomeDSCSupervBasic} - $${KERNEL_CalciumC} SalomeIDL${module} ${libs} ) diff --git a/module_generator/cppcompo.py b/module_generator/cppcompo.py index e3cfc5a..2902773 100644 --- a/module_generator/cppcompo.py +++ b/module_generator/cppcompo.py @@ -121,6 +121,14 @@ class CPPComponent(Component): return a dict where key is the file name and value is the file content """ (cmake_text, cmake_vars) = self.additionalLibraries() + # DSC_libs are needed for datastream ports only + DSC_libs = """${KERNEL_SalomeDSCContainer} + ${KERNEL_SalomeDSCSuperv} + ${KERNEL_SalomeDatastream} + ${KERNEL_SalomeDSCSupervBasic} + ${KERNEL_CalciumC} + """ + cmake_vars = DSC_libs + cmake_vars cxxfile = "%s.cxx" % self.name hxxfile = "%s.hxx" % self.name if self.kind == "exe": diff --git a/module_generator/gener.py b/module_generator/gener.py index 1473b8d..4487248 100644 --- a/module_generator/gener.py +++ b/module_generator/gener.py @@ -32,7 +32,7 @@ class Invalid(Exception): debug=0 from mod_tmpl import * -from cata_tmpl import catalog, interface, idl, parallel_interface +from cata_tmpl import catalog, interface, idl from cata_tmpl import xml, xml_interface, xml_service from cata_tmpl import idlMakefilePaCO_BUILT_SOURCES, idlMakefilePaCO_nodist_salomeinclude_HEADERS from cata_tmpl import idlMakefilePACO_salomepython_DATA, idlMakefilePACO_salomeidl_DATA @@ -206,6 +206,47 @@ class Component(object): def setPrerequisites(self, prerequisites_file): self.prerequisites = prerequisites_file + def getIdlInterfaces(self): + services = self.getIdlServices() + inheritedinterface="" + if self.inheritedinterface: + inheritedinterface=self.inheritedinterface+"," + return interface.substitute(component=self.name, + services="\n".join(services), + inheritedinterface=inheritedinterface) + + def getIdlServices(self): + services = [] + for serv in self.services: + params = [] + for name, typ in serv.inport: + if typ == "file":continue #files are not passed through IDL interface + if self.impl in ("PY", "ASTER") and typ == "pyobj": + typ = "Engines::fileBlock" + else: + typ=idlTypes[typ] + params.append("in %s %s" % (typ, name)) + for name, typ in serv.outport: + if typ == "file":continue #files are not passed through IDL interface + if self.impl in ("PY", "ASTER") and typ == "pyobj": + typ = "Engines::fileBlock" + else: + typ=idlTypes[typ] + params.append("out %s %s" % (typ, name)) + service = " %s %s(" % (idlTypes[serv.ret],serv.name) + service = service+",".join(params)+") raises (SALOME::SALOME_Exception);" + services.append(service) + return services + + def getIdlDefs(self): + idldefs = """ +#include "DSC_Engines.idl" +#include "SALOME_Parametric.idl" +""" + if self.interfacedefs: + idldefs = idldefs + self.interfacedefs + return idldefs + class Service(object): """ A :class:`Service` instance represents a component service with dataflow and datastream ports. @@ -708,77 +749,26 @@ class Generator(object): def makeidl(self): """generate module IDL file source (CORBA interface)""" - from pacocompo import PACOComponent interfaces = [] idldefs="" for compo in self.module.components: - if isinstance(compo, PACOComponent): - services = [] - for serv in compo.services: - params = [] - for name, typ in serv.inport: - if typ == "file":continue #files are not passed through IDL interface - params.append("in %s %s" % (idlTypes[typ], name)) - for name, typ in serv.outport: - if typ == "file":continue #files are not passed through IDL interface - params.append("out %s %s" % (idlTypes[typ], name)) - service = " void %s(" % serv.name - service = service+",".join(params)+");" - services.append(service) - - interfaces.append(parallel_interface.substitute(component=compo.name, services="\n".join(services))) - - else: - services = [] - for serv in compo.services: - params = [] - for name, typ in serv.inport: - if typ == "file":continue #files are not passed through IDL interface - if compo.impl in ("PY", "ASTER") and typ == "pyobj": - typ = "Engines::fileBlock" - else: - typ=idlTypes[typ] - params.append("in %s %s" % (typ, name)) - for name, typ in serv.outport: - if typ == "file":continue #files are not passed through IDL interface - if compo.impl in ("PY", "ASTER") and typ == "pyobj": - typ = "Engines::fileBlock" - else: - typ=idlTypes[typ] - params.append("out %s %s" % (typ, name)) - service = " %s %s(" % (idlTypes[serv.ret],serv.name) - service = service+",".join(params)+") raises (SALOME::SALOME_Exception);" - services.append(service) - - from hxxcompo import HXX2SALOMEComponent - from hxxparacompo import HXX2SALOMEParaComponent - if isinstance(compo,HXX2SALOMEComponent) or isinstance(compo,HXX2SALOMEParaComponent): - from hxx_tmpl import interfaceidlhxx - Inherited="" - if isinstance(compo,HXX2SALOMEParaComponent): - Inherited="SALOME_MED::ParaMEDMEMComponent" - idldefs="""#include "ParaMEDMEMComponent.idl"\n""" - else: - if compo.use_medmem==True: - Inherited="Engines::EngineComponent,SALOME::MultiCommClass,SALOME_MED::MED_Gen_Driver" - else: - Inherited="Engines::EngineComponent" - interfaces.append(interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services))) - else: - inheritedinterface="" - if compo.inheritedinterface: - inheritedinterface=compo.inheritedinterface+"," - interfaces.append(interface.substitute(component=compo.name, services="\n".join(services),inheritedinterface=inheritedinterface)) + interfaces.append(compo.getIdlInterfaces()) #build idl includes for SALOME modules for mod in self.used_modules: idldefs = idldefs + salome_modules[mod]["idldefs"] for compo in self.module.components: - if compo.interfacedefs: - idldefs = idldefs + compo.interfacedefs - - return idl.substitute(module=self.module.name, interfaces='\n'.join(interfaces),idldefs=idldefs) + idldefs = idldefs + compo.getIdlDefs() + + filteredDefs = [] + for defLine in idldefs.split('\n'): + if defLine not in filteredDefs: + filteredDefs.append(defLine) + + return idl.substitute(module=self.module.name, + interfaces='\n'.join(interfaces), + idldefs='\n'.join(filteredDefs) ) # For PaCO++ def makexml(self): diff --git a/module_generator/hxxcompo.py b/module_generator/hxxcompo.py index 94d8220..41aae04 100644 --- a/module_generator/hxxcompo.py +++ b/module_generator/hxxcompo.py @@ -526,3 +526,14 @@ class HXX2SALOMEComponent(Component): gui_salomeapp_file.close() list_of_gui_names.append(gui_salomeapp_file_name) return list_of_gui_names + + def getIdlInterfaces(self): + services = self.getIdlServices() + from hxx_tmpl import interfaceidlhxx + Inherited="" + if compo.use_medmem==True: + Inherited="Engines::EngineComponent,SALOME::MultiCommClass,SALOME_MED::MED_Gen_Driver" + else: + Inherited="Engines::EngineComponent" + return interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services)) + diff --git a/module_generator/hxxparacompo.py b/module_generator/hxxparacompo.py index 1d59a12..b27d003 100644 --- a/module_generator/hxxparacompo.py +++ b/module_generator/hxxparacompo.py @@ -471,3 +471,10 @@ void *th_%(serv_name)s(void *s) servicesimpl="\n".join(services), thread_impl=self.thread_impl % {"module":gen.module.name} ) + def getIdlInterfaces(self): + services = self.getIdlServices() + from hxx_tmpl import interfaceidlhxx + Inherited="" + Inherited="SALOME_MED::ParaMEDMEMComponent" + idldefs="""#include "ParaMEDMEMComponent.idl"\n""" + return interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services)) diff --git a/module_generator/mpi_tmpl.py b/module_generator/mpi_tmpl.py new file mode 100644 index 0000000..6ce3172 --- /dev/null +++ b/module_generator/mpi_tmpl.py @@ -0,0 +1,317 @@ +# Copyright (C) 2009-2015 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +try: + from string import Template +except: + from compat import Template,set + +# cxx file of a MPI component. +# template parameters: +# component : component name +# servicesdef : extra "#include" +# servicesimpl : services implementations +cxxCompo=""" +#include "${component}.hxx" +#include +#include +#include +#include +#include +#include "Utils_CorbaException.hxx" +#include +#include + +typedef struct +{ + bool exception; + std::string msg; +} exception_st; + +//DEFS +${servicesdef} +//ENDDEF + + +using namespace std; + +//! Constructor for component "${component}" instance +/*! + * + */ +${component}_i::${component}_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName, + bool regist) + : Engines_Component_i(orb, poa, contId, instanceName, interfaceName, + false, regist) +{ + _thisObj = this ; + _id = _poa->activate_object(_thisObj); +} + +${component}_i::${component}_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, + const char *interfaceName, + bool regist) + : Engines_Component_i(orb, poa, container, instanceName, interfaceName, + false, regist) +{ + _thisObj = this ; + _id = _poa->activate_object(_thisObj); +} + +//! Destructor for component "${component}" instance +${component}_i::~${component}_i() +{ +} + +${servicesimpl} + +extern "C" +{ + PortableServer::ObjectId * ${component}Engine_factory( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + MESSAGE("PortableServer::ObjectId * ${component}Engine_factory()"); + int is_mpi_container; + bool regist; + int numproc; + + MPI_Initialized(&is_mpi_container); + if (!is_mpi_container) + { + int argc = 0; + char ** argv = NULL; + MPI_Init(&argc, &argv); + } + + MPI_Comm_rank( MPI_COMM_WORLD, &numproc ); + if( numproc == 0 ) + regist = true; + else + regist = false; + ${component}_i * myEngine = new ${component}_i(orb, poa, contId, instanceName, interfaceName, regist); + return myEngine->getId() ; + } +} +""" +cxxCompo=Template(cxxCompo) + +# Header file of a MPI component +# template parameters: +# component : component name +# module : module name +# compodefs : additional "#include" and other specific declarations +# servicesdef : declaration of component services +hxxCompo=""" +#ifndef _${component}_HXX_ +#define _${component}_HXX_ + +#include +#include "Superv_Component_i.hxx" +#include "${module}.hh" +#include "MPIObject_i.hxx" + +//COMPODEFS +${compodefs} +//ENDDEF + +class ${component}_i: public virtual POA_${module}_ORB::${component}, + ${inheritedclass} + public virtual MPIObject_i, + public virtual Engines_Component_i +{ + public: + ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, const char *interfaceName, + bool regist = true); + ${component}_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, + Engines::Container_ptr container, + const char *instanceName, const char *interfaceName, + bool regist = true); + virtual ~${component}_i(); +${servicesdef} +}; + +extern "C" +{ + PortableServer::ObjectId * ${component}Engine_factory( CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); +} +#endif + +""" +hxxCompo=Template(hxxCompo) + +# Declaration of the thread function to run a MPI service. +# template parameters: +# service : name of the service. +# input_vals : declarations of input ports of the service. +hxxThreadService=""" +void * th_${service}(void * s); +typedef struct { + int ip; // mpi process id + Engines::IORTab* tior; + ${input_vals} +} thread_${service}_struct; + +""" +hxxThreadService=Template(hxxThreadService) + +# Body of a service. +# template parameters: +# module : module name +# component : component name +# service : service name +# out_vals : declaration of output ports ("type1 name1;\ntype2 name2;") +# service_call : +# in_vals : copy of input ports to thread structure +# parameters : list of parameters ("type1 name1, type2 name2") +# body : user body +cxxService=""" +void * th_${service}(void * s) +{ + std::ostringstream msg; + exception_st *est = new exception_st; + est->exception = false; + + thread_${service}_struct *st = (thread_${service}_struct *)s; + + try + { + ${out_vals} + ${module}_ORB::${component}_var compo = ${module}_ORB::${component}::_narrow((*(st->tior))[st->ip]); + compo->${service_call}; + } + catch(const SALOME::SALOME_Exception &ex) + { + est->exception = true; + est->msg = ex.details.text; + } + catch(const CORBA::Exception &ex) + { + est->exception = true; + msg << "CORBA::Exception: " << ex; + est->msg = msg.str(); + } + + delete st; + return ((void*)est); +} + +void ${component}_i::${service}(${parameters}) +{ + beginService("${component}_i::${service}"); + void *ret_th; + pthread_t *th; + exception_st *est; + + try + { + // Run the service in every MPI process + if(_numproc == 0) + { + th = new pthread_t[_nbproc]; + for(int ip=1;ip<_nbproc;ip++) + { + thread_${service}_struct *st = new thread_${service}_struct; + st->ip = ip; + st->tior = _tior; + ${in_vals} + pthread_create(&(th[ip]),NULL,th_${service},(void*)st); + } + } + +//BODY +${body} +//ENDBODY + if(_numproc == 0) + { + for(int ip=1;ip<_nbproc;ip++) + { + pthread_join(th[ip],&ret_th); + est = (exception_st*)ret_th; + if(est->exception) + { + std::ostringstream msg; + msg << "[" << ip << "] " << est->msg; + delete est; + delete[] th; + THROW_SALOME_CORBA_EXCEPTION(msg.str().c_str(),SALOME::INTERNAL_ERROR); + } + delete est; + } + delete[] th; + } + } + catch ( const SALOME_Exception & ex) + { + THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(ex.what()), SALOME::INTERNAL_ERROR); +/* SALOME::ExceptionStruct es; + es.text=CORBA::string_dup(ex.what()); + es.type=SALOME::INTERNAL_ERROR; + throw SALOME::SALOME_Exception(es);*/ + } + catch ( const SALOME::SALOME_Exception & ex) + { + throw; + } + catch ( const std::exception& ex) + { + THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(ex.what()), SALOME::INTERNAL_ERROR); +/* //std::cerr << typeid(ex).name() << std::endl; + SALOME::ExceptionStruct es; + es.text=CORBA::string_dup(ex.what()); + es.type=SALOME::INTERNAL_ERROR; + throw SALOME::SALOME_Exception(es);*/ + } + catch (...) + { + THROW_SALOME_CORBA_EXCEPTION("unknown exception", SALOME::INTERNAL_ERROR); +/* std::cerr << "unknown exception" << std::endl; + SALOME::ExceptionStruct es; + es.text=CORBA::string_dup(" unknown exception"); + es.type=SALOME::INTERNAL_ERROR; + throw SALOME::SALOME_Exception(es);*/ + } + endService("${component}_i::${service}"); +} + +""" +cxxService=Template(cxxService) + +interface=""" + interface ${component}:${inheritedinterface} Engines::MPIObject, Engines::EngineComponent + { +${services} + }; +""" +interface=Template(interface) \ No newline at end of file diff --git a/module_generator/mpicompo.py b/module_generator/mpicompo.py new file mode 100644 index 0000000..21b20ad --- /dev/null +++ b/module_generator/mpicompo.py @@ -0,0 +1,211 @@ +# Copyright (C) 2009-2015 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +""" + Module that defines CPPComponent for SALOME components implemented in C++ +""" + +import os +from gener import Component, Invalid +from cpp_tmpl import initService, cxxService, hxxCompo, cxxCompo +from cpp_tmpl import exeCPP, cmake_src_compo_cpp +from yacstypes import corba_rtn_type, corba_in_type +import mpi_tmpl +from cppcompo import CPPComponent + +try: + from string import Template +except: + from compat import Template,set + +class MPIComponent(CPPComponent): + """ + A :class:`MPIComponent` instance represents a C++ SALOME component with services given as a list of :class:`Service` + instances with the parameter *services*. + + :param name: gives the name of the component. + :type name: str + :param services: the list of services (:class:`Service`) of the component. + :param kind: If it is given and has the value "exe", the component will be built as a standalone + component (executable or shell script). The default is to build the component as a dynamic library. + :param libs: list of the additional libraries. see *Library* class. + If you want to add "libmylib.so", installed in "/path/to/lib" you should use: + libs=[Library(name="mylib", path="/path/to/lib")] + For more advanced features, see the documentation of cmake / FIND_LIBRARY + :param rlibs: space-separated list specifying the rpath to use in installed targets + :param includes: additional include directories, separated by spaces. + :param sources: gives all the external source files to add in the compilation step (list of paths). + :param exe_path: is only used when kind is "exe" and gives the path to the standalone component. + :param compodefs: can be used to add extra definition code in the component for example when using a base class + to define the component class by deriving it (see *inheritedclass* parameter) + :param inheritedclass: can be used to define a base class for the component. The base class can be defined in external + source or with the *compodefs* parameter. The value of the *inheritedclass* parameter is the name of the base class. + :param idls: can be used to add extra idl CORBA interfaces to the component. This parameter must gives a list of idl file + names that are added into the generated module (idl directory) and compiled with the generated idl of the module. + :param interfacedefs: can be used to add idl definitions (or includes of idl files) into the generated idl of the module. + :param inheritedinterface: can be used to make the component inherit an extra idl interface that has been included through + the *idls* and *interfacedefs* parameters. See the cppgui1 example for how to use these last parameters. + :param addedmethods: is a C++ specific parameter that can be used to redefine a component method (DumpPython for example). This + parameter is a string that must contain the definition and implementation code of the method. See the cppgui1 example + for how to use it. + + For example, the following call defines a standalone component named "mycompo" with one service s1 (it must have been defined before):: + + >>> c1 = module_generator.CPPComponent('mycompo', services=[s1,], kind="exe", + exe_path="./launch.sh") + """ + def __init__(self, name, services=None, libs=[], rlibs="", includes="", kind="lib", + exe_path=None, sources=None, inheritedclass="", compodefs="", + idls=None,interfacedefs="",inheritedinterface="",addedmethods=""): + self.exe_path = exe_path + Component.__init__(self, name, services, impl="CPP", libs=libs, rlibs=rlibs, + includes=includes, kind=kind, sources=sources, + inheritedclass=inheritedclass, compodefs=compodefs, idls=idls, + interfacedefs=interfacedefs, inheritedinterface=inheritedinterface, + addedmethods=addedmethods) + + def validate(self): + """ validate component definition parameters""" + Component.validate(self) + kinds = ("lib") + if self.kind not in kinds: + raise Invalid("kind must be one of %s for component %s" % (kinds,self.name)) + + def libraryName(self): + """ Name of the target library + """ + ret="" + if self.kind == "lib": + ret = self.name + "Engine" + else: + raise Invalid("Invalid kind of component: %s. Supported kinds are 'lib' and 'exe'" % self.name) + return ret + + def makeCompo(self, gen): + """generate files for C++ component + + return a dict where key is the file name and value is the file content + """ + (cmake_text, cmake_vars) = self.additionalLibraries() + cmake_vars = "${KERNEL_SalomeMPIContainer}\n " + cmake_vars + cxxfile = "%s.cxx" % self.name + hxxfile = "%s.hxx" % self.name + if self.kind == "exe": + exe_opt = 1 + else: + exe_opt = 0 + ret = { cxxfile:self.makecxx(gen, exe_opt), + hxxfile:self.makehxx(gen) + } + sources = " ".join(map(os.path.basename,self.sources)) + cmakelist_content = cmake_src_compo_cpp.substitute( + module = gen.module.name, + component = self.name, + componentlib = self.libraryName(), + includes = self.includes, + sources = sources, + libs = cmake_vars, + find_libs = cmake_text, + target_properties = self.targetProperties()) + + ret["CMakeLists.txt"] = cmakelist_content + + return ret + + def makeThServiceDeclaration(self, service, module_name): + inputVals = [] + for port in service.inport: + name, typ = service.validatePort(port) + inputVals.append("%s %s;" % (corba_in_type(typ, module_name), name )) + return mpi_tmpl.hxxThreadService.substitute(service=service.name, + input_vals="\n".join(inputVals)) + + def makehxx(self, gen): + """return a string that is the content of .hxx file + """ + services = [] + compodefs=self.compodefs + for serv in self.services: + service = " %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),serv.name) + service = service+gen.makeArgs(serv)+");" + services.append(service) + compodefs = compodefs + self.makeThServiceDeclaration(serv,gen.module.name) + + if self.addedmethods: + services.append(self.addedmethods) + servicesdef = "\n".join(services) + + inheritedclass=self.inheritedclass + if self.inheritedclass: + inheritedclass= " public virtual " + self.inheritedclass + "," + + return mpi_tmpl.hxxCompo.substitute(component=self.name, module=gen.module.name, + servicesdef=servicesdef, inheritedclass=inheritedclass, + compodefs=compodefs) + + def makecxx(self, gen, exe=0): + """return a string that is the content of .cxx file + """ + services = [] + inits = [] + defs = [] + for serv in self.services: + defs.append(serv.defs) + in_vals = [] + out_vals = [] + call_params = [] + for name, typ in serv.inport: + in_vals.append("st->%s = %s;" % (name, name )) + call_params.append("st->%s" % name) + + for name, typ in serv.outport: + out_vals.append("%s %s;" % (corba_in_type(typ, gen.module.name), name )) + call_params.append(name) + + service_call = "%s(%s)" % (serv.name, ",".join(call_params)) + + service = mpi_tmpl.cxxService.substitute(module=gen.module.name, + component=self.name, service=serv.name, + out_vals="\n".join(out_vals), + service_call=service_call, + in_vals="\n".join(in_vals), + parameters=gen.makeArgs(serv), + body=serv.body) + services.append(service) + + return mpi_tmpl.cxxCompo.substitute(component=self.name, + servicesdef="\n".join(defs), + servicesimpl="\n".join(services)) + + def getIdlInterfaces(self): + services = self.getIdlServices() + inheritedinterface="" + if self.inheritedinterface: + inheritedinterface=self.inheritedinterface+"," + return mpi_tmpl.interface.substitute(component=self.name, + services="\n".join(services), + inheritedinterface=inheritedinterface) + + def getIdlDefs(self): + idldefs = """ +#include "SALOME_MPIObject.idl" +""" + if self.interfacedefs: + idldefs = idldefs + self.interfacedefs + return idldefs diff --git a/module_generator/pacocompo.py b/module_generator/pacocompo.py index 54cb208..7ccdb78 100644 --- a/module_generator/pacocompo.py +++ b/module_generator/pacocompo.py @@ -32,6 +32,7 @@ from paco_tmpl import cxxFactoryDummy, cxxFactoryMpi, cxx_des_parallel_stream from paco_tmpl import hxxparallel_instream, hxxparallel_outstream, hxxinit_ok from paco_tmpl import hxxparallel_instream_init, hxxparallel_outstream_init, cxxService_connect from paco_tmpl import cxx_cons_service, cxx_cons_parallel_outstream, cxx_cons_parallel_instream +from cata_tmpl import parallel_interface class PACOComponent(Component): @@ -165,3 +166,29 @@ class PACOComponent(Component): return cxxfile + def getIdlServices(self): + services = [] + for serv in self.services: + params = [] + for name, typ in serv.inport: + if typ == "file":continue #files are not passed through IDL interface + params.append("in %s %s" % (idlTypes[typ], name)) + for name, typ in serv.outport: + if typ == "file":continue #files are not passed through IDL interface + params.append("out %s %s" % (idlTypes[typ], name)) + service = " void %s(" % serv.name + service = service+",".join(params)+");" + services.append(service) + return services + + def getIdlInterfaces(self): + services = self.getIdlServices() + return parallel_interface.substitute(component=self.name, services="\n".join(services)) + + def getIdlDefs(self): + idldefs = """ +#include "SALOME_PACOExtension.idl" +""" + if self.interfacedefs: + idldefs = idldefs + self.interfacedefs + return idldefs