Salome HOME
[EDF29576] : ready for clean SIGINT implementation
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 26 Feb 2024 08:20:09 +0000 (09:20 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Mon, 26 Feb 2024 08:20:09 +0000 (09:20 +0100)
src/yacsloader/CMakeLists.txt
src/yacsloader/driver [new file with mode: 0644]
src/yacsloader/driver.py [deleted file]
src/yacsloader/driver_internal.py [new file with mode: 0644]

index 3a8cb97e5cb29e1e0d71bece893bb22295378fb2..d42b1e33db2c44e7154eed755061fc779b6fea2b 100644 (file)
@@ -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 (file)
index 0000000..b7e6e89
--- /dev/null
@@ -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<string>) : 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 (file)
index 4b55a6f..0000000
+++ /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<string>) : 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 (file)
index 0000000..49f8e1e
--- /dev/null
@@ -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<string>) : 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 )