Skip to content

Commit a9f8dde

Browse files
wip
1 parent e90205b commit a9f8dde

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed

pallets/subtensor/src/epoch/math.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,15 @@ pub fn weighted_median_col_sparse(
10221022
median
10231023
}
10241024

1025+
// Element-wise product of two vectors.
1026+
#[allow(dead_code)]
1027+
pub fn vec_mul(a: &[I32F32], b: &[I32F32]) -> Vec<I32F32> {
1028+
a.iter()
1029+
.zip(b.iter())
1030+
.map(|(x, y)| x.checked_mul(*y).unwrap_or_default())
1031+
.collect()
1032+
}
1033+
10251034
// Element-wise product of two matrices.
10261035
#[allow(dead_code)]
10271036
pub fn hadamard(mat1: &[Vec<I32F32>], mat2: &[Vec<I32F32>]) -> Vec<Vec<I32F32>> {
@@ -1257,9 +1266,21 @@ pub fn mat_ema_alpha_vec(
12571266
old_row.get(j),
12581267
result.get_mut(i).and_then(|row| row.get_mut(j)),
12591268
) {
1260-
*result_val = alpha_val
1261-
.saturating_mul(*new_val)
1262-
.saturating_add(one_minus_alpha.saturating_mul(*old_val));
1269+
let decayed_val = one_minus_alpha.saturating_mul(*old_val);
1270+
let remaining_capacity = I32F32::from_num(1.0)
1271+
.saturating_sub(decayed_val)
1272+
.max(I32F32::from_num(0.0));
1273+
1274+
// Each validator can increase bonds by at most clamped_alpha per epoch towards the cap
1275+
// Validators allocate their purchase across miners based on weights
1276+
let purchase_increment = alpha_val.saturating_mul(*new_val);
1277+
1278+
// Ensure that purchase does not exceed remaining capacity
1279+
let purchase = purchase_increment.min(remaining_capacity);
1280+
1281+
*result_val = decayed_val
1282+
.saturating_add(purchase)
1283+
.min(I32F32::from_num(1.0));
12631284
}
12641285
}
12651286
}

pallets/subtensor/src/epoch/run_epoch.rs

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,25 @@ impl<T: Config> Pallet<T> {
167167
inplace_col_normalize(&mut bonds); // sum_i b_ij = 1
168168
log::trace!("B:\n{:?}\n", &bonds);
169169

170-
// Compute bonds delta column normalized.
171-
let mut bonds_delta: Vec<Vec<I32F32>> = row_hadamard(&weights, &active_stake); // ΔB = W◦S
172-
inplace_col_normalize(&mut bonds_delta); // sum_i b_ij = 1
173-
log::trace!("ΔB:\n{:?}\n", &bonds_delta);
174170
// Compute the Exponential Moving Average (EMA) of bonds.
175-
let mut ema_bonds = Self::compute_ema_bonds(netuid, consensus.clone(), bonds_delta, bonds);
171+
// Check if Liquid Alpha is enabled, consensus is not empty, and contains non-zero values.
172+
let mut ema_bonds = if let Some(clamped_bonds_alpha) =
173+
Self::compute_liquid_alpha(netuid, consensus.clone())
174+
{
175+
// Compute the Exponential Moving Average (EMA) of bonds using the clamped alpha values.
176+
Self::compute_ema_bonds_with_liquid_alpha(&weights.clone(), &bonds, clamped_bonds_alpha)
177+
} else {
178+
log::trace!("Using Bonds Moving Average");
179+
// Compute the EMA of bonds using a normal alpha value.
180+
Self::compute_ema_bonds_normal(&weights.clone(), &bonds, netuid)
181+
};
182+
176183
inplace_col_normalize(&mut ema_bonds); // sum_i b_ij = 1
177184
log::trace!("emaB:\n{:?}\n", &ema_bonds);
178185

179-
// Compute dividends: d_i = SUM(j) b_ij * inc_j
180-
let mut dividends: Vec<I32F32> = matmul_transpose(&ema_bonds, &incentive);
186+
// # === Dividend Calculation===
187+
let total_bonds_per_validator: Vec<I32F32> = matmul_transpose(&ema_bonds, &incentive);
188+
let mut dividends: Vec<I32F32> = vec_mul(&total_bonds_per_validator, &active_stake);
181189
inplace_normalize(&mut dividends);
182190
log::trace!("D:\n{:?}\n", &dividends);
183191

@@ -1112,22 +1120,15 @@ impl<T: Config> Pallet<T> {
11121120
}
11131121
}
11141122

1115-
/// Compute the Exponential Moving Average (EMA) of bonds based on the Liquid Alpha setting.
1123+
/// Compute liquid alphas based on the Liquid Alpha setting.
11161124
///
11171125
/// # Args:
11181126
/// * `netuid` - The network ID.
11191127
/// * `consensus` - A vector of consensus values.
1120-
/// * `bonds_delta` - A vector of bond deltas.
1121-
/// * `bonds` - A vector of bonds.
11221128
///
11231129
/// # Returns:
1124-
/// A vector of EMA bonds.
1125-
pub fn compute_ema_bonds(
1126-
netuid: u16,
1127-
consensus: Vec<I32F32>,
1128-
bonds_delta: Vec<Vec<I32F32>>,
1129-
bonds: Vec<Vec<I32F32>>,
1130-
) -> Vec<Vec<I32F32>> {
1130+
/// A vector of alphas
1131+
pub fn compute_liquid_alpha(netuid: u16, consensus: Vec<I32F32>) -> Option<Vec<I32F32>> {
11311132
// Check if Liquid Alpha is enabled, consensus is not empty, and contains non-zero values.
11321133
if LiquidAlphaOn::<T>::get(netuid)
11331134
&& !consensus.is_empty()
@@ -1159,20 +1160,10 @@ impl<T: Config> Pallet<T> {
11591160
// Clamp the alpha values between alpha_high and alpha_low.
11601161
let clamped_alpha = Self::clamp_alpha_values(alpha, alpha_high, alpha_low);
11611162

1162-
// Compute the Exponential Moving Average (EMA) of bonds using the clamped alpha values.
1163-
Self::compute_ema_bonds_with_liquid_alpha(&bonds_delta, &bonds, clamped_alpha)
1164-
} else {
1165-
log::trace!("Using Bonds Moving Average");
1166-
1167-
// Compute the EMA of bonds using a normal alpha value.
1168-
Self::compute_ema_bonds_normal(&bonds_delta, &bonds, netuid)
1163+
return Some(clamped_alpha);
11691164
}
1170-
} else {
1171-
log::trace!("Using Bonds Moving Average");
1172-
1173-
// Compute the EMA of bonds using a normal alpha value.
1174-
Self::compute_ema_bonds_normal(&bonds_delta, &bonds, netuid)
11751165
}
1166+
None
11761167
}
11771168

11781169
pub fn do_set_alpha_values(

0 commit comments

Comments
 (0)