Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add get_input_file_dict() in GenericJob #1472

Merged
merged 8 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
use-mamba: true
- name: Test
shell: bash -l {0}
timeout-minutes: 5
timeout-minutes: 6
run: |
python .ci_support/pyironconfig.py
bash .ci_support/pip_install.sh
Expand Down
54 changes: 38 additions & 16 deletions pyiron_base/jobs/job/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@
run_job_with_runmode_modal,
run_job_with_runmode_queue,
execute_job_with_external_executable,
write_input_files_from_input_dict,
)
from pyiron_base.jobs.job.util import (
_copy_restart_files,
_get_restart_copy_dict,
_kill_child,
_job_store_before_copy,
_job_reload_after_copy,
Expand Down Expand Up @@ -425,26 +426,48 @@ def collect_logfiles(self):

def write_input(self):
"""
Write the input files for the external executable. This method has to be implemented in the individual
hamiltonians.
Call routines that generate the code specific input files
Returns:
"""
write_input_files_from_input_dict(
input_dict=self.get_input_file_dict(),
working_directory=self.working_directory,
)

def get_input_file_dict(self) -> dict:
"""
Get an hierarchical dictionary of input files. On the first level the dictionary is divided in file_to_create
and files_to_copy. Both are dictionaries use the file names as keys. In file_to_create the values are strings
which represent the content which is going to be written to the corresponding file. In files_to_copy the values
are the paths to the source files to be copied.

Returns:
dict: hierarchical dictionary of input files
"""
if (
state.settings.configuration["write_work_dir_warnings"]
and self._write_work_dir_warnings
and not self._python_only_job
):
with open(
os.path.join(self.working_directory, "WARNING_pyiron_modified_content"),
"w",
) as f:
f.write(
"Files in this directory are intended to be written and read by pyiron. \n\n"
"pyiron may transform user input to enhance performance, thus, use these files with care!\n"
"Consult the log and/or the documentation to gain further information.\n\n"
"To disable writing these warning files, specify \n"
"WRITE_WORK_DIR_WARNINGS=False in the .pyiron configuration file (or set the "
"PYIRONWRITEWORKDIRWARNINGS environment variable accordingly)."
)
content = [
"Files in this directory are intended to be written and read by pyiron. \n\n",
"pyiron may transform user input to enhance performance, thus, use these files with care!\n",
"Consult the log and/or the documentation to gain further information.\n\n",
"To disable writing these warning files, specify \n",
"WRITE_WORK_DIR_WARNINGS=False in the .pyiron configuration file (or set the ",
"PYIRONWRITEWORKDIRWARNINGS environment variable accordingly).",
]
return {
"files_to_create": {
"WARNING_pyiron_modified_content": "".join(content)
},
"files_to_copy": _get_restart_copy_dict(job=self),
}
else:
return {
"files_to_create": {},
"files_to_copy": _get_restart_copy_dict(job=self),
}

def collect_output(self):
"""
Expand Down Expand Up @@ -1173,7 +1196,6 @@ def save(self):
if self._check_if_input_should_be_written():
self.project_hdf5.create_working_directory()
self.write_input()
_copy_restart_files(job=self)
self.status.created = True
self._calculate_predecessor()
print(
Expand Down
9 changes: 9 additions & 0 deletions pyiron_base/jobs/job/runfunction.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import multiprocessing
import os
import posixpath
import shutil
import subprocess

from jinja2 import Template
Expand Down Expand Up @@ -775,6 +776,14 @@ def multiprocess_wrapper(
job_wrap.job.run_static()


def write_input_files_from_input_dict(input_dict: dict, working_directory: str):
for file_name, content in input_dict["files_to_create"].items():
with open(os.path.join(working_directory, file_name), "w") as f:
f.writelines(content)
for file_name, source in input_dict["files_to_copy"].items():
shutil.copy(source, os.path.join(working_directory, file_name))


def _generate_flux_execute_string(job, database_is_disabled):
if not database_is_disabled:
executable_template = Template(
Expand Down
29 changes: 18 additions & 11 deletions pyiron_base/jobs/job/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,19 @@ def _is_valid_job_name(job_name):
)


def _get_restart_copy_dict(job):
copy_dict = {}
for i, actual_name in enumerate(
[os.path.basename(f) for f in job.restart_file_list]
):
if actual_name in job.restart_file_dict.keys():
new_name = job.restart_file_dict[actual_name]
else:
new_name = os.path.basename(job.restart_file_list[i])
copy_dict[new_name] = job.restart_file_list[i]
return copy_dict


def _copy_restart_files(job):
"""
Internal helper function to copy the files required for the restart job.
Expand All @@ -224,17 +237,11 @@ def _copy_restart_files(job):
raise ValueError(
"The working directory is not yet available to copy restart files"
)
for i, actual_name in enumerate(
[os.path.basename(f) for f in job.restart_file_list]
):
if actual_name in job.restart_file_dict.keys():
new_name = job.restart_file_dict[actual_name]
shutil.copy(
job.restart_file_list[i],
posixpath.join(job.working_directory, new_name),
)
else:
shutil.copy(job.restart_file_list[i], job.working_directory)
for file_name, source in _get_restart_copy_dict(job=job).items():
shutil.copy(
source,
posixpath.join(job.working_directory, file_name),
)


def _kill_child(job):
Expand Down
Loading