From: Anthony Geay Date: Mon, 26 Feb 2024 08:20:09 +0000 (+0100) Subject: [EDF29576] : ready for clean SIGINT implementation X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ababefd48b1eefd005c5aa206f491a58ed160f5b;p=modules%2Fyacs.git [EDF29576] : ready for clean SIGINT implementation --- diff --git a/src/yacsloader/CMakeLists.txt b/src/yacsloader/CMakeLists.txt index 3a8cb97e5..d42b1e33d 100644 --- a/src/yacsloader/CMakeLists.txt +++ b/src/yacsloader/CMakeLists.txt @@ -161,8 +161,8 @@ ADD_LIBRARY(ExampleOfObserversPluginForDriver ${ExampleOfObserversPluginForDrive TARGET_LINK_LIBRARIES(ExampleOfObserversPluginForDriver ${_link_LIBRARIES}) INSTALL(TARGETS ExampleOfObserversPluginForDriver DESTINATION ${SALOME_INSTALL_LIBS}) -ADD_EXECUTABLE(driver ${driver_SOURCES}) -TARGET_LINK_LIBRARIES(driver ${_link_LIBRARIES}) +ADD_EXECUTABLE(driverOld ${driver_SOURCES}) +TARGET_LINK_LIBRARIES(driverOld ${_link_LIBRARIES}) ADD_EXECUTABLE(resume ${resume_SOURCES}) TARGET_LINK_LIBRARIES(resume ${_link_LIBRARIES}) @@ -170,12 +170,16 @@ TARGET_LINK_LIBRARIES(resume ${_link_LIBRARIES}) ADD_EXECUTABLE(debugger ${debugger_SOURCES}) TARGET_LINK_LIBRARIES(debugger ${_link_LIBRARIES}) -SET_TARGET_PROPERTIES(driver resume debugger PROPERTIES COMPILE_FLAGS ${_exec_DEFINITIONS}) +SET_TARGET_PROPERTIES(driverOld resume debugger PROPERTIES COMPILE_FLAGS ${_exec_DEFINITIONS}) -INSTALL(TARGETS driver resume debugger EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) +INSTALL(TARGETS driverOld resume debugger EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) INSTALL(FILES ${YACSloader_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) +INSTALL(FILES driver_internal.py DESTINATION ${SALOME_INSTALL_PYTHON}) + +INSTALL(FILES driver PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${SALOME_INSTALL_BINS}) + FILE(GLOB sample_files ${PROJECT_SOURCE_DIR}/src/yacsloader/samples/*.xml ${PROJECT_SOURCE_DIR}/src/yacsloader/samples/*.pmml diff --git a/src/yacsloader/driver b/src/yacsloader/driver new file mode 100644 index 000000000..b7e6e89ec --- /dev/null +++ b/src/yacsloader/driver @@ -0,0 +1,235 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (C) 2024 CEA, EDF +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# driver -v -kt micro_schema.xml +# driver -d 3 -g 2 --stop-on-error --dump-on-error="popo.xml" -v -kt -i "PyScript0.p1=7" --dump-final="tutu.xml" micro_schema2.xml +# driver -g 2 --stop-on-error --dump-on-error="popo.xml" -v -kt -i "PyScript0.p1=7" --dump-final="tutu.xml" micro_schema2.xml +# driver -x -g 2 --stop-on-error --dump-on-error="popo.xml" -v -kt -i "PyScript0.p1=7" --dump-final="tutu.xml" micro_schema2.xml +# driver -x -g 2 -s -e "popo.xml" -v -kt -i "PyScript0.p1=7" -f "tutu.xml" micro_schema2.xml +# driver micro_schema3.xml + +import salome +import logging + +my_runtime_yacs = None + +def initializeSALOME(): + import SALOMERuntime + global my_runtime_yacs + if my_runtime_yacs: + return + salome.salome_init() + flags = SALOMERuntime.RuntimeSALOME.UsePython + SALOMERuntime.RuntimeSALOME.UseCorba + SALOMERuntime.RuntimeSALOME.UseXml + SALOMERuntime.RuntimeSALOME.UseCpp + SALOMERuntime.RuntimeSALOME.UseSalome + SALOMERuntime.RuntimeSALOME.setRuntime( flags ) + my_runtime_yacs = SALOMERuntime.getSALOMERuntime() + anIOR = salome.orb.object_to_string ( salome.modulcat ) + aCatalog = my_runtime_yacs.loadCatalog( "session", anIOR ) + my_runtime_yacs.addCatalog( aCatalog ) + +def SALOMEInitializationNeeded(func): + def decaratedFunc(*args,**kwargs): + initializeSALOME() + return func(*args,**kwargs) + return decaratedFunc + +@SALOMEInitializationNeeded +def loadGraph( xmlFileName ): + """ + Args: + ----- + xmlFileName : XML file containing YACS schema + + Returns + ------- + + SALOMERuntime.SalomeProc : YACS graph instance + """ + import loader + l=loader.YACSLoader() + p=l.load( xmlFileName ) + return p + +def patchGraph( proc, squeezeMemory, initPorts, xmlSchema, loadStateXmlFile, reset, display): + """ + Args: + ----- + + proc ( SALOMERuntime.SalomeProc ) : YACS Proc instance to be evaluated + squeezeMemory ( bool ) : squeezememory to be activated + initPorts (list) : list of bloc.node.port=value. + xmlSchema (string) : + loadStateXmlFile (string) : file if any of state to be loaded inside proc + reset (int) : + display (int) : + """ + import SALOMERuntime + import loader + def parse_init_port(input): + """ + Returns + ------- + node, port, value + """ + node_port, value = input.split("=") + nodePortSpl = node_port.split(".") + port = nodePortSpl[-1] + node = ".".join( nodePortSpl[:-1] ) + return node,port,value + + if squeezeMemory: + logging.info("SqueezeMemory requested -> update proc") + allNodes = proc.getAllRecursiveNodes() + for node in allNodes: + if isinstance(proc,SALOMERuntime.PythonNode): + node.setSqueezeStatus( True ) + # + for initPort in initPorts: + node,port,value = parse_init_port(initPort) + init_state = proc.setInPortValue(node, port, value) + if init_state != value: + raise RuntimeError(f"Error on initialization of {initPort}") + # + if xmlSchema: + SALOMERuntime.VisitorSaveSalomeSchemaUnsafe(proc,xmlSchema) + pass + # + if loadStateXmlFile: + loader.loadState( proc, loadStateXmlFile ) + if reset > 0: + proc.resetState(reset) + proc.exUpdateState() + # + if display > 0: + proc.writeDotInFile("toto") + +@SALOMEInitializationNeeded +def prepareExecution(proc, isStop, dumpErrorFile): + """ + Returns + ------- + + pilot.ExecutorSwig : Instance of executor + """ + import pilot + ex=pilot.ExecutorSwig() + if isStop: + logging.info(f"Stop has been activated with {dumpErrorFile}") + ex.setStopOnError( dumpErrorFile!="", dumpErrorFile ) + return ex + +@SALOMEInitializationNeeded +def executeGraph( executor, xmlfilename, proc, dump, finalDump, display, shutdown ): + """ + Args: + ----- + + executor (pilot.ExecutorSwig) : Executor in charge of evaluation. + proc ( SALOMERuntime.SalomeProc ) : YACS Proc instance to be evaluated + xmlfilename (string) + dump (int) : time interval between 2 dump state + finalDump ( string ) : filename containing final result of graph, if any. + display (int) : + shutdown (int) : shutdown level + """ + import signal + import SALOMERuntime + def handler(signum, frame): + print('Signal handler called with signal', signum) + proc.cleanNodes() + if finalDump: + SALOMERuntime.schemaSaveStateUnsafe( proc, finalDump ) + if shutdown < 999: + print(100*"shutdown") + proc.shutdown(shutdown) + + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) + dump_thread = None + import pilot + import os + + if dump != 0: + dumpFile = "dumpState_{}".format( os.path.basename(xmlfilename) ) + lockFile = "{}.lock".format( os.path.splitext( os.path.basename(xmlfilename) )[0] ) + dump_thread = SALOMERuntime.ThreadDumpState(proc,dump,dumpFile,lockFile) + dump_thread.start() + + executor.RunPy(proc,display,isPyThread=True,fromscratch=True) # same as RunW but releasing GIL + if proc.getEffectiveState() != pilot.DONE: + raise RuntimeError( proc.getErrorReport() ) + # + if display > 0: + proc.writeDotInFile("titi") + # + if dump_thread: + dump_thread.join() + # + if finalDump: + logging.info(f"Final dump requested : {finalDump}") + SALOMERuntime.schemaSaveStateUnsafe( proc, finalDump ) + +@SALOMEInitializationNeeded +def destroyElementsGeneratedByExecutionOfGraph( proc, shutdown ): + """ + Args: + ----- + + shutdown (int) : shutdown level + + """ + if shutdown < 999: + proc.shutdown(shutdown) + salome.dsm.shutdownScopes() + my_runtime_yacs.fini( False ) + +if __name__ == "__main__": + from salome_utils import positionVerbosityOfLoggerRegardingState,setVerboseLevel,setVerbose + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('xmlfilename',help = "XML file containing YACS schema to be executed") + parser.add_argument("-d", "--display", dest = "display", type=int, default=[0], nargs=1, help="Display dot files: 0=never to 3=very often") + parser.add_argument("-v", "--verbose", dest = "verbose",help="Produce verbose output", action='store_true') + parser.add_argument("-s","--stop-on-error",dest="stop",help="Stop on first error", action='store_true') + parser.add_argument("-e","--dump-on-error",dest="dumpErrorFile", type=str, const='dumpErrorState.xml', default="", nargs='?', help="Stop on first error and dump state") + parser.add_argument("-g","--dump",dest="dump", type=int, const=60, default=0, nargs='?', help="dump state") + parser.add_argument("-kt", "--kerneltrace", dest = "kerneltrace",help="Produce verbose of SALOME/KERNEL", action='store_true') + parser.add_argument("-f","--dump-final", dest ="finalDump", type=str, const='finalDumpState.xml', default="", nargs='?', help="dump final state") + parser.add_argument("-l","--load-state", dest="loadState", type=str, default="", help="Load State from a previous partial execution") + parser.add_argument("-x","--save-xml-schema", dest="saveXMLSchema", type=str, const="saveSchema.xml", nargs='?', default="", help = "dump xml schema") + parser.add_argument("-t","--shutdown", dest = 'shutdown', type=int , default=1, help="Shutdown the schema: 0=no shutdown to 3=full shutdown") + parser.add_argument("-r","--reset", dest = "reset", type=int , default = 0, help="Reset the schema before execution: 0=nothing, 1=reset error nodes to ready state") + parser.add_argument("-i","--init-port", dest = 'init_port', type=str, default ="", help="Initialisation value of a port, specified as bloc.node.port=value.") + parser.add_argument("-z","--donotsqueeze", dest = "donotsqueeze", help = "Desactivate squeeze memory optimization.", action='store_true') + args = parser.parse_args() + args.display = args.display[0] + # + if args.verbose: + setVerbose( args.kerneltrace ) + setVerboseLevel(logging.INFO) + positionVerbosityOfLoggerRegardingState() + # + proc = loadGraph( args.xmlfilename ) + patchGraph( proc, not args.donotsqueeze, [elt for elt in args.init_port.split(",") if elt !=""], args.saveXMLSchema, args.loadState, args.reset, args.display) + executor = prepareExecution( proc, args.stop, args.dumpErrorFile) + # + executeGraph( executor, args.xmlfilename, proc, args.dump, args.finalDump, args.display, args.shutdown) + # + destroyElementsGeneratedByExecutionOfGraph( proc, args.shutdown ) diff --git a/src/yacsloader/driver.py b/src/yacsloader/driver.py deleted file mode 100644 index 4b55a6f34..000000000 --- a/src/yacsloader/driver.py +++ /dev/null @@ -1,227 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2024 CEA, EDF -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -# python3 /home/H87074/salome/990_CEA/SALOME-master-native-DB11-SRC/SOURCES/yacs/src/yacsloader/driver.py -v -kt micro_schema.xml -# python3 /home/H87074/salome/990_CEA/SALOME-master-native-DB11-SRC/SOURCES/yacs/src/yacsloader/driver.py -d 3 -g 2 --stop-on-error --dump-on-error="popo.xml" -v -kt -ip "PyScript0.p1=7" --dump-final="tutu.xml" micro_schema2.xml -# python3 /home/H87074/salome/990_CEA/SALOME-master-native-DB11-SRC/SOURCES/yacs/src/yacsloader/driver.py -g 2 --stop-on-error --dump-on-error="popo.xml" -v -kt -ip "PyScript0.p1=7" --dump-final="tutu.xml" micro_schema2.xml -# python3 /home/H87074/salome/990_CEA/SALOME-master-native-DB11-SRC/SOURCES/yacs/src/yacsloader/driver.py -x -g 2 --stop-on-error --dump-on-error="popo.xml" -v -kt -ip "PyScript0.p1=7" --dump-final="tutu.xml" micro_schema2.xml - -import loader -#import SALOMERuntime -import salome -import logging - -""" -struct arguments -{ - int dump = 0; -}; - - {"dump", 'g', "nbsec", OPTION_ARG_OPTIONAL, "dump state"}, - {"save-xml-schema", 'x', "file", OPTION_ARG_OPTIONAL, "dump xml schema"}, -""" - -my_runtime_yacs = None - -def initializeSALOME(): - import SALOMERuntime - global my_runtime_yacs - if my_runtime_yacs: - return - salome.salome_init() - flags = SALOMERuntime.RuntimeSALOME.UsePython + SALOMERuntime.RuntimeSALOME.UseCorba + SALOMERuntime.RuntimeSALOME.UseXml + SALOMERuntime.RuntimeSALOME.UseCpp + SALOMERuntime.RuntimeSALOME.UseSalome - SALOMERuntime.RuntimeSALOME.setRuntime( flags ) - my_runtime_yacs = SALOMERuntime.getSALOMERuntime() - anIOR = salome.orb.object_to_string ( salome.modulcat ) - aCatalog = my_runtime_yacs.loadCatalog( "session", anIOR ) - my_runtime_yacs.addCatalog( aCatalog ) - -def SALOMEInitializationNeeded(func): - def decaratedFunc(*args,**kwargs): - initializeSALOME() - return func(*args,**kwargs) - return decaratedFunc - -@SALOMEInitializationNeeded -def loadGraph( xmlFileName ): - """ - Args: - ----- - xmlFileName : XML file containing YACS schema - - Returns - ------- - - SALOMERuntime.SalomeProc : YACS graph instance - """ - l=loader.YACSLoader() - p=l.load( xmlFileName ) - return p - -def patchGraph( proc, squeezeMemory, initPorts, xmlSchema, loadStateXmlFile, reset, display): - """ - Args: - ----- - - proc ( SALOMERuntime.SalomeProc ) : YACS Proc instance to be evaluated - squeezeMemory ( bool ) : squeezememory to be activated - initPorts (list) : list of bloc.node.port=value. - xmlSchema (string) : - loadStateXmlFile (string) : file if any of state to be loaded inside proc - reset (int) : - display (int) : - """ - import SALOMERuntime - def parse_init_port(input): - """ - Returns - ------- - node, port, value - """ - node_port, value = input.split("=") - nodePortSpl = node_port.split(".") - port = nodePortSpl[-1] - node = ".".join( nodePortSpl[:-1] ) - return node,port,value - - if squeezeMemory: - logging.info("SqueezeMemory requested -> update proc") - allNodes = proc.getAllRecursiveNodes() - for node in allNodes: - if isinstance(proc,SALOMERuntime.PythonNode): - node.setSqueezeStatus( True ) - # - for initPort in initPorts: - node,port,value = parse_init_port(initPort) - init_state = proc.setInPortValue(node, port, value) - if init_state != value: - raise RuntimeError(f"Error on initialization of {initPort}") - # - if xmlSchema: - SALOMERuntime.VisitorSaveSalomeSchemaUnsafe(proc,xmlSchema) - pass - # - if loadStateXmlFile: - loader.loadState( proc, loadStateXmlFile ) - if reset > 0: - proc.resetState(reset) - proc.exUpdateState() - # - if display > 0: - proc.writeDotInFile("toto") - -@SALOMEInitializationNeeded -def prepareExecution(proc, isStop, dumpErrorFile): - """ - Returns - ------- - - pilot.ExecutorSwig : Instance of executor - """ - import pilot - ex=pilot.ExecutorSwig() - if isStop: - logging.info(f"Stop has been activated with {dumpErrorFile}") - ex.setStopOnError( dumpErrorFile!="", dumpErrorFile ) - return ex - -@SALOMEInitializationNeeded -def executeGraph( executor, xmlfilename, proc, dump, finalDump, display ): - """ - Args: - ----- - - executor (pilot.ExecutorSwig) : Executor in charge of evaluation. - proc ( SALOMERuntime.SalomeProc ) : YACS Proc instance to be evaluated - xmlfilename (string) - dump (int) : time interval between 2 dump state - finalDump ( string ) : filename containing final result of graph, if any. - display (int) : - """ - global dump_thread - import pilot - import SALOMERuntime - import os - - if dump != 0: - dumpFile = "dumpState_{}".format( os.path.basename(xmlfilename) ) - lockFile = "{}.lock".format( os.path.splitext( os.path.basename(xmlfilename) )[0] ) - dump_thread = SALOMERuntime.ThreadDumpState(proc,dump,dumpFile,lockFile) - dump_thread.start() - - executor.RunPy(proc,display,isPyThread=True,fromscratch=True) # same as RunW but releasing GIL - if proc.getEffectiveState() != pilot.DONE: - raise RuntimeError( proc.getErrorReport() ) - # - if display > 0: - proc.writeDotInFile("titi") - # - if dump_thread: - dump_thread.join() - # - if finalDump: - logging.info(f"Final dump requested : {finalDump}") - SALOMERuntime.schemaSaveStateUnsafe( proc, finalDump ) - -@SALOMEInitializationNeeded -def destroyElementsGeneratedByExecutionOfGraph( proc, shutdown ): - """ - Args: - ----- - - shutdown (int) : shutdown level - - """ - if shutdown < 999: - proc.shutdown(shutdown) - salome.dsm.shutdownScopes() - my_runtime_yacs.fini( False ) - -if __name__ == "__main__": - from salome_utils import positionVerbosityOfLoggerRegardingState,setVerboseLevel,setVerbose - import argparse - parser = argparse.ArgumentParser() - parser.add_argument('xmlfilename',help = "XML file containing YACS schema to be executed") - parser.add_argument("-d", "--display", dest = "display", type=int, default=[0], nargs=1, help="Display dot files: 0=never to 3=very often") - parser.add_argument("-v", "--verbose", dest = "verbose",help="Produce verbose output", action='store_true') - parser.add_argument("--stop-on-error",dest="stop",help="Stop on first error", action='store_true') - parser.add_argument("-e","--dump-on-error",dest="dumpErrorFile", type=str, const='dumpErrorState.xml', default="", nargs='?', help="Stop on first error and dump state") - parser.add_argument("-g","--dump",dest="dump", type=int, const=60, default=0, nargs='?', help="dump state") - parser.add_argument("-kt", "--kerneltrace", dest = "kerneltrace",help="Produce verbose of SALOME/KERNEL", action='store_true') - parser.add_argument("-f","--dump-final", dest ="finalDump", type=str, const='finalDumpState.xml', default="", nargs='?', help="dump final state") - parser.add_argument("-l","--load-state", dest="loadState", type=str, default="", help="Load State from a previous partial execution") - parser.add_argument("-x","--save-xml-schema", dest="saveXMLSchema", type=str, const="saveSchema.xml", nargs='?', default="", help = "dump xml schema") - parser.add_argument("-t","--shutdown", dest = 'shutdown', type=int , default=1, help="Shutdown the schema: 0=no shutdown to 3=full shutdown") - parser.add_argument("--reset", dest = "reset", type=int , default = 0, help="Reset the schema before execution: 0=nothing, 1=reset error nodes to ready state") - parser.add_argument("-z","--donotsqueeze", dest = "donotsqueeze", help = "Desactivate squeeze memory optimization.", action='store_true') - parser.add_argument("-ip","--init-port", dest = 'init_port', type=str, help="Initialisation value of a port, specified as bloc.node.port=value.") - args = parser.parse_args() - args.display = args.display[0] - # - if args.verbose: - setVerbose( args.kerneltrace ) - setVerboseLevel(logging.INFO) - positionVerbosityOfLoggerRegardingState() - # - proc = loadGraph( args.xmlfilename ) - patchGraph( proc, not args.donotsqueeze, args.init_port.split(","), args.saveXMLSchema, args.loadState, args.reset, args.display) - executor = prepareExecution( proc, args.stop, args.dumpErrorFile) - executeGraph( executor, args.xmlfilename, proc, args.dump, args.finalDump, args.display) - destroyElementsGeneratedByExecutionOfGraph( proc, args.shutdown ) diff --git a/src/yacsloader/driver_internal.py b/src/yacsloader/driver_internal.py new file mode 100644 index 000000000..49f8e1e40 --- /dev/null +++ b/src/yacsloader/driver_internal.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 CEA, EDF +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +import salome +import logging + +my_runtime_yacs = None + +def initializeSALOME(): + import SALOMERuntime + global my_runtime_yacs + if my_runtime_yacs: + return + salome.salome_init() + flags = SALOMERuntime.RuntimeSALOME.UsePython + SALOMERuntime.RuntimeSALOME.UseCorba + SALOMERuntime.RuntimeSALOME.UseXml + SALOMERuntime.RuntimeSALOME.UseCpp + SALOMERuntime.RuntimeSALOME.UseSalome + SALOMERuntime.RuntimeSALOME.setRuntime( flags ) + my_runtime_yacs = SALOMERuntime.getSALOMERuntime() + anIOR = salome.orb.object_to_string ( salome.modulcat ) + aCatalog = my_runtime_yacs.loadCatalog( "session", anIOR ) + my_runtime_yacs.addCatalog( aCatalog ) + +def SALOMEInitializationNeeded(func): + def decaratedFunc(*args,**kwargs): + initializeSALOME() + return func(*args,**kwargs) + return decaratedFunc + +@SALOMEInitializationNeeded +def loadGraph( xmlFileName ): + """ + Args: + ----- + xmlFileName : XML file containing YACS schema + + Returns + ------- + + SALOMERuntime.SalomeProc : YACS graph instance + """ + import loader + l=loader.YACSLoader() + p=l.load( xmlFileName ) + return p + +def patchGraph( proc, squeezeMemory, initPorts, xmlSchema, loadStateXmlFile, reset, display): + """ + Args: + ----- + + proc ( SALOMERuntime.SalomeProc ) : YACS Proc instance to be evaluated + squeezeMemory ( bool ) : squeezememory to be activated + initPorts (list) : list of bloc.node.port=value. + xmlSchema (string) : + loadStateXmlFile (string) : file if any of state to be loaded inside proc + reset (int) : + display (int) : + """ + import SALOMERuntime + import loader + def parse_init_port(input): + """ + Returns + ------- + node, port, value + """ + node_port, value = input.split("=") + nodePortSpl = node_port.split(".") + port = nodePortSpl[-1] + node = ".".join( nodePortSpl[:-1] ) + return node,port,value + + if squeezeMemory: + logging.info("SqueezeMemory requested -> update proc") + allNodes = proc.getAllRecursiveNodes() + for node in allNodes: + if isinstance(proc,SALOMERuntime.PythonNode): + node.setSqueezeStatus( True ) + # + for initPort in initPorts: + node,port,value = parse_init_port(initPort) + init_state = proc.setInPortValue(node, port, value) + if init_state != value: + raise RuntimeError(f"Error on initialization of {initPort}") + # + if xmlSchema: + SALOMERuntime.VisitorSaveSalomeSchemaUnsafe(proc,xmlSchema) + pass + # + if loadStateXmlFile: + loader.loadState( proc, loadStateXmlFile ) + if reset > 0: + proc.resetState(reset) + proc.exUpdateState() + # + if display > 0: + proc.writeDotInFile("toto") + +@SALOMEInitializationNeeded +def prepareExecution(proc, isStop, dumpErrorFile): + """ + Returns + ------- + + pilot.ExecutorSwig : Instance of executor + """ + import pilot + ex=pilot.ExecutorSwig() + if isStop: + logging.info(f"Stop has been activated with {dumpErrorFile}") + ex.setStopOnError( dumpErrorFile!="", dumpErrorFile ) + return ex + +@SALOMEInitializationNeeded +def executeGraph( executor, xmlfilename, proc, dump, finalDump, display, shutdown ): + """ + Args: + ----- + + executor (pilot.ExecutorSwig) : Executor in charge of evaluation. + proc ( SALOMERuntime.SalomeProc ) : YACS Proc instance to be evaluated + xmlfilename (string) + dump (int) : time interval between 2 dump state + finalDump ( string ) : filename containing final result of graph, if any. + display (int) : + shutdown (int) : shutdown level + """ + import signal + import SALOMERuntime + def handler(signum, frame): + print('Signal handler called with signal', signum) + proc.cleanNodes() + if finalDump: + SALOMERuntime.schemaSaveStateUnsafe( proc, finalDump ) + if shutdown < 999: + print(100*"shutdown") + proc.shutdown(shutdown) + + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) + dump_thread = None + import pilot + import os + + if dump != 0: + dumpFile = "dumpState_{}".format( os.path.basename(xmlfilename) ) + lockFile = "{}.lock".format( os.path.splitext( os.path.basename(xmlfilename) )[0] ) + dump_thread = SALOMERuntime.ThreadDumpState(proc,dump,dumpFile,lockFile) + dump_thread.start() + + executor.RunPy(proc,display,isPyThread=True,fromscratch=True) # same as RunW but releasing GIL + if proc.getEffectiveState() != pilot.DONE: + raise RuntimeError( proc.getErrorReport() ) + # + if display > 0: + proc.writeDotInFile("titi") + # + if dump_thread: + dump_thread.join() + # + if finalDump: + logging.info(f"Final dump requested : {finalDump}") + SALOMERuntime.schemaSaveStateUnsafe( proc, finalDump ) + +@SALOMEInitializationNeeded +def destroyElementsGeneratedByExecutionOfGraph( proc, shutdown ): + """ + Args: + ----- + + shutdown (int) : shutdown level + + """ + if shutdown < 999: + proc.shutdown(shutdown) + salome.dsm.shutdownScopes() + my_runtime_yacs.fini( False ) + +if __name__ == "__main__": + from salome_utils import positionVerbosityOfLoggerRegardingState,setVerboseLevel,setVerbose + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('xmlfilename',help = "XML file containing YACS schema to be executed") + parser.add_argument("-d", "--display", dest = "display", type=int, default=[0], nargs=1, help="Display dot files: 0=never to 3=very often") + parser.add_argument("-v", "--verbose", dest = "verbose",help="Produce verbose output", action='store_true') + parser.add_argument("-s","--stop-on-error",dest="stop",help="Stop on first error", action='store_true') + parser.add_argument("-e","--dump-on-error",dest="dumpErrorFile", type=str, const='dumpErrorState.xml', default="", nargs='?', help="Stop on first error and dump state") + parser.add_argument("-g","--dump",dest="dump", type=int, const=60, default=0, nargs='?', help="dump state") + parser.add_argument("-kt", "--kerneltrace", dest = "kerneltrace",help="Produce verbose of SALOME/KERNEL", action='store_true') + parser.add_argument("-f","--dump-final", dest ="finalDump", type=str, const='finalDumpState.xml', default="", nargs='?', help="dump final state") + parser.add_argument("-l","--load-state", dest="loadState", type=str, default="", help="Load State from a previous partial execution") + parser.add_argument("-x","--save-xml-schema", dest="saveXMLSchema", type=str, const="saveSchema.xml", nargs='?', default="", help = "dump xml schema") + parser.add_argument("-t","--shutdown", dest = 'shutdown', type=int , default=1, help="Shutdown the schema: 0=no shutdown to 3=full shutdown") + parser.add_argument("-r","--reset", dest = "reset", type=int , default = 0, help="Reset the schema before execution: 0=nothing, 1=reset error nodes to ready state") + parser.add_argument("-i","--init-port", dest = 'init_port', type=str, default ="", help="Initialisation value of a port, specified as bloc.node.port=value.") + parser.add_argument("-z","--donotsqueeze", dest = "donotsqueeze", help = "Desactivate squeeze memory optimization.", action='store_true') + args = parser.parse_args() + args.display = args.display[0] + # + if args.verbose: + setVerbose( args.kerneltrace ) + setVerboseLevel(logging.INFO) + positionVerbosityOfLoggerRegardingState() + # + proc = loadGraph( args.xmlfilename ) + patchGraph( proc, not args.donotsqueeze, [elt for elt in args.init_port.split(",") if elt !=""], args.saveXMLSchema, args.loadState, args.reset, args.display) + executor = prepareExecution( proc, args.stop, args.dumpErrorFile) + # + executeGraph( executor, args.xmlfilename, proc, args.dump, args.finalDump, args.display, args.shutdown) + # + destroyElementsGeneratedByExecutionOfGraph( proc, args.shutdown )