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

Runtime environment can specify Julia executable and arguments #8

Merged
merged 7 commits into from
Sep 14, 2023
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
6 changes: 5 additions & 1 deletion dashboard/modules/runtime_env/runtime_env_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,11 @@ async def _setup_runtime_env(
# TODO(chenk008): Add log about allocated_resource to
# avoid lint error. That will be moved to cgroup plugin.
per_job_logger.debug(f"Worker has resource :" f"{allocated_resource}")
context = RuntimeEnvContext(env_vars=runtime_env.env_vars())
context = RuntimeEnvContext(
env_vars=runtime_env.env_vars(),
# TODO: use plugin instead of special casing
julia_command=runtime_env.julia_command(),
omus marked this conversation as resolved.
Show resolved Hide resolved
)
await self._container_manager.setup(
runtime_env, context, logger=per_job_logger
)
Expand Down
34 changes: 14 additions & 20 deletions python/ray/_private/runtime_env/context.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import logging
import os
import shlex
import subprocess
import sys
from typing import Any, Dict, List, Optional
Expand All @@ -25,6 +26,7 @@ def __init__(
resources_dir: Optional[str] = None,
container: Dict[str, Any] = None,
java_jars: List[str] = None,
julia_command: List[str] = None,
):
self.command_prefix = command_prefix or []
self.env_vars = env_vars or {}
Expand All @@ -36,6 +38,7 @@ def __init__(
self.resources_dir: str = resources_dir
self.container = container or {}
self.java_jars = java_jars or []
self.julia_command = julia_command or []

def serialize(self) -> str:
return json.dumps(self.__dict__)
Expand All @@ -47,16 +50,16 @@ def deserialize(json_string):
return RuntimeEnvContext(**json.loads(json_string))

def exec_worker(self, passthrough_args: List[str], language: Language):
# TODO(Beacon): remove these when we're done
# TODO(Beacon): remove these when we're done
logger.debug(f"Worker context env: {self.env_vars}")
update_envs(self.env_vars)

if language == Language.PYTHON and sys.platform == "win32":
executable = self.py_executable
command = [self.py_executable]
elif language == Language.PYTHON:
executable = f"exec {self.py_executable}"
command = ["exec", self.py_executable]
elif language == Language.JAVA:
executable = "java"
command = ["java"]
ray_jars = os.path.join(get_ray_jars_dir(), "*")

local_java_jars = []
Expand All @@ -67,23 +70,15 @@ def exec_worker(self, passthrough_args: List[str], language: Language):
class_path_args = ["-cp", ray_jars + ":" + str(":".join(local_java_jars))]
passthrough_args = class_path_args + passthrough_args
elif language == Language.JULIA:
executable = "julia"
args = [
"-e", "'using Ray; start_worker()'",
"--"
]
# TODO(omus): required to avoid escaping the Julia code. Ideally
# this information would be passed in via the serialized runtime
# context.
executable = " ".join([executable] + args)
command = self.julia_command or ["julia", "-e", "using Ray; start_worker()"]
command += ["--"]
elif sys.platform == "win32":
executable = ""
command = [""]
else:
executable = "exec "
command = ["exec"]

passthrough_args = [s.replace(" ", r"\ ") for s in passthrough_args]
exec_command = " ".join([f"{executable}"] + passthrough_args)
command_str = " ".join(self.command_prefix + [exec_command])
command = self.command_prefix + command + passthrough_args
command_str = shlex.join(command)
omus marked this conversation as resolved.
Show resolved Hide resolved
# TODO(SongGuyang): We add this env to command for macOS because it doesn't
# work for the C++ process of `os.execvp`. We should find a better way to
# fix it.
Expand All @@ -98,8 +93,7 @@ def exec_worker(self, passthrough_args: List[str], language: Language):
)
logger.debug(f"Exec'ing worker with command: {command_str}")
if sys.platform == "win32":
cmd = [*self.command_prefix, executable, *passthrough_args]
subprocess.Popen(cmd, shell=True).wait()
subprocess.Popen(command, shell=True).wait()
omus marked this conversation as resolved.
Show resolved Hide resolved
else:
# PyCharm will monkey patch the os.execvp at
# .pycharm_helpers/pydev/_pydev_bundle/pydev_monkey.py
Expand Down
8 changes: 8 additions & 0 deletions python/ray/runtime_env/runtime_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class MyClass:
"container",
"excludes",
"env_vars",
"julia_command",
"_ray_release",
"_ray_commit",
"_inject_current_ray",
Expand Down Expand Up @@ -308,6 +309,8 @@ def __init__(

if runtime_env.get("java_jars"):
runtime_env["java_jars"] = runtime_env.get("java_jars")
if runtime_env.get("julia_command"):
runtime_env["julia_command"] = runtime_env.get("julia_command")

self.update(runtime_env)

Expand Down Expand Up @@ -442,6 +445,11 @@ def java_jars(self) -> List[str]:
def env_vars(self) -> Dict:
return self.get("env_vars", {})

def julia_command(self) -> List[str]:
if "julia_command" in self:
return list(self["julia_command"])
return []

def has_conda(self) -> str:
if self.get("conda"):
return True
Expand Down