]> SALOME platform Git repositories - tools/yacsgen.git/commitdiff
Salome HOME
- Ajout du support de composants PaCO++
authorribes <ribes>
Tue, 21 Jul 2009 09:10:04 +0000 (09:10 +0000)
committerribes <ribes>
Tue, 21 Jul 2009 09:10:04 +0000 (09:10 +0000)
module_generator/__init__.py
module_generator/cata_tmpl.py
module_generator/gener.py
module_generator/mod_tmpl.py
module_generator/paco_tmpl.py [new file with mode: 0644]
module_generator/pacocompo.py [new file with mode: 0644]

index 42d4722d15feafbcfa6afea2e0757072a205a53a..e25bec1047af6681a605baae9275deb9dc1d428c 100644 (file)
@@ -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
index cce5dcfeaef508f68d833a856e2f4c3cb6edae75..f6ce82640b59d8239173b5c99c2b1e3a61cbfbcb 100644 (file)
@@ -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="""\
+<?xml version="1.0"?>
+<!-- YACSGEN -->
+
+<PaCO_Interface_description>
+  <Module>
+    <Name>${module}</Name>
+${interfaces}
+  </Module>
+</PaCO_Interface_description>
+"""
+xml = Template(xml)
+
+xml_interface="""\
+    <Interface>
+      <Name>${component}</Name>
+${xml_services}
+    </Interface>"""
+xml_interface = Template(xml_interface)
+
+xml_service = """\
+      <Method>
+        <Name>${service_name}</Name>
+        <Type>distributed</Type>
+      </Method>"""
+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="""<?xml version='1.0' encoding='us-ascii' ?>
@@ -161,3 +210,14 @@ cataOutStream="""                       <outParameter>
                        </outParameter>"""
 cataOutStream=Template(cataOutStream)
 
+cataInParallelStream="""                       <inParameter>
+                          <inParameter-name>${name}</inParameter-name>
+                          <inParameter-type>${type}</inParameter-type>
+                       </inParameter>"""
+cataInParallelStream=Template(cataInParallelStream)
+
+cataOutParallelStream="""                       <outParameter>
+                          <outParameter-name>${name}</outParameter-name>
+                          <outParameter-type>${type}</outParameter-type>
+                       </outParameter>"""
+cataOutParallelStream=Template(cataOutParallelStream)
index c610628dfe362f16dbe62cdb6f04d788e2978b01..5c857dc9687e24627b2d96909daeb5eb185b0af3 100644 (file)
@@ -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")
 
index 1a5746c0dd629604809bb07f8bd483493599bda5..df56a70b4faa64229514f9f2426a64d817b3cdc1 100644 (file)
@@ -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 (file)
index 0000000..0b87685
--- /dev/null
@@ -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 <Utils_SALOME_Exception.hxx>
+#include <paco_omni.h>
+#include <paco_${parallel_lib}.h>
+#include <paco_dummy.h>
+
+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 <string>
+
+//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", &parallel_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 (file)
index 0000000..3435f08
--- /dev/null
@@ -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
+