7
7
import param
8
8
import panel as pn
9
9
10
- from .file_browser import HpcFileBrowser , get_js_loading_code
10
+ from .file_browser import HpcFileBrowser , create_file_browser , get_js_loading_code , FileSelector
11
11
from .utils import HpcBase , HpcConfigurable
12
12
from ..uit import QUEUES
13
13
from ..pbs_script import NODE_TYPES , factors , PbsScript
14
14
from ..job import PbsJob
15
15
16
+
16
17
logger = logging .getLogger (__name__ )
17
18
18
19
19
20
class PbsScriptInputs (HpcBase ):
20
- hpc_subproject = param .Selector (default = None , label = "HPC Subproject" , precedence = 3 )
21
- subproject_usage = param .DataFrame (precedence = 3.1 )
22
- workdir = param .String (default = "" , precedence = 4 )
23
- node_type = param .Selector (default = "" , objects = [], label = "Node Type" , precedence = 5 )
24
- nodes = param .Integer (default = 1 , bounds = (1 , 1000 ), precedence = 5.1 )
25
- processes_per_node = param .Selector (default = 1 , objects = [], label = "Processes per Node" , precedence = 5.2 )
26
- wall_time = param .String (default = "01:00:00" , label = "Wall Time" , precedence = 6 )
21
+ hpc_subproject = param .Selector (
22
+ default = None ,
23
+ label = "HPC Subproject" ,
24
+ precedence = 3 ,
25
+ doc = "The resource allocation code that will be used when submitting this job." ,
26
+ )
27
+ subproject_usage = param .DataFrame (precedence = 3.1 , doc = "Usage details about your available subproject allocations." )
28
+ node_type = param .Selector (
29
+ default = "" , objects = [], label = "Node Type" , precedence = 5 , doc = "Type of node on which this job will be run."
30
+ )
31
+ nodes = param .Integer (
32
+ default = 1 ,
33
+ bounds = (1 , 1000 ),
34
+ precedence = 5.1 ,
35
+ doc = (
36
+ "Number of nodes to request for the job.\n \n "
37
+ "**Note:** for array jobs, the number of nodes requested are available to each sub job."
38
+ ),
39
+ )
40
+ processes_per_node = param .Selector (
41
+ default = 1 ,
42
+ objects = [],
43
+ label = "Processes per Node" ,
44
+ precedence = 5.2 ,
45
+ doc = "Number of processes per node to request for the job." ,
46
+ )
47
+ wall_time = param .String (
48
+ default = "01:00:00" ,
49
+ label = "Wall Time (HH:MM:SS)" ,
50
+ precedence = 6 ,
51
+ doc = (
52
+ "Maximum allowable time for the job to run.\n \n "
53
+ "**Note:** for array jobs, the entire amount of wall time requested is available to each sub job."
54
+ ),
55
+ )
27
56
wall_time_alert = pn .pane .Alert (visible = False )
28
57
node_alert = pn .pane .Alert (visible = False )
29
- queue = param .Selector (default = QUEUES [0 ], objects = QUEUES , precedence = 7 )
58
+ queue = param .Selector (
59
+ default = QUEUES [0 ], objects = QUEUES , precedence = 7 , doc = "Scheduling queue to which the job will be submitted."
60
+ )
30
61
max_wall_time = param .String (default = "Not Found" , label = "Max Wall Time" , precedence = 7.1 )
31
62
max_nodes = param .String (default = "Not Found" , label = "Max Processes" , precedence = 7.2 )
32
63
submit_script_filename = param .String (default = "run.pbs" , precedence = 8 )
33
- notification_email = param .String (label = "Notification E-mail(s)" , precedence = 9 )
64
+ notification_email = param .String (
65
+ label = "Notification E-mail(s)" ,
66
+ precedence = 9 ,
67
+ doc = "E-mail address to receive notification(s) when the job starts and/or ends." ,
68
+ )
34
69
notify_start = param .Boolean (default = True , label = "when job begins" , precedence = 9.1 )
35
70
notify_end = param .Boolean (default = True , label = "when job ends" , precedence = 9.2 )
36
71
@@ -39,6 +74,22 @@ class PbsScriptInputs(HpcBase):
39
74
wall_time_maxes = None
40
75
node_maxes = None
41
76
77
+ def __init__ (self , ** params ):
78
+ super ().__init__ (** params )
79
+ self .workdir = FileSelector (
80
+ title = "Base Directory" ,
81
+ show_browser = False ,
82
+ help_text = (
83
+ "Base directory that the job's working directory path will be created in.\n \n "
84
+ "**Note:** by default the job's working directory is: "
85
+ f"`<BASE_DIRECTORY>/{ PbsJob .DEFAULT_JOB_LABEL } /<JOB_NAME>.<TIMESTAMP>/`"
86
+ ),
87
+ )
88
+
89
+ @param .depends ("uit_client" , watch = True )
90
+ def set_file_browser (self ):
91
+ self .workdir .file_browser = create_file_browser (self .uit_client , patterns = [])
92
+
42
93
@staticmethod
43
94
def get_default (value , objects ):
44
95
return value if value in objects else objects [0 ]
@@ -54,7 +105,7 @@ async def update_hpc_connection_dependent_defaults(self):
54
105
subprojects = self .subproject_usage ["Subproject" ].to_list ()
55
106
self .param .hpc_subproject .objects = subprojects
56
107
self .hpc_subproject = self .get_default (self .hpc_subproject , subprojects )
57
- self .workdir = self .uit_client .WORKDIR .as_posix ()
108
+ self .workdir . file_path = self .uit_client .WORKDIR .as_posix ()
58
109
self .param .node_type .objects = list (NODE_TYPES [self .uit_client .system ].keys ())
59
110
self .node_type = self .get_default (self .node_type , self .param .node_type .objects )
60
111
self .param .queue .objects = await self .await_if_async (self .uit_client .get_queues ())
@@ -169,7 +220,7 @@ def pbs_options_view(self):
169
220
),
170
221
pn .Column (
171
222
self .param .hpc_subproject ,
172
- self .param . workdir ,
223
+ self .workdir ,
173
224
self .param .node_type ,
174
225
pn .widgets .Spinner .from_param (self .param .nodes ),
175
226
self .param .processes_per_node ,
@@ -198,39 +249,46 @@ class PbsScriptAdvancedInputs(HpcConfigurable):
198
249
env_browsers = param .List ()
199
250
env_delete_buttons = param .List ()
200
251
file_browser = param .ClassSelector (class_ = HpcFileBrowser )
201
- file_browser_col = param .ClassSelector (class_ = pn .Column , default = pn . Column ( None , sizing_mode = "stretch_width" ) )
252
+ file_browser_wb = param .ClassSelector (class_ = pn .layout . WidgetBox )
202
253
apply_file_browser = param .Action (label = "Apply" )
203
254
close_file_browser = param .Action (lambda self : self .show_file_browser (False ), label = "Close" )
204
255
append_path = param .Boolean (label = "Append to Path" )
205
256
257
+ def __init__ (self , ** params ):
258
+ super ().__init__ (** params )
259
+ self .environment_variables_card = pn .Card (
260
+ title = "Environment Variables" ,
261
+ sizing_mode = "stretch_width" ,
262
+ margin = (10 , 0 ),
263
+ )
264
+ self .update_environment_variables_col ()
265
+ self .file_browser_wb = pn .WidgetBox (
266
+ self .file_browser ,
267
+ pn .Row (
268
+ pn .widgets .Checkbox .from_param (self .param .append_path , width = 100 ),
269
+ pn .widgets .Button .from_param (
270
+ self .param .apply_file_browser ,
271
+ button_type = "success" ,
272
+ width = 100 ,
273
+ ),
274
+ pn .widgets .Button .from_param (
275
+ self .param .close_file_browser ,
276
+ button_type = "primary" ,
277
+ width = 100 ,
278
+ ),
279
+ align = "end" ,
280
+ ),
281
+ sizing_mode = "stretch_width" ,
282
+ )
283
+
206
284
@param .depends ("uit_client" , watch = True )
207
285
def configure_file_browser (self ):
208
- self .file_browser = None # HpcFileBrowser(self.uit_client) #TODO
286
+ self .file_browser = create_file_browser (self .uit_client )
287
+ if self .file_browser_wb :
288
+ self .file_browser_wb [0 ] = self .file_browser
209
289
210
290
def show_file_browser (self , show ):
211
- self .file_browser_col [0 ] = (
212
- pn .WidgetBox (
213
- self .file_browser .panel ,
214
- pn .Row (
215
- pn .widgets .Checkbox .from_param (self .param .append_path , width = 100 ),
216
- pn .widgets .Button .from_param (
217
- self .param .apply_file_browser ,
218
- button_type = "success" ,
219
- width = 100 ,
220
- ),
221
- pn .widgets .Button .from_param (
222
- self .param .close_file_browser ,
223
- button_type = "primary" ,
224
- width = 100 ,
225
- ),
226
- align = "end" ,
227
- ),
228
- sizing_mode = "stretch_width" ,
229
- )
230
- if show
231
- else None
232
- )
233
-
291
+ self .environment_variables_card [- 1 ] = self .file_browser_wb if show else None
234
292
if not show :
235
293
for btn in self .env_browsers :
236
294
btn .loading = False
@@ -281,8 +339,8 @@ def update_file_path(self, _, index):
281
339
else :
282
340
self .env_values [index ].value = self .file_browser .value [0 ]
283
341
284
- @param .depends ("environment_variables" )
285
- def environment_variables_view (self ):
342
+ @param .depends ("environment_variables" , watch = True )
343
+ def update_environment_variables_col (self ):
286
344
self .environment_variables .pop ("" , None ) # Clear blank key if there is one
287
345
self .env_names = list ()
288
346
self .env_values = list ()
@@ -311,25 +369,20 @@ def environment_variables_view(self):
311
369
self .env_names [0 ].name = "Name"
312
370
self .env_values [0 ].name = "Value"
313
371
314
- return pn .Card (
315
- * [
316
- pn .Row (k , v , b , d , sizing_mode = "stretch_width" )
317
- for k , v , b , d in zip_longest (
318
- self .env_names ,
319
- self .env_values ,
320
- self .env_browsers ,
321
- self .env_delete_buttons ,
322
- )
323
- ],
324
- self .file_browser_col ,
325
- title = "Environment Variables" ,
326
- sizing_mode = "stretch_width" ,
327
- margin = (10 , 0 ),
328
- )
372
+ self .environment_variables_card [:] = [
373
+ pn .Row (k , v , b , d , sizing_mode = "stretch_width" )
374
+ for k , v , b , d in zip_longest (
375
+ self .env_names ,
376
+ self .env_values ,
377
+ self .env_browsers ,
378
+ self .env_delete_buttons ,
379
+ )
380
+ ]
381
+ self .environment_variables_card .append (None )
329
382
330
383
def advanced_options_view (self ):
331
384
return pn .Column (
332
- self .environment_variables_view ,
385
+ self .environment_variables_card ,
333
386
pn .Card (
334
387
"<h3>Modules to Load</h3>" ,
335
388
pn .widgets .CrossSelector .from_param (self .param .modules_to_load , width = 700 ),
@@ -463,11 +516,13 @@ def pbs_script(self):
463
516
464
517
@property
465
518
def job (self ):
519
+
466
520
if self ._job is None :
467
521
self ._job = PbsJob (
468
522
script = self .pbs_script ,
469
523
client = self .uit_client ,
470
524
workspace = self .user_workspace ,
525
+ base_dir = self .workdir .file_path ,
471
526
)
472
527
return self ._job
473
528
0 commit comments