wrfrun 0.1.9__py3-none-any.whl → 0.3.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.
- wrfrun/__init__.py +8 -3
- wrfrun/cli.py +74 -31
- wrfrun/core/__init__.py +27 -10
- wrfrun/core/_config.py +308 -0
- wrfrun/core/_constant.py +236 -0
- wrfrun/core/_exec_db.py +105 -0
- wrfrun/core/_namelist.py +287 -0
- wrfrun/core/_record.py +178 -0
- wrfrun/core/_resource.py +172 -0
- wrfrun/core/base.py +136 -380
- wrfrun/core/core.py +196 -0
- wrfrun/core/error.py +35 -2
- wrfrun/core/replay.py +10 -96
- wrfrun/core/server.py +74 -32
- wrfrun/core/type.py +171 -0
- wrfrun/data.py +312 -149
- wrfrun/extension/goos_sst/__init__.py +2 -2
- wrfrun/extension/goos_sst/core.py +9 -14
- wrfrun/extension/goos_sst/res/__init__.py +0 -1
- wrfrun/extension/goos_sst/utils.py +50 -44
- wrfrun/extension/littler/core.py +105 -88
- wrfrun/extension/utils.py +5 -3
- wrfrun/log.py +117 -0
- wrfrun/model/__init__.py +11 -7
- wrfrun/model/constants.py +52 -0
- wrfrun/model/palm/__init__.py +30 -0
- wrfrun/model/palm/core.py +145 -0
- wrfrun/model/palm/namelist.py +33 -0
- wrfrun/model/plot.py +99 -114
- wrfrun/model/type.py +116 -0
- wrfrun/model/utils.py +9 -19
- wrfrun/model/wrf/__init__.py +4 -9
- wrfrun/model/wrf/core.py +262 -165
- wrfrun/model/wrf/exec_wrap.py +13 -12
- wrfrun/model/wrf/geodata.py +116 -99
- wrfrun/model/wrf/log.py +103 -0
- wrfrun/model/wrf/namelist.py +92 -76
- wrfrun/model/wrf/plot.py +102 -0
- wrfrun/model/wrf/scheme.py +108 -52
- wrfrun/model/wrf/utils.py +39 -24
- wrfrun/model/wrf/vtable.py +42 -7
- wrfrun/plot/__init__.py +20 -0
- wrfrun/plot/wps.py +90 -73
- wrfrun/res/__init__.py +115 -5
- wrfrun/res/config/config.template.toml +15 -0
- wrfrun/res/config/palm.template.toml +23 -0
- wrfrun/run.py +121 -77
- wrfrun/scheduler/__init__.py +1 -0
- wrfrun/scheduler/lsf.py +4 -1
- wrfrun/scheduler/pbs.py +4 -1
- wrfrun/scheduler/script.py +19 -5
- wrfrun/scheduler/slurm.py +4 -1
- wrfrun/scheduler/utils.py +14 -2
- wrfrun/utils.py +88 -199
- wrfrun/workspace/__init__.py +8 -5
- wrfrun/workspace/core.py +21 -11
- wrfrun/workspace/palm.py +137 -0
- wrfrun/workspace/wrf.py +59 -14
- wrfrun-0.3.0.dist-info/METADATA +240 -0
- wrfrun-0.3.0.dist-info/RECORD +78 -0
- wrfrun/core/config.py +0 -767
- wrfrun/model/base.py +0 -14
- wrfrun-0.1.9.dist-info/METADATA +0 -68
- wrfrun-0.1.9.dist-info/RECORD +0 -62
- {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
- {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
wrfrun/run.py
CHANGED
|
@@ -1,18 +1,58 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
wrfrun.run
|
|
3
|
+
##########
|
|
4
|
+
|
|
5
|
+
.. autosummary::
|
|
6
|
+
:toctree: generated/
|
|
7
|
+
|
|
8
|
+
confirm_model_area
|
|
9
|
+
WRFRun
|
|
10
|
+
|
|
11
|
+
This module defines class and function used by ``wrfrun`` to run simulations.
|
|
12
|
+
|
|
13
|
+
Use ``WRFRun`` to control simulations better
|
|
14
|
+
********************************************
|
|
15
|
+
|
|
16
|
+
:class:`WRFRun` provides many useful features:
|
|
17
|
+
|
|
18
|
+
* Set log files.
|
|
19
|
+
* Load config and namelist from files.
|
|
20
|
+
* Clear and prepare ``wrfrun`` workspace.
|
|
21
|
+
* Download background data from ERA5.
|
|
22
|
+
* Commit simulation to job schedulers.
|
|
23
|
+
* Record and replay simulations.
|
|
24
|
+
* Start socket server.
|
|
25
|
+
|
|
26
|
+
Though you can do same things manually, why bother yourself while :class:`WRFRun` is easy to use:
|
|
27
|
+
|
|
28
|
+
.. code-block:: python
|
|
29
|
+
:caption: main.py
|
|
30
|
+
|
|
31
|
+
from wrfrun.run import WRFRun
|
|
32
|
+
|
|
33
|
+
config_file = "./config.toml"
|
|
34
|
+
|
|
35
|
+
with WRFRun(config_file) as wrf_run:
|
|
36
|
+
# do something
|
|
37
|
+
...
|
|
3
38
|
"""
|
|
4
39
|
|
|
5
40
|
import sys
|
|
6
41
|
import threading
|
|
42
|
+
from collections.abc import Generator
|
|
7
43
|
from os.path import abspath, dirname
|
|
8
44
|
from typing import Optional, Tuple, Union
|
|
9
45
|
|
|
10
|
-
from .core import
|
|
46
|
+
from wrfrun.core.base import ExecutableBase
|
|
47
|
+
|
|
48
|
+
from .core import WRFRunBasicError, WRFRunServer, WRFRunServerHandler, call_subprocess, replay_config_generator, stop_server
|
|
49
|
+
from .core._record import ExecutableRecorder
|
|
50
|
+
from .core.core import WRFRUN
|
|
11
51
|
from .data import prepare_wps_input_data
|
|
52
|
+
from .log import logger, logger_add_file_handler
|
|
12
53
|
from .model import clear_model_logs, generate_domain_area
|
|
13
54
|
from .scheduler import in_job_scheduler, prepare_scheduler_script
|
|
14
|
-
from .
|
|
15
|
-
from .workspace import prepare_workspace, check_workspace
|
|
55
|
+
from .workspace import check_workspace, prepare_workspace
|
|
16
56
|
|
|
17
57
|
|
|
18
58
|
def confirm_model_area():
|
|
@@ -20,17 +60,17 @@ def confirm_model_area():
|
|
|
20
60
|
Ask user to check domain area.
|
|
21
61
|
|
|
22
62
|
"""
|
|
23
|
-
generate_domain_area()
|
|
63
|
+
flag = generate_domain_area()
|
|
24
64
|
|
|
25
|
-
if not in_job_scheduler():
|
|
65
|
+
if not in_job_scheduler() and flag:
|
|
26
66
|
# ask user
|
|
27
|
-
logger.warning(
|
|
67
|
+
logger.warning("Check the domain image, is it right?")
|
|
28
68
|
answer = input("Is it right? [y/N]: ")
|
|
29
69
|
|
|
30
70
|
answer = answer.lower()
|
|
31
71
|
|
|
32
72
|
if answer not in ["y", "yes"]:
|
|
33
|
-
logger.error(
|
|
73
|
+
logger.error("Change your domain setting and run again")
|
|
34
74
|
exit(1)
|
|
35
75
|
|
|
36
76
|
|
|
@@ -38,24 +78,38 @@ class WRFRun:
|
|
|
38
78
|
"""
|
|
39
79
|
``WRFRun`` is a context class to use all functions in ``wrfrun`` package.
|
|
40
80
|
"""
|
|
41
|
-
_instance = None
|
|
42
|
-
_initialized = False
|
|
43
81
|
|
|
44
|
-
def __init__(
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
config_file: str,
|
|
85
|
+
init_workspace=True,
|
|
86
|
+
start_server=False,
|
|
87
|
+
submit_job=False,
|
|
88
|
+
prepare_wps_data=False,
|
|
89
|
+
wps_data_area: Optional[Tuple[int, int, int, int]] = None,
|
|
90
|
+
skip_domain_confirm=False,
|
|
91
|
+
):
|
|
45
92
|
"""
|
|
46
|
-
|
|
93
|
+
Context class to achieve some goals before and after running WRF,
|
|
94
|
+
like saving a copy of config file, starting and closing WRFRunServer.
|
|
47
95
|
|
|
48
96
|
:param config_file: ``wrfrun`` config file's path.
|
|
97
|
+
:type config_file: str
|
|
49
98
|
:param init_workspace: If True, clean old files in workspace and re-create it.
|
|
99
|
+
:type init_workspace: bool
|
|
50
100
|
:param start_server: Whether to start WRFRunServer, defaults to True.
|
|
101
|
+
:type start_server: bool
|
|
51
102
|
:param submit_job: If commit this task to the PBS system, defaults to True.
|
|
103
|
+
:type submit_job: bool
|
|
52
104
|
:param prepare_wps_data: If True, download input datas for WPS first.
|
|
53
|
-
:
|
|
105
|
+
:type prepare_wps_data: bool
|
|
106
|
+
:param wps_data_area: If ``prepare_wps_data==True``, you need to give the area range of input data,
|
|
107
|
+
so download function can download data from ERA5.
|
|
108
|
+
:type wps_data_area: tuple
|
|
109
|
+
:param skip_domain_confirm: If ``True``, skip domain confirm.
|
|
110
|
+
:type skip_domain_confirm: bool
|
|
54
111
|
:return:
|
|
55
112
|
"""
|
|
56
|
-
if self._initialized:
|
|
57
|
-
return
|
|
58
|
-
|
|
59
113
|
# variables for running WRFRunServer
|
|
60
114
|
self._start_server = start_server
|
|
61
115
|
self._wrfrun_server: Union[WRFRunServer, None] = None
|
|
@@ -67,56 +121,51 @@ class WRFRun:
|
|
|
67
121
|
self._init_workspace = init_workspace
|
|
68
122
|
self._prepare_wps_data = prepare_wps_data
|
|
69
123
|
self._wps_data_area = wps_data_area
|
|
124
|
+
self._skip_domain_confirm = skip_domain_confirm
|
|
70
125
|
self._entry_file_path = abspath(sys.argv[0])
|
|
71
126
|
self._entry_file_dir_path = dirname(self._entry_file_path)
|
|
72
127
|
self._replay_configs = None
|
|
73
128
|
|
|
74
|
-
# make sure we can read the config file,
|
|
129
|
+
# make sure we can read the config file,
|
|
130
|
+
# because sometimes the user may run the Python script in a different path.
|
|
75
131
|
abs_config_path = f"{self._entry_file_dir_path}/{config_file}"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
self._record_output_path = None
|
|
79
|
-
self._record_include_data = False
|
|
80
|
-
self._WRFRUNReplay = ExecConfigRecorder
|
|
81
|
-
|
|
82
|
-
self._initialized = True
|
|
132
|
+
WRFRUN.init_wrfrun_config(abs_config_path)
|
|
83
133
|
|
|
84
|
-
|
|
85
|
-
if cls._instance is None:
|
|
86
|
-
cls._instance = super().__new__(cls)
|
|
87
|
-
|
|
88
|
-
return cls._instance
|
|
134
|
+
self._WRFRUNReplay: Optional[ExecutableRecorder] = None
|
|
89
135
|
|
|
90
136
|
def __enter__(self):
|
|
91
137
|
# check workspace
|
|
92
138
|
if not check_workspace():
|
|
93
|
-
logger.info(
|
|
139
|
+
logger.info("Force re-create workspace because it is broken.")
|
|
94
140
|
self._init_workspace = True
|
|
95
141
|
|
|
96
142
|
# here is the condition we need to initialize workspace:
|
|
97
|
-
# 1. submit_job = True and init_workspace = True,
|
|
143
|
+
# 1. submit_job = True and init_workspace = True,
|
|
144
|
+
# do prepare_workspace before submitting the task to job scheduler.
|
|
98
145
|
# 2. submit_job = False and init_workspace = True, do prepare_workspace.
|
|
99
146
|
if self._submit_job and not in_job_scheduler():
|
|
100
147
|
if self._init_workspace:
|
|
101
148
|
prepare_workspace()
|
|
102
149
|
|
|
103
150
|
# ask user before commit the task
|
|
104
|
-
|
|
151
|
+
if not self._skip_domain_confirm:
|
|
152
|
+
confirm_model_area()
|
|
105
153
|
|
|
106
154
|
prepare_scheduler_script(self._entry_file_path)
|
|
107
155
|
|
|
108
156
|
call_subprocess(["qsub", f"{self._entry_file_dir_path}/run.sh"])
|
|
109
|
-
logger.info(
|
|
157
|
+
logger.info("Work has been submit to PBS system")
|
|
110
158
|
exit(0)
|
|
111
159
|
|
|
112
160
|
elif not self._submit_job:
|
|
113
161
|
if self._init_workspace:
|
|
114
162
|
prepare_workspace()
|
|
115
163
|
|
|
116
|
-
|
|
164
|
+
if not self._skip_domain_confirm:
|
|
165
|
+
confirm_model_area()
|
|
117
166
|
|
|
118
167
|
# save a copy of config to the output path
|
|
119
|
-
|
|
168
|
+
WRFRUN.config.save_wrfrun_config(f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/config.toml")
|
|
120
169
|
|
|
121
170
|
# check if we need to start a server
|
|
122
171
|
if self._start_server:
|
|
@@ -124,14 +173,14 @@ class WRFRun:
|
|
|
124
173
|
self._start_wrfrun_server()
|
|
125
174
|
|
|
126
175
|
# change status
|
|
127
|
-
|
|
176
|
+
WRFRUN.config.set_wrfrun_context(True)
|
|
128
177
|
|
|
129
|
-
logger_add_file_handler(
|
|
178
|
+
logger_add_file_handler(WRFRUN.config.get_log_path())
|
|
130
179
|
|
|
131
180
|
if self._prepare_wps_data:
|
|
132
181
|
if self._wps_data_area is None:
|
|
133
|
-
logger.error(
|
|
134
|
-
raise ValueError(
|
|
182
|
+
logger.error("If you want wrfrun preparing data, you need to give `wps_data_area`")
|
|
183
|
+
raise ValueError("If you want wrfrun preparing data, you need to give `wps_data_area`")
|
|
135
184
|
else:
|
|
136
185
|
prepare_wps_input_data(self._wps_data_area)
|
|
137
186
|
|
|
@@ -142,14 +191,14 @@ class WRFRun:
|
|
|
142
191
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
143
192
|
# stop thread if needed
|
|
144
193
|
if self._start_server:
|
|
145
|
-
stop_server(self._ip, self._port)
|
|
194
|
+
stop_server(self._ip, self._port) # type: ignore
|
|
146
195
|
|
|
147
|
-
if exc_type is None and
|
|
196
|
+
if exc_type is None and self._WRFRUNReplay is not None:
|
|
148
197
|
self._WRFRUNReplay.export_replay_file()
|
|
149
198
|
self._WRFRUNReplay.clear_records()
|
|
150
199
|
|
|
151
200
|
# change status
|
|
152
|
-
|
|
201
|
+
WRFRUN.config.set_wrfrun_context(False)
|
|
153
202
|
|
|
154
203
|
clear_model_logs()
|
|
155
204
|
|
|
@@ -157,14 +206,14 @@ class WRFRun:
|
|
|
157
206
|
|
|
158
207
|
def _start_wrfrun_server(self):
|
|
159
208
|
"""
|
|
160
|
-
Start a WRFRunServer.
|
|
209
|
+
Start a WRFRunServer to report simulation progress.
|
|
161
210
|
"""
|
|
162
211
|
# read ip and port settings from config
|
|
163
|
-
socket_ip, socket_port =
|
|
212
|
+
socket_ip, socket_port = WRFRUN.config.get_socket_server_config()
|
|
164
213
|
|
|
165
214
|
# get simulate settings
|
|
166
|
-
start_date =
|
|
167
|
-
end_date =
|
|
215
|
+
start_date = WRFRUN.config.get_model_config("wrf")["time"]["start_date"]
|
|
216
|
+
end_date = WRFRUN.config.get_model_config("wrf")["time"]["end_date"]
|
|
168
217
|
|
|
169
218
|
start_date = start_date[0] if isinstance(start_date, list) else start_date
|
|
170
219
|
end_date = end_date[0] if isinstance(end_date, list) else end_date
|
|
@@ -174,55 +223,46 @@ class WRFRun:
|
|
|
174
223
|
simulate_seconds = time_delta.days * 24 * 60 * 60 + time_delta.seconds
|
|
175
224
|
|
|
176
225
|
# init server
|
|
177
|
-
self._wrfrun_server = WRFRunServer(
|
|
178
|
-
start_date, simulate_seconds, (socket_ip, socket_port),
|
|
179
|
-
WRFRunServerHandler
|
|
180
|
-
)
|
|
226
|
+
self._wrfrun_server = WRFRunServer(start_date, simulate_seconds, (socket_ip, socket_port), WRFRunServerHandler)
|
|
181
227
|
|
|
182
228
|
# get ip and port from instance, because the port may change
|
|
183
|
-
self._ip, self._port = self._wrfrun_server.server_address
|
|
229
|
+
self._ip, self._port = self._wrfrun_server.server_address # type: ignore
|
|
184
230
|
|
|
185
231
|
logger.info(f"Start socket server on {self._ip}:{self._port}")
|
|
186
232
|
|
|
187
233
|
# start server thread
|
|
188
|
-
self._wrfrun_server_thread = threading.Thread(
|
|
189
|
-
target=self._wrfrun_server.serve_forever
|
|
190
|
-
)
|
|
234
|
+
self._wrfrun_server_thread = threading.Thread(target=self._wrfrun_server.serve_forever)
|
|
191
235
|
self._wrfrun_server_thread.daemon = True
|
|
192
236
|
self._wrfrun_server_thread.start()
|
|
193
237
|
|
|
194
238
|
def record_simulation(self, output_path: str, include_data=False):
|
|
195
239
|
"""
|
|
196
|
-
|
|
240
|
+
Start to record simulation. Simulation parts before this function call will not be recorded.
|
|
197
241
|
|
|
198
242
|
:param output_path: Output file path.
|
|
199
243
|
:type output_path: str
|
|
200
244
|
:param include_data: If includes data.
|
|
201
245
|
:type include_data: bool
|
|
202
|
-
:return:
|
|
203
|
-
:rtype:
|
|
204
246
|
"""
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
self._WRFRUNReplay =
|
|
247
|
+
WRFRUN.init_recorder(output_path, include_data)
|
|
248
|
+
WRFRUN.config.IS_RECORDING = True
|
|
249
|
+
self._WRFRUNReplay = WRFRUN.record
|
|
208
250
|
|
|
209
251
|
def replay_simulation(self, replay_file: str):
|
|
210
252
|
"""
|
|
211
|
-
Replay the simulation
|
|
253
|
+
Replay the whole simulation with settings from the ``replay_file``.
|
|
212
254
|
|
|
213
|
-
:param replay_file:
|
|
214
|
-
:type replay_file:
|
|
215
|
-
:return:
|
|
216
|
-
:rtype:
|
|
255
|
+
:param replay_file: ``.replay`` file path.
|
|
256
|
+
:type replay_file: str
|
|
217
257
|
"""
|
|
218
|
-
|
|
258
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
219
259
|
|
|
220
260
|
if self._replay_configs is not None:
|
|
221
261
|
del self._replay_configs
|
|
222
262
|
|
|
223
263
|
self._replay_configs = replay_config_generator(replay_file)
|
|
224
264
|
|
|
225
|
-
|
|
265
|
+
WRFRUN.config.IS_IN_REPLAY = True
|
|
226
266
|
|
|
227
267
|
try:
|
|
228
268
|
for _, executable in self._replay_configs:
|
|
@@ -231,30 +271,34 @@ class WRFRun:
|
|
|
231
271
|
except WRFRunBasicError:
|
|
232
272
|
logger.error("Failed to replay the simulation")
|
|
233
273
|
|
|
234
|
-
|
|
274
|
+
WRFRUN.config.IS_IN_REPLAY = False
|
|
235
275
|
|
|
236
|
-
def replay_executables(self, replay_file: str):
|
|
276
|
+
def replay_executables(self, replay_file: str) -> Generator[tuple[str, ExecutableBase], None, None]:
|
|
237
277
|
"""
|
|
238
|
-
|
|
278
|
+
Read settings from the ``replay_file``, and yield ``Executable`` name and instance in order.
|
|
239
279
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
280
|
+
>>> with WRFRun("config.toml") as wrf_run:
|
|
281
|
+
>>> for name, _exec in wrf_run.replay_executables("example.replay"):
|
|
282
|
+
>>> _exec()
|
|
283
|
+
|
|
284
|
+
:param replay_file: ``.replay`` file path.
|
|
285
|
+
:type replay_file: str
|
|
286
|
+
:return: Generator that yields ``Executable`` name and instance.
|
|
287
|
+
:rtype: Generator[tuple[str, ExecutableBase]]
|
|
244
288
|
"""
|
|
245
|
-
|
|
289
|
+
WRFRUN.config.check_wrfrun_context(True)
|
|
246
290
|
|
|
247
291
|
if self._replay_configs is not None:
|
|
248
292
|
del self._replay_configs
|
|
249
293
|
|
|
250
294
|
self._replay_configs = replay_config_generator(replay_file)
|
|
251
295
|
|
|
252
|
-
|
|
296
|
+
WRFRUN.config.IS_IN_REPLAY = True
|
|
253
297
|
|
|
254
298
|
for name, executable in self._replay_configs:
|
|
255
299
|
yield name, executable
|
|
256
300
|
|
|
257
|
-
|
|
301
|
+
WRFRUN.config.IS_IN_REPLAY = False
|
|
258
302
|
|
|
259
303
|
|
|
260
304
|
__all__ = ["WRFRun"]
|
wrfrun/scheduler/__init__.py
CHANGED
wrfrun/scheduler/lsf.py
CHANGED
|
@@ -10,8 +10,9 @@ Scheduler interface for LSF system.
|
|
|
10
10
|
lsf_generate_settings
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from wrfrun.core import
|
|
13
|
+
from wrfrun.core import WRFRUN
|
|
14
14
|
from wrfrun.res import SCHEDULER_LSF_TEMPLATE
|
|
15
|
+
|
|
15
16
|
from .utils import get_core_num
|
|
16
17
|
|
|
17
18
|
|
|
@@ -22,6 +23,8 @@ def lsf_generate_settings(scheduler_config: dict) -> str:
|
|
|
22
23
|
:return: Generated settings.
|
|
23
24
|
:rtype: str
|
|
24
25
|
"""
|
|
26
|
+
WRFRUNConfig = WRFRUN.config
|
|
27
|
+
|
|
25
28
|
# get log path and job scheduler config
|
|
26
29
|
log_path = WRFRUNConfig.get_log_path()
|
|
27
30
|
|
wrfrun/scheduler/pbs.py
CHANGED
|
@@ -10,8 +10,9 @@ Scheduler interface for PBS system.
|
|
|
10
10
|
pbs_generate_settings
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from wrfrun.core import
|
|
13
|
+
from wrfrun.core import WRFRUN
|
|
14
14
|
from wrfrun.res import SCHEDULER_PBS_TEMPLATE
|
|
15
|
+
|
|
15
16
|
from .utils import get_core_num
|
|
16
17
|
|
|
17
18
|
|
|
@@ -22,6 +23,8 @@ def pbs_generate_settings(scheduler_config: dict) -> str:
|
|
|
22
23
|
:return: Generated settings.
|
|
23
24
|
:rtype: str
|
|
24
25
|
"""
|
|
26
|
+
WRFRUNConfig = WRFRUN.config
|
|
27
|
+
|
|
25
28
|
# get log path and job scheduler config
|
|
26
29
|
log_path = WRFRUNConfig.get_log_path()
|
|
27
30
|
|
wrfrun/scheduler/script.py
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.scheduler.script
|
|
3
|
+
#######################
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
Function to prepare bash script to commit job to scheduler.
|
|
6
|
+
|
|
7
|
+
.. autosummary::
|
|
8
|
+
:toctree: generated/
|
|
9
|
+
|
|
10
|
+
prepare_scheduler_script
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from os.path import abspath, dirname, exists
|
|
14
|
+
|
|
15
|
+
from wrfrun.core import WRFRUN
|
|
16
|
+
from wrfrun.log import logger
|
|
4
17
|
from wrfrun.res import RUN_SH_TEMPLATE
|
|
5
|
-
|
|
18
|
+
|
|
6
19
|
from .lsf import lsf_generate_settings
|
|
7
20
|
from .pbs import pbs_generate_settings
|
|
8
21
|
from .slurm import slurm_generate_settings
|
|
@@ -15,6 +28,8 @@ def prepare_scheduler_script(main_file_path: str):
|
|
|
15
28
|
:param main_file_path: Path of the main entry file.
|
|
16
29
|
:type main_file_path: str
|
|
17
30
|
"""
|
|
31
|
+
WRFRUNConfig = WRFRUN.config
|
|
32
|
+
|
|
18
33
|
# check main file path
|
|
19
34
|
if not exists(main_file_path):
|
|
20
35
|
logger.error(f"Wrong path of main entry file: {main_file_path}")
|
|
@@ -41,7 +56,7 @@ def prepare_scheduler_script(main_file_path: str):
|
|
|
41
56
|
raise ValueError(f"Unknown scheduler name: {scheduler_configs['job_scheduler']}")
|
|
42
57
|
|
|
43
58
|
# generate environment settings
|
|
44
|
-
env_settings =
|
|
59
|
+
env_settings = "export WRFRUN_ENV_JOB_SCHEDULER=1\n"
|
|
45
60
|
if len(scheduler_configs["env_settings"]) > 0:
|
|
46
61
|
for key in scheduler_configs["env_settings"]:
|
|
47
62
|
env_settings += f"export {key}={scheduler_configs['env_settings'][key]}\n"
|
|
@@ -52,7 +67,6 @@ def prepare_scheduler_script(main_file_path: str):
|
|
|
52
67
|
# generate shell script
|
|
53
68
|
shell_template_path = WRFRUNConfig.parse_resource_uri(RUN_SH_TEMPLATE)
|
|
54
69
|
with open(f"{dir_path}/run.sh", "w") as f:
|
|
55
|
-
|
|
56
70
|
with open(shell_template_path, "r") as f_template:
|
|
57
71
|
template = f_template.read()
|
|
58
72
|
|
wrfrun/scheduler/slurm.py
CHANGED
|
@@ -10,8 +10,9 @@ Scheduler interface for Slurm system.
|
|
|
10
10
|
slurm_generate_settings
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from wrfrun.core import
|
|
13
|
+
from wrfrun.core import WRFRUN
|
|
14
14
|
from wrfrun.res import SCHEDULER_SLURM_TEMPLATE
|
|
15
|
+
|
|
15
16
|
from .utils import get_core_num
|
|
16
17
|
|
|
17
18
|
|
|
@@ -22,6 +23,8 @@ def slurm_generate_settings(scheduler_config: dict) -> str:
|
|
|
22
23
|
:return: Generated settings.
|
|
23
24
|
:rtype: str
|
|
24
25
|
"""
|
|
26
|
+
WRFRUNConfig = WRFRUN.config
|
|
27
|
+
|
|
25
28
|
# get log path and job scheduler config
|
|
26
29
|
log_path = WRFRUNConfig.get_log_path()
|
|
27
30
|
|
wrfrun/scheduler/utils.py
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.scheduler.utils
|
|
3
|
+
######################
|
|
4
|
+
|
|
5
|
+
Utility functions used by ``wrfrun`` scheduler part.
|
|
6
|
+
|
|
7
|
+
.. autosummary::
|
|
8
|
+
:toctree: generated/
|
|
9
|
+
|
|
10
|
+
get_core_num
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from wrfrun.core import WRFRUN
|
|
2
14
|
|
|
3
15
|
|
|
4
16
|
def get_core_num() -> int:
|
|
@@ -8,7 +20,7 @@ def get_core_num() -> int:
|
|
|
8
20
|
:return: Core number.
|
|
9
21
|
:rtype: int
|
|
10
22
|
"""
|
|
11
|
-
return
|
|
23
|
+
return WRFRUN.config["core_num"]
|
|
12
24
|
|
|
13
25
|
|
|
14
26
|
__all__ = ["get_core_num"]
|