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

Last change on this file since 2850 was 2850, checked in by labetoulle, 8 years ago

[consogencmip6] Change cpt parsing to reflect latest changes in ccc_myproject output

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