diff --git a/src/user_session_builder.py b/src/user_session_builder.py index 0d3a3206b581f9b3a884ee9e8d80469128c08518..f649473077273d71b7bd9aac40efce54247e262f 100644 --- a/src/user_session_builder.py +++ b/src/user_session_builder.py @@ -155,7 +155,7 @@ class User: def to_dict(self, descr=None, cmd=None, version=1): - """User object to dictionnary, for printing or json export.""" + """User object to dictionnary, for printing or SABjson export.""" if descr is None: descr = f"Session Annotated Batsim JSON for user{self.id}" @@ -171,3 +171,14 @@ class User: res["command"] = cmd return res + + + def to_session_stat(self): + """Return a dictionnary with session stats""" + + return { + "first_submit_time": min([s.first_submit for _, s in self.sessions.items()]), + "max_finish_time": min([s.max_finish_time for _, s in self.sessions.items()]), + "nb_sessions": len(self.sessions), + "sessions": [s.to_session_stat() for _, s in self.sessions.items()] + } \ No newline at end of file diff --git a/src/workload.py b/src/workload.py index 5536aa70ec85e8288103a03863f738757eed4925..0135d2d8eefb7d3f2e557301f9b3701a42fdb27b 100644 --- a/src/workload.py +++ b/src/workload.py @@ -97,3 +97,14 @@ class Session: "jobs": [j.to_dict(session_start_offset = self.first_submit) for j in self.jobs] } + + + def to_session_stat(self): + """Return a dictionnary with session stats""" + + return { + "first_submit_time": self.first_submit, + "last_submit_time": max([j.submit_time for j in self.jobs]), + "finish_time": self.max_finish_time, + "nb_jobs": len(self.jobs) + } \ No newline at end of file diff --git a/swf2userSessions.py b/swf2userSessions.py index 087b23554a2fdea1ce5f329240da432754f3877b..b3ce842dcbd011d5a6a50eec577f128689814272 100755 --- a/swf2userSessions.py +++ b/swf2userSessions.py @@ -6,8 +6,8 @@ from src.workload import SwfField, Job def swf2sessions(input_swf, output_dir, delim_approach, delim_threshold, - dynamic_reduction, build_graph_rep, job_walltime_factor, - given_walltime_only, job_grain, quiet): + dynamic_reduction, build_graph_rep, session_stat, + job_walltime_factor, given_walltime_only, job_grain, quiet): users = {} if not os.path.exists(output_dir): @@ -66,6 +66,14 @@ def swf2sessions(input_swf, output_dir, delim_approach, delim_threshold, if build_graph_rep: user.export_dependancy_graph(f"{output_dir}/graphs") + if session_stat: + stats = {} + for user_id, user in users.items(): + stats[user_id] = user.to_session_stat() + + with open(f"{output_dir}/session_stat.json", "w") as file: + json.dump(stats, file) + if not quiet: print("\nSWF parsing done.") print("Number of users: ", len(users)) @@ -120,6 +128,13 @@ if __name__ == "__main__": action="store_true", help="Build a graphical representation of each session graph and save " "them in a subfolder as gml files") + parser.add_argument( + '--session_stat', action="store_true", + help="Output a separate file `session_stat.json` containing summary " + "information about the user sessions. In particular, it contains info " + "about the original session durations (finish times) that are NOT " + "embedded in the SABjsons." + ) parser.add_argument("-q", "--quiet", @@ -174,6 +189,7 @@ if __name__ == "__main__": delim_threshold=threshold, dynamic_reduction=not (args.no_dynamic_reduction), build_graph_rep=args.graph, + session_stat=args.session_stat, job_walltime_factor=args.job_walltime_factor, given_walltime_only=args.given_walltime_only, job_grain=args.job_grain,