--- /dev/null
+#!/usr/bin/env python
+
+import os
+
+def relpath(target, base):
+ """ Find relative path from base to target
+ if target== "/local/chris/appli" and base== "/local/chris" the result is appli
+ if target== /tmp/appli and base /local/chris the result is ../../tmp/appli
+ """
+ target=target.split(os.path.sep)
+ base=base.split(os.path.sep)
+ for i in xrange(len(base)):
+ if base[i] != target[i]:
+ i=i-1
+ #not in base
+ break
+ p=['..']*(len(base)-i-1)+target[i+1:]
+ if p == []:
+ return '.'
+ return os.path.join( *p )
+
+def set_var(VAR, strpath):
+ """Set VAR environment variable """
+ value = "%r" % strpath
+ shell = os.getenv('SHELL')
+ if shell and shell.endswith('csh'):
+ return "setenv %s %s" % (VAR, value)
+ else:
+ return "export %s=%s" % (VAR, value)
+
+
+applipath=relpath(os.path.abspath(os.path.dirname(__file__)),os.path.abspath(os.getenv('HOME')))
+
+#print set_var('APPLI', applipath)
+print applipath
--- /dev/null
+# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG
+# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT
+# 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
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# ---
+#
+# File : salome_utilities.py
+# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+#
+# ---
+
+"""
+Set of utility functions used by SALOME python scripts.
+"""
+
+#
+# Exported functions
+#
+__all__ = [
+ 'getORBcfgInfo',
+ 'getHostFromORBcfg',
+ 'getPortFromORBcfg',
+ 'getUserName',
+ 'getHostName',
+ 'getShortHostName',
+ 'getAppName',
+ 'getPortNumber',
+ 'getTmpDir',
+ 'generateFileName',
+ ]
+
+# ---
+
+def _try_bool( arg ):
+ """
+ Check if specified parameter represents boolean value and returns its value.
+ String values like 'True', 'TRUE', 'YES', 'Yes', 'y', 'NO', 'false', 'n', etc
+ are supported.
+ If <arg> does not represent a boolean, an exception is raised.
+ """
+ import types
+ if type( arg ) == types.BooleanType :
+ return arg
+ elif type( arg ) == types.StringType :
+ v = str( arg ).lower()
+ if v in [ "yes", "y", "true" ]: return True
+ elif v in [ "no", "n", "false" ]: return False
+ pass
+ raise Exception("Not boolean value")
+
+# ---
+
+def getORBcfgInfo():
+ """
+ Get omniORB current configuration.
+ Returns a list of three values: [ orb_version, host_name, port_number ].
+
+ The information is retrieved from the omniORB configuration file defined
+ by the OMNIORB_CONFIG environment variable.
+ If omniORB configuration file can not be accessed, a list of three empty
+ strings is returned.
+ """
+ import os, re
+ ret = [ "", "", "" ]
+ try:
+ f = open( os.getenv( "OMNIORB_CONFIG" ) )
+ lines = f.readlines()
+ f.close()
+ regvar = re.compile( "(ORB)?InitRef.*corbaname::(.*):(\d+)\s*$" )
+ for l in lines:
+ try:
+ m = regvar.match( l )
+ if m:
+ if m.group(1) is None:
+ ret[0] = "4"
+ else:
+ ret[0] = "3"
+ pass
+ ret[1] = m.group(2)
+ ret[2] = m.group(3)
+ break
+ pass
+ except:
+ pass
+ pass
+ pass
+ except:
+ pass
+ return ret
+
+# ---
+
+def getHostFromORBcfg():
+ """
+ Get current omniORB host.
+ """
+ return getORBcfgInfo()[1]
+# ---
+
+def getPortFromORBcfg():
+ """
+ Get current omniORB port.
+ """
+ return getORBcfgInfo()[2]
+
+# ---
+
+def getUserName():
+ """
+ Get user name:
+ 1. try USER environment variable
+ 2. if fails, return 'unknown' as default user name
+ """
+ import os
+ return os.getenv( "USER", "unknown" ) # 'unknown' is default user name
+
+# ---
+
+def getHostName():
+ """
+ Get host name:
+ 1. try socket python module gethostname() function
+ 2. if fails, try HOSTNAME environment variable
+ 3. if fails, try HOST environment variable
+ 4. if fails, return 'unknown' as default host name
+ """
+ import os
+ try:
+ import socket
+ host = socket.gethostname()
+ except:
+ host = None
+ pass
+ if not host: host = os.getenv("HOSTNAME")
+ if not host: host = os.getenv("HOST")
+ if not host: host = "unknown" # 'unknown' is default host name
+ return host
+
+# ---
+
+def getShortHostName():
+ """
+ Get short host name:
+ 1. try socket python module gethostname() function
+ 2. if fails, try HOSTNAME environment variable
+ 3. if fails, try HOST environment variable
+ 4. if fails, return 'unknown' as default host name
+ """
+ try:
+ return getHostName().split('.')[0]
+ except:
+ pass
+ return "unknown" # 'unknown' is default host name
+
+# ---
+
+def getAppName():
+ """
+ Get application name:
+ 1. try APPNAME environment variable
+ 2. if fails, return 'SALOME' as default application name
+ """
+ import os
+ return os.getenv( "APPNAME", "SALOME" ) # 'SALOME' is default user name
+
+# ---
+
+def getPortNumber():
+ """
+ Get current naming server port number:
+ 1. try NSPORT environment variable
+ 1. if fails, try to parse config file defined by OMNIORB_CONFIG environment variable
+ 2. if fails, return 2809 as default port number
+ """
+ import os
+ try:
+ return int( os.getenv( "NSPORT" ) )
+ except:
+ pass
+ port = getPortFromORBcfg()
+ if port is not None: return port
+ return 2809 # '2809' is default port number
+
+# ---
+
+def getTmpDir():
+ """
+ Get directory to be used for the temporary files.
+ """
+ import os, sys
+ if sys.platform == "win32":
+ # for Windows: temporarily using home directory for tmp files;
+ # to be replaced with TEMP environment variable later...
+ dir = os.getenv("HOME")
+ else:
+ # for Linux: use /tmp/logs/{user} folder
+ dir = os.path.join( '/tmp', 'logs', getUserName() )
+ pass
+ return dir
+
+# ---
+
+def generateFileName( dir, prefix = None, suffix = None, extension = None,
+ unique = False, separator = "_", hidden = False, **kwargs ):
+ """
+ Generate file name by sepecified parameters. If necessary, file name
+ can be generated to be unique.
+
+ Parameters:
+ - dir : directory path
+ - prefix : file prefix (not added by default)
+ - suffix : file suffix (not added by default)
+ - extension : file extension (not added by default)
+ - unique : if this parameter is True, the unique file name is generated:
+ in this case, if the file with the generated name already exists
+ in the <dir> directory, an integer suffix is added to the end of the
+ file name. This parameter is False by default.
+ - separator : separator of the words ('_' by default)
+ - hidden : if this parameter is True, the file name is prepended by . (dot)
+ symbol. This parameter is False by default.
+
+ Other keyword parameters are:
+ - with_username : 'add user name' flag/option:
+ * boolean value can be passed to determine user name automatically
+ * string value to be used as user name
+ - with_hostname : 'add host name' flag/option:
+ * boolean value can be passed to determine host name automatically
+ * string value to be used as host name
+ - with_port : 'add port number' flag/option:
+ * boolean value can be passed to determine port number automatically
+ * string value to be used as port number
+ - with_app : 'add application name' flag/option:
+ * boolean value can be passed to determine application name automatically
+ * string value to be used as application name
+ All <with_...> parameters are optional.
+ """
+ supported = [ 'with_username', 'with_hostname', 'with_port', 'with_app' ]
+ from launchConfigureParser import verbose
+ filename = []
+ # separator
+ if separator is None:
+ separator = ""
+ pass
+ else:
+ separator = str( separator )
+ pass
+ # prefix (if specified)
+ if prefix is not None:
+ filename.append( str( prefix ) )
+ pass
+ # additional keywords
+ ### check unsupported parameters
+ for kw in kwargs:
+ if kw not in supported and verbose():
+ print 'Warning! salome_utilitie.py: generateFileName(): parameter %s is not supported' % kw
+ pass
+ pass
+ ### process supported keywords
+ for kw in supported:
+ if kw not in kwargs: continue
+ ### user name
+ if kw == 'with_username':
+ try:
+ # auto user name ?
+ if _try_bool( kwargs[kw] ): filename.append( getUserName() )
+ pass
+ except:
+ # user name given as parameter
+ filename.append( kwargs[kw] )
+ pass
+ pass
+ ### host name
+ elif kw == 'with_hostname':
+ try:
+ # auto host name ?
+ if _try_bool( kwargs[kw] ): filename.append( getShortHostName() )
+ pass
+ except:
+ # host name given as parameter
+ filename.append( kwargs[kw] )
+ pass
+ pass
+ ### port number
+ elif kw == 'with_port':
+ try:
+ # auto port number ?
+ if _try_bool( kwargs[kw] ): filename.append( str( getPortNumber() ) )
+ pass
+ except:
+ # port number given as parameter
+ filename.append( str( kwargs[kw] ) )
+ pass
+ pass
+ ### application name
+ elif kw == 'with_app':
+ try:
+ # auto application name ?
+ if _try_bool( kwargs[kw] ): filename.append( getAppName() )
+ pass
+ except:
+ # application name given as parameter
+ filename.append( kwargs[kw] )
+ pass
+ pass
+ pass
+ # suffix (if specified)
+ if suffix is not None:
+ filename.append( str( suffix ) )
+ pass
+ # raise an exception if file name is empty
+ if not filename:
+ raise Exception("Empty file name")
+ #
+ if extension is not None and extension.startswith("."): extension = extension[1:]
+ #
+ import os
+ name = separator.join( filename )
+ if hidden: name = "." + name # add dot for hidden files
+ if extension: name = name + "." + str( extension ) # add extension if defined
+ name = os.path.join( dir, name )
+ if unique:
+ # create unique file name
+ index = 0
+ while os.path.exists( name ):
+ index = index + 1
+ name = separator.join( filename ) + separator + str( index )
+ if hidden: name = "." + name # add dot for hidden files
+ if extension: name = name + "." + str( extension ) # add extension if defined
+ name = os.path.join( dir, name )
+ pass
+ pass
+ return name
--- /dev/null
+#! /bin/sh
+status=1
+while [ $status -ne 0 ]; do
+ ls $HOME/$APPLI/.omniORB_last.cfg >& /dev/null
+ status=$?
+ sleep 1
+ echo -n "#"
+done
+./runSession waitNS.py
\ No newline at end of file
--- /dev/null
+/*!
+
+\page batch_page Batch
+
+<a href="Batch.html/index.html"> Batch documentation </a>
+
+*/
+
+
+
--- /dev/null
+/*!
+ \page INSTALL Installation instructions
+
+<b>NOT UP TO DATE %SALOME 4</b>
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+You'll find here generic instructions for installing the SALOME2 platform.
+
+\section Summary
+
+<ol>
+<li> \ref S1_install </li>
+<li> \ref S2_install </li>
+<li> \ref S3_install </li>
+<li> \ref S4_install </li>
+<li> \ref S5_install </li>
+<li> \ref S6_install </li>
+<li> \ref S7_install </li>
+<li> \ref S8_install </li>
+</ol>
+
+\section S1_install Quick Overview
+
+First of all, you have to check (or install if needed) the dependant
+software programs on your system. These programs are:
+
+- common development tools as gcc, automake, autoconf and libtools.
+- third party softwares used in SALOME building or runtime process
+ (python, OCC, VTK, ...)
+
+Further details can be found in sections [2] and [3].
+
+If the dependencies are installed on your system, then you have to set
+your shell environment to get access to the software components
+(cf. [4]. "Preparing the shell environment").
+
+The next step is to install the KERNEL (cf. [5] "Installing KERNEL"):
+
+\code
+$ mkdir <kernel_build>
+$ mkdir <kernel_install>
+$ cd <kernel_src>
+$ ./build_configure
+$ cd <kernel_build>
+$ <kernel_src>/configure --prefix=<kernel_install>
+$ make
+$ make install
+\endcode
+
+Then, the %SALOME components GEOM, MED, VISU, ... can be installed
+with a similar procedure (cf. [6]).
+
+Eventually, the platform ccodean be run by executing the shell script
+runSalome (cf. [7]). Here, somme additionnal variables have to be set
+to describe the %SALOME runtime configuration (<COMPONENT>_ROOT_DIR,
+OMNIORB_CONFIG)
+
+The following provides you with specific instructions for each step.
+
+
+\section S2_install System configuration
+
+%SALOME is compiled and tested on differents platforms with native packages:
+- Debian sarge
+- Mandrake 10.1
+- ...
+
+If you have another platform, we suggest the following configuration
+for building process:
+
+- gcc-3.3.x or 3.4.x
+- automake-1.7 or more (only aclocal is used)
+- autoconf-2.59
+- libtool-1.5.6
+
+remarks:
+
+- This is the minimum level of automake, autoconf and libtool, if you need
+ to compile all the third party softwares (included OpenCascade 5.2.x).
+
+\section S3_install Third-party dependencies
+
+The %SALOME platform relies on a set of third-party softwares. The
+current version depends on the following list
+(versions given here are from Debian Sarge, except OpenCascade, VTK and MED,
+which are not Debian packages):
+
+- CAS-5.2.4 OpenCascade (try binaries,a source patch is needed)
+- VTK-4.2.6 VTK 3D-viewer
+- PyQt-3.13 Python-Qt Wrapper
+- Python-2.3.5 Python interpreter
+- SWIG-1.3.24 SWIG library
+- boost-1_32_0 C++ library (only include templates are used)
+- hdf5-1.6.2 Files Database library
+- med-2.2.2 MED Data Format support for file records
+- omniORB-4.0.5 ORB used in %SALOME
+- qt-x11-free-3.3.3 Qt library
+- qwt-4.2 Graph components for Qt
+- sip4-4.1.1 langage binding software
+
+And, in order to build the documentation:
+
+- doxygen-1.4.2
+- graphviz-2.2.1
+
+
+Additionnal software may be installed for optional features:
+
+- netgen4.3 + patch
+- tix8.1.4
+- openpbs-2.3.16
+- lsf-???
+
+<b>To Do</b>
+
+- Instructions for installing these software programs can be found in a
+ special note doc/configuration_examples/install-prerequis.
+- Installation shell scripts are also provided.
+ These scripts have to be adapted to your own configuration.
+
+- See doc/configuration_examples/*
+
+In the following, we assume that all the third-party softwares are
+installed in the same root directory, named <salomeroot>/prerequis.
+Then, your file system should probably look like::
+
+\code
+<salomeroot>/prerequis/Python-2.2.2
+<salomeroot>/prerequis/omniORB-3.0.5
+<salomeroot>/prerequis/qt-x11-free-3.0.5
+...
+\endcode
+
+\section S4_install Preparing the shell environment
+
+Some variables have to be set to get acces to third-party software
+components (include files, executable, library, ...) during building
+process and runtime.
+
+The shell file prerequis.sh, embedded in the KERNEL source package,
+provides a template for setting those variables. In this example, all the
+softwares are supposed to be installed in the same root directory,
+named here INSTALLROOT.
+
+Copy the prerequis.sh in a working directory and adjust the settings
+to your own configuration. To get the shell prepared, just
+execute the following command in the building shell:
+
+\code
+$ source prerequis.sh
+\endcode
+
+(we assume here a ksh or bash mode)
+
+
+\section S5_install Installing the KERNEL component
+
+We use here the notation <kernel_src> to specify the source directory
+of the KERNEL component. The shell environment is supposed to have
+been set (cf. 4).
+
+Installing the KERNEL from a source package needs three directories:
+
+- the source directory, denoted here by <kernel_src>.
+
+- the build directory, denoted by <kernel_build> in the following. This
+ directory can't be the same directory as <kernel_src>.
+
+- the install directory, denoted by <kernel_install> in the following. This
+ directory can't be the same directory as <kernel_src> or
+ <kernel_build>.
+
+The installing process is:
+
+<b>STEP 1:</b>
+ preparing directories
+
+ create the <kernel_build> and the <kernel_install> directories:
+
+ \code
+$ mkdir <kernel_build>
+$ mkdir <kernel_install>
+\endcode
+
+<b>STEP 2:</b>
+ build configure script
+
+ go to <kernel_src> directory and generate the "configure" script:
+
+ \code
+$ cd <kernel_src>
+$ ./build_configure
+ \endcode
+
+ If it doesn't work, check your system automake tools as specified in
+ section [2].
+
+<b>STEP 3:</b>
+ configure the building process
+ go to the build directory and execute the configuration process::
+
+ \code
+$ cd <kernel_build>
+$ <kernel_src>/configure --prefix=<kernel_install>
+ \endcode
+
+ Note that <kernel_install> must be an absolute path.
+
+ When the configure process is complete, check the status of
+ third-party softwares detection. You should have a status like::
+
+ \code
+ ---------------------------------------------
+ Summary
+ ---------------------------------------------
+ Configure
+ cc : yes
+ boost : yes
+ lex_yacc : yes
+ python : yes
+ swig : yes
+ threads : yes
+ OpenGL : yes
+ qt : yes
+ vtk : yes
+ hdf5 : yes
+ med2 : yes
+ omniORB : yes
+ occ : yes
+ sip : yes
+ pyqt : yes
+ qwt : yes
+ doxygen : yes
+ graphviz : no
+ openpbs : no
+ lsf : no
+ Default ORB : omniORB
+ ----------------------------------------------
+ \endcode
+
+If a software get a status "no", then it's not "seen" in the system:
+
+- the software is not installed, or
+- the shell environment is not set correctly.
+
+In this example, the software programs graphviz, openpbs and lsf are not
+installed (optional for most usages).
+
+
+<b>STEP 4 :</b>
+ Building the binary files
+
+ Execute make in the <kernel_build> directory::
+
+ \code
+$ make
+ \endcode
+
+<b>STEP 5:</b>
+ Installing binary files, scripts and documentation
+
+ Execute install target in the <kernel_build> directory::
+
+ \code
+$ make install
+ \endcode
+
+\section S6_install Installing the SALOME components
+
+TInstalling a component <COMPONENT> is done by following the same
+instructions as given for the KERNEL, replacing KERNEL by
+<COMPONENT> (build_configure, configure, make, make install).
+
+You just have to be aware of the dependencies between components:
+
+- MED depends on KERNEL
+- GEOM depends on KERNEL
+- SMESH depends on KERNEL, MED, GEOM
+- VISU depends on KERNEL, MED
+- SUPERV depends on KERNEL
+
+For example, installing the component SMESH needs the previous
+installation of the KERNEL component, and then the GEOM and MED components.
+
+The building process uses the variables <COMPONENT>_ROOT_DIR to
+localize the dependant components. The variables must be set to the
+install path directory of the components <COMPONENT> (ex:
+KERNEL_ROOT_DIR=<kernel_install>).
+
+In the above example, the three variables KERNEL_ROOT_DIR,
+GEOM_ROOT_DIR and MED_ROOT_DIR have to be set before configuring the
+building process of the SMESH component (STEP 3).
+
+
+\section S7_install Runtime
+
+See SALOME_Application to define your own configuration of %SALOME and run it
+on one or several computers. This is the recommended way of configuration.
+
+The following explains the general principles.
+
+To run the %SALOME platform, the procedure is:
+
+- set the shell environment to get acces to third-party softwares:
+
+\code
+$ source prerequis.sh
+\endcode
+
+- define the %SALOME configuration by setting the whole set of
+ variables <COMPONENT>_ROOT_DIR. Here, you just have to set the
+ kernel and the components you need::
+
+ \code
+$ export KERNEL_ROOT_DIR=<kernel_install>
+$ export MED_ROOT_DIR=<med_install>
+$ ...
+ \endcode
+
+- define the CORBA configuration file by setting the variable
+ OMNIORB_CONFIG. This variable must be set to a writable file
+ path. The file may be arbitrary chosen and doesn't need to exist
+ before running. We suggest::
+
+ \code
+$ export OMNIORB_CONFIG=$HOME/.omniORB.cfg
+ \endcode
+
+- run the %SALOME platform by executing the script runSalome:
+
+ \code
+$KERNEL_ROOT_DIR/bin/salome/runSalome
+ \endcode
+
+\section S8_install Suggestions and advices
+
+For convenience or customization, we suggest the following organisation:
+
+- chose and create a root directory for the %SALOME platform, say
+ <salomeroot>.
+
+- install the third-party softwares in a sub-directory "prerequis"
+
+- install the %SALOME components in a sub-directory "SALOME2"
+
+- make personnal copies of the files prerequis.sh and runSalome in
+ <salomeroot>:
+
+ \code
+$ cp <kernel_src>/prerequis.sh <rundir>/.
+$ cp <kernel_install>/bin/salome/runSalome <rundir>/.
+ \endcode
+
+ Edit the file prerequis.sh and adjust it to your own configuration.
+
+- define the SALOME2 configuration
+
+ This step consists in setting the KERNEL_ROOT_DIR, the whole set of
+ variables <COMPONENT>_ROOT_DIR you need, and the OMNIORB_CONFIG
+ variable.
+
+ We suggest to create a shell file envSalome.sh containing those
+ settings. Then the configuration consists in loading envSalome.sh in
+ the runtime shell:
+
+\code
+$ source envSalome.sh
+\endcode
+
+- When installed with this file organisation, running %SALOME is done
+ with the following shell commands::
+
+ \code
+ $ source <salomeroot>/prerequis.sh
+ $ source <salomeroot>/envSalome.sh
+ $ ./runSalome
+ \endcode
+*/
--- /dev/null
+/*!
+
+\page kernel_resources SALOME Kernel resources for developer
+
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+
+\section S1_kernel_res Abstract
+
+This document describes the development environment for
+C++ and Python. Makefiles generation and usage are
+introduced in another document: "using the %SALOME
+configuration and building system environment".
+Development environment is intended here as: trace and
+debug macros usage; %SALOME exceptions usage, in C++ and
+Python; user CORBA exceptions usage, in C++ and Python,
+with and without Graphical User Interface; some general
+purpose services such as singleton, used for CORBA
+connection and disconnection.
+
+\section S2_kernel_res Trace and debug Utilities
+
+During the development process, an execution log is
+useful to identify problems. This log contains
+messages, variables values, source files names and line
+numbers. It is recommended to verify assertions on
+variables values and if necessary, to stop the
+execution at debug time, in order to validate all parts
+of code.
+
+<ol>
+<li>
+<b>Two modes: debug and release</b>
+
+The goal of debug mode is to check as many features as
+possible during the early stages of the development
+process. The purpose of the utilities provided in
+%SALOME is to help the developer to add detailed traces
+and check variables values, without writing a lot of code.
+
+When the code is assumed to be valid, the release mode
+optimizes execution, in terms of speed, memory, and
+display only user level messages.
+
+But, some informations must always be displayed in both
+modes: especially messages concerning environment or
+internal errors, with version identification. When an
+end user is confronted to such a message, he may refer
+to a configuration documentation or send the message to
+the people in charge of %SALOME installation, or to the
+development team, following the kind of error.
+</li>
+<li>
+<b>C++ Macros for trace and debug</b>
+
+%SALOME provides C++ macros for trace and debug. These
+macros are in:
+
+\code
+KERNEL_SRC/src/SALOMELocalTrace/utilities.h
+\endcode
+
+This file must be included in C++ source. Some
+macros are activated only in debug mode, others are
+always activated. To activate the debug mode, ``_DEBUG_``
+must be defined, which is the case when %SALOME
+Makefiles are generated from configure, without
+options. When ``_DEBUG_`` is undefined (release mode:
+``configure --disable-debug --enable-production``), the
+debug mode macros are defined empty (they do nothing).
+So, when switching from debug to release, it is
+possible (and recommended) to let the macro calls
+unchanged in the source.
+
+All the macros generate trace messages, stored in a
+circular buffer pool. %A separate %thread reads the
+messages in the buffer pool, and, depending on options
+given at %SALOME start, writes the messages on the
+standard output, a file, or send them via CORBA, in
+case of a multi machine configuration.
+
+Three informations are systematically added in front of
+the information displayed:
+
+- the %thread number from which the message come from;
+
+- the name of the source file in which the macros is set;
+
+- the line number of the source file at which the macro
+ is set.
+
+<ol>
+<li>
+<b>Macros defined in debug and release modes</b>
+\n
+<b>INFOS_COMPILATION</b>
+
+ The C++ macro INFOS_COMPILATION writes on the trace
+ buffer pool informations about the compiling process:
+
+ - the name of the compiler : g++, KCC, CC, pgCC;
+
+ - the date and the time of the compiling processing process.
+
+ This macro INFOS_COMPILATION does not have any
+ argument. Moreover, it is defined in both compiling
+ mode : _DEBUG_ and _RELEASE_.
+
+ Example:
+
+ \code
+#include "utilities.h"
+int main(int argc , char **argv)
+{
+ INFOS_COMPILATION;
+ ...
+}
+INFOS(str)
+ \endcode
+\n
+<b>INFOS</b>
+
+ In both compiling mode _DEBUG_ and _RELEASE_, The C++
+ macro INFOS writes on the trace buffer pool %the string
+ which has been passed in argument by the user.
+
+ Example:
+
+ \code
+#include "utilities.h"
+int main(int argc , char **argv)
+{
+ ...
+ INFOS("NORMAL END OF THE PROCESS");
+ return 0;
+}
+ \endcode
+
+ Displays:
+
+ \code
+main.cxx [5] : NORMAL END OF THE PROCESS
+ \endcode
+\n
+<b>INTERRUPTION(str)</b>
+
+ In both compiling mode _DEBUG_ and _RELEASE_, The C++
+ macro INTERRUPTION writes on the trace buffer pool the
+ %string, with a special ABORT type. When the %thread in
+ charge of collecting messages finds this message, it
+ terminates the application, after message treatment.
+
+<b>IMMEDIATE_ABORT(str)</b>
+
+ In both compiling mode _DEBUG_ and _RELEASE_, The C++
+ macro IMMEDIATE_ABORT writes the message str immediately on
+ standard error and exits the application. Remaining
+ messages not treated by the message collector %thread
+ are lost.
+
+</li>
+<li>
+<b>Macros defined only in debug mode</b>
+\n
+<b>MESSAGE(str)</b>
+
+ In _DEBUG_ compiling mode only, the C++ macro MESSAGE
+ writes on the trace buffer pool the %string which has
+ been passed in argument by the user. In _RELEASE_
+ compiling mode, this macro is blank.
+
+ Example:
+
+ \code
+#include "utilities.h"
+#include <string>
+
+using namespace std;
+
+int main(int argc , char **argv)
+{
+ ...
+ const char *str = "Salome";
+ MESSAGE(str);
+ ... const string st;
+ st = "Aster";
+ MESSAGE(c_str(st+" and CASTEM"));
+ return 0;
+}
+
+ \endcode
+
+ Displays:
+
+ \code
+- Trace main.cxx [8] : Salome
+- Trace main.cxx [12] : Aster and CASTEM
+ \endcode
+
+\n
+<b>BEGIN_OF(func_name)</b>
+
+ In _DEBUG_ compiling mode, The C++ macro BEGIN_OF
+ appends the %string "Begin of " to the one passed in
+ argument by the user and displays the result on the
+ trace buffer pool. In _RELEASE_ compiling mode, this
+ macro is blank.
+
+ Example:
+
+ \code
+#include "utilities.h"
+int main(int argc , char **argv)
+{
+ BEGIN_OF(argv[0]);
+ return 0;
+}
+ \endcode
+
+ Displays:
+
+ \code
+ - Trace main.cxx [3] : Begin of a.out
+ \endcode
+\n
+<b>END_OF(func_name)</b>
+
+ In _DEBUG_ compiling mode, The C++ macro END_OF appends
+ the %string "Normal end of " to the one passed in
+ argument by the user and displays the result on the
+ trace buffer pool. In _RELEASE_ compiling mode, this
+ macro is blank.
+
+ Example:
+
+ \code
+#include "utilities.h"
+int main(int argc , char **argv)
+{
+ END_OF(argv[0]);
+ return 0;
+}
+ \endcode
+
+ Displays:
+
+ \code
+- Trace main.cxx [4] : Normal end of a.out
+ \endcode
+\n
+<b>SCRUTE(var)</b>
+
+ In _DEBUG_ compiling mode, The C++ macro SCRUTE
+ displays its argument which is an application variable
+ followed by the value of the variable. In _RELEASE_
+ compiling mode, this macro is blank.
+
+ Example:
+
+ \code
+#include "utilities.h"
+int main(int argc , char **argv)
+{
+ const int i=999;
+ if( i > 0 ) SCRUTE(i) ; i=i+1;
+ return 0;
+}
+ \endcode
+
+ Displays:
+
+ \code
+- Trace main.cxx [5] : i=999
+ \endcode
+\n
+<b>ASSERT(condition)</b>
+
+ In _DEBUG_ compiling mode only, The C++ macro ASSERT
+ checks the expression passed in argument to be not
+ NULL. If it is NULL the condition is written with the
+ macro INTERRUPTION (see above). The process exits after
+ trace of this last message. In _RELEASE_ compiling
+ mode, this macro is blank. N.B. : if ASSERT is already
+ defined, this macro is ignored.
+
+ Example:
+
+ \code
+#include "utilities.h"
+...
+const char *ptrS = fonc();
+ASSERT(ptrS!=NULL);
+cout << strlen(ptrS);
+float table[10];
+int k;
+...
+ASSERT(k<10);
+cout << table[k];
+ \endcode
+
+</li>
+</ol>
+</li>
+</ol>
+
+\section S3_kernel_res Exceptions
+
+<ol>
+<li>
+<b>C++ exceptions: class SALOME_Exception</b>
+
+<ol>
+<li>
+<b>definition</b>
+
+The class SALOME_Exception provides a generic method to
+send a message, with optional source file name and line
+number. This class is intended to serve as a base class
+for all kinds of exceptions %SALOME code. All the
+exceptions derived from SALOME_Exception could be
+handled in a single catch, in which the message
+associated to the exception is displayed, or sent to a
+log file.
+
+The class SALOME_Exception inherits its behavior from
+the STL class exception.
+</li>
+<li>
+<b>usage</b>
+
+The header %SALOME/src/utils/utils_SALOME_Exception.hxx
+must be included in the C++ source, when raised or trapped:
+
+\code
+#include "utils_SALOME_Exception.hxx"
+\endcode
+
+The SALOME_Exception constructor is:
+
+\code
+SALOME_Exception( const char *text,
+ const char *fileName=0,
+ const unsigned int lineNumber=0 );
+\endcode
+
+The exception is raised like this:
+
+\code
+throw SALOME_Exception("my pertinent message");
+\endcode
+
+or like this:
+
+\code
+throw SALOME_Exception(LOCALIZED("my pertinent message"));
+\endcode
+
+where LOCALIZED is a macro provided with
+``utils_SALOME_Exception.hxx`` which gives file name and
+line number.
+
+The exception is handled like this:
+
+\code
+ try
+{
+ ...
+}
+catch (const SALOME_Exception &ex)
+{
+ cerr << ex.what() <<endl;
+}
+\endcode
+
+The what() method overrides the one defined in the STL
+exception class.
+</li>
+</ol>
+</li>
+<li>
+<b>CORBA exceptions</b>
+
+<ol>
+<li>
+<b>definition</b>
+
+The idl SALOME_Exception provides a generic CORBA
+exception for %SALOME, with an attribute that gives an
+exception type,a message, plus optional source file
+name and line number.
+
+This idl is intended to serve for all user CORBA
+exceptions raised in %SALOME code, as IDL specification
+does not support exception inheritance. So, all the
+user CORBA exceptions from %SALOME could be handled in a
+single catch.
+
+The exception types defined in idl are:
+
+ - COMM CORBA communication problem,
+
+ - BAD_PARAM Bad User parameters,
+
+ - INTERNAL_ERROR application level problem (often irrecoverable).
+
+CORBA system and user exceptions already defined in the
+packages used within %SALOME, such as OmniORB
+exceptions, must be handled separately.
+
+</li>
+<li>
+<b>usage</b>
+<ol>
+<li>
+<b>CORBA servant, C++</b>
+
+ The CORBA Server header for SALOME_Exception and a
+ macro to throw the exception are provided with the
+ header ``KERNEL_SRC/src/Utils/Utils_CorbaException.hxx``:
+
+ \code
+#include "Utils_CorbaException.hxx"
+ \endcode
+
+ The exception is raised with a macro which appends file
+ name and line number:
+
+ \code
+if (myStudyName.size() == 0)
+ THROW_SALOME_CORBA_EXCEPTION("No Study Name given",
+ SALOME::BAD_PARAM);
+ \endcode
+
+</li>
+<li>
+<b>CORBA Client, GUI Qt C++</b>
+
+ <b>NO MORE AVAILABLE in %SALOME 3.x</b>
+
+ The CORBA Client header for SALOME_Exception and a Qt
+ function header that displays a message box are
+ provided in:
+
+ ``KERNEL_SRC/src/SALOMEGUI/SALOMEGUI_QtCatchCorbaException.hxx``
+
+ \code
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+ \endcode
+
+ %A typical exchange with a CORBA Servant will be:
+
+ \code
+try
+{
+ ... // one ore more CORBA calls
+}
+
+catch (const SALOME::SALOME_Exception & S_ex)
+{
+ QtCatchCorbaException(S_ex);
+}
+ \endcode
+
+</li>
+<li>
+<b>CORBA Client, C++, without GUI</b>
+
+ Nothing specific has been provided to the developer
+ yet. See the idl or the Qt function
+ SALOMEGUI_QtCatchCorbaException.hxx to see how to get
+ the information given by the exception %object.
+
+</li>
+</ol>
+</li>
+</ol>
+</ol>
+
+\section S4_kernel_res Miscellaneous tools
+
+<ol>
+<li>
+<b>Singleton</b>
+<ol>
+<li>
+<b>Definition</b>
+
+%A singleton is an application data which is created and
+deleted only once at the end of the application
+process. The C++ compiler allows the user to create a
+static singleton data before the first executable
+statement. They are deleted after the last statement execution.
+
+The ``SINGLETON_`` template class deals with dynamic
+singleton. It is useful for functor objects. For
+example, an %object that connects the application to a
+system at creation and disconnects the application at deletion.
+
+</li>
+<li>
+<b>Usage</b>
+
+To create a single instance of a POINT %object:
+
+\code
+# include "Utils_SINGLETON.hxx"
+...
+POINT *ptrPoint=SINGLETON_<POINT>::Instance() ;
+assert(ptrPoint!=NULL) ;
+\endcode
+
+No need to delete ptrPoint. Deletion is achieved
+automatically at exit. If the user tries to create more
+than one singleton by using the class method
+SINGLETON_<TYPE>::Instance(), the pointer is returned
+with the same value even if this is done in different
+functions (threads ?):
+
+\code
+POINT *p1=SINGLETON_<POINT>::Instance() ;
+...
+POINT *p2=SINGLETON_<POINT>::Instance() ;
+
+assert(p1==p2)
+\endcode
+
+</li>
+<li>
+<b>Design description</b>
+
+Here are the principles features of the singleton
+design:
+
+- the user creates an %object of class TYPE by using the
+ class method ``SINGLETON_<TYPE>::Instance()`` which
+ returns a pointer to the single %object ;
+
+- to create an %object, ``SINGLETON_<TYPE>::Instance()``
+ uses the default constructor of class TYPE ;
+
+- at the same time, this class method creates a
+ destructor %object which is added to the generic list
+ of destructor objects to be executed at the end of
+ the application (atexit) ;
+
+- at the end of the application process all the
+ deletions are performed by the ``Nettoyage()`` C function
+ which executes the destruction objects end then
+ deletes the destructions objects themselves ;
+
+- the ``Nettoyage()`` C function using ``atexit()`` C function
+ is embedded in a static single %object ``ATEXIT_()``.
+
+</li>
+</ol>
+</li>
+</ol>
+
+*/
--- /dev/null
+/*!
+ \page KERNEL_Services KERNEL Services for end user (Python interface)
+
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+In a %SALOME application, distributed components, servers and clients use
+the CORBA middleware for comunication. CORBA interfaces are defined via idl
+files. All the different CORBA interfaces are available for users in Python,
+see CORBA interfaces below.
+
+For some general purpose services, CORBA interfaces have been encapsulated
+in order to provide a simple interface (encapsulation is generally done in
+C++ classes, and a Python SWIG interface is also generated from C++, to
+ensure a consistent behavior between C++ modules and Python modules or user
+script).
+
+\section S1_kernel_ser General purpose services
+
+<ol>
+<li>
+<b>%SALOME services access from a Python shell</b>
+
+See \ref SALOME_Application for detailed instructions to launch a Python
+interpreter with full acces to the %SALOME environment and services.
+
+You can use the embedded Python interpreter in Grahic User Interface, or an
+external interpreter, with:
+
+\code
+./runSession
+python
+\endcode
+
+In either cases, %SALOME services access is done with:
+
+\code
+import salome
+salome.salome_init()
+\endcode
+
+In the embedded interpreter, it is already done, but there is no problem to
+do it several times, so it is preferable to add these instructions
+systematically in your scripts, to allow them to work in all configurations.
+
+</li>
+<li>
+<b>Container and component instanciation</b>
+
+See LifeCycleCORBA for the C++ interface (Python interface obtained with SWIG
+is very similar).
+
+In the following example, a test component provided in KERNEL is launched
+in the local container, "FactoryServer", created when %SALOME starts:
+
+\code
+import salome
+salome.salome_init()
+
+import LifeCycleCORBA
+lcc = LifeCycleCORBA.LifeCycleCORBA()
+obj=lcc.FindOrLoad_Component("FactoryServer","SalomeTestComponent")
+
+import Engines
+comp=obj._narrow(Engines.TestComponent)
+
+comp.Coucou(1)
+\endcode
+
+The answer is something like:
+
+\code
+'TestComponent_i : L = 1'
+\endcode
+
+The _narrow() instruction is not always mandatory in Python, but sometimes
+useful to be sure you have got the right type of %object. Here, Testcomponent
+interface is defined in CORBA module Engines. With this example, it works also
+without the _narrow() instruction:
+
+\code
+ obj.Coucou(1)
+\endcode
+
+In the next example, a component instance is created in a specific Container
+defined by it's computer hostname and it's name. Here we use the local
+computer. Note that in Utils_Identity, getShortHostName() gives the short
+hostname of the computer, without domain suffixes, which is used in %SALOME.
+The container process is created here if it does not exists, and a new
+component instance is created:
+
+\code
+import salome
+salome.salome_init()
+import LifeCycleCORBA
+lcc = LifeCycleCORBA.LifeCycleCORBA()
+
+import Utils_Identity
+host = Utils_Identity.getShortHostName()
+
+import Engines
+params={}
+params['hostname']=host
+params['container_name']='myContainer'
+comp=lcc.LoadComponent(params,'SalomeTestComponent')
+comp.Coucou(1)
+\endcode
+
+If you want to get a list of containers and component instances, client %object
+from orbmodule provides a list:
+
+\code
+import orbmodule
+clt=orbmodule.client()
+clt.showNS()
+\endcode
+
+The list looks like:
+
+\code
+Logger.
+ContainerManager.object
+Containers.dir
+ cli70ac.dir
+ FactoryServerPy.object
+ SuperVisionContainer.object
+ FactoryServer.object
+ FactoryServer.dir
+ SalomeTestComponent_inst_1.object
+ myContainer.object
+ myContainer.dir
+ SalomeTestComponent_inst_1.object
+ SalomeTestComponent_inst_2.object
+Registry.object
+Kernel.dir
+ ModulCatalog.object
+ Session.object
+Study.dir
+ Study2.object
+ extStudy_1.object
+ extStudy_2.object
+ extStudy_3.object
+myStudyManager.object
+SalomeAppEngine.object
+\endcode
+
+</li>
+<li>
+<b>File transfer service</b>
+
+See SALOME_FileTransferCORBA for the C++ interface (Python interface obtained with
+SWIG is very similar).
+
+The following example shows how to tranfer a file from a remote host to the
+client computer. Remote hostname is 'cli76cc', we would like to copy
+'tkcvs_8_0_3.tar.gz' from remote to local computer. %A full pathname is
+required. %A container is created on remote computer if it does not exist,
+to handle the file transfer:
+
+\code
+import salome
+salome.salome_init()
+
+import LifeCycleCORBA
+remotefile="/home/prascle/tkcvs_8_0_3.tar.gz"
+aFileTransfer=LifeCycleCORBA.SALOME_FileTransferCORBA('cli76cc',remotefile)
+localFile=aFileTransfer.getLocalFile()
+\endcode
+
+</li>
+<li>
+<b>CORBA Naming service access</b>
+
+See SALOME_NamingService for the C++ interface. The Python interface
+SALOME_NamingServicePy is not yet derived from the C++ interface and offers
+only the most useful functions.
+
+</li>
+<li>
+<b>Batch services</b>
+
+See \ref batch_page documentation (in french only).
+
+</li>
+</ol>
+
+\section S2_kernel_ser All IDL Interfaces
+
+<ol>
+<li>
+<b>Containers and component life cycle, File transfer service</b>
+
+- Engines : engines CORBA module.
+- Engines::Component : generic component interface. All %SALOME components inherit this interface.
+- Engines::Container : host for C++ and Python components components instances
+- Engines::fileTransfer : agent for file transfer created by a container copy a local file to a distent client
+- Engines::fileRef : reference to a file, used by a container for file transfers
+- Engines::ContainerManager : unique instance, in charge of container creation on remote computers
+- Engines::MPIContainer : an exemple of parallel implementation for containers and components
+- Engines::MPIObject
+
+</li>
+<li>
+<b>Study management</b>
+
+- SALOMEDS : SALOMEDS CORBA module
+- SALOMEDS.idl
+- SALOMEDS_Attributes.idl
+
+</li>
+<li>
+<b>High speed transfer, object life cycle, exceptions, GUI interface...</b>
+
+- SALOME : %SALOME CORBA module
+- SALOME_Comm.idl
+- SALOME_GenericObj.idl
+- SALOME_Exception
+- SALOME_Session.idl
+
+</li>
+<li>
+<b>Miscelleanous</b>
+
+- SALOME_ModuleCatalog
+- SALOME_RessourcesCatalog
+- SALOME_Registry.idl
+- Logger.idl
+
+<b>Other idl for test purposes</b>
+\n
+- nstest.idl
+- SALOME_TestComponent.idl
+- SALOME_TestModuleCatalog.idl
+- SALOME_TestMPIComponent.idl
+- TestNotif.idl
+
+*/
--- /dev/null
+/*! \mainpage SALOME KERNEL Reference Documentation
+ \image html kernel_about_4.png
+
+ \section S1_main Introduction
+
+ Welcome to the %SALOME KERNEL documentation !
+
+ Following your kind of usage of %SALOME, you will find some specific
+ introductory documentation, listed below.
+
+ \section S2_main End user
+
+<ol>
+ <li>
+ <b>How to configure a %SALOME application</b>
+ \n The end user may have to configure his own %SALOME application by selection of a
+ subset of availables %SALOME modules. He also may want to install his
+ application on several computers.
+ See \subpage SALOME_Application to define your own configuration of %SALOME and run it
+ on one or several computers. This is the recommended way of configuration.
+ </li>
+ <li>
+ <b>How to launch %SALOME in a %SALOME application</b>
+ \n See \ref SALOME_Application.
+ </li>
+ <li>
+ <b>How to use KERNEL services in Python scripts</b>
+ \n The %SALOME KERNEL offers a list of services available in Python. See \subpage KERNEL_Services.
+ </li>
+</ol>
+
+ \section S3_main Application Integrator
+
+ Applications integrators are in charge of configuration and installation of
+ specific %SALOME applications over a local network. Application Integrators
+ built %SALOME modules binaries from sources tarballs.
+
+<ol>
+ <li>
+ <b>How to install %SALOME</b>
+ \n See \subpage INSTALL for general information on required configuration and
+ prerequisites, compilation procedure, setting environment principles.
+ </li>
+ <li>
+ <b>How to configure a %SALOME application</b>
+ \n See \ref SALOME_Application to define your own configuration of %SALOME and run it
+ on one or several computers. This is the recommended way of configuration.
+ </li>
+</ol>
+
+ \section S4_main Module maintainer
+
+ Module maintainers are in charge of the development and debug of the %SALOME
+ modules. Each %SALOME module is stored in a CVS base. CVS bases are organised
+ in separate branches for developments and debug. All official or development
+ releases are identified by a CVS tag.
+
+<ol>
+ <li>
+ <b>Source code structuration and Unit Tests</b>
+ \n See \subpage UnitTests for general information on code directories structure,
+ unit tests associated to the different kind of classes, and how to run
+ the unit tests.
+ </li>
+ <li>
+ <b>Some development utilities</b>
+ \n See \subpage kernel_resources for information on basic utilities for C++ and Python
+ development, like trace and debug, exceptions, singleton.
+ </li>
+</ol>
+
+ \section S5_main SALOME programming model
+
+ You will find in the next pages informations about
+ specific points of %SALOME Kernel :
+
+ - \subpage dsc_page : DSC documentation page.
+ - \subpage salome_file_page : Salome_file documentation page.
+ - \subpage batch_page : BATCH documentation page.
+
+*/
+
--- /dev/null
+/*!
+ \page SALOME_Application SALOME Application Concept
+
+ <b>Configuration for one or more computers</b>
+
+
+<b> **WORK in PROGRESS, INCOMPLETE DOCUMENT** </b>
+
+The following explains how to configure your own application with your list of
+modules, how to define and run this application on one or more computers.
+
+\section S1_sal_appl General principles
+
+%A %SALOME application is defined by a set of modules (GEOM, SMESH, ASTER...).
+
+%A %SALOME User can define several %SALOME Applications. These applications are
+runnable from the same user account. These applications may share the same
+KERNEL and modules. Thus, the application configuration is independant of
+KERNEL and must not be put in KERNEL_ROOT_DIR.
+
+Furthermore, prerequisites may not be the same on all the applications.
+
+%A %SALOME Session can run on a several computers.
+
+Binary modules and prerequisites are installed on the different computers.
+There is no need to have all the modules on each computer (the minimum is
+KERNEL).
+
+There is no need of standardization or centralised information on the details
+of configuration on each computer (PATH, LD_LIBRARY_PATH, environment
+variables) provided the application modules are version - compatible. Details
+of configuration stay private to the computer, and are held by scripts on each
+computer.
+
+There is no hierarchy between the computers (for example only one master
+computer used to launch application).
+
+The %SALOME user has an account on all the computers. Access between
+account@computer is via rsh or ssh and must be configured for use without
+password (key exchange for ssh). Account may be different on each
+computer.
+
+\section S2_sal_appl Application Directory
+
+There are two ways for creation of an application directory, <b>the recommended way is
+the second, easier to configure.</b>
+
+<ol>
+ <li>
+ <b>First way - references to different module directories</b>
+
+The script createAppli.sh in ${KERNEL_ROOT_DIR}/bin/salome creates an
+application directory with the given path in parameter. The path given, ${APPLI}, is
+relative to ${HOME}.
+
+The directory is only a skeleton, the user has to edit several files to
+configure his own application. These files are described after, the list is:
+
+- env.d/atFirst.sh
+- env.d/envProducts.sh
+- env.d/envSALOME.sh
+- CatalogResources.xml
+- SALOMEApp.xml
+
+ </li>
+ <li>
+ <b>Second and easiest way - one single virtual install directory</b>
+
+The user must create a %SALOME application configuration file by modifying a
+copy of ${KERNEL_ROOT_DIR}/bin/salome/config_appli.xml.
+The file describes the list of %SALOME modules used in the application, with
+their respective installation path. The configuration file also defines the
+path of an existing script which sets the %SALOME prerequisites,
+and optionnaly, the path of samples directory (SAMPLES_SRC).
+The following command::
+
+\code
+python <KERNEL_ROOT_DIR>/bin/salome/appli_gen.py --prefix=<install directory> --config=<configuration file>
+\endcode
+
+creates a virtual installation of %SALOME in the application directory ${APPLI}
+(bin, lib, doc, share...), with, for each file (executable, script, data,
+library, resources...), symbolic links to the actual file.
+<b>Note: it is recommended to set the environment for %SALOME prerequisites
+before invoking the above command, in order to use the same python as SALOME,
+otherwise installation may be wrong</b>
+
+Providing an existing script for %SALOME prerequisites (the same one
+used for modules compilation, or given with the modules installation), the
+installation works without further modification for a single computer (unless
+some modules needs a special environment not defined in the above script).
+For a distributed application (several computers), one must copy and adapt
+CatalogResources.xml from ${KERNEL_ROOT_DIR}/bin/salome/appliskel (see below).
+ </li>
+</ol>
+
+\section S3_sal_appl General rules
+
+Directory ${APPLI} must be created on each computer of the application.
+The easiest way is to use the same relative path (to ${HOME}) on each computer.
+(Sometimes it is not possible to use the same path everywhere, for instance
+when ${HOME} is shared with NFS, so it is possible to define different path
+following the computers).
+
+The ${APPLI} directory contains scripts for environment and runs. Environment
+scripts must be configured (by the user) on each computer. All the environment
+scripts are in the ${APPLI}/env.d directory.
+
+The script ${APPLI}/envd sources **all** the files (\*.sh) in ${APPLI}/env.d
+in alphanumeric order (after edition, think to remove backup files). the envd
+script is used by run scripts.
+
+<ol>
+ <li>
+<b>env.d scripts</b>
+
+With the first way of installation, each user **must define** his own
+configuration for these scripts, following the above rules.
+<b>With the virtual installation (second way, above), env.d
+scripts are built automatically.</b>
+
+ **The following is only an example proposed by createAppli.sh, (first way of installation) not working as it is**.
+
+- atFirst.sh
+ Sets the computer configuration not directly related to %SALOME,
+ like useful tools, default PATH.
+
+- envProducts.sh
+ Sets the %SALOME prerequisites.
+
+- envSALOME.sh
+ Sets all the MODULE_ROOT_DIR that can be used in the %SALOME application.
+
+ SALOMEAppConfig is also defined by:
+
+\code
+export SALOMEAppConfig=${HOME}/${APPLI}
+\endcode
+
+ where SALOMEAppConfig designates the directory containing SALOMEApp.xml.
+ Note that ${APPLI} is already defined by the calling scripts when
+ env.d/envSALOME.sh is sourced.
+ </li>
+ <li>
+<b>User run scripts</b>
+
+The %SALOME user can use 4 scripts:
+
+- runAppli
+ Launches a %SALOME Session
+ (similar to ${KERNEL_ROOT_DIR}/bin/salome/runSalome but with a different
+ name to avoid confusions). See parameters below.
+
+- runSession
+ Launches a shell script in the %SALOME application environment, with access
+ to the current (last launched) %SALOME session (naming service), if any.
+ Without arguments, the script is interactive. With arguments, the script
+ executes the command in the %SALOME application environment.
+
+- runConsole
+ Gives a python console connected to the current %SALOME Session.
+ It is also possible to use runSession, then python.
+
+- runTests
+ Similar to runSession, used for unit testing, but runSession tries to use an
+ already existing naming service definition from a running session (hostname
+ and port number), and runTests defines a new configuration for naming service
+ (new port number).
+ </li>
+ <li>
+<b>%SALOME internal run scripts</b>
+
+- envd
+ Sets %SALOME application environment, envd is sourced by other scripts.
+
+For remote calls, %SALOME uses one script.
+
+- runRemote.sh
+ This script is mainly used to launch containers. The first 3 arguments
+ define the hostname and port userd for naming service, plus a working directory, the remaining
+ arguments define the command to execute.
+ </li>
+ <li>
+<b>Other configuration files</b>
+
+- SALOMEApp.xml
+ This file is similar to the default given
+ in ${GUI_ROOT_DIR}/share/SALOME/resources/gui
+
+
+- CatalogRessources.xml
+ This files describes all the computers the application can use. The given
+ example is minimal and suppose ${APPLI} is the same relative path
+ to ${HOME}, on all the computers. %A different directory can be set on a
+ particular computer with a line:
+
+\code
+appliPath="my/specific/path/on/this/computer"
+\endcode
+
+ </li>
+</ol>
+
+\section S4_sal_appl Examples of use
+
+<ol>
+ <li>
+<b>Launch a %SALOME session with a GUI interface</b>
+
+Launch is done with a command like::
+
+\code
+./runAppli --logger
+\endcode
+
+The --logger option means here : collect all the traces from the all the
+distributed process, via CORBA, in a single file : logger.log.
+
+There are a lot of options, a complete list is given by::
+
+\code
+./runAppli --help
+\endcode
+
+Note that, without argument, runAppli is a non interactive Python application,
+and, with arguments, runAppli is an interactive Python interpreter.
+
+Several options are already defined by default in SALOMEApp.xml files. Optional
+arguments given in the command override the SALOMEApp.xml configuration.
+
+Several sessions can run simultaneously, each session use a different port for
+CORBA naming service, so the sessions are totally separated from each other.
+
+When the GUI is closed, the different %SALOME servers are still running.
+ </li>
+ <li>
+<b>Close a %SALOME session, kill all the servers</b>
+
+Inside the interactive python interpreter you get when you use runAppli
+with arguments, you can kill all the servers of your session with::
+
+\code
+>>> killLocalPort()
+\endcode
+
+or the servers of all the sessions with::
+
+\code
+>>> killAllPorts()
+\endcode
+
+If you have no active Python interpreter connected to your session, you can
+kill all the %SALOME servers of **all the sessions** on a given computer::
+
+\code
+./runSession killSalome.py
+\endcode
+
+Remember! it's the same idea in <b>Windows (R) operating system</b> (Microsoft and Windows are either registered trademarks or trademarks of
+ Microsoft Corporation in the United States and/or other countries) :
+use the start menu to stop...
+
+When you use only one session at a time, you don't need more.
+
+To kill a given session (when several session are running), one needs
+the naming service port number::
+
+\code
+./runSession killSalomeWithPort 2810
+\endcode
+
+Note that the port number of the last launched session can be found on Linux,
+in the prompt, within a runSession shell (see below).
+
+It is also possible to get the Naming Service host and port number of
+the last launched session with::
+
+\code
+./runSession NSparam.py
+\endcode
+
+ </li>
+ <li>
+<b>Launch a %SALOME session without GUI interface</b>
+
+This is used to launch a %SALOME Python script without GUI
+(no GUI %server = SALOME_session_server)
+
+Example of script (test_session_geom.py):
+
+\code
+import salome_session
+salome_session.startSession(modules=["GEOM"])
+import GEOM_usinggeom
+raw_input("Press a key and the servers will be killed ...")
+\endcode
+
+This script is run in a non interactive way with::
+
+\code
+./runSession python test_session_geom.py
+\endcode
+
+All the process are automatically killed when Python is closed
+(with SALOME_session delete).
+ </li>
+ <li>
+<b>Add an external Python interpretor to a running session</b>
+
+It's often easier to develop and try Python scripts outside the GUI embedded
+Python interpreter. Imagine, for instance, you are writing a script involving
+geometry and mesh modules.
+first, launch a %SALOME session with gui, then, on another terminal::
+
+\code
+./runSession
+python
+\endcode
+
+Import %SALOME module. salome_init() without arguments creates a new study
+in the running session (note: SALOME_init(n) attachs to a running session whose
+studyId is n)::
+
+\code
+import salome
+salome.salome_init()
+\endcode
+
+An example of script given with SMESH::
+
+\code
+import ex01_cube2build
+\endcode
+
+It is possible to connect the GUI interface to the study created in the above
+script with the file/connect menu, then browse study and display objects.
+Further modifications on study can be done either with GUI or external script
+(use refresh popup in GUI %object browser to see study modifications generated
+by the external script). **AVOID modifications with GUI when a Python script
+is running**. Not all the modules are protected against concurrent actions...
+ </li>
+ <li>
+<b>Different uses of the runSession shell interpreter</b>
+
+runSession invoked without arguments gives an interactive shell with the full
+environment of %SALOME (PATH, LD_LIBRARY_PATH, PYTHONPATH, other variables).
+If there are running sessions of the same %SALOME application, runSession
+connects to the last launched session (i.e. gets the naming service references
+of the session: hostname and port)
+
+On Linux, the shell prompt (bash) gives information on naming service
+references, hostname and port::
+
+\code
+[NS=cli76cc:2811]prascle@cli76cc:~/SALOME2/Run/Virtual$
+\endcode
+
+If there is no running session, prompt looks like::
+
+\code
+[NS=:]prascle@cli76cc:~/SALOME2/Run/Virtual$
+\endcode
+
+runSession is useful to launch any script or program which needs the complete
+%SALOME environment, with or without a session already running.
+For instance, to launch the ddd debugger interface on the gui %server, first
+launch a %SALOME session with gui, then, on another terminal::
+
+\code
+./runSession ddd
+\endcode
+
+Then attach to the running SALOME_Session_Server process.
+ </li>
+</ol>
+
+*/
--- /dev/null
+/*!
+
+\page salome_file_page Salome_file
+
+This page introduces the Salome_file feature. Salome_file is based on the
+SALOME_FileTransfer. It extends it to enable a higher model for managing files into
+%SALOME applications.
+
+\section S1_Salome_file Principles
+
+Salome_file is a CORBA %object. It's role is to managed many system files. When a Salome_file
+is created, no files are managed. Then, files are added using Salome_file interface. %A file is represented
+by a <b>name</b> and a <b>path</b>.
+
+There is two different cases when a file is added :
+
+- <b>Local file</b> : the file added exists or it will be created by the user with the path and the name used in
+its registration.
+- <b>Distributed file</b> : the file added exists into a distributed localization.
+
+To be able to get a distributed file, the Salome_file has to be connected with an another Salome_file that
+managed this file. This distributed Salome_file could be located into a distributed resource.
+
+\section S2_Salome_file Simple example
+
+This section shows a simple example of the use of Salome_file. The objective is to create
+two Salome_file; one is managing a local file, the other is managing a distributed file.
+Then, these Salome_files are connected to enable the copy of the real file gbetween the two Salome_files.
+
+Firstly, two Salome_files are created :
+
+\code
+#include "Salome_file_i.hxx"
+
+int main (int argc, char * argv[])
+{
+ Salome_file_i file_source;
+ Salome_file_i file_dest;
+
+\endcode
+
+Secondly, the real files are registered into the Salome_files.
+
+\code
+ file_source.setLocalFile("/bin/cat");
+ file_dest.setDistributedFile("/tmp/cat_copy");
+\endcode
+
+Thirdly, we connect the destination file with the source file :
+
+\code
+ file_dest.connect(file_source);
+\endcode
+
+Finally, the file is sended using Salome_file interface.
+
+\code
+ file_dest.recvFiles();
+ // Status check
+ state = file_dest.getSalome_fileState();
+ print_state(state); // You have to implement this function.
+};
+\endcode
+
+\section S3_Salome_file Advanced example
+
+This advanced example illustrates a part of the Salome_file API dedicated
+for situations where multiple files are managed.
+
+This is the situation :
+
+\code
+
+#include "Salome_file_i.hxx"
+
+int main (int argc, char * argv[])
+{
+ Salome_file_i file_source_a;
+ Salome_file_i file_source_b;
+ Salome_file_i file_dest;
+
+ file_source_a.setLocalFile("/bin/cat");
+ file_source_a.setLocalFile("/bin/ls");
+
+ file_source_b.setLocalFile("/bin/echo");
+ file_source_b.setLocalFile("/bin/cp");
+
+ file_dest.setDistributedFile("/tmp/cat_copy");
+ file_dest.setDistributedFile("/tmp/echo_copy");
+\endcode
+
+There is two problems in this case.
+
+The first problem is in the <b>file_dest</b> Salome_file, there is two files. If
+the method connect is used, the Salome_file cannot know if the reference is for <b>cat_copy</b> or
+<b>echo_copy</b>. Indeed <b>echo_copy</b> could be provided by another Salome_file that for <b>cat_copy</b>.
+
+The second problem comes from the two files of <b>file_source_a</b> Salome_file. Indeed when connect is used,
+there is no information about the choice of the source file into the source Salome_file. For
+<b>cat_copy</b>, did the used want <b>cat</b> or <b>echo</b> ?
+
+To avoid these cases, Salome_file API provides advanced methods :
+
+\code
+ file_dest.connectDistributedFile("cat_copy", file_source_a);
+ file_dest.setDistributedSourceFile("cat_copy", "cat");
+
+ file_dest.connectDistributedFile("cat_echo", file_source_b);
+ file_dest.setDistributedSourceFile("cat_echo", "echo");
+
+ file_dest.recvFiles();
+ // Status check
+ state = file_dest.getSalome_fileState();
+ print_state(state); // You have to implement this function.
+};
+\endcode
+
+\section S3_Salome_file Using Salome_file into %SALOME services
+
+Currently you can't use Salome_file into YACS schema. In the next version of %SALOME,
+files ports will be available to connect output files to input files.
+
+*/
--- /dev/null
+/*!
+
+\page UnitTests Source code structuration and Unit Tests
+
+<b>WORK in PROGRESS, INCOMPLETE DOCUMENT</b>
+
+You will find here general information on code directories structure,
+unit tests associated to the different kind of classes, and how to run
+the unit tests.
+
+\section S1_unit SALOME KERNEL source code structuration
+
+<ol>
+<li> <b>General structure of KERNEL_SRC</b>
+
+- KERNEL_SRC :
+ Some README files and configuration tools for build
+
+- KERNEL_SRC/adm_local :
+ Part of the configuration files, other modules have a directory with the
+ same name. Not used in KERNEL.
+
+- KERNEL_SRC/bin :
+ Python and shell scripts used at run time.
+ Kit to install a %SALOME Application.
+
+- KERNEL_SRC/doc :
+ Kit for KERNEL end user documentation production:
+ public interfaces, Python, CORBA.
+ Integrator and Developper documentation.
+
+- KERNEL_SRC/idl :
+ All CORBA interfaces from KERNEL are regrouped here.
+
+- KERNEL_SRC/resources :
+ Configuration files for servers (examples).
+ Interfaces definitions for KERNEL test components.
+
+- KERNEL_SRC/salome_adm :
+ Configuration files used by autotools (M4 macros & co.)
+
+- KERNEL_SRC/src :
+ The source code (C++ and Python)
+
+</li>
+<li>
+<b>Directory src: C++ and Python source code</b>
+
+<ol>
+<li>
+<b>Basic services non related to CORBA</b>
+
+- Basics
+ %A set of general purpose C++ services, not related to CORBA.
+ Some general purpose services that are in Utils directory (CORBA related),
+ are progressivley moved here, as they are not related to CORBA.
+
+
+- SALOMELocalTrace
+ %A multithread trace system that allows message tracing on standard error
+ or a file.
+
+- CASCatch
+ Exceptions and signal handler.
+
+- HDFPersist
+ %A C++ interface to HDF.
+
+</li>
+
+<li>
+<b>Basic CORBA services</b>
+
+- Logger :
+ %A CORBA %server that collects the trace messages from differents CORBA
+ process.
+
+- SALOMETraceCollector :
+ %A multithread trace system derived from SALOMELocalTrace, that sends messages
+ to Logger %server via CORBA.
+
+- Utils :
+ %A set of general purpose services related to CORBA, such as basic CORBA
+ exception system. See also Basics directory above.
+
+- NamingService :
+ C++ and Python interfaces to name, store and retrieve CORBA objects
+
+- GenericObj :
+ %A generic CORBA interface for CORBA objects, to count distributed references,
+ and to allow destruction by client.
+
+</li>
+<li>
+<b>Miscellaneous CORBA servers</b>
+
+- %Registry :
+ Implements SALOME_registry.idl.
+ Provides a CORBA %server library and a separate %server program.
+
+- ModuleCatalog :
+ Implements SALOME_moduleCatalog.idl.
+ Provide a CORBA %server library and separate %server and client programs.
+
+- ModuleGenerator :
+ Tool to generate a module catalog from CORBA idl
+
+- ResourcesManager :
+ library included in container %server
+
+- Notification :
+ library included in differents servers (container)
+
+- NOTIFICATION_SWIG
+
+</li>
+
+<li>
+<b>CORBA Containers for %SALOME Modules</b>
+
+- Container
+
+- TestContainer
+
+- LifeCycleCORBA
+
+- LifeCycleCORBA_SWIG
+
+</li>
+
+<li>
+<b>STUDY %server and related interfaces and tools</b>
+
+- SALOMEDSClient
+
+- TOOLSDS
+
+- SALOMEDSImpl
+
+- SALOMEDS
+
+</li>
+<li>
+<b>Python interface to %SALOME</b>
+
+- KERNEL_PY
+
+</li>
+<li>
+<b>Efficient CORBA transfer services</b>
+
+- Communication
+
+- Communication_SWIG
+
+</li>
+<li>
+<b>%A Parallel container with MPI</b>
+
+- MPIContainer
+
+- TestMPIContainer
+
+</li>
+<li>
+<b>Batch interface library</b>
+
+- Batch
+
+- Batch_SWIG
+
+</li>
+<li>
+<b>Unit tests</b>
+
+- UnitTests
+
+</li>
+</ol>
+</li>
+</ol>
+
+\section S2_unit Tools and principles used for Unit testing
+
+<b>**TO BE COMPLETED**</b>
+
+Unit Testing rely on cppunit package for C++ testing, and on unittest module
+for Python. See these products for general principles of unit testing.
+
+The cppunit package is optional. When the prerequisite is detected, the unit
+tests are compiled.
+
+Unit Tests sources are in directories Test under the src/directories
+containing the classes to test.
+
+Test are ordered following the order of directories given above.
+
+Tests can be run as a whole, or for a particular directory. In this case, only
+a partial test is run (the classes to test, and the classes used, i.e. the
+preceding test directories).
+
+
+Today, only some tests are written as an example. There are not yet python
+scripts in KERNEL_SRC, but it's a matter of days, there are working scripts
+to test LifeCycleCORBA_SWIG interface.
+
+*/
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.cxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+#include "Batch_BatchManager_eClient.hxx"
+
+namespace Batch {
+
+ BatchManager_eClient::BatchManager_eClient(const Batch::FactBatchManager * parent, const char* host, const char* protocol, const char* mpiImpl) : BatchManager(parent, host), _protocol(protocol), _username("")
+ {
+ // instanciation of mpi implementation needed to launch executable in batch script
+ _mpiImpl = FactoryMpiImpl(mpiImpl);
+ }
+
+ // Destructeur
+ BatchManager_eClient::~BatchManager_eClient()
+ {
+ // Nothing to do
+ delete _mpiImpl;
+ }
+
+ void BatchManager_eClient::exportInputFiles(const Job& job) throw(EmulationException)
+ {
+ int status;
+ Parametre params = job.getParametre();
+ Versatile V = params[INFILE];
+ Versatile::iterator Vit;
+ string command;
+ string copy_command;
+ _username = string(params[USER]);
+
+ // Test protocol
+ if( _protocol == "rsh" )
+ copy_command = "rcp ";
+ else if( _protocol == "ssh" )
+ copy_command = "scp ";
+ else
+ throw EmulationException("Unknown protocol : only rsh and ssh are known !");
+
+ // First step : creating batch tmp files directory
+ command = _protocol;
+ command += " ";
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+ command += _hostname;
+ command += " \"mkdir -p ";
+ command += string(params[TMPDIR]);
+ command += "\"" ;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ std::string ex_mess("Error of connection on remote host ! status = ");
+ ex_mess += oss.str();
+ throw EmulationException(ex_mess.c_str());
+ }
+
+ // Second step : copy fileToExecute into
+ // batch tmp files directory
+ command = copy_command;
+ command += string(params[EXECUTABLE]);
+ command += " ";
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+ command += _hostname;
+ command += ":";
+ command += string(params[TMPDIR]);
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ std::string ex_mess("Error of connection on remote host ! status = ");
+ ex_mess += oss.str();
+ throw EmulationException(ex_mess.c_str());
+ }
+
+ // Third step : copy filesToExportList into
+ // batch tmp files directory
+ for(Vit=V.begin(); Vit!=V.end(); Vit++) {
+ CoupleType cpt = *static_cast< CoupleType * >(*Vit);
+ Couple inputFile = cpt;
+ command = copy_command;
+ command += inputFile.getLocal();
+ command += " ";
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+ command += _hostname;
+ command += ":";
+ command += inputFile.getRemote();
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ std::string ex_mess("Error of connection on remote host ! status = ");
+ ex_mess += oss.str();
+ throw EmulationException(ex_mess.c_str());
+ }
+ }
+
+ }
+
+ void BatchManager_eClient::importOutputFiles( const Job & job, const string directory ) throw(EmulationException)
+ {
+ string command;
+ int status;
+
+ Parametre params = job.getParametre();
+ Versatile V = params[OUTFILE];
+ Versatile::iterator Vit;
+
+ for(Vit=V.begin(); Vit!=V.end(); Vit++) {
+ CoupleType cpt = *static_cast< CoupleType * >(*Vit);
+ Couple outputFile = cpt;
+ if( _protocol == "rsh" )
+ command = "rcp ";
+ else if( _protocol == "ssh" )
+ command = "scp ";
+ else
+ throw EmulationException("Unknown protocol");
+
+ if (_username != ""){
+ command += _username;
+ command += "@";
+ }
+ command += _hostname;
+ command += ":";
+ command += outputFile.getRemote();
+ command += " ";
+ command += directory;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ {
+ // Try to get what we can (logs files)
+ // throw BatchException("Error of connection on remote host");
+ std::string mess("Copy command failed ! status is :");
+ ostringstream status_str;
+ status_str << status;
+ mess += status_str.str();
+ cerr << mess << endl;
+ }
+ }
+
+ }
+
+ MpiImpl *BatchManager_eClient::FactoryMpiImpl(string mpiImpl) throw(EmulationException)
+ {
+ if(mpiImpl == "lam")
+ return new MpiImpl_LAM();
+ else if(mpiImpl == "mpich1")
+ return new MpiImpl_MPICH1();
+ else if(mpiImpl == "mpich2")
+ return new MpiImpl_MPICH2();
+ else if(mpiImpl == "openmpi")
+ return new MpiImpl_OPENMPI();
+ else if(mpiImpl == "slurm")
+ return new MpiImpl_SLURM();
+ else{
+ ostringstream oss;
+ oss << mpiImpl << " : not yet implemented";
+ throw EmulationException(oss.str().c_str());
+ }
+ }
+
+ string BatchManager_eClient::BuildTemporaryFileName() const
+ {
+ //build more complex file name to support multiple salome session
+ char *temp = new char[19];
+ strcpy(temp, "/tmp/command");
+ strcat(temp, "XXXXXX");
+#ifndef WNT
+ mkstemp(temp);
+#else
+ char aPID[80];
+ itoa(getpid(), aPID, 10);
+ strcat(temp, aPID);
+#endif
+
+ string command(temp);
+ delete [] temp;
+ command += ".sh";
+ return command;
+ }
+
+ void BatchManager_eClient::RmTmpFile(std::string & TemporaryFileName)
+ {
+ string command = "rm ";
+ command += TemporaryFileName;
+ char *temp = strdup(command.c_str());
+ int lgthTemp = strlen(temp);
+ temp[lgthTemp - 3] = '*';
+ temp[lgthTemp - 2] = '\0';
+ system(temp);
+ free(temp);
+ }
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.hxx : emulation of client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _BATCHMANAGER_eClient_H_
+#define _BATCHMANAGER_eClient_H_
+
+
+#include "MpiImpl.hxx"
+#include "Batch_BatchManager.hxx"
+
+namespace Batch {
+
+ class Job;
+
+ class EmulationException
+ {
+ public:
+ const std::string msg;
+
+ EmulationException(const std::string m) : msg(m) {}
+ };
+
+ class BatchManager_eClient : public BatchManager
+ {
+ public:
+ // Constructeur et destructeur
+ BatchManager_eClient(const Batch::FactBatchManager * parent, const char* host="localhost", const char* protocol="ssh", const char* mpiImpl="indif");
+ virtual ~BatchManager_eClient();
+ void importOutputFiles( const Job & job, const std::string directory ) throw(EmulationException);
+
+ protected:
+ std::string _protocol; // protocol to access _hostname
+ std::string _username; // username to access _hostname
+ MpiImpl *_mpiImpl; // Mpi implementation to launch executable in batch script
+
+ std::string BuildTemporaryFileName() const;
+ void RmTmpFile(std::string & TemporaryFileName);
+ MpiImpl* FactoryMpiImpl(string mpiImpl) throw(EmulationException);
+ void exportInputFiles(const Job & job) throw(EmulationException);
+
+ private:
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.cxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+#include "Batch_BatchManager_eLSF.hxx"
+
+namespace Batch {
+
+ BatchManager_eLSF::BatchManager_eLSF(const FactBatchManager * parent, const char * host, const char * protocol, const char * mpiImpl) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager_eClient(parent,host,protocol,mpiImpl)
+ {
+ // Nothing to do
+ }
+
+ // Destructeur
+ BatchManager_eLSF::~BatchManager_eLSF()
+ {
+ // Nothing to do
+ }
+
+ // Methode pour le controle des jobs : soumet un job au gestionnaire
+ const JobId BatchManager_eLSF::submitJob(const Job & job)
+ {
+ int status;
+ Parametre params = job.getParametre();
+ const std::string dirForTmpFiles = params[TMPDIR];
+ const string fileToExecute = params[EXECUTABLE];
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+ // export input files on cluster
+ exportInputFiles(job);
+
+ // build batch script for job
+ buildBatchScript(job);
+
+ // define name of log file
+ string logFile="/tmp/logs/";
+ logFile += getenv("USER");
+ logFile += "/batchSalome_";
+ srand ( time(NULL) );
+ int ir = rand();
+ ostringstream oss;
+ oss << ir;
+ logFile += oss.str();
+ logFile += ".log";
+
+ string command;
+
+ // define command to submit batch
+ command = _protocol;
+ command += " ";
+
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+
+ command += _hostname;
+ command += " \"cd " ;
+ command += dirForTmpFiles ;
+ command += "; bsub < " ;
+ command += fileNameToExecute ;
+ command += "_Batch.sh\" > ";
+ command += logFile;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ // read id of submitted job in log file
+ char line[128];
+ FILE *fp = fopen(logFile.c_str(),"r");
+ fgets( line, 128, fp);
+ fclose(fp);
+
+ string sline(line);
+ int p10 = sline.find("<");
+ int p20 = sline.find(">");
+ string strjob = sline.substr(p10+1,p20-p10-1);
+
+ JobId id(this, strjob);
+ return id;
+ }
+
+ // Methode pour le controle des jobs : retire un job du gestionnaire
+ void BatchManager_eLSF::deleteJob(const JobId & jobid)
+ {
+ int status;
+ int ref;
+ istringstream iss(jobid.getReference());
+ iss >> ref;
+
+ // define command to submit batch
+ string command;
+ command = _protocol;
+ command += " ";
+
+ if (_username != ""){
+ command += _username;
+ command += "@";
+ }
+
+ command += _hostname;
+ command += " \"bkill " ;
+ command += iss.str();
+ command += "\"";
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ cerr << "jobId = " << ref << "killed" << endl;
+ }
+
+ // Methode pour le controle des jobs : suspend un job en file d'attente
+ void BatchManager_eLSF::holdJob(const JobId & jobid)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+ // Methode pour le controle des jobs : relache un job suspendu
+ void BatchManager_eLSF::releaseJob(const JobId & jobid)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_eLSF::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_eLSF::alterJob(const JobId & jobid, const Parametre & param)
+ {
+ alterJob(jobid, param, Environnement());
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_eLSF::alterJob(const JobId & jobid, const Environnement & env)
+ {
+ alterJob(jobid, Parametre(), env);
+ }
+
+ // Methode pour le controle des jobs : renvoie l'etat du job
+ JobInfo BatchManager_eLSF::queryJob(const JobId & jobid)
+ {
+ int id;
+ istringstream iss(jobid.getReference());
+ iss >> id;
+
+ // define name of log file
+ string logFile="/tmp/logs/";
+ logFile += getenv("USER");
+ logFile += "/batchSalome_";
+
+ srand ( time(NULL) );
+ int ir = rand();
+ ostringstream oss;
+ oss << ir;
+ logFile += oss.str();
+ logFile += ".log";
+
+ string command;
+ int status;
+
+ // define command to submit batch
+ command = _protocol;
+ command += " ";
+
+ if (_username != ""){
+ command += _username;
+ command += "@";
+ }
+
+ command += _hostname;
+ command += " \"bjobs " ;
+ command += iss.str();
+ command += "\" > ";
+ command += logFile;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ JobInfo_eLSF ji = JobInfo_eLSF(id,logFile);
+ return ji;
+ }
+
+
+
+ // Methode pour le controle des jobs : teste si un job est present en machine
+ bool BatchManager_eLSF::isRunning(const JobId & jobid)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+ void BatchManager_eLSF::buildBatchScript(const Job & job) throw(EmulationException)
+ {
+ int status;
+ Parametre params = job.getParametre();
+ const int nbproc = params[NBPROC];
+ const long edt = params[MAXWALLTIME];
+ const long mem = params[MAXRAMSIZE];
+ const string workDir = params[WORKDIR];
+ const std::string dirForTmpFiles = params[TMPDIR];
+ const string fileToExecute = params[EXECUTABLE];
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ std::string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+ std::string fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(fileToExecute.c_str()));
+
+ int idx = dirForTmpFiles.find("Batch/");
+ std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+
+ std::string TmpFileName = BuildTemporaryFileName();
+ ofstream tempOutputFile;
+ tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+
+ tempOutputFile << "#! /bin/sh -f" << endl ;
+ if( edt > 0 )
+ tempOutputFile << "#BSUB -W " << getWallTime(edt) << endl ;
+ if( mem > 0 )
+ tempOutputFile << "#BSUB -M " << mem*1024 << endl ;
+ tempOutputFile << "#BSUB -n " << nbproc << endl ;
+ tempOutputFile << "#BSUB -o runSalome.output.log." << filelogtemp << endl ;
+ tempOutputFile << "#BSUB -e runSalome.error.log." << filelogtemp << endl ;
+ if( workDir.size() > 0 )
+ tempOutputFile << "cd " << workDir << endl ;
+ tempOutputFile << _mpiImpl->boot("",nbproc);
+ tempOutputFile << _mpiImpl->run("",nbproc,fileNameToExecute);
+ tempOutputFile << _mpiImpl->halt();
+ tempOutputFile.flush();
+ tempOutputFile.close();
+ chmod(TmpFileName.c_str(), 0x1ED);
+ cerr << TmpFileName.c_str() << endl;
+
+ string command;
+ if( _protocol == "rsh" )
+ command = "rcp ";
+ else if( _protocol == "ssh" )
+ command = "scp ";
+ else
+ throw EmulationException("Unknown protocol");
+ command += TmpFileName;
+ command += " ";
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+ command += _hostname;
+ command += ":";
+ command += dirForTmpFiles ;
+ command += "/" ;
+ command += rootNameToExecute ;
+ command += "_Batch.sh" ;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ RmTmpFile(TmpFileName);
+
+ }
+
+ std::string BatchManager_eLSF::getWallTime(const long edt)
+ {
+ long h, m;
+ h = edt / 60;
+ m = edt - h*60;
+ ostringstream oss;
+ if( m >= 10 )
+ oss << h << ":" << m;
+ else
+ oss << h << ":0" << m;
+ return oss.str();
+ }
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_eLSF.hxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _BATCHMANAGER_eLSF_H_
+#define _BATCHMANAGER_eLSF_H_
+
+
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_JobInfo_eLSF.hxx"
+#include "Batch_InvalidArgumentException.hxx"
+#include "Batch_ConnexionFailureException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_NotYetImplementedException.hxx"
+#include "Batch_BatchManager.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+
+namespace Batch {
+
+ class Job;
+ class JobId;
+ class JobInfo;
+ class FactBatchManager;
+
+ class BatchManager_eLSF : public BatchManager_eClient
+ {
+ public:
+ // Constructeur et destructeur
+ BatchManager_eLSF(const FactBatchManager * parent, const char * host="localhost", const char * protocol="ssh", const char * mpiImpl="indif") throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host
+ virtual ~BatchManager_eLSF();
+
+ // Recupere le nom du serveur par defaut
+ // static string BatchManager_LSF::getDefaultServer();
+
+ // Methodes pour le controle des jobs
+ virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire
+ virtual void deleteJob(const JobId & jobid); // retire un job du gestionnaire
+ virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente
+ virtual void releaseJob(const JobId & jobid); // relache un job suspendu
+ virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente
+ virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente
+ virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente
+ virtual JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job
+ virtual bool isRunning(const JobId & jobid); // teste si un job est present en machine
+
+ virtual void setParametre(const JobId & jobid, const Parametre & param) { return alterJob(jobid, param); } // modifie un job en file d'attente
+ virtual void setEnvironnement(const JobId & jobid, const Environnement & env) { return alterJob(jobid, env); } // modifie un job en file d'attente
+
+
+ protected:
+ void buildBatchScript(const Job & job) throw(EmulationException);
+ std::string getWallTime(const long edt);
+
+ private:
+
+#ifdef SWIG
+ public:
+ // Recupere le l'identifiant d'un job deja soumis au BatchManager
+ //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); }
+ virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); }
+#endif
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_ePBS.cxx : emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <sys/stat.h>
+#include "Batch_BatchManager_ePBS.hxx"
+
+namespace Batch {
+
+ BatchManager_ePBS::BatchManager_ePBS(const FactBatchManager * parent, const char * host, const char * protocol, const char * mpiImpl) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager_eClient(parent,host,protocol,mpiImpl)
+ {
+ // Nothing to do
+ }
+
+ // Destructeur
+ BatchManager_ePBS::~BatchManager_ePBS()
+ {
+ // Nothing to do
+ }
+
+ // Methode pour le controle des jobs : soumet un job au gestionnaire
+ const JobId BatchManager_ePBS::submitJob(const Job & job)
+ {
+ int status;
+ Parametre params = job.getParametre();
+ const std::string dirForTmpFiles = params[TMPDIR];
+ const string fileToExecute = params[EXECUTABLE];
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+
+ // export input files on cluster
+ exportInputFiles(job);
+
+ // build batch script for job
+ buildBatchScript(job);
+
+ // define name of log file
+ string logFile="/tmp/logs/";
+ logFile += getenv("USER");
+ logFile += "/batchSalome_";
+ srand ( time(NULL) );
+ int ir = rand();
+ ostringstream oss;
+ oss << ir;
+ logFile += oss.str();
+ logFile += ".log";
+
+ string command;
+
+ // define command to submit batch
+ command = _protocol;
+ command += " ";
+
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+
+ command += _hostname;
+ command += " \"cd " ;
+ command += dirForTmpFiles ;
+ command += "; qsub " ;
+ command += fileNameToExecute ;
+ command += "_Batch.sh\" > ";
+ command += logFile;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ // read id of submitted job in log file
+ char line[128];
+ FILE *fp = fopen(logFile.c_str(),"r");
+ fgets( line, 128, fp);
+ fclose(fp);
+
+ string sline(line);
+ int pos = sline.find(".");
+ string strjob;
+ if(pos == string::npos)
+ strjob = sline;
+ else
+ strjob = sline.substr(0,pos);
+
+ JobId id(this, strjob);
+ return id;
+ }
+
+ // Methode pour le controle des jobs : retire un job du gestionnaire
+ void BatchManager_ePBS::deleteJob(const JobId & jobid)
+ {
+ int status;
+ int ref;
+ istringstream iss(jobid.getReference());
+ iss >> ref;
+
+ // define command to submit batch
+ string command;
+ command = _protocol;
+ command += " ";
+
+ if (_username != ""){
+ command += _username;
+ command += "@";
+ }
+
+ command += _hostname;
+ command += " \"qdel " ;
+ command += iss.str();
+ command += "\"";
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ cerr << "jobId = " << ref << "killed" << endl;
+ }
+
+ // Methode pour le controle des jobs : suspend un job en file d'attente
+ void BatchManager_ePBS::holdJob(const JobId & jobid)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+ // Methode pour le controle des jobs : relache un job suspendu
+ void BatchManager_ePBS::releaseJob(const JobId & jobid)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_ePBS::alterJob(const JobId & jobid, const Parametre & param, const Environnement & env)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_ePBS::alterJob(const JobId & jobid, const Parametre & param)
+ {
+ alterJob(jobid, param, Environnement());
+ }
+
+ // Methode pour le controle des jobs : modifie un job en file d'attente
+ void BatchManager_ePBS::alterJob(const JobId & jobid, const Environnement & env)
+ {
+ alterJob(jobid, Parametre(), env);
+ }
+
+ // Methode pour le controle des jobs : renvoie l'etat du job
+ JobInfo BatchManager_ePBS::queryJob(const JobId & jobid)
+ {
+ int id;
+ istringstream iss(jobid.getReference());
+ iss >> id;
+
+ // define name of log file
+ string logFile="/tmp/logs/";
+ logFile += getenv("USER");
+ logFile += "/batchSalome_";
+
+ ostringstream oss;
+ oss << this << "_" << id;
+ logFile += oss.str();
+ logFile += ".log";
+
+ string command;
+ int status;
+
+ // define command to submit batch
+ command = _protocol;
+ command += " ";
+
+ if (_username != ""){
+ command += _username;
+ command += "@";
+ }
+
+ command += _hostname;
+ command += " \"qstat -f " ;
+ command += iss.str();
+ command += "\" > ";
+ command += logFile;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status && status != 153 && status != 256*153)
+ throw EmulationException("Error of connection on remote host");
+
+ JobInfo_ePBS ji = JobInfo_ePBS(id,logFile);
+ return ji;
+ }
+
+ // Methode pour le controle des jobs : teste si un job est present en machine
+ bool BatchManager_ePBS::isRunning(const JobId & jobid)
+ {
+ throw EmulationException("Not yet implemented");
+ }
+
+ void BatchManager_ePBS::buildBatchScript(const Job & job) throw(EmulationException)
+ {
+ int status;
+ Parametre params = job.getParametre();
+ const long nbproc = params[NBPROC];
+ const long edt = params[MAXWALLTIME];
+ const long mem = params[MAXRAMSIZE];
+ const string workDir = params[WORKDIR];
+ const std::string dirForTmpFiles = params[TMPDIR];
+ const string fileToExecute = params[EXECUTABLE];
+ const string home = params[HOMEDIR];
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ std::string rootNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+ std::string fileNameToExecute = "~/" + dirForTmpFiles + "/" + string(basename(fileToExecute.c_str()));
+
+ int idx = dirForTmpFiles.find("Batch/");
+ std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+
+ std::string TmpFileName = BuildTemporaryFileName();
+ ofstream tempOutputFile;
+ tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+
+ tempOutputFile << "#! /bin/sh -f" << endl;
+ if( edt > 0 )
+ tempOutputFile << "#PBS -l walltime=" << edt*60 << endl ;
+ if( mem > 0 )
+ tempOutputFile << "#PBS -l mem=" << mem << "mb" << endl ;
+ tempOutputFile << "#PBS -o " << home << "/" << dirForTmpFiles << "/runSalome.output.log." << filelogtemp << endl ;
+ tempOutputFile << "#PBS -e " << home << "/" << dirForTmpFiles << "/runSalome.error.log." << filelogtemp << endl ;
+ if( workDir.size() > 0 )
+ tempOutputFile << "cd " << workDir << endl ;
+ tempOutputFile << _mpiImpl->boot("${PBS_NODEFILE}",nbproc);
+ tempOutputFile << _mpiImpl->run("${PBS_NODEFILE}",nbproc,fileNameToExecute);
+ tempOutputFile << _mpiImpl->halt();
+ tempOutputFile.flush();
+ tempOutputFile.close();
+ chmod(TmpFileName.c_str(), 0x1ED);
+ cerr << TmpFileName.c_str() << endl;
+
+ string command;
+ if( _protocol == "rsh" )
+ command = "rcp ";
+ else if( _protocol == "ssh" )
+ command = "scp ";
+ else
+ throw EmulationException("Unknown protocol");
+ command += TmpFileName;
+ command += " ";
+ if(_username != ""){
+ command += _username;
+ command += "@";
+ }
+ command += _hostname;
+ command += ":";
+ command += dirForTmpFiles ;
+ command += "/" ;
+ command += rootNameToExecute ;
+ command += "_Batch.sh" ;
+ cerr << command.c_str() << endl;
+ status = system(command.c_str());
+ if(status)
+ throw EmulationException("Error of connection on remote host");
+
+ RmTmpFile(TmpFileName);
+
+ }
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * BatchManager_ePBS.hxx : emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _BATCHMANAGER_eLSF_H_
+#define _BATCHMANAGER_eLSF_H_
+
+#include "Batch_JobId.hxx"
+#include "Batch_JobInfo.hxx"
+#include "Batch_JobInfo_ePBS.hxx"
+#include "Batch_InvalidArgumentException.hxx"
+#include "Batch_ConnexionFailureException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_NotYetImplementedException.hxx"
+#include "Batch_BatchManager.hxx"
+#include "Batch_BatchManager_eClient.hxx"
+
+namespace Batch {
+
+ class Job;
+ class JobId;
+ class JobInfo;
+ class FactBatchManager;
+
+ class BatchManager_ePBS : public BatchManager_eClient
+ {
+ public:
+ // Constructeur et destructeur
+ BatchManager_ePBS(const FactBatchManager * parent, const char * host="localhost", const char * protocol="ssh", const char * mpiImpl="indif") throw(InvalidArgumentException,ConnexionFailureException); // connexion a la machine host
+ virtual ~BatchManager_ePBS();
+
+ // Recupere le nom du serveur par defaut
+ // static string BatchManager_LSF::getDefaultServer();
+
+ // Methodes pour le controle des jobs
+ virtual const JobId submitJob(const Job & job); // soumet un job au gestionnaire
+ virtual void deleteJob(const JobId & jobid); // retire un job du gestionnaire
+ virtual void holdJob(const JobId & jobid); // suspend un job en file d'attente
+ virtual void releaseJob(const JobId & jobid); // relache un job suspendu
+ virtual void alterJob(const JobId & jobid, const Parametre & param, const Environnement & env); // modifie un job en file d'attente
+ virtual void alterJob(const JobId & jobid, const Parametre & param); // modifie un job en file d'attente
+ virtual void alterJob(const JobId & jobid, const Environnement & env); // modifie un job en file d'attente
+ virtual JobInfo queryJob(const JobId & jobid); // renvoie l'etat du job
+ virtual bool isRunning(const JobId & jobid); // teste si un job est present en machine
+
+ virtual void setParametre(const JobId & jobid, const Parametre & param) { return alterJob(jobid, param); } // modifie un job en file d'attente
+ virtual void setEnvironnement(const JobId & jobid, const Environnement & env) { return alterJob(jobid, env); } // modifie un job en file d'attente
+
+
+ protected:
+ void buildBatchScript(const Job & job) throw(EmulationException);
+
+ private:
+
+#ifdef SWIG
+ public:
+ // Recupere le l'identifiant d'un job deja soumis au BatchManager
+ //virtual const JobId getJobIdByReference(const string & ref) { return BatchManager::getJobIdByReference(ref); }
+ virtual const JobId getJobIdByReference(const char * ref) { return BatchManager::getJobIdByReference(ref); }
+#endif
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eClient.cxx : emulation of client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <string>
+#include <sstream>
+#include "Batch_FactBatchManager_eClient.hxx"
+using namespace std;
+
+namespace Batch {
+
+ // Constructeur
+ FactBatchManager_eClient::FactBatchManager_eClient(const string & _t) : FactBatchManager(_t)
+ {
+ }
+
+ // Destructeur
+ FactBatchManager_eClient::~FactBatchManager_eClient()
+ {
+ // Nothing to do
+ }
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eClient.hxx : emulation of client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_eClient_H_
+#define _FACTBATCHMANAGER_eClient_H_
+
+#include <string>
+#include <map>
+#include "Batch_FactBatchManager.hxx"
+
+namespace Batch {
+
+ class BatchManager_eClient;
+
+ class FactBatchManager_eClient : public FactBatchManager
+ {
+ public:
+ // Constructeur et destructeur
+ FactBatchManager_eClient(const std::string & type);
+ virtual ~FactBatchManager_eClient();
+
+ virtual Batch::BatchManager_eClient * operator() (const char * hostname,const char * protocol, const char * mpi) const = 0;
+
+ protected:
+
+ private:
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eLSF.cxx :
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Date : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <string>
+#include "Batch_BatchManager_eLSF.hxx"
+#include "Batch_FactBatchManager_eLSF.hxx"
+//#include "utilities.h"
+
+namespace Batch {
+
+ static FactBatchManager_eLSF sFBM_eLSF;
+
+ // Constructeur
+ FactBatchManager_eLSF::FactBatchManager_eLSF() : FactBatchManager_eClient("eLSF")
+ {
+ // Nothing to do
+ }
+
+ // Destructeur
+ FactBatchManager_eLSF::~FactBatchManager_eLSF()
+ {
+ // Nothing to do
+ }
+
+ // Functor
+ BatchManager * FactBatchManager_eLSF::operator() (const char * hostname) const
+ {
+ // MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
+ return new BatchManager_eLSF(this, hostname);
+ }
+
+ BatchManager_eClient * FactBatchManager_eLSF::operator() (const char * hostname, const char * protocol, const char * mpiImpl) const
+ {
+ // MESSAGE("Building new BatchManager_LSF on host '" << hostname << "'");
+ return new BatchManager_eLSF(this, hostname, protocol, mpiImpl);
+ }
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_eLSF.hxx :
+ *
+ * Auteur : Bernard SECHER : CEA DEN
+ * Date : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_eLSF_H_
+#define _FACTBATCHMANAGER_eLSF_H_
+
+using namespace std;
+#include <string>
+#include <map>
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_FactBatchManager_eClient.hxx"
+
+namespace Batch {
+
+ class BatchManager_eLSF;
+
+ class FactBatchManager_eLSF : public FactBatchManager_eClient
+ {
+ public:
+ // Constructeur et destructeur
+ FactBatchManager_eLSF();
+ virtual ~FactBatchManager_eLSF();
+
+ virtual BatchManager * operator() (const char * hostname) const;
+ virtual BatchManager_eClient * operator() (const char * hostname, const char * protocol, const char * mpiImpl) const;
+
+ protected:
+
+ private:
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_ePBS.cxx :
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Date : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <string>
+#include "Batch_BatchManager_ePBS.hxx"
+#include "Batch_FactBatchManager_ePBS.hxx"
+//#include "utilities.h"
+
+namespace Batch {
+
+ static FactBatchManager_ePBS sFBM_ePBS;
+
+ // Constructeur
+ FactBatchManager_ePBS::FactBatchManager_ePBS() : FactBatchManager_eClient("ePBS")
+ {
+ // Nothing to do
+ }
+
+ // Destructeur
+ FactBatchManager_ePBS::~FactBatchManager_ePBS()
+ {
+ // Nothing to do
+ }
+
+ // Functor
+ BatchManager * FactBatchManager_ePBS::operator() (const char * hostname) const
+ {
+ // MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'");
+ return new BatchManager_ePBS(this, hostname);
+ }
+
+ BatchManager_eClient * FactBatchManager_ePBS::operator() (const char * hostname, const char * protocol, const char * mpiImpl) const
+ {
+ // MESSAGE("Building new BatchManager_PBS on host '" << hostname << "'");
+ return new BatchManager_ePBS(this, hostname, protocol, mpiImpl);
+ }
+
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * FactBatchManager_ePBS.hxx :
+ *
+ * Auteur : Bernard SECHER : CEA DEN
+ * Date : Avril 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _FACTBATCHMANAGER_ePBS_H_
+#define _FACTBATCHMANAGER_ePBS_H_
+
+using namespace std;
+#include <string>
+#include <map>
+#include "Batch_BatchManager_eClient.hxx"
+#include "Batch_FactBatchManager_eClient.hxx"
+
+namespace Batch {
+
+ class BatchManager_ePBS;
+
+ class FactBatchManager_ePBS : public FactBatchManager_eClient
+ {
+ public:
+ // Constructeur et destructeur
+ FactBatchManager_ePBS();
+ virtual ~FactBatchManager_ePBS();
+
+ virtual BatchManager * operator() (const char * hostname) const;
+ virtual BatchManager_eClient * operator() (const char * hostname, const char * protocol, const char * mpiImpl) const;
+
+ protected:
+
+ private:
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_eLSF.cxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_eLSF.hxx"
+
+namespace Batch {
+
+
+
+ // Constructeurs
+ JobInfo_eLSF::JobInfo_eLSF(int id, string logFile) : JobInfo()
+ {
+ // On remplit les membres _param et _env
+ ostringstream oss;
+ oss << id;
+ _param[ID] = oss.str();
+
+ // read status of job in log file
+ char line[128];
+ ifstream fp(logFile.c_str(),ios::in);
+ fp.getline(line,80,'\n');
+
+ string sjobid, username, status;
+ fp >> sjobid;
+ fp >> username;
+ fp >> status;
+
+ _param[STATE] = status;
+
+ if( status.find("RUN") != string::npos)
+ _running = true;
+
+ }
+
+ // Teste si un job est present en machine
+ bool JobInfo_eLSF::isRunning() const
+ {
+ return _running;
+ }
+
+
+ // Destructeur
+ JobInfo_eLSF::~JobInfo_eLSF()
+ {
+ // Nothing to do
+ }
+
+ // Convertit une date HH:MM:SS en secondes
+ long JobInfo_eLSF::HMStoLong(const string & s)
+ {
+ long hour, min, sec;
+
+ sscanf( s.c_str(), "%ld:%ld:%ld", &hour, &min, &sec);
+ return ( ( ( hour * 60L ) + min ) * 60L ) + sec;
+ }
+
+ // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+ string JobInfo_eLSF::__str__() const
+ {
+ ostringstream sst;
+ sst << "<JobInfo_eLSF (" << this << ") :" << endl;
+ sst << " ID = " <<_param[ID] << endl;
+ sst << " STATE = " <<_param[STATE] << endl;
+
+ return sst.str();
+ }
+
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_eLSF.hxx : emulation of LSF client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _JOBINFO_LSF_H_
+#define _JOBINFO_LSF_H_
+
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+ class JobInfo_eLSF : public JobInfo
+ {
+ public:
+ // Constructeurs et destructeur
+ JobInfo_eLSF() : _running(false) {};
+ JobInfo_eLSF(int id,std::string logFile);
+ virtual ~JobInfo_eLSF();
+
+ // Constructeur par recopie
+ JobInfo_eLSF(const JobInfo_eLSF & jinfo) : JobInfo(jinfo) {};
+
+ // Teste si un job est present en machine
+ virtual bool isRunning() const;
+
+ // Methodes pour l'interfacage avec Python (SWIG)
+ // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+ string __str__() const; // SWIG : affichage en Python
+ string __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+ protected:
+ bool _running; // etat du job en machine
+
+ private:
+ // Convertit une date HH:MM:SS en secondes
+ long HMStoLong(const string &);
+
+ };
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_ePBS.cxx : emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "Batch_Parametre.hxx"
+#include "Batch_Environnement.hxx"
+#include "Batch_RunTimeException.hxx"
+#include "Batch_APIInternalFailureException.hxx"
+#include "Batch_JobInfo_ePBS.hxx"
+
+namespace Batch {
+
+
+
+ // Constructeurs
+ JobInfo_ePBS::JobInfo_ePBS(int id, string logFile) : JobInfo()
+ {
+ // On remplit les membres _param et _env
+ ostringstream oss;
+ oss << id;
+ _param[ID] = oss.str();
+
+ // read of log file
+ char line[128];
+ ifstream fp(logFile.c_str(),ios::in);
+
+ string status;
+ string sline;
+ int pos = string::npos;
+ while( (pos == string::npos) && fp.getline(line,80,'\n') ){
+ sline = string(line);
+ pos = sline.find("job_state");
+ };
+
+ if(pos!=string::npos){
+ istringstream iss(sline);
+ iss >> status;
+ iss >> status;
+ iss >> status;
+ }
+ else
+ status = "U";
+
+ _param[STATE] = status;
+
+ if( status.find("R") != string::npos)
+ _running = true;
+
+ }
+
+ // Teste si un job est present en machine
+ bool JobInfo_ePBS::isRunning() const
+ {
+ return _running;
+ }
+
+
+ // Destructeur
+ JobInfo_ePBS::~JobInfo_ePBS()
+ {
+ // Nothing to do
+ }
+
+ // Convertit une date HH:MM:SS en secondes
+ long JobInfo_ePBS::HMStoLong(const string & s)
+ {
+ long hour, min, sec;
+
+ sscanf( s.c_str(), "%ld:%ld:%ld", &hour, &min, &sec);
+ return ( ( ( hour * 60L ) + min ) * 60L ) + sec;
+ }
+
+ // Methode pour l'interfacage avec Python (SWIG) : affichage en Python
+ string JobInfo_ePBS::__str__() const
+ {
+ ostringstream sst;
+ sst << "<JobInfo_ePBS (" << this << ") :" << endl;
+ sst << " ID = " <<_param[ID] << endl;
+ sst << " STATE = " <<_param[STATE] << endl;
+
+ return sst.str();
+ }
+
+
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+/*
+ * JobInfo_ePBS.hxx : emulation of PBS client
+ *
+ * Auteur : Bernard SECHER - CEA DEN
+ * Mail : mailto:bernard.secher@cea.fr
+ * Date : Thu Apr 24 10:17:22 2008
+ * Projet : PAL Salome
+ *
+ */
+
+#ifndef _JOBINFO_PBS_H_
+#define _JOBINFO_PBS_H_
+
+#include <string>
+#include "Batch_RunTimeException.hxx"
+#include "Batch_JobInfo.hxx"
+
+namespace Batch {
+
+ class JobInfo_ePBS : public JobInfo
+ {
+ public:
+ // Constructeurs et destructeur
+ JobInfo_ePBS() : _running(false) {};
+ JobInfo_ePBS(int id,std::string logFile);
+ virtual ~JobInfo_ePBS();
+
+ // Constructeur par recopie
+ JobInfo_ePBS(const JobInfo_ePBS & jinfo) : JobInfo(jinfo) {};
+
+ // Teste si un job est present en machine
+ virtual bool isRunning() const;
+
+ // Methodes pour l'interfacage avec Python (SWIG)
+ // TODO : supprimer ces methodes et transferer leur definitions dans SWIG
+ string __str__() const; // SWIG : affichage en Python
+ string __repr__() const { return __str__(); }; // SWIG : affichage en Python
+
+ protected:
+ bool _running; // etat du job en machine
+
+ private:
+ // Convertit une date HH:MM:SS en secondes
+ long HMStoLong(const string &);
+
+ };
+
+}
+
+#endif
--- /dev/null
+/*!
+
+\page dsc_page DSC
+
+DSC means Dynamic Software Component. It's an extension of the %SALOME programming model.
+It provides a new paradigm to design %SALOME components. It also provides new ports for %SALOME services.
+These ports are : interface ports and datastream ports.
+
+\section S1_DSC Datastream ports
+
+We list in this section the datastream ports that are provided by %SALOME.
+
+<ol>
+
+<li>
+<b>BASIC datastream ports</b>
+<table>
+<tr><td> <b> Port name </b> </td><td> <b> Data type </b> </td><td> <b> Idl Name </b> </td><td> <b> Idl File </b> </td></tr>
+<tr><td> BASIC_short </td><td> short </td><td> Data_Short_Port </td><td> SALOME_Ports.idl </td></tr>
+</table>
+</li>
+
+<li>
+<b>CALCIUM datastream ports</b>
+<table>
+<tr><td> <b> Port name </b> </td><td> <b> Data type </b> </td><td> <b> Idl Name </b> </td><td> <b> Idl File </b> </td></tr>
+<tr><td> CALCIUM_integer </td><td> sequence of long </td><td> Calcium_Integer_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_real </td><td> sequence of float </td><td> Calcium_Real_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_double </td><td> sequence of double </td><td> Calcium_Double_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_string </td><td> sequence of %string </td><td> Calcium_String_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_logical </td><td> sequence of boolean </td><td> Calcium_Logical_Port </td><td> Calcium_Ports.idl </td></tr>
+<tr><td> CALCIUM_complex </td><td> sequence of float </td><td> Calcium_Complex_Port </td><td> Calcium_Ports.idl </td></tr>
+</table>
+</li>
+
+<li>
+<b>PALM datastream ports</b>
+<table>
+<tr><td> <b> Port name </b> </td><td> <b> Data type </b> </td><td> <b> Idl Name </b> </td><td> <b> Idl File </b> </td></tr>
+<tr><td> PALM_short </td><td> short </td><td> Palm_Data_Short_Port </td><td> Palm_Ports.idl </td></tr>
+<tr><td> PALM_seq_short </td><td> sequence of short </td><td> Palm_Data_Seq_Short_Port </td><td> Palm_Ports.idl </td></tr>
+</table>
+</li>
+
+</ol>
+
+*/
+
+
--- /dev/null
+// Copyright (C) 2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+// File : CalciumCxxInterface.hxx
+// Author : Eric Fayolle (EDF)
+// Module : KERNEL
+// Modified by : $LastChangedBy$
+// Date : $LastChangedDate: 2007-03-01 13:27:58 +0100 (jeu, 01 mar 2007) $
+// Id : $Id$
+
+#ifndef _CALCIUM_CXXINTERFACE_HXX_
+#define _CALCIUM_CXXINTERFACE_HXX_
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include "Superv_Component_i.hxx"
+#include "CalciumException.hxx"
+#include "CalciumTypes.hxx"
+#include "CalciumGenericUsesPort.hxx"
+#include "Copy2UserSpace.hxx"
+#include "Copy2CorbaSpace.hxx"
+#include "CalciumPortTraits.hxx"
+
+#include <stdio.h>
+
+//#define _DEBUG_
+
+template <typename T1, typename T2>
+struct IsSameType {
+ static const bool value = false;
+};
+template <typename T1>
+struct IsSameType<T1,T1> {
+ static const bool value = true;
+};
+
+
+#include <boost/type_traits/remove_all_extents.hpp>
+
+namespace CalciumInterface {
+
+ /********************* INTERFACE DE DECONNEXION *****************/
+
+ static inline void
+ ecp_cd (Superv_Component_i & component, std::string & instanceName)
+ {
+ /* TODO : Trouver le nom de l'instance SALOME*/
+ if (instanceName.empty()) instanceName="UNDEFINED";
+
+ }
+
+ static void
+ ecp_fin (Superv_Component_i & component, bool provideLastGivenValue)
+ {
+ std::vector<std::string> usesPortNames;
+ std::vector<std::string>::const_iterator it;
+ component.get_uses_port_names(usesPortNames);
+
+ //Récupérer le type de réel du port est un peu difficile
+ //car l'interface ne donne aucune indication
+
+ // uses_port *myUsesPort;
+ calcium_uses_port* myCalciumUsesPort;
+
+ for (it=usesPortNames.begin(); it != usesPortNames.end(); ++it) {
+ try {
+
+ myCalciumUsesPort=
+ component.Superv_Component_i::get_port< calcium_uses_port >((*it).c_str());
+
+// component.Superv_Component_i::get_port(myUsesPort,(*it).c_str());
+// calcium_uses_port* myCalciumUsesPort=
+// dynamic_cast<calcium_uses_port*>(myUsesPort);
+
+#ifdef _DEBUG_
+ std::cerr << "-------- CalciumInterface(ecp_fin) MARK 1 -|"<< *it <<"|----"<<
+ // typeid(myUsesPort).name() <<"-------------" <<
+ typeid(myCalciumUsesPort).name() <<"-------------" << std::endl;
+#endif
+
+// if ( !myCalciumUsesPort )
+// throw Superv_Component_i::BadCast(LOC(OSS()<<"Impossible de convertir le port "
+// << *it << " en port de type calcium_uses_port." ));
+
+ myCalciumUsesPort->disconnect(provideLastGivenValue);
+
+ } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;
+#endif
+ throw (CalciumException(CalciumTypes::CPTPVR,ex));
+ } catch ( const DSC_Exception & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;
+#endif
+ // Exception venant de SupervComponent :
+ // PortNotDefined(CPNMVR), PortNotConnected(CPLIEN)
+ // ou du port uses : Dsc_Exception
+ // On continue à traiter la deconnexion des autres ports uses
+ } catch (...) {
+ throw (CalciumException(CalciumTypes::CPATAL,"Exception innatendue"));
+ // En fonction du mode de gestion des erreurs throw;
+ }
+ }
+ }
+
+
+ /********************* INTERFACES DE DESALLOCATION *****************/
+
+ // Uniquement appelé par l'utilisateur s'il utilise la 0 copie
+ // ( pointeur de données data==NULL à l'appel de ecp_lecture )
+ // Une désallocation aura lieu uniquement si un buffer intermédiaire
+ // était necessaire (type utilisateur et corba diffférent)
+ // La propriété du buffer est rendue à CORBA sinon
+ template <typename T1, typename T2> static void
+ ecp_free ( T1 * dataPtr )
+ {
+ typedef typename ProvidesPortTraits<T2>::PortType PortType;
+ typedef typename PortType::DataManipulator DataManipulator;
+ typedef typename DataManipulator::Type DataType; // Attention != T1
+ typedef typename DataManipulator::InnerType InnerType;
+
+ DeleteTraits<IsSameType<T1,InnerType>::value, DataManipulator >::apply(dataPtr);
+ }
+
+ template <typename T1> static void
+ ecp_free ( T1 * dataPtr )
+ {
+ ecp_free<T1,T1> ( dataPtr );
+ }
+
+
+ /********************* INTERFACES DE LECTURE *****************/
+
+
+ // T1 est le type de données
+ // T2 est un <nom> de type Calcium permettant de sélectionner le port CORBA correspondant
+ // T1 et T2 sont dissociés pour discriminer le cas des nombres complexes
+ // -> Les données des nombres complexes sont de type float mais
+ // le port à utiliser est le port cplx
+ template <typename T1, typename T2 > static void
+ ecp_lecture ( Superv_Component_i & component,
+ int const & dependencyType,
+ double & ti,
+ double const & tf,
+ long & i,
+ const string & nomVar,
+ size_t bufferLength,
+ size_t & nRead,
+ T1 * &data )
+ {
+
+ assert(&component);
+
+ typedef typename ProvidesPortTraits<T2>::PortType PortType;
+ typedef typename PortType::DataManipulator DataManipulator;
+ typedef typename DataManipulator::Type CorbaDataType; // Attention != T1
+ typedef typename DataManipulator::InnerType InnerType;
+ CalciumTypes::DependencyType _dependencyType=
+ static_cast<CalciumTypes::DependencyType>(dependencyType);
+
+ CorbaDataType corbaData;
+
+#ifdef _DEBUG_
+ std::cerr << "-------- CalciumInterface(ecp_lecture) MARK 1 ------------------" << std::endl;
+#endif
+
+ if (nomVar.empty())
+ throw CalciumException(CalciumTypes::CPNMVR,
+ LOC("Le nom de la variable est <nul>"));
+ PortType * port;
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 2 ------------------" << std::endl;
+#endif
+
+ try {
+ port = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 3 ------------------" << std::endl;
+#endif
+ } catch ( const Superv_Component_i::PortNotDefined & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;
+#endif
+ throw (CalciumException(CalciumTypes::CPNMVR,ex));
+ } catch ( const Superv_Component_i::PortNotConnected & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;;
+#endif
+ throw (CalciumException(CalciumTypes::CPLIEN,ex));
+ // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
+ } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;
+#endif
+ throw (CalciumException(CalciumTypes::CPTPVR,ex));
+ }
+
+ // mode == mode du port
+ CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
+
+ if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
+ throw CalciumException(CalciumTypes::CPIT,
+ LOC(OSS()<<"Le mode de dépendance de la variable "
+ << nomVar << " est indéfini."));
+
+ if ( ( portDependencyType != _dependencyType ) &&
+ ( _dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) )
+ throw CalciumException(CalciumTypes::CPITVR,
+ LOC(OSS()<<"Le mode de dépendance de la variable "
+ << nomVar << ": " << portDependencyType
+ << " ne correspond pas au mode demandé."));
+
+
+ if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
+ corbaData = port->get(ti,tf, 0);
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 5 ------------------" << std::endl;
+#endif
+ }
+ else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
+ corbaData = port->get(0, i);
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl;
+#endif
+ } else {
+ // Lecture en séquence
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 7 ------------------" << std::endl;
+#endif
+ corbaData = port->next(ti,i);
+ }
+
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 8 ------------------" << std::endl;
+#endif
+ size_t corbaDataSize = DataManipulator::size(corbaData);
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) corbaDataSize : " << corbaDataSize << std::endl;
+#endif
+
+ // Vérifie si l'utilisateur demande du 0 copie
+ if ( data == NULL ) {
+ if ( bufferLength != 0 ) {
+ MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)");
+ }
+ nRead = corbaDataSize;
+ // Si les types T1 et InnerType sont différents, il faudra effectuer tout de même une recopie
+ if (!IsSameType<T1,InnerType>::value) data = new T1[nRead];
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl;
+#endif
+ // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes.
+ // Copy2UserSpace :
+ // La raison d'être du foncteur Copy2UserSpace est que le compilateur n'acceptera
+ // pas une expresion d'affectation sur des types incompatibles même
+ // si cette expression se trouve dans une branche non exécuté d'un test
+ // sur la compatibilité des types.
+ // En utilisant le foncteur Copy2UserSpace, seul la spécialisation en adéquation
+ // avec la compatibilité des types sera compilée
+ Copy2UserSpace< IsSameType<T1,InnerType>::value, DataManipulator >::apply(data,corbaData,nRead);
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl;
+#endif
+ // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
+ // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+ // DataManipulator::delete_data(corbaData);
+ // ni DataManipulator::getPointer(corbaData,true); qui détruit la sequence lorsque l'on
+ // prend la propriété du buffer
+ // old : Dans les deux cas la structure CORBA n'est plus utile
+ // old : Si !IsSameType<T1,InnerType>::value l'objet CORBA est détruit avec son contenu
+ // old : Dans l'autre cas seul la coquille CORBA est détruite
+ // L'utilisateur devra appeler ecp_free qui déterminera s'il est necessaire
+ // de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété
+ } else {
+ nRead = std::min < size_t > (corbaDataSize,bufferLength);
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl;
+#endif
+ Copy2UserSpace<false, DataManipulator >::apply(data,corbaData,nRead);
+ DataManipulator::copy(corbaData,data,nRead);
+
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
+#endif
+ // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
+ // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+ // DataManipulator::delete_data(corbaData);
+ }
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecp_lecture), Valeur de data : " << std::endl;
+ std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
+ std::cout << "Ptr :" << data << std::endl;
+
+ std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl;
+#endif
+
+
+ return;
+ }
+
+ // T1 est le type de données
+ template <typename T1 > static void
+ ecp_lecture ( Superv_Component_i & component,
+ int const & dependencyType,
+ double & ti,
+ double const & tf,
+ long & i,
+ const string & nomVar,
+ size_t bufferLength,
+ size_t & nRead,
+ T1 * &data )
+ {
+ ecp_lecture<T1,T1> (component,dependencyType,ti,tf,
+ i,nomVar,bufferLength,nRead,data);
+
+ }
+
+ /********************* INTERFACES D'ECRITURE *****************/
+
+ // T1 : DataType
+ // T2 : PortType
+ template <typename T1, typename T2> static void
+ ecp_ecriture ( Superv_Component_i & component,
+ int const & dependencyType,
+ double const & t,
+ long const & i,
+ const string & nomVar,
+ size_t bufferLength,
+ T1 const & data )
+ {
+
+ assert(&component);
+
+ //typedef typename StarTrait<TT>::NonStarType T;
+ typedef typename boost::remove_all_extents< T2 >::type T2_without_extent;
+ typedef typename boost::remove_all_extents< T1 >::type T1_without_extent;
+
+ typedef typename UsesPortTraits <T2_without_extent>::PortType UsesPortType;
+ typedef typename ProvidesPortTraits<T2_without_extent>::PortType ProvidesPortType;// pour obtenir un manipulateur de données
+ typedef typename ProvidesPortType::DataManipulator DataManipulator;
+ // Verifier que l'on peut définir UsesPortType::DataManipulator
+ // typedef typename PortType::DataManipulator DataManipulator;
+ typedef typename DataManipulator::Type CorbaDataType; // Attention != T1
+ typedef typename DataManipulator::InnerType InnerType;
+
+ T1_without_extent const & _data = data;
+
+ CalciumTypes::DependencyType _dependencyType=
+ static_cast<CalciumTypes::DependencyType>(dependencyType);
+
+#ifdef _DEBUG_
+ std::cerr << "-------- CalciumInterface(ecriture) MARK 1 ------------------" << std::endl;
+#endif
+ if ( nomVar.empty() ) throw CalciumException(CalciumTypes::CPNMVR,
+ LOC("Le nom de la variable est <nul>"));
+ UsesPortType * port;
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture) MARK 2 ------------------" << std::endl;
+#endif
+
+ try {
+ port = component.Superv_Component_i::get_port< UsesPortType > (nomVar.c_str());
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl;
+#endif
+ } catch ( const Superv_Component_i::PortNotDefined & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;
+#endif
+ throw (CalciumException(CalciumTypes::CPNMVR,ex));
+ } catch ( const Superv_Component_i::PortNotConnected & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;;
+#endif
+ throw (CalciumException(CalciumTypes::CPLIEN,ex));
+ // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
+ } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+ std::cerr << ex.what() << std::endl;
+#endif
+ throw (CalciumException(CalciumTypes::CPTPVR,ex));
+ }
+
+ // mode == mode du port
+ // On pourrait créer la méthode CORBA dans le mode de Couplage CALCIUM.
+ // et donc ajouter cette cette méthode uniquement dans l'IDL calcium !
+
+// CalciumTypes::DependencyType portDependencyType;
+// try {
+// portDependencyType = port->getDependencyType();
+// std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
+// } catch ( const DSC_Exception & ex ) {
+// std::cerr << ex.what() << std::endl;;
+// throw (CalciumException(CalciumTypes::CPIT,ex));
+// }
+
+ if ( _dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
+ throw CalciumException(CalciumTypes::CPIT,
+ LOC(OSS()<<"Le mode de dépendance demandé pour la variable "
+ << nomVar << " est indéfini."));
+
+ if ( _dependencyType == CalciumTypes::SEQUENCE_DEPENDENCY )
+ throw CalciumException(CalciumTypes::CPIT,
+ LOC(OSS()<<"Le mode de dépendance SEQUENCE_DEPENDENCY pour la variable "
+ << nomVar << " est impossible en écriture."));
+
+ // Il faudrait que le port provides génère une exception si le mode donnée n'est pas
+ // le bon. La seule façon de le faire est d'envoyer -1 en temps si on n'est en itération
+ // et vice-versa pour informer les provides port du mode dans lequel on est. Sinon il faut
+ // modifier l'interface IDL pour y ajouter un mode de dépendance !
+ // ---->
+// if ( portDependencyType != _dependencyType )
+// throw CalciumException(CalciumTypes::CPITVR,
+// LOC(OSS()<<"Le mode de dépendance de la variable "
+// << nomVar << " ne correspond pas au mode demandé."));
+
+
+ if ( bufferLength < 1 )
+ throw CalciumException(CalciumTypes::CPNTNULL,
+ LOC(OSS()<<"Le buffer a envoyer est de taille nulle "));
+
+
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
+#endif
+ CorbaDataType corbaData;
+
+
+ // Si les types Utilisateurs et CORBA sont différents
+ // il faut effectuer une recopie sinon on utilise directement le
+ // buffer data pour constituer la séquence
+ // TODO :
+ // - Attention en mode asynchrone il faudra eventuellement
+ // faire une copie des données même si elles sont de même type.
+ // - OLD : En cas de collocalisation (du port provide et du port uses)
+ // OLD : il est necessaire d'effectuer une recopie du buffer car la
+ // OLD : séquence est envoyée au port provide par une référence sur
+ // OLD : la séquence locale. Or la méthode put récupère le buffer directement
+ // OLD : qui est alors le buffer utilisateur. Il pourrait alors arriver que :
+ // OLD : * Le recepteur efface le buffer emetteur
+ // OLD : * Le port lui-même efface le buffer de l'utilisateur !
+ // OLD : Cette copie est effectuée dans GenericPortUses::put
+ // OLD : en fonction de la collocalisation ou non.
+ // - OLD :En cas de connection multiples d'un port uses distant vers plusieurs port provides
+ // OLD : collocalisés les ports provides partagent la même copie de la donnée !
+ // OLD : Il faut effectuer une copie dans le port provides.
+ // OLD : Cette copie est effectuée dans GenericPortUses::put
+ // OLD : en fonction de la collocalisation ou non.
+ Copy2CorbaSpace<IsSameType<T1_without_extent,InnerType>::value, DataManipulator >::apply(corbaData,_data,bufferLength);
+
+ //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté
+ if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
+ try
+ {
+ port->put(*corbaData,t, -1);
+ }
+ catch ( const DSC_Exception & ex)
+ {
+ throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
+ }
+ //Le -1 peut être traité par le cst DataIdContainer et transformé en 0
+ //Etre obligé de mettre une étoile ds (*corbadata) va poser des pb pour les types <> seq
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl;
+#endif
+ }
+ else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
+ try
+ {
+ port->put(*corbaData,-1, i);
+ }
+ catch ( const DSC_Exception & ex)
+ {
+ throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
+ }
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture) MARK 6 ------------------" << std::endl;
+#endif
+ }
+
+
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture), Valeur de corbaData : " << std::endl;
+ for (int i = 0; i < corbaData->length(); ++i)
+ cout << "-------- CalciumInterface(ecriture), corbaData[" << i << "] = " << (*corbaData)[i] << endl;
+#endif
+
+ // if ( !IsSameType<T1,InnerType>::value ) delete corbaData;
+ // Supprime l'objet CORBA avec eventuellement les données qu'il contient (cas de la recopie)
+ delete corbaData;
+
+#ifdef _DEBUG_
+ std::cout << "-------- CalciumInterface(ecriture) MARK 7 ------------------" << std::endl;
+#endif
+
+ return;
+ };
+
+ template <typename T1> static void
+ ecp_ecriture ( Superv_Component_i & component,
+ int const & dependencyType,
+ double const & t,
+ long const & i,
+ const string & nomVar,
+ size_t bufferLength,
+ T1 const & data ) {
+ ecp_ecriture<T1,T1> (component,dependencyType,t,i,nomVar,bufferLength,data);
+ };
+
+};
+
+#endif
--- /dev/null
+/* Copyright (C) 2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+ * CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+ *
+ * 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
+ *
+ * See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+ *
+ *
+ *
+ * File : calcium.h
+ * Author : Eric Fayolle (EDF)
+ * Module : KERNEL
+ */
+
+/* Outils d'Aide au Couplage de Code de Calcul : $Id$ */
+
+#ifndef __CALCIUM_E_H
+#define __CALCIUM_E_H
+
+#include <calciumP.h>
+
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define CPNeedPrototype 1
+#else
+#define CPNeedPrototype 0
+#endif
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* */
+/* */
+/* Fonctions de connexion */
+/* */
+/* */
+extern int ecp_cd(
+/* ----- */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ char * /* S Nom de l instance appelante*/
+#endif
+);
+
+
+/* */
+/* */
+/* Fonction de deconnexion */
+/* */
+/* */
+extern int ecp_fin(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Directive de continuation */
+ /* CP_CONT ou CP_ARRET */
+#endif
+);
+
+/* */
+/* */
+/* Fonctions de libération du buffer 0 copy */
+/* */
+
+ extern void ecp_len_free(
+#if CPNeedPrototype
+ int *
+#endif
+ );
+ extern void ecp_lre_free(
+#if CPNeedPrototype
+ float *
+#endif
+ );
+ extern void ecp_ldb_free(
+#if CPNeedPrototype
+ double *
+#endif
+ );
+ extern void ecp_llo_free(
+#if CPNeedPrototype
+ int *
+#endif
+ );
+ extern void ecp_lcp_free(
+#if CPNeedPrototype
+ float *
+#endif
+ );
+ extern void ecp_lch_free(
+#if CPNeedPrototype
+ char **
+#endif
+ );
+
+
+
+/* */
+/* */
+/* Fonctions de lecture bloquante 0 copy */
+/* */
+/* */
+extern int ecp_len(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ int ** /* E/S Tableau d'entiers pour stocker les */
+ /* valeurs lues */
+#endif
+);
+
+extern int ecp_lre(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ float **/* E/S Tableau de flottants pour stocker les */
+ /* valeurs lues */
+#endif
+);
+
+extern int ecp_ldb(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ double* /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ double* /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ double**/* E/S Tableau de doubles pour stocker les */
+ /* valeurs lues */
+#endif
+);
+
+extern int ecp_lcp(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ float **/* E/S Tableau de flottants pour stocker les */
+ /* valeurs lues (dimension = 2 * le nombre */
+ /* de valeurs lues) */
+#endif
+);
+
+extern int ecp_llo(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ int ** /* E/S Tableau d 'entier pour stocker les */
+ /* valeurs lues (remplace le logiques) */
+#endif
+);
+
+extern int ecp_lch(
+/* ------ */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ char **[]/*E/S Tableau de chaines pour stocker les */
+ /* valeurs lues (remplace le logiques) */,
+ int /* E Taille des chaines du tablaeu */
+#endif
+);
+
+
+
+/* */
+/* */
+/* Fonctions de lecture non bloquantes */
+/* */
+/* */
+extern int ecp_nlen(
+/* ------- */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ int ** /* E/S Tableau d'entiers pour stocker les */
+ /* valeurs lues */
+#endif
+);
+
+extern int ecp_nlre(
+/* ------- */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ float **/* E/S Tableau de flottants pour stocker les */
+ /* valeurs lues */
+#endif
+);
+
+extern int ecp_nldb(
+/* ------- */
+
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ double */* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ double */* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ double**/* E/S Tableau de doubles pour stocker les */
+ /* valeurs lues */
+#endif
+);
+
+extern int ecp_nlcp(
+/* ------- */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ float **/* E/S Tableau de flottants pour stocker les */
+ /* valeurs lues (dimension = 2 * le nombre */
+ /* de valeurs lues) */
+#endif
+);
+
+extern int ecp_nllo(
+/* ------- */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ int **/* E/S Tableau d 'entier pour stocker les */
+ /* valeurs lues (remplace le logiques) */
+#endif
+);
+
+extern int ecp_nlch(
+/* ------- */
+#if CPNeedPrototype
+ void * component /* Pointeur de type Superv_Component_i* sur le */
+ /* composant SALOME Supervisable */,
+ int /* E Type de dependance ou de lecture */
+ /* CP_TEMPS, CP_ITERATION, CP_SEQUENTIEL */,
+ float * /* E/S Borne inf de l'intervalle de lecture */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ float * /* E Borne Sup de l'intervalle de lecture */,
+ int * /* E/S Pas d'iteration a lire */
+ /* Retourne le pas lu dans le cas de */
+ /* lecture sequentielle */,
+ char * /* E Nom de la variable a lire */,
+ int /* E Nombre max de valeurs a lire */,
+ int * /* S Nombre de valeurs rellement lues */,
+ char **[]/* E/S Tableau de chaines pour stocker les */
+ /* valeurs lues (remplace le logiques) */,
+ int /* E Taille des chaines du tablaeu */
+#endif
+);
+
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif
--- /dev/null
+#include "BatchTest.hxx"
+
+BatchTest::BatchTest(const Engines::MachineParameters& batch_descr)
+{
+ _batch_descr = batch_descr;
+
+ // Getting date
+ Batch::Date date = Batch::Date(time(0));
+ _date = date.str();
+ int lend = _date.size() ;
+ int i = 0 ;
+ while (i < lend)
+ {
+ if (_date[i] == '/' || _date[i] == '-' || _date[i] == ':' )
+ {
+ _date[i] = '_' ;
+ }
+ i++ ;
+ }
+
+ // Creating test temporary file
+ _test_filename = "/tmp/";
+ _test_filename += _date + "_test_cluster_file_";
+ _test_filename += _batch_descr.alias.in();
+ _base_filename = _date + "_test_cluster_file_" + _batch_descr.alias.in();
+}
+
+BatchTest::~BatchTest() {}
+
+bool
+BatchTest::test()
+{
+ bool rtn = false;
+ INFOS(std::endl
+ << "--- Testing batch Machine :" << std::endl
+ << "--- Name : " << _batch_descr.hostname << std::endl
+ << "--- Alias : " << _batch_descr.alias << std::endl
+ << "--- Protocol : " << _batch_descr.protocol << std::endl
+ << "--- User Name : " << _batch_descr.username << std::endl
+ << "--- Batch Type : " << _batch_descr.batch << std::endl
+ << "--- MPI Impl : " << _batch_descr.mpiImpl << std::endl
+ << "--- Appli Path : " << _batch_descr.applipath << std::endl
+ );
+
+ std::string result_connection("Not Tested");
+ std::string result_filecopy("Not Tested");
+ std::string result_getresult("Not Tested");
+ std::string result_jobsubmit_simple("Not Tested");
+ std::string result_jobsubmit_mpi("Not Tested");
+ std::string result_appli("Not Tested");
+
+ result_connection = test_connection();
+ result_filecopy = test_filecopy();
+ result_getresult = test_getresult();
+ result_jobsubmit_simple = test_jobsubmit_simple();
+ result_jobsubmit_mpi = test_jobsubmit_mpi();
+ result_appli = test_appli();
+
+ INFOS(std::endl
+ << "--- Test results" << std::endl
+ << "--- Connection : " << result_connection << std::endl
+ << "--- File copy : " << result_filecopy << std::endl
+ << "--- Get results : " << result_getresult << std::endl
+ << "--- Submit simple job : " << result_jobsubmit_simple << std::endl
+ << "--- Submit mpi job : " << result_jobsubmit_mpi << std::endl
+ << "--- Application : " << result_appli << std::endl
+ );
+
+ if (result_connection == "OK" and
+ result_filecopy == "OK" and
+ result_getresult == "OK" and
+ result_jobsubmit_simple == "OK" and
+ result_jobsubmit_mpi == "OK" and
+ result_appli == "OK")
+ rtn = true;
+
+ return rtn;
+}
+
+// For this test we use : alias, protocol, username
+std::string
+BatchTest::test_connection()
+{
+ int status;
+ std::string command;
+ std::string result("Failed : ");
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+
+ // Basic tests
+ if(alias == "")
+ {
+ result += "alias is empty !";
+ return result;
+ }
+ if(username == "")
+ {
+ result += "username is empty !";
+ return result;
+ }
+ if( protocol != "rsh" and protocol != "ssh")
+ {
+ result += "protocol unknown ! (" + protocol + ")";
+ return result;
+ }
+
+ // Build command
+ command += protocol
+ + " "
+ + username + "@" + alias;
+
+ // Test
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error of connection on remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ result = "OK";
+ return result;
+}
+
+// For this test we use : alias, protocol, username
+std::string
+BatchTest::test_filecopy()
+{
+ int status;
+ std::string home;
+ std::string command;
+ std::string result("Failed : ");
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+
+ // Getting home directory
+ std::string rst = get_home(&home);
+ if(rst != "") {
+ result += rst;
+ return result;
+ }
+
+ // Writing into the tempory file
+ command = "echo Hello > " + _test_filename;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in creating tempory file ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Build command
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " " + _test_filename + " "
+ + username + "@" + alias + ":" + home;
+
+ // Test
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in copy file on remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ result = "OK";
+ return result;
+}
+
+// For this test we use : alias, protocol, username
+std::string
+BatchTest::test_getresult()
+{
+ int status;
+ std::string home;
+ std::string command;
+ std::string result("Failed : ");
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+
+ // Getting home directory
+ std::string rst = get_home(&home);
+ if(rst != "") {
+ result += rst;
+ return result;
+ }
+
+ // Build command
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " " + username + "@" + alias + ":" + home
+ + "/" + _base_filename + " " + _test_filename + "_copy";
+
+ // Test
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in copy file from remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Compare files
+ std::ifstream src_file(_test_filename.c_str());
+ if (!src_file)
+ {
+ result += "Error in reading temporary file ! filename = " + _test_filename;
+ return result;
+ }
+ std::string cp_filename = _test_filename + "_copy";
+ std::ifstream cp_file(cp_filename.c_str());
+ if (!cp_file)
+ {
+ result += "Error in reading temporary copy file ! filename = " + cp_filename;
+ return result;
+ }
+ std::string src_firstline;
+ std::string cp_firstline;
+ std::getline(src_file, src_firstline);
+ std::getline(cp_file, cp_firstline);
+ src_file.close();
+ cp_file.close();
+ if (src_firstline != cp_firstline)
+ {
+ result += "Error source file and copy file are not equa ! source = " + src_firstline + " copy = " + cp_firstline;
+ return result;
+ }
+
+ result = "OK";
+ return result;
+}
+
+std::string
+BatchTest::test_jobsubmit_simple()
+{
+ int status;
+ std::string home;
+ std::string command;
+ std::string result("Failed : ");
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+ std::string batch_type = _batch_descr.batch.in();
+
+ // Basic test
+ if (batch_type == "slurm")
+ {
+ INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK");
+ result = "OK";
+ return result;
+ }
+ if (batch_type != "pbs")
+ {
+ result += "Batch type unknown ! : " + batch_type;
+ return result;
+ }
+
+ // Getting home directory
+ std::string rst = get_home(&home);
+ if(rst != "") {
+ result += rst;
+ return result;
+ }
+
+ // PBS test
+ std::string _test_file_simple = _test_filename + "_simple";
+ std::ofstream file;
+ file.open(_test_file_simple.c_str(), std::ofstream::out);
+ file << "#!/bin/bash\n"
+ << "#PBS -l nodes=1\n"
+ << "#PBS -l walltime=00:01:00\n"
+ << "#PBS -o " + home + "/" + _date + "_simple_output.log\n"
+ << "#PBS -e " + home + "/" + _date + "_simple_error.log\n"
+ << "echo Bonjour\n"
+ << "echo Error >&2\n";
+ file.flush();
+ file.close();
+
+
+ // Build command for copy
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " " + _test_file_simple + " "
+ + username + "@" + alias + ":" + home;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in copy job file to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Build command for submit job
+ std::string file_job_name = _test_filename + "_jobid";
+ command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_simple > " + file_job_name;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in sending qsub to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+ std::string jobid;
+ std::ifstream file_job(file_job_name.c_str());
+ if (!file_job)
+ {
+ result += "Error in reading temporary file ! filename = " + file_job_name;
+ return result;
+ }
+ std::getline(file_job, jobid);
+ file_job.close();
+
+ // Wait the end of the job
+ command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name;
+ bool stop = false;
+ while (!stop)
+ {
+ status = system(command.c_str());
+ if(status && status != 153 && status != 256*153)
+ {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in sending qstat to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ if(status == 153 || status == 256*153 )
+ stop = true;
+ sleep(1);
+ }
+
+ // Build command for getting results
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " "
+ + username + "@" + alias + ":" + home + "/" + _date + "_simple* /tmp";
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "error in getting file result of qsub simple to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Test results
+ std::string normal_input;
+ std::string file_normal_name = "/tmp/" + _date + "_simple_output.log";
+ std::ifstream file_normal(file_normal_name.c_str());
+ if (!file_normal)
+ {
+ result += "Error in reading temporary file ! filename = " + file_normal_name;
+ return result;
+ }
+ std::getline(file_normal, normal_input);
+ file_normal.close();
+ if (normal_input != "Bonjour")
+ {
+ result += "error from simple ouput file ! waiting for Bonjour and get : " + normal_input;
+ return result;
+ }
+ std::string error_input;
+ std::string file_error_name = "/tmp/" + _date + "_simple_error.log";
+ std::ifstream file_error(file_error_name.c_str());
+ if (!file_error)
+ {
+ result += "Error in reading temporary file ! filename = " + file_error_name;
+ return result;
+ }
+ std::getline(file_error, error_input);
+ file_error.close();
+ if (error_input != "Error")
+ {
+ result += "error from simple error file ! waiting for Error and get : " + error_input;
+ return result;
+ }
+ result = "OK";
+ return result;
+}
+
+std::string
+BatchTest::test_jobsubmit_mpi()
+{
+ int status;
+ std::string home;
+ std::string command;
+ MpiImpl * mpiImpl;
+ std::string result("Failed : ");
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+ std::string batch_type = _batch_descr.batch.in();
+ std::string mpi_type = _batch_descr.mpiImpl.in();
+
+ // Basic test
+ if(mpi_type == "lam")
+ mpiImpl = new MpiImpl_LAM();
+ else if(mpi_type == "mpich1")
+ mpiImpl = new MpiImpl_MPICH1();
+ else if(mpi_type == "mpich2")
+ mpiImpl = new MpiImpl_MPICH2();
+ else if(mpi_type == "openmpi")
+ mpiImpl = new MpiImpl_OPENMPI();
+ else
+ {
+ result += "Error MPI impl not supported : " + mpi_type;
+ return result;
+ }
+
+ // SLURM not yet implemented...
+ if (batch_type == "slurm")
+ {
+ INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK");
+ result = "OK";
+ return result;
+ }
+
+ // Getting home directory
+ std::string rst = get_home(&home);
+ if(rst != "") {
+ result += rst;
+ return result;
+ }
+
+ // MPI test
+ std::string _test_file_script = _test_filename + "_script";
+ std::ofstream file_script;
+ file_script.open(_test_file_script.c_str(), std::ofstream::out);
+ file_script << "#!/bin/bash\n"
+ << "echo HELLO MPI\n";
+ file_script.flush();
+ file_script.close();
+ chmod(_test_file_script.c_str(), 0x1ED);
+
+ std::string _test_file_mpi = _test_filename + "_mpi";
+ std::ofstream file_mpi;
+ file_mpi.open(_test_file_mpi.c_str(), std::ofstream::out);
+ file_mpi << "#!/bin/bash\n"
+ << "#PBS -l nodes=1\n"
+ << "#PBS -l walltime=00:01:00\n"
+ << "#PBS -o " << home << "/" << _date << "_mpi_output.log\n"
+ << "#PBS -e " << home << "/" << _date << "_mpi_error.log\n"
+ << mpiImpl->boot("${PBS_NODEFILE}", 1)
+ << mpiImpl->run("${PBS_NODEFILE}", 1, _base_filename + "_script")
+ << mpiImpl->halt();
+ file_mpi.flush();
+ file_mpi.close();
+
+
+ // Build command for copy
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " " + _test_file_script + " "
+ + username + "@" + alias + ":" + home;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in copy job file to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " " + _test_file_mpi + " "
+ + username + "@" + alias + ":" + home;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in copy job file to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Build command for submit job
+ std::string file_job_name = _test_filename + "_jobid";
+ command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_mpi > " + file_job_name;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in sending qsub to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+ std::string jobid;
+ std::ifstream file_job(file_job_name.c_str());
+ if (!file_job)
+ {
+ result += "Error in reading temporary file ! filename = " + file_job_name;
+ return result;
+ }
+ std::getline(file_job, jobid);
+ file_job.close();
+
+ // Wait the end of the job
+ command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name;
+ bool stop = false;
+ while (!stop)
+ {
+ status = system(command.c_str());
+ if(status && status != 153 && status != 256*153)
+ {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in sending qstat to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ if(status == 153 || status == 256*153 )
+ stop = true;
+ sleep(1);
+ }
+
+ // Build command for getting results
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " "
+ + username + "@" + alias + ":" + home + "/" + _date + "_mpi* /tmp";
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "error in getting file result of qsub mpi from remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Test results
+ std::string normal_input;
+ std::string file_normal_name = "/tmp/" + _date + "_mpi_output.log";
+ std::ifstream file_normal(file_normal_name.c_str());
+ if (!file_normal)
+ {
+ result += "Error in reading temporary file ! filename = " + file_normal_name;
+ return result;
+ }
+ bool test_ok = false;
+ while (std::getline(file_normal, normal_input))
+ {
+ if (normal_input == "HELLO MPI")
+ test_ok = true;
+ }
+ file_normal.close();
+ if (!test_ok)
+ {
+ result += "error from mpi ouput file ! waiting for HELLO MPI please watch /tmp/" + _date + "_mpi_output.log file";
+ return result;
+ }
+ result = "OK";
+ return result;
+}
+
+std::string
+BatchTest::test_appli()
+{
+ int status;
+ std::string home;
+ std::string command;
+ std::string result("Failed : ");
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+ std::string applipath = _batch_descr.applipath.in();
+
+ // Getting home directory
+ std::string rst = get_home(&home);
+ if(rst != "") {
+ result += rst;
+ return result;
+ }
+
+ std::string _test_file_appli = _test_filename + "_appli_test";
+ std::ofstream file_appli;
+ file_appli.open(_test_file_appli.c_str(), std::ofstream::out);
+ file_appli << "#!/bin/bash\n"
+ << "if [ -f " << applipath << "/runAppli ]\n"
+ << "then\n"
+ << " echo OK\n"
+ << "else\n"
+ << " echo NOK\n"
+ << "fi\n";
+ file_appli.flush();
+ file_appli.close();
+
+ // Build command for copy
+ command = "scp";
+ if(protocol == "rsh")
+ command = "rcp";
+ command += " " + _test_file_appli + " "
+ + username + "@" + alias + ":" + home;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in copy appli test file to remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Launch test
+ command = protocol + " " + username + "@" + alias
+ + " sh " + home + "/" + _base_filename + "_appli_test > "
+ + _test_filename + "_appli_test_result";
+
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in launching appli test on remote host ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ // Read test result
+ std::string rst_appli;
+ std::string file_appli_result_name = _test_filename + "_appli_test_result";
+ std::ifstream file_appli_result(file_appli_result_name.c_str());
+ if (!file_appli_result)
+ {
+ result += "Error in reading temporary file ! filename = " + file_appli_result_name;
+ return result;
+ }
+ std::getline(file_appli_result, rst_appli);
+ file_appli_result.close();
+
+ if (rst_appli != "OK")
+ {
+ result += "Error checking application on remote host ! result = " + rst;
+ return result;
+ }
+
+ result = "OK";
+ return result;
+}
+
+// Useful methods
+std::string
+BatchTest::get_home(std::string * home)
+{
+ int status;
+ std::string result = "";
+ std::string command;
+ std::string alias = _batch_descr.alias.in();
+ std::string username = _batch_descr.username.in();
+ std::string protocol = _batch_descr.protocol.in();
+ std::string file_home_name = _test_filename + "_home";
+
+ command = protocol + " " + username + "@" + alias + " 'echo $HOME' > " + file_home_name;
+ status = system(command.c_str());
+ if(status) {
+ std::ostringstream oss;
+ oss << status;
+ result += "Error in getting home directory ! status = ";
+ result += oss.str();
+ return result;
+ }
+
+ std::ifstream file_home(file_home_name.c_str());
+ if (!file_home)
+ {
+ result += "Error in reading temporary file ! filename = " + file_home_name;
+ return result;
+ }
+ std::getline(file_home, *home);
+ file_home.close();
+ return result;
+}
--- /dev/null
+// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __BatchTest_HXX__
+#define __BatchTest_HXX__
+
+#include <sys/stat.h>
+#include <iostream>
+#include <fstream>
+
+#include <SALOMEconfig.h>
+#include "utilities.h"
+#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
+
+#include "Batch_Date.hxx"
+#include "MpiImpl.hxx"
+
+class BatchTest
+{
+ public:
+ BatchTest(const Engines::MachineParameters& batch_descr);
+ virtual ~BatchTest();
+
+ bool test();
+
+ std::string test_connection();
+ std::string test_filecopy();
+ std::string test_getresult();
+ std::string test_jobsubmit_simple();
+ std::string test_jobsubmit_mpi();
+ std::string test_appli();
+
+ protected:
+ std::string get_home(std::string * home);
+
+ private:
+ Engines::MachineParameters _batch_descr;
+ std::string _test_filename;
+ std::string _base_filename;
+ std::string _date;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "Batch_Date.hxx"
+#include "Batch_FactBatchManager_eLSF.hxx"
+#include "Batch_FactBatchManager_ePBS.hxx"
+#include "Launcher.hxx"
+#include <iostream>
+#include <sstream>
+#include <sys/stat.h>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Constructor
+ * \param orb
+ * Define a CORBA single thread policy for the server, which avoid to deal
+ * with non thread-safe usage like Change_Directory in SALOME naming service
+ */
+//=============================================================================
+
+Launcher_cpp::Launcher_cpp()
+{
+ cerr << "Launcher_cpp constructor" << endl;
+}
+
+//=============================================================================
+/*!
+ * destructor
+ */
+//=============================================================================
+
+Launcher_cpp::~Launcher_cpp()
+{
+ cerr << "Launcher_cpp destructor" << endl;
+ std::map < string, Batch::BatchManager_eClient * >::const_iterator it1;
+ for(it1=_batchmap.begin();it1!=_batchmap.end();it1++)
+ delete it1->second;
+ std::map < std::pair<std::string,long> , Batch::Job* >::const_iterator it2;
+ for(it2=_jobmap.begin();it2!=_jobmap.end();it2++)
+ delete it2->second;
+}
+
+//=============================================================================
+/*! CORBA Method:
+ * Submit a batch job on a cluster and returns the JobId
+ * \param fileToExecute : .py/.exe/.sh/... to execute on the batch cluster
+ * \param filesToExport : to export on the batch cluster
+ * \param NumberOfProcessors : Number of processors needed on the batch cluster
+ * \param params : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+long Launcher_cpp::submitSalomeJob( const string fileToExecute ,
+ const vector<string>& filesToExport ,
+ const vector<string>& filesToImport ,
+ const batchParams& batch_params,
+ const machineParams& params) throw(LauncherException)
+{
+ cerr << "BEGIN OF Launcher_cpp::submitSalomeJob" << endl;
+ long jobId;
+ vector<string> aMachineList;
+
+ // check batch params
+ if ( !check(batch_params) )
+ throw LauncherException("Batch parameters are bad (see informations above)");
+
+ // find a cluster matching the structure params
+ vector<string> aCompoList ;
+ try{
+ aMachineList = _ResManager->GetFittingResources(params, aCompoList);
+ }
+ catch(const ResourcesException &ex){
+ throw LauncherException(ex.msg.c_str());
+ }
+ if (aMachineList.size() == 0)
+ throw LauncherException("No resources have been found with your parameters");
+
+ ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+ string clustername(p.Alias);
+ cerr << "Choose cluster: " << clustername << endl;
+
+ // search batch manager for that cluster in map or instanciate one
+ map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+ if(it == _batchmap.end())
+ {
+ _batchmap[clustername] = FactoryBatchManager(p);
+ // TODO: Add a test for the cluster !
+ }
+
+ try{
+ // tmp directory on cluster to put files to execute
+ string tmpdir = getTmpDirForBatchFiles();
+
+ // create and submit job on cluster
+ Batch::Parametre param;
+ param[USER] = p.UserName;
+ param[EXECUTABLE] = buildSalomeCouplingScript(fileToExecute,tmpdir,p);
+ param[INFILE] = Batch::Couple( fileToExecute, getRemoteFile(tmpdir,fileToExecute) );
+ for(int i=0;i<filesToExport.size();i++)
+ param[INFILE] += Batch::Couple( filesToExport[i], getRemoteFile(tmpdir,filesToExport[i]) );
+
+
+ ostringstream file_name_output;
+ file_name_output << "~/" << tmpdir << "/" << "runSalome.output.log*";
+ ostringstream file_name_error;
+ file_name_error << "~/" << tmpdir << "/" << "runSalome.error.log*";
+ ostringstream file_container_log;
+ file_container_log << "~/" << tmpdir << "/" << "YACS_Server*";
+ param[OUTFILE] = Batch::Couple( "", file_name_output.str());
+ param[OUTFILE] += Batch::Couple( "", file_name_error.str());
+ param[OUTFILE] += Batch::Couple( "", file_container_log.str());
+
+ for(int i=0;i<filesToImport.size();i++)
+ param[OUTFILE] += Batch::Couple( "", filesToImport[i] );
+
+ param[NBPROC] = batch_params.nb_proc;
+ param[WORKDIR] = batch_params.batch_directory;
+ param[TMPDIR] = tmpdir;
+ param[MAXWALLTIME] = getWallTime(batch_params.expected_during_time);
+ param[MAXRAMSIZE] = getRamSize(batch_params.mem);
+ param[HOMEDIR] = getHomeDir(p, tmpdir);
+
+ Batch::Environnement env;
+
+ Batch::Job* job = new Batch::Job(param,env);
+
+ // submit job on cluster
+ Batch::JobId jid = _batchmap[clustername]->submitJob(*job);
+
+ // get job id in long
+ istringstream iss(jid.getReference());
+ iss >> jobId;
+
+ _jobmap[ pair<string,long>(clustername,jobId) ] = job;
+ }
+ catch(const Batch::EmulationException &ex){
+ throw LauncherException(ex.msg.c_str());
+ }
+
+ return jobId;
+}
+
+//=============================================================================
+/*! CORBA Method:
+ * Query a batch job on a cluster and returns the status of job
+ * \param jobId : identification of Salome job
+ * \param params : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+string Launcher_cpp::querySalomeJob( long id,
+ const machineParams& params) throw(LauncherException)
+{
+ // find a cluster matching params structure
+ vector<string> aCompoList ;
+ vector<string> aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+ ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+ string clustername(p.Alias);
+
+ // search batch manager for that cluster in map
+ std::map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+ if(it == _batchmap.end())
+ throw LauncherException("no batchmanager for that cluster");
+
+ ostringstream oss;
+ oss << id;
+ Batch::JobId jobId( _batchmap[clustername], oss.str() );
+
+ Batch::JobInfo jinfo = jobId.queryJob();
+ Batch::Parametre par = jinfo.getParametre();
+ return par[STATE];
+}
+
+//=============================================================================
+/*! CORBA Method:
+ * Delete a batch job on a cluster
+ * \param jobId : identification of Salome job
+ * \param params : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+void Launcher_cpp::deleteSalomeJob( const long id,
+ const machineParams& params) throw(LauncherException)
+{
+ // find a cluster matching params structure
+ vector<string> aCompoList ;
+ vector<string> aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+ ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+ string clustername(p.Alias);
+
+ // search batch manager for that cluster in map
+ map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+ if(it == _batchmap.end())
+ throw LauncherException("no batchmanager for that cluster");
+
+ ostringstream oss;
+ oss << id;
+ Batch::JobId jobId( _batchmap[clustername], oss.str() );
+
+ jobId.deleteJob();
+}
+
+//=============================================================================
+/*! CORBA Method:
+ * Get result files of job on a cluster
+ * \param jobId : identification of Salome job
+ * \param params : Constraints for the choice of the batch cluster
+ */
+//=============================================================================
+void Launcher_cpp::getResultSalomeJob( const string directory,
+ const long id,
+ const machineParams& params) throw(LauncherException)
+{
+ vector<string> aCompoList ;
+ vector<string> aMachineList = _ResManager->GetFittingResources( params , aCompoList ) ;
+ ParserResourcesType p = _ResManager->GetResourcesList(aMachineList[0]);
+ string clustername(p.Alias);
+
+ // search batch manager for that cluster in map
+ map < string, Batch::BatchManager_eClient * >::const_iterator it = _batchmap.find(clustername);
+ if(it == _batchmap.end())
+ throw LauncherException("no batchmanager for that cluster");
+
+ Batch::Job* job = _jobmap[ pair<string,long>(clustername,id) ];
+
+ _batchmap[clustername]->importOutputFiles( *job, directory );
+}
+
+//=============================================================================
+/*!
+ * Factory to instanciate the good batch manager for choosen cluster.
+ */
+//=============================================================================
+
+Batch::BatchManager_eClient *Launcher_cpp::FactoryBatchManager( const ParserResourcesType& params ) throw(LauncherException)
+{
+
+ std::string hostname, protocol, mpi;
+ Batch::FactBatchManager_eClient* fact;
+
+ hostname = params.Alias;
+ switch(params.Protocol){
+ case rsh:
+ protocol = "rsh";
+ break;
+ case ssh:
+ protocol = "ssh";
+ break;
+ default:
+ throw LauncherException("unknown protocol");
+ break;
+ }
+ switch(params.mpi){
+ case lam:
+ mpi = "lam";
+ break;
+ case mpich1:
+ mpi = "mpich1";
+ break;
+ case mpich2:
+ mpi = "mpich2";
+ break;
+ case openmpi:
+ mpi = "openmpi";
+ break;
+ case slurm:
+ mpi = "slurm";
+ break;
+ default:
+ mpi = "indif";
+ break;
+ }
+ cerr << "Instanciation of batch manager" << endl;
+ switch( params.Batch ){
+ case pbs:
+ cerr << "Instantiation of PBS batch manager" << endl;
+ fact = new Batch::FactBatchManager_ePBS;
+ break;
+ case lsf:
+ cerr << "Instantiation of LSF batch manager" << endl;
+ fact = new Batch::FactBatchManager_eLSF;
+ break;
+ default:
+ cerr << "BATCH = " << params.Batch << endl;
+ throw LauncherException("no batchmanager for that cluster");
+ }
+ return (*fact)(hostname.c_str(),protocol.c_str(),mpi.c_str());
+}
+
+string Launcher_cpp::buildSalomeCouplingScript(const string fileToExecute, const string dirForTmpFiles, const ParserResourcesType& params)
+{
+ int idx = dirForTmpFiles.find("Batch/");
+ std::string filelogtemp = dirForTmpFiles.substr(idx+6, dirForTmpFiles.length());
+
+ string::size_type p1 = fileToExecute.find_last_of("/");
+ string::size_type p2 = fileToExecute.find_last_of(".");
+ std::string fileNameToExecute = fileToExecute.substr(p1+1,p2-p1-1);
+ std::string TmpFileName = "/tmp/runSalome_" + fileNameToExecute + ".sh";
+
+ MpiImpl* mpiImpl = FactoryMpiImpl(params.mpi);
+
+ ofstream tempOutputFile;
+ tempOutputFile.open(TmpFileName.c_str(), ofstream::out );
+
+ // Begin
+ tempOutputFile << "#! /bin/sh -f" << endl ;
+ tempOutputFile << "cd " ;
+ tempOutputFile << params.AppliPath << endl ;
+ tempOutputFile << "export SALOME_BATCH=1\n";
+ tempOutputFile << "export PYTHONPATH=~/" ;
+ tempOutputFile << dirForTmpFiles ;
+ tempOutputFile << ":$PYTHONPATH" << endl ;
+
+ // Test node rank
+ tempOutputFile << "if test " ;
+ tempOutputFile << mpiImpl->rank() ;
+ tempOutputFile << " = 0; then" << endl ;
+
+ // -----------------------------------------------
+ // Code for rank 0 : launch runAppli and a container
+ // RunAppli
+ if(params.ModulesList.size()>0)
+ tempOutputFile << " ./runAppli --terminal --modules=" ;
+ else
+ tempOutputFile << " ./runAppli --terminal ";
+ for ( int i = 0 ; i < params.ModulesList.size() ; i++ ) {
+ tempOutputFile << params.ModulesList[i] ;
+ if ( i != params.ModulesList.size()-1 )
+ tempOutputFile << "," ;
+ }
+ tempOutputFile << " --standalone=registry,study,moduleCatalog --ns-port-log="
+ << filelogtemp
+ << " &\n";
+
+ // Wait NamingService
+ tempOutputFile << " current=0\n"
+ << " stop=20\n"
+ << " while ! test -f " << filelogtemp << "\n"
+ << " do\n"
+ << " sleep 2\n"
+ << " let current=current+1\n"
+ << " if [ \"$current\" -eq \"$stop\" ] ; then\n"
+ << " echo Error Naming Service failed ! >&2"
+ << " exit\n"
+ << " fi\n"
+ << " done\n"
+ << " port=`cat " << filelogtemp << "`\n";
+
+ // Wait other containers
+ tempOutputFile << " for ((ip=1; ip < ";
+ tempOutputFile << mpiImpl->size();
+ tempOutputFile << " ; ip++))" << endl;
+ tempOutputFile << " do" << endl ;
+ tempOutputFile << " arglist=\"$arglist YACS_Server_\"$ip" << endl ;
+ tempOutputFile << " done" << endl ;
+ tempOutputFile << " sleep 5" << endl ;
+ tempOutputFile << " ./runSession waitContainers.py $arglist" << endl ;
+
+ // Launch user script
+ tempOutputFile << " ./runSession python ~/" << dirForTmpFiles << "/" << fileNameToExecute << ".py" << endl;
+
+ // Stop application
+ tempOutputFile << " rm " << filelogtemp << "\n"
+ << " ./runSession shutdownSalome.py" << endl;
+
+ // -------------------------------------
+ // Other nodes launch a container
+ tempOutputFile << "else" << endl ;
+
+ // Wait NamingService
+ tempOutputFile << " current=0\n"
+ << " stop=20\n"
+ << " while ! test -f " << filelogtemp << "\n"
+ << " do\n"
+ << " sleep 2\n"
+ << " let current=current+1\n"
+ << " if [ \"$current\" -eq \"$stop\" ] ; then\n"
+ << " echo Error Naming Service failed ! >&2"
+ << " exit\n"
+ << " fi\n"
+ << " done\n"
+ << " port=`cat " << filelogtemp << "`\n";
+
+ // Launching container
+ tempOutputFile << " ./runSession SALOME_Container YACS_Server_";
+ tempOutputFile << mpiImpl->rank()
+ << " > ~/" << dirForTmpFiles << "/YACS_Server_"
+ << mpiImpl->rank() << "_container_log." << filelogtemp
+ << " 2>&1\n";
+ tempOutputFile << "fi" << endl ;
+ tempOutputFile.flush();
+ tempOutputFile.close();
+ chmod(TmpFileName.c_str(), 0x1ED);
+ cerr << TmpFileName.c_str() << endl;
+
+ delete mpiImpl;
+
+ return TmpFileName;
+
+}
+
+MpiImpl *Launcher_cpp::FactoryMpiImpl(MpiImplType mpi) throw(LauncherException)
+{
+ switch(mpi){
+ case lam:
+ return new MpiImpl_LAM();
+ case mpich1:
+ return new MpiImpl_MPICH1();
+ case mpich2:
+ return new MpiImpl_MPICH2();
+ case openmpi:
+ return new MpiImpl_OPENMPI();
+ case slurm:
+ return new MpiImpl_SLURM();
+ case indif:
+ throw LauncherException("you must specify a mpi implementation in CatalogResources.xml file");
+ default:
+ ostringstream oss;
+ oss << mpi << " : not yet implemented";
+ throw LauncherException(oss.str().c_str());
+ }
+
+}
+
+string Launcher_cpp::getTmpDirForBatchFiles()
+{
+ string ret;
+ string thedate;
+
+ // Adding date to the directory name
+ Batch::Date date = Batch::Date(time(0));
+ thedate = date.str();
+ int lend = thedate.size() ;
+ int i = 0 ;
+ while ( i < lend ) {
+ if ( thedate[i] == '/' || thedate[i] == '-' || thedate[i] == ':' ) {
+ thedate[i] = '_' ;
+ }
+ i++ ;
+ }
+
+ ret = string("Batch/");
+ ret += thedate;
+ return ret;
+}
+
+string Launcher_cpp::getRemoteFile( std::string remoteDir, std::string localFile )
+{
+ string::size_type pos = localFile.find_last_of("/") + 1;
+ int ln = localFile.length() - pos;
+ string remoteFile = remoteDir + "/" + localFile.substr(pos,ln);
+ return remoteFile;
+}
+
+bool Launcher_cpp::check(const batchParams& batch_params)
+{
+ bool rtn = true;
+ cerr << "Job parameters are :" << endl;
+ cerr << "Directory : $HOME/Batch/$date" << endl;
+
+ // check expected_during_time (check the format)
+ std::string edt_info = batch_params.expected_during_time;
+ std::string edt_value = batch_params.expected_during_time;
+ if (edt_value != "") {
+ std::string begin_edt_value = edt_value.substr(0, 2);
+ std::string mid_edt_value = edt_value.substr(2, 1);
+ std::string end_edt_value = edt_value.substr(3);
+
+ long value;
+ std::istringstream iss(begin_edt_value);
+ if (!(iss >> value)) {
+ edt_info = "Error on definition ! : " + edt_value;
+ rtn = false;
+ }
+ else if (value < 0) {
+ edt_info = "Error on definition time is negative ! : " + value;
+ rtn = false;
+ }
+ std::istringstream iss_2(end_edt_value);
+ if (!(iss_2 >> value)) {
+ edt_info = "Error on definition ! : " + edt_value;
+ rtn = false;
+ }
+ else if (value < 0) {
+ edt_info = "Error on definition time is negative ! : " + value;
+ rtn = false;
+ }
+ if (mid_edt_value != ":") {
+ edt_info = "Error on definition ! :" + edt_value;
+ rtn = false;
+ }
+ }
+ else {
+ edt_info = "No value given";
+ }
+ cerr << "Expected during time : " << edt_info << endl;;
+
+ // check memory (check the format)
+ std::string mem_info;
+ std::string mem_value = batch_params.mem;
+ if (mem_value != "") {
+ std::string begin_mem_value = mem_value.substr(0, mem_value.length()-2);
+ long re_mem_value;
+ std::istringstream iss(begin_mem_value);
+ if (!(iss >> re_mem_value)) {
+ mem_info = "Error on definition ! : " + mem_value;
+ rtn = false;
+ }
+ else if (re_mem_value <= 0) {
+ mem_info = "Error on definition memory is negative ! : " + mem_value;
+ rtn = false;
+ }
+ std::string end_mem_value = mem_value.substr(mem_value.length()-2);
+ if (end_mem_value != "gb" and end_mem_value != "mb") {
+ mem_info = "Error on definition, type is bad ! " + mem_value;
+ rtn = false;
+ }
+ }
+ else {
+ mem_info = "No value given";
+ }
+ cerr << "Memory : " << mem_info << endl;
+
+ // check nb_proc
+ std::string nb_proc_info;
+ ostringstream nb_proc_value;
+ nb_proc_value << batch_params.nb_proc;
+ if(batch_params.nb_proc <= 0) {
+ nb_proc_info = "Bad value ! nb_proc = ";
+ nb_proc_info += nb_proc_value.str();
+ rtn = false;
+ }
+ else {
+ nb_proc_info = nb_proc_value.str();
+ }
+ cerr << "Nb of processors : " << nb_proc_info << endl;
+
+ return rtn;
+}
+
+long Launcher_cpp::getWallTime(std::string edt)
+{
+ long hh, mm, ret;
+
+ if( edt.size() == 0 )
+ return 0;
+
+ string::size_type pos = edt.find(":");
+ string h = edt.substr(0,pos);
+ string m = edt.substr(pos+1,edt.size()-pos+1);
+ istringstream issh(h);
+ issh >> hh;
+ istringstream issm(m);
+ issm >> mm;
+ ret = hh*60 + mm;
+ return ret;
+}
+
+long Launcher_cpp::getRamSize(std::string mem)
+{
+ long mv;
+
+ if( mem.size() == 0 )
+ return 0;
+
+ string ram = mem.substr(0,mem.size()-2);
+ istringstream iss(ram);
+ iss >> mv;
+ string unity = mem.substr(mem.size()-2,2);
+ if( (unity.find("gb") != string::npos) || (unity.find("GB") != string::npos) )
+ return mv*1024;
+ else if( (unity.find("mb") != string::npos) || (unity.find("MB") != string::npos) )
+ return mv;
+ else if( (unity.find("kb") != string::npos) || (unity.find("KB") != string::npos) )
+ return mv/1024;
+ else if( (unity.find("b") != string::npos) || (unity.find("B") != string::npos) )
+ return mv/(1024*1024);
+ else
+ return 0;
+}
+
+std::string
+Launcher_cpp::getHomeDir(const ParserResourcesType& p, const std::string& tmpdir)
+{
+ std::string home;
+ std::string command;
+ int idx = tmpdir.find("Batch/");
+ std::string filelogtemp = tmpdir.substr(idx+6, tmpdir.length());
+ filelogtemp = "/tmp/logs" + filelogtemp + "_home";
+
+ if( p.Protocol == rsh )
+ command = "rsh ";
+ else if( p.Protocol == ssh )
+ command = "ssh ";
+ else
+ throw LauncherException("Unknown protocol");
+ if (p.UserName != ""){
+ command += p.UserName;
+ command += "@";
+ }
+ command += p.Alias;
+ command += " 'echo $HOME' > ";
+ command += filelogtemp;
+ std::cerr << command.c_str() << std::endl;
+ int status = system(command.c_str());
+ if(status)
+ throw LauncherException("Error of launching home command on remote host");
+
+ std::ifstream file_home(filelogtemp.c_str());
+ std::getline(file_home, home);
+ file_home.close();
+ return home;
+}
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __LAUNCHER_HXX__
+#define __LAUNCHER_HXX__
+
+#include "Batch_BatchManager_eClient.hxx"
+#include "ResourcesManager.hxx"
+
+#include <string>
+
+struct batchParams{
+ std::string batch_directory;
+ std::string expected_during_time;
+ std::string mem;
+ unsigned long nb_proc;
+};
+
+class LauncherException
+{
+public:
+ const std::string msg;
+
+ LauncherException(const std::string m) : msg(m) {}
+};
+
+class Launcher_cpp
+{
+
+public:
+ Launcher_cpp();
+ ~Launcher_cpp();
+
+ long submitSalomeJob(const std::string fileToExecute ,
+ const std::vector<std::string>& filesToExport ,
+ const std::vector<std::string>& filesToImport ,
+ const batchParams& batch_params,
+ const machineParams& params) throw(LauncherException);
+
+ std::string querySalomeJob( const long jobId, const machineParams& params) throw(LauncherException);
+ void deleteSalomeJob( const long jobId, const machineParams& params) throw(LauncherException);
+ void getResultSalomeJob( const std::string directory, const long jobId, const machineParams& params ) throw(LauncherException);
+
+ void SetResourcesManager( ResourcesManager_cpp* rm ) { _ResManager = rm; }
+
+protected:
+
+ std::string buildSalomeCouplingScript(const string fileToExecute, const string dirForTmpFiles, const ParserResourcesType& params);
+ MpiImpl *FactoryMpiImpl(MpiImplType mpiImpl) throw(LauncherException);
+ Batch::BatchManager_eClient *FactoryBatchManager( const ParserResourcesType& params ) throw(LauncherException);
+ std::string getTmpDirForBatchFiles();
+ std::string getRemoteFile( std::string remoteDir, std::string localFile );
+ std::string getHomeDir(const ParserResourcesType& p, const std::string & tmpdir);
+
+ std::map <std::string,Batch::BatchManager_eClient*> _batchmap;
+ std::map < std::pair<std::string,long> , Batch::Job* > _jobmap;
+ ResourcesManager_cpp *_ResManager;
+ bool check(const batchParams& batch_params);
+ long getWallTime(std::string edt);
+ long getRamSize(std::string mem);
+};
+
+#endif
--- /dev/null
+// SALOME_ParallelContainerProxy : implementation of container and engine for Parallel Kernel
+//
+// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+// File : SALOME_ParallelContainerProxy_i.cxx
+// Author : André RIBES, EDF
+
+#include "SALOME_ParallelContainerProxy_i.hxx"
+
+Container_proxy_impl_final::Container_proxy_impl_final(CORBA::ORB_ptr orb,
+ paco_fabrique_thread * fab_thread,
+ bool is_a_return_proxy) :
+ Engines::Container_proxy_impl(orb, fab_thread, is_a_return_proxy),
+ InterfaceManager_impl(orb, fab_thread, is_a_return_proxy)
+{}
+
+Container_proxy_impl_final:: ~Container_proxy_impl_final() {}
+
+void
+Container_proxy_impl_final::Shutdown()
+{
+ INFOS("Shutdown Parallel Proxy");
+ if(!CORBA::is_nil(_orb))
+ _orb->shutdown(0);
+}
+
--- /dev/null
+// SALOME_ParallelContainerProxy : implementation of container and engine for Parallel Kernel
+//
+// Copyright (C) 2008 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+// File : SALOME_ParallelContainerProxy_i.hxx
+// Author : André RIBES, EDF
+
+#ifndef _SALOME_PARALLEL_CONTAINER_PROXY_I_HXX_
+#define _SALOME_PARALLEL_CONTAINER_PROXY_I_HXX_
+
+#include "utilities.h"
+#include "SALOME_ComponentPaCO_Engines_Container_server.h"
+
+class Container_proxy_impl_final :
+ public Engines::Container_proxy_impl
+{
+ public:
+ Container_proxy_impl_final(CORBA::ORB_ptr orb,
+ paco_fabrique_thread * fab_thread,
+ bool is_a_return_proxy = false);
+
+ virtual ~Container_proxy_impl_final();
+
+ virtual void Shutdown();
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "ResourcesManager.hxx"
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string.h>
+#include <map>
+#include <list>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libxml/parser.h>
+
+#include "utilities.h"
+
+#define MAX_SIZE_FOR_HOSTNAME 256;
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * just for test
+ */
+//=============================================================================
+
+ResourcesManager_cpp::
+ResourcesManager_cpp(const char *xmlFilePath) :
+ _path_resources(xmlFilePath)
+{
+ MESSAGE ( "ResourcesManager_cpp constructor" );
+}
+
+//=============================================================================
+/*!
+ * Standard constructor, parse resource file.
+ * - if ${APPLI} exists in environment,
+ * look for ${HOME}/${APPLI}/CatalogResources.xml
+ * - else look for default:
+ * ${KERNEL_ROOT_DIR}/share/salome/resources/kernel/CatalogResources.xml
+ * - parse XML resource file.
+ */
+//=============================================================================
+
+ResourcesManager_cpp::ResourcesManager_cpp()
+{
+ MESSAGE ( "ResourcesManager_cpp constructor" );
+ _isAppliSalomeDefined = (getenv("APPLI") != 0);
+
+ if (_isAppliSalomeDefined)
+ {
+ _path_resources = getenv("HOME");
+ _path_resources += "/";
+ _path_resources += getenv("APPLI");
+ _path_resources += "/CatalogResources.xml";
+ }
+
+ else
+ {
+ _path_resources = getenv("KERNEL_ROOT_DIR");
+ _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
+ }
+
+ ParseXmlFile();
+ MESSAGE ( "ResourcesManager_cpp constructor end" );
+}
+
+//=============================================================================
+/*!
+ * Standard Destructor
+ */
+//=============================================================================
+
+ResourcesManager_cpp::~ResourcesManager_cpp()
+{
+ MESSAGE ( "ResourcesManager_cpp destructor" );
+}
+
+//=============================================================================
+/*!
+ * get the list of name of ressources fitting for the specified module.
+ * If hostname specified, check it is local or known in resources catalog.
+ *
+ * Else
+ * - select first machines with corresponding OS (all machines if
+ * parameter OS empty),
+ * - then select the sublist of machines on witch the module is known
+ * (if the result is empty, that probably means that the inventory of
+ * modules is probably not done, so give complete list from previous step)
+ */
+//=============================================================================
+
+std::vector<std::string>
+ResourcesManager_cpp::GetFittingResources(const machineParams& params,
+ const std::vector<std::string>& componentList) throw(ResourcesException)
+{
+// cerr << "ResourcesManager_cpp::GetFittingResources" << endl;
+ vector <std::string> vec;
+
+ ParseXmlFile();
+
+ const char *hostname = params.hostname.c_str();
+ INFOS ( "GetFittingResources " << hostname << " " << GetHostname().c_str() );
+
+ if (hostname[0] != '\0'){
+ // cerr << "ResourcesManager_cpp::GetFittingResources : hostname specified" << endl;
+
+ if ( strcmp(hostname, "localhost") == 0 ||
+ strcmp(hostname, GetHostname().c_str()) == 0 )
+ {
+ // cerr << "ResourcesManager_cpp::GetFittingResources : localhost" << endl;
+ vec.push_back(GetHostname().c_str());
+ // cerr << "ResourcesManager_cpp::GetFittingResources : " << vec.size() << endl;
+ }
+
+ else if (_resourcesList.find(hostname) != _resourcesList.end())
+ {
+ // --- params.hostname is in the list of resources so return it.
+ vec.push_back(hostname);
+ }
+ else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end())
+ {
+ // --- params.hostname is in the list of resources so return it.
+ vec.push_back(hostname);
+ }
+ else
+ {
+ // Cas d'un cluster: nombre de noeuds > 1
+ int cpt=0;
+ for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
+ if( (*iter).second.DataForSort._nbOfNodes > 1 ){
+ if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
+ vec.push_back((*iter).first.c_str());
+ //cerr << "SALOME_ResourcesManager_cpp::GetFittingResources vector["
+ // << cpt << "] = " << (*iter).first.c_str() << endl ;
+ cpt++;
+ }
+ }
+ }
+ if(cpt==0){
+ // --- user specified an unknown hostame so notify him.
+ MESSAGE ( "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" );
+ throw ResourcesException("unknown host");
+ }
+ }
+ }
+
+ else{
+ // --- Search for available resources sorted by priority
+ SelectOnlyResourcesWithOS(vec, params.OS.c_str());
+
+ KeepOnlyResourcesWithModule(vec, componentList);
+
+ if (vec.size() == 0)
+ SelectOnlyResourcesWithOS(vec, params.OS.c_str());
+
+ // --- set wanted parameters
+ ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
+
+ ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
+
+ ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
+
+ ResourceDataToSort::_memInMBWanted = params.mem_mb;
+
+ // --- end of set
+
+ list<ResourceDataToSort> li;
+
+ for (vector<string>::iterator iter = vec.begin();
+ iter != vec.end();
+ iter++)
+ li.push_back(_resourcesList[(*iter)].DataForSort);
+
+ li.sort();
+
+ unsigned int i = 0;
+
+ for (list<ResourceDataToSort>::iterator iter2 = li.begin();
+ iter2 != li.end();
+ iter2++)
+ vec[i++] = (*iter2)._hostName;
+ }
+
+ return vec;
+
+}
+
+//=============================================================================
+/*!
+ * add an entry in the ressources catalog xml file.
+ * Return 0 if OK (KERNEL found in new resources modules) else throw exception
+ */
+//=============================================================================
+
+int
+ResourcesManager_cpp::
+AddResourceInCatalog(const machineParams& paramsOfNewResources,
+ const vector<string>& modulesOnNewResources,
+ const char *alias,
+ const char *userName,
+ AccessModeType mode,
+ AccessProtocolType prot)
+throw(ResourcesException)
+{
+ vector<string>::const_iterator iter = find(modulesOnNewResources.begin(),
+ modulesOnNewResources.end(),
+ "KERNEL");
+
+ if (iter != modulesOnNewResources.end())
+ {
+ ParserResourcesType newElt;
+ newElt.DataForSort._hostName = paramsOfNewResources.hostname;
+ newElt.Alias = alias;
+ newElt.Protocol = prot;
+ newElt.Mode = mode;
+ newElt.UserName = userName;
+ newElt.ModulesList = modulesOnNewResources;
+ newElt.OS = paramsOfNewResources.OS;
+ newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
+ newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
+ newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
+ newElt.DataForSort._nbOfProcPerNode =
+ paramsOfNewResources.nb_proc_per_node;
+ _resourcesList[newElt.DataForSort._hostName] = newElt;
+ return 0;
+ }
+
+ else
+ throw ResourcesException("KERNEL is not present in this resource");
+}
+
+//=============================================================================
+/*!
+ * Deletes a resource from the catalog
+ */
+//=============================================================================
+
+void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
+{
+ _resourcesList.erase(hostname);
+}
+
+//=============================================================================
+/*!
+ * write the current data in memory in file.
+ */
+//=============================================================================
+
+void ResourcesManager_cpp::WriteInXmlFile()
+{
+ const char* aFilePath = _path_resources.c_str();
+
+ FILE* aFile = fopen(aFilePath, "w");
+
+ if (aFile == NULL)
+ {
+ INFOS ( "Error opening file !" );
+ return;
+ }
+
+ xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
+ xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
+
+ SALOME_ResourcesCatalog_Handler* handler =
+ new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
+ handler->PrepareDocToXmlFile(aDoc);
+ delete handler;
+
+ int isOk = xmlSaveFile(aFilePath, aDoc);
+
+ if (!isOk)
+ INFOS ( "Error while XML file saving." );
+
+ // Free the document
+ xmlFreeDoc(aDoc);
+
+ fclose(aFile);
+
+ INFOS ( "WRITING DONE!" );
+}
+
+//=============================================================================
+/*!
+ * parse the data type catalog
+ */
+//=============================================================================
+
+const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
+{
+ SALOME_ResourcesCatalog_Handler* handler =
+ new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
+
+ const char* aFilePath = _path_resources.c_str();
+ FILE* aFile = fopen(aFilePath, "r");
+
+ if (aFile != NULL)
+ {
+ xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
+
+ if (aDoc != NULL)
+ handler->ProcessXmlDocument(aDoc);
+ else
+ INFOS ( "ResourcesManager_cpp: could not parse file "<< aFilePath );
+
+ // Free the document
+ xmlFreeDoc(aDoc);
+
+ fclose(aFile);
+ }
+ else
+ INFOS ( "ResourcesManager_cpp: file "<<aFilePath<<" is not readable." );
+
+ delete handler;
+
+ return _resourcesList;
+}
+
+//=============================================================================
+/*!
+ * consult the content of the list
+ */
+//=============================================================================
+
+const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
+ {
+ return _resourcesList;
+ }
+
+
+//=============================================================================
+/*!
+ * dynamically obtains the first machines
+ */
+//=============================================================================
+
+string ResourcesManager_cpp::FindFirst(const std::vector<std::string>& listOfMachines)
+{
+ return _dynamicResourcesSelecter.FindFirst(listOfMachines);
+}
+
+//=============================================================================
+/*!
+ * dynamically obtains the best machines
+ */
+//=============================================================================
+
+string ResourcesManager_cpp::FindNext(const std::vector<std::string>& listOfMachines)
+{
+ return _dynamicResourcesSelecter.FindNext(listOfMachines,_resourcesList);
+}
+//=============================================================================
+/*!
+ * dynamically obtains the best machines
+ */
+//=============================================================================
+
+string ResourcesManager_cpp::FindBest(const std::vector<std::string>& listOfMachines)
+{
+ return _dynamicResourcesSelecter.FindBest(listOfMachines);
+}
+
+//=============================================================================
+/*!
+ * Gives a sublist of machines with matching OS.
+ * If parameter OS is empty, gives the complete list of machines
+ */
+//=============================================================================
+
+// Warning need an updated parsed list : _resourcesList
+void ResourcesManager_cpp::SelectOnlyResourcesWithOS( vector<string>& hosts, const char *OS) const
+throw(ResourcesException)
+{
+ string base(OS);
+
+ for (map<string, ParserResourcesType>::const_iterator iter =
+ _resourcesList.begin();
+ iter != _resourcesList.end();
+ iter++)
+ {
+ if ( (*iter).second.OS == base || base.size() == 0)
+ hosts.push_back((*iter).first);
+ }
+}
+
+
+//=============================================================================
+/*!
+ * Gives a sublist of machines on which the module is known.
+ */
+//=============================================================================
+
+//Warning need an updated parsed list : _resourcesList
+void ResourcesManager_cpp::KeepOnlyResourcesWithModule( vector<string>& hosts, const vector<string>& componentList) const
+throw(ResourcesException)
+{
+ for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
+ {
+ MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
+ const vector<string>& mapOfModulesOfCurrentHost = (((*it).second).ModulesList);
+
+ bool erasedHost = false;
+ if( mapOfModulesOfCurrentHost.size() > 0 ){
+ for(int i=0;i<componentList.size();i++){
+ const char* compoi = componentList[i].c_str();
+ vector<string>::const_iterator itt = find(mapOfModulesOfCurrentHost.begin(),
+ mapOfModulesOfCurrentHost.end(),
+ compoi);
+// componentList[i]);
+ if (itt == mapOfModulesOfCurrentHost.end()){
+ erasedHost = true;
+ break;
+ }
+ }
+ }
+ if(erasedHost)
+ hosts.erase(iter);
+ else
+ iter++;
+ }
+}
+
+
+ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine)
+{
+ if (_resourcesList.find(machine) != _resourcesList.end())
+ return _resourcesList[machine];
+ else
+ return _resourcesBatchList[machine];
+}
+
+std::string ResourcesManager_cpp::GetHostname()
+{
+ int ls = 100, r = 1;
+ char *s;
+
+ while (ls < 10000 && r) {
+ ls *= 2;
+ s = new char[ls];
+ r = gethostname(s, ls-1);
+ switch (r)
+ {
+ case 0:
+ break;
+ default:
+#ifdef EINVAL
+ case EINVAL:
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+#endif
+ delete [] s;
+ continue;
+ }
+ }
+
+ if (r != 0) {
+ s = new char[50];
+ strcpy(s, "localhost");
+ }
+
+ // remove all after '.'
+ char *aDot = (strchr(s,'.'));
+ if (aDot) aDot[0] = '\0';
+
+ string p = s;
+ delete [] s;
+ return p;
+}
+
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __RESOURCESMANAGER_HXX__
+#define __RESOURCESMANAGER_HXX__
+
+#include <string>
+#include <fstream>
+#include <vector>
+#include "SALOME_ResourcesCatalog_Parser.hxx"
+#include "SALOME_ResourcesCatalog_Handler.hxx"
+#include "SALOME_LoadRateManager.hxx"
+
+// --- WARNING ---
+// The call of BuildTempFileToLaunchRemoteContainer and RmTmpFile must be done
+// in a critical section to be sure to be clean.
+// Only one thread should use the SALOME_ResourcesManager class in a SALOME
+// session.
+
+struct machineParams{
+ std::string hostname;
+ std::string OS;
+ unsigned int nb_node;
+ unsigned int nb_proc_per_node;
+ unsigned int cpu_clock;
+ unsigned int mem_mb;
+};
+
+class ResourcesException
+{
+public:
+ const std::string msg;
+
+ ResourcesException(const std::string m) : msg(m) {}
+};
+
+class ResourcesManager_cpp
+ {
+
+ public:
+
+ ResourcesManager_cpp(const char *xmlFilePath);
+ ResourcesManager_cpp();
+
+ ~ResourcesManager_cpp();
+
+ std::vector<std::string>
+ GetFittingResources(const machineParams& params,
+ const std::vector<std::string>& componentList) throw(ResourcesException);
+
+ std::string FindFirst(const std::vector<std::string>& listOfMachines);
+ std::string FindNext(const std::vector<std::string>& listOfMachines);
+ std::string FindBest(const std::vector<std::string>& listOfMachines);
+
+ int AddResourceInCatalog
+ (const machineParams& paramsOfNewResources,
+ const std::vector<std::string>& modulesOnNewResources,
+ const char *alias,
+ const char *userName,
+ AccessModeType mode,
+ AccessProtocolType prot) throw(ResourcesException);
+
+ void DeleteResourceInCatalog(const char *hostname);
+
+ void WriteInXmlFile();
+
+ const MapOfParserResourcesType& ParseXmlFile();
+
+ const MapOfParserResourcesType& GetList() const;
+
+ ParserResourcesType GetResourcesList(const std::string& machine);
+
+ protected:
+
+ void SelectOnlyResourcesWithOS(std::vector<std::string>& hosts,
+ const char *OS) const
+ throw(ResourcesException);
+
+ void KeepOnlyResourcesWithModule(std::vector<std::string>& hosts,
+ const std::vector<std::string>& componentList) const
+ throw(ResourcesException);
+
+ //! will contain the path to the ressources catalog
+ std::string _path_resources;
+
+ //! will contain the informations on the data type catalog(after parsing)
+ MapOfParserResourcesType _resourcesList;
+
+ //! will contain the informations on the data type catalog(after parsing)
+ MapOfParserResourcesType _resourcesBatchList;
+
+ SALOME_LoadRateManager _dynamicResourcesSelecter;
+
+ //! different behaviour if $APPLI exists (SALOME Application)
+ bool _isAppliSalomeDefined;
+
+ std::string GetHostname();
+ };
+
+#endif // __RESOURCESMANAGER_HXX__