Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions asic-rs-core/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod collector;
pub mod fan;
pub mod pools;
pub mod preset;
pub mod scaling;
pub mod temperature;
pub mod tuning;
38 changes: 38 additions & 0 deletions asic-rs-core/src/config/preset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#[cfg(feature = "python")]
use pyo3::prelude::*;
use serde::{Deserialize, Serialize};

/// An available autotune/overclock preset reported by the firmware.
///
/// Read-only: produced by the library (e.g. `Miner.get_presets`), never taken
/// as input from Python, so it is a plain `pyclass` rather than a pydantic model.
#[cfg_attr(
feature = "python",
pyclass(
name = "PresetInfo",
frozen,
get_all,
skip_from_py_object,
module = "asic_rs"
)
)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PresetInfo {
/// Canonical preset name the firmware expects (e.g. `"5560"`).
pub name: String,
/// Human-readable description (e.g. `"5560 watt ~ 175 TH"`), if provided.
pub pretty: Option<String>,
/// Tuning status (e.g. `"tuned"` / `"untuned"`), if provided.
pub status: Option<String>,
}

#[cfg(feature = "python")]
#[pymethods]
impl PresetInfo {
fn __repr__(&self) -> String {
format!(
"PresetInfo(name={:?}, pretty={:?}, status={:?})",
self.name, self.pretty, self.status
)
}
}
27 changes: 26 additions & 1 deletion asic-rs-core/src/config/tuning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl TuningConfig {
TuningTarget::Power(_) => "power",
TuningTarget::HashRate(_) => "hashrate",
TuningTarget::MiningMode(_) => "mode",
TuningTarget::Preset(_) => "preset",
}
}

Expand Down Expand Up @@ -68,6 +69,14 @@ impl TuningConfig {
}
}

/// Target preset name, or `None` if targeting power, hashrate, or mining mode.
pub fn target_preset(&self) -> Option<&str> {
match &self.target {
TuningTarget::Preset(name) => Some(name),
_ => None,
}
}

pub fn algorithm(&self) -> Option<&str> {
self.algorithm.as_deref()
}
Expand Down Expand Up @@ -109,6 +118,11 @@ impl TuningConfig {
Self::new(TuningTarget::MiningMode(mode))
}

#[classmethod]
fn preset(_cls: &Bound<'_, pyo3::types::PyType>, name: String) -> Self {
Self::new(TuningTarget::Preset(name))
}

#[getter]
#[pyo3(name = "variant")]
fn py_variant(&self) -> &'static str {
Expand Down Expand Up @@ -136,6 +150,13 @@ impl TuningConfig {
self.target_mode()
}

/// Target preset name, or `None` if targeting power, hashrate, or mining mode.
#[getter]
#[pyo3(name = "target_preset")]
fn py_target_preset(&self) -> Option<String> {
self.target_preset().map(str::to_owned)
}

#[getter]
#[pyo3(name = "algorithm")]
fn py_algorithm(&self) -> Option<&str> {
Expand Down Expand Up @@ -200,9 +221,13 @@ mod python_impls {
})?;
TuningTarget::MiningMode(mode)
}
"preset" => {
let name: String = get_required_field(&obj, "target_preset")?.extract()?;
TuningTarget::Preset(name)
}
_ => {
return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
"Unknown TuningConfig variant '{variant}', expected 'power', 'hashrate', or 'mode'",
"Unknown TuningConfig variant '{variant}', expected 'power', 'hashrate', 'mode', or 'preset'",
)));
}
};
Expand Down
37 changes: 36 additions & 1 deletion asic-rs-core/src/data/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub enum TuningTarget {
HashRate(HashRate),
/// Target a named mining mode.
MiningMode(MiningMode),
/// Target a named firmware preset (e.g. VNish autotune presets).
Preset(String),
}

impl TuningTarget {
Expand Down Expand Up @@ -158,6 +160,7 @@ mod python_tuning_target {
Power { watts: f64 },
HashRate { target_hashrate: HashRate },
Mode { target_mode: MiningMode },
Preset { name: String },
}

#[pymethods]
Expand All @@ -179,12 +182,18 @@ mod python_tuning_target {
Self::Mode { target_mode: mode }
}

#[staticmethod]
fn preset(name: String) -> Self {
Self::Preset { name }
}

#[getter]
fn variant(&self) -> &'static str {
match self {
Self::Power { .. } => "power",
Self::HashRate { .. } => "hashrate",
Self::Mode { .. } => "mode",
Self::Preset { .. } => "preset",
}
}

Expand Down Expand Up @@ -214,13 +223,22 @@ mod python_tuning_target {
}
}

#[getter]
fn preset_name(&self) -> Option<String> {
match self {
Self::Preset { name } => Some(name.clone()),
_ => None,
}
}

fn __repr__(&self) -> String {
match self {
Self::Power { watts } => format!("TuningTarget.power(watts={watts:?})"),
Self::HashRate { target_hashrate } => {
format!("TuningTarget.hashrate(hashrate={target_hashrate})")
}
Self::Mode { target_mode } => format!("TuningTarget.mode(mode={target_mode})"),
Self::Preset { name } => format!("TuningTarget.preset(name={name:?})"),
}
}

Expand All @@ -239,6 +257,7 @@ mod python_tuning_target {
target_hashrate: hashrate,
},
TuningTarget::MiningMode(mode) => Self::Mode { target_mode: mode },
TuningTarget::Preset(name) => Self::Preset { name },
}
}
}
Expand All @@ -251,6 +270,7 @@ mod python_tuning_target {
TuningTarget::HashRate(target_hashrate)
}
PyTuningTarget::Mode { target_mode } => TuningTarget::MiningMode(target_mode),
PyTuningTarget::Preset { name } => TuningTarget::Preset(name),
}
}
}
Expand Down Expand Up @@ -287,12 +307,17 @@ mod python_tuning_target {
"type" => required(literal_schema(core_schema, &["mode"])?),
"value" => required(<MiningMode as PyPydanticType>::pydantic_schema(core_schema, mode)?),
})?;
let preset_schema = pydantic_typed_dict_schema!(core_schema, "asic_rs.TuningTargetPreset", {
"type" => required(literal_schema(core_schema, &["preset"])?),
"value" => required(<String as PyPydanticType>::pydantic_schema(core_schema, mode)?),
})?;
let tagged_union = tagged_union_schema(
core_schema,
[
("power", power_schema),
("hashrate", hashrate_schema),
("mode", mode_schema),
("preset", preset_schema),
],
"type",
Some("asic_rs.TuningTarget"),
Expand Down Expand Up @@ -323,8 +348,11 @@ mod python_tuning_target {
"mode" => Ok(TuningTarget::MiningMode(
<MiningMode as PyPydanticType>::from_pydantic(&v)?,
)),
"preset" => Ok(TuningTarget::Preset(
<String as PyPydanticType>::from_pydantic(&v)?,
)),
_ => Err(PyValueError::new_err(format!(
"Unknown TuningTarget type '{type_str}', expected 'power', 'hashrate', or 'mode'"
"Unknown TuningTarget type '{type_str}', expected 'power', 'hashrate', 'mode', or 'preset'"
))),
}
}
Expand All @@ -351,6 +379,13 @@ mod python_tuning_target {
<MiningMode as PyPydanticType>::to_pydantic_data(m, py)?,
)?;
}
TuningTarget::Preset(name) => {
dict.set_item("type", "preset")?;
dict.set_item(
"value",
<String as PyPydanticType>::to_pydantic_data(name, py)?,
)?;
}
}
Ok(dict.into_any().unbind())
}
Expand Down
33 changes: 31 additions & 2 deletions asic-rs-core/src/traits/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
collector::{ConfigCollector, ConfigField, ConfigLocation},
fan::FanConfig,
pools::PoolGroupConfig,
preset::PresetInfo,
scaling::ScalingConfig,
temperature::TemperatureConfig,
tuning::TuningConfig,
Expand Down Expand Up @@ -43,12 +44,24 @@ pub trait MinerConstructor {
}

pub trait Miner:
GetMinerData + HasMinerControl + SupportsConfigs + UpgradeFirmware + HasAuth + HasDefaultAuth
GetMinerData
+ HasMinerControl
+ SupportsConfigs
+ SupportsPresets
+ UpgradeFirmware
+ HasAuth
+ HasDefaultAuth
{
}

impl<
T: GetMinerData + HasMinerControl + SupportsConfigs + UpgradeFirmware + HasAuth + HasDefaultAuth,
T: GetMinerData
+ HasMinerControl
+ SupportsConfigs
+ SupportsPresets
+ UpgradeFirmware
+ HasAuth
+ HasDefaultAuth,
> Miner for T
{
}
Expand Down Expand Up @@ -813,6 +826,22 @@ pub trait SetTuningPercent {
}
}

#[async_trait]
pub trait SupportsPresets {
/// List the firmware's available autotune/overclock presets.
///
/// Selecting a preset is done through [`SupportsTuningConfig::set_tuning_config`]
/// with a [`TuningTarget::Preset`], and the active preset is surfaced via
/// [`GetTuningTarget::get_tuning_target`].
async fn get_presets(&self) -> Vec<PresetInfo> {
Vec::new()
}
/// Defaults to `false`; backends with named presets override this.
fn supports_presets(&self) -> bool {
false
}
}

#[async_trait]
pub trait Restart {
async fn restart(&self) -> anyhow::Result<bool> {
Expand Down
5 changes: 5 additions & 0 deletions asic-rs-firmwares/antminer/src/backends/v2020/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,9 @@ impl SupportsTuningConfig for AntMinerV2020 {
TuningTarget::HashRate(_) => {
anyhow::bail!("Hashrate tuning target is not supported on Antminer stock firmware")
}
TuningTarget::Preset(_) => {
anyhow::bail!("Preset tuning target is not supported on Antminer stock firmware")
}
};

let pre = self.web.get_miner_conf().await?;
Expand Down Expand Up @@ -1241,6 +1244,8 @@ impl SupportsTemperatureConfig for AntMinerV2020 {}
impl GetTuningPercent for AntMinerV2020 {}
impl SetTuningPercent for AntMinerV2020 {}

impl SupportsPresets for AntMinerV2020 {}

#[cfg(test)]
mod tests {
use std::sync::Arc;
Expand Down
5 changes: 5 additions & 0 deletions asic-rs-firmwares/antminer/src/backends/v2023_07/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,9 @@ impl SupportsTuningConfig for AntMinerV202307 {
TuningTarget::HashRate(_) => {
anyhow::bail!("Hashrate tuning target is not supported on Antminer stock firmware")
}
TuningTarget::Preset(_) => {
anyhow::bail!("Preset tuning target is not supported on Antminer stock firmware")
}
};

let pre = self.web.get_miner_conf().await?;
Expand Down Expand Up @@ -1175,6 +1178,8 @@ impl SupportsTemperatureConfig for AntMinerV202307 {}
impl GetTuningPercent for AntMinerV202307 {}
impl SetTuningPercent for AntMinerV202307 {}

impl SupportsPresets for AntMinerV202307 {}

#[cfg(test)]
mod tests {
use std::sync::Arc;
Expand Down
2 changes: 2 additions & 0 deletions asic-rs-firmwares/auradine/src/backends/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,8 @@ impl SupportsTemperatureConfig for AuradineV1 {}
impl GetTuningPercent for AuradineV1 {}
impl SetTuningPercent for AuradineV1 {}

impl SupportsPresets for AuradineV1 {}

#[cfg(test)]
mod tests {
use std::sync::Arc;
Expand Down
2 changes: 2 additions & 0 deletions asic-rs-firmwares/avalonminer/src/backends/avalon_a/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,8 @@ impl SupportsTemperatureConfig for AvalonAMiner {}
impl GetTuningPercent for AvalonAMiner {}
impl SetTuningPercent for AvalonAMiner {}

impl SupportsPresets for AvalonAMiner {}

#[cfg(test)]
mod tests {
use asic_rs_core::data::board::MinerControlBoard;
Expand Down
2 changes: 2 additions & 0 deletions asic-rs-firmwares/avalonminer/src/backends/avalon_q/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ impl SupportsTemperatureConfig for AvalonQMiner {}
impl GetTuningPercent for AvalonQMiner {}
impl SetTuningPercent for AvalonQMiner {}

impl SupportsPresets for AvalonQMiner {}

#[cfg(test)]
mod tests {
use asic_rs_core::test::api::MockAPIClient;
Expand Down
2 changes: 2 additions & 0 deletions asic-rs-firmwares/bitaxe/src/backends/v2_0_0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ impl SupportsTemperatureConfig for Bitaxe200 {}
impl GetTuningPercent for Bitaxe200 {}
impl SetTuningPercent for Bitaxe200 {}

impl SupportsPresets for Bitaxe200 {}

#[cfg(test)]
mod tests {
use asic_rs_core::test::api::MockAPIClient;
Expand Down
1 change: 1 addition & 0 deletions asic-rs-firmwares/bitaxe/src/backends/v2_9_0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,3 +568,4 @@ impl SupportsFanConfig for Bitaxe290 {
impl SupportsTemperatureConfig for Bitaxe290 {}
impl GetTuningPercent for Bitaxe290 {}
impl SetTuningPercent for Bitaxe290 {}
impl SupportsPresets for Bitaxe290 {}
2 changes: 2 additions & 0 deletions asic-rs-firmwares/braiins/src/backends/v21_09/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,8 @@ impl SupportsTemperatureConfig for BraiinsV2109 {}
impl GetTuningPercent for BraiinsV2109 {}
impl SetTuningPercent for BraiinsV2109 {}

impl SupportsPresets for BraiinsV2109 {}

#[cfg(test)]
mod tests {
use asic_rs_core::test::api::MockAPIClient;
Expand Down
2 changes: 2 additions & 0 deletions asic-rs-firmwares/braiins/src/backends/v25_03/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,8 @@ impl SupportsTemperatureConfig for BraiinsV2503 {}
impl GetTuningPercent for BraiinsV2503 {}
impl SetTuningPercent for BraiinsV2503 {}

impl SupportsPresets for BraiinsV2503 {}

#[cfg(test)]
mod tests {
use std::str::FromStr;
Expand Down
2 changes: 2 additions & 0 deletions asic-rs-firmwares/braiins/src/backends/v25_05/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,8 @@ impl SupportsTemperatureConfig for BraiinsV2505 {}
impl GetTuningPercent for BraiinsV2505 {}
impl SetTuningPercent for BraiinsV2505 {}

impl SupportsPresets for BraiinsV2505 {}

#[cfg(test)]
mod tests {
use std::str::FromStr;
Expand Down
Loading