From 67a99552e3a22bb3ffde5169f8e57984a71327ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sun, 4 Feb 2024 10:34:48 +0100 Subject: [PATCH 1/6] create_job_step() function --- pyiron_base/project/generic.py | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pyiron_base/project/generic.py b/pyiron_base/project/generic.py index a999eca5f..a633c4a07 100644 --- a/pyiron_base/project/generic.py +++ b/pyiron_base/project/generic.py @@ -384,6 +384,52 @@ def create_job_class( executable_str=executable_str, ) + def create_job_step( + self, + job_name, + executable_str, + write_input_funct=None, + collect_output_funct=None, + default_input_dict=None, + conda_environment_path=None, + conda_environment_name=None, + input_file_lst=None, + execute_job=True, + ): + """ + + Args: + job_name (str): + executable_str (str): + write_input_funct (callable): + collect_output_funct (callable): + default_input_dict (dict): + conda_environment_path (str): + conda_environment_name (str): + input_file_lst (list): + execute_job (boolean): + + Returns: + + """ + job_factory = create_job_factory( + write_input_funct=write_input_funct, + collect_output_funct=collect_output_funct, + default_input_dict=default_input_dict, + executable_str=executable_str, + ) + job = job_factory(project=self, job_name=job_name) + if conda_environment_path is not None: + job.server.conda_environment_path = conda_environment_path + elif conda_environment_name is not None: + job.server.conda_environment_name = conda_environment_name + if input_file_lst is not None and len(input_file_lst) > 0: + for file in input_file_lst: + job.restart_file_list.append(file) + if execute_job: + job.run() + return job + def create_job(self, job_type, job_name, delete_existing_job=False): """ Create one of the following jobs: From 19cd94299d84e47116beb4f8a0f0bfca4115410f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sun, 4 Feb 2024 11:09:59 +0100 Subject: [PATCH 2/6] Rename default_input_dict to input_dict --- pyiron_base/project/generic.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyiron_base/project/generic.py b/pyiron_base/project/generic.py index a633c4a07..8193c67ae 100644 --- a/pyiron_base/project/generic.py +++ b/pyiron_base/project/generic.py @@ -390,7 +390,7 @@ def create_job_step( executable_str, write_input_funct=None, collect_output_funct=None, - default_input_dict=None, + input_dict=None, conda_environment_path=None, conda_environment_name=None, input_file_lst=None, @@ -403,7 +403,7 @@ def create_job_step( executable_str (str): write_input_funct (callable): collect_output_funct (callable): - default_input_dict (dict): + input_dict (dict): conda_environment_path (str): conda_environment_name (str): input_file_lst (list): @@ -415,7 +415,7 @@ def create_job_step( job_factory = create_job_factory( write_input_funct=write_input_funct, collect_output_funct=collect_output_funct, - default_input_dict=default_input_dict, + default_input_dict=input_dict, executable_str=executable_str, ) job = job_factory(project=self, job_name=job_name) From c186ed2a30757303b6dae68543872921fc534fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Fri, 9 Feb 2024 19:47:40 +0100 Subject: [PATCH 3/6] Add test for create_job_step() --- tests/flex/test_jobstep.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/flex/test_jobstep.py diff --git a/tests/flex/test_jobstep.py b/tests/flex/test_jobstep.py new file mode 100644 index 000000000..8f97fb811 --- /dev/null +++ b/tests/flex/test_jobstep.py @@ -0,0 +1,22 @@ +import os +from pyiron_base._tests import TestWithProject + + +class TestExecutableContainer(TestWithProject): + def test_conda_environment_path(self): + python_version_step = self.project.create_job_step( + job_name="pythonjobstep", + executable_str="python --version", + write_input_funct=None, + collect_output_funct=None, + input_dict=None, + conda_environment_path=None, + conda_environment_name=None, + input_file_lst=None, + execute_job=True, + ) + self.assertTrue(python_version_step.status.finished) + self.assertEqual( + python_version_step.files.error_out, + os.path.join(python_version_step.working_directory, "error.out") + ) From 02c2a317d219c1d29f46ab5987ae0550b2eea871 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sun, 10 Mar 2024 14:52:18 -0500 Subject: [PATCH 4/6] Add docstrings --- pyiron_base/project/generic.py | 49 ++++++++++++++----- ...est_jobstep.py => test_wrap_executable.py} | 0 2 files changed, 37 insertions(+), 12 deletions(-) rename tests/flex/{test_jobstep.py => test_wrap_executable.py} (100%) diff --git a/pyiron_base/project/generic.py b/pyiron_base/project/generic.py index 1ce01b17a..e51cfe465 100644 --- a/pyiron_base/project/generic.py +++ b/pyiron_base/project/generic.py @@ -365,7 +365,7 @@ def create_job_class( executable_str=executable_str, ) - def create_job_step( + def wrap_executable( self, job_name, executable_str, @@ -375,23 +375,48 @@ def create_job_step( conda_environment_path=None, conda_environment_name=None, input_file_lst=None, - execute_job=True, + execute_job=False, ): """ + Wrap any executable into a pyiron job object using the ExecutableContainerJob. Args: - job_name (str): - executable_str (str): - write_input_funct (callable): - collect_output_funct (callable): - input_dict (dict): - conda_environment_path (str): - conda_environment_name (str): - input_file_lst (list): - execute_job (boolean): + job_name (str): name of the new job object + executable_str (str): call to an external executable + write_input_funct (callable): The write input function write_input(input_dict, working_directory) + collect_output_funct (callable): The collect output function collect_output(working_directory) + input_dict (dict): Default input for the newly created job class + conda_environment_path (str): path of the conda environment + conda_environment_name (str): name of the conda environment + input_file_lst (list): list of files to be copied to the working directory before executing it\ + execute_job (boolean): automatically call run() on the job object - default false - Returns: + Example: + >>> def write_input(input_dict, working_directory="."): + >>> with open(os.path.join(working_directory, "input_file"), "w") as f: + >>> f.write(str(input_dict["energy"])) + >>> + >>> + >>> def collect_output(working_directory="."): + >>> with open(os.path.join(working_directory, "output_file"), "r") as f: + >>> return {"energy": float(f.readline())} + >>> + >>> + >>> from pyiron_base import Project + >>> pr = Project("test") + >>> job = pr.wrap_executable( + >>> job_name="Cat_Job_energy_1_0", + >>> write_input_funct=write_input, + >>> collect_output_funct=collect_output, + >>> input_dict={"energy": 1.0}, + >>> executable_str="cat input_file > output_file", + >>> execute_job=True, + >>> ) + >>> print(job.output) + + Returns: + pyiron_base.jobs.flex.ExecutableContainerJob: pyiron job object """ job_factory = create_job_factory( write_input_funct=write_input_funct, diff --git a/tests/flex/test_jobstep.py b/tests/flex/test_wrap_executable.py similarity index 100% rename from tests/flex/test_jobstep.py rename to tests/flex/test_wrap_executable.py From dc35eb5d98a18dec2910e63363d141bf3f4a5a3d Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sun, 10 Mar 2024 14:57:25 -0500 Subject: [PATCH 5/6] fix test --- tests/flex/test_wrap_executable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/flex/test_wrap_executable.py b/tests/flex/test_wrap_executable.py index 8f97fb811..dcba97d0f 100644 --- a/tests/flex/test_wrap_executable.py +++ b/tests/flex/test_wrap_executable.py @@ -4,7 +4,7 @@ class TestExecutableContainer(TestWithProject): def test_conda_environment_path(self): - python_version_step = self.project.create_job_step( + python_version_step = self.project.wrap_executable( job_name="pythonjobstep", executable_str="python --version", write_input_funct=None, From c87c28d5f502a4e4f59994a29e9815f3071e592f Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Mon, 11 Mar 2024 13:43:44 -0500 Subject: [PATCH 6/6] Add additional test --- tests/flex/test_wrap_executable.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/flex/test_wrap_executable.py b/tests/flex/test_wrap_executable.py index dcba97d0f..73e13602c 100644 --- a/tests/flex/test_wrap_executable.py +++ b/tests/flex/test_wrap_executable.py @@ -2,8 +2,18 @@ from pyiron_base._tests import TestWithProject -class TestExecutableContainer(TestWithProject): - def test_conda_environment_path(self): +def write_input(input_dict, working_directory="."): + with open(os.path.join(working_directory, "input_file"), "w") as f: + f.write(str(input_dict["energy"])) + + +def collect_output(working_directory="."): + with open(os.path.join(working_directory, "output_file"), "r") as f: + return {"energy": float(f.readline())} + + +class TestWrapExecutable(TestWithProject): + def test_python_version(self): python_version_step = self.project.wrap_executable( job_name="pythonjobstep", executable_str="python --version", @@ -20,3 +30,16 @@ def test_conda_environment_path(self): python_version_step.files.error_out, os.path.join(python_version_step.working_directory, "error.out") ) + + def test_cat(self): + job = self.project.wrap_executable( + job_name="Cat_Job_energy_1_0", + write_input_funct=write_input, + collect_output_funct=collect_output, + input_dict={"energy": 1.0}, + executable_str="cat input_file > output_file", + execute_job=False, + ) + job.input.energy = 2.0 + job.run() + self.assertEqual(job.output.energy, 2.0)