pydefx 9.14.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. mpmcn.py +154 -0
  2. pydefx/__init__.py +32 -0
  3. pydefx/allpurposebuilder.py +56 -0
  4. pydefx/configuration.py +120 -0
  5. pydefx/defaultschemabuilder.py +55 -0
  6. pydefx/localbuilder.py +37 -0
  7. pydefx/localstudy.py +78 -0
  8. pydefx/multijobbuilder.py +33 -0
  9. pydefx/multijobstudy.py +84 -0
  10. pydefx/parameters.py +169 -0
  11. pydefx/plugins/jobexecutor.py +130 -0
  12. pydefx/plugins/lightexecutor.py +40 -0
  13. pydefx/plugins/localexecutor.py +81 -0
  14. pydefx/plugins/mainjob.py +56 -0
  15. pydefx/plugins/pointeval.py +39 -0
  16. pydefx/plugins/srunexecutor.py +87 -0
  17. pydefx/pyscript.py +110 -0
  18. pydefx/pystudy.py +327 -0
  19. pydefx/salome_proxy.py +88 -0
  20. pydefx/sample.py +263 -0
  21. pydefx/samplecsviterator.py +191 -0
  22. pydefx/samplecsvmanager.py +136 -0
  23. pydefx/schemas/idefix_pyschema.xml +106 -0
  24. pydefx/schemas/plugin.py +81 -0
  25. pydefx/slurmbuilder.py +33 -0
  26. pydefx/slurmstudy.py +77 -0
  27. pydefx/studyexception.py +41 -0
  28. pydefx/studyresult.py +54 -0
  29. pydefx-9.14.0.dist-info/METADATA +22 -0
  30. pydefx-9.14.0.dist-info/RECORD +45 -0
  31. pydefx-9.14.0.dist-info/WHEEL +4 -0
  32. salome/bin/salome/test/CTestTestfile.cmake +28 -0
  33. salome/bin/salome/test/cpp/CTestTestfile.cmake +36 -0
  34. salome/bin/salome/test/cpp/SampleTest +0 -0
  35. salome/bin/salome/test/cpp/StudyGeneralTest +0 -0
  36. salome/bin/salome/test/cpp/StudyRestartTest +0 -0
  37. salome/bin/salome/test/pyexample/CTestTestfile.cmake +25 -0
  38. salome/bin/salome/test/pyexample/insitu/insituiterator.py +48 -0
  39. salome/bin/salome/test/pyexample/insitu/insitumanager.py +46 -0
  40. salome/bin/salome/test/pyexample/runUnitTest.sh +26 -0
  41. salome/bin/salome/test/pyexample/test_default.py +79 -0
  42. salome/bin/salome/test/pyexample/test_insitu.py +60 -0
  43. salome/bin/salome/test/pyexample/test_mpmcn.py +40 -0
  44. salome/bin/salome/test/pyexample/test_prescript.py +52 -0
  45. salome/bin/salome/test/pyexample/test_ydefx_base.py +79 -0
pydefx/parameters.py ADDED
@@ -0,0 +1,169 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2019-2024 EDF
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ #
18
+ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19
+ #
20
+ import tempfile
21
+ from . import salome_proxy
22
+ from . import configuration
23
+
24
+ class Parameters:
25
+ def __init__(self, resource="localhost",
26
+ nb_branches=None, salome_parameters=None):
27
+ if salome_parameters is None :
28
+ job_params = salome_proxy.createSalomeParameters()
29
+ job_params.job_type = "yacs_file"
30
+ job_params.resource_required.name = resource
31
+ job_params.job_name = "idefix_job"
32
+ job_params.wckey = configuration.defaultWckey(resource)
33
+ job_params.work_directory = configuration.defaultWorkingDir(resource)
34
+ if nb_branches is None:
35
+ nb_branches = configuration.defaultNbBranches(resource)
36
+ job_params.resource_required.nb_proc = nb_branches
37
+ self.nb_branches = nb_branches
38
+ self.salome_parameters = job_params
39
+ else:
40
+ if nb_branches is None:
41
+ nb_branches = salome_parameters.resource_required.nb_proc
42
+ self.nb_branches = nb_branches
43
+ self.salome_parameters = salome_parameters
44
+
45
+ def configureResource(self, resource):
46
+ self.salome_parameters.resource_required.name = resource
47
+ self.salome_parameters.work_directory = configuration.defaultWorkingDir(
48
+ resource)
49
+ nb_branches = configuration.defaultNbBranches(resource)
50
+ self.salome_parameters.resource_required.nb_proc = nb_branches
51
+ self.nb_branches = nb_branches
52
+ self.salome_parameters.wckey = configuration.defaultWckey(resource)
53
+
54
+ def createResultDirectory(self, result_base_dir):
55
+ self.salome_parameters.result_directory = configuration.newResultDirectory(
56
+ result_base_dir)
57
+
58
+ def createTmpResultDirectory(self):
59
+ self.salome_parameters.result_directory = configuration.newResultDirectory(
60
+ tempfile.gettempdir())
61
+
62
+ # Specific deep copy function is needed because the default one does not work
63
+ # for swig objects, when we are in no salome session mode.
64
+ def __deepcopy__(self, memo):
65
+ cls = self.__class__
66
+ newobj = cls.__new__(cls)
67
+ newobj.nb_branches = self.nb_branches
68
+ newobj.salome_parameters = salome_proxy.createSalomeParameters()
69
+ newobj.salome_parameters.job_name = self.salome_parameters.job_name
70
+ newobj.salome_parameters.job_type = self.salome_parameters.job_type
71
+ newobj.salome_parameters.job_file = self.salome_parameters.job_file
72
+ newobj.salome_parameters.pre_command = self.salome_parameters.pre_command
73
+ newobj.salome_parameters.env_file = self.salome_parameters.env_file
74
+ newobj.salome_parameters.in_files = list(self.salome_parameters.in_files)
75
+ newobj.salome_parameters.out_files = list(self.salome_parameters.out_files)
76
+ newobj.salome_parameters.work_directory = self.salome_parameters.work_directory
77
+ newobj.salome_parameters.local_directory = self.salome_parameters.local_directory
78
+ newobj.salome_parameters.result_directory = self.salome_parameters.result_directory
79
+ newobj.salome_parameters.maximum_duration = self.salome_parameters.maximum_duration
80
+ newobj.salome_parameters.queue = self.salome_parameters.queue
81
+ newobj.salome_parameters.partition = self.salome_parameters.partition
82
+ newobj.salome_parameters.exclusive = self.salome_parameters.exclusive
83
+ newobj.salome_parameters.mem_per_cpu = self.salome_parameters.mem_per_cpu
84
+ newobj.salome_parameters.wckey = self.salome_parameters.wckey
85
+ newobj.salome_parameters.extra_params = self.salome_parameters.extra_params
86
+ #newobj.salome_parameters.specific_parameters = self.salome_parameters.specific_parameters
87
+ newobj.salome_parameters.resource_required.name = self.salome_parameters.resource_required.name
88
+ newobj.salome_parameters.resource_required.hostname = self.salome_parameters.resource_required.hostname
89
+ newobj.salome_parameters.resource_required.can_launch_batch_jobs = self.salome_parameters.resource_required.can_launch_batch_jobs
90
+ newobj.salome_parameters.resource_required.can_run_containers = self.salome_parameters.resource_required.can_run_containers
91
+ newobj.salome_parameters.resource_required.OS = self.salome_parameters.resource_required.OS
92
+ newobj.salome_parameters.resource_required.nb_proc = self.salome_parameters.resource_required.nb_proc
93
+ newobj.salome_parameters.resource_required.mem_mb = self.salome_parameters.resource_required.mem_mb
94
+ newobj.salome_parameters.resource_required.cpu_clock = self.salome_parameters.resource_required.cpu_clock
95
+ newobj.salome_parameters.resource_required.nb_node = self.salome_parameters.resource_required.nb_node
96
+ newobj.salome_parameters.resource_required.nb_proc_per_node = self.salome_parameters.resource_required.nb_proc_per_node
97
+
98
+ return newobj
99
+
100
+ def dumpDict(self):
101
+ """Create a dictionary with all the properties.
102
+ Can be used for serialization with json."""
103
+ newdict = {
104
+ "nb_branches" : self.nb_branches,
105
+ "salome_parameters" : {
106
+ "job_name" : self.salome_parameters.job_name,
107
+ "job_type" : self.salome_parameters.job_type,
108
+ "job_file" : self.salome_parameters.job_file,
109
+ "pre_command" : self.salome_parameters.pre_command,
110
+ "env_file" : self.salome_parameters.env_file,
111
+ "in_files" : list(self.salome_parameters.in_files),
112
+ "out_files" : list(self.salome_parameters.out_files),
113
+ "work_directory" : self.salome_parameters.work_directory,
114
+ "local_directory" : self.salome_parameters.local_directory,
115
+ "result_directory" : self.salome_parameters.result_directory,
116
+ "maximum_duration" : self.salome_parameters.maximum_duration,
117
+ "queue" : self.salome_parameters.queue,
118
+ "partition" : self.salome_parameters.partition,
119
+ "exclusive" : self.salome_parameters.exclusive,
120
+ "mem_per_cpu" : self.salome_parameters.mem_per_cpu,
121
+ "wckey" : self.salome_parameters.wckey,
122
+ "extra_params" : self.salome_parameters.extra_params,
123
+ #"specific_parameters" : str(self.salome_parameters.specific_parameters),
124
+ "resource_required" : {
125
+ "name" : self.salome_parameters.resource_required.name,
126
+ "hostname" : self.salome_parameters.resource_required.hostname,
127
+ "can_launch_batch_jobs" : self.salome_parameters.resource_required.can_launch_batch_jobs,
128
+ "can_run_containers" : self.salome_parameters.resource_required.can_run_containers,
129
+ "OS" : self.salome_parameters.resource_required.OS,
130
+ "nb_proc" : self.salome_parameters.resource_required.nb_proc,
131
+ "mem_mb" : self.salome_parameters.resource_required.mem_mb,
132
+ "cpu_clock" : self.salome_parameters.resource_required.cpu_clock,
133
+ "nb_node" : self.salome_parameters.resource_required.nb_node,
134
+ "nb_proc_per_node" : self.salome_parameters.resource_required.nb_proc_per_node
135
+ }
136
+ }
137
+ }
138
+ return newdict
139
+
140
+ def loadDict(self, dico):
141
+ self.nb_branches = dico["nb_branches"]
142
+ #self.salome_parameters = salome_proxy.createSalomeParameters()
143
+ self.salome_parameters.job_name = dico["salome_parameters"]["job_name"]
144
+ self.salome_parameters.job_type = dico["salome_parameters"]["job_type"]
145
+ self.salome_parameters.job_file = dico["salome_parameters"]["job_file"]
146
+ self.salome_parameters.pre_command = dico["salome_parameters"]["pre_command"]
147
+ self.salome_parameters.env_file = dico["salome_parameters"]["env_file"]
148
+ self.salome_parameters.in_files = dico["salome_parameters"]["in_files"]
149
+ self.salome_parameters.out_files = dico["salome_parameters"]["out_files"]
150
+ self.salome_parameters.work_directory = dico["salome_parameters"]["work_directory"]
151
+ self.salome_parameters.local_directory = dico["salome_parameters"]["local_directory"]
152
+ self.salome_parameters.result_directory = dico["salome_parameters"]["result_directory"]
153
+ self.salome_parameters.maximum_duration = dico["salome_parameters"]["maximum_duration"]
154
+ self.salome_parameters.queue = dico["salome_parameters"]["queue"]
155
+ self.salome_parameters.partition = dico["salome_parameters"]["partition"]
156
+ self.salome_parameters.exclusive = dico["salome_parameters"]["exclusive"]
157
+ self.salome_parameters.mem_per_cpu = dico["salome_parameters"]["mem_per_cpu"]
158
+ self.salome_parameters.wckey = dico["salome_parameters"]["wckey"]
159
+ self.salome_parameters.extra_params = dico["salome_parameters"]["extra_params"]
160
+ self.salome_parameters.resource_required.name = dico["salome_parameters"]["resource_required"]["name"]
161
+ self.salome_parameters.resource_required.hostname = dico["salome_parameters"]["resource_required"]["hostname"]
162
+ self.salome_parameters.resource_required.can_launch_batch_jobs = dico["salome_parameters"]["resource_required"]["can_launch_batch_jobs"]
163
+ self.salome_parameters.resource_required.can_run_containers = dico["salome_parameters"]["resource_required"]["can_run_containers"]
164
+ self.salome_parameters.resource_required.OS = dico["salome_parameters"]["resource_required"]["OS"]
165
+ self.salome_parameters.resource_required.nb_proc = dico["salome_parameters"]["resource_required"]["nb_proc"]
166
+ self.salome_parameters.resource_required.mem_mb = dico["salome_parameters"]["resource_required"]["mem_mb"]
167
+ self.salome_parameters.resource_required.cpu_clock = dico["salome_parameters"]["resource_required"]["cpu_clock"]
168
+ self.salome_parameters.resource_required.nb_node = dico["salome_parameters"]["resource_required"]["nb_node"]
169
+ self.salome_parameters.resource_required.nb_proc_per_node = dico["salome_parameters"]["resource_required"]["nb_proc_per_node"]
@@ -0,0 +1,130 @@
1
+ import pydefx
2
+ import os
3
+ import pickle
4
+ import time
5
+ import traceback
6
+
7
+ pydefx.forceNoSalomeServers()
8
+ class Context:
9
+ def __init__(self):
10
+ self.launcher = pydefx.salome_proxy.getLauncher() # getLauncher()
11
+ pass
12
+
13
+ class JobExecutor:
14
+ def __init__(self, config):
15
+ self.config = config
16
+
17
+ def initialize(self):
18
+ """ This is executed before the first evaluation.
19
+ Put here global processing needed by all the evaluations like the copy of
20
+ commun files.
21
+ """
22
+ # Copy the commun files to the root work directory
23
+ params = pydefx.Parameters() # global parameters
24
+ params.loadDict(self.config["params"])
25
+ # use a fake empty command.
26
+ # Using launcher to copy some files on the remote file system,
27
+ # without launching a job.
28
+ command = os.path.join(os.getcwd(), "empty.sh")
29
+ open(command, "w").close()
30
+ params.salome_parameters.job_file = command
31
+ params.salome_parameters.job_type = "command"
32
+ study_module = os.path.join(os.getcwd(), self.config["studymodule"]+".py")
33
+ infiles = list(params.salome_parameters.in_files)
34
+ params.salome_parameters.in_files = infiles + [study_module]
35
+ launcher = pydefx.salome_proxy.getLauncher()
36
+ job_id = launcher.createJob(params.salome_parameters)
37
+ launcher.exportInputFiles(job_id)
38
+
39
+ def evaluate(self, idx, point):
40
+ """ This is executed for every point to be evaluated.
41
+ """
42
+ context = Context()
43
+ error = None
44
+ out_values = None
45
+ try:
46
+ self.prepare(idx, point, context)
47
+ if self.noRunFound(idx, point, context):
48
+ self.runjob(idx, point, context)
49
+ error, out_values = self.getResult(context)
50
+ except Exception as e:
51
+ error = str(e)
52
+ traceback.print_exc()
53
+ return error, out_values
54
+
55
+ def prepare(self, idx, point, context):
56
+ """
57
+ Define local and remote work directory.
58
+ Define job script.
59
+ """
60
+ context.params = pydefx.Parameters()
61
+ context.params.loadDict(self.config["params"])
62
+ salome_parameters = context.params.salome_parameters
63
+ root_local_dir = salome_parameters.result_directory
64
+ root_remote_dir = salome_parameters.work_directory
65
+ input_files = [] # commun files are already copied to the root directory
66
+ point_name = "job_"+str(idx)
67
+ context.local_dir = os.path.join(root_local_dir, point_name)
68
+ point_remote_dir = os.path.join(root_remote_dir, point_name)
69
+ if not os.path.exists(context.local_dir):
70
+ os.mkdir(context.local_dir)
71
+ # export the point to a file
72
+ data_file_name = "idefixdata.csv"
73
+ data_file_path = os.path.join(context.local_dir, data_file_name)
74
+ with open(data_file_path, "w") as f:
75
+ # explicit dict convertion is needed for compatibility between python versions
76
+ f.write(repr(dict(point)))
77
+ input_files.append(data_file_path)
78
+
79
+ #command_path = os.path.join(root_local_dir, "command.py")
80
+ #salome_parameters.job_type = "command_salome"
81
+ #salome_parameters.job_file = command_path
82
+
83
+ salome_parameters.in_files = input_files
84
+ salome_parameters.out_files = ["idefixresult.txt", "idefixerror.txt"]
85
+ salome_parameters.work_directory = point_remote_dir
86
+ salome_parameters.result_directory = context.local_dir
87
+
88
+ def noRunFound(self, idx, point, context):
89
+ return True
90
+
91
+ def runjob(self, idx, point, context):
92
+ """
93
+ Create, launch and wait for the end of the job.
94
+ """
95
+ import random
96
+ sleep_delay = random.randint(5, 15) #10
97
+ #launcher = pydefx.salome_proxy.getLauncher()
98
+ launcher = context.launcher
99
+ context.job_id = launcher.createJob(context.params.salome_parameters)
100
+ launcher.launchJob(context.job_id)
101
+ jobState = launcher.getJobState(context.job_id)
102
+ while jobState=="QUEUED" or jobState=="IN_PROCESS" or jobState=="RUNNING" :
103
+ time.sleep(sleep_delay)
104
+ jobState = launcher.getJobState(context.job_id)
105
+
106
+ def getResult(self, context):
107
+ """
108
+ Check the job state, fetch the result file.
109
+ """
110
+ #launcher = pydefx.salome_proxy.getLauncher()
111
+ launcher = context.launcher
112
+ jobState = launcher.getJobState(context.job_id)
113
+ error=""
114
+ result=None
115
+ if jobState != "FINISHED" :
116
+ error = "Job has not finished correctly."
117
+ else:
118
+ launcher.getJobResults(context.job_id, "")
119
+ error_file = os.path.join(context.local_dir, "idefixerror.txt")
120
+ result_file = os.path.join(context.local_dir, "idefixresult.txt")
121
+ with open(error_file, "r") as f:
122
+ error = f.read()
123
+ with open(result_file, "r") as f:
124
+ result_str = f.read()
125
+ result = eval(result_str)
126
+
127
+ return error, result
128
+
129
+ def createExecutor(config):
130
+ return JobExecutor(config)
@@ -0,0 +1,40 @@
1
+ import os
2
+ import pickle
3
+ import time
4
+ import traceback
5
+ import subprocess
6
+
7
+ class Context:
8
+ def __init__(self):
9
+ #self.launcher = pydefx.salome_proxy.getLauncher() # getLauncher()
10
+ pass
11
+
12
+ class JobExecutor:
13
+ def __init__(self, config):
14
+ self.config = config
15
+
16
+ def initialize(self):
17
+ """ This is executed before the first evaluation.
18
+ Put here global processing needed by all the evaluations like the copy of
19
+ commun files.
20
+ """
21
+ pass
22
+
23
+ def evaluate(self, idx, point):
24
+ """ This is executed for every point to be evaluated.
25
+ """
26
+ context = Context()
27
+ error = None
28
+ out_values = None
29
+ studymodule=self.config["studymodule"]
30
+ import importlib
31
+ try:
32
+ idefixstudy=importlib.import_module(studymodule)
33
+ out_values=idefixstudy._exec(**point)
34
+ except Exception as e:
35
+ error=str(e)
36
+ traceback.print_exc()
37
+ return error, out_values
38
+
39
+ def createExecutor(config):
40
+ return JobExecutor(config)
@@ -0,0 +1,81 @@
1
+ import os
2
+ import pickle
3
+ import time
4
+ import traceback
5
+ import subprocess
6
+
7
+ class Context:
8
+ def __init__(self):
9
+ pass
10
+
11
+ class JobExecutor:
12
+ def __init__(self, config):
13
+ self.config = config
14
+
15
+ def initialize(self):
16
+ """ This is executed before the first evaluation.
17
+ Put here global processing needed by all the evaluations like the copy of
18
+ commun files.
19
+ """
20
+ pointeval = os.path.join(os.getcwd(), "pointeval.py")
21
+ os.chmod(pointeval, 0o755)
22
+
23
+ def evaluate(self, idx, point):
24
+ """ This is executed for every point to be evaluated.
25
+ """
26
+ context = Context()
27
+ error = None
28
+ out_values = None
29
+ try:
30
+ self.prepare(idx, point, context)
31
+ if self.noRunFound(idx, point, context):
32
+ self.runjob(idx, point, context)
33
+ error, out_values = self.getResult(context)
34
+ except Exception as e:
35
+ error = str(e)
36
+ traceback.print_exc()
37
+ return error, out_values
38
+
39
+ def prepare(self, idx, point, context):
40
+ """
41
+ Define local and remote work directory.
42
+ Define job script.
43
+ """
44
+ root_dir = os.getcwd()
45
+ point_name = "job_"+str(idx)
46
+ context.local_dir = os.path.join(root_dir, point_name)
47
+ if not os.path.exists(context.local_dir):
48
+ os.mkdir(context.local_dir)
49
+ # export the point to a file
50
+ data_file_name = "idefixdata.csv"
51
+ data_file_path = os.path.join(context.local_dir, data_file_name)
52
+ with open(data_file_path, "w") as f:
53
+ # explicit dict convertion is needed for compatibility between python versions
54
+ f.write(repr(dict(point)))
55
+
56
+ def noRunFound(self, idx, point, context):
57
+ return True
58
+
59
+ def runjob(self, idx, point, context):
60
+ """
61
+ Create, launch and wait for the end of the job.
62
+ """
63
+ pointeval = os.path.join(os.getcwd(), "pointeval.py")
64
+ return_code = subprocess.check_call(pointeval, shell=True, cwd=context.local_dir)
65
+
66
+ def getResult(self, context):
67
+ """
68
+ Check the job state, fetch the result file.
69
+ """
70
+ error_file = os.path.join(context.local_dir, "idefixerror.txt")
71
+ result_file = os.path.join(context.local_dir, "idefixresult.txt")
72
+ with open(error_file, "r") as f:
73
+ error = f.read()
74
+ with open(result_file, "r") as f:
75
+ result_str = f.read()
76
+ result = eval(result_str)
77
+
78
+ return error, result
79
+
80
+ def createExecutor(config):
81
+ return JobExecutor(config)
@@ -0,0 +1,56 @@
1
+ #! /usr/bin/env python3
2
+ import json
3
+ import importlib
4
+ from multiprocessing import Pool
5
+ import traceback
6
+
7
+ class StartJob:
8
+ def __init__(self, executor):
9
+ self.executor = executor
10
+
11
+ def __call__(self, idx, in_values):
12
+ error=None
13
+ out_values=None
14
+ try:
15
+ error, out_values = self.executor.evaluate(idx, in_values)
16
+ except Exception as e:
17
+ error=str(e)
18
+ traceback.print_exc()
19
+ return idx, in_values, out_values, error
20
+
21
+ class TerminateJob:
22
+ def __init__(self, manager):
23
+ self.manager = manager
24
+
25
+ def __call__(self, result):
26
+ # without try statement we may experience deadlock in case of error.
27
+ try:
28
+ idx, in_values, out_values, error = result
29
+ if not error:
30
+ error = None
31
+ self.manager.addResult(idx, in_values, out_values, error)
32
+ except Exception as e:
33
+ traceback.print_exc()
34
+
35
+ if __name__ == '__main__':
36
+ with open("idefixconfig.json", "r") as f:
37
+ config = json.load(f)
38
+ plugin_module = importlib.import_module(config["plugin"])
39
+ executor = plugin_module.createExecutor(config)
40
+ # global initialization - commun work for every evaluation.
41
+ executor.initialize()
42
+
43
+ itModuleName = config["sampleIterator"]
44
+ itModule = importlib.import_module(itModuleName)
45
+ sampleManager = itModule.SampleIterator()
46
+ sampleManager.writeHeaders()
47
+
48
+ nbbranches=config["nbbranches"]
49
+ pool = Pool(nbbranches)
50
+ runPoint = StartJob(executor)
51
+ endOk = TerminateJob(sampleManager)
52
+ for point in sampleManager:
53
+ pool.apply_async(runPoint, point, callback=endOk)
54
+ pool.close()
55
+ pool.join()
56
+ sampleManager.terminate()
@@ -0,0 +1,39 @@
1
+ #! /usr/bin/env python3
2
+ import traceback
3
+ import os
4
+
5
+ data_file_name = "idefixdata.csv"
6
+ study_module = "idefixstudy.py"
7
+ error_result = "idefixerror.txt"
8
+ value_result = "idefixresult.txt"
9
+ traceback_result = "idefixtraceback.txt"
10
+
11
+ with open(data_file_name, "r") as f:
12
+ values = f.read()
13
+ inputvals = eval(values)
14
+
15
+ error=""
16
+ result=None
17
+ old_dir = os.getcwd()
18
+
19
+ try:
20
+ os.chdir("..") # go to commun root directory
21
+ with open(study_module, "r") as study_file:
22
+ study_string = study_file.read()
23
+ exec(study_string)
24
+ result = _exec(**inputvals)
25
+ except Exception as e:
26
+ error=str(e)
27
+ if not error :
28
+ error = "Exception " + repr(e)
29
+ os.chdir(old_dir) # back to the current case job directory
30
+ with open(traceback_result, "w") as f:
31
+ traceback.print_exc(file=f)
32
+
33
+ os.chdir(old_dir) # back to the current case job directory
34
+
35
+ with open(error_result, "w") as f:
36
+ f.write(error)
37
+
38
+ with open(value_result, "w") as f:
39
+ f.write(repr(result))
@@ -0,0 +1,87 @@
1
+ import os
2
+ import pickle
3
+ import time
4
+ import traceback
5
+ import subprocess
6
+
7
+ class Context:
8
+ def __init__(self):
9
+ #self.launcher = pydefx.salome_proxy.getLauncher() # getLauncher()
10
+ pass
11
+
12
+ class JobExecutor:
13
+ def __init__(self, config):
14
+ self.config = config
15
+
16
+ def initialize(self):
17
+ """
18
+ Execute prescript.
19
+ """
20
+ pointeval = os.path.join(os.getcwd(), "pointeval.py")
21
+ os.chmod(pointeval, 0o755)
22
+
23
+ def evaluate(self, idx, point):
24
+ """ This is executed for every point to be evaluated.
25
+ """
26
+ context = Context()
27
+ error = None
28
+ out_values = None
29
+ try:
30
+ self.prepare(idx, point, context)
31
+ if self.noRunFound(idx, point, context):
32
+ self.runjob(idx, point, context)
33
+ error, out_values = self.getResult(context)
34
+ except Exception as e:
35
+ error = str(e)
36
+ traceback.print_exc()
37
+ return error, out_values
38
+
39
+ def prepare(self, idx, point, context):
40
+ """
41
+ Define local and remote work directory.
42
+ Define job script.
43
+ """
44
+ root_dir = os.getcwd()
45
+ point_name = "job_"+str(idx)
46
+ context.local_dir = os.path.join(root_dir, point_name)
47
+ if not os.path.exists(context.local_dir):
48
+ os.mkdir(context.local_dir)
49
+ # export the point to a file
50
+ data_file_name = "idefixdata.csv"
51
+ data_file_path = os.path.join(context.local_dir, data_file_name)
52
+ with open(data_file_path, "w") as f:
53
+ # explicit dict convertion is needed for compatibility between python versions
54
+ f.write(repr(dict(point)))
55
+
56
+ def noRunFound(self, idx, point, context):
57
+ return True
58
+
59
+ def runjob(self, idx, point, context):
60
+ """
61
+ Create, launch and wait for the end of the job.
62
+ """
63
+ # srun
64
+ ntasks = self.config["tasksPerEval"]
65
+ pointeval = os.path.join(os.getcwd(), "pointeval.py")
66
+ command = "srun --ntasks={} --nodes=1 --chdir={} {} ".format(
67
+ str(ntasks),
68
+ context.local_dir,
69
+ pointeval)
70
+ return_code = subprocess.call(command, shell=True)
71
+
72
+ def getResult(self, context):
73
+ """
74
+ Check the job state, fetch the result file.
75
+ """
76
+ error_file = os.path.join(context.local_dir, "idefixerror.txt")
77
+ result_file = os.path.join(context.local_dir, "idefixresult.txt")
78
+ with open(error_file, "r") as f:
79
+ error = f.read()
80
+ with open(result_file, "r") as f:
81
+ result_str = f.read()
82
+ result = eval(result_str)
83
+
84
+ return error, result
85
+
86
+ def createExecutor(config):
87
+ return JobExecutor(config)