]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
Diverses améliorations pour la gestion et le lancement des incertitudes
authorEric Fayolle <eric.fayolle@edf.fr>
Thu, 1 Sep 2022 16:11:57 +0000 (18:11 +0200)
committerEric Fayolle <eric.fayolle@edf.fr>
Thu, 1 Sep 2022 16:11:57 +0000 (18:11 +0200)
generator/generator_UQ.py
generator/post_csv_rn.py
generator/textePersalys.py

index e709a3d68d3452bebafcc9ba90a20cfade646e3f..40627a1d56815de4a7f15b0892ca7115a6ae5752 100644 (file)
@@ -41,7 +41,7 @@ from .textePersalys import optionalResultTaylor, optionalPrintResultTaylor
 from .textePersalys import centralTendencyMC, resultMC
 from .textePersalys import critereArretMC, advancedParameterMC
 from .textePersalys import optionalResultMC, optionalPrintResultMC
-from .textePersalys import yacsJobParameters
+from .textePersalys import yacsJobParameters, yacsJobClusterParameters, yacsJobClusterMultiJob
 
 def entryPoint():
     """
@@ -88,7 +88,7 @@ class UQGenerator(PythonGenerator):
 
     def creeNomsFichiers(self,fichier):
         print ('creeNomsFichiers', fichier)
-        self.cheminFichierComm=os.path.dirname(fichier)
+        self.cheminFichierComm=os.path.abspath(os.path.dirname(fichier))
         if fichier.endswith('.comm'):
             self.fichierSansSuffixe=os.path.basename(fichier[:-5])
             if self.fichierSansSuffixe.endswith('_UQ'):
@@ -161,6 +161,7 @@ class UQGenerator(PythonGenerator):
                 self.nomsDesVariablesInput.append(mc.variableDeterministe.nom)
             self.mcIncertains.append(mc.variableDeterministe)
         sectionOutput = etapeIncertitude.getChildOrChildInBloc('Output')[0]
+        self.ScriptPosttraitement = sectionOutput.getChildOrChildInBloc('ScriptPosttraitement').valeur
         self.chaineDesVariablesInput=self.chaineDesVariablesInput[0:-2]
 
         sectionPropagation = etapeIncertitude.getChildOrChildInBloc('Propagation')[0]
@@ -231,15 +232,22 @@ class UQGenerator(PythonGenerator):
         self.NbDeBranches = sectionExecution.getChildOrChildInBloc('NbDeBranches').valeur
         if sectionExecution.getChildOrChildInBloc('ExecutionMode') != None :
             self.ExecutionMode = sectionExecution.getChildOrChildInBloc('ExecutionMode').valeur
-            self.NbOfProcs = sectionExecution.getChildOrChildInBloc('NbOfProcs').valeur
             self.JobName = sectionExecution.getChildOrChildInBloc('JobName').valeur
             self.ResourceName = sectionExecution.getChildOrChildInBloc('ResourceName').valeur
             self.Login = sectionExecution.getChildOrChildInBloc('Login').valeur
             self.WorkDirectory = sectionExecution.getChildOrChildInBloc('WorkDirectory').valeur
             self.ResultDirectory = sectionExecution.getChildOrChildInBloc('ResultDirectory').valeur
-            MultiJobStudy=sectionExecution.getChildOrChildInBloc('MultiJobStudy')
+            self.ScriptDeLancement = sectionExecution.getChildOrChildInBloc('ScriptDeLancement').valeur
+            NbOfProcs = sectionExecution.getChildOrChildInBloc('NbOfProcs')   # None si 'desktop', vérification à faire ds jobmanager
+            MultiJobStudy=sectionExecution.getChildOrChildInBloc('MultiJobStudy')  # None si 'desktop'
+            if (NbOfProcs != None):
+                self.NbOfProcs = NbOfProcs.valeur
+            else:
+                self.NbOfProcs = None
             if (MultiJobStudy != None):
                 self.MultiJobStudy = MultiJobStudy.valeur
+            else:
+                self.MultiJobStudy = None
             self.creeScriptPersalys()
           #else : 
           # TODO : creer ici le script URANIE
@@ -283,7 +291,7 @@ class UQGenerator(PythonGenerator):
         def getStrInitList(l):
             return getStrVarList( map(lambda x:'self.{} = {}'.format(x,x),l), '\n'+2*self.indent1 )
         def getStrReplaceVarList(l):
-            return getStrVarList( map(lambda x:"'@{}@': repr(self.{})".format(x,x), l), ',' )
+            return getStrVarList( map(lambda x:"'@ {} @': repr(self.{})".format(x,x), l), ',' )
         def getStrSelfVarList(l):
             return getStrVarList( map(lambda x:'self.{}'.format(x),l), ',' )
         
@@ -300,7 +308,10 @@ class UQGenerator(PythonGenerator):
             chaineInitDesVariablesInput = getStrInitList(self.nomsDesVariablesInput),
             commFileUQBalise = self.fichierUQBalise,
             commFileUQComm = self.fichierUQComm,
-            nproc = self.NbOfProcs,
+            nproc = self.NbOfProcs, #En local le nombre de procs est inutile
+                                                   #sauf si lancement mpi externe au script applicatif
+                                                   # auquel cas != NbOfTasks du jobmanager car
+                                                   # on ne compte pas les threads 
             replaceDataList = getStrReplaceVarList(self.nomsDesVariablesInput)
         )
 
@@ -378,19 +389,30 @@ class UQGenerator(PythonGenerator):
         inFiles.append(os.path.join(self.cheminFichierComm,pyFile))
         pyFile = self.fichierUQBalise
         inFiles.append(os.path.join(self.cheminFichierComm,pyFile))
-        scriptFile = "ib_test.sh"
-        inFiles.append(os.path.join(self.cheminFichierComm,scriptFile))
-        postFile = "post_csv.py"
-        inFiles.append(os.path.join(os.getcwd(),postFile))
+        scriptFile = os.path.abspath(self.ScriptDeLancement )
+        inFiles.append(scriptFile)
+        postFile = os.path.abspath(self.ScriptPosttraitement )
+        inFiles.append(postFile)
+
+        if (self.ExecutionMode == 'cluster'):
+           txtYacsJobClusterParameters=yacsJobClusterParameters.format(
+               nprocs = self.NbOfProcs,
+               wckey = wckey
+           )
+        else:
+           txtYacsJobClusterParameters=""
+        
         txtYacsJobParameters=yacsJobParameters.format(
             nomEtude = self.JobName,
             workDirectory = self.WorkDirectory,
             resultDirectory = self.ResultDirectory,
             resourceName = self.ResourceName,
-            nprocs = self.NbOfProcs,
-            wckey = wckey,
+            nbBranches = self.NbDeBranches,
             inFiles = repr(inFiles)
         )
+        txtYacsJobParameters+=txtYacsJobClusterParameters
+        if ( self.MultiJobStudy != None):
+            txtYacsJobParameters+= yacsJobClusterMultiJob
        
         self.txtScriptPersalys += mainPersalys.format(
             nomEtude=nomEtude,
index 057e638600e64ed20d2cd0abd485b6f275968702..e3ad0685dfb549cec51cf23a2538697c7fd26aaf 100644 (file)
@@ -90,79 +90,9 @@ def get_result_from_csv(variableName:str, functionList, filename:str=None, delim
              print(sys.stderr,"The transient duration name {} differs from the file's header one {}".format(transientName, header_transient_name))
              return -1 #TODO Exception ?
     
-    date_value_array=np.loadtxt(file_csv, delimiter = delimiter, skiprows = 1)[:,1:3]
+    date_value_array=np.loadtxt(filename, delimiter = delimiter, skiprows = 1)[:,1:3]
     valList=[]
     for func in functionList:
          valList.append(func(date_value_array))
     return valList
 
-def get_result_from_csv_v0(variableName:str, function, filename:str=None, delimiter=','):
-    from csv import reader
-    
-    #ex: file_csv = "Fuel temperature@Thermalhydraulics@MAX.csv"
-    if filename == None: filename = variableName+'.csv'
-    
-    with open(filename, "r") as csv_file:
-        csv_reader = reader(csv_file, delimiter=delimiter)
-        header = next(csv_reader)
-        header_variable_name=header[-1]
-        if header_variable_name != variableName:
-            print(sys.stderr,"The variable name {} differs from the file's header one {}".format(variableName, header_variable_name))
-            return -1 #TODO Exception ? 
-        # print("Header:")
-        # print(", ".join(header))
-        # print("Values:")
-        # for row in csv_reader:
-        #     print(", ".join(row))
-    return function(csv_reader)[-1]
-
-# import csv
-
-# #fich_csv = "Execution_APOLLO3/Neutronic power@Neutronics@SUM.csv"
-# fich_csv = "Fuel temperature@Thermalhydraulics@MAX.csv"
-# file_csv = open(fich_csv)
-
-# fich_sort = 'point.res'
-
-# csvReader = csv.reader(file_csv, delimiter=',')
-# header = []
-# header = next(csvReader)
-# # Pour APOLLO3 ?
-# # if len(header) != 2:
-# #     print("Correction des headers contenant des espaces")
-# #     tmp = header
-# #     header = []
-# #     header.append(tmp[1])
-# #     header.append(tmp[-2] + " " + tmp[-1])
-# print(header)
-
-# rows = []
-# for row in csvReader:
-#     ligne = []
-#     for elem in row:
-#         if elem != '':
-#             ligne.append(float(elem))
-#     rows.append(ligne)
-#     #print(ligne)
-# print(rows)
-
-# # reperage des valeurs min et max
-# point_min = rows[0]
-# point_max = rows[0]
-# for point in rows:
-#    if point[2] < point_min[2]:
-#        point_min = point
-#    if point[2] > point_max[2]:
-#        point_max = point
-
-# # impression dans un fichier res de sortie
-# print("point min")
-# print(point_min)
-# print("point max")
-# print(point_max)
-
-# txt = "# time_min min time_max max\n"
-# txt += "{0} {1} {2} {3}".format(point_min[0],point_min[1],point_max[0],point_max[1])
-
-# file_sort = open(fich_sort,'w')
-# file_sort.write(txt)
index 21f69cabe6fa8dc3a6038e24c4ea490acef9a2ec..5a1e49d881d1c6f4c4c83da59dc831c802a4042e 100644 (file)
@@ -9,8 +9,8 @@ headerScriptPersalys = """#! /usr/bin/env python3
 #  --------------------------------------------------------------------------
 # Script Eficas genere pour lancement Etude Probabiliste
 # ---------------------------------------------------------------------------
-# Utilisation standalone avec salome :
-# salome shell -- python3 mon_fichier.py
+# Exemple d'utilisation standalone avec salome :
+# salome start -k -t python3 mon_fichier_uq_genere.py
 
 # Chargement du module systeme
 import sys
@@ -88,26 +88,34 @@ class Study:
         #section spécifique au code de calcul
         comm_file_uq_balise = '{commFileUQBalise}'
 
-        self.nproc = {nproc}
+        self.nproc = {nproc} # La présence de cette variable dépend 
+                                          # du mode de lancement MPI
+                                          # S'il est géré par le script appelé à partir du MDD, il est inutile de le stocker 
         self.comm_file_uq_balise = os.path.join(self.workdir, comm_file_uq_balise)
         shutil.copy(comm_file_uq_balise, self.comm_file_uq_balise)
 
         self.comm_file_uq_comm = os.path.join(self.workdir, '{commFileUQComm}')
         replace_data(self.comm_file_uq_balise, {{ {replaceDataList}  }} , self.comm_file_uq_comm)
+        #TODO: Lancer la validation du fichier généré avant tout lancement
 
         pass
 
     def get_result_from_csv(self,postProcessedVar, aggregationFctList):
-       from post_csv import get_result_from_csv
+       from post_csv_rn import get_result_from_csv
         #Fonctions a implementer dans un fichier post_csv pour définir
        #comment l'aggrégation des valeurs peut se faire
-       from post_csv import vInitialTime, vHalfTime, vFinalTime, vMean, vSum, vMin, vMax
+       from post_csv_rn import vInitialTime, vHalfTime, vFinalTime, vMean, vSum, vMin, vMax
        print('--------------------------------------- 4 ---------------------------------------')
-       return get_result_from_csv(postProcessedVar, aggregationFctList)
+       savdir=os.getcwd()
+       os.chdir(self.workdir)
+       results = get_result_from_csv(postProcessedVar, aggregationFctList)
+       os.chdir(savdir)
+       return  results
 
     def run_case(self):
         print('--------------------------------------- 5 ---------------------------------------')
         #os.chdir(self.workdir)
+        # Si lancement mpi externe à ib_test.sh il faut utiliser self.nproc : mpiexec -n self.nproc ib_test.sh
         o,e,c = self.do_sh(command="ib_test.sh", execdir=self.workdir)
         if o != None : print('o.decode() : ',o.decode())
         if e != None : print('e.decode() : ',e.decode())
@@ -126,7 +134,7 @@ getResultCall="""    {variableOutputList} = study.get_result_from_csv( '{nomVarP
 # ------------------------
 fonctionPersalys = """
 def _exec({chaineDesVariablesInput}):
-    from post_csv import vInitialTime, vHalfTime, vFinalTime, vMean, vSum, vMin, vMax
+    from post_csv_rn import vInitialTime, vHalfTime, vFinalTime, vMean, vSum, vMin, vMax
 
     print('--------------------------------------- 00 ---------------------------------------')
 
@@ -286,15 +294,31 @@ optionalPrintResultMC={
 # ##nputSample=designOfExperiment.getInputSample()
 # ##computeQuantile=inputSample.computeQuantile(0.95)
 
+
+#En local le nombre de procs est inutile
 yacsJobParameters="""
+    yacsPhysicalModel.jobParameters().salome_parameters.resource_required.name = '{resourceName}'
     yacsPhysicalModel.jobParameters().salome_parameters.job_name = '{nomEtude}'
     yacsPhysicalModel.jobParameters().salome_parameters.work_directory = '{workDirectory}'
     yacsPhysicalModel.jobParameters().salome_parameters.result_directory = '{resultDirectory}'
-    yacsPhysicalModel.jobParameters().salome_parameters.resource_required.name = '{resourceName}'
+    yacsPhysicalModel.jobParameters().salome_parameters.in_files = {inFiles} # Chemins des fichiers locaux à copier dans work_directory
+    yacsPhysicalModel.jobParameters().nb_branches = {nbBranches} # nombre de jobs parallèles
+"""
+
+# Le nombre de procs du job manager est uniquement utile pour les clusters
+yacsJobClusterParameters="""
     yacsPhysicalModel.jobParameters().salome_parameters.resource_required.nb_proc = {nprocs}
     yacsPhysicalModel.jobParameters().salome_parameters.wckey = '{wckey}'
-    yacsPhysicalModel.jobParameters().salome_parameters.in_files = {inFiles} # Chemins des fichiers locaux à copier dans work_directory
-    yacsPhysicalModel.jobParameters().nb_branches = {nprocs} # nombre de jobs parallèles
+"""
+
+# Ces 3 lignes permettent de modifier le mode d'évaluation par défaut qui est
+# d'avoir toutes les évaluations dans un seul job.
+# Ici <nb_branches> jobs seront crées dynamiquement pour lancer chaque évaluation
+#  chaque job demandera la réservation de nprocs processus.
+yacsJobClusterMultiJob="""
+import pydefx
+multiJobModel = pydefx.MultiJobStudy() # mode un job par évaluation
+yacsPhysicalModel.setJobModel(multiJobModel)
 """
 
 yacsJobParametersRef="""