Skip to content

Commit

Permalink
[patch] Introduce a flag for _not_ mangling the name of wrapped funct…
Browse files Browse the repository at this point in the history
…ion jobs (#1356)

* Introduce a flag for _not_ mangling the name of wrapped function jobs

* Don't even override with function name, just keep the given name

* Add comment on the private var

* Indent and isolate the entire mangling block

Then fall back on super() otherwise, to further clarify the intent of the mangling

* Update pyiron_base/jobs/flex/pythonfunctioncontainer.py

Co-authored-by: Jan Janssen <[email protected]>

* Fix early return logic

That we broke by committing the readability suggestion

* Use a more descriptive name

* fix formatting

* Format black

---------

Co-authored-by: Jan Janssen <[email protected]>
Co-authored-by: pyiron-runner <[email protected]>
  • Loading branch information
3 people authored Mar 7, 2024
1 parent d26e451 commit 3b56972
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 11 deletions.
30 changes: 20 additions & 10 deletions pyiron_base/jobs/flex/pythonfunctioncontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def __init__(self, project, job_name):
super().__init__(project, job_name)
self._function = None
self._executor_type = None
self._automatically_rename_on_save_using_input = True

@property
def python_function(self):
Expand All @@ -64,23 +65,32 @@ def __call__(self, *args, **kwargs):
def to_hdf(self, hdf=None, group_name=None):
super().to_hdf(hdf=hdf, group_name=group_name)
self.project_hdf5["function"] = np.void(cloudpickle.dumps(self._function))
self.project_hdf5["_automatically_rename_on_save_using_input"] = (
self._automatically_rename_on_save_using_input
)

def from_hdf(self, hdf=None, group_name=None):
super().from_hdf(hdf=hdf, group_name=group_name)
self._function = cloudpickle.loads(self.project_hdf5["function"])
self._automatically_rename_on_save_using_input = bool(
self.project_hdf5["_automatically_rename_on_save_using_input"]
)

def save(self):
job_name = self._function.__name__ + get_hash(
binary=cloudpickle.dumps(
{"fn": self._function, "kwargs": self.input.to_builtin()}
if self._automatically_rename_on_save_using_input:
job_name = self._function.__name__ + get_hash(
binary=cloudpickle.dumps(
{"fn": self._function, "kwargs": self.input.to_builtin()}
)
)
)
self.job_name = job_name
if job_name in self.project.list_nodes():
self.from_hdf()
self.status.finished = True
else:
super().save()

self.job_name = job_name

if self.job_name in self.project.list_nodes():
self.from_hdf()
self.status.finished = True
return # Without saving
super().save()

def run_static(self):
if (
Expand Down
50 changes: 49 additions & 1 deletion tests/flex/test_pythonfunctioncontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def test_with_executor(self):
self.assertIsNone(job.server.future.result())
self.assertTrue(job.server.future.done())

@unittest.skipIf(os.name == "nt", "Starting subprocesses on windows take a long time.")
@unittest.skipIf(
os.name == "nt", "Starting subprocesses on windows take a long time."
)
def test_terminate_job(self):
job = self.project.wrap_python_function(my_sleep_funct)
job.input["a"] = 5
Expand Down Expand Up @@ -100,3 +102,49 @@ def test_with_internal_executor(self):
job.run()
self.assertEqual(job.output["result"], [6, 8, 10, 12])
self.assertTrue(job.status.finished)

def test_name_mangling(self):
def make_a_simple_job():
job = self.project.wrap_python_function(my_function)
job.input["a"] = 1
job.input["b"] = 2
return job

job = make_a_simple_job()
self.assertEqual(
job.job_name,
my_function.__name__,
msg="Sanity check"
)
try:
job.save()
self.assertNotEqual(
job.job_name,
my_function.__name__,
msg="By default, we expect the wrapped job names to get mangled based "
"on their input so multiple calls to the wrap get unique names"
)
loaded = self.project.load(job.job_name)
self.assertTrue(
loaded._automatically_rename_on_save_using_input,
msg="The mangling preference should survive saving and loading"
)
finally:
job.remove()

job = make_a_simple_job()
job._automatically_rename_on_save_using_input = False
try:
job.save()
self.assertEqual(
job.job_name,
my_function.__name__,
msg="When requested, the job name should retain its original value"
)
loaded = self.project.load(job.job_name)
self.assertFalse(
loaded._automatically_rename_on_save_using_input,
msg="The mangling preference should survive saving and loading"
)
finally:
job.remove()

0 comments on commit 3b56972

Please sign in to comment.