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

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