class JobAnalysis: """Provides functionality to analyze job results.""" def __init__(self, output_dir, config): self._output_dir = output_dir self._config = config self._results = ResultsSummary(output_dir) def get_job(self, job_name): """Return the job from the config file with job_name. Parameters ---------- job_name : str Returns ------- namedtuple """ return self._config.get_job(job_name) def get_successful_result(self, job_name): """Return the job result from the results file. Refer to :func:`~jade.result.ResultSummary.get_successful_result`. """ return self._results.get_successful_result(job_name) def get_simulation(self, job_name): """Return a simulation object for the job_name. Parameters ---------- job_name : str Returns ------- JobExecutionInterface """ # Make sure it was successful, otherwise it will raise. self.get_successful_result(job_name) job = self.get_job(job_name) simulation = self._config.create_from_result( job, os.path.join(self._output_dir, JOBS_OUTPUT_DIR)) return simulation def list_results(self): """Return a list of Result objects.""" return self._results.list_results() @property def output_dir(self): return self._output_dir def show_results(self, only_failed=False, only_successful=False): """Show the results in terminal.""" return self._results.show_results(only_failed=only_failed, only_successful=only_successful)
def test_job_order(generic_command_fixture): num_jobs = 50 commands = ["echo hello world"] * num_jobs with open(TEST_FILENAME, "w") as f_out: for command in commands: f_out.write(command + "\n") inputs = GenericCommandInputs(TEST_FILENAME) config = GenericCommandConfiguration() for job_param in inputs.iter_jobs(): config.add_job(job_param) assert config.get_num_jobs() == num_jobs job = config.get_job("1") for i in range(10, 15): job.blocked_by.add(i) config.get_job("2").blocked_by.add("1") config.get_job("21").blocked_by.add("30") config.get_job("41").blocked_by.add("50") config.dump(CONFIG_FILE) cmd = (f"{SUBMIT_JOBS} {CONFIG_FILE} --output={OUTPUT} " "--per-node-batch-size=10 " "--max-nodes=4 " "--poll-interval=0.1 " f"--hpc-config {FAKE_HPC_CONFIG} " "--num-processes=10") check_run_command(cmd) check_run_command(f"{WAIT} --output={OUTPUT} --poll-interval=0.01") result_summary = ResultsSummary(OUTPUT) results = result_summary.list_results() assert len(results) == num_jobs tracker = {x.name: x for x in results} for i in range(10, 15): assert tracker["1"].completion_time > tracker[str(i)].completion_time assert tracker["2"].completion_time > tracker["1"].completion_time assert tracker["21"].completion_time > tracker["30"].completion_time assert tracker["41"].completion_time > tracker["50"].completion_time # Verify that stats are summarized correctly with aggregation mode. stats_text = Path(OUTPUT) / "stats.txt" assert stats_text.exists() assert "Average" in stats_text.read_text() stats_json = Path(OUTPUT) / "stats_summary.json" assert stats_json.exists() stats = load_data(stats_json) assert stats assert "batch" in stats[0]
def test_job_order(generic_command_fixture): num_jobs = 50 commands = ["echo hello world"] * num_jobs with open(TEST_FILENAME, "w") as f_out: for command in commands: f_out.write(command + "\n") inputs = GenericCommandInputs(TEST_FILENAME) config = GenericCommandConfiguration(job_inputs=inputs) for job_param in inputs.iter_jobs(): config.add_job(job_param) assert config.get_num_jobs() == num_jobs job = config.get_job("1") for i in range(10, 15): job.blocked_by.add(i) config.get_job("2").blocked_by.add("1") config.get_job("21").blocked_by.add("30") config.get_job("41").blocked_by.add("50") config.dump(CONFIG_FILE) os.environ["FAKE_HPC_CLUSTER"] = "True" cmd = f"{SUBMIT_JOBS} {CONFIG_FILE} --output={OUTPUT} " \ "--per-node-batch-size=10 " \ "--max-nodes=4 " \ "--poll-interval=.1 " \ "--num-processes=10" ret = run_command(cmd) assert ret == 0 result_summary = ResultsSummary(OUTPUT) results = result_summary.list_results() assert len(results) == num_jobs tracker = {} for result in results: tracker[result.name] = result for i in range(10, 15): assert tracker["1"].completion_time > tracker[str(i)].completion_time assert tracker["2"].completion_time > tracker["1"].completion_time assert tracker["21"].completion_time > tracker["30"].completion_time assert tracker["41"].completion_time > tracker["50"].completion_time