diff --git a/src/lib.rs b/src/lib.rs index 9974b2737..0aef06d65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -257,6 +257,9 @@ pub(crate) mod tests { pub trait AssertClose { type Elem: std::fmt::Display + std::fmt::Debug + Copy; const DEFAULT_TOLERANCE: Self::Elem; + fn get_default_tol(&self) -> Self::Elem { + Self::DEFAULT_TOLERANCE + } fn get_far_pair( &self, rhs: &Self, @@ -313,15 +316,100 @@ pub(crate) mod tests { } } - pub fn assert_close(a: &T, b: &T) { - a.assert_close(b, T::DEFAULT_TOLERANCE); + pub trait NdMap { + type Elem; + type Mapped; + fn ndmap O>(self, f: F) -> Self::Mapped; + } + + impl NdMap for f32 { + type Elem = Self; + type Mapped = O; + fn ndmap O>(self, mut f: F) -> O { + f(self) + } + } + + impl NdMap for f64 { + type Elem = Self; + type Mapped = O; + fn ndmap O>(self, mut f: F) -> O { + f(self) + } + } + + impl NdMap for [T; M] { + type Elem = T::Elem; + type Mapped = [T::Mapped; M]; + fn ndmap O>(self, f: F) -> Self::Mapped { + self.map(|t| t.ndmap(f)) + } } - pub fn assert_close_with_tolerance( - a: &T, - b: &T, - tolerance: T::Elem, - ) { - a.assert_close(b, tolerance); + macro_rules! assert_close_to_literal { + ($Lhs:expr, $Rhs:expr) => {{ + let lhs = $Lhs.array(); + let tol = AssertClose::get_default_tol(&lhs); + let far_pair = AssertClose::get_far_pair( + &lhs, + &$Rhs.ndmap(|x| num_traits::FromPrimitive::from_f64(x).unwrap()), + tol, + ); + if let Some((l, r)) = far_pair { + panic!("lhs != rhs | {l} != {r}"); + } + }}; + ($Lhs:expr, $Rhs:expr, $Tolerance:expr) => {{ + let far_pair = $Lhs.array().get_far_pair( + &$Rhs.ndmap(|x| num_traits::FromPrimitive::from_f64(x).unwrap()), + num_traits::FromPrimitive::from_f64($Tolerance).unwrap(), + ); + if let Some((l, r)) = far_pair { + panic!("lhs != rhs | {l} != {r}"); + } + }}; + } + pub(crate) use assert_close_to_literal; + + macro_rules! assert_close_to_tensor { + ($Lhs:expr, $Rhs:expr) => { + let lhs = $Lhs.array(); + let tol = AssertClose::get_default_tol(&lhs); + let far_pair = AssertClose::get_far_pair(&lhs, &$Rhs.array(), tol); + if let Some((l, r)) = far_pair { + panic!("lhs != rhs | {l} != {r}"); + } + }; + ($Lhs:expr, $Rhs:expr, $Tolerance:expr) => {{ + let far_pair = $Lhs.array().get_far_pair( + &$Rhs.array(), + num_traits::FromPrimitive::from_f64($Tolerance).unwrap(), + ); + if let Some((l, r)) = far_pair { + panic!("lhs != rhs | {l} != {r}"); + } + }}; + } + pub(crate) use assert_close_to_tensor; + + macro_rules! assert_close { + ($Lhs:expr, $Rhs:expr) => { + let lhs = $Lhs; + let tol = AssertClose::get_default_tol(&lhs); + let far_pair = AssertClose::get_far_pair(&lhs, &$Rhs, tol); + if let Some((l, r)) = far_pair { + panic!("lhs != rhs | {l} != {r}"); + } + }; + ($Lhs:expr, $Rhs:expr, $Tolerance:expr) => {{ + let far_pair = $Lhs.get_far_pair( + &$Rhs, + num_traits::FromPrimitive::from_f64($Tolerance).unwrap(), + ); + if let Some((l, r)) = far_pair { + panic!("lhs != rhs | {l} != {r}"); + } + }}; } + pub(crate) use assert_close; } diff --git a/src/losses.rs b/src/losses.rs index 481ff63bc..7f9923014 100644 --- a/src/losses.rs +++ b/src/losses.rs @@ -136,11 +136,11 @@ mod tests { let y: Tensor<_, TestDtype, _> = dev.tensor([-0.90954804, -1.0193185, -0.39221755, 2.2524886, 1.3035554]); let loss = mse_loss(x.leaky_trace(), y); - assert_close(&loss.array(), &1.0846305); + assert_close_to_literal!(loss, 1.0846305); let g = loss.backward(); - assert_close( - &g.get(&x).array(), - &[0.7128116, 0.31071725, -0.24555098, -0.43896183, 0.10037976], + assert_close_to_literal!( + g.get(&x), + [0.7128116, 0.31071725, -0.24555098, -0.43896183, 0.10037976] ); } @@ -152,9 +152,9 @@ mod tests { let y: Tensor<_, TestDtype, _> = dev.tensor([-0.90954804, -1.0193186, -0.39221755, 2.2524886, 1.3035554]); let loss = mae_loss(x.leaky_trace(), y); - assert_close(&loss.array(), &0.9042107); + assert_close_to_literal!(loss, 0.9042107); let g = loss.backward(); - assert_eq!(g.get(&x).array(), [0.2, 0.2, -0.2, -0.2, 0.2]); + assert_close_to_literal!(g.get(&x), [0.2, 0.2, -0.2, -0.2, 0.2]); } #[test] @@ -169,21 +169,21 @@ mod tests { [0.15627657, 0.29779273, 0.10897867, 0.2879545, 0.14899758], ]); let loss = cross_entropy_with_logits_loss(x.leaky_trace(), y.clone()); - assert_close(&loss.array(), &1.9889611); + assert_close_to_literal!(loss, 1.9889611); let g = loss.backward(); - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [-0.0972354, 0.0515665, -0.09250933, 0.07864318, 0.05953507], [0.0035581, 0.1792296, -0.0074167, -0.1233234, -0.0520476], - ], + ] ); - assert_close( - &g.get(&y).array(), - &[ + assert_close_to_literal!( + g.get(&y), + [ [1.0454637, 0.6836907, 1.4958019, 0.70222294, 0.56051415], [0.9057989, 0.21060522, 1.1814584, 1.5933538, 1.5516331], - ], + ] ); } @@ -198,7 +198,7 @@ mod tests { targ[i] = 1.0; let y = dev.tensor(targ); let loss = cross_entropy_with_logits_loss(x.leaky_trace(), y.clone()); - assert_close(&loss.array(), &losses[i]); + assert_close_to_literal!(loss, losses[i]); } } @@ -220,17 +220,17 @@ mod tests { [0.0166, 0.8512, 0.1322], ]); let loss = kl_div_with_logits_loss(logits.leaky_trace(), targ); - assert_close(&loss.array(), &0.40656143); + assert_close_to_literal!(loss, 0.40656143); let g = loss.backward(); - assert_close( - &g.get(&logits).array(), - &[ + assert_close_to_literal!( + g.get(&logits), + [ [-0.031813223, -0.044453412, 0.07626665], [0.05489187, -0.04143352, -0.013458336], [-0.037454266, 0.02207594, 0.015378334], [-0.09656205, 0.013436668, 0.083125375], [0.02881821, -0.10633193, 0.0775137], - ], + ] ); } @@ -248,26 +248,26 @@ mod tests { [0.7026833, 0.5563793, 0.6429267], ]); let loss = binary_cross_entropy_with_logits_loss(logit.leaky_trace(), prob.clone()); - assert_close(&loss.array(), &0.7045728); + assert_close_to_literal!(loss, 0.7045728); let g = loss.backward(); - assert_close( - &g.get(&logit).array(), + assert_close_to_literal!( + g.get(&logit), &[ [0.003761424, -0.054871976, 0.025817735], [-0.0009343492, 0.0051718787, 0.0074731046], [-0.047248676, -0.03401173, 0.0071035423], - ], + ] ); - assert_close( - &g.get(&prob).array(), + assert_close_to_literal!( + g.get(&prob), &[ [0.04546672, 0.07451131, -0.10224107], [0.18426175, -0.18865204, 0.16475087], [0.10635218, 0.12190584, -0.097797275], - ], + ] ); } @@ -279,26 +279,26 @@ mod tests { let targ: Tensor<_, TestDtype, _> = dev.tensor([[0.0, 0.5, 1.0]; 3]); let loss = binary_cross_entropy_with_logits_loss(logit.leaky_trace(), targ.clone()); - assert_close(&loss.array(), &33.479964); + assert_close_to_literal!(loss, 33.479964); let g = loss.backward(); - assert_close( - &g.get(&logit).array(), + assert_close_to_literal!( + g.get(&logit), &[ [0.11111111, 0.055555556, 0.0], [0.0, -0.055555556, -0.11111111], [0.029882379, 0.0, -0.02988238], - ], + ] ); - assert_close( - &g.get(&targ).array(), + assert_close_to_literal!( + g.get(&targ), &[ [-11.111112, -11.111112, -11.111112], [11.111112, 11.111112, 11.111112], [0.11111111, 0.0, -0.11111111], - ], + ] ); } @@ -317,24 +317,24 @@ mod tests { ]); let loss = huber_loss(x.leaky_trace(), y.clone(), 0.5); - assert_close(&loss.array(), &0.24506615); + assert_close_to_literal!(loss, 0.24506615); let g = loss.backward(); - assert_close( - &g.get(&x).array(), + assert_close_to_literal!( + g.get(&x), &[ [-0.016490579, 0.014802615, -0.033333335, -0.012523981, 0.0], [0.033333335, -0.0099870805, -0.033333335, 0.033333335, 0.0], [0.033333335, -0.033333335, -0.02631244, 0.033333335, 0.0], - ], + ] ); - assert_close( - &g.get(&y).array(), + assert_close_to_literal!( + g.get(&y), &[ [0.016490579, -0.014802615, 0.033333335, 0.012523981, 0.0], [-0.033333335, 0.0099870805, 0.033333335, -0.033333335, 0.0], [-0.033333335, 0.033333335, 0.02631244, -0.033333335, 0.0], - ], + ] ); } @@ -353,24 +353,24 @@ mod tests { ]); let loss = smooth_l1_loss(x.leaky_trace(), y.clone(), 0.5); - assert_close(&loss.array(), &0.4901323); + assert_close_to_literal!(loss, 0.4901323); let g = loss.backward(); - assert_close( - &g.get(&x).array(), + assert_close_to_literal!( + g.get(&x), &[ [-0.032981157, 0.02960523, -0.06666667, -0.025047962, 0.0], [0.06666667, -0.019974161, -0.06666667, 0.06666667, 0.0], [0.06666667, -0.06666667, -0.05262488, 0.06666667, 0.0], - ], + ] ); - assert_close( - &g.get(&y).array(), + assert_close_to_literal!( + g.get(&y), &[ [0.032981157, -0.02960523, 0.06666667, 0.025047962, 0.0], [-0.06666667, 0.019974161, 0.06666667, -0.06666667, 0.0], [-0.06666667, 0.06666667, 0.05262488, -0.06666667, 0.0], - ], + ] ); } } diff --git a/src/nn/batchnorm1d.rs b/src/nn/batchnorm1d.rs index e81eb1343..f72c9a591 100644 --- a/src/nn/batchnorm1d.rs +++ b/src/nn/batchnorm1d.rs @@ -226,27 +226,27 @@ mod tests { let mut bn = BatchNorm1D::<2>::build_on_device(&dev); let y1 = bn.forward_mut(x1.leaky_trace()); - assert_close( - &y1.array(), - &[ + assert_close_to_literal!( + y1, + [ [1.3168651, 0.19157785], [-1.1049646, -1.3092154], [-0.21190044, 1.1176374], - ], + ] ); let g = y1.exp().mean().backward(); - assert_close(&bn.running_mean.array(), &[-0.09994803, 0.07696156]); - assert_close(&bn.running_var.array(), &[1.1536077, 0.9321649]); - assert_close(&g.get(&bn.scale).array(), &[0.72945416, 0.5493023]); - assert_close(&g.get(&bn.bias).array(), &[0.8119954, 0.7564688]); - assert_close( - &g.get(&x1).array(), - &[ + assert_close_to_literal!(bn.running_mean, [-0.09994803, 0.07696156]); + assert_close_to_literal!(bn.running_var, [1.1536077, 0.9321649]); + assert_close_to_literal!(g.get(&bn.scale), [0.72945416, 0.5493023]); + assert_close_to_literal!(g.get(&bn.bias), [0.8119954, 0.7564688]); + assert_close_to_literal!( + g.get(&x1), + [ [0.023908734, -0.18436226], [0.040923715, 0.0703277], [-0.06483248, 0.11403453], - ], + ] ); } @@ -262,27 +262,27 @@ mod tests { let mut bn = BatchNorm1D::::build_on_device(&dev); let y1 = bn.forward_mut(x1.leaky_trace()); - assert_close( - &y1.array(), - &[ + assert_close_to_literal!( + y1, + [ [[0.059494145, 0.21366562], [-1.0539212, 0.5588659]], [[-2.0465322, 0.6680055], [-0.46153978, 0.8375814]], [[-0.041158404, 1.1465254], [1.411404, -1.2923905]], - ], + ] ); let g = y1.exp().mean().backward(); - assert_close(&bn.running_mean.array(), &[0.065665804, -0.07374697]); - assert_close(&bn.running_var.array(), &[1.0069065, 1.2117702]); - assert_close(&g.get(&bn.scale).array(), &[0.4112549, 0.6407272]); - assert_close(&g.get(&bn.bias).array(), &[0.7071625, 0.78455544]); - assert_close( - &g.get(&x1).array(), - &[ + assert_close_to_literal!(bn.running_mean, [0.065665804, -0.07374697]); + assert_close_to_literal!(bn.running_var, [1.0069065, 1.2117702]); + assert_close_to_literal!(g.get(&bn.scale), [0.4112549, 0.6407272]); + assert_close_to_literal!(g.get(&bn.bias), [0.7071625, 0.78455544]); + assert_close_to_literal!( + g.get(&x1), + [ [[-0.035488494, -0.031065114], [0.0067214966, -0.02774144]], [[0.035152107, -0.0011850521], [-0.017958358, -0.017146945]], [[-0.03715139, 0.0697379], [0.037428252, 0.018696927]], - ], + ] ); } diff --git a/src/nn/batchnorm2d.rs b/src/nn/batchnorm2d.rs index 5640ac623..120d5b04e 100644 --- a/src/nn/batchnorm2d.rs +++ b/src/nn/batchnorm2d.rs @@ -293,30 +293,27 @@ mod tests { let mut bn = BatchNorm2D::<3>::build_on_device(&dev); let y1 = bn.forward_mut(x1.leaky_trace()); - assert_close( - &y1.array(), - &[ + assert_close_to_literal!( + y1, + [ [[0.66747534, 0.77682495], [-1.698878, 0.25457793]], [[-0.89111614, 1.2611268], [-1.0644908, 0.69448]], [[0.19064833, 0.80228466], [0.6924452, -1.6853783]], - ], + ] ); let g = y1.exp().mean().backward(); - assert_close( - &bn.running_mean.array(), - &[-0.0175438, -0.0214163, 0.0268384], - ); - assert_close(&bn.running_var.array(), &[1.1361228, 1.0889612, 1.3478994]); - assert_close(&g.get(&bn.scale).array(), &[0.2506705, 0.4257624, 0.257648]); - assert_close(&g.get(&bn.bias).array(), &[0.4663894, 0.5239304, 0.4687197]); - assert_close( - &g.get(&x1).array(), - &[ + assert_close_to_literal!(bn.running_mean, [-0.0175438, -0.0214163, 0.0268384]); + assert_close_to_literal!(bn.running_var, [1.1361228, 1.0889612, 1.3478994]); + assert_close_to_literal!(g.get(&bn.scale), [0.2506705, 0.4257624, 0.257648]); + assert_close_to_literal!(g.get(&bn.bias), [0.4663894, 0.5239304, 0.4687197]); + assert_close_to_literal!( + g.get(&x1), + [ [[0.0030178577, 0.011973545], [0.0038383976, -0.018829815]], [[-0.0016367957, 0.024275035], [0.0092941, -0.03193234]], [[-0.015617318, 0.009291172], [0.0026013851, 0.0037247613]], - ], + ] ); } @@ -329,26 +326,26 @@ mod tests { let y1 = bn.forward_mut(x1.leaky_trace()); #[rustfmt::skip] - assert_close( - &y1.array(), - &[ + assert_close_to_literal!( + y1, + [ [[[-0.93348885, -2.1979978, 0.19754872],[0.29159376, -0.6282544, -1.0415624]], [[1.1156346, 0.89029306, -1.1608727],[-0.73874927, 0.13254784, -0.77676374]]], [[[0.60655713, 0.62703574, 0.12648833],[1.5577206, 0.18830705, 1.2060523]],[[0.37415895, -0.9069047, -0.9519587],[-0.02608296, 2.3435123, -0.2948149]]], - ], + ] ); let g = y1.exp().mean().backward(); - assert_close(&bn.running_mean.array(), &[-0.02424082, 0.00407672]); - assert_close(&bn.running_var.array(), &[0.9676103, 1.0458221]); - assert_close(&g.get(&bn.scale).array(), &[0.5582906, 1.1929206]); - assert_close(&g.get(&bn.bias).array(), &[0.7535024, 0.92750454]); + assert_close_to_literal!(bn.running_mean, [-0.02424082, 0.00407672]); + assert_close_to_literal!(bn.running_var, [0.9676103, 1.0458221]); + assert_close_to_literal!(g.get(&bn.scale), [0.5582906, 1.1929206]); + assert_close_to_literal!(g.get(&bn.bias), [0.7535024, 0.92750454]); #[rustfmt::skip] - assert_close( - &g.get(&x1).array(), - &[ + assert_close_to_literal!( + g.get(&x1), + [ [[[-0.00378475, 0.05601016, -0.02694868],[-0.02614748, -0.01439525, 0.00047035]],[[-0.05280511, -0.05561727, 0.04425058],[0.01388359, -0.03710236, 0.01651]]], [[[-0.01853323, -0.01773504, -0.02717264],[0.0794776, -0.02699574, 0.02575465]],[[-0.04663141, 0.02567738, 0.0289102],[-0.0294986, 0.10708933, -0.01466625]]], - ], + ] ); } @@ -360,32 +357,20 @@ mod tests { let mut bn = BatchNorm2D::<3>::build_on_device(&dev); let _ = bn.forward_mut(x1.leaky_trace()); - assert_close( - &bn.running_mean.array(), - &[0.0083191, -0.0370511, -0.0079481], - ); - assert_close(&bn.running_var.array(), &[1.0344709, 0.9340682, 1.0266376]); + assert_close_to_literal!(bn.running_mean, [0.0083191, -0.0370511, -0.0079481]); + assert_close_to_literal!(bn.running_var, [1.0344709, 0.9340682, 1.0266376]); let _ = bn.forward_mut(x1.leaky_trace()); - assert_close( - &bn.running_mean.array(), - &[0.0158063, -0.0703971, -0.0151013], - ); - assert_close(&bn.running_var.array(), &[1.0654946, 0.87472963, 1.0506116]); + assert_close_to_literal!(bn.running_mean, [0.0158063, -0.0703971, -0.0151013]); + assert_close_to_literal!(bn.running_var, [1.0654946, 0.87472963, 1.0506116]); let _ = bn.forward_mut(x1.leaky_trace()); - assert_close( - &bn.running_mean.array(), - &[0.0225448, -0.1004085, -0.0215393], - ); - assert_close(&bn.running_var.array(), &[1.093416, 0.8213248, 1.0721881]); + assert_close_to_literal!(bn.running_mean, [0.0225448, -0.1004085, -0.0215393]); + assert_close_to_literal!(bn.running_var, [1.093416, 0.8213248, 1.0721881]); let _ = bn.forward_mut(x1.leaky_trace()); - assert_close( - &bn.running_mean.array(), - &[0.0286095, -0.1274188, -0.0273335], - ); - assert_close(&bn.running_var.array(), &[1.1185452, 0.7732605, 1.0916069]); + assert_close_to_literal!(bn.running_mean, [0.0286095, -0.1274188, -0.0273335]); + assert_close_to_literal!(bn.running_var, [1.1185452, 0.7732605, 1.0916069]); let m = bn.running_mean.clone(); let v = bn.running_var.clone(); @@ -395,13 +380,13 @@ mod tests { // running stats shouldn't have been updated assert_eq!(bn.running_mean.array(), m.array()); assert_eq!(bn.running_var.array(), v.array()); - assert_close( - &y2.array(), - &[ + assert_close_to_literal!( + y2, + [ [[0.0897828, -0.01880704], [-0.55082226, -0.50515544]], [[0.13778551, 0.25317147], [-1.2689502, 0.61595416]], [[0.73018146, 0.3243845], [-1.1041277, 0.38778353]], - ], + ] ); } diff --git a/src/nn/embedding.rs b/src/nn/embedding.rs index f3f9e078a..0a109b95b 100644 --- a/src/nn/embedding.rs +++ b/src/nn/embedding.rs @@ -147,19 +147,19 @@ mod tests { let x = dev.tensor([0, 0, 1]); let y = model.forward(x.leaky_trace()); - assert_close( - &y.array(), - &[ + assert_close_to_literal!( + y, + [ [-0.3458893, -0.30371523, -0.3712057, 0.14303583, -0.0268966], [-0.3458893, -0.30371523, -0.3712057, 0.14303583, -0.0268966], [0.11733949, 0.14059687, -0.10670426, -0.09373143, 0.18974298], - ], + ] ); let g = y.square().mean().backward(); - assert_close( - &g.get(&model.weight).array(), - &[ + assert_close_to_literal!( + g.get(&model.weight), + [ [ -0.09223715, -0.08099073, @@ -174,7 +174,7 @@ mod tests { -0.012497525, 0.025299065, ], - ], + ] ); } @@ -188,9 +188,9 @@ mod tests { let x = dev.tensor([[0, 0], [0, 1]]); let y = model.forward(x.leaky_trace()); - assert_close( - &y.array(), - &[ + assert_close_to_literal!( + y, + [ [ [-0.3458893, -0.30371523, -0.3712057, 0.14303583, -0.0268966], [-0.3458893, -0.30371523, -0.3712057, 0.14303583, -0.0268966], @@ -199,13 +199,13 @@ mod tests { [-0.3458893, -0.30371523, -0.3712057, 0.14303583, -0.0268966], [0.11733949, 0.14059687, -0.10670426, -0.09373143, 0.18974298], ], - ], + ] ); let g = y.square().mean().backward(); - assert_close( - &g.get(&model.weight).array(), - &[ + assert_close_to_literal!( + g.get(&model.weight), + [ [ -0.103766784, -0.091114566, @@ -220,7 +220,7 @@ mod tests { -0.009373143, 0.018974299, ], - ], + ] ); } } diff --git a/src/nn/generalized_residual.rs b/src/nn/generalized_residual.rs index 0eeb8f62f..0acc3789a 100644 --- a/src/nn/generalized_residual.rs +++ b/src/nn/generalized_residual.rs @@ -112,13 +112,13 @@ mod tests { let y = model.forward(x.leaky_trace()); #[rustfmt::skip] - assert_close(&y.array(), &[[-0.81360567, -1.1473482], [1.0925694, 0.17383915], [-0.32519114, 0.49806428], [0.08259219, -0.7277866]]); + assert_close_to_literal!(y, [[-0.81360567, -1.1473482], [1.0925694, 0.17383915], [-0.32519114, 0.49806428], [0.08259219, -0.7277866]]); let g = y.mean().backward(); - assert_close(&g.get(&x).array(), &[[0.15889636, 0.062031522]; 4]); - assert_close(&g.get(&model.f.weight).array(), &[[-0.025407, 0.155879]; 2]); - assert_close(&g.get(&model.f.bias).array(), &[0.5; 2]); - assert_close(&g.get(&model.r.weight).array(), &[[-0.025407, 0.155879]; 2]); - assert_close(&g.get(&model.r.bias).array(), &[0.5; 2]); + assert_close_to_literal!(g.get(&x), [[0.15889636, 0.062031522]; 4]); + assert_close_to_literal!(g.get(&model.f.weight), [[-0.025407, 0.155879]; 2]); + assert_close_to_literal!(g.get(&model.f.bias), [0.5; 2]); + assert_close_to_literal!(g.get(&model.r.weight), [[-0.025407, 0.155879]; 2]); + assert_close_to_literal!(g.get(&model.r.bias), [0.5; 2]); } } diff --git a/src/nn/layer_norm.rs b/src/nn/layer_norm.rs index 0cddd3c8f..f7559a7a3 100644 --- a/src/nn/layer_norm.rs +++ b/src/nn/layer_norm.rs @@ -147,16 +147,13 @@ mod tests { let mut m = dev.build_module::, TestDtype>(); let x = dev.sample_normal::>(); let r = m.forward_mut(x.leaky_trace()); - assert_close( - &r.array(), - &[0.873304, 0.9879816, -1.6083492, 0.44028836, -0.6932247], - ); + assert_close_to_literal!(r, [0.873304, 0.9879816, -1.6083492, 0.44028836, -0.6932247]); let g = r.mean().backward(); - assert_close( - &g.get(&m.gamma).array(), - &[0.1746608, 0.19759633, -0.32166985, 0.088057674, -0.13864495], + assert_close_to_literal!( + g.get(&m.gamma), + [0.1746608, 0.19759633, -0.32166985, 0.088057674, -0.13864495] ); - assert_close(&g.get(&m.beta).array(), &[0.2; 5]); + assert_close_to_literal!(g.get(&m.beta), [0.2; 5]); } #[test] @@ -165,19 +162,19 @@ mod tests { let m = dev.build_module::, TestDtype>(); let x = dev.sample_normal::>(); let r = m.forward(x.leaky_trace()); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.873304, 0.9879816, -1.6083492, 0.44028836, -0.6932247], [0.663322, -1.8449169, 0.05217871, 0.056903206, 1.0725129], [1.0343355, -1.5559655, -0.40086073, 1.1405537, -0.21806297], - ], + ] ); let g = r.mean().backward(); - assert_close( - &g.get(&m.gamma).array(), - &[0.1713974, -0.16086, -0.1304687, 0.109183, 0.0107483], + assert_close_to_literal!( + g.get(&m.gamma), + [0.1713974, -0.16086, -0.1304687, 0.109183, 0.0107483] ); - assert_close(&g.get(&m.beta).array(), &[0.2; 5]); + assert_close_to_literal!(g.get(&m.beta), [0.2; 5]); } } diff --git a/src/nn/linear.rs b/src/nn/linear.rs index a2bb299d4..3e951ccd8 100644 --- a/src/nn/linear.rs +++ b/src/nn/linear.rs @@ -194,17 +194,17 @@ mod tests { let x = dev.tensor([-0.8808001, 2.4185333, 2.2478335, 0.0565211, 2.031299]); let y = model.forward(x.leaky_trace()); - assert_close(&y.array(), &[-0.93430865, 0.08624211]); + assert_close_to_literal!(y, [-0.93430865, 0.08624211]); let g = y.square().mean().backward(); - assert_close( - &g.get(&model.weight).array(), - &[ + assert_close_to_literal!( + g.get(&model.weight), + [ [0.82293916, -2.2596567, -2.1001704, -0.05280815, -1.8978603], [-0.07596206, 0.20857942, 0.19385791, 0.004874499, 0.17518352], - ], + ] ); - assert_close(&g.get(&model.bias).array(), &[-0.93430865, 0.08624211]); + assert_close_to_literal!(g.get(&model.bias), [-0.93430865, 0.08624211]); } #[test] @@ -222,24 +222,24 @@ mod tests { [-0.8291412, 0.07691376, -0.26538327, 0.90017676, -1.8790455], ]); let y = model.forward(x.leaky_trace()); - assert_close( - &y.array(), - &[ + assert_close_to_literal!( + y, + [ [1.3914378, -0.012851536], [-0.005462587, -0.14800104], [0.9177769, -0.7897872], - ], + ] ); let g = y.square().mean().backward(); - assert_close( - &g.get(&model.weight).array(), - &[ + assert_close_to_literal!( + g.get(&model.weight), + [ [-1.1541969, 0.6956873, -0.8553807, 0.9289255, 0.04931633], [0.29272807, -0.17702839, 0.08586791, -0.24057935, 0.5286576], - ], + ] ); - assert_close(&g.get(&model.bias).array(), &[0.7679174, -0.31687993]); + assert_close_to_literal!(g.get(&model.bias), [0.7679174, -0.31687993]); } #[test] @@ -257,9 +257,9 @@ mod tests { [[1.2879219, 0.70150787, -1.6746868, 1.7261779, -0.94021803], [-2.6883178, 2.9369607, 2.9256766, 0.27559614, -0.17530347], [0.17499207, -0.11440835, 0.16627812, -0.91773695, 1.1128315]], ]); let y = model.forward(x.leaky_trace()); - assert_close( - &y.array(), - &[ + assert_close_to_literal!( + y, + [ [ [1.3914378, -0.012851536], [-0.005462587, -0.14800104], @@ -270,15 +270,15 @@ mod tests { [-0.6274954, -0.56451213], [0.12783213, -0.0068387985], ], - ], + ] ); let g = y.square().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&model.weight).array(), - &[[-0.16088384, 0.10978711, -0.9008978, 0.59211355, -0.029177088], [0.35563633, -0.38838047, -0.17600831, -0.2034213, 0.31128058]], + assert_close_to_literal!( + g.get(&model.weight), + [[-0.16088384, 0.10978711, -0.9008978, 0.59211355, -0.029177088], [0.35563633, -0.38838047, -0.17600831, -0.2034213, 0.31128058]] ); - assert_close(&g.get(&model.bias).array(), &[0.40265593, -0.2874091]); + assert_close_to_literal!(g.get(&model.bias), [0.40265593, -0.2874091]); } } diff --git a/src/nn/prelu.rs b/src/nn/prelu.rs index e12ea7dba..122ae5f9e 100644 --- a/src/nn/prelu.rs +++ b/src/nn/prelu.rs @@ -132,10 +132,7 @@ impl> TensorCollection for PReLU1D, expected: [[TestDtype; 5]; 5]) { + fn test_matches_expected(cfg: RMSpropConfig, expected: [[f64; 5]; 5]) { let dev: TestDevice = Default::default(); let rate: Tensor<_, TestDtype, _> = dev.tensor([0.1, 1.0, 2.0, 10.0, 100.0]); let mut t: Tensor, TestDtype, _> = dev.ones(); @@ -194,8 +194,7 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).square().sum().backward(); opt.update(&mut t, &gradients).expect(""); - std::println!("{:?}", t.array()); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } @@ -209,7 +208,7 @@ mod tests { centered: false, weight_decay: None, }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.9997892, 0.98245883, 0.9703907, 0.9683808, 0.96837723], [0.99956703, 0.96670717, 0.9485176, 0.9457928, 0.945788], [0.9993329, 0.9521923, 0.9301649, 0.9270585, 0.9270531], @@ -229,7 +228,7 @@ mod tests { centered: false, weight_decay: None, }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.9997892, 0.98245883, 0.9703907, 0.9683808, 0.96837723], [0.9993773, 0.9509201, 0.9218692, 0.9173355, 0.9173275], [0.9987725, 0.9082085, 0.86019397, 0.8530321, 0.8530196], @@ -249,7 +248,7 @@ mod tests { centered: false, weight_decay: None, }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.99971724, 0.9873509, 0.9859671, 0.985858, 0.98585784], [0.9993176, 0.9763115, 0.97450525, 0.97436625, 0.97436607], [0.9987531, 0.96588355, 0.9639029, 0.9637519, 0.96375173], @@ -269,7 +268,7 @@ mod tests { centered: false, weight_decay: None, }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.9997904, 0.98252594, 0.97041094, 0.9683808, 0.96837723], [0.99956954, 0.9668238, 0.9485463, 0.94579285, 0.945788], [0.999337, 0.95234853, 0.93019867, 0.9270586, 0.9270531], @@ -289,7 +288,7 @@ mod tests { centered: true, weight_decay: None, }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.9997892, 0.98218256, 0.96900064, 0.9666708, 0.9666667], [0.99956703, 0.965664, 0.9448974, 0.941596, 0.9415902], [0.9993329, 0.9498438, 0.9236177, 0.91970736, 0.91970056], @@ -305,7 +304,7 @@ mod tests { weight_decay: Some(WeightDecay::L2(0.5)), ..Default::default() }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.9945992, 0.9797556, 0.97018003, 0.96838075, 0.96837723], [0.9890257, 0.96231526, 0.9482287, 0.94579273, 0.945788], [0.98328084, 0.94663495, 0.92983353, 0.92705846, 0.9270531], @@ -321,7 +320,7 @@ mod tests { weight_decay: Some(WeightDecay::Decoupled(0.5)), ..Default::default() }; - const EXPECTED: [[TestDtype; 5]; 5] = [ + const EXPECTED: [[f64; 5]; 5] = [ [0.9947892, 0.97745883, 0.9653907, 0.9633808, 0.96337724], [0.98959416, 0.9568803, 0.9387497, 0.93603325, 0.9360285], [0.9844144, 0.93768346, 0.91579914, 0.9127129, 0.9127075], diff --git a/src/optim/sgd/mod.rs b/src/optim/sgd/mod.rs index ce9b91b36..be945d4c5 100644 --- a/src/optim/sgd/mod.rs +++ b/src/optim/sgd/mod.rs @@ -218,8 +218,8 @@ mod tests { let gradients = loss.backward(); sgd.update(&mut pred, &gradients).expect(""); } - assert_close(&pred.array(), &[1.0; 5]); - assert_close(&targ.array(), &[1.0; 5]); + assert_close_to_literal!(pred, [1.0; 5]); + assert_close_to_literal!(targ, [1.0; 5]); } #[test] @@ -240,7 +240,7 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } @@ -270,7 +270,7 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } @@ -300,7 +300,7 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } @@ -338,13 +338,13 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd_l2.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } t = dev.ones(); for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd_decoupled.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } @@ -373,7 +373,7 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } @@ -412,7 +412,7 @@ mod tests { for e in expected.iter() { let gradients = (t.leaky_trace() * rate.clone()).mean().backward(); sgd_l2.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } // Should be equivalent to l2 regularization, even with momentum @@ -424,7 +424,7 @@ mod tests { let gradients = loss.backward(); sgd.update(&mut t, &gradients).expect(""); - assert_close(&t.array(), e); + assert_close_to_literal!(t, e); } } diff --git a/src/tensor_ops/abs/mod.rs b/src/tensor_ops/abs/mod.rs index 9c66e7272..61ca7a3a7 100644 --- a/src/tensor_ops/abs/mod.rs +++ b/src/tensor_ops/abs/mod.rs @@ -48,8 +48,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().abs(); - assert_eq!(r.array(), [2.0, 1.0, 0.0, 1.0, 2.0]); + assert_close_to_literal!(r, [2.0, 1.0, 0.0, 1.0, 2.0]); let g = r.mean().backward(); - assert_eq!(g.get(&x).array(), [-0.2, -0.2, 0.0, 0.2, 0.2]); + assert_close_to_literal!(g.get(&x), [-0.2, -0.2, 0.0, 0.2, 0.2]); } } diff --git a/src/tensor_ops/add/mod.rs b/src/tensor_ops/add/mod.rs index 0579a5e25..86a10044f 100644 --- a/src/tensor_ops/add/mod.rs +++ b/src/tensor_ops/add/mod.rs @@ -94,10 +94,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor(1.0); let r = a.leaky_trace() + b.clone(); - assert_eq!(r.array(), 2.0); + assert_close_to_literal!(r, 2.0); let g = r.backward(); - assert_eq!(g.get(&a).array(), 1.0); - assert_eq!(g.get(&b).array(), 1.0); + assert_close_to_literal!(g.get(&a), 1.0); + assert_close_to_literal!(g.get(&b), 1.0); } #[test] @@ -107,10 +107,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([1.0, -1.0, 0.0]); let r = a.leaky_trace() + b.clone(); - assert_eq!(r.array(), [2.0, 1.0, 3.0]); + assert_close_to_literal!(r, [2.0, 1.0, 3.0]); let g = r.mean().backward(); - assert_eq!(g.get(&a).array(), [1.0 / 3.0; 3]); - assert_eq!(g.get(&b).array(), [1.0 / 3.0; 3]); + assert_close_to_literal!(g.get(&a), [1.0 / 3.0; 3]); + assert_close_to_literal!(g.get(&b), [1.0 / 3.0; 3]); } #[test] @@ -122,13 +122,10 @@ mod tests { dev.tensor([[0.5199, 0.3844, 0.3759], [0.8259, 0.3682, 0.0388]]); let r = a.leaky_trace() + b.clone(); - assert_eq!( - r.array(), - [[1.1769, 0.5552, 0.5259], [1.3917, 1.0692, 0.873]] - ); + assert_close_to_literal!(r, [[1.1769, 0.5552, 0.5259], [1.3917, 1.0692, 0.873]]); let g = r.mean().backward(); - assert_eq!(g.get(&a).array(), [[1.0 / 6.0; 3]; 2]); - assert_eq!(g.get(&b).array(), [[1.0 / 6.0; 3]; 2]); + assert_close_to_literal!(g.get(&a), [[1.0 / 6.0; 3]; 2]); + assert_close_to_literal!(g.get(&b), [[1.0 / 6.0; 3]; 2]); } #[test] @@ -143,16 +140,16 @@ mod tests { let b2 = b.broadcast::, _>(); let r = a2.leaky_trace() + b2.clone(); - assert_eq!( - r.array(), + assert_close_to_literal!( + r, [ [[1.1769; 4], [0.5552; 4], [0.5259; 4]], [[1.3917; 4], [1.0692; 4], [0.873; 4]] ] ); let g = r.mean().backward(); - assert_eq!(g.get(&a2).array(), [[[1.0 / 6.0; 4]; 3]; 2]); - assert_eq!(g.get(&b2).array(), [[[1.0 / 6.0; 4]; 3]; 2]); + assert_close_to_literal!(g.get(&a2), [[[1.0 / 6.0; 4]; 3]; 2]); + assert_close_to_literal!(g.get(&b2), [[[1.0 / 6.0; 4]; 3]; 2]); } #[test] @@ -167,13 +164,10 @@ mod tests { let b2 = b.broadcast::, _>(); let r = a2.leaky_trace() + b2.clone(); - assert_eq!( - r.array(), - [[[1.1769, 0.5552, 0.5259], [1.3917, 1.0692, 0.873]]; 4] - ); + assert_close_to_literal!(r, [[[1.1769, 0.5552, 0.5259], [1.3917, 1.0692, 0.873]]; 4]); let g = r.mean().backward(); - assert_eq!(g.get(&a2).array(), [[[1.0 / 6.0; 3]; 2]; 4]); - assert_eq!(g.get(&b2).array(), [[[1.0 / 6.0; 3]; 2]; 4]); + assert_close_to_literal!(g.get(&a2), [[[1.0 / 6.0; 3]; 2]; 4]); + assert_close_to_literal!(g.get(&b2), [[[1.0 / 6.0; 3]; 2]; 4]); } #[test] @@ -181,9 +175,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor(0.0); let r = x.leaky_trace() + 1.0; - assert_eq!(r.array(), 1.0); + assert_close_to_literal!(r, 1.0); let g = r.exp().backward(); - assert_eq!(g.get(&x).array(), TestDtype::exp(1.0)); + assert_close_to_literal!(g.get(&x), f64::exp(1.0)); } #[test] @@ -191,9 +185,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([0.0, 1.0, 2.0]); let r = x.leaky_trace() + 0.5; - assert_eq!(r.array(), [0.5, 1.5, 2.5]); + assert_close_to_literal!(r, [0.5, 1.5, 2.5]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[1.6487212, 4.481689, 12.182494]); + assert_close_to_literal!(g.get(&x), [1.6487212, 4.481689, 12.182494]); } #[test] @@ -201,8 +195,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([[0.0; 2]; 3]); let r = x.leaky_trace() + 0.5; - assert_eq!(r.array(), [[0.5; 2]; 3]); + assert_close_to_literal!(r, [[0.5; 2]; 3]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[[1.6487212; 2]; 3]); + assert_close_to_literal!(g.get(&x), [[1.6487212; 2]; 3]); } } diff --git a/src/tensor_ops/axpy/mod.rs b/src/tensor_ops/axpy/mod.rs index 12ad5e639..73c72df38 100644 --- a/src/tensor_ops/axpy/mod.rs +++ b/src/tensor_ops/axpy/mod.rs @@ -85,12 +85,12 @@ mod tests { a.axpy(0.01, &b, 0.99); - assert_close( - &a.array(), - &[ + assert_close_to_literal!( + a, + [ [-1.505, -1.495, -1.485, -1.475, -1.465], [1.465, 1.475, 1.485, 1.495, 1.505], - ], + ] ); } } diff --git a/src/tensor_ops/bce/mod.rs b/src/tensor_ops/bce/mod.rs index f8d26162b..545cd2798 100644 --- a/src/tensor_ops/bce/mod.rs +++ b/src/tensor_ops/bce/mod.rs @@ -70,12 +70,12 @@ mod tests { [0.75429636, 0.66566986, 0.6182751], ]); let r = a.leaky_trace().bce_with_logits(b); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.79638255, 0.69238377, 1.161215], [0.561272, 0.63843495, 0.8688978], - ], + ] ); } } diff --git a/src/tensor_ops/broadcast_to.rs b/src/tensor_ops/broadcast_to.rs index 7951992d6..e63476b5b 100644 --- a/src/tensor_ops/broadcast_to.rs +++ b/src/tensor_ops/broadcast_to.rs @@ -136,7 +136,7 @@ mod tests { let a: Tensor, TestDtype, _> = dev.sample_normal(); let b: Tensor, TestDtype, _> = dev.sample_normal(); let a_up = a.leaky_trace().broadcast::, _>(); - a_up.array().assert_close(&[a.array(); 5], 1e-4); + assert_close!(a_up.array(), [a.array(); 5], 1e-4); let r = a_up * b.clone(); let g = r.exp().mean().backward(); @@ -145,8 +145,8 @@ mod tests { let a_grad = (b.clone() * (b.clone() * a_up.clone()).exp()).sum::, _>() / 15.0; // b's gradient: (a * (b * a).exp()) / 15 let b_grad = (a_up.clone() * (b.clone() * a_up).exp()) / 15.0; - g.get(&a).array().assert_close(&a_grad.array(), 1e-4); - g.get(&b).array().assert_close(&b_grad.array(), 1e-4); + assert_close_to_tensor!(g.get(&a), a_grad, 1e-4); + assert_close_to_tensor!(g.get(&b), b_grad, 1e-4); } #[test] @@ -159,6 +159,6 @@ mod tests { .exp() .mean() .backward(); - assert_close(&g.get(&a).array(), &a.array().map(|x| x.exp() / 3.0)); + assert_close_to_tensor!(g.get(&a), a.exp() / 3.0); } } diff --git a/src/tensor_ops/clamp/mod.rs b/src/tensor_ops/clamp/mod.rs index 0083262f9..2d75b51ef 100644 --- a/src/tensor_ops/clamp/mod.rs +++ b/src/tensor_ops/clamp/mod.rs @@ -51,11 +51,8 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[-1.0, 0.0, 1.0], [-2.0, 2.0, 1.1]]); let r = t.leaky_trace().clamp(-1.0, 1.0); - assert_close(&r.array(), &[[-1.0, 0.0, 1.0], [-1.0, 1.0, 1.0]]); + assert_close_to_literal!(r, [[-1.0, 0.0, 1.0], [-1.0, 1.0, 1.0]]); let g = r.exp().mean().backward(); - assert_close( - &g.get(&t).array(), - &[[0.06131324, 0.16666667, 0.45304698], [0.0; 3]], - ); + assert_close_to_literal!(g.get(&t), [[0.06131324, 0.16666667, 0.45304698], [0.0; 3]]); } } diff --git a/src/tensor_ops/conv2d/mod.rs b/src/tensor_ops/conv2d/mod.rs index db26fb38c..dfcb0b434 100644 --- a/src/tensor_ops/conv2d/mod.rs +++ b/src/tensor_ops/conv2d/mod.rs @@ -229,7 +229,6 @@ impl< mod tests { use super::*; use crate::{tensor_ops::*, tests::*}; - use num_traits::FromPrimitive; #[test] /// Produced by @@ -251,26 +250,26 @@ mod tests { ]]); let result = x.leaky_trace().conv2d::<1, 0>(weight.clone()) + bias.leaky_trace().broadcast::<_, Axes2<1, 2>>(); - assert_close( - &result.array(), - &[[[0.24369538, 0.71453357]], [[-0.69169492, -0.06172103]]], + assert_close_to_literal!( + result, + [[[0.24369538, 0.71453357]], [[-0.69169492, -0.06172103]]] ); let g = result.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[ + assert_close_to_literal!( + g.get(&x), + [[ [0.03936806, -0.08457474, -0.26788417], [-0.03140351, -0.04316529, 0.02424446], - ]], + ]] ); - assert_close( - &g.get(&weight).array(), - &[ + assert_close_to_literal!( + g.get(&weight), + [ [[[-0.00703794, -0.31814471], [0.19160703, -0.00260070]]], [[[0.01548620, -0.15778227], [0.10209797, -0.01799832]]], - ], + ] ); - assert_close(&g.get(&bias).array(), &[0.82979727, 0.36021793]); + assert_close_to_literal!(g.get(&bias), [0.82979727, 0.36021793]); } #[test] @@ -294,24 +293,24 @@ mod tests { let result = x.leaky_trace().conv2d::<2, 0>(weight.clone()) + bias.leaky_trace().broadcast::<_, Axes2<1, 2>>(); - assert_close(&result.array(), &[[[-0.29368058]], [[0.30018353]]]); + assert_close_to_literal!(result, [[[-0.29368058]], [[0.30018353]]]); let g = result.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[[-0.03917716, 0.06006697, 0.], [0.19859464, 0.19576924, 0.]]], + assert_close_to_literal!( + g.get(&x), + [[[-0.03917716, 0.06006697, 0.], [0.19859464, 0.19576924, 0.]]] ); - assert_close( - &g.get(&weight).array(), - &[ + assert_close_to_literal!( + g.get(&weight), + [ [[[0.13829342, -0.22180916], [-0.11759478, 0.21646728]]], [[[0.25044560, -0.40169036], [-0.21296094, 0.39201635]]], - ], + ] ); - assert_close(&g.get(&bias).array(), &[0.37275729, 0.67505330]); + assert_close_to_literal!(g.get(&bias), [0.37275729, 0.67505330]); } #[test] @@ -331,33 +330,33 @@ mod tests { + bias.leaky_trace().broadcast::<_, Axes2<1, 2>>(); #[rustfmt::skip] - assert_close( - &result.array(), - &[ + assert_close_to_literal!( + result, + [ [[-0.37165433, 0.26964033, -0.47000977],[-0.52418506, 0.3161699, -0.56809187]], [[0.10800815, 0.66143924, 0.16603859],[-0.11654915, 0.5421771, 0.21993488]], [[0.26416105, -0.22402346, 0.420797],[-0.23212466, 0.3085245, 0.41083777]], - ], + ] ); let g = result.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[[0.010052743, 0.038219165]], [[0.0013861917, 0.096129306]]], + assert_close_to_literal!( + g.get(&x), + [[[0.010052743, 0.038219165]], [[0.0013861917, 0.096129306]]] ); #[rustfmt::skip] - assert_close( - &g.get(&weight).array(), - &[ + assert_close_to_literal!( + g.get(&weight), + [ [[[-0.03488452, -0.035597768], [-0.03483199, -0.036207683]],[[-0.05705857, 0.03406856], [-0.05008337, 0.024666183]]], [[[-0.053492695, -0.04727108], [-0.05620105, -0.055251926]],[[-0.04363727, 0.033381317], [-0.0607851, 0.030584559]]], [[[-0.051853612, -0.03900232], [-0.04206547, -0.037880093]],[[-0.0073834136, 0.0208545], [0.02886929, -0.040557314]]], - ], + ] ); - assert_close(&g.get(&bias).array(), &[0.28636602, 0.44933242, 0.40484178]); + assert_close_to_literal!(g.get(&bias), [0.28636602, 0.44933242, 0.40484178]); } #[test] @@ -376,32 +375,32 @@ mod tests { + bias.leaky_trace().broadcast::<_, Axes2<1, 2>>(); #[rustfmt::skip] - assert_close( - &result.array(), - &[ + assert_close_to_literal!( + result, + [ [[-0.07123789, -0.07123789, -0.07123789],[-0.07123789, -0.14481398, -0.07123789],[-0.07123789, -0.59748650, -0.07123789],[-0.07123789, -0.07123789, -0.07123789]], [[-0.17244765, -0.17244765, -0.17244765],[-0.17244765, -0.3061839, -0.17244765],[-0.17244765, -0.42046443, -0.17244765],[-0.17244765, -0.17244765, -0.17244765]], - ], + ] ); let g = result.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[[[-0.009780421, 0.01484663],[0.010391434, 0.0062526874],[0.00032053515, -0.009087289],[-0.0073772445, 0.0105412705]]], + assert_close_to_literal!( + g.get(&x), + [[[-0.009780421, 0.01484663],[0.010391434, 0.0062526874],[0.00032053515, -0.009087289],[-0.0073772445, 0.0105412705]]] ); #[rustfmt::skip] - assert_close( - &g.get(&weight).array(), - &[ + assert_close_to_literal!( + g.get(&weight), + [ [[[0.0, 0.019200183, 0.012330416],[0.0, 0.051398464, -0.003175714],[0.0, -0.013860448, 0.0011212977]]], [[[0.0, 0.02291844, 0.01471829],[0.0, 0.05281557, -0.0069562597],[0.0, -0.011794927, 0.00095419877]]], - ], + ] ); - assert_close(&g.get(&bias).array(), &[0.44699076, 0.408709]); + assert_close_to_literal!(g.get(&bias), [0.44699076, 0.408709]); } #[test] @@ -416,7 +415,7 @@ mod tests { let out = out + bias.broadcast::<_, Axes2<1, 2>>(); #[rustfmt::skip] - assert_close(&out.array(), &[ + assert_close_to_literal!(out, [ [[-0.57176435, -0.57176435, -0.57176435],[-0.57176435, 1.0759051, 1.4307989],[-0.57176435, -0.86296344, -1.8794353]], [[0.29306656, 0.29306656, 0.29306656],[0.29306656, 0.9771965, 1.467767],[0.29306656, -6.367015, -2.3370528]], [[-0.19717735, -0.19717735, -0.19717735],[-0.19717735, 1.3412137, 2.9476144],[-0.19717735, 4.247249, -2.1779637]], @@ -430,10 +429,10 @@ mod tests { let w: Tensor, TestDtype, _> = dev.sample_normal(); let y: Tensor, _, _, _> = x.leaky_trace().conv2d::<3, 2>(w.clone()); - let y0 = y.array(); + let y0 = y.retaped::(); let grads0 = y.square().mean().backward(); - let x0 = grads0.get(&x).array(); - let w0 = grads0.get(&w).array(); + let x0 = grads0.get(&x); + let w0 = grads0.get(&w); let x = x .broadcast::, _>() @@ -442,16 +441,16 @@ mod tests { let y: Tensor, _, _, _> = x.leaky_trace().conv2d::<3, 2>(w.clone()); for i in 0..10 { - assert_close(&y0, &y.retaped::().select(dev.tensor(i)).array()); + assert_close_to_tensor!(y0, y.retaped::().select(dev.tensor(i))); } let grads = y.square().mean().backward(); - w0.assert_close(&(grads.get(&w)).array(), TestDtype::from_f32(1e-3).unwrap()); + assert_close_to_tensor!(w0, grads.get(&w), 1e-3); let x_grad = grads.get(&x) * 10.0; for i in 0..10 { - assert_close(&x0, &x_grad.clone().select(dev.tensor(i)).array()); + assert_close_to_tensor!(x0, x_grad.clone().select(dev.tensor(i))); } } } diff --git a/src/tensor_ops/convtrans2d/mod.rs b/src/tensor_ops/convtrans2d/mod.rs index ae4db712a..4b69b142e 100644 --- a/src/tensor_ops/convtrans2d/mod.rs +++ b/src/tensor_ops/convtrans2d/mod.rs @@ -226,7 +226,6 @@ impl< mod tests { use super::*; use crate::{tensor_ops::*, tests::*}; - use num_traits::FromPrimitive; #[test] /// TODO @@ -258,33 +257,33 @@ mod tests { ]); let y = x.leaky_trace().convtrans2d::<1, 0>(w.clone()); #[rustfmt::skip] - assert_close( - &y.array(), - &[ + assert_close_to_literal!( + y, + [ [[0.0950315, 0.7752370, 1.4619386, 1.2272182, 0.4955567], [0.9404547, 2.0147018, 2.9196219, 2.3676410, 1.0898490], [0.9427375, 2.4812443, 3.9218845, 3.6057489, 1.6545289], [0.7178541, 1.8030399, 3.0822182, 1.9167527, 1.0201255], [0.1575270, 0.6028528, 0.8236330, 0.8117172, 0.4487746]], [[0.0818333, 0.5889638, 0.7130897, 0.9325359, 0.3723960], [0.9338222, 1.1092455, 2.6313026, 1.3005096, 0.5866395], [1.0377907, 2.8708880, 3.3737209, 2.5207422, 1.1140431], [1.6855066, 1.9777625, 3.1483138, 1.4968101, 0.8816571], [0.4305007, 1.0563757, 1.3593760, 0.9304471, 0.4780220]], [[0.1231446, 0.9889490, 1.7642095, 1.5334388, 0.5994515], [1.3248383, 2.7914243, 3.7239599, 2.3741565, 1.0753872], [1.5313777, 2.9749527, 4.2994099, 3.4086916, 1.9924896], [1.2760720, 1.3538387, 3.8719988, 1.6865263, 1.5946647], [0.2967100, 0.8310994, 1.0901904, 1.1780756, 0.6721083]], - ], + ] ); let g = y.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [[2.4066830, 2.4581399, 2.5645943], [3.0028410, 3.2547507, 3.4216807], [2.1464431, 3.0581608, 2.8662176]], [[2.9864695, 3.5932014, 2.5797451], [3.3677268, 3.8909531, 3.2242548], [2.4629762, 3.3527191, 2.9590628]], - ], + ] ); #[rustfmt::skip] - assert_close( - &g.get(&w).array(), - &[ + assert_close_to_literal!( + g.get(&w), + [ [[[0.6642238, 1.0354118, 0.9408946], [0.9326871, 1.1026800, 1.0413336], [0.5472590, 0.7134937, 0.7234858]], [[0.5456561, 0.7068147, 0.6173539], [0.8016681, 1.0878984, 1.0714644], [0.8350498, 1.1260045, 0.7775879]]], [[[0.5567597, 0.5549879, 0.4975571], [0.6702054, 0.8184303, 0.6338357], [0.6227797, 0.5077031, 0.5278049]], [[0.3733614, 0.3889205, 0.3597363], [0.6457027, 0.7389204, 0.5783513], [0.7389930, 0.7089815, 0.5071381]]], [[[1.1678052, 1.4273405, 1.2900156], [1.4765850, 1.5869446, 1.4983673], [1.0089380, 0.8733283, 1.0910161]], [[0.9175905, 1.0371233, 0.9381008], [1.4550014, 1.5706275, 1.4026034], [1.3066854, 1.4330946, 1.0638479]]], - ], + ] ); } @@ -315,33 +314,33 @@ mod tests { ]); let y = x.leaky_trace().convtrans2d::<2, 0>(w.clone()); #[rustfmt::skip] - assert_close( - &y.array(), - &[ + assert_close_to_literal!( + y, + [ [[0.0521149, 0.0666962, 0.1576860, 0.2318948, 0.4811018, 0.4908646, 0.3878066,],[0.0572037, 0.1399591, 0.2562388, 0.4253721, 0.8630048, 1.0908685, 0.8445575,],[0.5902850, 0.2447678, 1.3523079, 0.3064790, 1.4716963, 0.5718186, 1.1411824,],[0.4790645, 0.7306364, 0.5590932, 0.3465975, 0.3586293, 0.2446325, 0.1219794,],[0.8389287, 0.7641755, 2.1468871, 0.7580858, 1.6488208, 0.4078493, 0.8917535,],[0.7521397, 1.3120791, 1.5495670, 1.5312154, 1.6393251, 0.9781042, 0.5516644,],[0.3645314, 0.6125304, 1.4806095, 0.7151946, 1.3534986, 0.4565403, 0.5764900,],], [[0.0467758, 0.0816279, 0.2529318, 0.2647139, 0.5785270, 0.6197178, 0.5749097,],[0.0940269, 0.0473439, 0.4393802, 0.1367552, 1.1979207, 0.3760918, 1.0771828,],[0.0882189, 0.3613173, 0.5524452, 0.2317001, 0.7967559, 0.3886862, 0.8587984,],[0.4311106, 0.2884232, 0.7299427, 0.1313255, 0.4212312, 0.0960777, 0.1760126,],[0.5547202, 1.0043029, 1.7619288, 0.9596879, 1.2826418, 0.5885472, 0.6480764,],[0.8100029, 0.4932112, 2.0489488, 0.5505725, 1.9815230, 0.3730083, 0.7659331,],[0.5683053, 0.5217513, 1.6775545, 0.4934808, 1.6013979, 0.4135783, 0.8336955,],], [[0.1094690, 0.0878869, 0.3636634, 0.2225572, 1.0195196, 0.7292423, 0.4567231,],[0.1196501, 0.0582169, 0.4756527, 0.1914707, 1.0404429, 0.4393238, 0.3976323,],[0.8271067, 0.8317585, 1.2522885, 0.6402028, 1.5488806, 1.1506698, 0.9447322,],[0.2783581, 0.2198445, 0.3992766, 0.1154844, 0.2090276, 0.0746117, 0.0746450,],[1.5267723, 1.8244361, 2.8728042, 1.4814504, 2.0451818, 1.1080496, 0.7630367,],[0.7074417, 0.4451926, 1.4631481, 0.5704955, 1.0126743, 0.3209994, 0.3122311,],[0.7568032, 1.1887968, 2.1608419, 1.3324623, 1.7372788, 0.8979155, 0.8516415,],], - ], + ] ); let g = y.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [[0.1513395, 0.1986136, 0.2298895],[0.3779295, 0.3469064, 0.2452929],[0.4825282, 0.5639746, 0.3148936],], [[0.1527605, 0.2144486, 0.2480491],[0.3177541, 0.3597765, 0.2327209],[0.3772507, 0.5048490, 0.2865718],], - ], + ] ); #[rustfmt::skip] - assert_close( - &g.get(&w).array(), - &[ + assert_close_to_literal!( + g.get(&w), + [ [[[0.1134962, 0.0483045, 0.1292279],[0.0842974, 0.0839551, 0.0851499],[0.0981565, 0.0517171, 0.1198249],],[[0.0928453, 0.0412302, 0.0897282],[0.0699945, 0.0741750, 0.0777097],[0.0907740, 0.0422520, 0.0901646],],], [[[0.0771443, 0.0567608, 0.0866109],[0.1149883, 0.0410739, 0.1213422],[0.0952494, 0.0514846, 0.1152932],],[[0.0687711, 0.0483170, 0.0680406],[0.1007998, 0.0350681, 0.1096105],[0.0770078, 0.0379331, 0.0848609],],], [[[0.1948610, 0.1028565, 0.1976164],[0.0683245, 0.0401628, 0.0643963],[0.1662624, 0.1036348, 0.2046718],],[[0.1715550, 0.0769297, 0.1411840],[0.0654903, 0.0355645, 0.0568618],[0.1351082, 0.0760437, 0.1234931],],], - ], + ] ); } @@ -352,10 +351,10 @@ mod tests { let w: Tensor, TestDtype, _> = dev.sample_normal(); let y: Tensor, _, _, _> = x.leaky_trace().convtrans2d::<3, 2>(w.clone()); - let y0 = y.array(); + let y0 = y.retaped::(); let grads0 = y.square().mean().backward(); - let x0 = grads0.get(&x).array(); - let w0 = grads0.get(&w).array(); + let x0 = grads0.get(&x); + let w0 = grads0.get(&w); let x = x .broadcast::, _>() @@ -364,19 +363,16 @@ mod tests { let y: Tensor, _, _, _> = x.leaky_trace().convtrans2d::<3, 2>(w.clone()); for i in 0..10 { - y0.assert_close( - &y.retaped::().select(dev.tensor(i)).array(), - TestDtype::from_f32(1e-5).unwrap(), - ); + assert_close_to_tensor!(y0, y.retaped::().select(dev.tensor(i)), 1e-5); } let grads = y.square().mean().backward(); - assert_close(&w0, &(grads.get(&w)).array()); + assert_close_to_tensor!(w0, grads.get(&w)); let x_grad = grads.get(&x) * 10.0; for i in 0..10 { - assert_close(&x0, &x_grad.clone().select(dev.tensor(i)).array()); + assert_close_to_tensor!(x0, x_grad.clone().select(dev.tensor(i))); } } } diff --git a/src/tensor_ops/cos/mod.rs b/src/tensor_ops/cos/mod.rs index 3d193eb3f..b9d13d90d 100644 --- a/src/tensor_ops/cos/mod.rs +++ b/src/tensor_ops/cos/mod.rs @@ -47,14 +47,11 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().cos(); - assert_close( - &r.array(), - &[-0.41614684, 0.5403023, 1.0, 0.5403023, -0.41614684], - ); + assert_close_to_literal!(r, [-0.41614684, 0.5403023, 1.0, 0.5403023, -0.41614684]); let g = r.mean().backward(); - assert_close( - &g.get(&x).array(), - &[0.18185948, 0.16829419, -0.0, -0.16829419, -0.18185948], + assert_close_to_literal!( + g.get(&x), + [0.18185948, 0.16829419, -0.0, -0.16829419, -0.18185948] ); } } diff --git a/src/tensor_ops/div/mod.rs b/src/tensor_ops/div/mod.rs index 005121a21..4ce5bc74d 100644 --- a/src/tensor_ops/div/mod.rs +++ b/src/tensor_ops/div/mod.rs @@ -92,10 +92,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor(4.0); let r = b.leaky_trace() / a.clone(); - assert_eq!(r.array(), 2.0); + assert_close_to_literal!(r, 2.0); let g = r.backward(); - assert_close(&g.get(&a).array(), &-1.0); - assert_close(&g.get(&b).array(), &0.5); + assert_close_to_literal!(g.get(&a), -1.0); + assert_close_to_literal!(g.get(&b), 0.5); } #[test] @@ -105,10 +105,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([1.0, -1.0, 0.0]); let r = b.leaky_trace() / a.clone(); - assert_eq!(r.array(), [1.0, -0.5, 0.0]); + assert_close_to_literal!(r, [1.0, -0.5, 0.0]); let g = r.mean().backward(); - assert_close(&g.get(&a).array(), &[-1.0 / 3.0, 1.0 / 12.0, 0.0]); - assert_close(&g.get(&b).array(), &[1.0 / 3.0, 1.0 / 6.0, 0.11111112]); + assert_close_to_literal!(g.get(&a), [-1.0 / 3.0, 1.0 / 12.0, 0.0]); + assert_close_to_literal!(g.get(&b), [1.0 / 3.0, 1.0 / 6.0, 0.11111112]); } #[test] @@ -120,27 +120,27 @@ mod tests { dev.tensor([[0.5199, 0.3844, 0.3759], [0.8259, 0.3682, 0.0388]]); let r = b.leaky_trace() / a.clone(); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.79132426, 2.2505856, 2.5059998], [1.4597031, 0.52524966, 0.046511628], - ], + ] ); let g = r.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [-0.20074181, -2.1961217, -2.7844446], [-0.42998204, -0.12488105, -0.009292662], - ], + ] ); - assert_close( - &g.get(&b).array(), + assert_close_to_literal!( + g.get(&b), &[ [0.25367835, 0.97580016, 1.1111112], [0.29456818, 0.2377556, 0.1997922], - ], + ] ); } @@ -149,9 +149,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor(1.0); let r = x.leaky_trace() / 2.0; - assert_eq!(r.array(), 0.5); + assert_close_to_literal!(r, 0.5); let g = r.exp().backward(); - assert_close(&g.get(&x).array(), &0.8243606); + assert_close_to_literal!(g.get(&x), 0.8243606); } #[test] @@ -159,9 +159,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([0.0, 1.0, 2.0]); let r = x.leaky_trace() / 2.0; - assert_eq!(r.array(), [0.0, 0.5, 1.0]); + assert_close_to_literal!(r, [0.0, 0.5, 1.0]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[0.5, 0.8243606, 1.3591409]); + assert_close_to_literal!(g.get(&x), [0.5, 0.8243606, 1.3591409]); } #[test] @@ -169,8 +169,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([[1.0; 2]; 3]); let r = x.leaky_trace() / 2.0; - assert_eq!(r.array(), [[0.5; 2]; 3]); + assert_close_to_literal!(r, [[0.5; 2]; 3]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[[0.8243606; 2]; 3]); + assert_close_to_literal!(g.get(&x), [[0.8243606; 2]; 3]); } } diff --git a/src/tensor_ops/dropout/mod.rs b/src/tensor_ops/dropout/mod.rs index 045ae35e3..a11352c3d 100644 --- a/src/tensor_ops/dropout/mod.rs +++ b/src/tensor_ops/dropout/mod.rs @@ -88,9 +88,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, f32, _> = dev.tensor(3.0); let r = t.leaky_trace().dropout(1.0); - assert_eq!(r.array(), 0.0); + assert_close_to_literal!(r, 0.0); let g = r.backward(); - assert_eq!(g.get(&t).array(), 0.0); + assert_close_to_literal!(g.get(&t), 0.0); } #[test] @@ -98,9 +98,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, f32, _> = dev.tensor(3.0); let r = t.leaky_trace().dropout(0.0); - assert_eq!(r.array(), 3.0); + assert_close_to_literal!(r, 3.0); let g = r.backward(); - assert_eq!(g.get(&t).array(), 1.0); + assert_close_to_literal!(g.get(&t), 1.0); } #[test] @@ -108,9 +108,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, f32, _> = dev.tensor([0.0, 2.0, -3.0, -4.0, 0.0]); let r = t.leaky_trace().dropout(0.5); - assert_eq!(r.array(), [0.0, 4.0, -6.0, 0.0, 0.0]); + assert_close_to_literal!(r, [0.0, 4.0, -6.0, 0.0, 0.0]); let g = r.mean().backward(); - assert_eq!(g.get(&t).array(), [0.4, 0.4, 0.4, 0.0, 0.0]); + assert_close_to_literal!(g.get(&t), [0.4, 0.4, 0.4, 0.0, 0.0]); } #[test] @@ -118,12 +118,12 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, f32, _> = dev.tensor([[0.05, 0.1, -0.2], [0.3, -0.4, 0.5]]); let r = t.leaky_trace().dropout(0.6); - assert_close(&r.array(), &[[0.125, 0.25, -0.5], [0.0, 0.0, 1.25]]); + assert_close_to_literal!(r, [[0.125, 0.25, -0.5], [0.0, 0.0, 1.25]]); // NOTE: .exp() so we ensure result grad is used properly let g = r.exp().mean().backward(); - assert_close( - &g.get(&t).array(), - &[[0.47214523, 0.5350107, 0.2527211], [0.0, 0.0, 1.4543099]], + assert_close_to_literal!( + g.get(&t), + [[0.47214523, 0.5350107, 0.2527211], [0.0, 0.0, 1.4543099]] ); } } diff --git a/src/tensor_ops/exp/mod.rs b/src/tensor_ops/exp/mod.rs index 833c0e7a4..a8c762a96 100644 --- a/src/tensor_ops/exp/mod.rs +++ b/src/tensor_ops/exp/mod.rs @@ -47,14 +47,11 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().exp(); - assert_close( - &r.array(), - &[0.13533528, 0.36787945, 1.0, TestDtype::exp(1.0), 7.389056], - ); + assert_close_to_literal!(r, [0.13533528, 0.36787945, 1.0, f64::exp(1.0), 7.389056]); let g = r.mean().backward(); - assert_close( - &g.get(&x).array(), - &[0.027067056, 0.07357589, 0.2, 0.54365635, 1.4778112], + assert_close_to_literal!( + g.get(&x), + [0.027067056, 0.07357589, 0.2, 0.54365635, 1.4778112] ); } } diff --git a/src/tensor_ops/gelu/mod.rs b/src/tensor_ops/gelu/mod.rs index 5ddfbc059..98e208a44 100644 --- a/src/tensor_ops/gelu/mod.rs +++ b/src/tensor_ops/gelu/mod.rs @@ -45,16 +45,12 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().gelu(); - assert_close( - &r.array(), - &[-0.04540229, -0.158808, 0.0, 0.841192, 1.9545977], - ); - + assert_close_to_literal!(r, [-0.04540229, -0.158808, 0.0, 0.841192, 1.9545977]); // NOTE: call .exp() to make sure we cover cases where .gelu() uses the result's gradient let g = r.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[-0.016455507, -0.014156329, 0.1, 0.5023068, 1.5338063], + assert_close_to_literal!( + g.get(&x), + [-0.016455507, -0.014156329, 0.1, 0.5023068, 1.5338063] ); } } diff --git a/src/tensor_ops/huber_error/mod.rs b/src/tensor_ops/huber_error/mod.rs index 3f84c3a20..c64d77950 100644 --- a/src/tensor_ops/huber_error/mod.rs +++ b/src/tensor_ops/huber_error/mod.rs @@ -75,13 +75,13 @@ mod tests { ]); let r1 = a.leaky_trace().huber_error(b.leaky_trace(), 1.0); let r2 = a.leaky_trace().huber_error(b.leaky_trace(), 100.0); - assert_close( - &r1.array(), - &[ + assert_close_to_literal!( + r1, + [ [0.8626251, 0.0013595072, 0.37522575], [0.16297975, 0.003332735, 0.79848814], - ], + ] ); - assert_close(&r2.array(), &((a - b).square() / 2.0).array()); + assert_close_to_tensor!(r2, (a - b).square() / 2.0); } } diff --git a/src/tensor_ops/ln/mod.rs b/src/tensor_ops/ln/mod.rs index a51b3fd25..6dcaedfe6 100644 --- a/src/tensor_ops/ln/mod.rs +++ b/src/tensor_ops/ln/mod.rs @@ -52,9 +52,6 @@ mod tests { assert!(r_array[1].is_nan()); assert!(r_array[2..] == [TestDtype::NEG_INFINITY, 0.0, TestDtype::ln(2.0)]); let g = r.mean().backward(); - assert_eq!( - g.get(&x).array(), - [-0.1, -0.2, TestDtype::INFINITY, 0.2, 0.1] - ); + assert_close_to_literal!(g.get(&x), [-0.1, -0.2, f64::INFINITY, 0.2, 0.1]); } } diff --git a/src/tensor_ops/log_softmax.rs b/src/tensor_ops/log_softmax.rs index 9f6034a98..59557c654 100644 --- a/src/tensor_ops/log_softmax.rs +++ b/src/tensor_ops/log_softmax.rs @@ -105,20 +105,20 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = a.leaky_trace().log_softmax(); - assert_close( - &r.array(), - &[-4.4519143, -3.4519143, -2.4519143, -1.4519143, -0.4519143], + assert_close_to_literal!( + r, + [-4.4519143, -3.4519143, -2.4519143, -1.4519143, -0.4519143] ); let g = r.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ 0.18834378, 0.16831508, 0.11387146, -0.034121647, -0.43640864, - ], + ] ); } @@ -127,20 +127,20 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([[-2.0, -1.0, 0.0], [1.0, 4.0, 7.0]]); let r = a.leaky_trace().log_softmax::>(); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [-2.407606, -1.4076059, -0.40760595], [-6.0509458, -3.0509458, -0.05094576], - ], + ] ); let g = r.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.12165138, 0.044302434, -0.1659538], [0.16548885, 0.14300959, -0.30849844], - ], + ] ); } } diff --git a/src/tensor_ops/logsumexp_to.rs b/src/tensor_ops/logsumexp_to.rs index 3675f8495..a5e54ab3c 100644 --- a/src/tensor_ops/logsumexp_to.rs +++ b/src/tensor_ops/logsumexp_to.rs @@ -75,11 +75,11 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = a.leaky_trace().logsumexp(); - assert_close(&r.array(), &2.4519143); + assert_close_to_literal!(r, 2.4519143); let g = r.backward(); - assert_close( - &g.get(&a).array(), - &[0.011656231, 0.03168492, 0.08612854, 0.23412165, 0.6364086], + assert_close_to_literal!( + g.get(&a), + [0.011656231, 0.03168492, 0.08612854, 0.23412165, 0.6364086] ); } @@ -88,14 +88,14 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([[-2.0, -1.0, 0.0], [1.0, 4.0, 7.0]]); let r = a.leaky_trace().logsumexp::, _>(); - assert_close(&r.array(), &[0.40760595, 7.0509458]); + assert_close_to_literal!(r, [0.40760595, 7.0509458]); let g = r.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.045015287, 0.12236424, 0.33262047], [0.0011778167, 0.023657078, 0.47516513], - ], + ] ); } } diff --git a/src/tensor_ops/matmul/mod.rs b/src/tensor_ops/matmul/mod.rs index a1fb3c7ef..a59f3a0d3 100644 --- a/src/tensor_ops/matmul/mod.rs +++ b/src/tensor_ops/matmul/mod.rs @@ -374,32 +374,32 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([[0.4651, 0.9106], [0.3360, 0.5534], [0.8092, 0.3827]]); let r = a.leaky_trace().matmul(b.clone()); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.62960154, 0.8554974], [1.4642863, 1.5830379], [1.0090116, 0.82806206], [1.0546886, 1.165766], - ], + ] ); let g = r.exp().mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.37689444, 0.24156547, 0.30238447], [0.80570966, 0.5184905, 0.6703743], [0.4199963, 0.2735345, 0.38693744], [0.5321113, 0.34252504, 0.4438907], - ], + ] ); - assert_close( - &g.get(&b).array(), - &[ + assert_close_to_literal!( + g.get(&b), + [ [0.8737376, 0.9888564], [0.9339924, 0.991189], [1.1659734, 1.2298465], - ], + ] ); } @@ -415,8 +415,8 @@ mod tests { let c2 = b.leaky_trace().permute().matmul(a.leaky_trace().permute()); let g2 = c2.exp().mean().backward(); - assert_close(&g1.get(&a).array(), &g2.get(&a).array()); - assert_close(&g1.get(&b).array(), &g2.get(&b).array()); + assert_close_to_tensor!(g1.get(&a), g2.get(&a)); + assert_close_to_tensor!(g1.get(&b), g2.get(&b)); } #[test] @@ -431,7 +431,7 @@ mod tests { for i in 0..N { let sub_a = dev.tensor(a_array[i]); let sub_c = sub_a.matmul(b.clone()); - assert_close(&r_array[i], &sub_c.array()); + assert_close!(r_array[i], sub_c.array()); } let gs = r.sum().backward(); let a_grad = gs.get(&a).array(); @@ -439,7 +439,7 @@ mod tests { for i in 0..N { let sub_a = dev.tensor(a_array[i]); let sub_gs = sub_a.leaky_trace().matmul(b.clone()).sum().backward(); - assert_close(&a_grad[i], &sub_gs.get(&sub_a).array()); + assert_close!(a_grad[i], sub_gs.get(&sub_a).array()); let sub_b_grad = sub_gs.get(&b).array(); for x in 0..3 { for y in 0..2 { @@ -447,7 +447,7 @@ mod tests { } } } - assert_close(&gs.get(&b).array(), &sub_bs_summed); + assert_close!(gs.get(&b).array(), sub_bs_summed); } #[test] @@ -463,12 +463,7 @@ mod tests { let g1 = r1.exp().mean().backward(); let g2 = r2.exp().mean().backward(); assert_eq!(g1.get(&a).array(), g2.get(&a).array()); - assert_close( - &dev.tensor(g1.get(&b_up).array()) - .sum::<_, Axis<0>>() - .array(), - &g2.get(&b).array(), - ); + assert_close_to_tensor!(g1.get(&b_up).sum::<_, Axis<0>>(), g2.get(&b)); } #[test] @@ -490,10 +485,10 @@ mod tests { let sub_a = dev.tensor(a_array[i]); let sub_b = dev.tensor(b_array[i]); let sub_c = sub_a.leaky_trace().matmul(sub_b.clone()); - assert_close(&sub_c.array(), &c_array[i]); + assert_close!(sub_c.array(), c_array[i]); let sub_g = sub_c.exp().sum().backward(); - assert_close(&sub_g.get(&sub_a).array(), &g_a[i]); - sub_g.get(&sub_b).array().assert_close(&g_b[i], 1e-5); + assert_close!(sub_g.get(&sub_a).array(), g_a[i]); + assert_close!(sub_g.get(&sub_b).array(), g_b[i], 1e-5); } } @@ -517,10 +512,10 @@ mod tests { let sub_a = dev.tensor(a_array[i][j]); let sub_b = dev.tensor(b_array[i][j]); let sub_c = sub_a.leaky_trace().matmul(sub_b.clone()); - assert_close(&sub_c.array(), &c_array[i][j]); + assert_close!(sub_c.array(), c_array[i][j]); let sub_g = sub_c.exp().sum().backward(); - assert_close(&sub_g.get(&sub_a).array(), &g_a[i][j]); - sub_g.get(&sub_b).array().assert_close(&g_b[i][j], 1e-5); + assert_close!(sub_g.get(&sub_a).array(), g_a[i][j]); + assert_close!(sub_g.get(&sub_b).array(), g_b[i][j], 1e-5); } } } @@ -533,16 +528,16 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([[0.7804, 0.5540], [0.5378, 0.8401], [0.5042, 0.8604]]); let r = a.leaky_trace().matmul(b.clone()); - assert_close(&r.array(), &[1.261436, 1.5543157]); + assert_close_to_literal!(r, [1.261436, 1.5543157]); let g = r.exp().mean().backward(); - assert_close(&g.get(&a).array(), &[2.6883178, 2.9369607, 2.9256766]); - assert_close( - &g.get(&b).array(), - &[ + assert_close_to_literal!(g.get(&a), [2.6883178, 2.9369607, 2.9256766]); + assert_close_to_literal!( + g.get(&b), + [ [1.2879219, 1.7261779], [0.70150787, 0.94021803], [1.6746868, 2.244552], - ], + ] ); } @@ -553,15 +548,15 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([[0.7804, 0.5378, 0.5042], [0.5540, 0.8401, 0.8604]]); let r = a.leaky_trace().matmul(b.leaky_trace().permute()); - assert_close(&r.array(), &[1.261436, 1.5543157]); + assert_close_to_literal!(r, [1.261436, 1.5543157]); let g = r.exp().mean().backward(); - assert_close(&g.get(&a).array(), &[2.6883178, 2.9369607, 2.9256766]); - assert_close( - &g.get(&b).array(), - &[ + assert_close_to_literal!(g.get(&a), [2.6883178, 2.9369607, 2.9256766]); + assert_close_to_literal!( + g.get(&b), + [ [1.2879219, 0.70150787, 1.6746868], [1.7261779, 0.94021803, 2.244552], - ], + ] ); } @@ -574,29 +569,24 @@ mod tests { let c = a.leaky_trace().matmul(b.clone()); let c_t = b.leaky_trace().matmul(a.clone()).permute(); assert_eq!(c.array(), c_t.array()); - assert_close( - &c.array(), - &[ + assert_close_to_literal!( + c, + [ [-0.66041213, 1.4961504, 0.7766599], [0.26427752, -0.5987154, -0.31079647], [-0.3337961, 0.75620836, 0.39255193], [-0.43132398, 0.97715575, 0.507247], [-0.8670264, 1.9642308, 1.0196431], - ], + ] ); let g = c.exp().mean().backward(); - assert_close( - &g.get(&a).array(), - &[ - -0.34898597, - -0.02309341, - -0.16800028, - -0.21024881, - -0.54529756, - ], + #[rustfmt::skip] + assert_close_to_literal!( + g.get(&a), + [-0.34898597, -0.02309341, -0.16800028, -0.21024881, -0.54529756] ); - assert_close(&g.get(&b).array(), &[-0.13630435, -1.6781758, -0.75171506]); + assert_close_to_literal!(g.get(&b), &[-0.13630435, -1.6781758, -0.75171506]); } #[test] @@ -605,10 +595,10 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([0.5]); let b: Tensor<_, TestDtype, _> = dev.tensor([2.0]); let c = a.leaky_trace().matmul(b.clone()); - assert_eq!(c.array(), [[1.0]]); + assert_close_to_literal!(c, [[1.0]]); let g = c.exp().sum().backward(); - assert_close(&g.get(&a).array(), &[5.4365635]); - assert_close(&g.get(&b).array(), &[1.3591409]); + assert_close_to_literal!(g.get(&a), [5.4365635]); + assert_close_to_literal!(g.get(&b), [1.3591409]); } #[test] @@ -619,36 +609,36 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([0.5]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0]]); let c = a.leaky_trace().matmul(b.clone()); - assert_eq!(c.array(), [1.0]); + assert_close_to_literal!(c, [1.0]); let g = c.exp().sum().backward(); - assert_close(&g.get(&a).array(), &[5.4365635]); - assert_close(&g.get(&b).array(), &[[1.3591409]]); + assert_close_to_literal!(g.get(&a), [5.4365635]); + assert_close_to_literal!(g.get(&b), [[1.3591409]]); // 1 * 1x1 (permuted) let c = a.leaky_trace().matmul(b.leaky_trace().permute()); - assert_eq!(c.array(), [1.0]); + assert_close_to_literal!(c, [1.0]); let g = c.exp().sum().backward(); - assert_close(&g.get(&a).array(), &[5.4365635]); - assert_close(&g.get(&b).array(), &[[1.3591409]]); + assert_close_to_literal!(g.get(&a), [5.4365635]); + assert_close_to_literal!(g.get(&b), [[1.3591409]]); // 1 * 1x2 let a: Tensor<_, TestDtype, _> = dev.tensor([0.5]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0, 4.0]]); let c = a.leaky_trace().matmul(b.clone()); - let e = [1.0, 2.0]; - assert_eq!(c.array(), e); + let e: [f64; 2] = [1.0, 2.0]; + assert_close_to_literal!(c, e); let g = c.exp().sum().backward(); - assert_close(&g.get(&a).array(), &[e[0].exp() * 2.0 + e[1].exp() * 4.0]); - assert_close(&g.get(&b).array(), &[[1.3591409, 3.694528]]); + assert_close_to_literal!(g.get(&a), [e[0].exp() * 2.0 + e[1].exp() * 4.0], 1e-4); + assert_close_to_literal!(g.get(&b), [[1.3591409, 3.694528]]); // 1 * 1x2 (permuted) let a: Tensor<_, TestDtype, _> = dev.tensor([0.5]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0], [4.0]]); let c = a.leaky_trace().matmul(b.leaky_trace().permute()); - assert_eq!(c.array(), e); + assert_close_to_literal!(c, e); let g = c.exp().sum().backward(); - assert_close(&g.get(&a).array(), &[e[0].exp() * 2.0 + e[1].exp() * 4.0]); - assert_close(&g.get(&b).array(), &[[1.3591409], [3.694528]]); + assert_close_to_literal!(g.get(&a), [e[0].exp() * 2.0 + e[1].exp() * 4.0], 1e-4); + assert_close_to_literal!(g.get(&b), [[1.3591409], [3.694528]]); } #[test] @@ -660,10 +650,10 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([[0.5]]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0]]); let c = a.leaky_trace().matmul(b.clone()); - assert_eq!(c.array(), [[1.0]]); + assert_close_to_literal!(c, [[1.0]]); let g = c.exp().sum().backward(); - assert_close(&g.get(&a).array(), &[[5.4365635]]); - assert_close(&g.get(&b).array(), &[[1.3591409]]); + assert_close_to_literal!(g.get(&a), [[5.4365635]]); + assert_close_to_literal!(g.get(&b), [[1.3591409]]); } { @@ -671,12 +661,10 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([[0.5, 0.1]]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0], [4.0]]); let c = a.leaky_trace().matmul(b.clone()); - assert_eq!(c.array(), [[1.4]]); + assert_close_to_literal!(c, [[1.4]]); let g = c.exp().sum().backward(); - g.get(&a).array().assert_close(&[[8.1104, 16.2208]], 1e-5); - g.get(&b) - .array() - .assert_close(&[[2.0276], [0.40552002]], 1e-5); + assert_close_to_literal!(g.get(&a), [[8.1104, 16.2208]], 1e-5); + assert_close_to_literal!(g.get(&b), [[2.0276], [0.40552002]], 1e-5); } { @@ -684,12 +672,10 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([[0.5], [0.1]]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0], [4.0]]); let c = a.leaky_trace().permute().matmul(b.clone()); - assert_eq!(c.array(), [[1.4]]); + assert_close_to_literal!(c, [[1.4]]); let g = c.exp().sum().backward(); - g.get(&a).array().assert_close(&[[8.1104], [16.2208]], 1e-5); - g.get(&b) - .array() - .assert_close(&[[2.0276], [0.40552002]], 1e-5); + assert_close_to_literal!(g.get(&a), [[8.1104], [16.2208]], 1e-5); + assert_close_to_literal!(g.get(&b), [[2.0276], [0.40552002]], 1e-5); } { @@ -697,12 +683,10 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([[0.5, 0.1]]); let b: Tensor<_, TestDtype, _> = dev.tensor([[2.0, 4.0]]); let c = a.leaky_trace().matmul(b.leaky_trace().permute()); - assert_eq!(c.array(), [[1.4]]); + assert_close_to_literal!(c, [[1.4]]); let g = c.exp().sum().backward(); - g.get(&a).array().assert_close(&[[8.1104, 16.2208]], 1e-5); - g.get(&b) - .array() - .assert_close(&[[2.0276, 0.40552002]], 1e-5); + assert_close_to_literal!(g.get(&a), [[8.1104, 16.2208]], 1e-5); + assert_close_to_literal!(g.get(&b), [[2.0276, 0.40552002]], 1e-5); } } diff --git a/src/tensor_ops/max_to/mod.rs b/src/tensor_ops/max_to/mod.rs index 38526a459..f9537384e 100644 --- a/src/tensor_ops/max_to/mod.rs +++ b/src/tensor_ops/max_to/mod.rs @@ -92,11 +92,11 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 2.0], [3.0, -2.0, 2.0]]); let r = t.leaky_trace().max::<_, Axis<0>>(); - assert_eq!(r.array(), [3.0, 2.0, 2.0]); + assert_close_to_literal!(r, [3.0, 2.0, 2.0]); let g = r.exp().mean().backward(); - assert_close( - &g.get(&t).array(), - &[[0.0, 2.463019, 2.463019], [6.695179, 0.0, 2.463019]], + assert_close_to_literal!( + g.get(&t), + [[0.0, 2.463019, 2.463019], [6.695179, 0.0, 2.463019]] ); } @@ -105,9 +105,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 2.0], [3.0, -2.0, 2.0]]); let r = t.leaky_trace().max::<_, Axis<1>>(); - assert_eq!(r.array(), [2.0, 3.0]); + assert_close_to_literal!(r, [2.0, 3.0]); let g = r.sum().backward(); - assert_eq!(g.get(&t).array(), [[0.0, 1.0, 1.0], [1.0, 0.0, 0.0]]); + assert_close_to_literal!(g.get(&t), [[0.0, 1.0, 1.0], [1.0, 0.0, 0.0]]); } #[test] @@ -116,10 +116,10 @@ mod tests { let t: Tensor<_, TestDtype, _> = dev.sample_normal::>(); let r = t.leaky_trace().max::, _>(); let r2 = t.leaky_trace().max::<_, Axis<0>>().max::<_, Axis<0>>(); - assert_close(&r.array(), &r2.array()); + assert_close_to_tensor!(r, r2); let g = r.mean().backward(); let g2 = r2.mean().backward(); - assert_close(&g.get(&t).array(), &g2.get(&t).array()); + assert_close_to_tensor!(g.get(&t), g2.get(&t)); } #[test] @@ -128,11 +128,8 @@ mod tests { let t: Tensor<_, TestDtype, _> = dev.tensor([[-0.0, 0.0], [0.0, -0.0], [-1.0, -0.0], [-1.0, 0.0]]); let r = t.leaky_trace().max::<_, Axis<1>>(); - assert_eq!(r.array(), [0.0, 0.0, -0.0, 0.0]); + assert_close_to_literal!(r, [0.0, 0.0, -0.0, 0.0]); let g = r.sum().backward(); - assert_eq!( - g.get(&t).array(), - [[1.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, 1.0]] - ); + assert_close_to_literal!(g.get(&t), [[1.0, 1.0], [1.0, 1.0], [0.0, 1.0], [0.0, 1.0]]); } } diff --git a/src/tensor_ops/maximum/mod.rs b/src/tensor_ops/maximum/mod.rs index 9da634339..fbe3bbf96 100644 --- a/src/tensor_ops/maximum/mod.rs +++ b/src/tensor_ops/maximum/mod.rs @@ -58,10 +58,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([[0.0, 0.0, -1.0], [3.0, -4.0, 5.0]]); let result = a.leaky_trace().maximum(b.clone()); - assert_eq!(result.array(), [[0.0, 0.0, 1.0], [3.0, 4.0, 5.0]]); + assert_close_to_literal!(result, [[0.0, 0.0, 1.0], [3.0, 4.0, 5.0]]); let g = result.sum().backward(); - assert_eq!(g.get(&a).array(), [[0.0, 0.5, 1.0], [0.5, 1.0, 0.0]]); - assert_eq!(g.get(&b).array(), [[1.0, 0.5, 0.0], [0.5, 0.0, 1.0]]); + assert_close_to_literal!(g.get(&a), [[0.0, 0.5, 1.0], [0.5, 1.0, 0.0]]); + assert_close_to_literal!(g.get(&b), [[1.0, 0.5, 0.0], [0.5, 0.0, 1.0]]); } } diff --git a/src/tensor_ops/mean_to.rs b/src/tensor_ops/mean_to.rs index bd002dad9..911ae4544 100644 --- a/src/tensor_ops/mean_to.rs +++ b/src/tensor_ops/mean_to.rs @@ -73,10 +73,10 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([1.0, 2.0, 3.0]); let r = t.leaky_trace().mean(); - assert_eq!(r.array(), 2.0); + assert_close_to_literal!(r, 2.0); // NOTE: .exp() so we cover the case where .mean() has to use result grad. let g = r.exp().backward(); - assert_close(&g.get(&t).array(), &[2.463019; 3]); + assert_close_to_literal!(&g.get(&t), &[2.463019; 3]); } #[test] @@ -84,9 +84,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]); let r = t.leaky_trace().mean(); - assert_eq!(r.array(), 3.5); + assert_close_to_literal!(r, 3.5); let g = r.backward(); - assert_eq!(g.get(&t).array(), [[1.0 / 6.0; 3]; 2]); + assert_close_to_literal!(g.get(&t), [[1.0 / 6.0; 3]; 2]); } #[test] @@ -94,9 +94,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.ones::>(); let r = t.leaky_trace().mean(); - assert_eq!(r.array(), 1.0); + assert_close_to_literal!(r, 1.0); let g = r.backward(); - assert_eq!(g.get(&t).array(), [[[1.0 / 24.0; 3]; 2]; 4]); + assert_close_to_literal!(g.get(&t), [[[1.0 / 24.0; 3]; 2]; 4]); } #[test] @@ -104,12 +104,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [-2.0, 4.0, -6.0]]); let r = t.leaky_trace().mean::, _>(); - assert_eq!(r.array(), [-0.5, 3.0, -1.5]); + assert_close_to_literal!(r, [-0.5, 3.0, -1.5]); let g = r.exp().mean().backward(); - assert_close( - &g.get(&t).array(), - &[[0.10108845, 3.3475895, 0.037188362]; 2], - ); + assert_close_to_literal!(g.get(&t), [[0.10108845, 3.3475895, 0.037188362]; 2]); } #[test] @@ -117,9 +114,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [-2.0, 4.0, -6.0]]); let r = t.leaky_trace().mean::, _>(); - assert_eq!(r.array(), [2.0, -4.0 / 3.0]); + assert_close_to_literal!(r, [2.0, -4.0 / 3.0]); let g = r.exp().mean().backward(); - assert_close(&g.get(&t).array(), &[[1.2315094; 3], [0.043932855; 3]]); + assert_close_to_literal!(g.get(&t), [[1.2315094; 3], [0.043932855; 3]]); } #[test] @@ -128,11 +125,11 @@ mod tests { let t: Tensor, TestDtype, _> = dev.sample_normal(); let r = t.leaky_trace().mean::, _>(); let r2 = t.leaky_trace().sum::<_, Axis<0>>().sum::<_, Axis<1>>() / 8.0; - assert_close(&r.array(), &r2.array()); + assert_close_to_tensor!(r, r2); let g = r.mean().backward(); let g2 = r2.mean().backward(); - assert_close(&g.get(&t).array(), &[[[1. / 24.; 4]; 3]; 2]); - assert_close(&g.get(&t).array(), &g2.get(&t).array()); + assert_close_to_literal!(g.get(&t), [[[1. / 24.; 4]; 3]; 2]); + assert_close_to_tensor!(g.get(&t), g2.get(&t)); } #[test] @@ -141,6 +138,6 @@ mod tests { let t: Tensor, TestDtype, _> = dev.sample_normal(); let r = t.leaky_trace().mean::, _>(); let r2 = t.sum::<_, Axis<0>>().sum::<_, Axis<0>>() / 6.0; - assert_close(&r.array(), &r2.array()); + assert_close_to_tensor!(r, r2); } } diff --git a/src/tensor_ops/min_to/mod.rs b/src/tensor_ops/min_to/mod.rs index fbced1849..690c78de3 100644 --- a/src/tensor_ops/min_to/mod.rs +++ b/src/tensor_ops/min_to/mod.rs @@ -92,11 +92,11 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 1.0, 2.0], [3.0, -2.0, 2.0]]); let r = t.leaky_trace().min::, _>(); - assert_eq!(r.array(), [1.0, -2.0, 2.0]); + assert_close_to_literal!(r, [1.0, -2.0, 2.0]); let g = r.exp().mean().backward(); - assert_close( - &g.get(&t).array(), - &[[0.90609396, 0.0, 2.463019], [0.0, 0.04511176, 2.463019]], + assert_close_to_literal!( + g.get(&t), + [[0.90609396, 0.0, 2.463019], [0.0, 0.04511176, 2.463019]] ); } @@ -105,9 +105,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 1.0, 2.0], [3.0, -2.0, 2.0]]); let r = t.leaky_trace().min::, _>(); - assert_eq!(r.array(), [1.0, -2.0]); + assert_close_to_literal!(r, [1.0, -2.0]); let g = r.sum().backward(); - assert_eq!(g.get(&t).array(), [[1.0, 1.0, 0.0], [0.0, 1.0, 0.0]]); + assert_close_to_literal!(g.get(&t), [[1.0, 1.0, 0.0], [0.0, 1.0, 0.0]]); } #[test] @@ -116,10 +116,10 @@ mod tests { let t: Tensor<_, TestDtype, _> = dev.sample_normal::>(); let r = t.leaky_trace().min::, _>(); let r2 = t.leaky_trace().min::, _>().min::, _>(); - assert_close(&r.array(), &r2.array()); + assert_close_to_tensor!(r, r2); let g = r.mean().backward(); let g2 = r2.mean().backward(); - assert_close(&g.get(&t).array(), &g2.get(&t).array()); + assert_close_to_tensor!(g.get(&t), g2.get(&t)); } #[test] @@ -128,11 +128,8 @@ mod tests { let t: Tensor<_, TestDtype, _> = dev.tensor([[-0.0, 0.0], [0.0, -0.0], [-1.0, -0.0], [-1.0, 0.0]]); let r = t.leaky_trace().min::<_, Axis<1>>(); - assert_eq!(r.array(), [-0.0, -0.0, -1.0, -1.0]); + assert_close_to_literal!(r, [-0.0, -0.0, -1.0, -1.0]); let g = r.sum().backward(); - assert_eq!( - g.get(&t).array(), - [[1.0, 1.0], [1.0, 1.0], [1.0, 0.0], [1.0, 0.0]] - ); + assert_close_to_literal!(g.get(&t), [[1.0, 1.0], [1.0, 1.0], [1.0, 0.0], [1.0, 0.0]]); } } diff --git a/src/tensor_ops/minimum/mod.rs b/src/tensor_ops/minimum/mod.rs index 02c352e31..529d7b792 100644 --- a/src/tensor_ops/minimum/mod.rs +++ b/src/tensor_ops/minimum/mod.rs @@ -57,10 +57,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([[0.0, 0.0, -1.0], [3.0, -4.0, 5.0]]); let result = a.leaky_trace().minimum(b.clone()); - assert_eq!(result.array(), [[-1., 0., -1.], [3., -4., -5.]]); + assert_close_to_literal!(result, [[-1., 0., -1.], [3., -4., -5.]]); let g = result.sum().backward(); - assert_eq!(g.get(&a).array(), [[1.0, 0.5, 0.0], [0.5, 0.0, 1.0]]); - assert_eq!(g.get(&b).array(), [[0.0, 0.5, 1.0], [0.5, 1.0, 0.0]]); + assert_close_to_literal!(g.get(&a), [[1.0, 0.5, 0.0], [0.5, 0.0, 1.0]]); + assert_close_to_literal!(g.get(&b), [[0.0, 0.5, 1.0], [0.5, 1.0, 0.0]]); } } diff --git a/src/tensor_ops/mul/mod.rs b/src/tensor_ops/mul/mod.rs index 1e2f3df04..33780b942 100644 --- a/src/tensor_ops/mul/mod.rs +++ b/src/tensor_ops/mul/mod.rs @@ -84,10 +84,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor(3.0); let r = a.leaky_trace() * b.clone(); - assert_close(&r.array(), &6.0); + assert_close_to_literal!(r, 6.0); let g = r.backward(); - assert_close(&g.get(&a).array(), &3.0); - assert_close(&g.get(&b).array(), &2.0); + assert_close_to_literal!(g.get(&a), 3.0); + assert_close_to_literal!(g.get(&b), 2.0); } #[test] @@ -97,10 +97,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([1.0, -1.0, 0.0]); let r = a.leaky_trace() * b.clone(); - assert_close(&r.array(), &[1.0, -2.0, 0.0]); + assert_close_to_literal!(r, [1.0, -2.0, 0.0]); let g = r.mean().backward(); - assert_close(&g.get(&a).array(), &[1.0 / 3.0, -1.0 / 3.0, 0.0]); - assert_close(&g.get(&b).array(), &[1.0 / 3.0, 2.0 / 3.0, 1.0]); + assert_close_to_literal!(g.get(&a), [1.0 / 3.0, -1.0 / 3.0, 0.0]); + assert_close_to_literal!(g.get(&b), [1.0 / 3.0, 2.0 / 3.0, 1.0]); } #[test] @@ -112,27 +112,27 @@ mod tests { dev.tensor([[0.5199, 0.3844, 0.3759], [0.8259, 0.3682, 0.0388]]); let r = a.leaky_trace() * b.clone(); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.3415743, 0.06565552, 0.056385003], [0.46729425, 0.2581082, 0.03236696], - ], + ] ); let g = r.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.08665001, 0.06406667, 0.06265], [0.13765001, 0.06136667, 0.006466667], - ], + ] ); - assert_close( - &g.get(&b).array(), - &[ + assert_close_to_literal!( + g.get(&b), + [ [0.109500006, 0.028466668, 0.025000002], [0.0943, 0.11683333, 0.13903335], - ], + ] ); } @@ -141,9 +141,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor(1.0); let r = x.leaky_trace() * 0.5; - assert_close(&r.array(), &0.5); + assert_close_to_literal!(r, 0.5); let g = r.exp().backward(); - assert_close(&g.get(&x).array(), &0.8243606); + assert_close_to_literal!(g.get(&x), 0.8243606); } #[test] @@ -151,9 +151,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([0.0, 1.0, 2.0]); let r = x.leaky_trace() * 0.5; - assert_close(&r.array(), &[0.0, 0.5, 1.0]); + assert_close_to_literal!(r, [0.0, 0.5, 1.0]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[0.5, 0.8243606, 1.3591409]); + assert_close_to_literal!(g.get(&x), [0.5, 0.8243606, 1.3591409]); } #[test] @@ -161,8 +161,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([[1.0; 2]; 3]); let r = x.leaky_trace() * 0.5; - assert_close(&r.array(), &[[0.5; 2]; 3]); + assert_close_to_literal!(r, [[0.5; 2]; 3]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[[0.8243606; 2]; 3]); + assert_close_to_literal!(g.get(&x), [[0.8243606; 2]; 3]); } } diff --git a/src/tensor_ops/nans_to/mod.rs b/src/tensor_ops/nans_to/mod.rs index 9f8f7d5b0..7167b6189 100644 --- a/src/tensor_ops/nans_to/mod.rs +++ b/src/tensor_ops/nans_to/mod.rs @@ -49,9 +49,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([1.0, TestDtype::NAN, -TestDtype::NAN, 4.0]); let r = t.leaky_trace().nans_to(0.0); - assert_close(&r.array(), &[1.0, 0.0, 0.0, 4.0]); + assert_close_to_literal!(r, [1.0, 0.0, 0.0, 4.0]); // NOTE: .exp() so we cover case where nans_to() needs to use result grad let g = r.exp().mean().backward(); - assert_close(&g.get(&t).array(), &[0.67957044, 0.0, 0.0, 13.649537]); + assert_close_to_literal!(g.get(&t), [0.67957044, 0.0, 0.0, 13.649537]); } } diff --git a/src/tensor_ops/negate/mod.rs b/src/tensor_ops/negate/mod.rs index f83cf67cb..39fe4529d 100644 --- a/src/tensor_ops/negate/mod.rs +++ b/src/tensor_ops/negate/mod.rs @@ -53,9 +53,9 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([-2.0, 0.0, 5.0]); let r = -(a.leaky_trace()); - assert_close(&r.array(), &[2.0, 0.0, -5.0]); + assert_close_to_literal!(r, [2.0, 0.0, -5.0]); // NOTE: .exp() so we can make sure neg is using result grad properly let g = r.exp().mean().backward(); - assert_close(&g.get(&a).array(), &[-2.463019, -0.33333334, -0.0022459824]); + assert_close_to_literal!(g.get(&a), [-2.463019, -0.33333334, -0.0022459824]); } } diff --git a/src/tensor_ops/normalize.rs b/src/tensor_ops/normalize.rs index 900aeffe9..e3657bab5 100644 --- a/src/tensor_ops/normalize.rs +++ b/src/tensor_ops/normalize.rs @@ -59,10 +59,10 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([-2.0, 0.0, 5.0]); let r = a.leaky_trace().normalize(1e-5); - assert_close(&r.array(), &[-1.0190487, -0.3396829, 1.3587316]); + assert_close_to_literal!(&r, [-1.0190487, -0.3396829, 1.3587316]); // NOTE: .exp() so we can make sure normalize is using result grad properly let g = r.exp().mean().backward(); - assert_close(&g.get(&a).array(), &[0.033410847, -0.04677555, 0.013364702]); + assert_close_to_literal!(&g.get(&a), [0.033410847, -0.04677555, 0.013364702]); } #[test] @@ -70,20 +70,20 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([[-2.0, 0.0, 5.0], [1.0, 2.0, 3.0]]); let r = a.leaky_trace().normalize::>(1e-5); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [-1.0190487, -0.3396829, 1.3587316], [-1.2247356, 0.0, 1.2247356], - ], + ] ); let g = r.exp().mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.016705424, -0.023387775, 0.006682351], [0.05773133, -0.11547226, 0.057740927], - ], + ] ); } @@ -92,22 +92,22 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([[-2.0, 0.0], [1.0, 2.0], [4.0, 5.0]]); let r = a.leaky_trace().normalize::>(1e-5); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [-1.2247438, -1.1355485], [0.0, -0.16222118], [1.2247438, 1.2977698], - ], + ] ); let g = r.exp().mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.019245632, 0.025835907], [-0.038491584, -0.043060362], [0.019245982, 0.01722446], - ], + ] ); } @@ -116,8 +116,8 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor, TestDtype, _> = dev.ones(); let r = a.leaky_trace().normalize::>(1e-5); - assert_eq!(r.array(), [[[0.0; 3]; 2]; 4]); + assert_close_to_literal!(r, [[[0.0; 3]; 2]; 4]); let g = r.exp().mean().backward(); - assert_eq!(g.get(&a).array(), [[[0.0; 3]; 2]; 4]); + assert_close_to_literal!(g.get(&a), [[[0.0; 3]; 2]; 4]); } } diff --git a/src/tensor_ops/pool2d/mod.rs b/src/tensor_ops/pool2d/mod.rs index a7bad018c..bf98f9d84 100644 --- a/src/tensor_ops/pool2d/mod.rs +++ b/src/tensor_ops/pool2d/mod.rs @@ -203,9 +203,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([[[1.0, 1., 0.5, 0.2], [0.2, 0.2, 0.5, 1.2]]]); let r = x.leaky_trace().max_pool2d::<2, 1, 0>(); - assert_close(&r.array(), &[[[1., 1., 1.2]]]); + assert_close_to_literal!(r, [[[1., 1., 1.2]]]); let g = r.sum().backward(); - assert_close(&g.get(&x).array(), &[[[1., 2., 0., 0.], [0., 0., 0., 1.]]]); + assert_close_to_literal!(g.get(&x), [[[1., 2., 0., 0.], [0., 0., 0., 1.]]]); } #[test] @@ -213,9 +213,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([[[1., 1., 0.5, 0.2], [0.2, 0.2, 0.5, 1.2]]]); let r = x.leaky_trace().min_pool2d::<2, 1, 0>(); - assert_close(&r.array(), &[[[0.2, 0.2, 0.2]]]); + assert_close_to_literal!(r, [[[0.2, 0.2, 0.2]]]); let g = r.sum().backward(); - assert_close(&g.get(&x).array(), &[[[0., 0., 0., 1.], [1., 2., 0., 0.]]]); + assert_close_to_literal!(g.get(&x), [[[0., 0., 0., 1.], [1., 2., 0., 0.]]]); } #[test] @@ -223,15 +223,12 @@ mod tests { let dev = TestDevice::seed_from_u64(234); let x: Tensor, TestDtype, _> = dev.sample_normal(); let r = x.leaky_trace().max_pool2d::<2, 2, 0>(); - assert_close( - &r.array(), - &[[[1.79155397, 1.10126066]], [[1.14464748, 2.26301837]]], - ); + assert_close_to_literal!(r, [[[1.79155397, 1.10126066]], [[1.14464748, 2.26301837]]]); let g = r.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [[1.49969184, 0., 0., 0.75198889],[0., 0., 0., 0.],[0., 0., 0., 0.]], [[0., 0., 2.40301466, 0.],[0.78533345, 0., 0., 0.],[0., 0., 0., 0.]] ] @@ -243,18 +240,18 @@ mod tests { let dev = TestDevice::seed_from_u64(234); let x: Tensor, TestDtype, _> = dev.sample_normal(); let r = x.leaky_trace().min_pool2d::<2, 2, 0>(); - assert_close( - &r.array(), - &[[[-1.09635627, -1.07717276]], [[-0.01996479, -1.82562149]]], + assert_close_to_literal!( + r, + [[[-1.09635627, -1.07717276]], [[-0.01996479, -1.82562149]]] ); let g = r.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [[0., 0., 0., 0.],[0.083521545, 0., 0., 0.08513925],[0., 0., 0., 0.]], [[0., 0.2450583, 0., 0.04027937],[0., 0., 0., 0.],[0., 0., 0., 0.]], - ], + ] ); } @@ -263,15 +260,12 @@ mod tests { let dev = TestDevice::seed_from_u64(234); let x: Tensor, TestDtype, _> = dev.sample_normal(); let r = x.leaky_trace().avg_pool2d::<2, 2, 0>(); - assert_close( - &r.array(), - &[[[0.03031558, -0.25052455]], [[0.39499030, 0.04878314]]], - ); + assert_close_to_literal!(r, [[[0.03031558, -0.25052455]], [[0.39499030, 0.04878314]]]); let g = r.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [[0.06442373, 0.06442373, 0.048649523, 0.048649523],[0.06442373, 0.06442373, 0.048649523, 0.048649523],[0.0, 0.0, 0.0, 0.0]], [[0.09277311, 0.09277311, 0.06562454, 0.06562454],[0.09277311, 0.09277311, 0.06562454, 0.06562454],[0.0, 0.0, 0.0, 0.0]] ] @@ -283,18 +277,18 @@ mod tests { let dev = TestDevice::seed_from_u64(234); let x: Tensor, TestDtype, _> = dev.sample_normal(); let r = x.leaky_trace().avg_pool2d::<1, 2, 0>(); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [[[1.791554]], [[-1.0963563]], [[0.86268073]], [[0.28538525]]], [[[1.1446475]], [[0.2833436]], [[-1.2026008]], [[0.21327473]]], - ], + ] ); let g = r.exp().mean().backward(); #[rustfmt::skip] - assert_close( - &g.get(&x).array(), - &[ + assert_close_to_literal!( + g.get(&x), + [ [[[0.7498459, 0.0], [0.0, 0.0]],[[0.041760772, 0.0], [0.0, 0.0]],[[0.29618803, 0.0], [0.0, 0.0]],[[0.16628431, 0.0], [0.0, 0.0]]], [[[0.39266673, 0.0], [0.0, 0.0]],[[0.16594516, 0.0], [0.0, 0.0]],[[0.037551485, 0.0], [0.0, 0.0]],[[0.15471558, 0.0], [0.0, 0.0]]] ] diff --git a/src/tensor_ops/pow/mod.rs b/src/tensor_ops/pow/mod.rs index 9f2cb210b..7d8db4a70 100644 --- a/src/tensor_ops/pow/mod.rs +++ b/src/tensor_ops/pow/mod.rs @@ -76,17 +76,17 @@ mod tests { let r_array = r.array(); assert!(r_array[0].is_nan()); assert!(r_array[1].is_nan()); - assert_close(&r_array[2], &0.0); - assert_close(&r_array[3], &1.0); - assert_close(&r_array[4], &11.313708); + assert_close!(r_array[2], 0.0); + assert_close!(r_array[3], 1.0); + assert_close!(r_array[4], 11.313708); let g = r.sum().backward(); let grad = g.get(&t).array(); assert!(grad[0].is_nan()); assert!(grad[1].is_nan()); - assert_close(&grad[2], &0.0); - assert_close(&grad[3], &3.5); - assert_close(&grad[4], &19.79899); + assert_close!(grad[2], 0.0); + assert_close!(grad[3], 3.5); + assert_close!(grad[4], 19.79899); } #[test] @@ -97,17 +97,17 @@ mod tests { let r_array = r.array(); assert!(r_array[0].is_nan()); assert!(r_array[1].is_nan()); - assert_close(&r_array[2], &TestDtype::INFINITY); - assert_close(&r_array[3], &1.0); - assert_close(&r_array[4], &0.43527526); + assert_close!(r_array[2], TestDtype::INFINITY); + assert_close!(r_array[3], 1.0); + assert_close!(r_array[4], 0.43527526); let g = r.sum().backward(); let grad = g.get(&t).array(); assert!(grad[0].is_nan()); assert!(grad[1].is_nan()); - assert_close(&grad[2], &TestDtype::NEG_INFINITY); - assert_close(&grad[3], &-1.2); - assert_close(&grad[4], &-0.26116517); + assert_close!(grad[2], TestDtype::NEG_INFINITY); + assert_close!(grad[3], -1.2); + assert_close!(grad[4], -0.26116517); } #[test] @@ -115,9 +115,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = t.leaky_trace().powi(3); - assert_eq!(r.array(), [-8., -1., 0., 1., 8.]); + assert_close_to_literal!(r, [-8., -1., 0., 1., 8.]); let g = r.sum().backward(); - assert_eq!(g.get(&t).array(), [12., 3., 0., 3., 12.]); + assert_close_to_literal!(g.get(&t), [12., 3., 0., 3., 12.]); } #[test] @@ -125,11 +125,8 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = t.leaky_trace().powi(-3); - assert_eq!(r.array(), [-0.125, -1.0, TestDtype::INFINITY, 1.0, 0.125]); + assert_close_to_literal!(r, [-0.125, -1.0, f64::INFINITY, 1.0, 0.125]); let g = r.sum().backward(); - assert_close( - &g.get(&t).array(), - &[-0.1875, -3., TestDtype::NEG_INFINITY, -3., -0.1875], - ); + assert_close_to_literal!(g.get(&t), [-0.1875, -3., f64::NEG_INFINITY, -3., -0.1875]); } } diff --git a/src/tensor_ops/prelu.rs b/src/tensor_ops/prelu.rs index d10243624..7955cc994 100644 --- a/src/tensor_ops/prelu.rs +++ b/src/tensor_ops/prelu.rs @@ -94,13 +94,13 @@ mod tests { let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let y: Tensor<_, TestDtype, _> = dev.tensor([0.05, 0.05, 0.05, 0.05, 0.05]); let r = x.leaky_trace().prelu(y.clone()); - assert_eq!(r.array(), [-0.1, -0.05, 0.0, 1.0, 2.0]); + assert_close_to_literal!(r, [-0.1, -0.05, 0.0, 1.0, 2.0]); // NOTE: call .exp() to make sure we cover cases where .prelu() uses the result's gradient let g = r.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[0.00904837, 0.00951229, 0.2, 0.54365635, 1.4778112], + assert_close_to_literal!( + g.get(&x), + [0.00904837, 0.00951229, 0.2, 0.54365635, 1.4778112] ); - assert_close(&g.get(&y).array(), &[-0.3619348, -0.1902458, 0.0, 0.0, 0.0]); + assert_close_to_literal!(g.get(&y), [-0.3619348, -0.1902458, 0.0, 0.0, 0.0]); } } diff --git a/src/tensor_ops/recip/mod.rs b/src/tensor_ops/recip/mod.rs index 6ddf57a91..fa738b3a5 100644 --- a/src/tensor_ops/recip/mod.rs +++ b/src/tensor_ops/recip/mod.rs @@ -45,11 +45,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().recip(); - assert_close(&r.array(), &[-0.5, -1.0, TestDtype::INFINITY, 1.0, 0.5]); + assert_close_to_literal!(r, [-0.5, -1.0, f64::INFINITY, 1.0, 0.5]); let g = r.mean().backward(); - assert_close( - &g.get(&x).array(), - &[-0.05, -0.2, TestDtype::NEG_INFINITY, -0.2, -0.05], - ); + assert_close_to_literal!(g.get(&x), [-0.05, -0.2, f64::NEG_INFINITY, -0.2, -0.05]); } } diff --git a/src/tensor_ops/relu/mod.rs b/src/tensor_ops/relu/mod.rs index 876b1313c..cc7952a39 100644 --- a/src/tensor_ops/relu/mod.rs +++ b/src/tensor_ops/relu/mod.rs @@ -48,9 +48,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().relu(); - assert_eq!(r.array(), [0.0, 0.0, 0.0, 1.0, 2.0]); + assert_close_to_literal!(r, [0.0, 0.0, 0.0, 1.0, 2.0]); // NOTE: call .exp() to make sure we cover cases where .relu() uses the result's gradient let g = r.exp().mean().backward(); - assert_close(&g.get(&x).array(), &[0.0, 0.0, 0.0, 0.54365635, 1.4778112]); + assert_close_to_literal!(g.get(&x), [0.0, 0.0, 0.0, 0.54365635, 1.4778112]); } } diff --git a/src/tensor_ops/reshape_to/mod.rs b/src/tensor_ops/reshape_to/mod.rs index 657db6bcb..15da6eb2f 100644 --- a/src/tensor_ops/reshape_to/mod.rs +++ b/src/tensor_ops/reshape_to/mod.rs @@ -181,13 +181,11 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([0.1, 0.2, 0.3, 0.4, 0.5, 0.6]); let b = a.leaky_trace().reshape::>(); - assert_eq!(b.array(), [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]); + assert_close_to_literal!(b, [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]); let g = b.exp().mean().backward(); - assert_close( - &g.get(&a).array(), - &[ - 0.18419516, 0.20356713, 0.22497648, 0.24863747, 0.2747869, 0.3036865, - ], + assert_close_to_literal!( + g.get(&a), + [0.18419516, 0.20356713, 0.22497648, 0.24863747, 0.2747869, 0.3036865] ) } @@ -199,14 +197,14 @@ mod tests { .leaky_trace() .permute::, _>() .reshape::>(); - assert_eq!(b.array(), [0.1, 0.4, 0.2, 0.5, 0.3, 0.6]); + assert_close_to_literal!(b, [0.1, 0.4, 0.2, 0.5, 0.3, 0.6]); let g = b.exp().mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.18419516, 0.20356713, 0.22497648], [0.24863747, 0.2747869, 0.3036865], - ], + ] ) } diff --git a/src/tensor_ops/roll/mod.rs b/src/tensor_ops/roll/mod.rs index df0149519..59ff4d5a1 100644 --- a/src/tensor_ops/roll/mod.rs +++ b/src/tensor_ops/roll/mod.rs @@ -98,11 +98,11 @@ mod tests { .leaky_trace() .broadcast::, _>() .roll::>(2); - assert_eq!(y.array(), [[[0.15, 0.2, -0.3, -0.15, 0.0]; 3]; 2]); + assert_close_to_literal!(y, [[[0.15, 0.2, -0.3, -0.15, 0.0]; 3]; 2]); let grads = y.exp().mean().backward(); - assert_close( - &grads.get(&t).array(), - &[0.14816365, 0.1721416, 0.2, 0.23236685, 0.24428058], + assert_close_to_literal!( + grads.get(&t), + [0.14816365, 0.1721416, 0.2, 0.23236685, 0.24428058] ); } @@ -114,12 +114,12 @@ mod tests { .leaky_trace() .broadcast::, _>() .roll::>(3); - assert_eq!(y0.array(), [[[1.0, 2.0, 3.0, 4.0, 5.0]; 3]; 2]); + assert_close_to_literal!(y0, [[[1.0, 2.0, 3.0, 4.0, 5.0]; 3]; 2]); let y1 = t .leaky_trace() .broadcast::, _>() .roll::>(3); - assert_eq!(y1.array(), [[[1.0, 2.0, 3.0, 4.0, 5.0]; 3]; 2]); + assert_close_to_literal!(y1, [[[1.0, 2.0, 3.0, 4.0, 5.0]; 3]; 2]); let g0 = y0.exp().mean().backward(); let g1 = y1.exp().mean().backward(); diff --git a/src/tensor_ops/select_and_gather/mod.rs b/src/tensor_ops/select_and_gather/mod.rs index caf32fd92..104a47ccb 100644 --- a/src/tensor_ops/select_and_gather/mod.rs +++ b/src/tensor_ops/select_and_gather/mod.rs @@ -300,7 +300,7 @@ mod tests { let r = t.leaky_trace().gather(dev.tensor([0, 3])); assert_eq!(r.array(), [t_array[0], t_array[3]]); let g = r.mean().backward(); - assert_eq!(g.get(&t).array(), [0.5, 0.0, 0.0, 0.5, 0.0]); + assert_close_to_literal!(g.get(&t), [0.5, 0.0, 0.0, 0.5, 0.0]); } #[test] @@ -314,8 +314,8 @@ mod tests { [_t[0], _t[1], _t[2], _t[3], _t[4], _t[2], _t[4], _t[4]] ); let g = r.mean().backward(); - assert_eq!( - g.get(&t).array(), + assert_close_to_literal!( + g.get(&t), [1.0 / 8.0, 1.0 / 8.0, 2.0 / 8.0, 1.0 / 8.0, 3.0 / 8.0] ); } @@ -325,9 +325,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [-1.0, -2.0, -3.0]]); let r = t.leaky_trace().select(dev.tensor(0)); - assert_eq!(r.array(), [1.0, 2.0, 3.0]); + assert_close_to_literal!(r, [1.0, 2.0, 3.0]); let g = r.mean().backward(); - assert_eq!(g.get(&t).array(), [[1.0 / 3.0; 3], [0.0; 3]]); + assert_close_to_literal!(g.get(&t), [[1.0 / 3.0; 3], [0.0; 3]]); } #[test] @@ -335,9 +335,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [-1.0, -2.0, -3.0]]); let r = t.leaky_trace().select(dev.tensor([1, 1])); - assert_eq!(r.array(), [2.0, -2.0]); + assert_close_to_literal!(r, [2.0, -2.0]); let g = r.mean().backward(); - assert_eq!(g.get(&t).array(), [[0.0, 0.5, 0.0], [0.0, 0.5, 0.0]]); + assert_close_to_literal!(g.get(&t), [[0.0, 0.5, 0.0], [0.0, 0.5, 0.0]]); } #[test] @@ -348,9 +348,9 @@ mod tests { .leaky_trace() .broadcast::, _>() .select(dev.tensor([0, 1])); - assert_eq!(r.array(), [1.0, 2.0]); + assert_close_to_literal!(r, [1.0, 2.0]); let g = r.mean().backward(); - assert_eq!(g.get(&t).array(), [0.5, 0.5, 0.0]); + assert_close_to_literal!(g.get(&t), [0.5, 0.5, 0.0]); } #[test] @@ -360,9 +360,9 @@ mod tests { let idx: Tensor, usize, _> = dev.tensor([[0, 1], [1, 2]]); let r: Tensor, _, _, _> = t.leaky_trace().broadcast::, _>().gather(idx); - assert_eq!(r.array(), [[1.0, 2.0], [2.0, 3.0]]); + assert_close_to_literal!(r, [[1.0, 2.0], [2.0, 3.0]]); let g = r.mean().backward(); - assert_eq!(g.get(&t).array(), [0.25, 0.5, 0.25]); + assert_close_to_literal!(g.get(&t), [0.25, 0.5, 0.25]); } #[test] @@ -374,7 +374,10 @@ mod tests { assert_eq!(r.array(), t_array[0]); let g = r.exp().mean().backward(); let sub_g = dev.tensor(t_array[0]).exp() / 12.0; - assert_close(&g.get(&t).array(), &[sub_g.array(), [[0.0; 4]; 3]]); + assert_close!( + g.get(&t).array(), + [sub_g.array(), [[TestDtype::default(); 4]; 3]] + ); } #[test] @@ -388,12 +391,12 @@ mod tests { let g = r.exp().mean().backward(); let sub_g = dev.tensor(sub_t).exp() / 8.0; let sub_g = sub_g.array(); - assert_close( - &g.get(&t).array(), - &[ + assert_close!( + g.get(&t).array(), + [ [[0.0; 4], sub_g[0], [0.0; 4]], [[0.0; 4], [0.0; 4], sub_g[1]], - ], + ] ); } @@ -411,9 +414,9 @@ mod tests { let g = r.exp().mean().backward(); let sub_g = dev.tensor(sub_t).exp() / 6.0; let sub_g = sub_g.array(); - assert_close( - &g.get(&t).array(), - &[ + assert_close!( + g.get(&t).array(), + [ [ [0.0, 0.0, sub_g[0][0], 0.0], [0.0, 0.0, 0.0, sub_g[0][1]], @@ -424,7 +427,7 @@ mod tests { [0.0, sub_g[1][1], 0.0, 0.0], [sub_g[1][2], 0.0, 0.0, 0.0], ], - ], + ] ); } @@ -438,7 +441,7 @@ mod tests { assert_eq!(r_array[0], [t_array[2], t_array[0], t_array[3]]); assert_eq!(r_array[1], [t_array[0], t_array[0], t_array[3]]); let g = r.sum().backward(); - assert_eq!(g.get(&t).array(), [[3.; 5], [0.; 5], [1.; 5], [2.; 5]]); + assert_close_to_literal!(g.get(&t), [[3.; 5], [0.; 5], [1.; 5], [2.; 5]]); } #[test] diff --git a/src/tensor_ops/sigmoid/mod.rs b/src/tensor_ops/sigmoid/mod.rs index 0ab2d4598..d789c8afe 100644 --- a/src/tensor_ops/sigmoid/mod.rs +++ b/src/tensor_ops/sigmoid/mod.rs @@ -47,14 +47,11 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().sigmoid(); - assert_close( - &r.array(), - &[0.11920292, 0.26894143, 0.5, 0.7310586, 0.880797], - ); + assert_close_to_literal!(r, [0.11920292, 0.26894143, 0.5, 0.7310586, 0.880797]); let g = r.mean().backward(); - assert_close( - &g.get(&x).array(), - &[0.020998716, 0.039322387, 0.05, 0.039322387, 0.020998726], + assert_close_to_literal!( + g.get(&x), + [0.020998716, 0.039322387, 0.05, 0.039322387, 0.020998726] ); } } diff --git a/src/tensor_ops/sin/mod.rs b/src/tensor_ops/sin/mod.rs index 7601b9c45..2fa7d9334 100644 --- a/src/tensor_ops/sin/mod.rs +++ b/src/tensor_ops/sin/mod.rs @@ -48,14 +48,11 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().sin(); - assert_close( - &r.array(), - &[-0.9092974, -0.84147096, 0.0, 0.84147096, 0.9092974], - ); + assert_close_to_literal!(r, [-0.9092974, -0.84147096, 0.0, 0.84147096, 0.9092974]); let g = r.mean().backward(); - assert_close( - &g.get(&x).array(), - &[-0.08322937, 0.10806046, 0.2, 0.10806046, -0.08322937], + assert_close_to_literal!( + g.get(&x), + [-0.08322937, 0.10806046, 0.2, 0.10806046, -0.08322937] ); } } diff --git a/src/tensor_ops/slice/mod.rs b/src/tensor_ops/slice/mod.rs index 1c2eddb64..09adf7190 100644 --- a/src/tensor_ops/slice/mod.rs +++ b/src/tensor_ops/slice/mod.rs @@ -84,13 +84,12 @@ impl, T: Tape> Tensor { #[cfg(test)] mod tests { use super::*; - use crate::tensor_ops::*; - use crate::tests::TestDevice; + use crate::{tensor_ops::*, tests::*}; #[test] fn test_slice() { let dev = TestDevice::default(); - let a = dev.tensor([ + let a: Tensor<_, TestDtype, _> = dev.tensor([ [1., 2., 3., 4.], [5., 6., 7., 8.], [9., 10., 11., 12.], @@ -98,70 +97,70 @@ mod tests { ]); let b: Tensor, _, _> = a.clone().slice((2.., 2..)).realize().unwrap(); - assert_eq!(b.array(), [[11., 12.], [15., 16.]]); + assert_close_to_literal!(b, [[11., 12.], [15., 16.]]); let b: Tensor, _, _> = a.clone().slice((1..3, 1..3)).realize().unwrap(); - assert_eq!(b.array(), [[6., 7.], [10., 11.]]); + assert_close_to_literal!(b, [[6., 7.], [10., 11.]]); let b: Tensor, _, _> = a.clone().slice((..1, 1..4)).realize().unwrap(); - assert_eq!(b.array(), [[2., 3., 4.]]); + assert_close_to_literal!(b, [[2., 3., 4.]]); let b: Tensor, _, _> = a.clone().slice((1..3, ..3)).realize().unwrap(); - assert_eq!(b.array(), [[5., 6., 7.], [9., 10., 11.]]); + assert_close_to_literal!(b, [[5., 6., 7.], [9., 10., 11.]]); let b: Tensor, _, _> = a.clone().slice((1..=2, 1..=3)).realize().unwrap(); - assert_eq!(b.array(), [[6., 7., 8.], [10., 11., 12.]]); + assert_close_to_literal!(b, [[6., 7., 8.], [10., 11., 12.]]); let b: Tensor, _, _> = a.clone().slice((0..=1, 2..=3)).realize().unwrap(); - assert_eq!(b.array(), [[3., 4.], [7., 8.]]); + assert_close_to_literal!(b, [[3., 4.], [7., 8.]]); let b: Tensor, _, _> = a.clone().slice((1.., ..2)).realize().unwrap(); - assert_eq!(b.array(), [[5., 6.], [9., 10.], [13., 14.]]); + assert_close_to_literal!(b, [[5., 6.], [9., 10.], [13., 14.]]); let b: Tensor, _, _> = a.slice((..2, 2..)).realize().unwrap(); - assert_eq!(b.array(), [[3., 4.], [7., 8.]]); + assert_close_to_literal!(b, [[3., 4.], [7., 8.]]); } #[test] fn test_slice_broadcast_top() { let dev = TestDevice::default(); - let a: Tensor, _, _> = dev.tensor([1., 2., 3., 4.]).broadcast(); + let a: Tensor, TestDtype, _> = dev.tensor([1., 2., 3., 4.]).broadcast(); let b: Tensor, _, _> = a.clone().slice((..3, ..)).realize().unwrap(); - assert_eq!(b.array(), [[1., 2., 3., 4.]; 3]); + assert_close_to_literal!(b, [[1., 2., 3., 4.]; 3]); let b: Tensor, _, _> = a.clone().slice((.., 1..3)).realize().unwrap(); - assert_eq!(b.array(), [[2., 3.]; 5]); + assert_close_to_literal!(b, [[2., 3.]; 5]); let b: Tensor, _, _> = a.clone().slice((1..3, 1..3)).realize().unwrap(); - assert_eq!(b.array(), [[2., 3.], [2., 3.]]); + assert_close_to_literal!(b, [[2., 3.], [2., 3.]]); let b: Tensor, _, _> = a.slice((1..4, 1..4)).realize().unwrap(); - assert_eq!(b.array(), [[2., 3., 4.]; 3]); + assert_close_to_literal!(b, [[2., 3., 4.]; 3]); } #[test] fn test_slice_broadcast_bottom() { let dev = TestDevice::default(); - let a: Tensor, _, _> = dev.tensor([1., 2., 3., 4.]).broadcast(); + let a: Tensor, TestDtype, _> = dev.tensor([1., 2., 3., 4.]).broadcast(); let b: Tensor, _, _> = a.clone().slice((1..3, ..)).realize().unwrap(); - assert_eq!(b.array(), [[2.; 5], [3.; 5]]); + assert_close_to_literal!(b, [[2.; 5], [3.; 5]]); let b: Tensor, _, _> = a.clone().slice((.., 1..3)).realize().unwrap(); - assert_eq!(b.array(), [[1., 1.], [2., 2.], [3., 3.], [4., 4.]]); + assert_close_to_literal!(b, [[1., 1.], [2., 2.], [3., 3.], [4., 4.]]); let b: Tensor, _, _> = a.clone().slice((1..3, 3..)).realize().unwrap(); - assert_eq!(b.array(), [[2., 2.], [3., 3.]]); + assert_close_to_literal!(b, [[2., 2.], [3., 3.]]); let b: Tensor, _, _> = a.slice((..2, 1..3)).realize().unwrap(); - assert_eq!(b.array(), [[1., 1.], [2., 2.]]); + assert_close_to_literal!(b, [[1., 1.], [2., 2.]]); } #[test] fn test_slice_backward() { let dev = TestDevice::default(); - let a = dev.tensor([ + let a: Tensor<_, TestDtype, _> = dev.tensor([ [1., 2., 3., 4.], [5., 6., 7., 8.], [9., 10., 11., 12.], @@ -169,10 +168,10 @@ mod tests { ]); let b: Tensor, _, _, _> = a.leaky_trace().slice((2.., 2..)).realize().unwrap(); - assert_eq!(b.array(), [[11., 12.], [15., 16.]]); + assert_close_to_literal!(b, [[11., 12.], [15., 16.]]); let g = b.square().sum().backward(); - assert_eq!( - g.get(&a).array(), + assert_close_to_literal!( + g.get(&a), [[0.; 4], [0.; 4], [0., 0., 22., 24.], [0., 0., 30., 32.]] ); } diff --git a/src/tensor_ops/softmax.rs b/src/tensor_ops/softmax.rs index 81a4f27d0..125f5a0d4 100644 --- a/src/tensor_ops/softmax.rs +++ b/src/tensor_ops/softmax.rs @@ -115,22 +115,22 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = a.leaky_trace().softmax(); - assert_close( - &r.array(), - &[0.011656232, 0.031684924, 0.086128555, 0.23412168, 0.6364087], + assert_close_to_literal!( + r, + [0.011656232, 0.031684924, 0.086128555, 0.23412168, 0.6364087] ); let l = r * dev.tensor([0.0, 0.0, 1.0, 0.0, 0.0]); - assert_close(&l.array(), &[0.0, 0.0, 0.086128555, 0.0, 0.0]); + assert_close_to_literal!(l, [0.0, 0.0, 0.086128555, 0.0, 0.0]); let g = l.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ -0.00020078686, -0.00054579525, 0.015742086, -0.0040329117, -0.010962591, - ], + ] ); } @@ -139,25 +139,22 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([[-2.0, -1.0, 0.0], [1.0, 4.0, 7.0]]); let r = a.leaky_trace().softmax::>(); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.09003058, 0.24472849, 0.66524094], [0.002355633, 0.047314156, 0.9503302], - ], + ] ); let l = r * dev.tensor([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]); - assert_close( - &l.array(), - &[[0.09003058, 0.0, 0.0], [0.0, 0.047314156, 0.0]], - ); + assert_close_to_literal!(l, [[0.09003058, 0.0, 0.0], [0.0, 0.047314156, 0.0]]); let g = l.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.01365418, -0.0036721744, -0.009982005], [-1.85758e-5, 0.0075125876, -0.0074940124], - ], + ] ); } @@ -166,25 +163,22 @@ mod tests { let dev: TestDevice = Default::default(); let a: Tensor<_, TestDtype, _> = dev.tensor([[-2.0, -1.0, 0.0], [1.0, 4.0, 7.0]]); let r = a.leaky_trace().softmax::>(); - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [0.047425874, 0.0066928514, 0.0009110514], [0.95257413, 0.9933072, 0.9990892], - ], + ] ); let l = r * dev.tensor([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]); - assert_close( - &l.array(), - &[[0.047425874, 0.0, 0.0], [0.0, 0.9933072, 0.0]], - ); + assert_close_to_literal!(l, [[0.047425874, 0.0, 0.0], [0.0, 0.9933072, 0.0]]); let g = l.mean().backward(); - assert_close( - &g.get(&a).array(), - &[ + assert_close_to_literal!( + g.get(&a), + [ [0.0075294436, -0.0011080095, 0.0], [-0.0075294436, 0.0011080056, 0.0], - ], + ] ); } @@ -194,12 +188,12 @@ mod tests { let t: Tensor, TestDtype, _> = dev.sample_normal(); let r = t.leaky_trace().softmax::>(); #[rustfmt::skip] - assert_close( - &r.array(), - &[ + assert_close_to_literal!( + r, + [ [[0.08535644, 0.0987266, 0.00366116, 0.04927256], [0.01169326, 0.1515922, 0.00951258, 0.07721686], [0.0776206, 0.23813945, 0.19471556, 0.00249278]], [[0.01881982, 0.25171953, 0.02559674, 0.03725754], [0.04064152, 0.314442, 0.02427996, 0.04708378], [0.02791536, 0.14462142, 0.02221143, 0.04541067]], - ], + ] ); } } diff --git a/src/tensor_ops/square/mod.rs b/src/tensor_ops/square/mod.rs index ed70842b6..36838290d 100644 --- a/src/tensor_ops/square/mod.rs +++ b/src/tensor_ops/square/mod.rs @@ -47,8 +47,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().square(); - assert_eq!(r.array(), [4.0, 1.0, 0.0, 1.0, 4.0]); + assert_close_to_literal!(r, [4.0, 1.0, 0.0, 1.0, 4.0]); let g = r.mean().backward(); - assert_eq!(g.get(&x).array(), [-0.8, -0.4, 0.0, 0.4, 0.8]); + assert_close_to_literal!(g.get(&x), [-0.8, -0.4, 0.0, 0.4, 0.8]); } } diff --git a/src/tensor_ops/stddev_to.rs b/src/tensor_ops/stddev_to.rs index bd137c91c..34962a951 100644 --- a/src/tensor_ops/stddev_to.rs +++ b/src/tensor_ops/stddev_to.rs @@ -49,11 +49,11 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0, 4.0], [0.0, 2.0, 5.0, 10.0]]); let r = t.leaky_trace().stddev::, _>(1e-8); - assert_close(&r.array(), &[0.5, 0.0001, 1.0, 3.0]); + assert_close_to_literal!(r, [0.5, 0.0001, 1.0, 3.0]); let g = r.mean().backward(); - assert_close( - &g.get(&t).array(), - &[[0.125, 0.0, -0.125, -0.125], [-0.125, 0.0, 0.125, 0.125]], + assert_close_to_literal!( + g.get(&t), + [[0.125, 0.0, -0.125, -0.125], [-0.125, 0.0, 0.125, 0.125]] ); } @@ -62,14 +62,14 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0, 4.0], [0.0, 2.0, 5.0, 10.0]]); let r = t.leaky_trace().stddev::, _>(0.0); - assert_close(&r.array(), &[1.118034, 3.7666297]); + assert_close_to_literal!(r, [1.118034, 3.7666297]); let g = r.mean().backward(); - assert_close( - &g.get(&t).array(), - &[ + assert_close_to_literal!( + g.get(&t), + [ [-0.16770509, -0.0559017, 0.0559017, 0.16770509], [-0.14104122, -0.07466887, 0.024889633, 0.19082046], - ], + ] ); } } diff --git a/src/tensor_ops/sub/mod.rs b/src/tensor_ops/sub/mod.rs index f8f68716b..573dac7bb 100644 --- a/src/tensor_ops/sub/mod.rs +++ b/src/tensor_ops/sub/mod.rs @@ -89,10 +89,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor(1.0); let r = b.leaky_trace() - a.clone(); - assert_eq!(r.array(), 0.0); + assert_close_to_literal!(r, 0.0); let g = r.backward(); - assert_eq!(g.get(&a).array(), -1.0); - assert_eq!(g.get(&b).array(), 1.0); + assert_close_to_literal!(g.get(&a), -1.0); + assert_close_to_literal!(g.get(&b), 1.0); } #[test] @@ -102,10 +102,10 @@ mod tests { let b: Tensor<_, TestDtype, _> = dev.tensor([1.0, -1.0, 0.0]); let r = b.leaky_trace() - a.clone(); - assert_eq!(r.array(), [0.0, -3.0, -3.0]); + assert_close_to_literal!(r, [0.0, -3.0, -3.0]); let g = r.mean().backward(); - assert_eq!(g.get(&a).array(), [-1.0 / 3.0; 3]); - assert_eq!(g.get(&b).array(), [1.0 / 3.0; 3]); + assert_close_to_literal!(g.get(&a), [-1.0 / 3.0; 3]); + assert_close_to_literal!(g.get(&b), [1.0 / 3.0; 3]); } #[test] @@ -117,16 +117,10 @@ mod tests { dev.tensor([[0.5199, 0.3844, 0.3759], [0.8259, 0.3682, 0.0388]]); let r = b.leaky_trace() - a.clone(); - assert_close( - &r.array(), - &[ - [-0.13709998, 0.21360001, 0.2259], - [0.2601, -0.33279997, -0.7954], - ], - ); + assert_close_to_literal!(r, [[-0.1371, 0.2136, 0.2259], [0.2601, -0.3328, -0.7954]]); let g = r.mean().backward(); - assert_eq!(g.get(&a).array(), [[-1.0 / 6.0; 3]; 2]); - assert_eq!(g.get(&b).array(), [[1.0 / 6.0; 3]; 2]); + assert_close_to_literal!(g.get(&a), [[-1.0 / 6.0; 3]; 2]); + assert_close_to_literal!(g.get(&b), [[1.0 / 6.0; 3]; 2]); } #[test] @@ -134,9 +128,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor(0.0); let r = x.leaky_trace() - 1.0; - assert_eq!(r.array(), -1.0); + assert_close_to_literal!(r, -1.0); let g = r.exp().backward(); - assert_close(&[g.get(&x).array()], &[TestDtype::exp(-1.0)]); + assert_close_to_literal!(g.get(&x), f64::exp(-1.0)); } #[test] @@ -144,9 +138,9 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([0.0, 1.0, 2.0]); let r = x.leaky_trace() - 1.0; - assert_eq!(&r.array(), &[-1.0, 0.0, 1.0]); + assert_close_to_literal!(r, [-1.0, 0.0, 1.0]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[0.36787945, 1.0, 2.7182817]); + assert_close_to_literal!(g.get(&x), [0.36787945, 1.0, 2.7182817]); } #[test] @@ -154,8 +148,8 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([[0.0; 2]; 3]); let r = x.leaky_trace() - 1.0; - assert_eq!(r.array(), [[-1.0; 2]; 3]); + assert_close_to_literal!(r, [[-1.0; 2]; 3]); let g = r.exp().sum().backward(); - assert_close(&g.get(&x).array(), &[[0.36787945; 2]; 3]); + assert_close_to_literal!(g.get(&x), [[0.36787945; 2]; 3]); } } diff --git a/src/tensor_ops/sum_to/mod.rs b/src/tensor_ops/sum_to/mod.rs index 328e3f20c..a000c32e1 100644 --- a/src/tensor_ops/sum_to/mod.rs +++ b/src/tensor_ops/sum_to/mod.rs @@ -88,11 +88,11 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([1.0, 2.0, 3.0]); let r = t.leaky_trace().sum::(); - let e = 6.0; - assert_eq!(r.array(), e); + let e = 6.0f64; + assert_close_to_literal!(r, e); // NOTE: .exp() to make sure its using result grad properly let g = r.exp().backward(); - assert_eq!(g.get(&t).array(), [e.exp(); 3]); + assert_close_to_literal!(g.get(&t), [e.exp(); 3]); } #[test] @@ -100,10 +100,10 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [-2.0, 4.0, -6.0]]); let r = t.leaky_trace().sum::, _>(); - let e = [-1.0, 6.0, -3.0]; - assert_eq!(r.array(), e); + let e = [-1.0f64, 6.0, -3.0]; + assert_close_to_literal!(r, e); let g = r.exp().mean().backward(); - assert_close(&g.get(&t).array(), &[e.map(|x| x.exp() / 3.0); 2]); + assert_close_to_literal!(g.get(&t), [e.map(|x| x.exp() / 3.0); 2], 1e-4); } #[test] @@ -111,13 +111,10 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0], [-2.0, 4.0, -6.0]]); let r = t.leaky_trace().sum::, _>(); - let e = [6.0, -4.0]; - assert_eq!(r.array(), e); + let e = [6.0f64, -4.0]; + assert_close_to_literal!(r, e); let g = r.exp().mean().backward(); - assert_close( - &g.get(&t).array(), - &[[e[0].exp() / 2.0; 3], [e[1].exp() / 2.0; 3]], - ); + assert_close_to_literal!(g.get(&t), [[e[0].exp() / 2.0; 3], [e[1].exp() / 2.0; 3]]); } #[test] @@ -126,10 +123,10 @@ mod tests { let t: Tensor, TestDtype, _> = dev.sample_normal(); let r = t.leaky_trace().sum::, _>(); let r2 = t.leaky_trace().sum::, _>().sum::, _>(); - assert_close(&r.array(), &r2.array()); + assert_close_to_tensor!(r, r2); let g = r.sum().backward(); let g2 = r2.sum().backward(); - assert_close(&g.get(&t).array(), &g2.get(&t).array()); + assert_close_to_tensor!(g.get(&t), g2.get(&t)); } #[test] @@ -139,9 +136,9 @@ mod tests { let t2 = t1.clone().broadcast::, _>(); let r1 = t1.leaky_trace().sum::, _>() * 5.0; let r2 = t2.leaky_trace().sum::, _>(); - assert_close_with_tolerance(&r1.array(), &r2.array(), 3e-6); + assert_close_to_tensor!(r1, r2, 3e-6); let g = r1.sum().backward(); - assert_close(&g.get(&t1).array(), &[[5.0; 3]; 4]); + assert_close_to_literal!(g.get(&t1), [[5.0; 3]; 4]); } #[test] @@ -149,9 +146,9 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0; 100]; 60]); let r = t.leaky_trace().sum::, _>(); - assert_eq!(r.array(), [100.0; 60]); + assert_close_to_literal!(r, [100.0; 60]); let g = r.sum().backward(); - assert_close(&g.get(&t).array(), &t.array()); + assert_close_to_tensor!(g.get(&t), t); } #[test] @@ -160,7 +157,7 @@ mod tests { let a: Tensor<_, TestDtype, _> = dev.tensor([1.0, 2.0, 3.0]); let b = a.broadcast::, _>(); let c = b.sum::, _>(); - assert_eq!(c.array(), [[2.0, 4.0, 6.0]; 4]); + assert_close_to_literal!(c, [[2.0, 4.0, 6.0]; 4]); } #[test] @@ -169,8 +166,8 @@ mod tests { let a: Tensor, TestDtype, _> = dev.ones(); let b = a.leaky_trace().broadcast::, _>(); let c = b.sum(); - assert_eq!(c.array(), 24.0); + assert_close_to_literal!(c, 24.0); let g = c.backward(); - assert_eq!(g.get(&a).array(), [8.0; 3]); + assert_close_to_literal!(g.get(&a), [8.0; 3]); } } diff --git a/src/tensor_ops/tanh/mod.rs b/src/tensor_ops/tanh/mod.rs index 7d3d2bfe6..09d8e0317 100644 --- a/src/tensor_ops/tanh/mod.rs +++ b/src/tensor_ops/tanh/mod.rs @@ -47,14 +47,11 @@ mod tests { let dev: TestDevice = Default::default(); let x: Tensor<_, TestDtype, _> = dev.tensor([-2.0, -1.0, 0.0, 1.0, 2.0]); let r = x.leaky_trace().tanh(); - assert_close( - &r.array(), - &[-0.9640276, -0.7615942, 0., 0.7615942, 0.9640276], - ); + assert_close_to_literal!(r, [-0.9640276, -0.7615942, 0., 0.7615942, 0.9640276]); let g = r.mean().backward(); - assert_close( - &g.get(&x).array(), - &[0.014130163, 0.083994865, 0.2, 0.083994865, 0.014130163], + assert_close_to_literal!( + g.get(&x), + [0.014130163, 0.083994865, 0.2, 0.083994865, 0.014130163] ); } } diff --git a/src/tensor_ops/tri.rs b/src/tensor_ops/tri.rs index 0e7660316..32b94c0a8 100644 --- a/src/tensor_ops/tri.rs +++ b/src/tensor_ops/tri.rs @@ -68,16 +68,13 @@ where #[cfg(test)] mod tests { - use crate::{ - prelude::{AsArray, TensorFrom}, - tests::TestDevice, - }; + use crate::{tensor::*, tests::*}; #[test] fn test_tri() { let dev: TestDevice = Default::default(); - let t = dev.tensor( + let t: Tensor<_, TestDtype, _> = dev.tensor( [[[ [1., 2., 3., 4., 5., 6.], [1., 2., 3., 4., 5., 6.], @@ -86,35 +83,35 @@ mod tests { [1., 2., 3., 4., 5., 6.], ]; 4]; 3], ); - assert_eq!( - t.clone().lower_tri(None).array(), + assert_close_to_literal!( + t.clone().lower_tri(None), [[[ [1., 0., 0., 0., 0., 0.], [1., 2., 0., 0., 0., 0.], [1., 2., 3., 0., 0., 0.], [1., 2., 3., 4., 0., 0.], [1., 2., 3., 4., 5., 0.], - ]; 4]; 3], + ]; 4]; 3] ); - assert_eq!( - t.clone().lower_tri(2).array(), + assert_close_to_literal!( + t.clone().lower_tri(2), [[[ [1., 2., 3., 0., 0., 0.], [1., 2., 3., 4., 0., 0.], [1., 2., 3., 4., 5., 0.], [1., 2., 3., 4., 5., 6.], [1., 2., 3., 4., 5., 6.], - ]; 4]; 3], + ]; 4]; 3] ); - assert_eq!( - t.upper_tri(-1).array(), + assert_close_to_literal!( + t.upper_tri(-1), [[[ [1., 2., 3., 4., 5., 6.], [1., 2., 3., 4., 5., 6.], [0., 2., 3., 4., 5., 6.], [0., 0., 3., 4., 5., 6.], [0., 0., 0., 4., 5., 6.], - ]; 4]; 3], + ]; 4]; 3] ); } } diff --git a/src/tensor_ops/upscale2d/mod.rs b/src/tensor_ops/upscale2d/mod.rs index 7034dea5a..8e60acd10 100644 --- a/src/tensor_ops/upscale2d/mod.rs +++ b/src/tensor_ops/upscale2d/mod.rs @@ -256,20 +256,20 @@ mod tests { let x = dev.tensor([[[1.0, 0.0], [2.0, 3.0]]]); let y = x.leaky_trace().upscale2d::<4, 4, _>(NearestNeighbor); - assert_close( - &y.array(), - &[[ + assert_close_to_literal!( + y, + [[ [1.0, 1.0, 0.0, 0.0], [1.0, 1.0, 0.0, 0.0], [2.0, 2.0, 3.0, 3.0], [2.0, 2.0, 3.0, 3.0], - ]], + ]] ); let g = y.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[[0.679570457, 0.25], [1.847264025, 5.021384231]]], + assert_close_to_literal!( + g.get(&x), + [[[0.679570457, 0.25], [1.847264025, 5.021384231]]] ); } @@ -279,21 +279,21 @@ mod tests { let x = dev.tensor([[[1.0, 0.0, 2.0], [2.0, 3.0, 4.0]]]); let y = x.leaky_trace().upscale2d::<2, 7, _>(NearestNeighbor); - assert_close( - &y.array(), - &[[ + assert_close_to_literal!( + y, + [[ [1.0, 1.0, 1.0, 0.0, 0.0, 2.0, 2.0], [2.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0], - ]], + ]] ); let g = y.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[ + assert_close_to_literal!( + g.get(&x), + [[ [0.582488963, 0.142857143, 1.055579443], [1.583369164, 2.869362418, 7.799735719], - ]], + ]] ); } @@ -321,16 +321,13 @@ mod tests { } let grads = y.exp().mean().backward(); - let x_grad = grads.get(&x).array(); - for row in x_grad.iter() { - assert_close( - row, - &[[ - [0.03624376, 0.09852076, 0.26780716], - [0.48531687, 1.319228, 3.5860338], - ]; 3], - ); - } + assert_close_to_literal!( + grads.get(&x), + [[[ + [0.03624376, 0.09852076, 0.26780716], + [0.48531687, 1.319228, 3.5860338], + ]; 3]; 5] + ); } // Use align_corners when comparing these @@ -340,20 +337,20 @@ mod tests { let x = dev.tensor([[[1.0, 0.0], [2.0, 3.0]]]); let y = x.leaky_trace().upscale2d::<4, 4, _>(Bilinear); - assert_close( - &y.array(), - &[[ + assert_close_to_literal!( + y, + [[ [1.0, 0.66666663, 0.33333331, 0.0], [1.33333325, 1.22222221, 1.11111116, 1.0], [1.66666675, 1.77777779, 1.88888907, 2.0], [2.0, 2.33333325, 2.66666651, 3.0], - ]], + ]] ); let g = y.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[[0.8130764, 0.6928807], [1.8153939, 2.7659647]]], + assert_close_to_literal!( + g.get(&x), + [[[0.8130764, 0.6928807], [1.8153939, 2.7659647]]] ); } @@ -363,21 +360,21 @@ mod tests { let x = dev.tensor([[[1.0, 0.0, 2.0], [2.0, 3.0, 4.0]]]); let y = x.leaky_trace().upscale2d::<2, 7, _>(Bilinear); - assert_close( - &y.array(), - &[[ + assert_close_to_literal!( + y, + [[ [1.0, 0.6666666, 0.3333333, 0.0, 0.6666667, 1.3333335, 2.0], [2.0, 2.3333333, 2.6666665, 3.0, 3.3333335, 3.6666667, 4.0], - ]], + ]] ); let g = y.exp().mean().backward(); - assert_close( - &g.get(&x).array(), - &[[ + assert_close_to_literal!( + g.get(&x), + [[ [0.3201411, 0.3673356, 0.7548153], [1.3615142, 4.6318388, 6.4302063], - ]], + ]] ); } @@ -390,30 +387,24 @@ mod tests { let x: Tensor, _, _> = [x.clone(), x.clone(), x.clone(), x.clone(), x].stack(); let y = x.leaky_trace().upscale2d::<5, 6, _>(Bilinear); - let y_array = y.array(); - for img in y_array { - assert_close( - &img, - &[[ - [1.0, 1.4, 1.8, 2.2, 2.6, 3.0], - [1.75, 2.15, 2.55, 2.95, 3.35, 3.75], - [2.5, 2.9, 3.3, 3.7, 4.1, 4.5], - [3.25, 3.65, 4.05, 4.45, 4.85, 5.25], - [4.0, 4.4, 4.8, 5.2, 5.6, 6.0], - ]; 3], - ); - } + assert_close_to_literal!( + y, + [[[ + [1.0, 1.4, 1.8, 2.2, 2.6, 3.0], + [1.75, 2.15, 2.55, 2.95, 3.35, 3.75], + [2.5, 2.9, 3.3, 3.7, 4.1, 4.5], + [3.25, 3.65, 4.05, 4.45, 4.85, 5.25], + [4.0, 4.4, 4.8, 5.2, 5.6, 6.0], + ]; 3]; 5] + ); let grads = y.exp().mean().backward(); - let x_grad = grads.get(&x).array(); - for row in x_grad.iter() { - assert_close( - row, - &[[ - [0.10178878, 0.30509925, 0.47953573], - [0.42368498, 1.2699431, 1.9960163], - ]; 3], - ); - } + assert_close_to_literal!( + grads.get(&x), + [[[ + [0.10178878, 0.30509925, 0.47953573], + [0.42368498, 1.2699431, 1.9960163], + ]; 3]; 5] + ); } } diff --git a/src/tensor_ops/var_to.rs b/src/tensor_ops/var_to.rs index f4a640390..423cf8b59 100644 --- a/src/tensor_ops/var_to.rs +++ b/src/tensor_ops/var_to.rs @@ -50,10 +50,10 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0, 4.0], [0.0, 2.0, 5.0, 10.0]]); let r = t.leaky_trace().var::, _>(); - assert_eq!(r.array(), [0.25, 0.0, 1.0, 9.0]); + assert_close_to_literal!(r, [0.25, 0.0, 1.0, 9.0]); let g = r.mean().backward(); - assert_eq!( - g.get(&t).array(), + assert_close_to_literal!( + g.get(&t), [[0.125, 0.0, -0.25, -0.75], [-0.125, 0.0, 0.25, 0.75]] ); } @@ -63,10 +63,10 @@ mod tests { let dev: TestDevice = Default::default(); let t: Tensor<_, TestDtype, _> = dev.tensor([[1.0, 2.0, 3.0, 4.0], [0.0, 2.0, 5.0, 10.0]]); let r = t.leaky_trace().var::, _>(); - assert_eq!(r.array(), [1.25, 14.1875]); + assert_close_to_literal!(r, [1.25, 14.1875]); let g = r.mean().backward(); - assert_eq!( - g.get(&t).array(), + assert_close_to_literal!( + g.get(&t), [ [-0.375, -0.125, 0.125, 0.375], [-1.0625, -0.5625, 0.1875, 1.4375]