nodeocc 1.0.2__tar.gz → 1.0.4__tar.gz
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.
- {nodeocc-1.0.2 → nodeocc-1.0.4}/PKG-INFO +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.4}/pyproject.toml +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/controller/controller.py +1 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/model/infrastructure.py +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/nodeocc.egg-info/PKG-INFO +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/readers/slurmreader.py +45 -27
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/view/curses_multiwindow.py +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/view/slurm_list.py +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.4}/README.md +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/setup.cfg +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/setup.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/__init__.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/model/job.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/nodeocc.egg-info/SOURCES.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/nodeocc.egg-info/dependency_links.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/nodeocc.egg-info/entry_points.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/nodeocc.egg-info/requires.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/nodeocc.egg-info/top_level.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/readers/compute_wait_time.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/view/__init__.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/view/slurm_viz.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/view/styles.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.4}/src/view/utils.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "nodeocc"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.4"
|
|
8
8
|
authors = [{ name = "Matteo Boschini" }]
|
|
9
9
|
maintainers = [{ name = "Lorenzo Bonicelli" }, { name = "Aniello Panariello" }]
|
|
10
10
|
description = "TUI application for viewing the status of GPU allocations on a Slurm cluster"
|
|
@@ -67,7 +67,7 @@ class Infrastructure:
|
|
|
67
67
|
self.cpu_limit_grp = cpu_limit_grp
|
|
68
68
|
self.cpu_limit_stu = cpu_limit_stu
|
|
69
69
|
self.cpu_limit_stugrp = cpu_limit_stugrp
|
|
70
|
-
self.prior = ['n/a', None, 'RTXA5000', 'RTX6000', 'RTX5000', '2080', 'V100', '1080', 'P100', 'K80']
|
|
70
|
+
self.prior = ['n/a', None, 'A40', 'RTXA5000', 'RTX6000', 'RTX5000', '2080', 'V100', '1080', 'P100', 'K80']
|
|
71
71
|
|
|
72
72
|
@staticmethod
|
|
73
73
|
def from_dict(d):
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import os
|
|
3
|
-
import
|
|
2
|
+
import re
|
|
4
3
|
from io import StringIO
|
|
5
4
|
|
|
6
5
|
import pandas as pd
|
|
@@ -152,27 +151,29 @@ def _load_joblet_meta(line):
|
|
|
152
151
|
|
|
153
152
|
|
|
154
153
|
def _gpus_per_joblet(line):
|
|
155
|
-
|
|
154
|
+
try:
|
|
155
|
+
if 'node=1' in line['TRES_ALLOC']:
|
|
156
|
+
return line['TRES_ALLOC'].split('gpu=')[-1].split(',')[0] if 'gpu=' in line['TRES_ALLOC'] else 0
|
|
157
|
+
else:
|
|
158
|
+
node = line['NODELIST']
|
|
159
|
+
node_idx = line['ALL_JOB_NODES'].split(',').index(node)
|
|
160
|
+
return int(re.findall(r'gpu:(\d+)', line['TRES_PER_NODE'])[node_idx]) if 'gpu:' in line['TRES_PER_NODE'] else 0
|
|
161
|
+
except BaseException as e:
|
|
156
162
|
return 0
|
|
157
|
-
elif not pd.isna(line['gpus_per_node']):
|
|
158
|
-
return line['gpus_per_node'] * (line['NODES'] if pd.isna(line['NODELIST']) else 1)
|
|
159
|
-
else:
|
|
160
|
-
if line['ST'] == 'PD':
|
|
161
|
-
return line['gpus_per_job'] if not pd.isna(line['gpus_per_job']) else line['gpus_per_task']
|
|
162
|
-
gpus_id = line['joblet_meta_str']
|
|
163
|
-
gpus_id = sum([x.split('IDX:')[-1].split(')')[0].split(',') for x in gpus_id if 'gpu' in x], [])
|
|
164
|
-
gpus_n = len(gpus_id) + sum([len(range(int(x.split('-')[1].split()[0]) - int(x.split('-')[0]))) for x in gpus_id if '-' in x])
|
|
165
|
-
return gpus_n
|
|
166
163
|
|
|
167
164
|
|
|
168
165
|
def _cpus_per_joblet(line):
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
166
|
+
try:
|
|
167
|
+
if 'node=1' in line['TRES_ALLOC']:
|
|
168
|
+
return int(str(line['TRES_ALLOC']).split('cpu=')[-1].split(',')[0])
|
|
169
|
+
else:
|
|
170
|
+
nodes = line['NODES']
|
|
171
|
+
tot_gpu = int(str(line['TRES_ALLOC']).split('gpu=')[-1].split(',')[0]) if 'gpu=' in str(line['TRES_ALLOC']) else 0
|
|
172
|
+
tot_cpus = int(str(line['TRES_ALLOC']).split('cpu=')[-1].split(',')[0])
|
|
173
|
+
n_gpus = line['joblet_gpus']
|
|
174
|
+
return int(tot_cpus) // int(nodes) if tot_gpu == 0 else int(tot_cpus) // tot_gpu * n_gpus
|
|
175
|
+
except BaseException as e:
|
|
176
|
+
return 0
|
|
176
177
|
|
|
177
178
|
|
|
178
179
|
memunits = {
|
|
@@ -193,12 +194,24 @@ def parse_mem(thing):
|
|
|
193
194
|
|
|
194
195
|
|
|
195
196
|
def _mem_per_joblet(line):
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
197
|
+
try:
|
|
198
|
+
mem = line['TRES_ALLOC'].split('mem=')[-1].split(',')[0]
|
|
199
|
+
if 'G' in mem:
|
|
200
|
+
mem = int(mem.split('G')[0]) * 1024
|
|
201
|
+
elif 'M' in mem:
|
|
202
|
+
mem = int(mem.split('M')[0])
|
|
203
|
+
else:
|
|
204
|
+
mem = int(mem)
|
|
205
|
+
except BaseException:
|
|
206
|
+
return 0
|
|
207
|
+
|
|
208
|
+
if 'node=1' in line['TRES_ALLOC']:
|
|
201
209
|
return mem
|
|
210
|
+
else:
|
|
211
|
+
nodes = line['NODES']
|
|
212
|
+
tot_gpu = int(str(line['TRES_ALLOC']).split('gpu=')[-1].split(',')[0]) if 'gpu=' in str(line['TRES_ALLOC']) else 0
|
|
213
|
+
n_gpus = line['joblet_gpus']
|
|
214
|
+
return int(mem) // int(nodes) if tot_gpu == 0 else int(mem) // tot_gpu * n_gpus
|
|
202
215
|
|
|
203
216
|
|
|
204
217
|
def _true_jobid(line):
|
|
@@ -257,15 +270,20 @@ def read_jobs():
|
|
|
257
270
|
instance.timeme(f"\t- squeue and dataframe creation")
|
|
258
271
|
|
|
259
272
|
squeue_df['JOBID'] = squeue_df['JOBID'].apply(str)
|
|
273
|
+
squeue_df['ALL_JOB_NODES'] = squeue_df['NODELIST']
|
|
260
274
|
squeue_df = _split_column(squeue_df, 'NODELIST')
|
|
275
|
+
|
|
261
276
|
squeue_df['gpus_per_node'] = squeue_df['TRES_PER_NODE'].apply(lambda x: try_parse_gpu(x) if isinstance(x, str) else x)
|
|
262
277
|
squeue_df['gpus_per_job'] = squeue_df['TRES_PER_JOB'].apply(lambda x: try_parse_gpu(x) if isinstance(x, str) else x)
|
|
263
278
|
squeue_df['gpus_per_task'] = squeue_df['TRES_PER_TASK'].apply(lambda x: try_parse_gpu(x) if isinstance(x, str) else x)
|
|
264
279
|
|
|
265
280
|
try:
|
|
266
|
-
squeue_df['
|
|
267
|
-
squeue_df['joblet_gpus'] = squeue_df
|
|
268
|
-
squeue_df['joblet_cpus'] = squeue_df['TRES_ALLOC'].apply(lambda l: int(str(l).split('cpu=')[-1].split(',')[0]))
|
|
281
|
+
# squeue_df['joblet_gpus'] = squeue_df['TRES_ALLOC'].apply(lambda l: str(l).split('gpu=')[-1].split(',')[0] if 'gpu=' in str(l) else 0)
|
|
282
|
+
squeue_df['joblet_gpus'] = squeue_df.apply(_gpus_per_joblet, axis=1)
|
|
283
|
+
# squeue_df['joblet_cpus'] = squeue_df['TRES_ALLOC'].apply(lambda l: int(str(l).split('cpu=')[-1].split(',')[0]))
|
|
284
|
+
squeue_df['joblet_cpus'] = squeue_df.apply(_cpus_per_joblet, axis=1)
|
|
285
|
+
# squeue_df['joblet_mem'] = squeue_df['TRES_ALLOC'].apply(get_mem_joblet)
|
|
286
|
+
squeue_df['joblet_mem'] = squeue_df.apply(_mem_per_joblet, axis=1)
|
|
269
287
|
except Exception as e:
|
|
270
288
|
instance.err(f"Exception PD: {e}")
|
|
271
289
|
|
|
@@ -89,7 +89,7 @@ class Singleton:
|
|
|
89
89
|
self.basepath = self.args.basepath
|
|
90
90
|
|
|
91
91
|
if self.args.daemon_only:
|
|
92
|
-
handler = RotatingFileHandler(os.path.join(self.basepath, '.
|
|
92
|
+
handler = RotatingFileHandler(os.path.join(self.basepath, '.master_log.txt'), maxBytes=5 * 1024 * 1024, backupCount=2, mode='w')
|
|
93
93
|
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S',
|
|
94
94
|
handlers=[handler])
|
|
95
95
|
# set logging file
|
|
@@ -47,7 +47,7 @@ def _joblet_format(instance, job, width=74, jobid_type='agg'):
|
|
|
47
47
|
if instance.view_mode in ('gpu', 'ram'):
|
|
48
48
|
joblet_repr += _format_to((f'{joblet.n_gpus}gp' if joblet.n_gpus > 0 else " - "), 3, 'left')
|
|
49
49
|
elif instance.view_mode == 'cpu':
|
|
50
|
-
joblet_repr += _format_to((f'{joblet.cpus}cp' if joblet.cpus > 0 else "-"), 3, 'left')
|
|
50
|
+
joblet_repr += _format_to((f'{joblet.cpus}cp' if joblet.cpus > 0 else " - "), 3, 'left')
|
|
51
51
|
joblet_repr += ' '
|
|
52
52
|
joblet_repr += _format_to(joblet.node if joblet.node is not None else job.reason, 11)
|
|
53
53
|
joblet_reprs.append(joblet_repr)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|