def sumjobs(jobs): sumjob = {} for key in jobs[0]: if key in ("job_name", "job_description", "input_file", "output_file", "error_file", "output_dir", "sub_cwd", "exec_home", "exec_cwd", "exit_reson", "application", "command", "pre_exec_command", "post_exec_command", "resize_notification_command", "effective_resreq"): # find string pattern sumjob[key] = findstringpattern( [job[key] for job in jobs if job[key]]) elif key in ("runlimit", "swaplimit", "stacklimit", "memlimit", "filelimit", "processlimit", "corelimit", "run_time", "swap", "slots", "mem", "max_mem", "avg_mem", "nexec_host", "cpu_used", "time_left"): # sum sumjob[key] = sum(job[key] for job in jobs if job[key]) elif key in ("%complete", "job_priority", "idle_factor"): # compute average pcomp = [job[key] for job in jobs if job[key]] if pcomp: sumjob[key] = sum(pcomp) / len(pcomp) else: sumjob[key] = None elif key in ("exec_host", "rsvd_host"): # collect host counts sumjob[key] = defaultdict(int) for job in jobs: if job[key]: for host, count in job[key].iteritems(): sumjob[key][host] += count elif key == "pids": # collect sumjob[key] = sum((job[key] for job in jobs if job[key]), []) elif key == "jobid": # collect sumjob[key] = [] for job in jobs: if job[key] and job[key] not in sumjob[key]: sumjob[key].append(job[key]) elif key == "pend_reason": # sum sumjob[key] = defaultdict(int) for job in jobs: if not job[key]: continue for key2, val in job[key]: sumjob[key][key2] += val else: # collect and count sumjob[key] = defaultdict(int) for job in jobs: sumjob[key][job[key]] += 1 return sumjob
def sumjobs(jobs): sumjob = {} for key in jobs[0]: if key in ("job_name", "job_description", "input_file", "output_file", "error_file", "output_dir", "sub_cwd", "exec_home", "exec_cwd", "exit_reson", "application", "command", "pre_exec_command", "post_exec_command", "resize_notification_command", "effective_resreq"): # find string pattern sumjob[key] = findstringpattern([job[key] for job in jobs if job[key]]) elif key in ("runlimit", "swaplimit", "stacklimit", "memlimit", "filelimit", "processlimit", "corelimit", "run_time", "swap", "slots", "mem", "max_mem", "avg_mem", "nexec_host", "cpu_used", "time_left"): # sum sumjob[key] = sum(job[key] for job in jobs if job[key]) elif key in ("%complete", "job_priority", "idle_factor"): # compute average pcomp = [job[key] for job in jobs if job[key]] if pcomp: sumjob[key] = sum(pcomp) / len(pcomp) else: sumjob[key] = None elif key in ("exec_host", "rsvd_host"): # collect host counts sumjob[key] = defaultdict(int) for job in jobs: if job[key]: for host, count in job[key].iteritems(): sumjob[key][host] += count elif key == "pids": # collect sumjob[key] = sum((job[key] for job in jobs if job[key]), []) elif key == "jobid": # collect sumjob[key] = [] for job in jobs: if job[key] and job[key] not in sumjob[key]: sumjob[key].append(job[key]) elif key == "pend_reason": # sum sumjob[key] = defaultdict(int) for job in jobs: if not job[key]: continue for key2, val in job[key]: sumjob[key][key2] += val else: # collect and count sumjob[key] = defaultdict(int) for job in jobs: sumjob[key][job[key]] += 1 return sumjob
def sumhosts(hosts): """Summarize a list of hosts.""" sumhost = {} for key in hosts[0]: if key in ("host_name"): # find string pattern sumhost[key] = findstringpattern( [host[key] for host in hosts if host[key]]) elif key in ("max", "njobs", "run", "ssusp", "ususp", "rsv", "ncpus", "maxmem", "maxswp"): # sum sumhost[key] = sum(host[key] for host in hosts if host[key]) elif key in ("status", "server", "type", "comment"): sumhost[key] = defaultdict(int) for host in hosts: sumhost[key][host[key]] += 1 elif key in ("load", "threshold"): # sum up free/used pairs sumhost[key] = dict() for key2 in hosts[0][key]: free, used = zip(*[host[key][key2] for host in hosts]) if all(x is None for x in free): free = None else: free = sum(x for x in free if x) if all(x is None for x in used): used = None else: used = sum(x for x in used if x) sumhost[key][key2] = [free, used] else: # colect sumhost[key] = [] for host in hosts: if host[key] and host[key] not in sumhost[key]: sumhost[key].append(host[key]) sumhost["host_names"] = [host["host_name"] for host in hosts] return sumhost
def sumhosts(hosts): sumhost = {} for key in hosts[0]: if key in ("host_name"): # find string pattern sumhost[key] = findstringpattern([host[key] for host in hosts if host[key]]) elif key in ("max", "njobs", "run", "ssusp", "ususp", "rsv", "ncpus", "maxmem", "maxswp"): # sum sumhost[key] = sum(host[key] for host in hosts if host[key]) elif key in ("status", "server", "type", "comment"): sumhost[key] = defaultdict(int) for host in hosts: sumhost[key][host[key]] += 1 elif key in ("load", "threshold"): # sum up free/used pairs sumhost[key] = dict() for key2 in hosts[0][key]: free, used = zip(*[host[key][key2] for host in hosts]) if all(x is None for x in free): free = None else: free = sum(x for x in free if x) if all(x is None for x in used): used = None else: used = sum(x for x in used if x) sumhost[key][key2] = [free, used] else: # colect sumhost[key] = [] for host in hosts: if host[key] and host[key] not in sumhost[key]: sumhost[key].append(host[key]) sumhost["host_names"] = [host["host_name"] for host in hosts] return sumhost
def printjobs(jobs, wide=False, long=False, output=None, title=None, header=True, file=sys.stdout): """Print a list of jobs.""" if len(jobs) == 0: return sumjob = not isinstance(jobs[0]["jobid"], str) if long: for job in jobs: printjoblong(job, sumjob=sumjob, file=file) return if output: if header: print(*output, sep="\t", file=file) for job in jobs: print(*[job[field] for field in output], sep="\t", file=file) return # begin output whoami = os.getenv("USER") namelen = max(map(len, (job["job_name"] for job in jobs))) if sumjob: titlelen = 0 if "title" in jobs[0]: titlelen = max(map(len, (job["title"] for job in jobs))) lens = { "title": 10, "jobid": 10, "name": min(20, max(6, namelen + 1)), "stat": 6, "user": 10, "time": 12, "model": 14 } if sumjob: lens["stat"] = 12 else: if any(job["jobid"][-1] == "]" for job in jobs): lens["jobid"] = 14 if wide: if sumjob: lens["title"] = max(6, titlelen + 1) lens["name"] = max(6, namelen + 1) lens["queue"] = 8 lens["project"] = 8 lens["prio."] = 6 # header if header: h = "" if sumjob and "title" in jobs[0]: h += "group".ljust(lens["title"]) if not sumjob: h += "jobid".ljust(lens["jobid"]) h += "".join(n.ljust(lens[n]) for n in ("name", "stat", "user")) if wide: h += "".join(n.ljust(lens[n]) for n in ("queue", "project")) if not sumjob: h += "prio.".ljust(lens["prio."]) if sumjob: h += "runtime".rjust(lens["time"]) else: h += "wait/runtime".rjust(lens["time"]) h += " resources" h = h.upper() if title: h += " " + color(title, "b") print(h, file=file) for job in jobs: l = "" if sumjob and "title" in job: # title title = job["title"] if not wide: if len(title) >= lens["title"]: title = title[:lens["title"] - 2] + "*" l += color(title.ljust(lens["title"]), "b") if not sumjob: # jobid l += (job["jobid"] + " ").ljust(lens["jobid"]) # job name jobname = job["job_name"] if job["job_name"] else "" if not wide: if len(jobname) >= lens["name"]: jobname = "*" + jobname[-lens["name"] + 2:] l += jobname.ljust(lens["name"]) # status if sumjob and isinstance(job["stat"], defaultdict): l += color("%3d " % job["stat"]["PEND"], "r") l += color("%3d " % job["stat"]["RUN"], "g") done = job["stat"]["EXIT"] + job["stat"]["DONE"] if done: l += color("%3d " % done, "y") else: l += " " else: stat = job["stat"] if stat == "PEND": c = "r" if len(job["pend_reason"]) == 1: pr = job["pend_reason"][0] if "New job is waiting for scheduling" in pr[0]: stat = "NEW" c = "b" if "Waiting for rescheduling after parameters" in pr[0]: stat = "MOD" c = "b" if "Job dependency condition not satisfied" in pr[0]: stat = "DEP" c = "b" elif stat == "RUN": c = "g" if job["interactive"]: stat = "INT" if job["X11"]: stat = "X11" else: c = "y" l += color(stat.ljust(lens["stat"]), c) # user if sumjob and isinstance(job["user"], defaultdict): l += color(str(len(job["user"])).ljust(lens["user"]), "b") else: c = "g" if job["user"] == whoami else 0 username = getuseralias(job["user"]) l += color((username + " ").ljust(lens["user"]), c) if wide: # queue if sumjob and isinstance(job["queue"], defaultdict): l += color(str(len(job["queue"])).ljust(lens["queue"]), "b") else: l += job["queue"].ljust(lens["queue"]) # project if sumjob and isinstance(job["project"], defaultdict): l += color( str(len(job["project"])).ljust(lens["project"]), "b") else: l += job["project"].ljust(lens["project"]) if not sumjob: # priority l += str(job["priority"]).rjust(lens["prio."] - 1) + " " # wait/runtime t = job["run_time"] if not sumjob and job["stat"] == "PEND": t = time() - job["submit_time"] s = format_duration(t) l += s.rjust(lens["time"]) # resources # %t if job["%complete"]: ptime = job["%complete"] c = fractioncolor(1 - ptime / 100) if wide: s = "%6.2f" % round(ptime, 2) else: s = "%3d" % int(round(ptime)) l += " " + color(s, c) + "%t" elif not sumjob and job["stat"] == "RUN": l += " " if wide: l += " " # %m if job["memlimit"] and job["mem"] and job["slots"]: memlimit = job["memlimit"] * job["slots"] pmem = 100 * job["mem"] / memlimit c = fractioncolor(1 - pmem / 100) if wide: s = "%6.2f" % round(pmem, 2) else: s = "%3d" % int(round(pmem)) l += " " + color(s, c) + "%m" elif not sumjob and job["stat"] == "RUN": l += " " if wide: l += " " # time if job["runlimit"]: l += " " + format_duration(job["runlimit"]) # memory memlimit = None if job["memlimit"]: memlimit = job["memlimit"] if job["min_req_proc"]: memlimit *= job["min_req_proc"] if memlimit is not None: l += format_mem(memlimit).rjust(10) else: l += "".rjust(10) # Hosts if job["exec_host"]: if wide or len(job["exec_host"]) == 1: d = job["exec_host"] else: d = defaultdict(int) for key, val in job["exec_host"].iteritems(): d[re.match("(.*?)\d+", key).groups()[0] + "*"] += val for key in sorted(d.keys()): val = d[key] c = "r" if val >= 100 else "y" if val >= 20 else 0 exclusive = job["exclusive"] if sumjob and exclusive not in (True, False): exclusive = False times = color("x", "r") if exclusive else "*" l += color(" %3d" % val, c) + times + "%s" % key else: if not sumjob: if job["min_req_proc"]: times = color("x", "r") if job["exclusive"] else "*" l += " %3d" % job["min_req_proc"] + times elif job["exclusive"]: l += " 1" + color("x", "r") else: l += " 1*" if job["host_req"]: hosts = job["host_req"] if len(hosts) == 1: hosts = hosts[0] else: if wide: hosts = "(%s)" % ", ".join(hosts) else: hosts = findstringpattern(hosts) l += hosts.ljust(lens["model"]) elif job["resreq"]: match = re.search("model==(\w+)", job["resreq"]) model = "" if match: model += match.groups()[0] if re.search("phi", job["resreq"]): if match: model += "+" model += "Phi" l += model.ljust(lens["model"]) if job["alloc_slot"]: l += color(" rsvd:", "y") if wide or len(job["alloc_slot"]) == 1: d = job["alloc_slot"] else: d = defaultdict(int) for key, val in job["alloc_slot"].iteritems(): d[re.match("(.*?)\d+", key).groups()[0] + "*"] += val for key, val in d.iteritems(): c = "r" if val >= 100 else "y" if val >= 20 else 0 l += color(" %3d" % val, c) + "*%s" % key if wide and job["pend_reason"] and len(job["pend_reason"]) == 1: reason = job["pend_reason"][0][0] if reason != title: l += color(" %s" % reason, "b") if job["dependency"]: l += color(":", "b") if job["dependency"]: l += color(" %s" % job["dependency"], "b") print(l, file=file) file.flush()
def printjobs(jobs, wide=False, long=False, output=None, title=None, header=True, file=sys.stdout): """Print a list of jobs.""" if len(jobs) == 0: return sumjob = not isinstance(jobs[0]["jobid"], str) if long: for job in jobs: printjoblong(job, sumjob=sumjob, file=file) return if output: # header print(*output, sep="\t", file=file) for job in jobs: print(*[job[field] for field in output], sep="\t", file=file) return # begin output whoami = os.getenv("USER") namelen = max(map(len, (job["job_name"] for job in jobs))) if sumjob: titlelen = 0 if "title" in jobs[0]: titlelen = max(map(len, (job["title"] for job in jobs))) lens = { "title": 10, "jobid": 10, "name": min(20, max(6, namelen + 1)), "stat": 6, "user": 10, "time": 12, "model": 14 } if sumjob: lens["stat"] = 12 else: if any(job["jobid"][-1] == "]" for job in jobs): lens["jobid"] = 14 if wide: if sumjob: lens["title"] = max(6, titlelen + 1) lens["name"] = max(6, namelen + 1) lens["queue"] = 8 lens["project"] = 8 lens["prio."] = 6 # header if header: h = "" if sumjob and "title" in jobs[0]: h += "group".ljust(lens["title"]) if not sumjob: h += "jobid".ljust(lens["jobid"]) h += "".join(n.ljust(lens[n]) for n in ("name", "stat", "user")) if wide: h += "".join(n.ljust(lens[n]) for n in ("queue", "project")) if not sumjob: h += "prio.".ljust(lens["prio."]) if sumjob: h += "runtime".rjust(lens["time"]) else: h += "wait/runtime".rjust(lens["time"]) h += " resources" h = h.upper() if title: h += " " + color(title, "b") print(h, file=file) for job in jobs: l = "" if sumjob and "title" in job: # title title = job["title"] if not wide: if len(title) >= lens["title"]: title = title[:lens["title"] - 2] + "*" l += color(title.ljust(lens["title"]), "b") if not sumjob: # jobid l += (job["jobid"] + " ").ljust(lens["jobid"]) # job name jobname = job["job_name"] if job["job_name"] else "" if not wide: if len(jobname) >= lens["name"]: jobname = "*" + jobname[-lens["name"] + 2:] l += jobname.ljust(lens["name"]) # status if sumjob and isinstance(job["stat"], defaultdict): l += color("%3d " % job["stat"]["PEND"], "r") l += color("%3d " % job["stat"]["RUN"], "g") done = job["stat"]["EXIT"] + job["stat"]["DONE"] if done: l += color("%3d " % done, "y") else: l += " " else: stat = job["stat"] if stat == "PEND": c = "r" if len(job["pend_reason"]) == 1: pr = job["pend_reason"][0] if "New job is waiting for scheduling" in pr[0]: stat = "NEW" c = "b" if "Waiting for rescheduling after parameters" in pr[0]: stat = "MOD" c = "b" if "Job dependency condition not satisfied" in pr[0]: stat = "DEP" c = "b" elif stat == "RUN": c = "g" if job["interactive"]: stat = "INT" if job["X11"]: stat = "X11" else: c = "y" l += color(stat.ljust(lens["stat"]), c) # user if sumjob and isinstance(job["user"], defaultdict): l += color(str(len(job["user"])).ljust(lens["user"]), "b") else: c = "g" if job["user"] == whoami else 0 username = getuseralias(job["user"]) l += color((username + " ").ljust(lens["user"]), c) if wide: # queue if sumjob and isinstance(job["queue"], defaultdict): l += color(str(len(job["queue"])).ljust(lens["queue"]), "b") else: l += job["queue"].ljust(lens["queue"]) # project if sumjob and isinstance(job["project"], defaultdict): l += color(str(len(job["project"])).ljust(lens["project"]), "b") else: l += job["project"].ljust(lens["project"]) if not sumjob: # priority l += str(job["priority"]).rjust(lens["prio."] - 1) + " " # wait/runtime t = job["run_time"] if not sumjob and job["stat"] == "PEND": t = time() - job["submit_time"] s = format_duration(t) l += s.rjust(lens["time"]) # resources # %t if job["%complete"]: ptime = job["%complete"] c = fractioncolor(1 - ptime / 100) if wide: s = "%6.2f" % round(ptime, 2) else: s = "%3d" % int(round(ptime)) l += " " + color(s, c) + "%t" elif not sumjob and job["stat"] == "RUN": l += " " if wide: l += " " # %m if job["memlimit"] and job["mem"] and job["slots"]: memlimit = job["memlimit"] * job["slots"] pmem = 100 * job["mem"] / memlimit c = fractioncolor(1 - pmem / 100) if wide: s = "%6.2f" % round(pmem, 2) else: s = "%3d" % int(round(pmem)) l += " " + color(s, c) + "%m" elif not sumjob and job["stat"] == "RUN": l += " " if wide: l += " " # time if job["runlimit"]: l += " " + format_duration(job["runlimit"]) # memory memlimit = None if job["memlimit"]: memlimit = job["memlimit"] if job["min_req_proc"]: memlimit *= job["min_req_proc"] if memlimit is not None: l += format_mem(memlimit).rjust(10) else: l += "".rjust(10) # Hosts if job["exec_host"]: if wide or len(job["exec_host"]) == 1: d = job["exec_host"] else: d = defaultdict(int) for key, val in job["exec_host"].iteritems(): d[re.match("(.*?)\d+", key).groups()[0] + "*"] += val for key in sorted(d.keys()): val = d[key] c = "r" if val >= 100 else "y" if val >= 20 else 0 exclusive = job["exclusive"] if sumjob and exclusive not in (True, False): exclusive = False times = color("x", "r") if exclusive else "*" l += color(" %3d" % val, c) + times + "%s" % key else: if not sumjob: if job["min_req_proc"]: times = color("x", "r") if job["exclusive"] else "*" l += " %3d" % job["min_req_proc"] + times elif job["exclusive"]: l += " 1" + color("x", "r") else: l += " 1*" if job["host_req"]: hosts = job["host_req"] if len(hosts) == 1: hosts = hosts[0] else: if wide: hosts = "(%s)" % ", ".join(hosts) else: hosts = findstringpattern(hosts) l += hosts.ljust(lens["model"]) elif job["resreq"]: match = re.search("model==(\w+)", job["resreq"]) model = "" if match: model += match.groups()[0] if re.search("phi", job["resreq"]): if match: model += "+" model += "Phi" l += model.ljust(lens["model"]) if job["alloc_slot"]: l += color(" rsvd:", "y") if wide or len(job["alloc_slot"]) == 1: d = job["alloc_slot"] else: d = defaultdict(int) for key, val in job["alloc_slot"].iteritems(): d[re.match("(.*?)\d+", key).groups()[0] + "*"] += val for key, val in d.iteritems(): c = "r" if val >= 100 else "y" if val >= 20 else 0 l += color(" %3d" % val, c) + "*%s" % key if wide and job["pend_reason"] and len(job["pend_reason"]) == 1: reason = job["pend_reason"][0][0] if reason != title: l += color(" %s" % reason, "b") if job["dependency"]: l += color(":", "b") if job["dependency"]: l += color(" %s" % job["dependency"], "b") print(l, file=file) file.flush()