source: TOOLS/ConsoGENCMIP6/bin/conso_gencmip6.py @ 2437

Last change on this file since 2437 was 2437, checked in by labetoulle, 7 years ago

Add plot_bilan_jobs.py and do some cleaning

  • Property svn:executable set to *
File size: 11.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# this must come first
5from __future__ import print_function, unicode_literals, division
6
7# standard library imports
8from argparse import ArgumentParser
9import json
10import shutil
11import os
12import os.path
13import subprocess
14# import datetime as dt
15
16# Application library imports
17from gencmip6 import *
18from gencmip6_path import *
19
20
21########################################
22def get_storedir(login):
23
24  print("get_storedir")
25
26  command = ["ccc_home", "-A", "-u", login]
27  try :
28    res = subprocess.check_output(command)
29    print("res", res)
30  except Exception as rc:
31    print("exception", rc)
32    res = None
33
34  return res.strip()
35
36
37########################################
38def get_dirsize(dirname):
39
40  command = ["du", "-sbh", dirname]
41  try :
42    res = subprocess.check_output(command)
43    res = res.split()[0]
44  except Exception as rc :
45    print(rc)
46    res = None
47
48  return res
49
50
51# ########################################
52# def get_dirlist(dirname):
53
54
55#   return output
56
57
58########################################
59def parse_myproject(filename):
60
61  project = {}
62  project["project"] = "gencmip6"
63  logins  = {}
64
65  if where_we_run() == "curie":
66    try :
67      res = subprocess.check_output("ccc_myproject")
68    except Exception as rc :
69      print(rc)
70      exit(1)
71    with open(os.path.join(DIR["DATA"], OUT["CCCMP"]), "w") as fileout:
72      fileout.write(res)
73
74  with open(filename, "r") as filein:
75    # Skip lines until we find project name.
76    # Then extract script date
77    for ligne in filein:
78      if project["project"] in ligne:
79        today = ligne.split()[-1]
80        today = string_to_date(today)
81
82        break
83
84    # Skip next two lines : first is blank and second is login titles
85    for _ in xrange(1):
86      next(filein)
87
88    # Login list, until blank line
89    for ligne in filein:
90      if not ligne.strip():
91        break
92      login, conso = ligne.split()
93      logins[login] = float(conso)
94
95    # Skip until we find consumed time (hours)
96    for ligne in filein:
97      if "Total" in ligne:
98        total = float(ligne.split()[-1])
99        break
100
101    # Skip until we find allocated time (hours)
102    for ligne in filein:
103      if "Allocated" in ligne:
104        project["alloc"] = float(ligne.split()[-1])
105        break
106
107    # Skip until we find theoratical use (%)
108    for ligne in filein:
109      if "Suggested use at this time" in ligne:
110        utheo = float(ligne.split()[-1].strip("%"))
111        break
112
113    # Skip until we find real use (%)
114    for ligne in filein:
115      if "Real use at this time" in ligne:
116        ureal = float(ligne.split()[-1].strip("%"))
117        break
118
119    # Skip until we find deadline
120    for ligne in filein:
121      if "Project deadline" in ligne:
122        project["deadline"] = ligne.split()[-1]
123        break
124
125  return project, logins, today, total, utheo, ureal
126
127
128########################################
129def write_param(filename, project):
130
131  if args.dryrun:
132    print(json.dumps(project, indent=2))
133  else:
134    with open(filename, "w") as fileout:
135      json.dump(project, fileout, indent=2)
136
137
138########################################
139def write_bilan(filename, today, total, ureal, utheo, run_mean, pen_mean, run_std, pen_std):
140  """
141  Conso totale par jour
142  ---------------------
143  on garde le total, date en tete en accumulant dans le fichier :
144  OUT_CONSO_BILAN
145  """
146
147  title_str  = "{:10s} {:12s} {:11s} {:11s} {:13s} {:13s} {:13s} {:13s}\n".format(
148                 "date",
149                 "conso(hours)",
150                 "real_use(%)",
151                 "theo_use(%)",
152                 "running(core)",
153                 "pending(core)",
154                 "run_std(core)",
155                 "pen_std(core)",
156               )
157  str_fmt = "{:%Y-%m-%d} {:12.2f} {:11.2f} {:11.2f} {:13.2f} {:13.2f} {:13.2f} {:13.2f}\n"
158  result_str = str_fmt.format(
159                 today,
160                 total,
161                 ureal,
162                 utheo,
163                 run_mean,
164                 pen_mean,
165                 run_std,
166                 pen_std,
167               )
168
169  if args.dryrun:
170    print(title_str.strip())
171    print(result_str.strip())
172  else:
173    if not os.path.isfile(filename):
174      with open(filename, "w") as fileout:
175        fileout.write(title_str)
176    with open(filename, "a") as fileout:
177      fileout.write(result_str)
178
179
180########################################
181def write_utheo(filename, today, utheo):
182  """
183  Conso théorique par jour
184  ------------------------
185  OUT_CONSO_THEO
186  """
187
188  title_str  = "{:10s} {:11s}\n".format(
189                 "date",
190                 "theo_use(%)",
191               )
192  result_str = "{:%Y-%m-%d} {:11.2f}\n".format(
193                 today,
194                 utheo,
195               )
196
197  if args.dryrun:
198    print(title_str.strip())
199    print(result_str.strip())
200  else:
201    if not os.path.isfile(filename):
202      with open(filename, "w") as fileout:
203        fileout.write(title_str)
204    with open(filename, "a") as fileout:
205      fileout.write(result_str)
206
207
208########################################
209def write_login(filename, today, logins):
210  """
211  Conso par login (HOME)
212  ----------------------
213  on garde la trace de chaque login, date en tete, en remplacant
214  le fichier a chaque fois : OUT_CONSO_LOGIN
215  """
216
217  title_str  = "{:10s} {:10s} {:12s}\n".format(
218                 "date",
219                 "login",
220                 "conso(hours)",
221               )
222
223  with open(filename, "w") as fileout:
224    if args.dryrun:
225      print(title_str.strip())
226    else:
227      fileout.write(title_str)
228
229    for key in sorted(logins):
230      result_str = "{:%Y-%m-%d} {:10s} {:12.2f}\n".format(
231                     today,
232                     key,
233                     logins[key],
234                   )
235      if args.dryrun:
236        print(result_str.strip())
237      else:
238        fileout.write(result_str)
239
240
241########################################
242def write_store(filename, today, logins):
243  """
244  volume cree sur STORE
245  ---------------------
246  par login qui a consomme, en remplacant le fichier a chaque fois :
247  OUT_CONSO_STORE
248  """
249
250  items = (login for login, conso in logins.iteritems()
251                  if conso > 0.)
252
253  title_str  = "{:10s} {:10s} {:>7s} {:s}\n".format(
254                 "date",
255                 "login",
256                 "dirsize",
257                 "dirname",
258               )
259
260  with open(filename, "w") as fileout:
261    if args.dryrun:
262      print(title_str.strip())
263    else:
264      fileout.write(title_str)
265
266    for login in items:
267      if args.verbose:
268        print(login)
269      storedir = get_storedir(login)
270      if not storedir:
271        break
272      igcm_out = os.path.join(storedir, "IGCM_OUT")
273
274      if not os.path.isdir(igcm_out):
275        break
276
277      dirlist = []
278      try:
279        dirlist = os.listdir(igcm_out)
280      except OSError as rc:
281        print("Error on os.listdir({}):\n{}".format(igcm_out, rc))
282
283      for dirname in dirlist:
284        result_str = "{:%Y-%m-%d} {:10s} {:>7s} {:s}\n".format(
285                       today,
286                       login,
287                       get_dirsize(os.path.join(igcm_out, dirname)),
288                       os.path.join(igcm_out, dirname)
289                     )
290
291        if args.dryrun or args.verbose:
292          print(result_str.strip())
293
294        if not args.dryrun:
295          fileout.write(result_str)
296
297
298########################################
299def save_files(file_list, today):
300
301  if not args.dryrun:
302    suffix = "{:%Y%m%d}".format(today)
303    for filename in file_list:
304      filein  = os.path.join(DIR["DATA"], filename)
305      if os.path.isfile(filein):
306        fileout = os.path.join(DIR["SAVEDATA"],
307                               "_".join((filename, suffix)))
308        shutil.copy(filein, fileout)
309
310
311########################################
312if __name__ == '__main__':
313
314  # Get arguments from command line
315  # ===============================
316  parser = ArgumentParser()
317  parser.add_argument("-v", "--verbose", action="store_true",
318                      help="Verbose mode")
319  parser.add_argument("-d", "--dryrun", action="store_true",
320                      help="dry run, no file produced")
321  parser.add_argument("-a", "--all", action="store_false",
322                      help="produce all files (default)")
323  parser.add_argument("-b", "--bilan", action="store_true",
324                      help="produce all files (default)")
325  parser.add_argument("-l", "--login", action="store_true",
326                      help="produce all files (default)")
327  parser.add_argument("-s", "--store", action="store_true",
328                      help="produce all files (default)")
329
330  args = parser.parse_args()
331  if args.verbose:
332    print(os.path.basename(__file__))
333    print(where_we_run())
334    print(args)
335
336  if args.bilan or args.login or args.store:
337    args.all = False
338
339  if args.verbose:
340    print(DIR["DATA"])
341    print(DIR["SAVEDATA"])
342
343  (project, logins, today, total, utheo, ureal) = \
344      parse_myproject(os.path.join(DIR["DATA"], OUT["CCCMP"]))
345
346  if args.verbose:
347    print(today, utheo, ureal)
348    print(project)
349    print(logins)
350
351  # Produce files
352  # =============
353
354  # 1- Parametres du projet
355  # -----------------------
356  if args.verbose:
357    print("=> write_param")
358
359  write_param(os.path.join(DIR["DATA"], OUT["PARAM"]), project)
360
361  # 2- Conso totale par jour
362  # ------------------------
363
364  if args.verbose:
365    print("=> write_bilan")
366
367  file_jobs = get_last_file(
368      DIR["SAVEDATA"],
369      "{}_{:%Y%m%d}".format(OUT["JOBS"], today)
370  )
371  if args.verbose:
372    print(file_jobs)
373
374  run_mean = np.nan
375  pen_mean = np.nan
376  run_std  = np.nan
377  pen_std  = np.nan
378
379  if file_jobs:
380    try:
381      data = np.genfromtxt(
382        file_jobs,
383        skip_header=1,
384        converters={
385          0: string_to_datetime,
386          1: int,
387          2: int,
388        },
389        missing_values="nan",
390      )
391    except Exception as rc:
392      print("Problem with file {} :\n{}".format(file_jobs, rc))
393      exit(1)
394
395    if len(data) == 24:
396      run_mean = np.nanmean(
397          np.array([run for _, run, _ in data])
398      )
399      pen_mean = np.nanmean(
400          np.array([pen for _, _, pen in data])
401      )
402
403      run_std = np.nanstd(
404          np.array([run for _, run, _ in data])
405      )
406      pen_std = np.nanstd(
407          np.array([pen for _, _, pen in data])
408      )
409
410  if args.verbose:
411    print(run_mean, pen_mean, run_std, pen_std)
412
413  write_bilan(
414    os.path.join(DIR["DATA"], OUT["BILAN"]),
415    today,
416    total,
417    ureal,
418    utheo,
419    run_mean,
420    pen_mean,
421    run_std,
422    pen_std,
423  )
424
425  # 2b- Conso théorique par jour
426  # ----------------------------
427  if args.verbose:
428    print("=> write_utheo")
429
430  write_utheo(os.path.join(DIR["DATA"], OUT["UTHEO"]), today, utheo)
431
432  # 3- Conso par login (HOME)
433  # -------------------------
434  if args.verbose:
435    print("=> write_login")
436
437  write_login(os.path.join(DIR["DATA"], OUT["LOGIN"]), today, logins)
438
439  # 4- volume cree sur STORE
440  # ------------------------
441  if args.verbose:
442    print("=> write_store")
443
444  if where_we_run() == "curie":
445    write_store(os.path.join(DIR["DATA"], OUT["STORE"]), today, logins)
446
447  # Save files (on WORKDIR)
448  # =======================
449  if args.verbose:
450    print("=> Save files")
451  if not args.dryrun:
452    file_list = [
453        OUT["PARAM"],
454        OUT["BILAN"],
455        OUT["UTHEO"],
456        OUT["LOGIN"],
457        OUT["STORE"],
458        OUT["CCCMP"],
459    ]
460
461    save_files(file_list, today)
462
463  exit(0)
464
Note: See TracBrowser for help on using the repository browser.