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

Support energy schedule #2903

Merged
merged 6 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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 .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repos:
hooks:
- id: sort-all
- repo: https://github.com/PyCQA/isort
rev: '5.10.1'
rev: '5.12.0'
hooks:
- id: isort
- repo: https://github.com/psf/black
Expand Down
3 changes: 3 additions & 0 deletions CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,7 @@ neuro config show [OPTIONS]
Name | Description|
|----|------------|
|_--help_|Show this message and exit.|
|_--energy_|Including cluster energy consumption and CO2 emissions information|



Expand Down Expand Up @@ -2693,6 +2694,7 @@ Name | Description|
|_--cluster CLUSTER_|Run job in a specified cluster|
|_\-d, --description DESC_|Optional job description in free format|
|_--detach_|Don't attach to job logs and don't wait for exit code|
|_\--energy-schedule NAME_|Run job only within a selected energy schedule. Selected preset should have scheduler enabled.|
|_--entrypoint TEXT_|Executable entrypoint in the container \(note that it overwrites `ENTRYPOINT` and `CMD` instructions of the docker image)|
|_\-e, --env VAR=VAL_|Set environment variable in container. Use multiple options to define more than one variable. See `neuro help secrets` for information about passing secrets as environment variables.|
|_\--env-file PATH_|File with environment variables to pass|
Expand Down Expand Up @@ -3827,6 +3829,7 @@ Name | Description|
|_--cluster CLUSTER_|Run job in a specified cluster|
|_\-d, --description DESC_|Optional job description in free format|
|_--detach_|Don't attach to job logs and don't wait for exit code|
|_\--energy-schedule NAME_|Run job only within a selected energy schedule. Selected preset should have scheduler enabled.|
|_--entrypoint TEXT_|Executable entrypoint in the container \(note that it overwrites `ENTRYPOINT` and `CMD` instructions of the docker image)|
|_\-e, --env VAR=VAL_|Set environment variable in container. Use multiple options to define more than one variable. See `neuro help secrets` for information about passing secrets as environment variables.|
|_\--env-file PATH_|File with environment variables to pass|
Expand Down
1 change: 1 addition & 0 deletions neuro-cli/docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ Print current settings.
| Name | Description |
| :--- | :--- |
| _--help_ | Show this message and exit. |
| _--energy_ | Including cluster energy consumption and CO2 emissions information |



Expand Down
1 change: 1 addition & 0 deletions neuro-cli/docs/job.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ $ neuro run -s cpu-small --entrypoint=/script.sh image:my-ubuntu:latest -- arg1
| _--cluster CLUSTER_ | Run job in a specified cluster |
| _-d, --description DESC_ | Optional job description in free format |
| _--detach_ | Don't attach to job logs and don't wait for exit code |
| _--energy-schedule NAME_ | Run job only within a selected energy schedule. Selected preset should have scheduler enabled. |
| _--entrypoint TEXT_ | Executable entrypoint in the container \(note that it overwrites `ENTRYPOINT` and `CMD` instructions of the docker image\) |
| _-e, --env VAR=VAL_ | Set environment variable in container. Use multiple options to define more than one variable. See `neuro help secrets` for information about passing secrets as environment variables. |
| _--env-file PATH_ | File with environment variables to pass |
Expand Down
1 change: 1 addition & 0 deletions neuro-cli/docs/shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ $ neuro run -s cpu-small --entrypoint=/script.sh image:my-ubuntu:latest -- arg1
| _--cluster CLUSTER_ | Run job in a specified cluster |
| _-d, --description DESC_ | Optional job description in free format |
| _--detach_ | Don't attach to job logs and don't wait for exit code |
| _--energy-schedule NAME_ | Run job only within a selected energy schedule. Selected preset should have scheduler enabled. |
| _--entrypoint TEXT_ | Executable entrypoint in the container \(note that it overwrites `ENTRYPOINT` and `CMD` instructions of the docker image\) |
| _-e, --env VAR=VAL_ | Set environment variable in container. Use multiple options to define more than one variable. See `neuro help secrets` for information about passing secrets as environment variables. |
| _--env-file PATH_ | File with environment variables to pass |
Expand Down
4 changes: 3 additions & 1 deletion neuro-cli/src/neuro_cli/asyncio_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ def __del__(self, _warn: Any = warnings.warn) -> None:
source=self,
)

def add_child_handler(self, pid: int, callback: _Callback, *args: Any) -> None:
def add_child_handler( # type: ignore
self, pid: int, callback: _Callback, *args: Any
) -> None:
loop = asyncio.get_event_loop()
thread = threading.Thread(
target=self._do_waitpid,
Expand Down
12 changes: 10 additions & 2 deletions neuro-cli/src/neuro_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ def config() -> None:


@command()
async def show(root: Root) -> None:
@option(
"--energy",
is_flag=True,
help="Including cluster energy consumption and CO2 emissions information",
)
async def show(root: Root, energy: bool) -> None:
"""
Print current settings.
"""
Expand All @@ -48,7 +53,10 @@ async def show(root: Root) -> None:
jobs_capacity = {}
quota = await root.client.users.get_quota()
org_quota = await root.client.users.get_org_quota()
root.print(fmt(root.client.config, jobs_capacity, quota, org_quota))
config_cluster = None
if energy:
config_cluster = await root.client._clusters.get_cluster(cluster_name)
dalazx marked this conversation as resolved.
Show resolved Hide resolved
root.print(fmt(root.client.config, jobs_capacity, quota, org_quota, config_cluster))


@command()
Expand Down
47 changes: 41 additions & 6 deletions neuro-cli/src/neuro_cli/formatters/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import operator
from decimal import Decimal
from typing import Iterable, List, Mapping, Optional, Union
from typing import Iterable, List, Mapping, Optional, Sequence, Union

import click
from rich import box
Expand All @@ -10,7 +10,7 @@
from rich.table import Table
from rich.text import Text

from neuro_sdk import Cluster, Config, Preset, Quota, _Balance, _Quota
from neuro_sdk import Cluster, Config, Preset, Quota, _Balance, _ConfigCluster, _Quota

from neuro_cli.click_types import OrgType
from neuro_cli.utils import format_size
Expand All @@ -23,6 +23,7 @@ def __call__(
available_jobs_counts: Mapping[str, int],
quota: Quota,
org_quota: Optional[Quota],
config_cluster: Optional[_ConfigCluster] = None,
) -> RenderableType:
table = Table(
title="User Configuration:",
Expand All @@ -46,10 +47,10 @@ def __call__(
table.add_row("API URL", str(config.api_url))
table.add_row("Docker Registry URL", str(config.registry_url))

return RichGroup(
table,
_format_presets(config.presets, available_jobs_counts),
)
to_render = [table, _format_presets(config.presets, available_jobs_counts)]
if config_cluster and config_cluster.energy:
to_render.extend(_format_cluster_energy(config_cluster)) # type: ignore
return RichGroup(*to_render)


class AdminQuotaFormatter:
Expand Down Expand Up @@ -158,6 +159,40 @@ def _format_presets(
return table


def _format_cluster_energy(cluster: _ConfigCluster) -> Sequence[RenderableType]:
assert cluster.energy

summary = [
Text("Cluster energy parameters", style="i"),
Text.assemble(
Text("CO2 emmitions (g/kWh): "),
Text(str(cluster.energy.g_co2eq_kwh), style="b"),
),
]

schedules_tbl = Table(
title="Energy schedules",
title_justify="left",
box=box.SIMPLE_HEAVY,
show_edge=False,
)
schedules_tbl.add_column("Name", style="bold", justify="left")
schedules_tbl.add_column("Price (kW/h)", justify="center")
schedules_tbl.add_column("Weekday", justify="center")
schedules_tbl.add_column("Period start time", justify="center")
schedules_tbl.add_column("Period end time", justify="center")
for schedule in cluster.energy.schedules:
for period in schedule.periods:
schedules_tbl.add_row(
str(schedule.name),
str(schedule.price_kwh),
str(period.weekday),
period.start_time.strftime("%H:%M:%S"),
period.end_time.strftime("%H:%M:%S"),
)
return *summary, schedules_tbl


class AliasesFormatter:
def __call__(self, aliases: Iterable[click.Command]) -> Table:
table = Table(box=box.MINIMAL_HEAVY_HEAD)
Expand Down
2 changes: 2 additions & 0 deletions neuro-cli/src/neuro_cli/formatters/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ def __call__(self, job_status: JobDescription) -> RenderableType:
table.add_row("Working dir", job_status.container.working_dir)
if job_status.preset_name:
table.add_row("Preset", job_status.preset_name)
if job_status.energy_schedule_name:
table.add_row("Energy schedule", job_status.energy_schedule_name)
table.add_row("Priority", f"{job_status.priority.name.capitalize()}")
table.add_row(
"Price (credits / hour)", f"{job_status.price_credits_per_hour:.4f}"
Expand Down
16 changes: 15 additions & 1 deletion neuro-cli/src/neuro_cli/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,14 @@ async def kill(root: Root, jobs: Sequence[str]) -> None:
"Jobs with higher priority will start before ones with lower priority. "
"Priority should be supported by cluster.",
)
@option(
"--energy-schedule",
metavar="NAME",
help=(
"Run job only within a selected energy schedule. "
"Selected preset should have scheduler enabled."
),
)
@TTY_OPT
async def run(
root: Root,
Expand Down Expand Up @@ -1055,6 +1063,7 @@ async def run(
privileged: bool,
share: Sequence[str],
priority: Optional[str],
energy_schedule: Optional[str],
) -> None:
"""
Run a job
Expand Down Expand Up @@ -1123,6 +1132,7 @@ async def run(
cluster_name=cluster_name,
org_name=org_name,
priority=priority,
energy_schedule_name=energy_schedule,
)


Expand Down Expand Up @@ -1194,6 +1204,7 @@ async def run_job(
cluster_name: str,
org_name: Optional[str],
priority: Optional[str],
energy_schedule_name: Optional[str],
) -> JobDescription:
if http_auth is None:
http_auth = True
Expand Down Expand Up @@ -1291,6 +1302,7 @@ async def _force_disk_id(disk_uri: URL) -> URL:
schedule_timeout=job_schedule_timeout,
privileged=privileged,
priority=job_priority,
energy_schedule_name=energy_schedule_name,
)
permission = Permission(job.uri, Action.WRITE)
for user in share:
Expand Down Expand Up @@ -1467,9 +1479,11 @@ def _job_to_cli_args(job: JobDescription) -> List[str]:
res += ["--privileged"]
if job.priority != JobPriority.NORMAL:
res += ["--priority", job.priority.name.lower()]
if job.energy_schedule_name:
res += ["--energy-schedule", job.energy_schedule_name]
res += [str(job.container.image)]
if job.container.command:
res += [job.container.command]
res += ["--", job.container.command]
dalazx marked this conversation as resolved.
Show resolved Hide resolved
return res


Expand Down
2 changes: 1 addition & 1 deletion neuro-cli/tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def _run_cli(arguments: List[str]) -> SysCapWithCode:

main(default_args + arguments)
except SystemExit as e:
code = e.code
code = e.code # type: ignore
pass
out, err = capfd.readouterr()
return SysCapWithCode(out.strip(), err.strip(), code)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
User Configuration:
User Name user
Current Cluster default
Current Org <no-org>
Credits Quota 500.00
Jobs Quota 10
API URL https://dev.neu.ro/api/v1
Docker Registry URL https://registry-dev.neu.ro
Resource Presets:
Name #CPU Memory Round Robin Preemptible Node GPU Credits per hour
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
gpu-small 7 32.2 GB × × 1 x nvidia-tesla-k80 10
gpu-large 7 64.4 GB × × 1 x nvidia-tesla-v100 10
cpu-small 7 2.1 GB × × 10
cpu-large 7 15.0 GB × × 10
Cluster energy parameters
CO2 emmitions (g/kWh): 40.4
Energy schedules
Name Price (kW/h) Weekday Period start time Period end time
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DEFAULT 0 1 00:00:00 23:59:59
dalazx marked this conversation as resolved.
Show resolved Hide resolved
DEFAULT 0 2 00:00:00 23:59:59
DEFAULT 0 3 00:00:00 23:59:59
DEFAULT 0 4 00:00:00 23:59:59
DEFAULT 0 5 00:00:00 23:59:59
DEFAULT 0 6 00:00:00 23:59:59
DEFAULT 0 7 00:00:00 23:59:59
GREEN 0 1 00:00:00 08:00:00
GREEN 0 2 00:00:00 08:00:00
GREEN 0 3 00:00:00 08:00:00
GREEN 0 4 00:00:00 08:00:00
GREEN 0 5 00:00:00 08:00:00
GREEN 0 6 00:00:00 08:00:00
GREEN 0 7 00:00:00 08:00:00
GREEN 0 1 20:00:00 23:59:59
GREEN 0 2 20:00:00 23:59:59
GREEN 0 3 20:00:00 23:59:59
GREEN 0 4 20:00:00 23:59:59
GREEN 0 5 20:00:00 23:59:59
GREEN 0 6 20:00:00 23:59:59
GREEN 0 7 20:00:00 23:59:59
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Job test-job
Owner owner
Cluster default
Description test job description
Status pending
Image test-image
Command test-command
Preset cpu-small
Energy schedule some-schedule
Priority Normal
Price (credits / hour) 15.0000
Current cost 150.0000
Resources Memory 16.8 MB
CPU 0.1
Round Robin True
TTY False
Created Sep 25 2018 at 12:28
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Job test-job
Owner owner
Cluster default
Description test job description
Status pending
Image test-image
Command test-command
Preset cpu-small
Energy schedule some-schedule
Priority Normal
Price (credits / hour) 15.0000
Current cost 150.0000
Resources Memory 16.8 MB
CPU 0.1
Round Robin True
TTY False
Created 2018-09-25T12:28:21.298672+00:00
Loading