Skip to content

Commit

Permalink
feat: initial support for multiple settings profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
ilya-zlobintsev committed May 11, 2024
1 parent aa670be commit d7f0434
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 12 deletions.
44 changes: 43 additions & 1 deletion lact-daemon/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ use tracing::{debug, error};
const FILE_NAME: &str = "config.yaml";
const DEFAULT_ADMIN_GROUPS: [&str; 2] = ["wheel", "sudo"];

#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Config {
pub daemon: Daemon,
#[serde(default = "default_apply_settings_timer")]
pub apply_settings_timer: u64,
pub gpus: HashMap<String, Gpu>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
gpus: HashMap<String, Gpu>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
profiles: HashMap<String, Profile>,
#[serde(default)]
pub current_profile: Option<String>,
}

impl Default for Config {
Expand All @@ -33,6 +39,8 @@ impl Default for Config {
daemon: Daemon::default(),
apply_settings_timer: default_apply_settings_timer(),
gpus: HashMap::new(),
profiles: HashMap::new(),
current_profile: None,
}
}
}
Expand All @@ -55,6 +63,12 @@ impl Default for Daemon {
}
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct Profile {
#[serde(default)]
pub gpus: HashMap<String, Gpu>,
}

#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct Gpu {
Expand Down Expand Up @@ -168,6 +182,34 @@ impl Config {
Ok(config)
}
}

/// Gets the GPU configs according to the current profile. Returns an error if the current profile could not be found.
pub fn gpus(&self) -> anyhow::Result<&HashMap<String, Gpu>> {
match &self.current_profile {
Some(profile) => {
let profile = self
.profiles
.get(profile)
.with_context(|| format!("Could not find profile '{profile}'"))?;
Ok(&profile.gpus)
}
None => Ok(&self.gpus),
}
}

/// Same as [`gpus`], but with a mutable reference
pub fn gpus_mut(&mut self) -> anyhow::Result<&mut HashMap<String, Gpu>> {
match &self.current_profile {
Some(profile) => {
let profile = self
.profiles
.get_mut(profile)
.with_context(|| format!("Could not find profile '{profile}'"))?;
Ok(&mut profile.gpus)
}
None => Ok(&mut self.gpus),
}
}
}

pub fn start_watcher(config_last_applied: Arc<Mutex<Instant>>) -> mpsc::UnboundedReceiver<Config> {
Expand Down
35 changes: 24 additions & 11 deletions lact-daemon/src/server/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,19 @@ impl<'a> Handler {

*self.config_last_applied.lock().unwrap() = Instant::now();

for (id, gpu_config) in &config.gpus {
if let Some(controller) = self.gpu_controllers.get(id) {
if let Err(err) = controller.apply_config(gpu_config).await {
error!("could not apply existing config for gpu {id}: {err}");
match config.gpus() {
Ok(gpus) => {
for (id, gpu_config) in gpus {
if let Some(controller) = self.gpu_controllers.get(id) {
if let Err(err) = controller.apply_config(gpu_config).await {
error!("could not apply existing config for gpu {id}: {err}");
}
} else {
info!("could not find GPU with id {id} defined in configuration");
}
}
} else {
info!("could not find GPU with id {id} defined in configuration");
}
Err(err) => error!("{err:#}"),
}
}

Expand All @@ -152,7 +157,7 @@ impl<'a> Handler {
let (gpu_config, apply_timer) = {
let config = self.config.try_borrow().map_err(|err| anyhow!("{err}"))?;
let apply_timer = config.apply_settings_timer;
let gpu_config = config.gpus.get(&id).cloned().unwrap_or_default();
let gpu_config = config.gpus()?.get(&id).cloned().unwrap_or_default();
(gpu_config, apply_timer)
};

Expand Down Expand Up @@ -214,7 +219,12 @@ impl<'a> Handler {
*handler.config_last_applied.lock().unwrap() = Instant::now();

let mut config_guard = handler.config.borrow_mut();
config_guard.gpus.insert(id, new_config);
match config_guard.gpus_mut() {
Ok(gpus) => {
gpus.insert(id, new_config);
}
Err(err) => error!("{err:#}"),
}

if let Err(err) = config_guard.save() {
error!("{err}");
Expand Down Expand Up @@ -268,7 +278,7 @@ impl<'a> Handler {
.config
.try_borrow()
.map_err(|err| anyhow!("Could not read config: {err:?}"))?;
let gpu_config = config.gpus.get(id);
let gpu_config = config.gpus()?.get(id);
Ok(self.controller_by_id(id)?.get_stats(gpu_config))
}

Expand All @@ -282,7 +292,10 @@ impl<'a> Handler {
.config
.try_borrow_mut()
.map_err(|err| anyhow!("{err}"))?;
let gpu_config = config_guard.gpus.entry(opts.id.to_owned()).or_default();
let gpu_config = config_guard
.gpus_mut()?
.entry(opts.id.to_owned())
.or_default();

match opts.mode {
Some(mode) => match mode {
Expand Down Expand Up @@ -378,7 +391,7 @@ impl<'a> Handler {
.config
.try_borrow()
.map_err(|err| anyhow!("Could not read config: {err:?}"))?;
let gpu_config = config.gpus.get(id);
let gpu_config = config.gpus()?.get(id);

let states = self.controller_by_id(id)?.get_power_states(gpu_config);
Ok(states)
Expand Down

0 comments on commit d7f0434

Please sign in to comment.