From c0e4c71d91cb51ee610965d78050b3336d3fe11c Mon Sep 17 00:00:00 2001 From: ribes Date: Tue, 21 Jul 2009 09:10:04 +0000 Subject: [PATCH] - Ajout du support de composants PaCO++ --- module_generator/__init__.py | 1 + module_generator/cata_tmpl.py | 72 +++++- module_generator/gener.py | 177 ++++++++++++--- module_generator/mod_tmpl.py | 13 +- module_generator/paco_tmpl.py | 407 ++++++++++++++++++++++++++++++++++ module_generator/pacocompo.py | 163 ++++++++++++++ 6 files changed, 801 insertions(+), 32 deletions(-) create mode 100644 module_generator/paco_tmpl.py create mode 100644 module_generator/pacocompo.py diff --git a/module_generator/__init__.py b/module_generator/__init__.py index 42d4722..e25bec1 100644 --- a/module_generator/__init__.py +++ b/module_generator/__init__.py @@ -6,5 +6,6 @@ from gener import Module, Service, Generator from fcompo import F77Component from cppcompo import CPPComponent +from pacocompo import PACOComponent from pycompo import PYComponent from astcompo import ASTERComponent diff --git a/module_generator/cata_tmpl.py b/module_generator/cata_tmpl.py index cce5dcf..f6ce826 100644 --- a/module_generator/cata_tmpl.py +++ b/module_generator/cata_tmpl.py @@ -11,6 +11,7 @@ idl=""" #include "DSC_Engines.idl" #include "SALOME_Exception.idl" +#include "SALOME_PACOExtension.idl" module ${module} { @@ -33,27 +34,64 @@ ${services} """ interface=Template(interface) +parallel_interface=""" +interface ${component} : Engines::Parallel_DSC + { +${services} + }; +""" +parallel_interface=Template(parallel_interface) + +xml="""\ + + + + + + ${module} +${interfaces} + + +""" +xml = Template(xml) + +xml_interface="""\ + + ${component} +${xml_services} + """ +xml_interface = Template(xml_interface) + +xml_service = """\ + + ${service_name} + distributed + """ +xml_service = Template(xml_service) + idlMakefile=""" include $$(top_srcdir)/adm_local/make_common_starter.am -BUILT_SOURCES = ${module}SK.cc +BUILT_SOURCES = ${module}SK.cc ${PACO_BUILT_SOURCES} IDL_FILES=${module}.idl lib_LTLIBRARIES = lib${module}.la -salomeidl_DATA = $$(IDL_FILES) -salomepython_DATA = ${module}_idl.py +salomeidl_DATA = $$(IDL_FILES) ${PACO_salomeidl_DATA} +salomepython_DATA = ${module}_idl.py ${PACO_salomepython_DATA} lib${module}_la_SOURCES = nodist_lib${module}_la_SOURCES = ${module}SK.cc -nodist_salomeinclude_HEADERS= ${module}.hh +nodist_salomeinclude_HEADERS= ${module}.hh ${PACO_SALOMEINCLUDE_HEADERS} lib${module}_la_CXXFLAGS = -I. $$(KERNEL_INCLUDES) lib${module}_la_LIBADD = $$(KERNEL_LIBS) ########################################################## %SK.cc %.hh : %.idl \t$$(OMNIORB_IDL) -bcxx $$(IDLCXXFLAGS) $$(OMNIORB_IDLCXXFLAGS) $$(IDL_INCLUDES) $$< %_idl.py : %.idl -\t$$(OMNIORB_IDL) -bpython $$(IDL_INCLUDES) $$< +\t$$(OMNIORB_IDL) -bpython $$(IDL_INCLUDES) ${PACO_INCLUDES} $$< +%PaCO.hxx %PaCO.cxx : %.idl %.xml +\t$$(OMNIORB_IDL) -I@KERNEL_ROOT_DIR@/idl/salome -p@PACOPATH@/lib/python -bpaco -Wb$$(top_srcdir)/idl/$$*.xml,$$(srcdir):@PACOPATH@/idl:@KERNEL_ROOT_DIR@/idl/salome $$(top_srcdir)/idl/$$*.idl -CLEANFILES = *.hh *SK.cc *.py +CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx clean-local: \trm -rf ${module} ${module}__POA @@ -68,6 +106,17 @@ uninstall-local: """ idlMakefile=Template(idlMakefile) +# PACO Part +idlMakefilePaCO_BUILT_SOURCES = "${module}PaCO.cxx " +idlMakefilePaCO_nodist_salomeinclude_HEADERS = "${module}PaCO.hxx " +idlMakefilePaCO_BUILT_SOURCES = Template(idlMakefilePaCO_BUILT_SOURCES) +idlMakefilePaCO_nodist_salomeinclude_HEADERS = Template(idlMakefilePaCO_nodist_salomeinclude_HEADERS) +idlMakefilePACO_INCLUDES = "-I@PACOPATH@/idl" +idlMakefilePACO_salomepython_DATA = "${module}PaCO_idl.py" +idlMakefilePACO_salomepython_DATA = Template(idlMakefilePACO_salomepython_DATA) +idlMakefilePACO_salomeidl_DATA = "${module}PaCO.idl" +idlMakefilePACO_salomeidl_DATA = Template(idlMakefilePACO_salomeidl_DATA) + #SALOME catalog catalog=""" @@ -161,3 +210,14 @@ cataOutStream=""" """ cataOutStream=Template(cataOutStream) +cataInParallelStream=""" + ${name} + ${type} + """ +cataInParallelStream=Template(cataInParallelStream) + +cataOutParallelStream=""" + ${name} + ${type} + """ +cataOutParallelStream=Template(cataOutParallelStream) diff --git a/module_generator/gener.py b/module_generator/gener.py index c610628..5c857dc 100644 --- a/module_generator/gener.py +++ b/module_generator/gener.py @@ -8,10 +8,15 @@ except: class Invalid(Exception): pass -from mod_tmpl import resMakefile, makecommon, configure +from mod_tmpl import resMakefile, makecommon, configure, paco_configure from mod_tmpl import mainMakefile, autogen, application -from cata_tmpl import catalog, interface, idl, idlMakefile +from cata_tmpl import catalog, interface, idl, idlMakefile, parallel_interface +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 +from cata_tmpl import idlMakefilePACO_INCLUDES from cata_tmpl import cataOutStream, cataInStream, cataOutparam, cataInparam +from cata_tmpl import cataOutParallelStream, cataInParallelStream from cata_tmpl import cataService, cataCompo from aster_tmpl import check_aster @@ -42,9 +47,13 @@ calciumTypes = {"CALCIUM_double":"CALCIUM_double", "CALCIUM_logical":"CALCIUM_logical", } -ValidImpl = ("CPP", "PY", "F77", "ASTER") +DatastreamParallelTypes = {"Param_Double_Port":"Param_Double_Port"} + +ValidImpl = ("CPP", "PY", "F77", "ASTER", "PACO") +ValidImplTypes = ("sequential", "parallel") ValidTypes = corbaTypes.keys() ValidStreamTypes = calciumTypes.keys() +ValidParallelStreamTypes = DatastreamParallelTypes.keys() ValidDependencies = ("I", "T") PyValidTypes = ValidTypes+["pyobj"] @@ -105,15 +114,18 @@ class Component(object): class Service(object): def __init__(self, name, inport=None, outport=None, instream=None, - outstream=None, body="", defs=""): + outstream=None, parallel_instream=None, parallel_outstream=None, body="", defs="", impl_type="sequential"): self.name = name self.inport = inport or [] self.outport = outport or [] self.instream = instream or [] self.outstream = outstream or [] + self.parallel_instream = parallel_instream or [] + self.parallel_outstream = parallel_outstream or [] self.defs = defs self.body = body self.impl = "" + self.impl_type = impl_type def validate(self): lports = set() @@ -141,6 +153,20 @@ class Service(object): if name in lports: raise Invalid("%s is already defined as a stream port" % name) lports.add(name) + + for port in self.parallel_instream: + name, typ = self.validateParallelStream(port) + if name in lports: + raise Invalid("%s is already defined as a stream port" % name) + lports.add(name) + + for port in self.parallel_outstream: + name, typ = self.validateParallelStream(port) + if name in lports: + raise Invalid("%s is already defined as a stream port" % name) + lports.add(name) + + self.validateImplType() def validatePort(self, port): try: @@ -157,6 +183,10 @@ class Service(object): raise Invalid("%s is not a valid type. It should be one of %s" % (typ, validtypes)) return name, typ + def validateImplType(self): + if self.impl_type not in ValidImplTypes: + raise Invalid("%s is not a valid impl type. It should be one of %s" % (self.impl_type, ValidImplTypes)) + def validateStream(self, port): try: name, typ, dep = port @@ -168,11 +198,21 @@ class Service(object): raise Invalid("%s is not a valid dependency. It should be one of %s" % (dep, ValidDependencies)) return name, typ, dep + def validateParallelStream(self, port): + try: + name, typ = port + except: + raise Invalid("%s is not a valid definition of a parallel stream port (name,type)" % (port,)) + if typ not in ValidParallelStreamTypes: + raise Invalid("%s is not a valid type. It should be one of %s" % (typ, ValidParallelStreamTypes)) + return name, typ + class Generator(object): def __init__(self, module, context=None): self.module = module self.context = context or {} self.kernel = self.context["kernel"] + self.makeflags = self.context.get("makeflags") self.aster = "" def generate(self): @@ -180,6 +220,7 @@ class Generator(object): namedir = module.name+"_SRC" force = self.context.get("force") update = self.context.get("update") + paco = self.context.get("paco") if os.path.exists(namedir): if force: shutil.rmtree(namedir) @@ -205,12 +246,44 @@ class Generator(object): self.makeFiles({"autogen.sh":autogen, "Makefile.am":mainMakefile, "README":"", "NEWS":"", "AUTHORS":"", "ChangeLog":"", - "configure.ac":configure.substitute(module=module.name.lower(), makefiles='\n'.join(makefiles)), - "idl":{"Makefile.am":idlMakefile.substitute(module=module.name), idlfile:self.makeidl()}, "src":srcs, "resources":{"Makefile.am":resMakefile.substitute(module=module.name), catalogfile:self.makeCatalog()}, "adm_local":{"make_common_starter.am":makecommon, "check_aster.m4":check_aster}, }, namedir) + + if paco: + xmlfile = "%s.xml" % module.name + PACO_BUILT_SOURCES = idlMakefilePaCO_BUILT_SOURCES.substitute(module=module.name) + PACO_SALOMEINCLUDE_HEADERS = idlMakefilePaCO_nodist_salomeinclude_HEADERS.substitute(module=module.name) + PACO_salomepython_DATA = idlMakefilePACO_salomepython_DATA.substitute(module=module.name) + PACO_salomeidl_DATA = idlMakefilePACO_salomeidl_DATA.substitute(module=module.name) + PACO_INCLUDES = idlMakefilePACO_INCLUDES + + self.makeFiles({"configure.ac":configure.substitute(module=module.name.lower(), + makefiles='\n'.join(makefiles), + paco_configure=paco_configure), + "idl":{"Makefile.am":idlMakefile.substitute(module=module.name, + PACO_BUILT_SOURCES=PACO_BUILT_SOURCES, + PACO_SALOMEINCLUDE_HEADERS=PACO_SALOMEINCLUDE_HEADERS, + PACO_INCLUDES=PACO_INCLUDES, + PACO_salomepython_DATA=PACO_salomepython_DATA, + PACO_salomeidl_DATA=PACO_salomeidl_DATA), + idlfile:self.makeidl(), + xmlfile:self.makexml()}, + }, namedir) + else : + self.makeFiles({"configure.ac":configure.substitute(module=module.name.lower(), + makefiles='\n'.join(makefiles), + paco_configure=""), + "idl":{"Makefile.am":idlMakefile.substitute(module=module.name, + PACO_BUILT_SOURCES="", + PACO_SALOMEINCLUDE_HEADERS="", + PACO_INCLUDES="", + PACO_salomepython_DATA="", + PACO_salomeidl_DATA=""), + idlfile:self.makeidl()}, + }, namedir) + os.chmod(os.path.join(namedir, "autogen.sh"), 0777) #copy source files if any in creates tree for compo in module.components: @@ -220,7 +293,8 @@ class Generator(object): for m4file in ("check_Kernel.m4", "check_omniorb.m4", "ac_linker_options.m4", "ac_cxx_option.m4", "python.m4", "enable_pthreads.m4", "check_f77.m4", - "acx_pthread.m4", "check_boost.m4"): + "acx_pthread.m4", "check_boost.m4", "check_paco++.m4", + "check_mpi.m4", "check_lam.m4", "check_openmpi.m4", "check_mpich.m4"): shutil.copyfile(os.path.join(self.kernel, "salome_adm", "unix", "config_files", m4file), os.path.join(namedir, "adm_local", m4file)) @@ -252,6 +326,10 @@ class Generator(object): streams.append(cataInStream.substitute(name=name, type=calciumTypes[typ], dep=dep)) for name, typ, dep in serv.outstream: streams.append(cataOutStream.substitute(name=name, type=calciumTypes[typ], dep=dep)) + for name, typ in serv.parallel_instream: + streams.append(cataInParallelStream.substitute(name=name, type=DatastreamParallelTypes[typ])) + for name, typ in serv.parallel_outstream: + streams.append(cataOutParallelStream.substitute(name=name, type=DatastreamParallelTypes[typ])) datastreams = "\n".join(streams) services.append(cataService.substitute(service=serv.name, author="EDF-RD", inparams=inparams, outparams=outparams, datastreams=datastreams)) @@ -261,25 +339,53 @@ class Generator(object): return catalog.substitute(components='\n'.join(components)) def makeidl(self): + from pacocompo import PACOComponent interfaces = [] for compo in self.module.components: - services = [] - for serv in compo.services: - params = [] - for name, typ in serv.inport: - if compo.impl in ("PY", "ASTER") and typ == "pyobj": - typ = "Engines::fileBlock" - params.append("in %s %s" % (typ, name)) - for name, typ in serv.outport: - if compo.impl in ("PY", "ASTER") and typ == "pyobj": - typ = "Engines::fileBlock" - params.append("out %s %s" % (typ, name)) - service = " void %s(" % serv.name - service = service+",".join(params)+") raises (SALOME::SALOME_Exception);" - services.append(service) - interfaces.append(interface.substitute(component=compo.name, services="\n".join(services))) + if isinstance(compo, PACOComponent): + services = [] + for serv in compo.services: + params = [] + for name, typ in serv.inport: + params.append("in %s %s" % (typ, name)) + for name, typ in serv.outport: + params.append("out %s %s" % (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 compo.impl in ("PY", "ASTER") and typ == "pyobj": + typ = "Engines::fileBlock" + params.append("in %s %s" % (typ, name)) + for name, typ in serv.outport: + if compo.impl in ("PY", "ASTER") and typ == "pyobj": + typ = "Engines::fileBlock" + params.append("out %s %s" % (typ, name)) + service = " void %s(" % serv.name + service = service+",".join(params)+") raises (SALOME::SALOME_Exception);" + services.append(service) + interfaces.append(interface.substitute(component=compo.name, services="\n".join(services))) return idl.substitute(module=self.module.name, interfaces='\n'.join(interfaces)) + # For PaCO++ + def makexml(self): + from pacocompo import PACOComponent + interfaces = [] + for compo in self.module.components: + if isinstance(compo, PACOComponent): + services = [] + for serv in compo.services: + if serv.impl_type == "parallel": + service = xml_service.substitute(service_name=serv.name) + services.append(service) + interfaces.append(xml_interface.substitute(component=compo.name, xml_services="\n".join(services))) + return xml.substitute(module=self.module.name, interfaces='\n'.join(interfaces)) + def makeFiles(self, dic, basedir): for name, content in dic.items(): filename = os.path.join(basedir, name) @@ -299,18 +405,39 @@ class Generator(object): def configure(self): prefix = self.module.prefix + paco = self.context.get("paco") + mpi = self.context.get("mpi") if prefix: prefix = os.path.abspath(prefix) cmd = "cd %s_SRC;./configure --with-kernel=%s --with-aster=%s --prefix=%s" - ier = os.system(cmd % (self.module.name, self.kernel, self.aster, prefix)) + if paco: + cmd += " --with-paco=%s" + if mpi: + cmd += " --with-mpi=%s" + ier = os.system(cmd % (self.module.name, self.kernel, self.aster, prefix, paco, mpi)) + else : + ier = os.system(cmd % (self.module.name, self.kernel, self.aster, prefix, paco)) + else : + ier = os.system(cmd % (self.module.name, self.kernel, self.aster, prefix)) else: cmd = "cd %s_SRC;./configure --with-kernel=%s --with-aster=%s" - ier = os.system(cmd % (self.module.name, self.kernel, self.aster)) + if paco: + cmd += " --with-paco=%s" + if mpi: + cmd += " --with-mpi=%s" + ier = os.system(cmd % (self.module.name, self.kernel, self.aster, paco, mpi)) + else: + ier = os.system(cmd % (self.module.name, self.kernel, self.aster, paco)) + else: + ier = os.system(cmd % (self.module.name, self.kernel, self.aster)) if ier != 0: raise Invalid("configure has ended in error") def make(self): - ier = os.system("cd %s_SRC;make" % self.module.name) + make_command = "make " + if self.makeflags: + make_command += self.makeflags + ier = os.system("cd %s_SRC;%s" % (self.module.name, make_command)) if ier != 0: raise Invalid("make has ended in error") diff --git a/module_generator/mod_tmpl.py b/module_generator/mod_tmpl.py index 1a5746c..df56a70 100644 --- a/module_generator/mod_tmpl.py +++ b/module_generator/mod_tmpl.py @@ -49,6 +49,8 @@ AC_PROG_CXX CHECK_F77 CHECK_BOOST CHECK_OMNIORB +CHECK_PACO +CHECK_MPI MODULE_NAME=${module} AC_SUBST(MODULE_NAME) @@ -71,6 +73,8 @@ echo " OmniOrbpy (CORBA) ...... : $$omniORBpy_ok" echo " Python ................. : $$python_ok" echo " Boost ................. : $$boost_ok" echo " SALOME KERNEL .......... : $$Kernel_ok" +echo " PaCO++ ................. : $$PaCO_ok" +echo " MPI .................... : $$mpi_ok" echo " Code Aster ............. : $$Aster_ok" echo echo "------------------------------------------------------------------------" @@ -89,8 +93,9 @@ if test "x$$omniORBpy_ok" = "xno"; then AC_MSG_ERROR([OmniOrbpy is required],1) fi if test "x$$Kernel_ok" = "xno"; then - AC_MSG_ERROR([Expat is required],1) + AC_MSG_ERROR([SALOME KERNEL is required],1) fi +${paco_configure} AC_CONFIG_FILES([ Makefile @@ -103,6 +108,12 @@ AC_OUTPUT """ configure=Template(configure) +paco_configure="""\ +if test "x$$PaCO_ok" = "xno"; then + AC_MSG_ERROR([PaCO++ is required],1) +fi +""" + makecommon=""" # Standard directory for installation salomeincludedir = $(includedir)/salome diff --git a/module_generator/paco_tmpl.py b/module_generator/paco_tmpl.py new file mode 100644 index 0000000..0b87685 --- /dev/null +++ b/module_generator/paco_tmpl.py @@ -0,0 +1,407 @@ +#!/usr/bin/env python +# -*- coding: utf-8 *- +# Copyright (C) 2009 - 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. +# +# 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 +# +# Author : Andre RIBES (EDF R&D) + +try: + from string import Template +except: + from compat import Template,set + +compoMakefile=""" +include $$(top_srcdir)/adm_local/make_common_starter.am + +BUILT_SOURCES = SALOME_Exception.hxx SALOME_GenericObj.hxx SALOMEDS.hxx + +%.hxx : @KERNEL_ROOT_DIR@/idl/salome/%.idl +\t$$(OMNIORB_IDL) -bcxx $$(IDLCXXFLAGS) $$(OMNIORB_IDLCXXFLAGS) $$(IDL_INCLUDES) -I@KERNEL_ROOT_DIR@/idl/salome -Wbh=.hxx -Wbs=.cxx $$< + +AM_CFLAGS=$$(KERNEL_INCLUDES) $$(PACO_INCLUDES) -fexceptions + +lib_LTLIBRARIES = lib${component}Engine.la +lib${component}Engine_la_SOURCES = ${component}.cxx ${sources} +nodist_lib${component}Engine_la_SOURCES = +lib${component}Engine_la_CXXFLAGS = -I$$(top_builddir)/idl $$(KERNEL_INCLUDES) $$(PACO_INCLUDES) $$(MPI_INCLUDES) ${includes} +lib${component}Engine_la_LIBADD = -L$$(top_builddir)/idl -l${module} @KERNEL_ROOT_DIR@/lib/salome/libSalomeParallelDSCContainer.la @PACOPATH@/lib/libPaCO_direct_comScheduling.la $$(FLIBS) ${libs} $$(PACO_LIBS) +lib${component}Engine_la_LDFLAGS = ${rlibs} +salomeinclude_HEADERS = ${component}.hxx +""" +compoMakefile=Template(compoMakefile) + +paco_sources = """\ +$$(top_builddir)/idl/${module}PaCO_${module}_${component}_client.cxx $$(top_builddir)/idl/${module}PaCO_${module}_${component}_server.cxx $$(top_builddir)/idl/${module}PaCO.cxx $$(top_builddir)/idl/${module}.cxx +""" +paco_sources = Template(paco_sources) + +hxxCompo=""" +#ifndef _${component}_HXX_ +#define _${component}_HXX_ + +#include "${module}PaCO_${module}_${component}_server.hxx" +#include "ParallelDSC_i.hxx" +#include "Param_Double_Port_uses_i.hxx" +#include "Param_Double_Port_provides_i.hxx" + +#include "PortProperties_i.hxx" +#include +#include +#include +#include + +class ${component}_i: + public virtual ${module}::${component}_serv, + public virtual Engines_ParallelDSC_i +{ + public: + ${component}_i(CORBA::ORB_ptr orb, + char * ior, + int rank, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); + + virtual ~${component}_i(); + + void provides_port_changed(const char* provides_port_name, + int connection_nbr, + const Engines::DSC::Message message) {} + + void uses_port_changed(const char* uses_port_name, + Engines::DSC::uses_port * new_uses_port, + const Engines::DSC::Message message) {delete new_uses_port;} + + CORBA::Boolean init_service(const char * service_name); + +${servicesdef} + private: + PortProperties_i * _fake_properties; +${services_init_ok} +${parallelstreamports} +}; + +extern "C" +{ + PortableServer::ObjectId * ${component}Engine_factory(CORBA::ORB_ptr orb, + char * ior, + int rank, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName); + + PortableServer::ObjectId * ${component}EngineProxy_factory(CORBA::ORB_ptr orb, + paco_fabrique_thread * fab_thread, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + RegistryConnexion **, + const char *instanceName, + int node_number); + void ${component}_isAPACO_Component() {}; +} +#endif + +""" +hxxCompo=Template(hxxCompo) + +hxxinit_ok = """\ + bool _${service_name}_init_ok;""" +hxxinit_ok = Template(hxxinit_ok) + +hxxparallel_outstream = """\ + ${type}_uses_i * _${name}_port; + bool _${name}_port_start_ok;""" +hxxparallel_outstream = Template(hxxparallel_outstream) + +hxxparallel_instream = """\ + ${type}_provides_i * _${name}_port;""" +hxxparallel_instream = Template(hxxparallel_instream) + +cxxCompo=""" +#include "${component}.hxx" +#include + +//DEFS +${servicesdef} +//ENDDEF + +//! Constructor for component "${component}" instance +/*! + * + */ +${component}_i::${component}_i(CORBA::ORB_ptr orb, + char * ior, + int rank, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) : + ${module}::${component}_serv(orb, ior, rank), + ${module}::${component}_base_serv(orb, ior, rank), + Engines_ParallelDSC_i(orb, ior, rank, poa, contId, instanceName, interfaceName), + Engines_Parallel_Component_i(orb, ior, rank, poa, contId, instanceName, interfaceName), + Engines::Parallel_DSC_serv(orb, ior, rank), + InterfaceParallel_impl(orb,ior, rank), + Engines::Superv_Component_serv(orb, ior, rank), + Engines::DSC_serv(orb, ior, rank), + Engines::Component_serv(orb,ior, rank), + Engines::Parallel_Component_serv(orb,ior, rank), + Engines::Parallel_DSC_base_serv(orb, ior, rank), + Engines::Superv_Component_base_serv(orb, ior, rank), + Engines::DSC_base_serv(orb, ior, rank), + Engines::Component_base_serv(orb,ior, rank), + Engines::Parallel_Component_base_serv(orb,ior, rank) + +{ + std::cerr << "creating paralle component" << std::endl; + _thisObj = this ; + _id = _poa->activate_object(_thisObj); +${cons_services} +} + +//! Destructor for component "${component}" instance +${component}_i::~${component}_i() +{ +${des_services} +} + +//! Register datastream ports for a component service given its name +/*! + * \param service_name : service name + * \\return true if port registering succeeded, false if not + */ +CORBA::Boolean +${component}_i::init_service(const char * service_name) { + CORBA::Boolean rtn = false; + string s_name(service_name); +${initservice} + return rtn; +} + +${servicesimpl} +""" +cxxCompo=Template(cxxCompo) + +cxx_cons_service = """\ + _${service_name}_init_ok = false; +""" +cxx_cons_service = Template(cxx_cons_service) + +cxx_cons_parallel_outstream = """\ + _${name}_port = NULL; + _${name}_port_start_ok = false; +""" +cxx_cons_parallel_outstream = Template(cxx_cons_parallel_outstream) + +cxx_cons_parallel_instream = """\ + _${name}_port = NULL; +""" +cxx_cons_parallel_instream = Template(cxx_cons_parallel_instream) + +cxx_des_parallel_stream = """\ + if (_${name}_port) + delete _${name}_port; +""" +cxx_des_parallel_stream = Template(cxx_des_parallel_stream) + +initService="""\ + if (s_name == "${service_name}") + { + if (!_${service_name}_init_ok) + { +${init_parallel_datastream_ports} + _${service_name}_init_ok = true; + } + rtn = true; + } +""" +initService=Template(initService) + +hxxparallel_outstream_init = """\ + _${name}_port = new ${type}_uses_i(this, \"${name}\", _orb); + _${name}_port->add_port_to_component(); +""" +hxxparallel_outstream_init = Template(hxxparallel_outstream_init) + +hxxparallel_instream_init = """\ + _${name}_port = ${type}_provides_i::init_port(this, \"${name}\", _orb); + ${type}_provides_i::wait_init_port(this, \"${name}\", _orb); +""" +hxxparallel_instream_init = Template(hxxparallel_instream_init) + +cxxService=""" +void ${component}_i::${service}(${parameters}) +{ + std::cerr << "Begin of ${component}_i::${service} of node " << _myRank << std::endl; + if (_myRank == 0) + beginService("${component}_i::${service}"); +${connect_parallel_streamport} + try + { +//BODY +${body} +//ENDBODY + } + catch ( const SALOME_Exception & ex) + { + SALOME::ExceptionStruct es; + es.text=CORBA::string_dup(ex.what()); + es.type=SALOME::INTERNAL_ERROR; + throw SALOME::SALOME_Exception(es); + } + catch (...) + { + 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); + } + if (_myRank == 0) + endService("${component}_i::${service}"); + std::cerr << "End of ${component}_i::${service} of node " << _myRank << std::endl; +} + +""" +cxxService=Template(cxxService) + +cxxService_connect = """\ + if (!_${name}_port_start_ok) + { + _${name}_port->start_port(); + _${name}_port_start_ok = true; + } +""" +cxxService_connect = Template(cxxService_connect) + +cxxFactoryDummy = """ +extern "C" +{ + PortableServer::ObjectId * ${component}Engine_factory(CORBA::ORB_ptr orb, char * ior, int rank, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + std::cerr << "Begin of ${component}Engine_factory()" << std::endl; + + paco_fabrique_manager * pfm = paco_getFabriqueManager(); + pfm->register_com("${component}_node_dummy", new paco_dummy_fabrique()); + pfm->register_thread("${component}_node_omni", new paco_omni_fabrique()); + ${component}_i * ${component}_node = new ${component}_i(CORBA::ORB::_duplicate(orb), ior, rank, poa, contId, instanceName, interfaceName); + ${component}_node->setLibCom("${component}_node_dummy", ${component}_node); + ${component}_node->setLibThread("${component}_node_omni"); + + std::cerr << "End of ${component}Engine_factory()" << std::endl; + return ${component}_node->getId(); + } + + PortableServer::ObjectId * ${component}EngineProxy_factory(CORBA::ORB_ptr orb, + paco_fabrique_thread * fab_thread, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + RegistryConnexion ** connexion, + const char *instanceName, + int node_number) + { + cerr << "Begin of ${component}EngineProxy_factory()" << endl; + + paco_fabrique_manager* pfm = paco_getFabriqueManager(); + pfm->register_com("proxy_dummy", new paco_dummy_fabrique()); + pfm->register_thread("proxy_thread", new paco_omni_fabrique()); + ${module}::${component}_proxy_impl * proxy = new ${module}::${component}_proxy_impl(CORBA::ORB::_duplicate(orb), + fab_thread); + PortableServer::ObjectId * id = poa->activate_object(proxy); + proxy->_remove_ref(); + // Initialisation du proxy + proxy->setLibCom("proxy_dummy", proxy); + proxy->setLibThread("proxy_thread"); + PaCO::PacoTopology_t serveur_topo; + serveur_topo.total = node_number; + proxy->setTopology(serveur_topo); + + // Ajout dans le registry ... + CORBA::Object_var o = poa->id_to_reference(*contId); // container ior... + const CORBA::String_var the_ior = orb->object_to_string(o); + *connexion = new RegistryConnexion(0, 0, the_ior, "theSession", instanceName); + + cerr << "End of ${component}EngineProxy_factory()" << endl; + return id; + } +} +""" +cxxFactoryDummy = Template(cxxFactoryDummy) + +cxxFactoryMpi = """ +extern "C" +{ + PortableServer::ObjectId * ${component}Engine_factory(CORBA::ORB_ptr orb, char * ior, int rank, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName) + { + std::cerr << "Begin of ${component}Engine_factory()" << std::endl; + + paco_fabrique_manager * pfm = paco_getFabriqueManager(); + pfm->register_com("${component}_node_mpi", new paco_mpi_fabrique()); + pfm->register_thread("${component}_node_omni", new paco_omni_fabrique()); + ${component}_i * ${component}_node = new ${component}_i(CORBA::ORB::_duplicate(orb), ior, rank, poa, contId, instanceName, interfaceName); + MPI_Comm parallel_object_group = MPI_COMM_WORLD; + ${component}_node->setLibCom("${component}_node_mpi", ¶llel_object_group); + ${component}_node->setLibThread("${component}_node_omni"); + + std::cerr << "End of ${component}Engine_factory()" << std::endl; + return ${component}_node->getId(); + } + + PortableServer::ObjectId * ${component}EngineProxy_factory(CORBA::ORB_ptr orb, + paco_fabrique_thread * fab_thread, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + RegistryConnexion ** connexion, + const char *instanceName, + int node_number) + { + cerr << "Begin of ${component}EngineProxy_factory()" << endl; + + paco_fabrique_manager* pfm = paco_getFabriqueManager(); + pfm->register_com("proxy_dummy", new paco_dummy_fabrique()); + pfm->register_thread("proxy_thread", new paco_omni_fabrique()); + ${module}::${component}_proxy_impl * proxy = new ${module}::${component}_proxy_impl(CORBA::ORB::_duplicate(orb), + fab_thread); + PortableServer::ObjectId * id = poa->activate_object(proxy); + proxy->_remove_ref(); + // Initialisation du proxy + proxy->setLibCom("proxy_dummy", proxy); + proxy->setLibThread("proxy_thread"); + PaCO::PacoTopology_t serveur_topo; + serveur_topo.total = node_number; + proxy->setTopology(serveur_topo); + + // Ajout dans le registry ... + CORBA::Object_var o = poa->id_to_reference(*contId); // container ior... + const CORBA::String_var the_ior = orb->object_to_string(o); + *connexion = new RegistryConnexion(0, 0, the_ior, "theSession", instanceName); + + cerr << "End of ${component}EngineProxy_factory()" << endl; + return id; + } +} +""" +cxxFactoryMpi = Template(cxxFactoryMpi) diff --git a/module_generator/pacocompo.py b/module_generator/pacocompo.py new file mode 100644 index 0000000..3435f08 --- /dev/null +++ b/module_generator/pacocompo.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python +# -*- coding: utf-8 *- +# Copyright (C) 2009 - 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. +# +# 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 +# +# Author : Andre RIBES (EDF R&D) + +""" + Module that defines PACOComponent for SALOME PaCO++ components implemented in C++ +""" + +from gener import Component, Invalid +from paco_tmpl import compoMakefile, hxxCompo, cxxService +from paco_tmpl import initService, cxxCompo, paco_sources +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 + +class PACOComponent(Component): + + def __init__(self, name, parallel_lib, services=None, libs="", rlibs="", includes="", + kind="lib", exe_path=None, sources=None): + self.exe_path = exe_path + self.parallel_lib = parallel_lib + Component.__init__(self, name, services, impl="PACO", libs=libs, + rlibs=rlibs, includes=includes, kind=kind, + sources=sources) + 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" % kinds) + parallel_libs = ("dummy", "mpi") + if self.parallel_lib not in parallel_libs: + raise Invalid("parallel_lib must be one of %s" % parallel_libs) + + def makeCompo(self, gen): + """generate files for PaCO++ component + + return a dict where key is the file name and value is the content of the file + """ + cxxfile = "%s.cxx" % self.name + hxxfile = "%s.hxx" % self.name + if self.kind == "lib": + sources = " ".join(self.sources) + sources += paco_sources.substitute(module=gen.module.name, + component=self.name) + return {"Makefile.am":compoMakefile.substitute(module=gen.module.name, + component=self.name, + libs=self.libs, + rlibs=self.rlibs, + sources=sources, + includes=self.includes), + cxxfile:self.makecxx(gen), + hxxfile:self.makehxx(gen)} + + def makehxx(self, gen): + """return a string that is the content of .hxx file + """ + services = [] + parallel_instream = "" + parallel_outstream = "" + services_init_ok = "" + parallelstreamports = "" + for serv in self.services: + service = " void %s(" % serv.name + service = service+gen.makeArgs(serv)+");" + services.append(service) + services_init_ok += hxxinit_ok.substitute(service_name=serv.name) + + # Ajout des ports parallel DataStream + for name, type in serv.parallel_instream: + parallel_instream += hxxparallel_instream.substitute(name=name, + type=type) + for name, type in serv.parallel_outstream: + parallel_outstream += hxxparallel_outstream.substitute(name=name, + type=type) + servicesdef = "\n".join(services) + parallelstreamports += parallel_instream + parallelstreamports += parallel_outstream + return hxxCompo.substitute(component=self.name, + module=gen.module.name, + servicesdef=servicesdef, + services_init_ok=services_init_ok, + parallelstreamports=parallelstreamports, + parallel_lib=self.parallel_lib) + + def makecxx(self, gen): + """return a string that is the content of .cxx file + """ + services = [] + inits = [] + defs = [] + cons_services = "" + des_services = "" + for serv in self.services: + defs.append(serv.defs) + + # Constructeur + cons_services += cxx_cons_service.substitute(service_name=serv.name) + for name, type in serv.parallel_instream: + cons_services += cxx_cons_parallel_instream.substitute(name=name) + for name, type in serv.parallel_outstream: + cons_services += cxx_cons_parallel_outstream.substitute(name=name) + + # Destructeur + # On détruit uniquement les ports uses + # Les ports provides sont détruit lors de la destruction du poa + for name, type in serv.parallel_outstream: + des_services += cxx_des_parallel_stream.substitute(name=name) + + # init_service + init_parallel_datastream_ports="" + for name, type in serv.parallel_instream: + init_parallel_datastream_ports += hxxparallel_instream_init.substitute(name=name, + type=type) + for name, type in serv.parallel_outstream: + init_parallel_datastream_ports += hxxparallel_outstream_init.substitute(name=name, + type=type) + init = initService.substitute(service_name=serv.name, + init_parallel_datastream_ports=init_parallel_datastream_ports) + inits.append(init) + + # Code du service + connect_parallel_streamport = "" + for name, type in serv.parallel_outstream: + connect_parallel_streamport += cxxService_connect.substitute(name=name) + + service = cxxService.substitute(component=self.name, service=serv.name, + parameters=gen.makeArgs(serv), + body=serv.body, + connect_parallel_streamport=connect_parallel_streamport) + services.append(service) + + cxxfile = cxxCompo.substitute(component=self.name, module=gen.module.name, + servicesdef="\n".join(defs), + servicesimpl="\n".join(services), + initservice='\n'.join(inits), + cons_services=cons_services, + des_services=des_services) + + if self.parallel_lib == "dummy": + cxxfile += cxxFactoryDummy.substitute(component=self.name, module=gen.module.name) + elif self.parallel_lib == "mpi": + cxxfile += cxxFactoryMpi.substitute(component=self.name, module=gen.module.name) + + return cxxfile + -- 2.39.2