diff --git a/README.md b/README.md index 8ed09c18..2866782d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # NRM Python -Python binaries and notebook infrastructure on top of nrm-core. +Python binaries and notebook infrastructure on top of libnrm. Currently contains the official nrm daemon implementation, as well as additional python modules to talk to the NRM from a python application, both diff --git a/nrm/api/__init__.py b/nrm/api/__init__.py new file mode 100644 index 00000000..9455df56 --- /dev/null +++ b/nrm/api/__init__.py @@ -0,0 +1,12 @@ +############################################################################### +# Copyright 2023 UChicago Argonne, LLC. +# (c.f. AUTHORS, LICENSE) +# +# This file is part of the NRM project. +# For more info, see https://github.com/anlsys/nrm-python +# +# SPDX-License-Identifier: BSD-3-Clause +############################################################################### + +from .components import Actuator, Scope, Sensor, Slice +from .client import Client diff --git a/bin/nrmd b/nrm/api/_build/__init__.py old mode 100755 new mode 100644 similarity index 52% rename from bin/nrmd rename to nrm/api/_build/__init__.py index 94aef68d..e5433105 --- a/bin/nrmd +++ b/nrm/api/_build/__init__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 ############################################################################### # Copyright 2019 UChicago Argonne, LLC. # (c.f. AUTHORS, LICENSE) @@ -8,17 +7,3 @@ # # SPDX-License-Identifier: BSD-3-Clause ############################################################################### - -import sys -from nrm.sharedlib import WrapEither, Lib -import nrm.daemon -import os -from ctypes.util import find_library - -nrmcoreso = find_library("nrm-core") -if not nrmcoreso: - nrmcoreso = os.environ.get("NRMSO") - -with Lib(nrmcoreso) as lib: - cfg = lib.cli(sys.argv[1:]) - nrm.daemon.runner(cfg, lib) diff --git a/nrm/api/build.py b/nrm/api/build.py new file mode 100644 index 00000000..2c764e2f --- /dev/null +++ b/nrm/api/build.py @@ -0,0 +1,78 @@ +from cffi import FFI +import subprocess +import os + +ffi = FFI() + +ffi.set_source( + "nrm.api._build._nrm_cffi", + """ + #include "nrm.h" + """, + libraries=["nrm"], +) + +def my_temporary_header_locator(): + return subprocess.Popen(["find", "../libnrm", "-name", "nrm.h"], stdout=subprocess.PIPE).communicate()[0].decode().split("\n")[0] + +nrmh = my_temporary_header_locator() + +cdef_base = \ +""" + +typedef int... time_t; + +typedef struct timespec{ + time_t tv_sec; + long tv_nsec; +}; + +typedef struct timespec nrm_time_t; + +nrm_time_t nrm_time_fromns(int64_t ns); +typedef char *nrm_string_t; +typedef nrm_string_t nrm_uuid_t; +typedef struct nrm_vector_s nrm_vector_t; +typedef struct nrm_scope nrm_scope_t; + +extern "Python" int _event_listener_wrap(nrm_string_t sensor_uuid, + nrm_time_t time, + nrm_scope_t *scope, + double value, + void *arg); + +extern "Python" int _actuate_listener_wrap(nrm_uuid_t *uuid, + double value, + void *arg); + +nrm_string_t nrm_string_fromchar(const char *buf); + +void nrm_time_gettime(nrm_time_t *now); + +int nrm_scope_destroy(nrm_scope_t *scope); + +""" + +with open(nrmh, "r") as f: + lines = f.readlines() + +avoid_tokens = ["#", "extern \"C\" {", " nrm_log_printf("] +avoid_block = [ +"\tdo { \\\n", +"\t\tchar *__nrm_errstr = strerror(errno); \\\n", +"\t\tnrm_log_printf(NRM_LOG_ERROR, __FILE__, __LINE__, \\\n", +"\t\t __VA_ARGS__); \\\n", +"\t\tnrm_log_printf(NRM_LOG_ERROR, __FILE__, __LINE__, \\\n", +"\t\t \"perror: %s\\n\", __nrm_errstr); \\\n", +"\t} while (0)\n", +] + +for line in lines: + if not any([line.startswith(token) for token in avoid_tokens]) and line not in avoid_block: + cdef_base += line + + +ffi.cdef(cdef_base) + +if __name__ == "__main__": + ffi.compile(verbose=True) diff --git a/nrm/api/client.py b/nrm/api/client.py new file mode 100644 index 00000000..952c75bc --- /dev/null +++ b/nrm/api/client.py @@ -0,0 +1,188 @@ +import time +from loguru import logger +from dataclasses import dataclass, field +from typing import Callable, List, Union + +from nrm.api._build._nrm_cffi import ffi, lib +from nrm.api.components import ( + NRMActuators, + NRMScopes, + NRMSensors, + NRMSlices, + Actuator, + Scope, + Sensor, + Slice, +) + + +@dataclass +class Client: + """Client class for interacting with NRM C interface. Use as a context switcher. + Tentative usage: + ``` + from nrm.api import Client, Actuator + with Client("tcp://127.0.0.1", 2345, 3456) as nrmc: + ... + nrmc.scopes["uuid"] = my_scope + + ... + nrmc.send_event(sensor, scope, 1234) + ... + + ``` + """ + + scopes: NRMScopes = field(default_factory=NRMScopes) + sensors: NRMSensors = field(default_factory=NRMSensors) + slices: NRMSlices = field(default_factory=NRMSlices) + actuators: NRMActuators = field(default_factory=NRMActuators) + + def __enter__( + self, uri: str = "tcp://127.0.0.1", pub_port: int = 2345, rpc_port: int = 3456 + ): + self._c_client_p = ffi.new("nrm_client_t **") + self._c_uri = ffi.new("char[]", bytes(uri, "utf-8")) + self._pyinfo_p = ffi.new("pyinfo_t **") + self._py_client_h = ffi.new_handle(self) + self.pub_port = pub_port + self.rpc_port = rpc_port + + assert not lib.nrm_init( + ffi.NULL, ffi.NULL + ), "NRM library did not initialize successfully" + logger.debug("NRM initialized") + + assert not lib.nrm_client_create( + self._c_client_p, self._c_uri, self.pub_port, self.rpc_port + ), "Python Client was unable to instantiate an underlying NRM C client" + logger.debug("NRM client created") + self._c_client = self._c_client_p[0] + + assert not lib.nrm_pyinfo_create( + self._pyinfo_p, + self._py_client_h, + lib._event_listener_wrap, + lib._actuate_listener_wrap, + ), "Python Client was unable to instantiate an underlying NRM C structure" + logger.debug("C pyinfo structure populated") + self._pyinfo = self._pyinfo_p[0] + + for d in [self.scopes, self.sensors, self.slices, self.actuators]: + d._set_client(self._c_client) + logger.debug( + "NRM client assigned to Scopes, Sensors, Slices, and Actuators dict subclasses" + ) + logger.info("Client instance initialized. Starting") + return self + + def __exit__(self, exc_type, exc_value, traceback): + logger.info("Destroying Client instance") + lib.nrm_client_destroy(self._c_client_p) + + def actuate(self, actuator: "Actuator", value: float) -> int: + """Perform an actuation given an actuator and a value to set. Register this actuator + with the client first: + ``` + from nrm.api import Client, Actuator + act = Actuator("my-actuator") + act.set_choices(1.0, 2.0, 3.0, 4.0) + with Client("tcp://127.0.0.1", 2345, 3456) as nrmc: + ``` + NOTE: The given value should've already been set with `actuator_instance.set_values()`. + + Parameters + ---------- + """ + logger.debug(f"ACTUATING with (actuator: {actuator}), (value: {value})") + return lib.nrm_client_actuate(self._c_client, actuator._actuator_ptr[0], value) + + def send_event(self, sensor: "Sensor", scope: "Scope", value: float) -> int: + """ + Parameters + ---------- + """ + timespec = lib.nrm_time_fromns(time.time_ns()) + logger.debug( + f"SENDING EVENT with (sensor: {sensor}), (value: {value}), (Value: {value})" + ) + return lib.nrm_client_send_event( + self._c_client, timespec, sensor._sensor_ptr[0], scope._scope_ptr, value + ) + + def set_event_listener(self, event_listener: Callable) -> int: + """ + Parameters + ---------- + """ + self._event_listener = event_listener + logger.debug(f"Setting event Python callback: {event_listener}") + return lib.nrm_client_set_event_Pylistener(self._c_client, self._pyinfo) + + def start_event_listener(self, topic: str) -> int: + """ + Parameters + ---------- + """ + topic = ffi.new("char []", bytes(topic, "utf-8")) + topic_as_nrm_string_t = ffi.new("nrm_string_t *", topic) + logger.debug(f"Starting event listener. Will call: {self._event_listener}") + return lib.nrm_client_start_event_listener(self._c_client, topic) + + def set_actuate_listener(self, actuate_listener: Callable) -> int: + """ + Parameters + ---------- + """ + self._actuate_listener = actuate_listener + logger.debug(f"Setting actuate Python callback: {actuate_listener}") + return lib.nrm_client_set_actuate_Pylistener(self._c_client, self._pyinfo) + + def start_actuate_listener(self) -> int: + """ + Returns + ------- + """ + logger.debug(f"Starting actuate listener. Will call: {self._actuate_listener}") + return lib.nrm_client_start_actuate_listener(self._c_client) + + def remove(self, obj) -> int: + + if isinstance(obj, Actuator): + return lib.nrm_client_remove_actuator(self._c_client, obj._actuator_ptr[0]) + elif isinstance(obj, Slice): + return lib.nrm_client_remove_slice(self._c_client, obj._slice_ptr[0]) + elif isinstance(obj, Sensor): + return lib.nrm_client_remove_sensor(self._c_client, obj._sensor_ptr[0]) + else: + return lib.nrm_client_remove_scope(self._c_client, obj._scope_ptr) + + def send_exit(self) -> int: + logger.debug("Sending daemon EXIT request") + return lib.nrm_client_send_exit(self._c_client) + + def send_tick(self) -> int: + logger.debug("Sending daemon TICK request") + return lib.nrm_client_send_tick(self._c_client) + + def _event(self, sensor_uuid, time, scope, value): + logger.debug(f"Calling event callback: {self._event_listener}") + return self._event_listener(sensor_uuid, time, scope, value) + + def _actuate(self, uuid, value): + logger.debug(f"Calling actuate callback: {self._actuate_listener}") + return self._actuate_listener(uuid, value) + + +@ffi.def_extern() +def _event_listener_wrap( + sensor_uuid, timespec, scope, value, py_client +): # see build.py for the C declaration of this and _actuate_listener_wrap + logger.debug("In event extern wrapper. Unpacking client") + return ffi.from_handle(py_client)._event(sensor_uuid, timespec, scope, value) + + +@ffi.def_extern() +def _actuate_listener_wrap(uuid, value, py_client): + logger.debug("In actuate extern wrapper. Unpacking client") + return ffi.from_handle(py_client)._actuate(uuid, value) diff --git a/nrm/api/components.py b/nrm/api/components.py new file mode 100644 index 00000000..56cc2693 --- /dev/null +++ b/nrm/api/components.py @@ -0,0 +1,139 @@ +from typing import Callable, List, Union +from loguru import logger + +from nrm.api._build._nrm_cffi import ffi, lib + + +class Actuator: + """Actuator class for interacting with NRM C interface. Prototyped interface for client below. + Tentative usage: + ``` + from nrm import Actuator, Client + with Client("tcp://127.0.0.1", 2345, 3456) as nrmc: + + act = Actuator(name="hello-act") + nrmc.actuators.append(act) + + + ``` + """ + + def __init__(self, name: str = "nrm-actuator"): + self._actuator_ptr = ffi.new("nrm_actuator_t **") + self._c_name = ffi.new("char[]", bytes(name, "utf-8")) + self._actuator_ptr[0] = lib.nrm_actuator_create(self._c_name) + + def __del__(self): + lib.nrm_actuator_destroy(self._actuator_ptr) + + def close(self): + lib.nrm_actuator_destroy(self._actuator_ptr) + + def set_choices(self, *cargs) -> int: + return lib.nrm_actuator_set_choices( + self._actuator_ptr[0], len(cargs), list(cargs) + ) + + def set_value(self, value: float) -> int: + return lib.nrm_actuator_set_value(self._actuator_ptr[0], value) + + +class Scope: + """Scope class for interacting with NRM C interface. Prototyped interface for scope below.""" + + def __init__(self, name: str = "nrm-scope"): + self._c_name = ffi.new("char[]", bytes(name, "utf-8")) + self._scope_ptr = lib.nrm_scope_create(self._c_name) + + def __del__(self): + lib.nrm_scope_destroy(self._scope_ptr) + + def close(self) -> int: + return lib.nrm_scope_destroy(self._scope_ptr) + + +class Sensor: + """Sensor class for interacting with NRM C interface. Prototyped interface for client below. + Tentative usage: + ``` + from nrm import Sensor, Actuator + with Client("tcp://127.0.0.1", 2345, 3456) as nrmc: + ... + nrmc.sensors["abc123"] = my_sensor + ... + nrmc.send_event(get_time(), sensor, scope, 1234) + ... + + ``` + """ + + def __init__(self, name: str = "nrm-sensor"): + self._sensor_ptr = ffi.new("nrm_sensor_t **") + self._c_name = ffi.new("char[]", bytes(name, "utf-8")) + self._sensor_ptr[0] = lib.nrm_sensor_create(self._c_name) + + def __del__(self): + lib.nrm_sensor_destroy(self._sensor_ptr) + + def close(self): + lib.nrm_sensor_destroy(self._sensor_ptr) + + +class Slice: + """Slice class for interacting with NRM C interface. Prototyped interface for client below. + Tentative usage: + ``` + from nrm import Client, Actuator + with Client("tcp://127.0.0.1", 2345, 3456) as nrmc: + ... + my_slice = Slice("nrm-slice", "abc123) + nrmc.slices["uuid"] = my_slice + + ... + nrmc.send_event(get_time(), sensor, scope, 1234) + ... + ``` + """ + + def __init__(self, name: str = "nrm-slice"): + self._slice_ptr = ffi.new("nrm_slice_t **") + self._c_name = ffi.new("char[]", bytes(name, "utf-8")) + self._slice_ptr[0] = lib.nrm_slice_create(self._c_name) + + def __del__(self): + lib.nrm_slice_destroy(self._slice_ptr) + + def close(self): + lib.nrm_slice_destroy(self._slice_ptr) + + +class _NRM_d(dict): + def __init__(self, *args): + dict.__init__(self, args) + + def _set_client(self, client): + self._c_client = client + + +class NRMScopes(_NRM_d): + def __setitem__(self, uuid_key: str, nrm_object: "Scope"): + super().__setitem__(uuid_key, nrm_object) + return lib.nrm_client_add_scope(self._c_client, nrm_object._scope_ptr) + + +class NRMSensors(_NRM_d): + def __setitem__(self, uuid_key: str, nrm_object: "Sensor"): + super().__setitem__(uuid_key, nrm_object) + return lib.nrm_client_add_sensor(self._c_client, nrm_object._sensor_ptr[0]) + + +class NRMSlices(_NRM_d): + def __setitem__(self, uuid_key: str, nrm_object: "Slice"): + super().__setitem__(uuid_key, nrm_object) + return lib.nrm_client_add_slice(self._c_client, nrm_object._slice_ptr[0]) + + +class NRMActuators(_NRM_d): + def __setitem__(self, uuid_key: str, nrm_object: "Actuator"): + super().__setitem__(uuid_key, nrm_object) + return lib.nrm_client_add_actuator(self._c_client, nrm_object._actuator_ptr[0]) diff --git a/nrm/schemas/downstreamEvent.json b/nrm/schemas/downstreamEvent.json deleted file mode 100644 index 8afb4f44..00000000 --- a/nrm/schemas/downstreamEvent.json +++ /dev/null @@ -1,345 +0,0 @@ -{ - "required": [ - "timestamp", - "info" - ], - "type": "object", - "properties": { - "timestamp": { - "type": "number" - }, - "info": { - "oneOf": [ - { - "required": [ - "cmdPerformance" - ], - "type": "object", - "properties": { - "cmdPerformance": { - "required": [ - "cmdID", - "perf" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "perf": { - "type": "number" - } - } - } - } - }, - { - "required": [ - "cmdPause" - ], - "type": "object", - "properties": { - "cmdPause": { - "required": [ - "cmdID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - } - } - } - } - }, - { - "required": [ - "threadProgress" - ], - "type": "object", - "properties": { - "threadProgress": { - "required": [ - "downstreamThreadID", - "scopes", - "progress" - ], - "type": "object", - "properties": { - "progress": { - "type": "number" - }, - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - }, - "scopes": { - "required": [ - "cpu", - "node", - "gpu" - ], - "type": "object", - "properties": { - "cpu": { - "type": "array", - "items": { - "type": "number" - } - }, - "node": { - "type": "array", - "items": { - "type": "number" - } - }, - "gpu": { - "type": "array", - "items": { - "type": "number" - } - } - } - } - } - } - } - }, - { - "required": [ - "threadPause" - ], - "type": "object", - "properties": { - "threadPause": { - "required": [ - "downstreamThreadID" - ], - "type": "object", - "properties": { - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - } - } - } - } - }, - { - "required": [ - "threadPhaseContext" - ], - "type": "object", - "properties": { - "threadPhaseContext": { - "required": [ - "downstreamThreadID", - "scopes", - "phaseContext" - ], - "type": "object", - "properties": { - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - }, - "scopes": { - "required": [ - "cpu", - "node", - "gpu" - ], - "type": "object", - "properties": { - "cpu": { - "type": "array", - "items": { - "type": "number" - } - }, - "node": { - "type": "array", - "items": { - "type": "number" - } - }, - "gpu": { - "type": "array", - "items": { - "type": "number" - } - } - } - }, - "phaseContext": { - "required": [ - "cpu", - "aggregation", - "computetime", - "totaltime" - ], - "type": "object", - "properties": { - "computetime": { - "type": "number" - }, - "aggregation": { - "type": "number" - }, - "totaltime": { - "type": "number" - }, - "cpu": { - "type": "number" - } - } - } - } - } - } - }, - { - "required": [ - "threadPhasePause" - ], - "type": "object", - "properties": { - "threadPhasePause": { - "required": [ - "downstreamThreadID", - "scopes" - ], - "type": "object", - "properties": { - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - }, - "scopes": { - "required": [ - "cpu", - "node", - "gpu" - ], - "type": "object", - "properties": { - "cpu": { - "type": "array", - "items": { - "type": "number" - } - }, - "node": { - "type": "array", - "items": { - "type": "number" - } - }, - "gpu": { - "type": "array", - "items": { - "type": "number" - } - } - } - } - } - } - } - } - ] - } - } -} diff --git a/resources/defaults/manifest.json b/resources/defaults/manifest.json deleted file mode 100644 index 81cbbdc7..00000000 --- a/resources/defaults/manifest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "app": { - "instrumentation": null, - "perfwrapper": null - }, - "name": "default" -} \ No newline at end of file diff --git a/resources/defaults/manifest.yml b/resources/defaults/manifest.yml deleted file mode 100644 index 16ec122d..00000000 --- a/resources/defaults/manifest.yml +++ /dev/null @@ -1,4 +0,0 @@ -app: - instrumentation: - perfwrapper: -name: default diff --git a/resources/defaults/nrmd.json b/resources/defaults/nrmd.json deleted file mode 100644 index c41d7217..00000000 --- a/resources/defaults/nrmd.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "extraStaticPassiveSensors": [], - "perfPath": "perf", - "verbose": "Error", - "logfile": "/tmp/nrm.log", - "controlCfg": "ControlOff", - "upstreamCfg": { - "upstreamBindAddress": "*", - "rpcPort": 3456, - "pubPort": 2345 - }, - "libnrmPath": null, - "downstreamCfg": { - "downstreamBindAddress": "ipc:///tmp/nrm-downstream-event" - }, - "perfwrapperPath": "nrm-perfwrapper", - "extraStaticActuators": [], - "raplCfg": { - "referencePower": { - "microwatts": 250000000 - }, - "raplActions": [ - { - "microwatts": 100000000 - }, - { - "microwatts": 200000000 - } - ], - "raplPath": "/sys/devices/virtual/powercap/intel-rapl" - }, - "passiveSensorFrequency": { - "hertz": 1 - } -} \ No newline at end of file diff --git a/resources/defaults/nrmd.yml b/resources/defaults/nrmd.yml deleted file mode 100644 index cfdc8933..00000000 --- a/resources/defaults/nrmd.yml +++ /dev/null @@ -1,23 +0,0 @@ -extraStaticPassiveSensors: [] -perfPath: perf -verbose: Error -logfile: "/tmp/nrm.log" -controlCfg: ControlOff -upstreamCfg: - upstreamBindAddress: "*" - rpcPort: 3456 - pubPort: 2345 -libnrmPath: -downstreamCfg: - downstreamBindAddress: ipc:///tmp/nrm-downstream-event -perfwrapperPath: nrm-perfwrapper -extraStaticActuators: [] -raplCfg: - referencePower: - microwatts: 250000000 - raplActions: - - microwatts: 100000000 - - microwatts: 200000000 - raplPath: "/sys/devices/virtual/powercap/intel-rapl" -passiveSensorFrequency: - hertz: 1 diff --git a/resources/schemas/downstream.json b/resources/schemas/downstream.json deleted file mode 100644 index 4389d0d4..00000000 --- a/resources/schemas/downstream.json +++ /dev/null @@ -1,258 +0,0 @@ -{ - "required": [ - "timestamp", - "info" - ], - "type": "object", - "properties": { - "timestamp": { - "type": "number" - }, - "info": { - "oneOf": [ - { - "required": [ - "cmdPerformance" - ], - "type": "object", - "properties": { - "cmdPerformance": { - "required": [ - "cmdID", - "perf" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "perf": { - "type": "number" - } - } - } - } - }, - { - "required": [ - "cmdPause" - ], - "type": "object", - "properties": { - "cmdPause": { - "required": [ - "cmdID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - } - } - } - } - }, - { - "required": [ - "threadProgress" - ], - "type": "object", - "properties": { - "threadProgress": { - "required": [ - "downstreamThreadID", - "progress" - ], - "type": "object", - "properties": { - "progress": { - "type": "number" - }, - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - } - } - } - } - }, - { - "required": [ - "threadPause" - ], - "type": "object", - "properties": { - "threadPause": { - "required": [ - "downstreamThreadID" - ], - "type": "object", - "properties": { - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - } - } - } - } - }, - { - "required": [ - "threadPhaseContext" - ], - "type": "object", - "properties": { - "threadPhaseContext": { - "required": [ - "downstreamThreadID", - "phaseContext" - ], - "type": "object", - "properties": { - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - }, - "phaseContext": { - "required": [ - "cpu", - "aggregation", - "computetime", - "totaltime" - ], - "type": "object", - "properties": { - "computetime": { - "type": "number" - }, - "aggregation": { - "type": "number" - }, - "totaltime": { - "type": "number" - }, - "cpu": { - "type": "number" - } - } - } - } - } - } - }, - { - "required": [ - "threadPhasePause" - ], - "type": "object", - "properties": { - "threadPhasePause": { - "required": [ - "downstreamThreadID" - ], - "type": "object", - "properties": { - "downstreamThreadID": { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - } - } - } - } - } - ] - } - } -} \ No newline at end of file diff --git a/resources/schemas/upstream-pub.json b/resources/schemas/upstream-pub.json deleted file mode 100644 index 238d2403..00000000 --- a/resources/schemas/upstream-pub.json +++ /dev/null @@ -1,1111 +0,0 @@ -{ - "oneOf": [ - { - "required": [ - "pubMeasurements" - ], - "type": "object", - "properties": { - "pubMeasurements": { - "items": [ - { - "type": "number" - }, - { - "uniqueItems": false, - "items": { - "required": [ - "sensorID", - "sensorValue", - "time" - ], - "type": "object", - "properties": { - "time": { - "type": "number" - }, - "sensorValue": { - "type": "number" - }, - "sensorID": { - "type": "string" - } - } - }, - "type": "array" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "pubCPD" - ], - "type": "object", - "properties": { - "pubCPD": { - "items": [ - { - "type": "number" - }, - { - "required": [ - "sensors", - "actuators", - "objectives", - "constraints" - ], - "type": "object", - "properties": { - "objectives": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - {} - ], - "type": "array" - }, - "type": "array" - }, - "constraints": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - {} - ], - "type": "array" - }, - "type": "array" - }, - "sensors": { - "additionalProperties": { - "required": [ - "range", - "maxFrequency" - ], - "type": "object", - "properties": { - "maxFrequency": { - "type": "number" - }, - "range": { - "oneOf": [ - { - "required": [ - "i" - ], - "type": "object", - "properties": { - "i": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "empty" - ], - "type": "object", - "properties": { - "empty": { - "type": "object", - "properties": {} - } - } - } - ] - } - } - }, - "type": "object" - }, - "actuators": { - "additionalProperties": { - "required": [ - "actions" - ], - "type": "object", - "properties": { - "actions": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - } - } - }, - "type": "object" - } - } - } - ], - "type": "array" - } - } - }, - { - "required": [ - "pubPerformance" - ], - "type": "object", - "properties": { - "pubPerformance": { - "items": [ - { - "type": "number" - }, - { - "type": "string" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "pubPhaseContext" - ], - "type": "object", - "properties": { - "pubPhaseContext": { - "items": [ - { - "type": "number" - }, - { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - }, - { - "oneOf": [ - { - "required": [ - "sliceID" - ], - "type": "object", - "properties": { - "sliceID": { - "type": "string" - } - } - }, - { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - ] - }, - { - "required": [ - "cpu", - "aggregation", - "computetime", - "totaltime" - ], - "type": "object", - "properties": { - "computetime": { - "type": "number" - }, - "aggregation": { - "type": "number" - }, - "totaltime": { - "type": "number" - }, - "cpu": { - "type": "number" - } - } - } - ], - "type": "array" - } - } - }, - { - "required": [ - "pubProgress" - ], - "type": "object", - "properties": { - "pubProgress": { - "items": [ - { - "type": "number" - }, - { - "required": [ - "cmdID", - "processID", - "taskID", - "threadID", - "rankID" - ], - "type": "object", - "properties": { - "cmdID": { - "type": "string" - }, - "taskID": { - "type": "string" - }, - "processID": { - "type": "number" - }, - "rankID": { - "type": "number" - }, - "threadID": { - "type": "number" - } - } - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "pubAction" - ], - "type": "object", - "properties": { - "pubAction": { - "items": [ - { - "type": "number" - }, - { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - }, - { - "oneOf": [ - { - "required": [ - "initialDecision" - ], - "type": "object", - "properties": { - "initialDecision": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "referenceMeasurementDecision" - ], - "type": "object", - "properties": { - "referenceMeasurementDecision": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "innerDecision" - ], - "type": "object", - "properties": { - "innerDecision": { - "required": [ - "constraints", - "objectives", - "loss", - "reportEvaluatedObjectives", - "reportNormalizedObjectives", - "reportEvaluatedConstraints" - ], - "type": "object", - "properties": { - "objectives": { - "uniqueItems": false, - "items": { - "required": [ - "fromObjectiveValue" - ], - "type": "object", - "properties": { - "fromObjectiveValue": { - "type": "number" - } - } - }, - "type": "array" - }, - "reportEvaluatedConstraints": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - }, - { - "oneOf": [ - { - "required": [ - "i" - ], - "type": "object", - "properties": { - "i": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "empty" - ], - "type": "object", - "properties": { - "empty": { - "type": "object", - "properties": {} - } - } - } - ] - } - ], - "type": "array" - }, - "type": "array" - }, - "reportEvaluatedObjectives": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - { - "oneOf": [ - { - "required": [ - "Just" - ], - "type": "object", - "properties": { - "Just": { - "type": "number" - } - } - }, - { - "required": [ - "Nothing" - ], - "type": "object", - "properties": { - "Nothing": { - "const": "null" - } - } - } - ] - }, - { - "oneOf": [ - { - "required": [ - "Just" - ], - "type": "object", - "properties": { - "Just": { - "oneOf": [ - { - "required": [ - "i" - ], - "type": "object", - "properties": { - "i": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "empty" - ], - "type": "object", - "properties": { - "empty": { - "type": "object", - "properties": {} - } - } - } - ] - } - } - }, - { - "required": [ - "Nothing" - ], - "type": "object", - "properties": { - "Nothing": { - "const": "null" - } - } - } - ] - } - ], - "type": "array" - }, - "type": "array" - }, - "reportNormalizedObjectives": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - }, - "type": "array" - }, - "loss": { - "type": "number" - }, - "constraints": { - "uniqueItems": false, - "items": { - "required": [ - "fromConstraintValue" - ], - "type": "object", - "properties": { - "fromConstraintValue": { - "type": "number" - } - } - }, - "type": "array" - } - } - } - } - } - ] - }, - { - "required": [ - "integrator", - "armstats", - "referenceMeasurements", - "referenceMeasurementCounter" - ], - "type": "object", - "properties": { - "bandit": { - "oneOf": [ - { - "required": [ - "lagrange" - ], - "type": "object", - "properties": { - "lagrange": { - "required": [ - "lagrange" - ], - "type": "object", - "properties": { - "lagrange": { - "required": [ - "t", - "lastAction", - "k", - "weights" - ], - "type": "object", - "properties": { - "lastAction": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - }, - "k": { - "type": "number" - }, - "t": { - "type": "number" - }, - "weights": { - "uniqueItems": false, - "items": { - "required": [ - "probability", - "cumulativeLoss", - "action" - ], - "type": "object", - "properties": { - "probability": { - "required": [ - "getProbability" - ], - "type": "object", - "properties": { - "getProbability": { - "type": "number" - } - } - }, - "action": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - }, - "cumulativeLoss": { - "required": [ - "getCumulativeLoss" - ], - "type": "object", - "properties": { - "getCumulativeLoss": { - "type": "number" - } - } - } - } - }, - "type": "array" - } - } - } - } - } - } - }, - { - "required": [ - "random" - ], - "type": "object", - "properties": { - "random": { - "required": [ - "random" - ], - "type": "object", - "properties": { - "random": { - "uniqueItems": false, - "items": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - }, - "type": "array" - } - } - } - } - }, - { - "required": [ - "contextual" - ], - "type": "object", - "properties": { - "contextual": { - "required": [ - "contextual" - ], - "type": "object", - "properties": { - "contextual": { - "required": [ - "t", - "horizon", - "k", - "n", - "lambda", - "constraint", - "experts" - ], - "type": "object", - "properties": { - "lastAction": { - "required": [ - "action", - "globalProbabilityOfSample", - "perExpertProbabilityOfSample" - ], - "type": "object", - "properties": { - "perExpertProbabilityOfSample": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - }, - "action": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - }, - "globalProbabilityOfSample": { - "type": "number" - } - } - }, - "k": { - "type": "number" - }, - "n": { - "type": "number" - }, - "t": { - "type": "number" - }, - "lambda": { - "type": "number" - }, - "horizon": { - "type": "number" - }, - "experts": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - } - ], - "type": "array" - }, - "type": "array" - } - ], - "type": "array" - }, - "type": "array" - }, - "constraint": { - "type": "number" - } - } - } - } - } - } - } - ] - }, - "referenceMeasurements": { - "additionalProperties": { - "required": [ - "getMemBuffer" - ], - "type": "object", - "properties": { - "getMemBuffer": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - } - } - }, - "type": "object" - }, - "referenceMeasurementCounter": { - "type": "number" - }, - "bufferedMeasurements": { - "additionalProperties": { - "type": "number" - }, - "type": "object" - }, - "integrator": { - "required": [ - "meta", - "measured" - ], - "type": "object", - "properties": { - "measured": { - "additionalProperties": { - "oneOf": [ - { - "required": [ - "never" - ], - "type": "object", - "properties": { - "never": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "discarded" - ], - "type": "object", - "properties": { - "discarded": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "running" - ], - "type": "object", - "properties": { - "running": { - "required": [ - "firstTime", - "lastTime", - "lastValue", - "area" - ], - "type": "object", - "properties": { - "area": { - "type": "number" - }, - "firstTime": { - "type": "number" - }, - "lastTime": { - "type": "number" - }, - "lastValue": { - "type": "number" - } - } - } - } - }, - { - "required": [ - "done" - ], - "type": "object", - "properties": { - "done": { - "required": [ - "firstTime", - "lastTime", - "lastValue", - "area" - ], - "type": "object", - "properties": { - "area": { - "type": "number" - }, - "firstTime": { - "type": "number" - }, - "lastTime": { - "type": "number" - }, - "lastValue": { - "type": "number" - } - } - } - } - } - ] - }, - "type": "object" - }, - "meta": { - "required": [ - "tLast", - "minimumWaitInterval", - "minimumControlInterval" - ], - "type": "object", - "properties": { - "minimumWaitInterval": { - "type": "number" - }, - "minimumControlInterval": { - "type": "number" - }, - "tLast": { - "type": "number" - } - } - } - } - }, - "armstats": { - "additionalProperties": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - }, - { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - }, - { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - }, - { - "additionalProperties": { - "type": "number" - }, - "type": "object" - }, - { - "additionalProperties": { - "type": "number" - }, - "type": "object" - } - ], - "type": "array" - }, - "type": "object" - }, - "lastA": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - } - } - } - ], - "type": "array" - } - } - }, - { - "required": [ - "pubEnd" - ], - "type": "object", - "properties": { - "pubEnd": { - "type": "string" - } - } - } - ] -} \ No newline at end of file diff --git a/resources/schemas/upstream-rep.json b/resources/schemas/upstream-rep.json deleted file mode 100644 index 7b671130..00000000 --- a/resources/schemas/upstream-rep.json +++ /dev/null @@ -1,1316 +0,0 @@ -{ - "oneOf": [ - { - "required": [ - "repList" - ], - "type": "object", - "properties": { - "repList": { - "required": [ - "slices" - ], - "type": "object", - "properties": { - "slices": { - "uniqueItems": false, - "items": { - "items": [ - { - "oneOf": [ - { - "required": [ - "sliceID" - ], - "type": "object", - "properties": { - "sliceID": { - "type": "string" - } - } - }, - { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - ] - }, - { - "required": [ - "cmds", - "awaiting" - ], - "type": "object", - "properties": { - "awaiting": { - "additionalProperties": { - "required": [ - "cmdPath", - "arguments", - "manifest" - ], - "type": "object", - "properties": { - "upstreamClientID": { - "type": "string" - }, - "arguments": { - "uniqueItems": false, - "items": { - "type": "string" - }, - "type": "array" - }, - "cmdPath": { - "type": "string" - }, - "manifest": { - "required": [ - "app", - "name" - ], - "type": "object", - "properties": { - "app": { - "type": "object", - "properties": { - "instrumentation": { - "required": [ - "ratelimit" - ], - "type": "object", - "properties": { - "ratelimit": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - }, - "perfwrapper": { - "required": [ - "perfFreq", - "perfLimit" - ], - "type": "object", - "properties": { - "perfLimit": { - "type": "number" - }, - "perfFreq": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - } - } - }, - "name": { - "type": "string" - } - } - } - } - }, - "type": "object" - }, - "cmds": { - "additionalProperties": { - "required": [ - "cmdCore", - "pid", - "processState", - "downstreamCmds", - "downstreamThreads" - ], - "type": "object", - "properties": { - "downstreamCmds": { - "additionalProperties": { - "required": [ - "maxValue", - "ratelimit", - "dtLastReferenceMeasurements" - ], - "type": "object", - "properties": { - "ratelimit": { - "type": "number" - }, - "maxValue": { - "type": "number" - }, - "dtLastReferenceMeasurements": { - "required": [ - "getMemBuffer" - ], - "type": "object", - "properties": { - "getMemBuffer": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - } - } - }, - "lastRead": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - "type": "object" - }, - "cmdCore": { - "required": [ - "cmdPath", - "arguments", - "manifest" - ], - "type": "object", - "properties": { - "upstreamClientID": { - "type": "string" - }, - "arguments": { - "uniqueItems": false, - "items": { - "type": "string" - }, - "type": "array" - }, - "cmdPath": { - "type": "string" - }, - "manifest": { - "required": [ - "app", - "name" - ], - "type": "object", - "properties": { - "app": { - "type": "object", - "properties": { - "instrumentation": { - "required": [ - "ratelimit" - ], - "type": "object", - "properties": { - "ratelimit": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - }, - "perfwrapper": { - "required": [ - "perfFreq", - "perfLimit" - ], - "type": "object", - "properties": { - "perfLimit": { - "type": "number" - }, - "perfFreq": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - } - } - }, - "name": { - "type": "string" - } - } - } - } - }, - "processState": { - "required": [ - "stdoutFinished", - "stderrFinished" - ], - "type": "object", - "properties": { - "stderrFinished": { - "type": "boolean" - }, - "stdoutFinished": { - "type": "boolean" - }, - "ended": { - "oneOf": [ - { - "required": [ - "exitSuccess" - ], - "type": "object", - "properties": { - "exitSuccess": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "exitFailure" - ], - "type": "object", - "properties": { - "exitFailure": { - "type": "number" - } - } - } - ] - } - } - }, - "pid": { - "type": "number" - }, - "downstreamThreads": { - "additionalProperties": { - "required": [ - "maxValue", - "ratelimit", - "dtLastReferenceMeasurements" - ], - "type": "object", - "properties": { - "ratelimit": { - "type": "number" - }, - "maxValue": { - "type": "number" - }, - "dtLastReferenceMeasurements": { - "required": [ - "getMemBuffer" - ], - "type": "object", - "properties": { - "getMemBuffer": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - } - } - }, - "lastRead": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - "type": "object" - } - } - }, - "type": "object" - } - } - } - ], - "type": "array" - }, - "type": "array" - } - } - } - } - }, - { - "required": [ - "repCPD" - ], - "type": "object", - "properties": { - "repCPD": { - "required": [ - "sensors", - "actuators", - "objectives", - "constraints" - ], - "type": "object", - "properties": { - "objectives": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - {} - ], - "type": "array" - }, - "type": "array" - }, - "constraints": { - "uniqueItems": false, - "items": { - "items": [ - { - "type": "number" - }, - {} - ], - "type": "array" - }, - "type": "array" - }, - "sensors": { - "additionalProperties": { - "required": [ - "range", - "maxFrequency" - ], - "type": "object", - "properties": { - "maxFrequency": { - "type": "number" - }, - "range": { - "oneOf": [ - { - "required": [ - "i" - ], - "type": "object", - "properties": { - "i": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "type": "array" - } - } - }, - { - "required": [ - "empty" - ], - "type": "object", - "properties": { - "empty": { - "type": "object", - "properties": {} - } - } - } - ] - } - } - }, - "type": "object" - }, - "actuators": { - "additionalProperties": { - "required": [ - "actions" - ], - "type": "object", - "properties": { - "actions": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - } - } - }, - "type": "object" - } - } - } - } - }, - { - "required": [ - "repStart" - ], - "type": "object", - "properties": { - "repStart": { - "required": [ - "startSliceID", - "startCmdID" - ], - "type": "object", - "properties": { - "startCmdID": { - "type": "string" - }, - "startSliceID": { - "oneOf": [ - { - "required": [ - "sliceID" - ], - "type": "object", - "properties": { - "sliceID": { - "type": "string" - } - } - }, - { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - ] - } - } - } - } - }, - { - "required": [ - "repStdout" - ], - "type": "object", - "properties": { - "repStdout": { - "required": [ - "stdoutCmdID", - "stdoutPayload" - ], - "type": "object", - "properties": { - "stdoutPayload": { - "type": "string" - }, - "stdoutCmdID": { - "type": "string" - } - } - } - } - }, - { - "required": [ - "repStderr" - ], - "type": "object", - "properties": { - "repStderr": { - "required": [ - "stderrCmdID", - "stderrPayload" - ], - "type": "object", - "properties": { - "stderrPayload": { - "type": "string" - }, - "stderrCmdID": { - "type": "string" - } - } - } - } - }, - { - "required": [ - "repEndStream" - ], - "type": "object", - "properties": { - "repEndStream": { - "required": [ - "streamType" - ], - "type": "object", - "properties": { - "streamType": { - "oneOf": [ - { - "const": "\"stdoutOutput\"" - }, - { - "const": "\"stderrOutput\"" - } - ] - } - } - } - } - }, - { - "required": [ - "repStartFailure" - ], - "type": "object", - "properties": { - "repStartFailure": { - "const": "\"startFailure\"" - } - } - }, - { - "required": [ - "repCmdEnded" - ], - "type": "object", - "properties": { - "repCmdEnded": { - "required": [ - "exitCode" - ], - "type": "object", - "properties": { - "exitCode": { - "oneOf": [ - { - "required": [ - "exitSuccess" - ], - "type": "object", - "properties": { - "exitSuccess": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "exitFailure" - ], - "type": "object", - "properties": { - "exitFailure": { - "type": "number" - } - } - } - ] - } - } - } - } - }, - { - "required": [ - "repNoSuchSlice" - ], - "type": "object", - "properties": { - "repNoSuchSlice": { - "const": "\"noSuchSlice\"" - } - } - }, - { - "required": [ - "repNoSuchCmd" - ], - "type": "object", - "properties": { - "repNoSuchCmd": { - "const": "\"noSuchCmd\"" - } - } - }, - { - "required": [ - "repSliceKilled" - ], - "type": "object", - "properties": { - "repSliceKilled": { - "required": [ - "killedSliceID" - ], - "type": "object", - "properties": { - "killedSliceID": { - "oneOf": [ - { - "required": [ - "sliceID" - ], - "type": "object", - "properties": { - "sliceID": { - "type": "string" - } - } - }, - { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - ] - } - } - } - } - }, - { - "required": [ - "repCmdKilled" - ], - "type": "object", - "properties": { - "repCmdKilled": { - "required": [ - "killedCmdID" - ], - "type": "object", - "properties": { - "killedCmdID": { - "type": "string" - } - } - } - } - }, - { - "required": [ - "repThisCmdKilled" - ], - "type": "object", - "properties": { - "repThisCmdKilled": { - "const": "\"thisCmdKilled\"" - } - } - }, - { - "required": [ - "repActuate" - ], - "type": "object", - "properties": { - "repActuate": { - "oneOf": [ - { - "const": "\"actuated\"" - }, - { - "const": "\"notActuated\"" - } - ] - } - } - }, - { - "required": [ - "repGetState" - ], - "type": "object", - "properties": { - "repGetState": { - "type": "string" - } - } - }, - { - "required": [ - "repGetConfig" - ], - "type": "object", - "properties": { - "repGetConfig": { - "required": [ - "config" - ], - "type": "object", - "properties": { - "config": { - "required": [ - "controlCfg", - "downstreamCfg", - "extraStaticActuators", - "extraStaticPassiveSensors", - "logfile", - "passiveSensorFrequency", - "perfPath", - "perfwrapperPath", - "upstreamCfg", - "verbose" - ], - "type": "object", - "properties": { - "extraStaticPassiveSensors": { - "uniqueItems": false, - "items": { - "required": [ - "sensor", - "sensorID" - ], - "type": "object", - "properties": { - "sensorID": { - "type": "string" - }, - "sensor": { - "required": [ - "range", - "sensorArguments", - "sensorBehavior", - "sensorBinary", - "tags" - ], - "type": "object", - "properties": { - "range": { - "required": [ - "lower", - "upper" - ], - "type": "object", - "properties": { - "upper": { - "type": "number" - }, - "lower": { - "type": "number" - } - } - }, - "sensorBehavior": { - "oneOf": [ - { - "required": [ - "cumulative" - ], - "type": "object", - "properties": { - "cumulative": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "cumulativeWithCapacity" - ], - "type": "object", - "properties": { - "cumulativeWithCapacity": { - "type": "number" - } - } - }, - { - "required": [ - "intervalBased" - ], - "type": "object", - "properties": { - "intervalBased": { - "type": "object", - "properties": {} - } - } - } - ] - }, - "sensorArguments": { - "uniqueItems": false, - "items": { - "type": "string" - }, - "type": "array" - }, - "tags": { - "uniqueItems": false, - "items": { - "oneOf": [ - { - "const": "\"tagDownstreamCmdSignal\"" - }, - { - "const": "\"tagDownstreamThreadSignal\"" - }, - { - "const": "\"tagMaximize\"" - }, - { - "const": "\"tagMinimize\"" - }, - { - "const": "\"tagPower\"" - }, - { - "const": "\"tagRapl\"" - } - ] - }, - "type": "array" - }, - "sensorBinary": { - "type": "string" - } - } - } - } - }, - "type": "array" - }, - "perfPath": { - "type": "string" - }, - "verbose": { - "oneOf": [ - { - "const": "\"debug\"" - }, - { - "const": "\"error\"" - }, - { - "const": "\"info\"" - } - ] - }, - "logfile": { - "type": "string" - }, - "controlCfg": { - "oneOf": [ - { - "required": [ - "controlCfg" - ], - "type": "object", - "properties": { - "controlCfg": { - "required": [ - "hint", - "learnCfg", - "minimumControlInterval", - "minimumWaitInterval", - "referenceMeasurementRoundInterval", - "speedThreshold", - "staticPower" - ], - "type": "object", - "properties": { - "referenceMeasurementRoundInterval": { - "type": "number" - }, - "minimumWaitInterval": { - "required": [ - "microseconds" - ], - "type": "object", - "properties": { - "microseconds": { - "type": "number" - } - } - }, - "hint": { - "oneOf": [ - { - "required": [ - "full" - ], - "type": "object", - "properties": { - "full": { - "type": "object", - "properties": {} - } - } - }, - { - "required": [ - "only" - ], - "type": "object", - "properties": { - "only": { - "required": [ - "neHead", - "neTail" - ], - "type": "object", - "properties": { - "neHead": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorValue", - "actuatorValueID" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorValueID": { - "type": "string" - } - } - }, - "type": "array" - }, - "neTail": { - "uniqueItems": false, - "items": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorValue", - "actuatorValueID" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorValueID": { - "type": "string" - } - } - }, - "type": "array" - }, - "type": "array" - } - } - } - } - } - ] - }, - "learnCfg": { - "oneOf": [ - { - "required": [ - "contextual" - ], - "type": "object", - "properties": { - "contextual": { - "required": [ - "horizon" - ], - "type": "object", - "properties": { - "horizon": { - "type": "number" - } - } - } - } - }, - { - "required": [ - "lagrange" - ], - "type": "object", - "properties": { - "lagrange": { - "required": [ - "lagrange" - ], - "type": "object", - "properties": { - "lagrange": { - "type": "number" - } - } - } - } - }, - { - "required": [ - "random" - ], - "type": "object", - "properties": { - "random": { - "required": [ - "seed" - ], - "type": "object", - "properties": { - "seed": { - "type": "number" - } - } - } - } - } - ] - }, - "staticPower": { - "required": [ - "microwatts" - ], - "type": "object", - "properties": { - "microwatts": { - "type": "number" - } - } - }, - "speedThreshold": { - "type": "number" - }, - "minimumControlInterval": { - "required": [ - "microseconds" - ], - "type": "object", - "properties": { - "microseconds": { - "type": "number" - } - } - } - } - } - } - }, - { - "required": [ - "controlOff" - ], - "type": "object", - "properties": { - "controlOff": { - "type": "object", - "properties": {} - } - } - } - ] - }, - "upstreamCfg": { - "required": [ - "pubPort", - "rpcPort", - "upstreamBindAddress" - ], - "type": "object", - "properties": { - "upstreamBindAddress": { - "type": "string" - }, - "rpcPort": { - "type": "number" - }, - "pubPort": { - "type": "number" - } - } - }, - "libnrmPath": { - "type": "string" - }, - "downstreamCfg": { - "required": [ - "downstreamBindAddress" - ], - "type": "object", - "properties": { - "downstreamBindAddress": { - "type": "string" - } - } - }, - "perfwrapperPath": { - "type": "string" - }, - "extraStaticActuators": { - "uniqueItems": false, - "items": { - "required": [ - "actuator", - "actuatorID" - ], - "type": "object", - "properties": { - "actuator": { - "required": [ - "actions", - "actuatorArguments", - "actuatorBinary", - "referenceAction" - ], - "type": "object", - "properties": { - "actuatorBinary": { - "type": "string" - }, - "actions": { - "uniqueItems": false, - "items": { - "type": "number" - }, - "type": "array" - }, - "actuatorArguments": { - "uniqueItems": false, - "items": { - "type": "string" - }, - "type": "array" - }, - "referenceAction": { - "type": "number" - } - } - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - }, - "raplCfg": { - "required": [ - "raplActions", - "raplPath", - "referencePower" - ], - "type": "object", - "properties": { - "referencePower": { - "required": [ - "microwatts" - ], - "type": "object", - "properties": { - "microwatts": { - "type": "number" - } - } - }, - "raplActions": { - "uniqueItems": false, - "items": { - "required": [ - "microwatts" - ], - "type": "object", - "properties": { - "microwatts": { - "type": "number" - } - } - }, - "type": "array" - }, - "raplPath": { - "type": "string" - } - } - }, - "passiveSensorFrequency": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - } - } - } - } - }, - { - "required": [ - "repException" - ], - "type": "object", - "properties": { - "repException": { - "type": "string" - } - } - } - ] -} \ No newline at end of file diff --git a/resources/schemas/upstream-req.json b/resources/schemas/upstream-req.json deleted file mode 100644 index 7c38a072..00000000 --- a/resources/schemas/upstream-req.json +++ /dev/null @@ -1,277 +0,0 @@ -{ - "oneOf": [ - { - "required": [ - "reqSliceList" - ], - "type": "object", - "properties": { - "reqSliceList": { - "const": "\"sliceList\"" - } - } - }, - { - "required": [ - "reqRun" - ], - "type": "object", - "properties": { - "reqRun": { - "required": [ - "manifest", - "spec", - "runSliceID", - "detachCmd" - ], - "type": "object", - "properties": { - "detachCmd": { - "type": "boolean" - }, - "runSliceID": { - "oneOf": [ - { - "required": [ - "sliceID" - ], - "type": "object", - "properties": { - "sliceID": { - "type": "string" - } - } - }, - { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - ] - }, - "manifest": { - "required": [ - "app", - "name" - ], - "type": "object", - "properties": { - "app": { - "type": "object", - "properties": { - "instrumentation": { - "required": [ - "ratelimit" - ], - "type": "object", - "properties": { - "ratelimit": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - }, - "perfwrapper": { - "required": [ - "perfFreq", - "perfLimit" - ], - "type": "object", - "properties": { - "perfLimit": { - "type": "number" - }, - "perfFreq": { - "required": [ - "hertz" - ], - "type": "object", - "properties": { - "hertz": { - "type": "number" - } - } - } - } - } - } - }, - "name": { - "type": "string" - } - } - }, - "spec": { - "required": [ - "cmd", - "args", - "env" - ], - "type": "object", - "properties": { - "args": { - "uniqueItems": false, - "items": { - "type": "string" - }, - "type": "array" - }, - "env": { - "required": [ - "fromEnv" - ], - "type": "object", - "properties": { - "fromEnv": { - "additionalProperties": { - "type": "string" - }, - "type": "object" - } - } - }, - "cmd": { - "type": "string" - } - } - } - } - } - } - }, - { - "required": [ - "reqKillSlice" - ], - "type": "object", - "properties": { - "reqKillSlice": { - "required": [ - "killSliceID" - ], - "type": "object", - "properties": { - "killSliceID": { - "oneOf": [ - { - "required": [ - "sliceID" - ], - "type": "object", - "properties": { - "sliceID": { - "type": "string" - } - } - }, - { - "required": [ - "name" - ], - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - ] - } - } - } - } - }, - { - "required": [ - "reqCPD" - ], - "type": "object", - "properties": { - "reqCPD": { - "const": "\"cPD\"" - } - } - }, - { - "required": [ - "reqKillCmd" - ], - "type": "object", - "properties": { - "reqKillCmd": { - "required": [ - "killCmdID" - ], - "type": "object", - "properties": { - "killCmdID": { - "type": "string" - } - } - } - } - }, - { - "required": [ - "reqActuate" - ], - "type": "object", - "properties": { - "reqActuate": { - "uniqueItems": false, - "items": { - "required": [ - "actuatorID", - "actuatorValue" - ], - "type": "object", - "properties": { - "actuatorValue": { - "type": "number" - }, - "actuatorID": { - "type": "string" - } - } - }, - "type": "array" - } - } - }, - { - "required": [ - "reqGetState" - ], - "type": "object", - "properties": { - "reqGetState": { - "const": "\"getState\"" - } - } - }, - { - "required": [ - "reqGetConfig" - ], - "type": "object", - "properties": { - "reqGetConfig": { - "const": "\"getConfig\"" - } - } - } - ] -} \ No newline at end of file diff --git a/setup.py b/setup.py index b74b9103..4580d3c0 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ ], packages=find_packages(), - install_requires=['msgpack', 'pyyaml', "warlock", "pyzmq", "tornado", "jsonschema"], - package_data={'nrm': ['schemas/*.json', 'schemas/*.yml']}, - scripts=['bin/nrmd'] + setup_requires=["cffi"], + cffi_modules=["nrm/api/build.py:ffi"], + install_requires=['msgpack', 'pyyaml', "warlock", "pyzmq", "tornado", "jsonschema", "loguru", "cffi"], ) diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 00000000..1311d3f3 --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,108 @@ +import secrets +import time +from nrm.api import Client, Actuator, Scope, Sensor, Slice + +act_uuid = secrets.token_hex(3) +sco_uuid = secrets.token_hex(3) +sen_uuid = secrets.token_hex(3) +sli_uuid = secrets.token_hex(3) + + +def test_client_init(): + print("test_client_init") + with Client() as nrmc: + pass + + +def test_set_objs_to_client(): + print("test_set_objs_to_client") + act = Actuator("nrm-test-actuator") + sco = Scope("nrm-test-scope") + sen = Sensor("nrm-test-sensor") + sli = Slice("nrm-test-slice") + + with Client() as nrmc: + nrmc.actuators[act_uuid] = act + nrmc.scopes[sco_uuid] = sco + nrmc.sensors[sen_uuid] = sen + nrmc.slices[sli_uuid] = sli + nrmc.remove(act) + act.close() + + +def test_actuate(): + print("test_actuate") + act = Actuator("nrm-test-actuator") + assert not act.set_choices(12.0, 123.0, 1234.0, 12345.0) + assert not act.set_value(1234.0) + with Client() as nrmc: + nrmc.actuators[act_uuid] = act + assert not nrmc.actuate(act, 123.0) + nrmc.remove(act) + act.close() + + +def test_send_event(): + print("test_send_event") + sco = Scope("nrm-test-scope") + sen = Sensor("nrm-test-sensor") + with Client() as nrmc: + nrmc.scopes[sco_uuid] = sco + nrmc.sensors[sen_uuid] = sen + assert not nrmc.send_event(sen, sco, 1234) + + +def test_event_callbacks(): + print("test_event_callbacks") + + def print_event_info(*args): + print("IN EVENT PYTHON CALLBACK: Responding to subscribed event") + return 0 + + sco = Scope("nrm-test-scope") + sen = Sensor("test-report-numa-pwr") + with Client() as nrmc: + nrmc.scopes[sco_uuid] = sco + nrmc.sensors[sen_uuid] = sen + assert not nrmc.set_event_listener(print_event_info) + assert not nrmc.start_event_listener("test-report-numa-pwr") + assert not nrmc.send_event(sen, sco, 1234) + time.sleep(1) + assert not nrmc.send_event(sen, sco, 12) + time.sleep(1) + assert not nrmc.send_event(sen, sco, 1) + + +def test_actuate_callbacks(): + print("test_actuate_callbacks") + + def print_actuate_info(*args): + print("IN PYTHON ACTUATE CALLBACK: Responding to actuation request") + return 0 + + act = Actuator("nrm-test-actuator") + assert not act.set_choices(12.0, 123.0, 1234.0, 12345.0) + assert not act.set_value(1234.0) + with Client() as nrmc: + nrmc.actuators[act_uuid] = act + assert not nrmc.set_actuate_listener(print_actuate_info) + assert not nrmc.start_actuate_listener() + assert not nrmc.actuate(act, 123.0) + time.sleep(1) + assert not nrmc.actuate(act, 12345.0) + time.sleep(1) + assert not nrmc.actuate(act, 12.0) + time.sleep(1) + assert not act.set_value(123.0) + time.sleep(1) + nrmc.remove(act) + act.close() + + +if __name__ == "__main__": + test_client_init() + test_set_objs_to_client() + test_actuate() + test_send_event() + test_event_callbacks() + test_actuate_callbacks()