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.
- mpmcn.py +154 -0
- pydefx/__init__.py +32 -0
- pydefx/allpurposebuilder.py +56 -0
- pydefx/configuration.py +120 -0
- pydefx/defaultschemabuilder.py +55 -0
- pydefx/localbuilder.py +37 -0
- pydefx/localstudy.py +78 -0
- pydefx/multijobbuilder.py +33 -0
- pydefx/multijobstudy.py +84 -0
- pydefx/parameters.py +169 -0
- pydefx/plugins/jobexecutor.py +130 -0
- pydefx/plugins/lightexecutor.py +40 -0
- pydefx/plugins/localexecutor.py +81 -0
- pydefx/plugins/mainjob.py +56 -0
- pydefx/plugins/pointeval.py +39 -0
- pydefx/plugins/srunexecutor.py +87 -0
- pydefx/pyscript.py +110 -0
- pydefx/pystudy.py +327 -0
- pydefx/salome_proxy.py +88 -0
- pydefx/sample.py +263 -0
- pydefx/samplecsviterator.py +191 -0
- pydefx/samplecsvmanager.py +136 -0
- pydefx/schemas/idefix_pyschema.xml +106 -0
- pydefx/schemas/plugin.py +81 -0
- pydefx/slurmbuilder.py +33 -0
- pydefx/slurmstudy.py +77 -0
- pydefx/studyexception.py +41 -0
- pydefx/studyresult.py +54 -0
- pydefx-9.14.0.dist-info/METADATA +22 -0
- pydefx-9.14.0.dist-info/RECORD +45 -0
- pydefx-9.14.0.dist-info/WHEEL +4 -0
- salome/bin/salome/test/CTestTestfile.cmake +28 -0
- salome/bin/salome/test/cpp/CTestTestfile.cmake +36 -0
- salome/bin/salome/test/cpp/SampleTest +0 -0
- salome/bin/salome/test/cpp/StudyGeneralTest +0 -0
- salome/bin/salome/test/cpp/StudyRestartTest +0 -0
- salome/bin/salome/test/pyexample/CTestTestfile.cmake +25 -0
- salome/bin/salome/test/pyexample/insitu/insituiterator.py +48 -0
- salome/bin/salome/test/pyexample/insitu/insitumanager.py +46 -0
- salome/bin/salome/test/pyexample/runUnitTest.sh +26 -0
- salome/bin/salome/test/pyexample/test_default.py +79 -0
- salome/bin/salome/test/pyexample/test_insitu.py +60 -0
- salome/bin/salome/test/pyexample/test_mpmcn.py +40 -0
- salome/bin/salome/test/pyexample/test_prescript.py +52 -0
- 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)
|