diff --git a/joj3_config_generator/models/task.py b/joj3_config_generator/models/task.py index 52966a8..ededc4e 100644 --- a/joj3_config_generator/models/task.py +++ b/joj3_config_generator/models/task.py @@ -16,6 +16,7 @@ from pydantic import ( from joj3_config_generator.models.common import Memory, Time from joj3_config_generator.models.const import ( DEFAULT_CASE_SCORE, + DEFAULT_CLOCK_LIMIT_MULTIPLIER, DEFAULT_CPU_LIMIT, DEFAULT_FILE_LIMIT, DEFAULT_MEMORY_LIMIT, @@ -143,25 +144,30 @@ class StageFiles(BaseModel): class Limit(BaseModel): mem: int = DEFAULT_MEMORY_LIMIT cpu: int = DEFAULT_CPU_LIMIT + time: int = 0 stdout: int = DEFAULT_FILE_LIMIT stderr: int = DEFAULT_FILE_LIMIT proc: int = DEFAULT_PROC_LIMIT - model_config = ConfigDict(validate_assignment=True) - - @field_validator("cpu", mode="before") + @field_validator("cpu", "time", mode="before") @classmethod - def ensure_time(cls, v: Any) -> Time: + def ensure_time_type(cls, v: Any) -> Time: if isinstance(v, str): return Time(v) - raise ValueError("Must be a string") + raise ValueError(f'Must be a string, e.g., "1s" or "100ms", but got {v}') @field_validator("mem", "stdout", "stderr", mode="before") @classmethod - def ensure_mem(cls, v: Any) -> Memory: + def ensure_mem_type(cls, v: Any) -> Memory: if isinstance(v, str): return Memory(v) - raise ValueError("Must be a string") + raise ValueError(f'Must be a string, e.g., "256m" or "1g", but got {v}') + + @model_validator(mode="after") + def set_time_if_not_set(self) -> "Limit": + if self.time == 0: + self.time = DEFAULT_CLOCK_LIMIT_MULTIPLIER * self.cpu + return self class Parser(str, Enum): diff --git a/joj3_config_generator/transformers/task.py b/joj3_config_generator/transformers/task.py index 6b2e92e..f635ca5 100644 --- a/joj3_config_generator/transformers/task.py +++ b/joj3_config_generator/transformers/task.py @@ -5,12 +5,7 @@ from pathlib import Path, PurePosixPath from typing import Any, Callable, Dict, List, Optional, Tuple, Union from joj3_config_generator.models import result, task -from joj3_config_generator.models.common import Memory, Time -from joj3_config_generator.models.const import ( - DEFAULT_CLOCK_LIMIT_MULTIPLIER, - DEFAULT_PATH_ENV, - JOJ3_CONFIG_ROOT, -) +from joj3_config_generator.models.const import DEFAULT_PATH_ENV, JOJ3_CONFIG_ROOT from joj3_config_generator.utils.logger import logger @@ -102,15 +97,15 @@ def get_executor_with( copy_out=copy_out_files, copy_in_cached={file: file for file in cached}, copy_out_cached=file_export, - cpu_limit=Time(task_stage.limit.cpu), - clock_limit=DEFAULT_CLOCK_LIMIT_MULTIPLIER * Time(task_stage.limit.cpu), - memory_limit=Memory(task_stage.limit.mem), + cpu_limit=task_stage.limit.cpu, + clock_limit=task_stage.limit.time, + memory_limit=task_stage.limit.mem, proc_limit=task_stage.limit.proc, stderr=result.Collector( - name="stderr", pipe=True, max=Memory(task_stage.limit.stderr) + name="stderr", pipe=True, max=task_stage.limit.stderr ), stdout=result.Collector( - name="stdout", pipe=True, max=Memory(task_stage.limit.stdout) + name="stdout", pipe=True, max=task_stage.limit.stdout ), ), cases=[], @@ -218,7 +213,7 @@ def fix_diff( stdin=stdin, args=shlex.split(case.command) if case.command else None, cpu_limit=case.limit.cpu, - clock_limit=DEFAULT_CLOCK_LIMIT_MULTIPLIER * case.limit.cpu, + clock_limit=case.limit.time, memory_limit=case.limit.mem, proc_limit=task_stage.limit.proc, ) diff --git a/tests/convert/basic/task.json b/tests/convert/basic/task.json index a4097a5..864f918 100644 --- a/tests/convert/basic/task.json +++ b/tests/convert/basic/task.json @@ -741,7 +741,7 @@ "pipe": true }, "cpuLimit": 1000000000, - "clockLimit": 2000000000, + "clockLimit": 100000000000, "memoryLimit": 134217728, "stackLimit": 0, "procLimit": 50, diff --git a/tests/convert/basic/task.toml b/tests/convert/basic/task.toml index 382aa97..e54dbef 100644 --- a/tests/convert/basic/task.toml +++ b/tests/convert/basic/task.toml @@ -91,6 +91,7 @@ command="./h7/build/ex2-asan -a" copy-in-cwd = false files.import = [ "h7/build/ex2-asan" ] limit.mem = "128m" +limit.time = "100s" diff.score = 10 @@ -100,6 +101,7 @@ result-detail.stderr = true # will be removed as long as the name is fixed case0.limit.cpu = "0.5s" +case0.limit.time = "1s" case0.limit.mem = "5m" case0.diff.ignore-spaces = true #case0.limit.stdout = 8