nodeocc 1.0.2__tar.gz → 1.0.3__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.3}/PKG-INFO +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.3}/pyproject.toml +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/model/infrastructure.py +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/nodeocc.egg-info/PKG-INFO +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/readers/slurmreader.py +43 -25
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/view/curses_multiwindow.py +1 -1
- {nodeocc-1.0.2 → nodeocc-1.0.3}/README.md +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/setup.cfg +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/setup.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/__init__.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/controller/controller.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/model/job.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/nodeocc.egg-info/SOURCES.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/nodeocc.egg-info/dependency_links.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/nodeocc.egg-info/entry_points.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/nodeocc.egg-info/requires.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/nodeocc.egg-info/top_level.txt +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/readers/compute_wait_time.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/view/__init__.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/view/slurm_list.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/view/slurm_viz.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/src/view/styles.py +0 -0
- {nodeocc-1.0.2 → nodeocc-1.0.3}/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.3"
|
|
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,27 @@ def _load_joblet_meta(line):
|
|
|
152
151
|
|
|
153
152
|
|
|
154
153
|
def _gpus_per_joblet(line):
|
|
155
|
-
if pd.isna(line['
|
|
154
|
+
if pd.isna(line['ALL_JOB_NODES']):
|
|
156
155
|
return 0
|
|
157
|
-
|
|
158
|
-
return line['
|
|
156
|
+
if line['ALL_JOB_NODES'].count(',') == 0:
|
|
157
|
+
return line['TRES_ALLOC'].split('gpu=')[-1].split(',')[0] if 'gpu=' in line['TRES_ALLOC'] else 0
|
|
159
158
|
else:
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
159
|
+
node = line['NODELIST']
|
|
160
|
+
node_idx = line['ALL_JOB_NODES'].split(',').index(node)
|
|
161
|
+
return int(re.findall(r'gpu:(\d+)', line['TRES_PER_NODE'])[node_idx]) if 'gpu:' in line['TRES_PER_NODE'] else 0
|
|
166
162
|
|
|
167
163
|
|
|
168
164
|
def _cpus_per_joblet(line):
|
|
169
|
-
if line['
|
|
170
|
-
return
|
|
165
|
+
if pd.isna(line['ALL_JOB_NODES']):
|
|
166
|
+
return 0
|
|
167
|
+
if line['ALL_JOB_NODES'].count(',') == 0:
|
|
168
|
+
return int(str(line['TRES_ALLOC']).split('cpu=')[-1].split(',')[0])
|
|
171
169
|
else:
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
|
176
175
|
|
|
177
176
|
|
|
178
177
|
memunits = {
|
|
@@ -193,12 +192,26 @@ def parse_mem(thing):
|
|
|
193
192
|
|
|
194
193
|
|
|
195
194
|
def _mem_per_joblet(line):
|
|
196
|
-
if line['
|
|
197
|
-
return
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
if pd.isna(line['ALL_JOB_NODES']):
|
|
196
|
+
return 0
|
|
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 line['ALL_JOB_NODES'].count(',') == 0:
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|