anchor.diff:              Assert.AreEqual(revxdCorrect, revxd)
               Assert.AreEqual(revydCorrect, revyd)
   
  -    // TODO: add test for MulTTConst
  -    // TODO: add test for MulTT0
  -    // TODO: add test for MulTConstT0
  -    // TODO: add test for MulTT0Const
  +    [<Test>]
  +    member _.TestDerivativeMulTTConst () =
  +        for swap in [true; false] do
  +            for combo in Combos.AllDevicesAndBackends do
  +                let fwdx = combo.tensor([1.; 2.; 3.]).forwardDiff(combo.tensor([2.; 3.; 4.]))
  +                let fwdy = combo.tensor([5.; 6.; 7.])
  +                let fwdz = if swap then fwdy * fwdx else fwdx * fwdy
  +                let fwdzCorrect = combo.tensor([5.; 12.; 21.])
  +                let fwdzd = fwdz.derivative
  +                let fwdzdCorrect = combo.tensor([10.; 18.; 28.])
  +
  +                let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
  +                let revy = combo.tensor([5.; 6.; 7.])
  +                let revz = if swap then revy * revx else revx * revy
  +                let revzCorrect = combo.tensor([5.; 12.; 21.])
  +                revz.reverse(combo.tensor([5.; 5.; 5.]))
  +                let revxd = revx.derivative
  +                let revxdCorrect = combo.tensor([25.; 30.; 35.])
  +
  +                Assert.AreEqual(fwdzCorrect, fwdz)
  +                Assert.AreEqual(fwdzdCorrect, fwdzd)
  +                Assert.AreEqual(revzCorrect, revz)
  +                Assert.AreEqual(revxdCorrect, revxd)
  +
  +    [<Test>]
  +    member _.TestDerivativeMulTT0 () =
  +        for swap in [true; false] do
  +            for combo in Combos.AllDevicesAndBackends do
  +                let fwdx = combo.tensor([1.; 2.; 3.]).forwardDiff(combo.tensor([2.; 3.; 4.]))
  +                let fwdy = combo.tensor(5.).forwardDiff(combo.tensor(2.))
  +                let fwdz = if swap then fwdy * fwdx else fwdx * fwdy
  +                let fwdzCorrect = combo.tensor([5.; 10.; 15.])
  +                let fwdzd = fwdz.derivative
  +                let fwdzdCorrect = combo.tensor([12.; 19.; 26.])
  +
  +                let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
  +                let revy = combo.tensor(5.).reverseDiff()
  +                let revz = if swap then revy * revx else revx * revy
  +                let revzCorrect = combo.tensor([5.; 10.; 15.])
  +                revz.reverse(combo.tensor([5.; 6.; 7.]))
  +                let revxd = revx.derivative
  +                let revxdCorrect = combo.tensor([25.; 30.; 35.])
  +                let revyd = revy.derivative
  +                let revydCorrect = combo.tensor(38.)
  +
  +                Assert.AreEqual(fwdzCorrect, fwdz)
  +                Assert.AreEqual(fwdzdCorrect, fwdzd)
  +                Assert.AreEqual(revzCorrect, revz)
  +                Assert.AreEqual(revxdCorrect, revxd)
  +                Assert.AreEqual(revydCorrect, revyd)
  +
  +    [<Test>]
  +    member _.TestDerivativeMulTConstT0 () =
  +        for swap in [true; false] do
  +            for combo in Combos.AllDevicesAndBackends do
  +                let fwdx = combo.tensor([1.; 2.; 3.])
  +                let fwdy = combo.tensor(5.).forwardDiff(combo.tensor(2.))
  +                let fwdz = if swap then fwdy * fwdx else fwdx * fwdy
  +                let fwdzCorrect = combo.tensor([5.; 10.; 15.])
  +                let fwdzd = fwdz.derivative
  +                let fwdzdCorrect = combo.tensor([2.; 4.; 6.])
  +
  +                let revx = combo.tensor([1.; 2.; 3.])
  +                let revy = combo.tensor(5.).reverseDiff()
  +                let revz = if swap then revy * revx else revx * revy
  +                let revzCorrect = combo.tensor([5.; 10.; 15.])
  +                revz.reverse(combo.tensor([5.; 6.; 7.]))
  +                let revyd = revy.derivative
  +                let revydCorrect = combo.tensor(38.)
  +
  +                Assert.AreEqual(fwdzCorrect, fwdz)
  +                Assert.AreEqual(fwdzdCorrect, fwdzd)
  +                Assert.AreEqual(revzCorrect, revz)
  +                Assert.AreEqual(revydCorrect, revyd)
  +
  +    [<Test>]
  +    member _.TestDerivativeMulTT0Const () =
  +        for swap in [true; false] do
  +            for combo in Combos.AllDevicesAndBackends do
  +                let fwdx = combo.tensor([1.; 2.; 3.]).forwardDiff(combo.tensor([2.; 3.; 4.]))
  +                let fwdy = combo.tensor(5.)
  +                let fwdz = if swap then fwdy * fwdx else fwdx * fwdy
  +                let fwdzCorrect = combo.tensor([5.; 10.; 15.])
  +                let fwdzd = fwdz.derivative
  +                let fwdzdCorrect = combo.tensor([10.; 15.; 20.])
  +
  +                let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
  +                let revy = combo.tensor(5.)
  +                let revz = if swap then revy * revx else revx * revy
  +                let revzCorrect = combo.tensor([5.; 10.; 15.])
  +                revz.reverse(combo.tensor([5.; 6.; 7.]))
  +                let revxd = revx.derivative
  +                let revxdCorrect = combo.tensor([25.; 30.; 35.])
  +
  +                Assert.AreEqual(fwdzCorrect, fwdz)
  +                Assert.AreEqual(fwdzdCorrect, fwdzd)
  +                Assert.AreEqual(revzCorrect, revz)
  +                Assert.AreEqual(revxdCorrect, revxd)
   
       [<Test>]
       member _.TestDerivativeDivTT () =
  
positive.code:             Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeAddT2T1 () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor([[1.; 2.]; [3.; 4.]]).forwardDiff(combo.tensor([[2.; 3.]; [4.; 5.]]))
              let fwdy = combo.tensor([5.; 6.]).forwardDiff(combo.tensor([2.; 3.]))
              let fwdz = fwdx + fwdy
              let fwdzCorrect = combo.tensor([[6.; 8.]; [8.; 10.]])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([[4.; 6.]; [6.; 8.]])
  
              let revx = combo.tensor([[1.; 2.]; [3.; 4.]]).reverseDiff()
              let revy = combo.tensor([5.; 6.]).reverseDiff()
              let revz = revx + revy
              let revzCorrect = combo.tensor([[6.; 8.]; [8.; 10.]])
              revz.reverse(combo.tensor([[2.; 3.]; [4.; 5.]]))
              let revxd = revx.derivative
              let revxdCorrect = combo.tensor([[2.; 3.]; [4.; 5.]])
              let revyd = revy.derivative
              let revydCorrect = combo.tensor([6.; 8.])
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revxdCorrect, revxd)
              Assert.AreEqual(revydCorrect, revyd)
  
      // TODO: add test for AddTTConst
      // TODO: add test for AddTT0
      // TODO: add test for AddTT0Const
      // TODO: add test for AddTConstT0
      // TODO: add test for AddT2T1Const
      // TODO: add test for AddT2ConstT1
  
      [<Test>]
      member _.TestDerivativeExpand () =
  
negative.code:             Assert.AreEqual(revxdCorrect, revxd)
              Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeSubTTConst () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor([1.; 2.; 3.]).forwardDiff(combo.tensor([2.; 3.; 4.]))
              let fwdy = combo.tensor([5.; 6.; 7.])
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([-4.; -4.; -4.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([2.; 3.; 4.])
  
              let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
              let revy = combo.tensor([5.; 6.; 7.])
              let revz = revx - revy
              let revzCorrect = combo.tensor([-4.; -4.; -4.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revxd = revx.derivative
              let revxdCorrect = combo.tensor([5.; 5.; 5.])
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revxdCorrect, revxd)
  
      [<Test>]
      member _.TestDerivativeSubTConstT () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor([1.; 2.; 3.])
              let fwdy = combo.tensor([5.; 6.; 7.]).forwardDiff(combo.tensor([2.; 2.; 3.]))
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([-4.; -4.; -4.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([-2.; -2.; -3.])
  
              let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
              let revy = combo.tensor([5.; 6.; 7.]).reverseDiff()
              let revz = revx - revy
              let revzCorrect = combo.tensor([-4.; -4.; -4.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revyd = revy.derivative
              let revydCorrect = combo.tensor([-5.; -5.; -5.])
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeSubT0T () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor(9.).forwardDiff(combo.tensor(7.))
              let fwdy = combo.tensor([5.; 6.; 7.]).forwardDiff(combo.tensor([2.; 2.; 3.]))
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([4.; 3.; 2.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([5.; 5.; 4.])
  
              let revx = combo.tensor(9.).reverseDiff()
              let revy = combo.tensor([5.; 6.; 7.]).reverseDiff()
              let revz = revx - revy
              let revzCorrect = combo.tensor([4.; 3.; 2.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revxd = revx.derivative
              let revxdCorrect = combo.tensor(15.)
              let revyd = revy.derivative
              let revydCorrect = combo.tensor([-5.; -5.; -5.])
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revxdCorrect, revxd)
              Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeSubTT0 () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor([1.; 2.; 3.]).forwardDiff(combo.tensor([2.; 3.; 4.]))
              let fwdy = combo.tensor(5.).forwardDiff(combo.tensor(7.))
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([-4.; -3.; -2.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([-5.; -4.; -3.])
  
              let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
              let revy = combo.tensor(5.).reverseDiff()
              let revz = revx - revy
              let revzCorrect = combo.tensor([-4.; -3.; -2.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revxd = revx.derivative
              let revxdCorrect = combo.tensor([5.; 5.; 5.])
              let revyd = revy.derivative
              let revydCorrect = combo.tensor(-15.)
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revxdCorrect, revxd)
              Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeSubT0TConst () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor(9.).forwardDiff(combo.tensor(7.))
              let fwdy = combo.tensor([5.; 6.; 7.])
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([4.; 3.; 2.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([7.; 7.; 7.])
  
              let revx = combo.tensor(9.).reverseDiff()
              let revy = combo.tensor([5.; 6.; 7.])
              let revz = revx - revy
              let revzCorrect = combo.tensor([4.; 3.; 2.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revxd = revx.derivative
              let revxdCorrect = combo.tensor(15.)
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revxdCorrect, revxd)
  
      [<Test>]
      member _.TestDerivativeSubTConstT0 () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor([1.; 2.; 3.])
              let fwdy = combo.tensor(5.).forwardDiff(combo.tensor(7.))
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([-4.; -3.; -2.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([-7.; -7.; -7.])
  
              let revx = combo.tensor([1.; 2.; 3.])
              let revy = combo.tensor(5.).reverseDiff()
              let revz = revx - revy
              let revzCorrect = combo.tensor([-4.; -3.; -2.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revyd = revy.derivative
              let revydCorrect = combo.tensor(-15.)
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeSubT0ConstT () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor(9.)
              let fwdy = combo.tensor([5.; 6.; 7.]).forwardDiff(combo.tensor([2.; 2.; 3.]))
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([4.; 3.; 2.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([-2.; -2.; -3.])
  
              let revx = combo.tensor(9.)
              let revy = combo.tensor([5.; 6.; 7.]).reverseDiff()
              let revz = revx - revy
              let revzCorrect = combo.tensor([4.; 3.; 2.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revyd = revy.derivative
              let revydCorrect = combo.tensor([-5.; -5.; -5.])
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revydCorrect, revyd)
  
      [<Test>]
      member _.TestDerivativeSubTT0Const () =
          for combo in Combos.AllDevicesAndBackends do
              let fwdx = combo.tensor([1.; 2.; 3.]).forwardDiff(combo.tensor([2.; 3.; 4.]))
              let fwdy = combo.tensor(5.)
              let fwdz = fwdx - fwdy
              let fwdzCorrect = combo.tensor([-4.; -3.; -2.])
              let fwdzd = fwdz.derivative
              let fwdzdCorrect = combo.tensor([2.; 3.; 4.])
  
              let revx = combo.tensor([1.; 2.; 3.]).reverseDiff()
              let revy = combo.tensor(5.)
              let revz = revx - revy
              let revzCorrect = combo.tensor([-4.; -3.; -2.])
              revz.reverse(combo.tensor([5.; 5.; 5.]))
              let revxd = revx.derivative
              let revxdCorrect = combo.tensor([5.; 5.; 5.])
  
              Assert.AreEqual(fwdzCorrect, fwdz)
              Assert.AreEqual(fwdzdCorrect, fwdzd)
              Assert.AreEqual(revzCorrect, revz)
              Assert.AreEqual(revxdCorrect, revxd)
  
      [<Test>]
      member _.TestDerivativeMulTT () =
  