MlCoord: Execution queue

This CL enables multiple outstanding periodic executions. To do so the
MlCoordinator now includes an array of started models and a queue of
models that are ready to be executed immediately. Additionally, each
periodic model has an associated timer. When that timer fires the model
is added to the execution queue. When a model finishes executing, the
next model is popped off the queue and executed. If a model becomes
ready when there's already an execution for it queued, that execution
is dropped and a warning printed. A cancel command is added to remove
periodic or outstanding executions.

A state debug command was also added.

Currently we can only load a single model due to limitations with the
StorageManager, but we can do so multiple times.

Tests:
Single shot: https://paste.googleplex.com/6704629669691392
Two periodic execs: https://paste.googleplex.com/5288292800004096
Overloaded warning: https://paste.googleplex.com/4549962219126784

Debug State:
KATA> state_mlcoord
kata_ml_coordinator::Running model: fubar:mobilenet_v1_emitc_static.model
kata_ml_coordinator::Loaded model: fubar:mobilenet_v1_emitc_static.model
kata_ml_coordinator::Loadable Models:
kata_ml_coordinator::  LoadableModel { bundle_id: "fubar", model_id: "mobilenet_v1_emitc_static.model", rate_in_ms: Some(2000) }
kata_ml_coordinator::  LoadableModel { bundle_id: "fubar", model_id: "mobilenet_v1_emitc_static.model", rate_in_ms: Some(6000) }
kata_ml_coordinator::Execution Queue:
kata_ml_coordinator::  fubar:mobilenet_v1_emitc_static.model
kata_ml_coordinator::Statistics: Statistics { load_failures: 0, already_queued: 0 }

Change-Id: I7637c9c390eb6ffd9ae22088f37b98c056a441c2
GitOrigin-RevId: 18c0d3fe740a37381f7f1eddee8f2224f679fd61
This commit is contained in:
Adam Jesionowski
2022-05-12 18:18:33 +00:00
committed by Sam Leffler
parent 20f1d1aa9d
commit 1662e80ef1
15 changed files with 705 additions and 266 deletions

View File

@@ -0,0 +1,4 @@
INTERFACES=../../../interfaces
${INTERFACES}/MlCoordBindings.h: src/lib.rs
cbindgen -c cbindgen.toml $? -o $@

View File

@@ -0,0 +1,7 @@
language = "C"
include_guard = "__ML_COORDINATOR_BINDINGS_H__"
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
no_includes = true
[export]
include = ["MlCoordError"]

View File

@@ -1,5 +1,5 @@
#![no_std]
#[allow(dead_code)]
use cstr_core::CString;
use kata_memory_interface::ObjDescBundle;
@@ -19,11 +19,29 @@ pub struct ModelSections {
pub data: Window,
}
pub trait MlCoordinatorInterface {
fn execute(&mut self, bundle_id: &str, model_id: &str);
fn set_continuous_mode(&mut self, mode: bool);
/// Errors that can occur when interacting with the MlCoordinator.
#[repr(C)]
#[derive(Debug, Eq, PartialEq)]
pub enum MlCoordError {
MlCoordOk,
InvalidModelId,
InvalidBundleId,
LoadModelFailed,
NoModelSlotsLeft,
NoSuchModel,
}
impl From<MlCoordError> for Result<(), MlCoordError> {
fn from(err: MlCoordError) -> Result<(), MlCoordError> {
if err == MlCoordError::MlCoordOk {
Ok(())
} else {
Err(err)
}
}
}
/// Abstraction layer over the hardware vector core.
pub trait MlCoreInterface {
fn set_wmmu(&mut self, sections: &ModelSections);
fn enable_interrupts(&mut self, enabled: bool);
@@ -38,19 +56,57 @@ pub trait MlCoreInterface {
}
#[inline]
#[allow(dead_code)]
pub fn kata_mlcoord_execute(bundle_id: &str, model_id: &str)
-> Result<(),cstr_core:: NulError>
{
pub fn kata_mlcoord_oneshot(bundle_id: &str, model_id: &str) -> Result<(), MlCoordError> {
extern "C" {
// NB: this assumes the MlCoordinator component is named "mlcoord".
fn mlcoord_execute(
fn mlcoord_oneshot(
c_bundle_id: *const cstr_core::c_char,
c_model_id: *const cstr_core::c_char
);
c_model_id: *const cstr_core::c_char,
) -> MlCoordError;
}
let bundle_id_cstr = CString::new(bundle_id)?;
let model_id_cstr = CString::new(model_id)?;
unsafe { mlcoord_execute(bundle_id_cstr.as_ptr(), model_id_cstr.as_ptr()) };
Ok(())
let bundle_id_cstr = CString::new(bundle_id).map_err(|_| MlCoordError::InvalidBundleId)?;
let model_id_cstr = CString::new(model_id).map_err(|_| MlCoordError::InvalidModelId)?;
unsafe { mlcoord_oneshot(bundle_id_cstr.as_ptr(), model_id_cstr.as_ptr()) }.into()
}
#[inline]
pub fn kata_mlcoord_periodic(
bundle_id: &str,
model_id: &str,
rate_in_ms: u32,
) -> Result<(), MlCoordError> {
extern "C" {
fn mlcoord_periodic(
c_bundle_id: *const cstr_core::c_char,
c_model_id: *const cstr_core::c_char,
rate_in_ms: u32,
) -> MlCoordError;
}
let bundle_id_cstr = CString::new(bundle_id).map_err(|_| MlCoordError::InvalidBundleId)?;
let model_id_cstr = CString::new(model_id).map_err(|_| MlCoordError::InvalidModelId)?;
unsafe { mlcoord_periodic(bundle_id_cstr.as_ptr(), model_id_cstr.as_ptr(), rate_in_ms) }.into()
}
#[inline]
pub fn kata_mlcoord_cancel(bundle_id: &str, model_id: &str) -> Result<(), MlCoordError> {
extern "C" {
fn mlcoord_cancel(
c_bundle_id: *const cstr_core::c_char,
c_model_id: *const cstr_core::c_char,
) -> MlCoordError;
}
let bundle_id_cstr = CString::new(bundle_id).map_err(|_| MlCoordError::InvalidBundleId)?;
let model_id_cstr = CString::new(model_id).map_err(|_| MlCoordError::InvalidModelId)?;
unsafe { mlcoord_cancel(bundle_id_cstr.as_ptr(), model_id_cstr.as_ptr()) }.into()
}
#[inline]
pub fn kata_mlcoord_debug_state() {
extern "C" {
fn mlcoord_debug_state();
}
unsafe { mlcoord_debug_state() };
}