Skip to content

Commit 824d952

Browse files
author
Samuel Dare
committed
chore: merge conflicts , safe maths
1 parent e5f1346 commit 824d952

File tree

7 files changed

+79
-135
lines changed

7 files changed

+79
-135
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,7 @@ specs/*.json
4040
.idea
4141

4242
# Runtime upgrade snapshot
43-
bt.snap
43+
bt.snap
44+
45+
# localnet spec
46+
scripts/specs/local.json

justfile

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,16 @@ benchmarks:
2525

2626
clippy:
2727
@echo "Running cargo clippy..."
28-
cargo +{{RUSTV}} clippy --workspace --all-targets -- -D \
28+
cargo +{{RUSTV}} clippy --workspace --all-targets -- \
2929
-D clippy::todo \
3030
-D clippy::unimplemented
3131

3232
clippy-fix:
33-
@echo "Running cargo clippy with automatic fixes on potentially dirty code..."
34-
cargo +{{RUSTV}} clippy --fix --allow-dirty --workspace --all-targets -- -A \
35-
36-
-A clippy::todo \
37-
-A clippy::unimplemented \
38-
-A clippy::indexing_slicing
33+
@echo "Running cargo clippy with automatic fixes on potentially dirty code..."
34+
cargo +{{RUSTV}} clippy --fix --allow-dirty --workspace --all-targets -- \
35+
-A clippy::todo \
36+
-A clippy::unimplemented \
37+
-A clippy::indexing_slicing
3938
fix:
4039
@echo "Running cargo fix..."
4140
cargo +{{RUSTV}} fix --workspace
@@ -47,4 +46,5 @@ lint:
4746
@echo "Running cargo clippy with automatic fixes on potentially dirty code..."
4847
just clippy-fix
4948
@echo "Running cargo clippy..."
50-
just clippy
49+
just clippy
50+

pallets/subtensor/src/epoch.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,6 @@ impl<T: Config> Pallet<T> {
531531
inplace_col_normalize_sparse(&mut bonds_delta, n); // sum_i b_ij = 1
532532
log::trace!("ΔB (norm): {:?}", &bonds_delta);
533533

534-
535534
// Compute the Exponential Moving Average (EMA) of bonds.
536535
let mut ema_bonds =
537536
Self::compute_ema_bonds_sparse(netuid, consensus.clone(), bonds_delta, bonds);
@@ -857,8 +856,10 @@ impl<T: Config> Pallet<T> {
857856

858857
// Calculate the intercept 'b' of the logistic function.
859858
// b = ln((1 / alpha_low - 1)) + a * consensus_low
860-
let b = safe_ln((I32F32::from_num(1.0) / alpha_low).saturating_sub(I32F32::from_num(1.0)))
861-
.saturating_add(a.saturating_mul(consensus_low));
859+
let b = safe_ln(
860+
(I32F32::from_num(1.0).saturating_div(alpha_low)).saturating_sub(I32F32::from_num(1.0)),
861+
)
862+
.saturating_add(a.saturating_mul(consensus_low));
862863
log::trace!("b: {:?}", b);
863864

864865
// Return the calculated slope 'a' and intercept 'b'.

pallets/subtensor/src/math.rs

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::alloc::borrow::ToOwned;
44
#[allow(unused)]
55
use num_traits::float::Float;
6-
use sp_runtime::traits::CheckedAdd;
6+
use sp_runtime::traits::{CheckedAdd, Saturating};
77
use sp_std::cmp::Ordering;
88

99
use sp_std::vec;
@@ -1161,52 +1161,59 @@ pub fn mat_ema_alpha_vec_sparse(
11611161
let n = new.len(); // Assume square matrix, rows=cols
11621162
let zero: I32F32 = I32F32::from_num(0.0);
11631163
let mut result: Vec<Vec<(u16, I32F32)>> = vec![vec![]; n];
1164+
11641165
// Iterate over each row of the matrices.
1165-
for i in 0..new.len() {
1166+
for (i, (new_row, old_row)) in new.iter().zip(old).enumerate() {
11661167
// Initialize a row of zeros for the result matrix.
11671168
let mut row: Vec<I32F32> = vec![zero; n];
11681169

11691170
// Process the new matrix values.
1170-
for (j, value) in new[i].iter() {
1171+
for (j, value) in new_row.iter() {
11711172
// Retrieve the alpha value for the current column.
1172-
let alpha_val: I32F32 = alpha[*j as usize];
1173-
// Compute the EMA component for the new value.
1174-
row[*j as usize] = alpha_val * value;
1173+
let alpha_val: I32F32 = alpha.get(*j as usize).copied().unwrap_or(zero);
1174+
// Compute the EMA component for the new value using saturating multiplication.
1175+
if let Some(row_val) = row.get_mut(*j as usize) {
1176+
*row_val = alpha_val.saturating_mul(*value);
1177+
}
11751178
log::trace!(
11761179
"new[{}][{}] * alpha[{}] = {} * {} = {}",
11771180
i,
11781181
j,
11791182
j,
11801183
value,
11811184
alpha_val,
1182-
row[*j as usize]
1185+
row.get(*j as usize).unwrap_or(&zero)
11831186
);
11841187
}
11851188

11861189
// Process the old matrix values.
1187-
for (j, value) in old[i].iter() {
1190+
for (j, value) in old_row.iter() {
11881191
// Retrieve the alpha value for the current column.
1189-
let alpha_val: I32F32 = alpha[*j as usize];
1190-
// Calculate the complement of the alpha value.
1191-
let one_minus_alpha: I32F32 = I32F32::from_num(1.0) - alpha_val;
1192-
// Compute the EMA component for the old value and add it to the row.
1193-
row[*j as usize] += one_minus_alpha * value;
1192+
let alpha_val: I32F32 = alpha.get(*j as usize).copied().unwrap_or(zero);
1193+
// Calculate the complement of the alpha value using saturating subtraction.
1194+
let one_minus_alpha: I32F32 = I32F32::from_num(1.0).saturating_sub(alpha_val);
1195+
// Compute the EMA component for the old value and add it to the row using saturating operations.
1196+
if let Some(row_val) = row.get_mut(*j as usize) {
1197+
*row_val = row_val.saturating_add(one_minus_alpha.saturating_mul(*value));
1198+
}
11941199
log::trace!(
11951200
"old[{}][{}] * (1 - alpha[{}]) = {} * {} = {}",
11961201
i,
11971202
j,
11981203
j,
11991204
value,
12001205
one_minus_alpha,
1201-
one_minus_alpha * value
1206+
one_minus_alpha.saturating_mul(*value)
12021207
);
12031208
}
12041209

12051210
// Collect the non-zero values into the result matrix.
12061211
for (j, value) in row.iter().enumerate() {
12071212
if *value > zero {
1208-
result[i].push((j as u16, *value));
1209-
log::trace!("result[{}][{}] = {}", i, j, value);
1213+
if let Some(result_row) = result.get_mut(i) {
1214+
result_row.push((j as u16, *value));
1215+
log::trace!("result[{}][{}] = {}", i, j, value);
1216+
}
12101217
}
12111218
}
12121219
}
@@ -1224,16 +1231,17 @@ pub fn mat_ema_alpha_vec(
12241231
alpha: &[I32F32],
12251232
) -> Vec<Vec<I32F32>> {
12261233
// Check if the new matrix is empty or its first row is empty.
1227-
if new.is_empty() || new[0].is_empty() {
1234+
if new.is_empty() || new.first().map_or(true, |row| row.is_empty()) {
12281235
return vec![vec![]; 1];
12291236
}
12301237

12311238
// Ensure the dimensions of the new and old matrices match.
12321239
assert!(new.len() == old.len());
1233-
assert!(new[0].len() == alpha.len());
1240+
assert!(new.first().map_or(0, |row| row.len()) == alpha.len());
12341241

12351242
// Initialize the result matrix with zeros, having the same dimensions as the new matrix.
1236-
let mut result: Vec<Vec<I32F32>> = vec![vec![I32F32::from_num(0.0); new[0].len()]; new.len()];
1243+
let mut result: Vec<Vec<I32F32>> =
1244+
vec![vec![I32F32::from_num(0.0); new.first().map_or(0, |row| row.len())]; new.len()];
12371245

12381246
// Iterate over each row of the matrices.
12391247
for (i, (new_row, old_row)) in new.iter().zip(old).enumerate() {
@@ -1242,11 +1250,19 @@ pub fn mat_ema_alpha_vec(
12421250

12431251
// Iterate over each column of the current row.
12441252
for (j, &alpha_val) in alpha.iter().enumerate().take(new_row.len()) {
1245-
// Calculate the complement of the alpha value.
1246-
let one_minus_alpha = I32F32::from_num(1.0) - alpha_val;
1247-
1248-
// Compute the EMA for the current element.
1249-
result[i][j] = alpha_val * new_row[j] + one_minus_alpha * old_row[j];
1253+
// Calculate the complement of the alpha value using saturating subtraction.
1254+
let one_minus_alpha = I32F32::from_num(1.0).saturating_sub(alpha_val);
1255+
1256+
// Compute the EMA for the current element using saturating operations.
1257+
if let (Some(new_val), Some(old_val), Some(result_val)) = (
1258+
new_row.get(j),
1259+
old_row.get(j),
1260+
result.get_mut(i).and_then(|row| row.get_mut(j)),
1261+
) {
1262+
*result_val = alpha_val
1263+
.saturating_mul(*new_val)
1264+
.saturating_add(one_minus_alpha.saturating_mul(*old_val));
1265+
}
12501266
}
12511267
}
12521268

@@ -1271,7 +1287,7 @@ pub fn quantile(data: &[I32F32], quantile: f64) -> I32F32 {
12711287
}
12721288

12731289
// Calculate the position in the sorted array corresponding to the quantile.
1274-
let pos = quantile * (len - 1) as f64;
1290+
let pos = quantile * (len.saturating_sub(1)) as f64;
12751291

12761292
// Determine the lower index by flooring the position.
12771293
let low = pos.floor() as usize;
@@ -1281,17 +1297,26 @@ pub fn quantile(data: &[I32F32], quantile: f64) -> I32F32 {
12811297

12821298
// If the low and high indices are the same, return the value at that index.
12831299
if low == high {
1284-
sorted_data[low]
1300+
sorted_data
1301+
.get(low)
1302+
.copied()
1303+
.unwrap_or_else(|| I32F32::from_num(0))
12851304
} else {
12861305
// Otherwise, perform linear interpolation between the low and high values.
1287-
let low_value = sorted_data[low];
1288-
let high_value = sorted_data[high];
1306+
let low_value = sorted_data
1307+
.get(low)
1308+
.copied()
1309+
.unwrap_or_else(|| I32F32::from_num(0));
1310+
let high_value = sorted_data
1311+
.get(high)
1312+
.copied()
1313+
.unwrap_or_else(|| I32F32::from_num(0));
12891314

12901315
// Calculate the weight for interpolation.
12911316
let weight = I32F32::from_num(pos - low as f64);
12921317

1293-
// Return the interpolated value.
1294-
low_value + (high_value - low_value) * weight
1318+
// Return the interpolated value using saturating operations.
1319+
low_value.saturating_add((high_value.saturating_sub(low_value)).saturating_mul(weight))
12951320
}
12961321
}
12971322

pallets/subtensor/src/utils.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,9 @@ impl<T: Config> Pallet<T> {
669669

670670
pub fn get_alpha_values_32(netuid: u16) -> (I32F32, I32F32) {
671671
let (alpha_low, alpha_high): (u16, u16) = AlphaValues::<T>::get(netuid);
672-
let converted_low = I32F32::from_num(alpha_low) / I32F32::from_num(u16::MAX);
673-
let converted_high = I32F32::from_num(alpha_high) / I32F32::from_num(u16::MAX);
672+
let converted_low = I32F32::from_num(alpha_low).saturating_div(I32F32::from_num(u16::MAX));
673+
let converted_high =
674+
I32F32::from_num(alpha_high).saturating_div(I32F32::from_num(u16::MAX));
674675

675676
(converted_low, converted_high)
676677
}

pallets/subtensor/tests/math.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#![allow(
2+
clippy::arithmetic_side_effects,
3+
clippy::unwrap_used,
4+
clippy::indexing_slicing
5+
)]
16
use substrate_fixed::types::{I32F32, I64F64};
27

38
use pallet_subtensor::math::*;

scripts/specs/local.json

Lines changed: 0 additions & 91 deletions
This file was deleted.

0 commit comments

Comments
 (0)