Skip to content

Commit

Permalink
Adds method access in isolated functions (#280)
Browse files Browse the repository at this point in the history
* Adds method access in isolated functions

* Changes the name of the optional dependency for ehrlich

* Updates ehrlich testing to include modifying the underlying env

* Comments the old test again

* Bumps version
  • Loading branch information
miguelgondu authored Oct 23, 2024
1 parent e9d0cc6 commit 51ebfc4
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 14 deletions.
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "poli"
version = "1.0.0.dev11"
version = "1.0.0.dev12"
description = "poli, a library of discrete objective functions"
readme = "README.md"
authors = [{name="Miguel González-Duque", email="[email protected]"}, {name="Simon Bartels"}]
Expand Down Expand Up @@ -38,7 +38,10 @@ protein = [
"python-levenshtein",
"pdb-tools",
]
ehrlich_holo = [
ehrlich = [
"pytorch-holo",
]
ehrlichholo = [
"pytorch-holo",
]
tdc = [
Expand Down Expand Up @@ -76,7 +79,7 @@ profile = "black"
exclude = ["src/poli/core/util/proteins/rasp/inner_rasp", "src/poli/objective_repository/gfp_cbas"]

[tool.bumpversion]
current_version = "1.0.0.dev11"
current_version = "1.0.0.dev12"
parse = """(?x)
(?P<major>0|[1-9]\\d*)\\.
(?P<minor>0|[1-9]\\d*)\\.
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = poli
version = "1.0.0.dev11"
version = "1.0.0.dev12"
author = Miguel González-Duque
author_email = [email protected]
description = A library of discrete objective functions
Expand Down
2 changes: 1 addition & 1 deletion src/poli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""poli, a library for discrete black-box objective functions."""

__version__ = "1.0.0.dev11"
__version__ = "1.0.0.dev12"
from .core.util.isolation.instancing import instance_function_as_isolated_process

# from .core import get_problems
Expand Down
43 changes: 39 additions & 4 deletions src/poli/core/util/isolation/external_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,51 @@ def __getattr__(self, __name: str) -> Any:
attribute : Any
The attribute of the underlying black-box function.
"""
self.process_wrapper.send(["ATTRIBUTE", __name])
self.process_wrapper.send(["IS_METHOD", __name])
msg_type, *msg = self.process_wrapper.recv()
if msg_type == "EXCEPTION":
e, traceback_ = msg
print(traceback_)
raise e
else:
assert msg_type == "ATTRIBUTE"
attribute = msg[0]
return attribute
assert msg_type == "IS_METHOD"
is_method = msg[0]

if is_method:
return lambda *args, **kwargs: self._method_call(__name, *args, **kwargs)
else:
self.process_wrapper.send(["ATTRIBUTE", __name])
msg_type, *msg = self.process_wrapper.recv()
if msg_type == "EXCEPTION":
e, traceback_ = msg
print(traceback_)
raise e
else:
assert msg_type == "ATTRIBUTE"
attribute = msg[0]
return attribute

def _method_call(self, method_name: str, *args, **kwargs) -> Any:
"""Calls a method of the underlying isolated function.
Asks for the method of the underlying
isolated function by sending a message
to the process w. the msg_type "METHOD".
Parameters
----------
method_name : str
The name of the method.
"""
self.process_wrapper.send(["METHOD", method_name, args, kwargs])
msg_type, *msg = self.process_wrapper.recv()
if msg_type == "EXCEPTION":
e, traceback_ = msg
print(traceback_)
raise e
else:
assert msg_type == "METHOD"
return msg[0]

def __del__(self):
self.terminate()
Expand Down
14 changes: 13 additions & 1 deletion src/poli/external_isolated_function_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,20 @@ def run(objective_name: str, port: int, password: str) -> None:
y = f(x, context=context)
conn.send(["QUERY", y])
elif msg_type == "ATTRIBUTE":
attribute = getattr(f, msg[0])
attribute_name = msg[0]
attribute = getattr(f, attribute_name)
conn.send(["ATTRIBUTE", attribute])
elif msg_type == "IS_METHOD":
attribute_name = msg[0]
is_method = callable(getattr(f, attribute_name))
conn.send(["IS_METHOD", is_method])
elif msg_type == "METHOD":
method_name = msg[0]
method_args = msg[1]
method_kwargs = msg[2]
method = getattr(f, method_name)
result = method(*method_args, **method_kwargs)
conn.send(["METHOD", result])
except Exception as e:
tb = traceback.format_exc()
conn.send(["EXCEPTION", e, tb])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ def test_ehrlich_holo_builds_and_queries():
These issues will be addressed by the new isolation interface,
and if the user installs this black box with
`pip install poli[ehrlich_holo]` they won't face these issues.
`pip install poli[ehrlich]` they won't face these issues.
The error we currently get is the following:
multiprocessing.context.AuthenticationError: digest sent was rejected
Testing it locally seems to work well.
TODO: install in Colab and test.
TODO: fix.
"""
# @pytest.mark.poli__ehrlich_holo
# def test_ehrlich_holo_works_on_isolation():
Expand All @@ -57,7 +59,7 @@ def test_ehrlich_holo_builds_and_queries():
# epistasis_factor=0.0,
# force_isolation=True,
# )
# x0 = black_box.initial_solution()
# x0 = black_box.initial_solution(100)
# print(black_box(x0))

# x_final = black_box.optimal_solution()
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,6 @@ wheel_build_env = .pkg
deps=
{[testenv]deps}
-r requirements.txt
-e.[ehrlich_holo]
-e.[ehrlich]
commands=
pytest {tty:--color=yes} -v -m 'not slow and poli__ehrlich_holo' {posargs}

0 comments on commit 51ebfc4

Please sign in to comment.