From: Margarita KARPUNINA Date: Thu, 15 Dec 2022 17:27:47 +0000 (+0300) Subject: [bos #32519][EDF] (2022-T3) X-Git-Tag: V9_11_0a1~6 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d1a36be37c4d5971f3c7fe59a4ef608baf658caa;p=modules%2Fkernel.git [bos #32519][EDF] (2022-T3) Parametrize commands in KERNEL --- diff --git a/src/Container/CMakeLists.txt b/src/Container/CMakeLists.txt index 0c7b8e9b8..0484d29c4 100644 --- a/src/Container/CMakeLists.txt +++ b/src/Container/CMakeLists.txt @@ -145,3 +145,5 @@ SWIG_LINK_LIBRARIES(KernelContainer ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} SalomeC install(TARGETS _KernelContainer DESTINATION ${SALOME_INSTALL_LIBS}) install(FILES ${KernelContainer_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) SALOME_INSTALL_SCRIPTS("${_swig_SCRIPTS}" ${SALOME_INSTALL_BINS} EXTRA_DPYS "${SWIG_MODULE_KernelContainer_REAL_NAME}") + +INSTALL(DIRECTORY ScriptsTemplate DESTINATION ${SALOME_KERNEL_INSTALL_RES_DATA}) \ No newline at end of file diff --git a/src/Container/SALOME_CPythonHelper.cxx b/src/Container/SALOME_CPythonHelper.cxx index 07631c7db..ee06f9568 100644 --- a/src/Container/SALOME_CPythonHelper.cxx +++ b/src/Container/SALOME_CPythonHelper.cxx @@ -77,6 +77,14 @@ void SALOME_CPythonHelper::initializePython(int argc, char *argv[]) PyDict_SetItemString(_globals,"socket",socket); } +void SALOME_CPythonHelper::allowPythonCallsFromDifferentThread() const +{ +#if PY_VERSION_HEX < 0x03070000 + PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/ +#endif + PyEval_SaveThread(); /* Release the thread state */ +} + void SALOME_CPythonHelper::registerToSalomePiDict(const std::string& processName, long pid) const { AutoGIL agil; diff --git a/src/Container/SALOME_CPythonHelper.hxx b/src/Container/SALOME_CPythonHelper.hxx index b93e400b4..e7372d16b 100644 --- a/src/Container/SALOME_CPythonHelper.hxx +++ b/src/Container/SALOME_CPythonHelper.hxx @@ -31,6 +31,7 @@ class CONTAINER_EXPORT SALOME_CPythonHelper { public: void initializePython(int argc, char *argv[]); + void allowPythonCallsFromDifferentThread() const; void registerToSalomePiDict(const std::string& processName, long pid) const; std::vector evalVL(const std::string& pyCode) const; std::string evalS(const std::string& pyCode) const; diff --git a/src/Container/SALOME_ContainerManager.cxx b/src/Container/SALOME_ContainerManager.cxx index b70145d7e..006578eea 100644 --- a/src/Container/SALOME_ContainerManager.cxx +++ b/src/Container/SALOME_ContainerManager.cxx @@ -29,6 +29,7 @@ #include "SALOME_ModuleCatalog.hh" #include "Basics_Utils.hxx" #include "Basics_DirUtils.hxx" +#include "PythonCppUtils.hxx" #include #include #include @@ -39,6 +40,7 @@ #include "Utils_CorbaException.hxx" #include #include +#include #include #include CORBA_CLIENT_HEADER(SALOME_Session) @@ -603,7 +605,7 @@ SALOME_ContainerManager::LaunchContainer(const Engines::ContainerParameters& par logFilename += ".log" ; command += " > " + logFilename + " 2>&1"; MakeTheCommandToBeLaunchedASync(command); - + // launch container with a system call status=SystemThreadSafe(command.c_str()); }//end of critical of section @@ -808,85 +810,186 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer(const std::string& } //============================================================================= -/*! - * builds the command to be launched. +//! Return a path to the directory with scripts templates +/*! + * \return the path pointed by SALOME_KERNEL_SCRIPTS_DIR environment variable, if it is defined, + * ${KERNEL_ROOT_DIR}/share/salome/resources/separator/kernel/ScriptsTemplate - otherwise */ //============================================================================= -std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const Engines::ContainerParameters& params, const std::string& machinesFile, const std::string& container_exe, std::string& tmpFileName) const +std::string getScriptTemplateFilePath() +{ + auto parseScriptTemplateFilePath = []() -> std::string + { + std::string scriptTemplateFilePath = SALOME_ContainerManager::GetenvThreadSafeAsString("SALOME_KERNEL_SCRIPTS_DIR"); + if (!scriptTemplateFilePath.empty()) + { + return scriptTemplateFilePath; + } + else { + return SALOME_ContainerManager::GetenvThreadSafeAsString("KERNEL_ROOT_DIR") + + "/share/salome/resources/kernel/ScriptsTemplate"; + } + }; + + static const std::string scriptTemplateFilePath = parseScriptTemplateFilePath(); + return scriptTemplateFilePath; +} + +//============================================================================= +//! Return a command line constructed based on Python scripts templates +/*! + * \param theScriptName the name of Python script template + * \param theScriptParameters the queue of parameter values + * \return the command line constructed according to the given parameters + */ +//============================================================================= +std::string GetCommandFromTemplate(const std::string& theScriptName, + std::queue& theScriptParameters) { - tmpFileName = BuildTemporaryFileName(); std::string command; + AutoGIL agil; + // manage GIL - std::ostringstream o; + PyObject* mod(PyImport_ImportModule(theScriptName.c_str())); + if (!mod) + { + PyObject* sys = PyImport_ImportModule("sys"); + PyObject* sys_path = PyObject_GetAttrString(sys, "path"); + PyObject* folder_path = PyUnicode_FromString(getScriptTemplateFilePath().c_str()); + PyList_Append(sys_path, folder_path); - if (params.isMPI) + mod = PyImport_ImportModule(theScriptName.c_str()); + + Py_XDECREF(folder_path); + Py_XDECREF(sys_path); + Py_XDECREF(sys); + } + + if (mod) + { + PyObject* meth(PyObject_GetAttrString(mod, "command")); + if (!meth) { - int nbproc = params.nb_proc <= 0 ? 1 : params.nb_proc; + Py_XDECREF(mod); + } + else + { + int id = -1; + PyObject* tuple(PyTuple_New(theScriptParameters.size())); - o << "mpirun -np "; + auto insert_parameter = [&tuple, &theScriptParameters, &id]() + { + if (!theScriptParameters.empty()) + { + PyTuple_SetItem(tuple, ++id, PyUnicode_FromString(theScriptParameters.front().c_str())); + theScriptParameters.pop(); + } + }; - o << nbproc << " "; + while (!theScriptParameters.empty()) + { + insert_parameter(); + } + + PyObject *args(PyTuple_New(1)); + PyTuple_SetItem(args, 0, tuple); + + PyObject *res(PyObject_CallObject(meth, args)); + if (res) + { + command = PyUnicode_AsUTF8(res); + Py_XDECREF(res); + } + + Py_XDECREF(args); + Py_XDECREF(tuple); + Py_XDECREF(meth); + Py_XDECREF(mod); + } + } - if( GetenvThreadSafe("LIBBATCH_NODEFILE") != NULL ) - o << "-machinefile " << machinesFile << " "; + MESSAGE("Command from template is ... " << command << std::endl); + return command; +} +//============================================================================= +//============================================================================= +/*! + * builds the command to be launched. + */ +//============================================================================= +std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const Engines::ContainerParameters& params, const std::string& machinesFile, const std::string& container_exe, std::string& tmpFileName) const +{ + // Prepare name of the script to be used + std::string script_name = "SALOME_CM_LOCAL_NO_MPI"; + if (params.isMPI) + { #ifdef LAM_MPI - o << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace "; + script_name = "SALOME_CM_LOCAL_MPI_LAN"; #elif defined(OPEN_MPI) - if( GetenvThreadSafe("OMPI_URI_FILE") == NULL ) - o << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace"; - else - { - o << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:"; - o << GetenvThreadSafeAsString("OMPI_URI_FILE"); - } + script_name = "SALOME_CM_LOCAL_MPI_OPENMPI"; #elif defined(MPICH) - o << "-nameserver " + Kernel_Utils::GetHostname(); + script_name = "SALOME_CM_LOCAL_MPI_MPICH"; #endif + } + + // Prepare parameters to use in the Python script: + // 1. All parameters are strings. + // 2. For some booleans use "1" = True, "0" = False. + // 3. If a parameter is NULL, then its value is "NULL". - if (isPythonContainer(params.container_name)) - o << " pyMPI SALOME_ContainerPy.py "; - else - o << " SALOME_MPIContainer "; - } + std::queue script_parameters; + + // ===== Number of processes (key = "nb_proc") + script_parameters.push(params.isMPI ? std::to_string(params.nb_proc <= 0 ? 1 : params.nb_proc) : "NULL"); + + // ===== Working directory (key = "workdir") and temporary directory flag (key = "isTmpDir") + // A working directory is requested + std::string workdir = params.workingdir.in(); + std::string isTmpDir = std::to_string(0); + if (workdir == "$TEMPDIR") + { + // A new temporary directory is requested + isTmpDir = std::to_string(1); + workdir = Kernel_Utils::GetTmpDir(); + } + script_parameters.push(workdir); + script_parameters.push(isTmpDir); + + // ===== Server name (key = "name_server") + script_parameters.push(Kernel_Utils::GetHostname()); + // ===== Container (key = "container") + std::string container; + if (params.isMPI) + { + container = isPythonContainer(params.container_name) ? "pyMPI SALOME_ContainerPy.py" : "SALOME_MPIContainer"; + } else - { - std::string wdir=params.workingdir.in(); - if(wdir != "") - { - // a working directory is requested - if(wdir == "$TEMPDIR") - { - // a new temporary directory is requested - std::string dir = Kernel_Utils::GetTmpDir(); -#ifdef WIN32 - o << "cd /d " << dir << std::endl; -#else - o << "cd " << dir << ";"; -#endif + { + container = isPythonContainer(params.container_name) ? "SALOME_ContainerPy.py" : container_exe; + } + script_parameters.push(container); - } - else - { - // a permanent directory is requested use it or create it -#ifdef WIN32 - o << "mkdir " + wdir << std::endl; - o << "cd /D " + wdir << std::endl; -#else - o << "mkdir -p " << wdir << " && cd " << wdir + ";"; -#endif - } - } + // ===== Container name (key = "container_name") + script_parameters.push(_NS->ContainerName(params)); - if (isPythonContainer(params.container_name)) - o << "SALOME_ContainerPy.py "; - else - o << container_exe + " "; + // ===== LIBBATCH node file (key = "libbatch_nodefile") + script_parameters.push(std::to_string(GetenvThreadSafe("LIBBATCH_NODEFILE") != NULL ? 1 : 0)); - } + // ===== Machine file (key = "machine_file") + script_parameters.push(machinesFile.empty() ? "NULL" : machinesFile); + + // ===== OMPI uri file (key = "ompi_uri_file") + std::string ompi_uri_file = GetenvThreadSafeAsString("OMPI_URI_FILE"); + script_parameters.push(ompi_uri_file.empty() ? "NULL" : ompi_uri_file); + + std::string command_from_template = GetCommandFromTemplate(script_name, script_parameters); + + std::ostringstream o; + o << command_from_template << " "; - o << _NS->ContainerName(params) << " "; + //==================================================================================== */ if( this->_isSSL ) { @@ -900,6 +1003,7 @@ std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const En AddOmninamesParams(o); } + tmpFileName = BuildTemporaryFileName(); std::ofstream command_file( tmpFileName.c_str() ); command_file << o.str(); command_file.close(); @@ -907,8 +1011,8 @@ std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const En #ifndef WIN32 chmod(tmpFileName.c_str(), 0x1ED); #endif - command = tmpFileName; - + + std::string command = tmpFileName; MESSAGE("Command is file ... " << command); MESSAGE("Command is ... " << o.str()); return command; @@ -1255,6 +1359,83 @@ std::string SALOME_ContainerManager::getCommandToRunRemoteProcess(AccessProtocol const std::string & workdir) const { std::ostringstream command; + + // Prepare parameters to use in the Python script: + // 1. All parameters are strings. + // 2. For some booleans use "1" = True, "0" = False. + // 3. If a parameter is NULL, then its value is "NULL". + + std::queue script_parameters; + + // ===== Protocol (key = "protocol") + std::string strProtocol; + switch (protocol) + { + case rsh: strProtocol = "rsh"; break; + case ssh: strProtocol = "ssh"; break; + case srun: strProtocol = "srun"; break; + case pbsdsh: strProtocol = "pbsdsh"; break; + case blaunch: strProtocol = "blaunch"; break; + default: + throw SALOME_Exception("Unknown protocol"); + } + script_parameters.push(strProtocol); + + // ===== User name (key = "user") + script_parameters.push(username.empty() ? "NULL" : username); + + // ===== Host name (key = "host") + script_parameters.push(hostname.empty() ? "NULL" : hostname); + + + // ===== Remote APPLI path (key = "appli") + script_parameters.push(applipath.empty() ? GetenvThreadSafeAsString("APPLI") : applipath); + + if(!this->_isSSL) + { + ASSERT(GetenvThreadSafe("NSHOST")); + ASSERT(GetenvThreadSafe("NSPORT")); + } + + struct stat statbuf; + std::string appli_mode = (stat(GetenvThreadSafe("APPLI"), &statbuf) == 0 && S_ISREG(statbuf.st_mode)) ? "launcher" : "dir"; + + // ===== Working directory (key = "workdir") + script_parameters.push(workdir == "$TEMPDIR" ? "\\$TEMPDIR" : workdir); + + // ===== SSL (key = "ssl") + script_parameters.push(this->_isSSL ? "1" : "0"); + + // ===== Hostname of CORBA name server (key = "nshost") + std::string nshost = GetenvThreadSafeAsString("NSHOST"); + script_parameters.push(nshost.empty() ? "NULL" : nshost); + + // ===== Port of CORBA name server (key = "nsport") + std::string nsport = GetenvThreadSafeAsString("NSPORT"); + script_parameters.push(nsport.empty() ? "NULL" : nsport); + + // ===== Remote script (key = "remote_script") + std::string remoteScript = this->GetRunRemoteExecutableScript(); + script_parameters.push(remoteScript.empty() ? "NONE" : remoteScript); + + // ===== Naming service (key = "naming_service") + std::string namingService = "NONE"; + if(this->_isSSL) + { + Engines::EmbeddedNamingService_var ns = GetEmbeddedNamingService(); + CORBA::String_var iorNS = _orb->object_to_string(ns); + namingService = iorNS; + } + script_parameters.push(namingService); + + // ===== APPLI mode (key = "appli_mode") + // $APPLI points either to an application directory, or to a salome launcher file + // we prepare the remote command according to the case + script_parameters.push(appli_mode); + + command << GetCommandFromTemplate("SALOME_CM_REMOTE", script_parameters); + + /* //==================================================================================== bool envd = true; // source the environment switch (protocol) { @@ -1353,6 +1534,7 @@ std::string SALOME_ContainerManager::getCommandToRunRemoteProcess(AccessProtocol command << "'"; } } + //==================================================================================== */ return command.str(); } diff --git a/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_LAN.py b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_LAN.py new file mode 100644 index 000000000..d4eb85966 --- /dev/null +++ b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_LAN.py @@ -0,0 +1,19 @@ +import sys +from script_parameters import ScriptLocalParameters + +def command(args): + options = ScriptLocalParameters(args) + if options.debug: print(options) + + cmd = [] + cmd.append("mpirun -np " + options.nb_proc) + + if options.libbatch_nodefile: + cmd.append("-machinefile %s " % options.machine_file) + + cmd.append("-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ") + + cmd.append(options.container) + cmd.append(options.container_name) + + return " ".join(cmd) \ No newline at end of file diff --git a/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_MPICH.py b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_MPICH.py new file mode 100644 index 000000000..2fd94c74a --- /dev/null +++ b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_MPICH.py @@ -0,0 +1,18 @@ +import sys +from script_parameters import ScriptLocalParameters + +def command(args): + options = ScriptLocalParameters(args) + if options.debug: print(options) + + cmd = [] + cmd.append("mpirun -np " + options.nb_proc) + + if options.libbatch_nodefile: + cmd.append("-machinefile %s " % options.machine_file) + + cmd.append("-nameserver %s" % options.name_server) + cmd.append(options.container) + cmd.append(options.container_name) + + return " ".join(cmd) \ No newline at end of file diff --git a/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_OPENMPI.py b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_OPENMPI.py new file mode 100644 index 000000000..a0ff6f833 --- /dev/null +++ b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_MPI_OPENMPI.py @@ -0,0 +1,21 @@ +import sys +from script_parameters import ScriptLocalParameters + +def command(args): + options = ScriptLocalParameters(args) + if options.debug: print(options) + + cmd = [] + cmd.append("mpirun -np " + options.nb_proc) + + if options.libbatch_nodefile: + cmd.append("-machinefile %s " % options.machine_file) + + cmd.append("-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace ") + if options.ompi_uri_file: + cmd.append("-ompi-server file:%s" % options.ompi_uri_file) + + cmd.append(options.container) + cmd.append(options.container_name) + + return " ".join(cmd) \ No newline at end of file diff --git a/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_NO_MPI.py b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_NO_MPI.py new file mode 100644 index 000000000..b291e7356 --- /dev/null +++ b/src/Container/ScriptsTemplate/SALOME_CM_LOCAL_NO_MPI.py @@ -0,0 +1,25 @@ +import sys +from script_parameters import ScriptLocalParameters + +def command(args): + options = ScriptLocalParameters(args) + if options.debug: print(options) + + cmd = [] + if options.workdir: + if options.isTmpDir: + if options.Windows: + cmd.append("cd /d %s\n" % options.workdir) + else: + cmd.append("cd %s;" % options.workdir) + else: + if options.Windows: + cmd.append("mkdir %s" % options.workdir); + cmd.append("cd /d %s\n" % options.workdir) + else: + cmd.append("mkdir -p %s && cd %s;" % (options.workdir, options.workdir)) + + cmd.append(options.container) + cmd.append(options.container_name) + + return " ".join(cmd) \ No newline at end of file diff --git a/src/Container/ScriptsTemplate/SALOME_CM_REMOTE.py b/src/Container/ScriptsTemplate/SALOME_CM_REMOTE.py new file mode 100644 index 000000000..9be7bd72e --- /dev/null +++ b/src/Container/ScriptsTemplate/SALOME_CM_REMOTE.py @@ -0,0 +1,116 @@ +import sys + +class ScriptRemoteParameters: + def __init__(self, args): + self.debug = False + if args[0] == "-d": + self.debug = True + args = args[1:] + + self.protocol = args[0] + self.user = self._read_arg(args[1], "NULL") + self.host = self._read_arg(args[2], "NULL") + self.appli = self._read_arg(args[3], "NULL") + self.workdir = self._read_arg(args[4], "NULL") + self.ssl = True if args[5] == "1" else False + self.nshost = args[6] + self.nsport = args[7] + self.remote_script = self._read_arg(args[8], "NULL") + self.naming_service = self._read_arg(args[9], "NULL") + self.appli_mode = args[10] + + import platform + self.Windows = platform.system() == "Windows" + + def _read_arg(self, value, null_value): + if value == null_value: + return None + return value + + def __str__(self): + str = [] + str.append("protocol: %s" % self.protocol) + str.append("user: %s" % self.user) + str.append("hostname: %s" % self.host) + str.append("appli: %s" % self.appli) + str.append("workdir: %s" % self.workdir) + str.append("ssl: %s" % self.ssl) + str.append("nshost: %s" % self.nshost) + str.append("nsport: %s" % self.nsport) + str.append("remote_script: %s" % self.remote_script) + str.append("naming_service: %s" % self.naming_service) + str.append("appil_mode: %s" % self.appli_mode) + str.append("--") + return "\n".join(str) + +# ---------------------------------------------- +def command(args): + options = ScriptRemoteParameters(args) + if options.debug: print(options) + + # build command depending on protocol + cmd = [] + envd = (options.protocol != "srun") + + if options.protocol == "rsh": + # RSH command + cmd.append("rsh") + if options.user: + cmd.append("-l " + options.user) + cmd.append(options.host) + + elif options.protocol == "ssh": + # SSH command + cmd.append("ssh") + if options.user: + cmd.append("-l " + options.user) + cmd.append(options.host) + + elif options.protocol == "srun": + # srun command + cmd.append("srun") + cmd.append("-n 1 -N 1 -s --mem-per-cpu=0 --cpu-bind=none") + cmd.append("--nodelist=" + options.host) + + elif options.protocol == "pbsdsh": + # pbsdh command + cmd.append("pbsdsh") + cmd.append("-o -h") + cmd.append(options.host) + + elif options.protocol == "blaunch": + # blaunch command + cmd.append("blaunch") + cmd.append("-no-shell") + cmd.append(options.host) + + else: + # unknown protocol + raise ValueError("Unknown protocol: %s" % options.protocol) + + + if options.appli_mode == "dir": + cmd.append(options.appli + "/" + options.remote_script) + if not envd: + cmd.append("--noenvd") + if options.ssl: + cmd.append(options.naming_service) + else: + cmd.append(options.nshost) + cmd.append(options.nsport) + + if options.workdir: + cmd.append(" WORKINGDIR '%s'" % options.workdir) + + elif options.appli_mode == "launcher": + cmd.append(options.appli + " remote") + if not options.ssl: + cmd.append("-m %s -p %s" % (options.nshost, options.nsport)) + + if options.workdir: + cmd.append("-d " + options.workdir) + cmd.append("--") + + # elif ignore other appli_mode value + + return " ".join(cmd) \ No newline at end of file diff --git a/src/Container/ScriptsTemplate/script_parameters.py b/src/Container/ScriptsTemplate/script_parameters.py new file mode 100644 index 000000000..407f24a3e --- /dev/null +++ b/src/Container/ScriptsTemplate/script_parameters.py @@ -0,0 +1,38 @@ +class ScriptLocalParameters: + def __init__(self, args): + self.debug = False + if args[0] == "-d": + self.debug = True + args = args[1:] + + self.nb_proc = self._read_arg(args[0], "NULL") + self.workdir = self._read_arg(args[1], "NULL") + self.isTmpDir = True if args[2] == "1" else False + self.name_server = args[3] + self.container = args[4] + self.container_name = args[5] + self.libbatch_nodefile = self._read_arg(args[6], "NULL") + self.machine_file = self._read_arg(args[7], "NULL") + self.ompi_uri_file = self._read_arg(args[8], "NULL") + + import platform + self.Windows = platform.system() == "Windows" + + def _read_arg(self, value, null_value): + if value == null_value: + return None + return value + + def __str__(self): + str = [] + str.append("nb_proc: %s" % self.nb_proc) + str.append("workdir: %s" % self.workdir) + str.append("isTmpDir: %s" % self.isTmpDir) + str.append("name_server: %s" % self.name_server) + str.append("container: %s" % self.container) + str.append("container_name: %s" % self.container_name) + str.append("libbatch_nodefile: %s" % self.libbatch_nodefile) + str.append("machine_file: %s" % self.machine_file) + str.append("ompi_uri_file: %s" % self.ompi_uri_file) + str.append("--") + return "\n".join(str) \ No newline at end of file diff --git a/src/Launcher/SALOME_LauncherServer.cxx b/src/Launcher/SALOME_LauncherServer.cxx index ed41de8b5..8ceb76486 100644 --- a/src/Launcher/SALOME_LauncherServer.cxx +++ b/src/Launcher/SALOME_LauncherServer.cxx @@ -118,6 +118,7 @@ int main(int argc, char* argv[]) threadPol->destroy(); SALOME_CPythonHelper cPyh; cPyh.initializePython(argc,argv); + cPyh.allowPythonCallsFromDifferentThread(); SALOME_Launcher *lServ(new SALOME_Launcher(orb,safePOA)); lServ->DeclareUsingSalomeSession(); lServ->_remove_ref();