Replies: 5 comments 16 replies
-
Question: should the function body be executed |
Beta Was this translation helpful? Give feedback.
-
Question: what customization would we want to enable with respect to decorator parameters? It could be possible to do the following. @work_at(source("bar_dir")) # <---
@submit('sleep 1000',
type='slurm',
is_block=True,
config=source("bar_config")) # <---
def bar(foo: str) -> str:
return foo so that we could do the following: result = dr.execute([...], inputs={"bar_config": dict(...), "bar_dir": "some/path/to/folder"}) |
Beta Was this translation helpful? Give feedback.
-
What would be some example procedural code that we'd want the Hamilton code to map to? -- just to ensure it's clear what Hamilton is replacing/helping with. TODO: provide example |
Beta Was this translation helpful? Give feedback.
-
OK, @skrawcz and I thought this over. I think this is a nice solution. What we do:
Then, the function you have with the # module
def some_var() -> str:
...
@slurm(...)
def slurm_job_1(some_var: str) -> dict:
return _make_config(...)
@slurm(...)
@tag(slurm_execute=True)
def slurm_job_2(some_var: str) -> dict:
return _make_config(...)
def results(slurm_job_1: dict, slurm_job_2: dict) -> dict:
return ...
# 1. break into four tasks
# 2. run through each task
# 2.a if not decorated with slurm -- execute as normal
# 3.a if decorated with slurm -- pass to SlurmExecutor
# 3. SlurmExecutor should wait and pass some indicator of the results, interpreted as node output
# execution manager, this is custom but let's push this back to hamilton
class RemoteDelegatingExecutionManager(DefaultExecutionManager):
def __init__(local_executor, remote_executor, indicator_tag="should_execute_remotely"):
super(...)
self.indicator_tag = indicator_tag
def get_executor_for_task(self, task: DefaultExecutionManager) -> TaskExecutor:
is_single_node_task = len(task.nodes) == 1
if not is_single_node_task:
raise ValueError("Only single node tasks supported")
node, = task.nodes
if indicator_tag in node.tags:
return self.remote_executor
return self.local_executor
def slurm(params):
# Decorator that:
# 0. Tags with the indicator above, with fn = tag(is_slurm_fn=True)(fn)
# 1. takes a function,
# 2. uses it to evaluate a config
# 3. launches a task
# 4. Polls that task on a loop
# 5. Returns the result or erorrs out (depending on how you want to do failure management)
# Call out to your class for these?
dr = (
driver
.Builder()
.enable_dynamic_execution(...)
.with_execution_manager(
RemoteDelegatingExecutionManager(
SynchronousLocalTaskExecutor(),
MultiThreadingExecutor(),
indicator_tag="is_slurm_fn")
)
)
dr.execute(["results"]) |
Beta Was this translation helpful? Give feedback.
-
Things to figure out:
Example user flow - 1 with polling:
Example user flow - 2 with fire & forget:
|
Beta Was this translation helpful? Give feedback.
-
This is a brainstorming discussion on what the shape of the API should be to support some decorators/functionality that would submit to slurm. The catalyst for this issue is @Roy-Kid !
For example, given a sketch of an API:
what do we want it to do and how do we want users to think?
Beta Was this translation helpful? Give feedback.
All reactions