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

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

Add plot_bilan_jobs.py and do some cleaning

  • Property svn:executable set to *
File size: 11.2 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
17from gencmip6 import *
18from gencmip6_path import *
[2411]19
[2413]20
[2412]21########################################
[2413]22def get_storedir(login):
[2411]23
[2437]24  print("get_storedir")
25
[2413]26  command = ["ccc_home", "-A", "-u", login]
27  try :
28    res = subprocess.check_output(command)
[2437]29    print("res", res)
[2421]30  except Exception as rc:
[2437]31    print("exception", rc)
[2413]32    res = None
33
[2424]34  return res.strip()
[2413]35
36
37########################################
38def get_dirsize(dirname):
39
40  command = ["du", "-sbh", dirname]
41  try :
[2421]42    res = subprocess.check_output(command)
43    res = res.split()[0]
[2413]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"
[2412]63  logins  = {}
[2411]64
[2413]65  if where_we_run() == "curie":
66    try :
67      res = subprocess.check_output("ccc_myproject")
68    except Exception as rc :
69      print(rc)
[2426]70      exit(1)
[2421]71    with open(os.path.join(DIR["DATA"], OUT["CCCMP"]), "w") as fileout:
[2413]72      fileout.write(res)
73
[2412]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]
[2413]80        today = string_to_date(today)
81
[2412]82        break
[2411]83
[2412]84    # Skip next two lines : first is blank and second is login titles
85    for _ in xrange(1):
86      next(filein)
[2411]87
[2413]88    # Login list, until blank line
[2412]89    for ligne in filein:
90      if not ligne.strip():
91        break
92      login, conso = ligne.split()
93      logins[login] = float(conso)
[2411]94
[2413]95    # Skip until we find consumed time (hours)
[2412]96    for ligne in filein:
97      if "Total" in ligne:
98        total = float(ligne.split()[-1])
99        break
[2411]100
[2413]101    # Skip until we find allocated time (hours)
[2412]102    for ligne in filein:
103      if "Allocated" in ligne:
104        project["alloc"] = float(ligne.split()[-1])
105        break
[2411]106
[2413]107    # Skip until we find theoratical use (%)
[2412]108    for ligne in filein:
109      if "Suggested use at this time" in ligne:
110        utheo = float(ligne.split()[-1].strip("%"))
111        break
[2411]112
[2413]113    # Skip until we find real use (%)
[2412]114    for ligne in filein:
115      if "Real use at this time" in ligne:
116        ureal = float(ligne.split()[-1].strip("%"))
117        break
[2411]118
[2413]119    # Skip until we find deadline
[2412]120    for ligne in filein:
121      if "Project deadline" in ligne:
122        project["deadline"] = ligne.split()[-1]
123        break
[2411]124
[2413]125  return project, logins, today, total, utheo, ureal
[2411]126
127
[2412]128########################################
129def write_param(filename, project):
[2411]130
[2412]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)
[2411]136
137
[2412]138########################################
[2437]139def write_bilan(filename, today, total, ureal, utheo, run_mean, pen_mean, run_std, pen_std):
[2412]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  """
[2411]146
[2437]147  title_str  = "{:10s} {:12s} {:11s} {:11s} {:13s} {:13s} {:13s} {:13s}\n".format(
[2412]148                 "date",
149                 "conso(hours)",
150                 "real_use(%)",
151                 "theo_use(%)",
[2437]152                 "running(core)",
153                 "pending(core)",
154                 "run_std(core)",
155                 "pen_std(core)",
[2412]156               )
[2437]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(
[2412]159                 today,
160                 total,
161                 ureal,
162                 utheo,
[2437]163                 run_mean,
164                 pen_mean,
165                 run_std,
166                 pen_std,
[2412]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               )
[2413]192  result_str = "{:%Y-%m-%d} {:11.2f}\n".format(
[2412]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):
[2413]230      result_str = "{:%Y-%m-%d} {:10s} {:12.2f}\n".format(
[2412]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########################################
[2417]242def write_store(filename, today, logins):
[2412]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
[2413]250  items = (login for login, conso in logins.iteritems()
251                  if conso > 0.)
[2412]252
[2417]253  title_str  = "{:10s} {:10s} {:>7s} {:s}\n".format(
254                 "date",
255                 "login",
256                 "dirsize",
257                 "dirname",
258               )
[2412]259
[2417]260  with open(filename, "w") as fileout:
261    if args.dryrun:
262      print(title_str.strip())
263    else:
264      fileout.write(title_str)
[2413]265
[2417]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")
[2413]273
[2421]274      if not os.path.isdir(igcm_out):
275        break
[2417]276
[2421]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:
[2417]284        result_str = "{:%Y-%m-%d} {:10s} {:>7s} {:s}\n".format(
285                       today,
286                       login,
[2421]287                       get_dirsize(os.path.join(igcm_out, dirname)),
288                       os.path.join(igcm_out, dirname)
[2417]289                     )
[2421]290
291        if args.dryrun or args.verbose:
[2417]292          print(result_str.strip())
[2421]293
294        if not args.dryrun:
[2417]295          fileout.write(result_str)
296
297
[2412]298########################################
[2437]299def save_files(file_list, today):
[2417]300
301  if not args.dryrun:
302    suffix = "{:%Y%m%d}".format(today)
[2437]303    for filename in file_list:
[2417]304      filein  = os.path.join(DIR["DATA"], filename)
305      if os.path.isfile(filein):
[2425]306        fileout = os.path.join(DIR["SAVEDATA"],
[2417]307                               "_".join((filename, suffix)))
308        shutil.copy(filein, fileout)
309
310
311########################################
[2412]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__))
[2413]333    print(where_we_run())
[2412]334    print(args)
335
[2417]336  if args.bilan or args.login or args.store:
337    args.all = False
[2412]338
339  if args.verbose:
[2413]340    print(DIR["DATA"])
[2425]341    print(DIR["SAVEDATA"])
[2412]342
[2413]343  (project, logins, today, total, utheo, ureal) = \
[2417]344      parse_myproject(os.path.join(DIR["DATA"], OUT["CCCMP"]))
[2412]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  # -----------------------
[2417]356  if args.verbose:
357    print("=> write_param")
[2412]358
[2417]359  write_param(os.path.join(DIR["DATA"], OUT["PARAM"]), project)
360
[2412]361  # 2- Conso totale par jour
362  # ------------------------
[2437]363
[2417]364  if args.verbose:
365    print("=> write_bilan")
366
[2437]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
[2412]413  write_bilan(
[2417]414    os.path.join(DIR["DATA"], OUT["BILAN"]),
[2412]415    today,
416    total,
417    ureal,
[2437]418    utheo,
419    run_mean,
420    pen_mean,
421    run_std,
422    pen_std,
[2412]423  )
424
425  # 2b- Conso théorique par jour
426  # ----------------------------
[2417]427  if args.verbose:
428    print("=> write_utheo")
[2412]429
[2417]430  write_utheo(os.path.join(DIR["DATA"], OUT["UTHEO"]), today, utheo)
431
[2412]432  # 3- Conso par login (HOME)
433  # -------------------------
[2417]434  if args.verbose:
435    print("=> write_login")
[2412]436
[2417]437  write_login(os.path.join(DIR["DATA"], OUT["LOGIN"]), today, logins)
438
[2412]439  # 4- volume cree sur STORE
440  # ------------------------
[2417]441  if args.verbose:
442    print("=> write_store")
443
[2437]444  if where_we_run() == "curie":
445    write_store(os.path.join(DIR["DATA"], OUT["STORE"]), today, logins)
[2412]446
447  # Save files (on WORKDIR)
448  # =======================
[2417]449  if args.verbose:
450    print("=> Save files")
[2412]451  if not args.dryrun:
[2437]452    file_list = [
453        OUT["PARAM"],
454        OUT["BILAN"],
455        OUT["UTHEO"],
456        OUT["LOGIN"],
457        OUT["STORE"],
458        OUT["CCCMP"],
459    ]
[2426]460
[2437]461    save_files(file_list, today)
462
[2426]463  exit(0)
[2433]464
Note: See TracBrowser for help on using the repository browser.