Skip to content

Commit

Permalink
fix(launcher): add / correct default time limit in submission form (#…
Browse files Browse the repository at this point in the history
…1976)

ANT-1271
  • Loading branch information
laurent-laporte-pro authored Mar 14, 2024
2 parents ab1253e + 60cca11 commit 8b00715
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 30 deletions.
25 changes: 9 additions & 16 deletions antarest/launcher/adapters/slurm_launcher/slurm_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,22 +513,15 @@ def _apply_params(self, launcher_params: LauncherParametersDTO) -> argparse.Name
):
other_options.append("xpansion_sensitivity")

time_limit = launcher_params.time_limit
if time_limit is not None:
if MIN_TIME_LIMIT > time_limit:
logger.warning(
f"Invalid slurm launcher time limit ({time_limit}),"
f" should be higher than {MIN_TIME_LIMIT}. Using min limit."
)
launcher_args.time_limit = MIN_TIME_LIMIT
elif time_limit >= MAX_TIME_LIMIT:
logger.warning(
f"Invalid slurm launcher time limit ({time_limit}),"
f" should be lower than {MAX_TIME_LIMIT}. Using max limit."
)
launcher_args.time_limit = MAX_TIME_LIMIT - 3600
else:
launcher_args.time_limit = time_limit
# The `time_limit` parameter could be `None`, in that case, the default value is used.
time_limit = launcher_params.time_limit or MIN_TIME_LIMIT
time_limit = min(max(time_limit, MIN_TIME_LIMIT), MAX_TIME_LIMIT)
if launcher_args.time_limit != time_limit:
logger.warning(
f"Invalid slurm launcher time_limit ({time_limit}),"
f" should be between {MIN_TIME_LIMIT} and {MAX_TIME_LIMIT}"
)
launcher_args.time_limit = time_limit

post_processing = launcher_params.post_processing
if post_processing is not None:
Expand Down
3 changes: 2 additions & 1 deletion antarest/launcher/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ class LauncherParametersDTO(BaseModel):
adequacy_patch: t.Optional[t.Dict[str, t.Any]] = None
nb_cpu: t.Optional[int] = None
post_processing: bool = False
time_limit: t.Optional[int] = None # 3600 ≤ time_limit < 864000 (10 days)
time_limit: int = 240 * 3600 # Default value set to 240 hours (in seconds)
xpansion: t.Union[XpansionParametersDTO, bool, None] = None
xpansion_r_version: bool = False
archive_output: bool = True
auto_unzip: bool = True
output_suffix: t.Optional[str] = None
other_options: t.Optional[str] = None

# add extensions field here

@classmethod
Expand Down
8 changes: 5 additions & 3 deletions tests/launcher/test_slurm_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from antareslauncher.data_repo.data_repo_tinydb import DataRepoTinydb
from antareslauncher.main import MainParameters
from antareslauncher.study_dto import StudyDTO
from sqlalchemy.orm import Session # type: ignore

from antarest.core.config import Config, LauncherConfig, NbCoresConfig, SlurmConfig
from antarest.launcher.adapters.abstractlauncher import LauncherInitException
Expand All @@ -37,7 +36,7 @@ def launcher_config(tmp_path: Path) -> Config:
"key_password": "password",
"password": "password",
"default_wait_time": 10,
"default_time_limit": 20,
"default_time_limit": MAX_TIME_LIMIT,
"default_json_db_name": "antares.db",
"slurm_script_path": "/path/to/slurm/launcher.sh",
"partition": "fake_partition",
Expand Down Expand Up @@ -203,11 +202,14 @@ def test_extra_parameters(launcher_config: Config) -> None:
launcher_params = apply_params(LauncherParametersDTO(nb_cpu=999))
assert launcher_params.n_cpu == slurm_config.nb_cores.default # out of range

launcher_params = apply_params(LauncherParametersDTO.construct(time_limit=None))
assert launcher_params.time_limit == MIN_TIME_LIMIT

launcher_params = apply_params(LauncherParametersDTO(time_limit=10))
assert launcher_params.time_limit == MIN_TIME_LIMIT

launcher_params = apply_params(LauncherParametersDTO(time_limit=999999999))
assert launcher_params.time_limit == MAX_TIME_LIMIT - 3600
assert launcher_params.time_limit == MAX_TIME_LIMIT

launcher_params = apply_params(LauncherParametersDTO(time_limit=99999))
assert launcher_params.time_limit == 99999
Expand Down
28 changes: 18 additions & 10 deletions webapp/src/components/App/Studies/LauncherDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ import CheckBoxFE from "../../common/fieldEditors/CheckBoxFE";
import { convertVersions } from "../../../services/utils";
import UsePromiseCond from "../../common/utils/UsePromiseCond";
import SwitchFE from "../../common/fieldEditors/SwitchFE";
import moment from "moment";

const LAUNCH_LOAD_DEFAULT = 22;
const DEFAULT_NB_CPU = 22;
const DEFAULT_TIME_LIMIT = 240 * 3600; // 240 hours in seconds

interface Props {
open: boolean;
Expand All @@ -53,8 +55,9 @@ function LauncherDialog(props: Props) {
const { enqueueSnackbar } = useSnackbar();
const enqueueErrorSnackbar = useEnqueueErrorSnackbar();
const [options, setOptions] = useState<LaunchOptions>({
nb_cpu: LAUNCH_LOAD_DEFAULT,
nb_cpu: DEFAULT_NB_CPU,
auto_unzip: true,
time_limit: DEFAULT_TIME_LIMIT,
});
const [solverVersion, setSolverVersion] = useState<string>();
const [isLaunching, setIsLaunching] = useState(false);
Expand Down Expand Up @@ -170,12 +173,16 @@ function LauncherDialog(props: Props) {
// Utils
////////////////////////////////////////////////////////////////

const timeLimitParse = (value: string): number => {
try {
return parseInt(value, 10) * 3600;
} catch {
return 48 * 3600;
}
/**
* Parses an hour value from a string and converts it to seconds.
* If the input is invalid, returns a default value.
*
* @param hourString - A string representing the number of hours.
* @returns The equivalent number of seconds, or a default value for invalid inputs.
*/
const parseHoursToSeconds = (hourString: string): number => {
const seconds = moment.duration(hourString, "hours").asSeconds();
return seconds > 0 ? seconds : DEFAULT_TIME_LIMIT;
};

////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -265,9 +272,10 @@ function LauncherDialog(props: Props) {
label={t("study.timeLimit")}
type="number"
variant="filled"
value={(options.time_limit ?? 864000) / 3600} // 240 hours default
// Convert from seconds to hours the displayed value
value={(options.time_limit ?? DEFAULT_TIME_LIMIT) / 3600}
onChange={(e) =>
handleChange("time_limit", timeLimitParse(e.target.value))
handleChange("time_limit", parseHoursToSeconds(e.target.value))
}
InputLabelProps={{
shrink: true,
Expand Down

0 comments on commit 8b00715

Please sign in to comment.