cd $script_dir
-list_dirs="calcium1 calcium2 cpp1 cpp2 cppgui1 fort1 fort2 pydoc1 pygui1 pyth1 pyth2 types1 hxx1"
+list_dirs="calcium1 calcium2 cpp1 cpp2 cppgui1 fort1 fort2 pydoc1 pygui1 pyth1 pyth2 types1 mpi1 parahxx1 hxx1"
for dir in $list_dirs ; do
cd $dir
echo Building $dir ...
script_dir=`dirname $0`
cd $script_dir
-list_dirs="calcium1 calcium2 cpp1 cpp2 cppgui1 fort1 fort2 pydoc1 pygui1 pyth1 pyth2 types1 hxx1"
+list_dirs="calcium1 calcium2 cpp1 cpp2 cppgui1 fort1 fort2 pydoc1 pygui1 pyth1 pyth2 types1 mpi1 parahxx1 hxx1"
for dir in $list_dirs ; do
cd $dir
--- /dev/null
+# 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
+#
+
+clean:
+ rm -rf *.o *.so appli install *.bak traceExec_* mymodule_* *.err *.log
+ cd mpilib; make clean
--- /dev/null
+A example of a MPI component
+=========================================
+
+To build this example, modify the ../exec.sh file to take into account your configuration.
+Run build.sh to build and test the component.
+
+You should get a SALOME module in source form (mymodule_SRC), its installation (install) and
+a SALOME application (appli) composed of modules KERNEL, GUI, YACS and the new module cppcompos.
+
+To run a coupling:
+
+ 1. start SALOME in background : ./appli/salome -t
+ 2. run the example schema in a SALOME session : ./appli/salome shell -- driver coupling.xml
+ 3. examine output files in /tmp
+ 4. shutdown SALOME : ./appli/salome killall
--- /dev/null
+(cd mpilib; make)
+../exec.sh python components.py
+
+# test
+appli/salome shell ../test_compo.py
+
--- /dev/null
+# -*- coding: utf-8 -*-
+import os
+from module_generator import Generator,Module,Service
+from module_generator import MPIComponent
+from module_generator import Library
+
+SALOME_ROOT=os.getenv("SALOME_DIR")
+prerequis_file=os.path.join(SALOME_ROOT, "salome_prerequisites.sh")
+
+kernel_root_dir=os.getenv("KERNEL_ROOT_DIR")
+gui_root_dir=os.getenv("GUI_ROOT_DIR")
+yacs_root_dir=os.getenv("YACS_ROOT_DIR")
+
+context={'update':1,
+ "makeflags":"-j2",
+ "prerequisites":prerequis_file,
+ "kernel":kernel_root_dir
+ }
+
+cwd=os.getcwd()
+
+# PUT HERE DEFINITIONS OF THE COMPONENTS AND THE SERVICES
+body_a="""
+Mylibmpi myinstance;
+res_val = myinstance.mympi_funct(in_val);
+"""
+
+defs_service="""
+"""
+
+service_s = Service("mpifunc",
+ inport=[("in_val", "long")],
+ outport=[("res_val", "long")],
+ body=body_a,
+ defs=defs_service
+ )
+
+mpilib_root_path = os.path.join(cwd, "mpilib")
+mpilib_include_path = os.path.join(mpilib_root_path, "include")
+mpilib_lib_path = os.path.join(mpilib_root_path, "lib")
+
+compodefs = """
+#include "mylibmpi.h"
+"""
+
+compo=MPIComponent("mycompoMpi",
+ services=[service_s],
+ compodefs=compodefs,
+ libs=[Library(name="mylibmpi", path=mpilib_lib_path)],
+ rlibs=mpilib_lib_path,
+ includes=mpilib_include_path,
+ )
+
+g=Generator(Module("mymodule",components=[compo],prefix="./install"),context)
+g.generate()
+g.configure()
+g.make()
+g.install()
+g.make_appli("appli",
+ restrict=["KERNEL","GUI","YACS","JOBMANAGER"])
+
+
--- /dev/null
+<?xml version='1.0' encoding='iso-8859-1' ?>
+<proc name="newSchema_1">
+ <property name="DefaultStudyID" value="1"/>
+ <type name="string" kind="string"/>
+ <struct name="Engines/dataref">
+ <member name="ref" type="string"/>
+ </struct>
+ <type name="bool" kind="bool"/>
+ <sequence name="boolvec" content="bool"/>
+ <type name="double" kind="double"/>
+ <sequence name="dblevec" content="double"/>
+ <objref name="file" id="file"/>
+ <type name="int" kind="int"/>
+ <sequence name="intvec" content="int"/>
+ <struct name="stringpair">
+ <member name="name" type="string"/>
+ <member name="value" type="string"/>
+ </struct>
+ <sequence name="propvec" content="stringpair"/>
+ <objref name="pyobj" id="python:obj:1.0"/>
+ <sequence name="seqboolvec" content="boolvec"/>
+ <sequence name="seqdblevec" content="dblevec"/>
+ <sequence name="seqintvec" content="intvec"/>
+ <sequence name="seqpyobj" content="pyobj"/>
+ <sequence name="stringvec" content="string"/>
+ <sequence name="seqstringvec" content="stringvec"/>
+ <container name="DefaultContainer">
+ <property name="container_kind" value="Salome"/>
+ <property name="attached_on_cloning" value="0"/>
+ <property name="container_name" value="FactoryServer"/>
+ <property name="name" value="localhost"/>
+ </container>
+ <container name="container0">
+ <property name="container_kind" value="Salome"/>
+ <property name="attached_on_cloning" value="0"/>
+ <property name="isMPI" value="true"/>
+ <property name="nb_parallel_procs" value="3"/>
+ </container>
+ <service name="mpifunc1">
+ <component>mycompoMpi</component>
+ <load container="container0"/>
+ <method>mpifunc</method>
+ <inport name="in_val" type="int"/>
+ <outport name="res_val" type="int"/>
+ </service>
+ <parameter>
+ <tonode>mpifunc1</tonode><toport>in_val</toport>
+ <value><int>1</int></value>
+ </parameter>
+ <presentation name="mpifunc1" x="4" y="42" width="158" height="63" expanded="1" expx="4" expy="42" expWidth="158" expHeight="63" shownState="0"/>
+ <presentation name="__ROOT__" x="0" y="0" width="166" height="109" expanded="1" expx="0" expy="0" expWidth="166" expHeight="109" shownState="0"/>
+</proc>
--- /dev/null
+
+all : myexe
+
+myexe : lib/libmylibmpi.so src/myexempi.cxx include/mylibmpi.h
+ mpic++ -o myexe -Iinclude src/myexempi.cxx -Llib -lmylibmpi
+
+lib/libmylibmpi.so : src/mylibmpi.cxx include/mylibmpi.h
+ mkdir -p lib; mpic++ -shared -fPIC -o lib/libmylibmpi.so -Iinclude src/mylibmpi.cxx
+
+clean :
+ rm -f myexe lib/libmylibmpi.so *~
--- /dev/null
+#ifndef _mylibmpi_h_
+#define _mylibmpi_h_
+
+#define MASTER 0
+
+class Mylibmpi
+{
+ public:
+ int mympi_funct(int v);
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+#include "mylibmpi.h"
+#include <iostream>
+#include <mpi.h>
+
+int main(int argc, char* argv[])
+{
+ int namelen, numprocs, myid ;
+ int result;
+ Mylibmpi myinstance;
+
+ /** initialisation de mpi **/
+ MPI_Init(&argc,&argv);
+ /** combien y-a-t-il de processeurs ? **/
+ MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
+ /** numero du processus courant **/
+ MPI_Comm_rank(MPI_COMM_WORLD,&myid);
+
+ result = myinstance.mympi_funct(3);
+ if(MASTER == myid)
+ std::cout << "Resultat:" << result << std::endl;
+
+ /** fin du pg **/
+ MPI_Finalize();
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include "mylibmpi.h"
+#include "mpi.h"
+
+int Mylibmpi::mympi_funct(int v)
+{
+ int namelen, numprocs, myid ;
+ char processor_name[MPI_MAX_PROCESSOR_NAME] ;
+ int local_result;
+ int result, err_code;
+
+ /** combien y-a-t-il de processeurs ? **/
+ MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
+ /** numero du processus courant **/
+ MPI_Comm_rank(MPI_COMM_WORLD,&myid);
+ /** num du processeur courant **/
+ MPI_Get_processor_name(processor_name,&namelen);
+
+ local_result = myid + v;
+ err_code = MPI_Reduce(&local_result, &result, 1, MPI_INT, MPI_SUM,
+ MASTER, MPI_COMM_WORLD);
+ if(MPI_SUCCESS != err_code)
+ printf("%d: failure on mpc_reduce\n", myid);
+
+ return result;
+// if(MASTER == myid)
+//printf("id %d: result=%d\n", myid, result);
+
+}
\ No newline at end of file
--- /dev/null
+# 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
+#
+
+clean:
+ rm -rf *.o *.so appli install *.bak traceExec_* hxxcompos_* *.err *.log par*
--- /dev/null
+../exec.sh python components.py
+
+# test
+LD_LIBRARY_PATH=`pwd`/../mpi1/mpilib/lib/ appli/salome shell ../test_compo.py
+
--- /dev/null
+# 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
+#
+
+import os
+from module_generator import Generator,Module,Service
+from module_generator import CPPComponent,PYComponent,HXX2SALOMEParaComponent
+class Invalid(Exception):
+ pass
+
+kernel_root_dir=os.environ["KERNEL_ROOT_DIR"]
+gui_root_dir=os.environ["GUI_ROOT_DIR"]
+yacs_root_dir=os.environ["YACS_ROOT_DIR"]
+med_root_dir=os.environ["MED_ROOT_DIR"]
+SALOME_ROOT=os.getenv("SALOME_DIR")
+prereq_file=os.path.join(SALOME_ROOT, "salome_prerequisites.sh")
+
+if not os.path.exists(prereq_file):
+ prereq_file=os.path.join(kernel_root_dir,"..","..","env_products.sh")
+if not os.path.exists(prereq_file):
+ raise Invalid("prerequisite file env_products.sh not found. please replace it manually in component.py")
+
+context={'update':1,
+ "makeflags":"",
+ "prerequisites":prereq_file,
+ "kernel":kernel_root_dir,
+ "gui":gui_root_dir,
+ "med":med_root_dir,
+ "yacs":yacs_root_dir,
+ }
+
+cwd=os.getcwd()
+cpppath=os.path.join(cwd,"..","mpi1","mpilib")
+
+# PUT HERE DEFINITIONS OF THE COMPONENTS AND THE SERVICES
+
+c1=HXX2SALOMEParaComponent("mylibmpi.h","libmylibmpi.so" , cpppath )
+
+g=Generator(Module("hxxcompos",components=[c1],prefix="./install"),context)
+g.generate()
+g.configure()
+g.make()
+g.install()
+g.make_appli("appli",
+ restrict=["KERNEL","GUI","YACS","MED"],
+ )
--- /dev/null
+<?xml version='1.0' encoding='iso-8859-1' ?>
+<proc name="newSchema_1">
+ <property name="DefaultStudyID" value="1"/>
+ <type name="string" kind="string"/>
+ <struct name="Engines/dataref">
+ <member name="ref" type="string"/>
+ </struct>
+ <type name="bool" kind="bool"/>
+ <sequence name="boolvec" content="bool"/>
+ <type name="double" kind="double"/>
+ <sequence name="dblevec" content="double"/>
+ <objref name="file" id="file"/>
+ <type name="int" kind="int"/>
+ <sequence name="intvec" content="int"/>
+ <struct name="stringpair">
+ <member name="name" type="string"/>
+ <member name="value" type="string"/>
+ </struct>
+ <sequence name="propvec" content="stringpair"/>
+ <objref name="pyobj" id="python:obj:1.0"/>
+ <sequence name="seqboolvec" content="boolvec"/>
+ <sequence name="seqdblevec" content="dblevec"/>
+ <sequence name="seqintvec" content="intvec"/>
+ <sequence name="seqpyobj" content="pyobj"/>
+ <sequence name="stringvec" content="string"/>
+ <sequence name="seqstringvec" content="stringvec"/>
+ <container name="DefaultContainer">
+ <property name="container_kind" value="Salome"/>
+ <property name="attached_on_cloning" value="0"/>
+ <property name="container_name" value="FactoryServer"/>
+ <property name="name" value="localhost"/>
+ </container>
+ <container name="container0">
+ <property name="container_kind" value="Salome"/>
+ <property name="attached_on_cloning" value="0"/>
+ <property name="isMPI" value="true"/>
+ <property name="nb_parallel_procs" value="3"/>
+ </container>
+ <service name="mympi_funct1">
+ <component>Mylibmpi</component>
+ <load container="container0"/>
+ <method>mympi_funct</method>
+ <inport name="v" type="int"/>
+ <outport name="return" type="int"/>
+ </service>
+ <parameter>
+ <tonode>mympi_funct1</tonode><toport>v</toport>
+ <value><int>1</int></value>
+ </parameter>
+ <presentation name="mympi_funct1" x="57" y="33" width="158" height="63" expanded="1" expx="57" expy="33" expWidth="158" expHeight="63" shownState="0"/>
+ <presentation name="__ROOT__" x="0" y="0" width="219" height="100" expanded="1" expx="0" expy="0" expWidth="219" expHeight="100" shownState="0"/>
+</proc>
cmake_vars = cmake_vars + "${" + lib.cmakeVarName() + "}\n "
var_template = Template("$${${name}_SalomeIDL${name}}")
- for mod in self.depend_modules:
+ for mod in self.getDependentModules():
if salome_modules[mod]["linklibs"]:
cmake_vars = cmake_vars + salome_modules[mod]["linklibs"]
else:
idldefs = idldefs + self.interfacedefs
return idldefs
+ def getDependentModules(self):
+ """get the list of SALOME modules used by the component
+ """
+ def get_dependent_modules(mod,modules):
+ modules.add(mod)
+ if salome_modules[mod].has_key("depends"):
+ for m in salome_modules[mod]["depends"]:
+ if m not in modules:
+ get_dependent_modules(m,modules)
+
+ depend_modules = set()
+ for serv in self.services:
+ for name, typ in serv.inport + serv.outport + [ ("return",serv.ret) ] :
+ mod = moduleTypes[typ]
+ if mod:
+ get_dependent_modules(mod,depend_modules)
+ return depend_modules
+
class Service(object):
"""
A :class:`Service` instance represents a component service with dataflow and datastream ports.
srcs = {}
#get the list of SALOME modules used and put it in used_modules attribute
- def get_dependent_modules(mod,modules):
- modules[mod]=1
- if not salome_modules[mod].has_key("depends"):return
- for m in salome_modules[mod]["depends"]:
- if modules.has_key(m):continue
- get_dependent_modules(m,modules)
-
- modules = {}
+ modules = set()
for compo in module.components:
- compo.depend_modules = set()
- for serv in compo.services:
- for name, typ in serv.inport + serv.outport + [ ("return",serv.ret) ] :
- mod = moduleTypes[typ]
- if mod:
- get_dependent_modules(mod,modules)
- compo.depend_modules.add(mod)
-
- self.used_modules = modules.keys()
+ modules |= compo.getDependentModules()
+
+ self.used_modules = modules
for compo in module.components:
#for components files
$${OMNIORB_INCLUDE_DIR}
$${PROJECT_BINARY_DIR}
$${PROJECT_BINARY_DIR}/idl
+ $${MEDCOUPLING_INCLUDE_DIRS}
${includes}
)
$${KERNEL_SalomeIDLKernel}
$${KERNEL_OpUtil}
$${KERNEL_SalomeContainer}
- $${KERNEL_SalomeDSCContainer}
- $${KERNEL_SalomeDSCSuperv}
- $${KERNEL_SalomeDatastream}
- $${KERNEL_SalomeDSCSupervBasic}
- $${KERNEL_CalciumC}
$${KERNEL_SalomeMPIContainer}
$${MED_paramedmemcompo}
+ $${MED_paramedcouplingcorba}
SalomeIDL${module}
${libs}
)
services = self.getIdlServices()
from hxx_tmpl import interfaceidlhxx
Inherited=""
- if compo.use_medmem==True:
+ if self.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))
+ return interfaceidlhxx.substitute(component=self.name,inherited=Inherited, services="\n".join(services))
from hxx_tmpl import interfaceidlhxx
Inherited=""
Inherited="SALOME_MED::ParaMEDMEMComponent"
+ return interfaceidlhxx.substitute(component=self.name,inherited=Inherited, services="\n".join(services))
+
+ def getIdlDefs(self):
idldefs="""#include "ParaMEDMEMComponent.idl"\n"""
- return interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services))
+ if self.interfacedefs:
+ idldefs = idldefs + self.interfacedefs
+ return idldefs
+
+ def getDependentModules(self):
+ """ This component depends on "MED" because it inherits from ParaMEDMEMComponent
+ """
+ depend_modules = Component.getDependentModules(self)
+ depend_modules.add("MED")
+ return depend_modules
: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 kind: For this type of component, "lib" is the unique valid option. The component is built 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")]
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),
+ ret = { cxxfile:self.makecxx(gen),
hxxfile:self.makehxx(gen)
}
sources = " ".join(map(os.path.basename,self.sources))
servicesdef=servicesdef, inheritedclass=inheritedclass,
compodefs=compodefs)
- def makecxx(self, gen, exe=0):
+ def makecxx(self, gen):
"""return a string that is the content of .cxx file
"""
services = []