Skip to content
Snippets Groups Projects
Commit d0bab69d authored by Christian Witzler's avatar Christian Witzler
Browse files

Merge branch 'MPI_SLEEP' into 'main'

See merge request !62
parents bf5e343f 86c32804
No related branches found
No related tags found
1 merge request!62MPI sleep timer
Pipeline #144069 passed
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
### Added ### Added
- each non basic JuMonC plugin gets an automatic option to disable that plugin - each non basic JuMonC plugin gets an automatic option to disable that plugin
- standart function to add parameter to REST-API call (json_schema), to return a json schema describing the expected normal result for this path - standart function to add parameter to REST-API call (json_schema), to return a json schema describing the expected normal result for this path
- allow changes to the MPI_sleep_timer using the CMD parameters and the REST-API
### Changed ### Changed
- rename from JuMonC to jumonc for package name - rename from JuMonC to jumonc for package name
......
...@@ -10,6 +10,7 @@ usage: jumonc [-h] ...@@ -10,6 +10,7 @@ usage: jumonc [-h]
[--log-level {'ERROR','WARN','INFO','DEBUG'}] [--log-stdout] [--log-level {'ERROR','WARN','INFO','DEBUG'}] [--log-stdout]
[--log-prefix LOG_PREFIX] [--log-prefix LOG_PREFIX]
[--max-worker-threads MAX_WORKER_THREADS] [--max-worker-threads MAX_WORKER_THREADS]
[--mpi_sleep_timer MPI_SLEEP_TIMER]
[--only-choosen-rest-api-version] [--only-choosen-rest-api-version]
[--pending-tasks-soft-limit PENDING_TASKS_SOFT_LIMIT] [--pending-tasks-soft-limit PENDING_TASKS_SOFT_LIMIT]
[--plugin-paths [PLUGIN_PATHS ...]] [-p [1024-65535]] [--plugin-paths [PLUGIN_PATHS ...]] [-p [1024-65535]]
...@@ -36,6 +37,7 @@ usage: jumonc [-h] ...@@ -36,6 +37,7 @@ usage: jumonc [-h]
| |`--log-stdout` | |If used log to stdout, otherwise to stderr | | |`--log-stdout` | |If used log to stdout, otherwise to stderr |
| |`--log-prefix` |`` |Set a prefix that will be prefaced to every logging output | | |`--log-prefix` |`` |Set a prefix that will be prefaced to every logging output |
| |`--max-worker-threads` |`4` |Limits the number of worker threads that work on the actual tasks at once | | |`--max-worker-threads` |`4` |Limits the number of worker threads that work on the actual tasks at once |
| |`--mpi_sleep_timer` |`0.005` |Allow the CPU to idle before checking for new MPI communication, time in seconds between checks. Reduces CPU load but increases latency for requests |
| |`--only-choosen-rest-api-version` | |If set will only provide one version of the api links | | |`--only-choosen-rest-api-version` | |If set will only provide one version of the api links |
| |`--pending-tasks-soft-limit` |`100` |Limits tasks being added by the REST-API, to not have more than PENDING-TASKS-SOFT-LIMIT tasks waiting | | |`--pending-tasks-soft-limit` |`100` |Limits tasks being added by the REST-API, to not have more than PENDING-TASKS-SOFT-LIMIT tasks waiting |
| |`--plugin-paths` |`[]` |Paths to jumonc plugins, multiple values allowed | | |`--plugin-paths` |`[]` |Paths to jumonc plugins, multiple values allowed |
...@@ -103,6 +105,10 @@ Set a prefix that will be prefaced to every logging output ...@@ -103,6 +105,10 @@ Set a prefix that will be prefaced to every logging output
### `--max-worker-threads` (Default: 4) ### `--max-worker-threads` (Default: 4)
Limits the number of worker threads that work on the actual tasks at once Limits the number of worker threads that work on the actual tasks at once
### `--mpi_sleep_timer` (Default: 0.005)
Allow the CPU to idle before checking for new MPI communication, time in
seconds between checks. Reduces CPU load but increases latency for requests
### `--only-choosen-rest-api-version` ### `--only-choosen-rest-api-version`
If set will only provide one version of the api links If set will only provide one version of the api links
......
import logging
from typing import Dict
from typing import List
from typing import Union
from flask import jsonify
from flask import make_response
from flask import request
from flask import Response
from jumonc import settings
from jumonc.authentication import scopes
from jumonc.authentication.check import check_auth
from jumonc.handlers.base import api_version_path
from jumonc.handlers.base import check_version
from jumonc.handlers.base import RESTAPI
from jumonc.tasks import Settings
logger = logging.getLogger(__name__)
links: List[Dict[str, Union[bool, str, List[Dict[str, str]]]]] = []
settings_path = "/settings"
@RESTAPI.route(api_version_path + settings_path, methods=["GET"])
@check_version
@check_auth(scopes["see_links"])
def returnCPULinks(version: int) -> Response:
logger.debug("Accessed /v%i/settings/", version)
return make_response(jsonify(sorted(links, key=lambda dic: dic['link'])), 200)
def registerRestApiPaths(version: int) -> Dict[str, Union[bool, str, List[Dict[str, str]]]]:
registerSettingsLinks(version)
return {
"link": "/v" + str(version) + settings_path,
"isOptional": False,
"description": "Gather and change JuMonC parameters",
"parameters": [
{"name": "token",
"description": "Supply a token that shows you are allowed to access this link (or login once using /login)"}]
}
def registerSettingsLinks(version: int) -> None:
registerMPISleepLink(version)
def registerMPISleepLink(version:int) -> None:
logger.debug("Register \"/v%s%s/mpi_sleep_timer\"", str(version), settings_path)
@RESTAPI.route(api_version_path + settings_path + "/mpi_sleep_timer", methods=["GET"])
@check_version
@check_auth(scopes["full"])
def MPISleepTimer(version: int) -> Response:
logger.debug("Accessed /v%i/settings/mpi_sleep_timer/", version)
sleep_time = request.args.get('sleep_time', default = None, type = float)
if sleep_time is not None:
Settings.setMPISleep(sleep_time)
return make_response(jsonify({"Update MPI_sleep_timer": settings.MPI_sleep_timer}), 200)
return make_response(jsonify({"MPI_sleep_timer": settings.MPI_sleep_timer}), 200)
...@@ -65,12 +65,12 @@ def setupParser() -> argparse.ArgumentParser: ...@@ -65,12 +65,12 @@ def setupParser() -> argparse.ArgumentParser:
action='store_true') action='store_true')
parser.add_argument("--INIT-FILE".lower() , parser.add_argument("--INIT-FILE".lower() ,
dest="INIT_FILE", dest="INIT_FILE",
help=(("Path and filename to an init file, to overwrite settings. This file will be imported and allows abitrary code execution. " help=("Path and filename to an init file, to overwrite settings. This file will be imported and allows abitrary code execution. "
"Only use trustworthy sources for this init file. " "Only use trustworthy sources for this init file. "
"The settings from the init File take priority over all CMD arguments and will not be verified for correctness. " "The settings from the init File take priority over all CMD arguments and will not be verified for correctness. "
"All possible values (with their default values): " "All possible values (with their default values): "
"https://gitlab.jsc.fz-juelich.de/coec/jumonc/-/blob/main/jumonc/settings/__init__.py " "https://gitlab.jsc.fz-juelich.de/coec/jumonc/-/blob/main/jumonc/settings/__init__.py "
"An example init file can be seen at: https://gitlab.jsc.fz-juelich.de/coec/jumonc/-/blob/main/doc/CMD/init_jumonc.py ")), "An example init file can be seen at: https://gitlab.jsc.fz-juelich.de/coec/jumonc/-/blob/main/doc/CMD/init_jumonc.py "),
default=None, default=None,
type=str) type=str)
parser.add_argument("--LOCAL-ONLY".lower(), parser.add_argument("--LOCAL-ONLY".lower(),
...@@ -104,6 +104,12 @@ def setupParser() -> argparse.ArgumentParser: ...@@ -104,6 +104,12 @@ def setupParser() -> argparse.ArgumentParser:
help="Limits the number of worker threads that work on the actual tasks at once", help="Limits the number of worker threads that work on the actual tasks at once",
default=4, default=4,
type=int) type=int)
parser.add_argument("--MPI_SLEEP_TIMER".lower(),
dest="MPI_SLEEP_TIMER",
help=("Allow the CPU to idle before checking for new MPI communication, time in seconds between checks. "
"Reduces CPU load but increases latency for requests"),
default=0.005,
type=float)
parser.add_argument("--ONLY-CHOOSEN-REST-API-VERSION".lower(), parser.add_argument("--ONLY-CHOOSEN-REST-API-VERSION".lower(),
dest="ONLY_CHOOSEN_REST_API_VERSION", dest="ONLY_CHOOSEN_REST_API_VERSION",
help="If set will only provide one version of the api links", help="If set will only provide one version of the api links",
...@@ -204,7 +210,6 @@ def evaluateArgs(parser: argparse.ArgumentParser, args: List[str]) -> None: ...@@ -204,7 +210,6 @@ def evaluateArgs(parser: argparse.ArgumentParser, args: List[str]) -> None:
# After adding plugin arguments, reparse # After adding plugin arguments, reparse
addPluginArgs(parser) addPluginArgs(parser)
#parsed = parser.parse_args(args)
parsed, unknown = parser.parse_known_args(args) parsed, unknown = parser.parse_known_args(args)
logger.debug("Argument parsing, first pass") logger.debug("Argument parsing, first pass")
...@@ -217,8 +222,14 @@ def evaluateArgs(parser: argparse.ArgumentParser, args: List[str]) -> None: ...@@ -217,8 +222,14 @@ def evaluateArgs(parser: argparse.ArgumentParser, args: List[str]) -> None:
evaluateThreadingArgs(parsed) evaluateThreadingArgs(parsed)
evaluateSecurityArgs(parsed) evaluateSecurityArgs(parsed)
evaluateSchedulingArgs(parsed) evaluateSchedulingArgs(parsed)
# After adding plugin arguments, reparse
evaluteInitFile(parsed) evaluteInitFile(parsed)
parsed, unknown = parser.parse_known_args(args)
logger.debug("Argument parsing, first pass")
logger.debug("Parsed: %s", str(parsed))
logger.debug("Unknown: %s", str(unknown))
evaluatePluginArgs(parsed) evaluatePluginArgs(parsed)
logger.debug("Argument parsing") logger.debug("Argument parsing")
...@@ -368,6 +379,16 @@ def evaluateMiscellaneousArgs(parsed:argparse.Namespace) -> None: ...@@ -368,6 +379,16 @@ def evaluateMiscellaneousArgs(parsed:argparse.Namespace) -> None:
settings.PLUGIN_PATHS.extend(parsed.PLUGIN_PATHS) settings.PLUGIN_PATHS.extend(parsed.PLUGIN_PATHS)
logger.info("Set PLUGIN_PATHS to %s", str(settings.PLUGIN_PATHS)) logger.info("Set PLUGIN_PATHS to %s", str(settings.PLUGIN_PATHS))
if parsed.MPI_SLEEP_TIMER > 0.0:
settings.MPI_reduce_idle_CPU_load = True
settings.MPI_sleep_timer = parsed.MPI_SLEEP_TIMER
logger.info("Set MPI_SLEEP_TIMER to %s", str(settings.MPI_sleep_timer))
else:
settings.MPI_reduce_idle_CPU_load = False
settings.MPI_sleep_timer = 0.0
logger.info("Disabled MPI_SLEEP")
def evaluateSchedulingArgs(parsed:argparse.Namespace) -> None: def evaluateSchedulingArgs(parsed:argparse.Namespace) -> None:
......
...@@ -59,4 +59,4 @@ SCHEDULE_TASKS:List[str] = [] ...@@ -59,4 +59,4 @@ SCHEDULE_TASKS:List[str] = []
MPI_reduce_idle_CPU_load = True MPI_reduce_idle_CPU_load = True
MPI_sleep_timer=0.001 MPI_sleep_timer=0.005
import logging
from jumonc import settings
from jumonc.tasks.mpi_helper import multi_node_information
logger = logging.getLogger(__name__)
@multi_node_information()
def setMPISleep(sleep_time: float) -> None:
settings.MPI_sleep_timer = sleep_time
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment