Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/reset bonds on dereg #1443

Merged
merged 5 commits into from
Mar 21, 2025
Merged
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
38 changes: 38 additions & 0 deletions pallets/subtensor/src/epoch/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,24 @@ pub fn inplace_mask_rows(mask: &[bool], matrix: &mut [Vec<I32F32>]) {
});
}

// Apply column mask to matrix, mask=true will mask out, i.e. set to 0.
// Assumes each column has the same length.
#[allow(dead_code)]
pub fn inplace_mask_cols(mask: &[bool], matrix: &mut [Vec<I32F32>]) {
let Some(first_row) = matrix.first() else {
return;
};
assert_eq!(mask.len(), first_row.len());
let zero: I32F32 = I32F32::saturating_from_num(0);
matrix.iter_mut().for_each(|row_elem| {
row_elem.iter_mut().zip(mask).for_each(|(elem, mask_col)| {
if *mask_col {
*elem = zero;
}
});
});
}

// Mask out the diagonal of the input matrix in-place.
#[allow(dead_code)]
pub fn inplace_mask_diag(matrix: &mut [Vec<I32F32>]) {
Expand All @@ -569,6 +587,26 @@ pub fn inplace_mask_diag(matrix: &mut [Vec<I32F32>]) {
});
}

// Remove cells from sparse matrix where the mask function of a scalar and a vector is true.
#[allow(dead_code, clippy::indexing_slicing)]
pub fn scalar_vec_mask_sparse_matrix(
sparse_matrix: &[Vec<(u16, I32F32)>],
scalar: u64,
vector: &[u64],
mask_fn: &dyn Fn(u64, u64) -> bool,
) -> Vec<Vec<(u16, I32F32)>> {
let n: usize = sparse_matrix.len();
let mut result: Vec<Vec<(u16, I32F32)>> = vec![vec![]; n];
for (i, sparse_row) in sparse_matrix.iter().enumerate() {
for (j, value) in sparse_row {
if !mask_fn(scalar, vector[*j as usize]) {
result[i].push((*j, *value));
}
}
}
result
}

// Mask out the diagonal of the input matrix in-place, except for the diagonal entry at except_index.
#[allow(dead_code)]
pub fn inplace_mask_diag_except_index(matrix: &mut [Vec<I32F32>], except_index: u16) {
Expand Down
34 changes: 28 additions & 6 deletions pallets/subtensor/src/epoch/run_epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ impl<T: Config> Pallet<T> {
let current_block: u64 = Self::get_current_block_as_u64();
log::trace!("current_block:\n{:?}\n", current_block);

// Get tempo.
let tempo: u64 = Self::get_tempo(netuid).into();
log::trace!("tempo: {:?}", tempo);

// Get activity cutoff.
let activity_cutoff: u64 = Self::get_activity_cutoff(netuid) as u64;
log::trace!("activity_cutoff:\n{:?}\n", activity_cutoff);
Expand All @@ -44,7 +48,7 @@ impl<T: Config> Pallet<T> {
let block_at_registration: Vec<u64> = Self::get_block_at_registration(netuid);
log::trace!("Block at registration:\n{:?}\n", &block_at_registration);

// Outdated matrix, updated_ij=True if i has last updated (weights) after j has last registered.
// Outdated matrix, outdated_ij=True if i has last updated (weights) after j has last registered.
let outdated: Vec<Vec<bool>> = last_update
.iter()
.map(|updated| {
Expand All @@ -56,6 +60,16 @@ impl<T: Config> Pallet<T> {
.collect();
log::trace!("Outdated:\n{:?}\n", &outdated);

// Recently registered matrix, recently_ij=True if last_tempo was *before* j was last registered.
// Mask if: the last tempo block happened *before* the registration block
// ==> last_tempo <= registered
let last_tempo: u64 = current_block.saturating_sub(tempo);
let recently_registered: Vec<bool> = block_at_registration
.iter()
.map(|registered| last_tempo <= *registered)
.collect();
log::trace!("Recently registered:\n{:?}\n", &recently_registered);

// ===========
// == Stake ==
// ===========
Expand Down Expand Up @@ -185,7 +199,8 @@ impl<T: Config> Pallet<T> {

// Access network bonds.
let mut bonds: Vec<Vec<I32F32>> = Self::get_bonds(netuid);
inplace_mask_matrix(&outdated, &mut bonds); // mask outdated bonds
// Remove bonds referring to neurons that have registered since last tempo.
inplace_mask_cols(&recently_registered, &mut bonds); // mask recently registered bonds
inplace_col_normalize(&mut bonds); // sum_i b_ij = 1
log::trace!("B:\n{:?}\n", &bonds);

Expand Down Expand Up @@ -386,6 +401,10 @@ impl<T: Config> Pallet<T> {
let current_block: u64 = Self::get_current_block_as_u64();
log::trace!("current_block: {:?}", current_block);

// Get tempo.
let tempo: u64 = Self::get_tempo(netuid).into();
log::trace!("tempo:\n{:?}\n", tempo);

// Get activity cutoff.
let activity_cutoff: u64 = Self::get_activity_cutoff(netuid) as u64;
log::trace!("activity_cutoff: {:?}", activity_cutoff);
Expand Down Expand Up @@ -548,12 +567,15 @@ impl<T: Config> Pallet<T> {
let mut bonds: Vec<Vec<(u16, I32F32)>> = Self::get_bonds_sparse(netuid);
log::trace!("B: {:?}", &bonds);

// Remove bonds referring to deregistered neurons.
bonds = vec_mask_sparse_matrix(
// Remove bonds referring to neurons that have registered since last tempo.
// Mask if: the last tempo block happened *before* the registration block
// ==> last_tempo <= registered
let last_tempo: u64 = current_block.saturating_sub(tempo);
bonds = scalar_vec_mask_sparse_matrix(
&bonds,
&last_update,
last_tempo,
&block_at_registration,
&|updated, registered| updated <= registered,
&|last_tempo, registered| last_tempo <= registered,
);
log::trace!("B (outdatedmask): {:?}", &bonds);

Expand Down
1 change: 1 addition & 0 deletions pallets/subtensor/src/subnets/uids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ impl<T: Config> Pallet<T> {
Consensus::<T>::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0));
Incentive::<T>::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0));
Dividends::<T>::mutate(netuid, |v| Self::set_element_at(v, neuron_index, 0));
Bonds::<T>::remove(netuid, neuron_uid); // Remove bonds for Validator.
}

/// Replace the neuron under this uid.
Expand Down
Loading
Loading