diff --git a/unit_tests/operator/Test_MulImpl.cpp b/unit_tests/operator/Test_MulImpl.cpp
index 2937e94938c671140eeeee87d47d5c48f685203e..f932b150876b4c6113d41165051cee3b7d67cc1b 100644
--- a/unit_tests/operator/Test_MulImpl.cpp
+++ b/unit_tests/operator/Test_MulImpl.cpp
@@ -9,6 +9,7 @@
  *
  ********************************************************************************/
 
+<<<<<<< HEAD
 #include <chrono>
 #include <cstddef> // std::size_t
 #include <cstdint> // std::uint16_t
@@ -22,6 +23,36 @@
 #include "aidge/backend/cpu/data/TensorImpl.hpp"
 #include "aidge/backend/cpu/operator/MulImpl.hpp"
 #include "aidge/data/DataType.hpp"
+=======
+<<<<<<< HEAD
+#include <chrono>      // std::micro, std::chrono::time_point,
+                       // std::chrono::system_clock,
+#include <cstddef>     // std::size_t
+#include <cstdint>     // std::uint16_t
+#include <functional>  // std::multiplies
+#include <memory>
+#include <numeric>     // std::accumulate
+#include <random>      // std::random_device, std::mt19937
+                       // std::uniform_int_distribution, std::uniform_real_distribution
+#include <vector>
+
+#include <catch2/catch_test_macros.hpp>
+#include <fmt/core.h>
+=======
+#include <catch2/catch_test_macros.hpp>
+#include <chrono>
+#include <cstddef> // std::size_t
+#include <cstdint> // std::uint16_t
+#include <iostream>
+#include <memory>
+#include <numeric> // std::accumulate
+#include <random> // std::random_device, std::mt19937, std::uniform_real_distribution
+>>>>>>> 9d427c111c3c37ad141cd12a30c851f7fdf6a8fe
+
+#include "aidge/backend/cpu/data/TensorImpl.hpp"
+#include "aidge/backend/cpu/operator/MulImpl.hpp"
+#include "aidge/data/Data.hpp"
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
 #include "aidge/data/Tensor.hpp"
 #include "aidge/operator/Mul.hpp"
 #include "aidge/utils/ArrayHelpers.hpp"
@@ -30,11 +61,19 @@
 
 namespace Aidge {
 
+<<<<<<< HEAD
 TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
+=======
+<<<<<<< HEAD
+TEST_CASE("[CPU/Operator] Mul Backward", "[Mul][CPU][Backward]")
+{
+    using aif32 = cpptype_t<DataType::Float32>;
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
     std::shared_ptr<Mul_Op> op = std::make_shared<Mul_Op>();
     op->setDataType(DataType::Float32);
     op->setBackend("cpu");
 
+<<<<<<< HEAD
     // NOTE: The first four tests use fixed values, the last one uses random values but static dimensions.
 
     SECTION("Case 1: 1D and 2D Tensors") {
@@ -120,6 +159,88 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
                                    {70.0, 74.0, 78.0},
                                    {82.0, 86.0, 90.0}}});
 
+=======
+    SECTION("Case 1: 2D and 1D tensors") {
+        const auto T0 = std::make_shared<Tensor>(Array2D<aif32,2,3>(
+            {
+                {
+                    {1,2,3},{4,5,6}
+                }
+            }
+        ));
+
+        const auto T1 = std::make_shared<Tensor>(Array1D<aif32,3>(
+            {0.1,0.2,0.3}
+        ));
+
+        op->getOutput(0)->setGrad(std::make_shared<Tensor>(Array2D<aif32,2,3>({{{1.0,1.0,1.0},{1.0,1.0,1.0}}})));
+
+        op->associateInput(0,T0);
+        op->associateInput(1,T1);
+        op->forwardDims();
+
+        op->forward();
+        op->backward();
+
+        const Tensor T0Grad = Array2D<aif32, 2, 3>({{{0.1,0.2,0.3},{0.1, 0.2, 0.3}}});
+        const Tensor T1Grad = Array1D<aif32, 3>({5,7,9});
+
+        REQUIRE(approxEq<aif32>(*(op->getInput(0)->grad()), T0Grad));
+        REQUIRE(approxEq<aif32>(*(op->getInput(1)->grad()), T1Grad));
+    }
+
+    SECTION("Case 2: 3D and 1D tensors") {
+        const auto T0 = std::make_shared<Tensor>(Array3D<aif32,2,2,3>(
+            {
+                {
+                    {
+                        {1.0, 2.0, 3.0},
+                        {4.0, 5.0, 6.0}
+                    },
+                    {
+                        {7.0, 8.0, 9.0},
+                        {10.0, 11.0, 12.0}
+                    }
+                }
+            }
+        ));
+
+        const auto T1 = std::make_shared<Tensor>(Array1D<aif32, 3>({0.3,0.2,0.1}));
+
+        const auto newGrad = std::make_shared<Tensor>(Array3D<aif32,2,2,3>(
+                {
+                    {
+                        {
+                            {1, 1, 1},
+                            {1, 1, 1}
+                        },
+                        {
+                            {1, 1, 1},
+                            {1, 1, 1}
+                        }
+                    }
+                }
+            ));
+
+        const Tensor expectedGrad0 = Array3D<aif32,2,2,3>(
+            {
+                {
+                    {
+                        {0.3, 0.2, 0.1},
+                        {0.3, 0.2, 0.1}
+                    },
+                    {
+                        {0.3, 0.2, 0.1},
+                        {0.3, 0.2, 0.1}
+                    }
+                }
+            }
+        );
+
+        const Tensor expectedGrad1 = Array1D<aif32,3>(
+            {22.0, 26.0, 30.0}
+        );
+
         op->associateInput(0, T0);
         op->associateInput(1, T1);
         op->getOutput(0)->setGrad(newGrad);
@@ -127,6 +248,133 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
 
         op->backward();
 
+        REQUIRE(approxEq<aif32>(*(op->getInput(0)->grad()), expectedGrad0));
+        REQUIRE(approxEq<aif32>(*(op->getInput(1)->grad()), expectedGrad1));
+    }
+
+    SECTION("Case 3: 4D and 2D tensors") {
+        const auto T0 = std::make_shared<Tensor>(Array4D<aif32,2, 2, 3, 3>(
+            {
+                {
+                    {
+                        {
+                            {1.0, 2.0, 3.0},
+                            {4.0, 5.0, 6.0},
+                            {7.0, 8.0, 9.0}
+                        },
+                        {
+                            {10.0, 11.0, 12.0},
+                            {13.0, 14.0, 15.0},
+                            {16.0, 17.0, 18.0}
+                        }
+                    },
+                    {
+                        {
+                            {19.0, 20.0, 21.0},
+                            {22.0, 23.0, 24.0},
+                            {25.0, 26.0, 27.0}
+                        },
+                        {
+                            {28.0, 29.0, 30.0},
+                            {31.0, 32.0, 33.0},
+                            {34.0, 35.0, 36.0}
+                        }
+                    }
+                }
+            }
+        ));
+
+        const auto T1 = std::make_shared<Tensor>(Array2D<aif32, 3,3>(
+            {
+                {
+                    {0.5,0.3,0.1},
+                    {0.4,0.2,0.6},
+                    {0.7,0.8,0.9}
+                }
+            }
+        ));
+
+        const auto newGrad = std::make_shared<Tensor>(Array4D<aif32,2, 2, 3, 3>(
+            {
+                {
+                    {
+                        {
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0}
+                        },
+                        {
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0}
+                        }
+                    },
+                    {
+                        {
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0}
+                        },
+                        {
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0},
+                            {1.0, 1.0, 1.0}
+                        }
+                    }
+                }
+            }
+        ));
+
+        const Tensor expectedGrad0 = Array4D<aif32,2,2,3,3>(
+            {
+                {
+                    {
+                        {
+                            {0.5, 0.3, 0.1},
+                            {0.4, 0.2, 0.6},
+                            {0.7, 0.8, 0.9}
+                        },
+                        {
+                            {0.5, 0.3, 0.1},
+                            {0.4, 0.2, 0.6},
+                            {0.7, 0.8, 0.9}
+                        }
+                    },
+                    {
+                        {
+                            {0.5, 0.3, 0.1},
+                            {0.4, 0.2, 0.6},
+                            {0.7, 0.8, 0.9}
+                        },
+                        {
+                            {0.5, 0.3, 0.1},
+                            {0.4, 0.2, 0.6},
+                            {0.7, 0.8, 0.9}
+                        }
+                    }
+                }
+            }
+        );
+
+        const Tensor expectedGrad1 = Array2D<aif32,3, 3>(
+            {
+                {
+                    {58.0, 62.0, 66.0},
+                    {70.0, 74.0, 78.0},
+                    {82.0, 86.0, 90.0}
+                }
+            }
+        );
+
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+        op->getOutput(0)->setGrad(newGrad);
+        op->forwardDims();
+<<<<<<< HEAD
+
+        op->backward();
+
         REQUIRE(approxEq<cpptype_t<DataType::Float32>>(*(op->getInput(0)->grad()), expectedGrad0));
         REQUIRE(approxEq<cpptype_t<DataType::Float32>>(*(op->getInput(1)->grad()), expectedGrad1));
     }
@@ -281,6 +529,392 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
 
         // Perform backward pass
         op->backward();
+=======
+
+        op->backward();
+
+        REQUIRE(approxEq<aif32>(*(op->getInput(0)->grad()), expectedGrad0));
+        REQUIRE(approxEq<aif32>(*(op->getInput(1)->grad()), expectedGrad1));
+    }
+
+    SECTION("Case 4: 3D and 2D tensors") {
+        const auto T0 = std::make_shared<Tensor>(Array3D<aif32, 2, 3, 4>(
+            {
+                {
+                    {
+                        {1.0, 2.0, 3.0, 4.0},
+                        {5.0, 6.0, 7.0, 8.0},
+                        {9.0, 10.0, 11.0, 12.0},
+                    },
+                    {
+                        {13.0, 14.0, 15.0, 16.0},
+                        {17.0, 18.0, 19.0, 20.0},
+                        {21.0, 22.0, 23.0, 24.0},
+                    }
+                }
+            }
+        ));
+
+        const auto T1 = std::make_shared<Tensor>(Array2D<aif32, 3, 4>(
+            {
+                {
+                    {0.1, 0.2, 0.3, 0.4},
+                    {0.5, 0.6, 0.7, 0.8},
+                    {0.9, 1.0, 1.1, 1.2}
+                }
+            }
+        ));
+
+        const auto newGrad = std::make_shared<Tensor>(Array3D<aif32, 2,3,4>(
+            {
+                {
+                    {
+                        {1.0, 1.0, 1.0, 1.0},
+                        {1.0, 1.0, 1.0, 1.0},
+                        {1.0, 1.0, 1.0, 1.0},
+                    },
+                    {
+                        {1.0, 1.0, 1.0, 1.0},
+                        {1.0, 1.0, 1.0, 1.0},
+                        {1.0, 1.0, 1.0, 1.0},
+                    }
+                }
+            }
+        ));
+
+        const Tensor expectedGrad0 = Array3D<aif32,2,3,4>(
+            {
+                {
+                    {
+                        {0.1, 0.2, 0.3, 0.4},
+                        {0.5, 0.6, 0.7, 0.8},
+                        {0.9, 1.0, 1.1, 1.2}
+                    },
+                    {
+                        {0.1, 0.2, 0.3, 0.4},
+                        {0.5, 0.6, 0.7, 0.8},
+                        {0.9, 1.0, 1.1, 1.2}
+                    }
+                }
+            }
+        );
+
+        const Tensor expectedGrad1 = Array2D<aif32,3,4>(
+            {
+                {
+                    {14.0, 16.0, 18.0, 20.0},
+                    {22.0, 24.0, 26.0, 28.0},
+                    {30.0, 32.0, 34.0, 36.0}
+                }
+            }
+        );
+
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+        op->getOutput(0)->setGrad(newGrad);
+        op->forwardDims();
+
+        op->backward();
+
+        REQUIRE(approxEq<aif32>(*(op->getInput(0)->grad()), expectedGrad0));
+        REQUIRE(approxEq<aif32>(*(op->getInput(1)->grad()), expectedGrad1));
+=======
+TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
+    std::shared_ptr<Node> myMul = Mul();
+    auto op = std::static_pointer_cast<OperatorTensor>(myMul->getOperator());
+    op->setDataType(DataType::Float32);
+    op->setBackend("cpu");
+
+    // NOTE: The first four tests use fixed values, the last one uses random values but static dimensions.
+
+    SECTION("Case 1: 1D and 2D Tensors") {
+        const auto T0 = std::make_shared<Tensor>(
+            Array2D<float, 2, 3>({{{1, 2, 3}, {4, 5, 6}}}));
+
+        const auto T1 =
+            std::make_shared<Tensor>(Array1D<float, 3>({0.1, 0.2, 0.3}));
+
+        float *input0 = static_cast<float *>(T0->getImpl()->rawPtr());
+        float *input1 = static_cast<float *>(T1->getImpl()->rawPtr());
+
+        // TODO Use
+        T0->setDataType(DataType::Float32);
+        T0->setBackend("cpu");
+        T1->setDataType(DataType::Float32);
+        T1->setBackend("cpu");
+
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+        op->getOutput(0)->setGrad(std::make_shared<Tensor>(
+            Array2D<float, 2, 3>({{{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}}})));
+        op->forwardDims();
+
+        myMul->backward();
+
+        const auto expectedGrad0 = std::make_shared<Tensor>(
+            Array2D<float, 2, 3>({{{0.1, 0.2, 0.3}, {0.1, 0.2, 0.3}}}));
+
+        const auto expectedGrad1 =
+            std::make_shared<Tensor>(Array1D<float, 3>({5, 7, 9}));
+
+        REQUIRE(approxEq<float>(*(op->getInput(0)->grad()), *expectedGrad0));
+        REQUIRE(approxEq<float>(*(op->getInput(1)->grad()), *expectedGrad1));
+    }
+
+    SECTION("Case 2: 3D and 1D tensors") {
+        const auto T0 = std::make_shared<Tensor>(Array3D<float, 2, 2, 3>(
+            {{{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}},
+              {{7.0, 8.0, 9.0}, {10.0, 11.0, 12.0}}}}));
+
+        const auto T1 =
+            std::make_shared<Tensor>(Array1D<float, 3>({0.3, 0.2, 0.1}));
+
+        const auto newGrad = std::make_shared<Tensor>(Array3D<float, 2, 2, 3>(
+            {{{{1, 1, 1}, {1, 1, 1}}, {{1, 1, 1}, {1, 1, 1}}}}));
+
+        const auto expectedGrad0 = std::make_shared<Tensor>(
+            Array3D<float, 2, 2, 3>({{{{0.3, 0.2, 0.1}, {0.3, 0.2, 0.1}},
+                                      {{0.3, 0.2, 0.1}, {0.3, 0.2, 0.1}}}}));
+
+        const auto expectedGrad1 =
+            std::make_shared<Tensor>(Array1D<float, 3>({22.0, 26.0, 30.0}));
+
+        for (auto T : {T0, T1, newGrad, expectedGrad0, expectedGrad1}) {
+            T->setBackend("cpu");
+            T->setDataType(DataType::Float32);
+        }
+
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+        op->getOutput(0)->setGrad(newGrad);
+        op->forwardDims();
+
+        myMul->backward();
+
+        REQUIRE(approxEq<float>(*(op->getInput(0)->grad()), *expectedGrad0));
+        REQUIRE(approxEq<float>(*(op->getInput(1)->grad()), *expectedGrad1));
+    }
+
+    SECTION("Case 3: 4D and 2D tensors") {
+        const auto T0 = std::make_shared<Tensor>(Array4D<float, 2, 2, 3, 3>(
+            {{{{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}},
+               {{10.0, 11.0, 12.0}, {13.0, 14.0, 15.0}, {16.0, 17.0, 18.0}}},
+              {{{19.0, 20.0, 21.0}, {22.0, 23.0, 24.0}, {25.0, 26.0, 27.0}},
+               {{28.0, 29.0, 30.0},
+                {31.0, 32.0, 33.0},
+                {34.0, 35.0, 36.0}}}}}));
+
+        const auto T1 = std::make_shared<Tensor>(Array2D<float, 3, 3>(
+            {{{0.5, 0.3, 0.1}, {0.4, 0.2, 0.6}, {0.7, 0.8, 0.9}}}));
+
+        const auto newGrad =
+            std::make_shared<Tensor>(Array4D<float, 2, 2, 3, 3>(
+                {{{{{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}},
+                   {{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}}},
+                  {{{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}},
+                   {{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}}}}}));
+
+        const auto expectedGrad0 =
+            std::make_shared<Tensor>(Array4D<float, 2, 2, 3, 3>(
+                {{{{{0.5, 0.3, 0.1}, {0.4, 0.2, 0.6}, {0.7, 0.8, 0.9}},
+                   {{0.5, 0.3, 0.1}, {0.4, 0.2, 0.6}, {0.7, 0.8, 0.9}}},
+                  {{{0.5, 0.3, 0.1}, {0.4, 0.2, 0.6}, {0.7, 0.8, 0.9}},
+                   {{0.5, 0.3, 0.1}, {0.4, 0.2, 0.6}, {0.7, 0.8, 0.9}}}}}));
+
+        const auto expectedGrad1 = std::make_shared<Tensor>(
+            Array2D<float, 3, 3>({{{58.0, 62.0, 66.0},
+                                   {70.0, 74.0, 78.0},
+                                   {82.0, 86.0, 90.0}}}));
+
+        for (const auto T : {T0, T1, newGrad, expectedGrad0, expectedGrad1}) {
+            T->setBackend("cpu");
+            T->setDataType(DataType::Float32);
+        }
+
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+        op->getOutput(0)->setGrad(newGrad);
+        op->forwardDims();
+
+        myMul->backward();
+
+        REQUIRE(approxEq<float>(*(op->getInput(0)->grad()), *expectedGrad0));
+        REQUIRE(approxEq<float>(*(op->getInput(1)->grad()), *expectedGrad1));
+    }
+
+    SECTION("Case 4: 3D and 2D tensors") {
+        const auto T0 = std::make_shared<Tensor>(
+            Array3D<float, 2, 3, 4>({{{
+                                          {1.0, 2.0, 3.0, 4.0},
+                                          {5.0, 6.0, 7.0, 8.0},
+                                          {9.0, 10.0, 11.0, 12.0},
+                                      },
+                                      {
+                                          {13.0, 14.0, 15.0, 16.0},
+                                          {17.0, 18.0, 19.0, 20.0},
+                                          {21.0, 22.0, 23.0, 24.0},
+                                      }}}));
+
+        const auto T1 = std::make_shared<Tensor>(
+            Array2D<float, 3, 4>({{{0.1, 0.2, 0.3, 0.4},
+                                   {0.5, 0.6, 0.7, 0.8},
+                                   {0.9, 1.0, 1.1, 1.2}}}));
+
+        const auto newGrad = std::make_shared<Tensor>(
+            Array3D<float, 2, 3, 4>({{{
+                                          {1.0, 1.0, 1.0, 1.0},
+                                          {1.0, 1.0, 1.0, 1.0},
+                                          {1.0, 1.0, 1.0, 1.0},
+                                      },
+                                      {
+                                          {1.0, 1.0, 1.0, 1.0},
+                                          {1.0, 1.0, 1.0, 1.0},
+                                          {1.0, 1.0, 1.0, 1.0},
+                                      }}}));
+
+        const auto expectedGrad0 = std::make_shared<Tensor>(
+            Array3D<float, 2, 3, 4>({{{{0.1, 0.2, 0.3, 0.4},
+                                       {0.5, 0.6, 0.7, 0.8},
+                                       {0.9, 1.0, 1.1, 1.2}},
+                                      {{0.1, 0.2, 0.3, 0.4},
+                                       {0.5, 0.6, 0.7, 0.8},
+                                       {0.9, 1.0, 1.1, 1.2}}}}));
+
+        const auto expectedGrad1 = std::make_shared<Tensor>(
+            Array2D<float, 3, 4>({{{14.0, 16.0, 18.0, 20.0},
+                                   {22.0, 24.0, 26.0, 28.0},
+                                   {30.0, 32.0, 34.0, 36.0}}}));
+
+        for (const auto T : {T0, T1, newGrad, expectedGrad0, expectedGrad1}) {
+            T->setBackend("cpu");
+            T->setDataType(DataType::Float32);
+        }
+
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+        op->getOutput(0)->setGrad(newGrad);
+        op->forwardDims();
+
+        myMul->backward();
+
+        REQUIRE(approxEq<float>(*(op->getInput(0)->grad()), *expectedGrad0));
+        REQUIRE(approxEq<float>(*(op->getInput(1)->grad()), *expectedGrad1));
+    }
+
+    SECTION("Case 5: Tensors with random values") {
+
+        // Use random values
+        std::vector<std::size_t> dims0 = {5, 2, 1, 7}; // First tensor
+        std::vector<std::size_t> dims1 = {2, 6, 7};    // Second tensor
+        std::vector<std::size_t> outputDims = {5, 2, 6, 7};
+
+        const auto input0Size = 5 * 2 * 1 * 7;
+        const auto input1Size = 2 * 6 * 7;
+        const auto outputSize = 5 * 2 * 6 * 7;
+
+        std::random_device rd;
+        std::mt19937 gen(rd());
+        std::uniform_real_distribution<float> dist(0.1f, 1.0f);
+
+        std::vector<float> input0Data(input0Size);
+        std::vector<float> input1Data(input1Size);
+
+        // Fill with random values
+        for (auto &val : input0Data) {
+            val = dist(gen);
+        }
+        for (auto &val : input1Data) {
+            val = dist(gen);
+        }
+
+        auto T0 = std::make_shared<Tensor>();
+        auto T1 = std::make_shared<Tensor>();
+
+        T0->setDataType(DataType::Float32);
+        T0->setBackend("cpu");
+        T0->resize(dims0);
+        T0->getImpl()->setRawPtr(input0Data.data(), input0Size);
+
+        T1->setDataType(DataType::Float32);
+        T1->setBackend("cpu");
+        T1->resize(dims1);
+        T1->getImpl()->setRawPtr(input1Data.data(), input1Size);
+
+        op->associateInput(0, T0);
+        op->associateInput(1, T1);
+
+        op->forwardDims();
+        myMul->forward();
+
+        std::vector<float> expectedOutput(outputSize);
+
+        for (std::size_t n = 0; n < 5; ++n) {
+            for (std::size_t c = 0; c < 2; ++c) {
+                for (std::size_t h = 0; h < 6; ++h) {
+                    for (std::size_t w = 0; w < 7; ++w) {
+                        std::size_t outIdx = w + 7 * (h + 6 * (c + 2 * n));
+                        std::size_t in0Idx =
+                            w + 7 * (0 + 1 * (c + 2 * n)); // middle dim is 1
+                        std::size_t in1Idx =
+                            w + 7 * (h + 6 * c);           // no n dimension
+
+                        expectedOutput[outIdx] =
+                            input0Data[in0Idx] * input1Data[in1Idx];
+                    }
+                }
+            }
+        }
+
+        auto outputTensor = op->getOutput(0);
+
+        // Verify forward pass
+        auto expectedOutputTensor = std::make_shared<Tensor>();
+        expectedOutputTensor->resize(outputDims);
+        expectedOutputTensor->setBackend("cpu");
+        expectedOutputTensor->setDataType(DataType::Float32);
+        expectedOutputTensor->getImpl()->setRawPtr(expectedOutput.data(),
+                                                     expectedOutput.size());
+
+        REQUIRE(approxEq<float>(*outputTensor, *expectedOutputTensor));
+
+        // Backward pass
+        std::vector<float> gradOutputData(outputSize);
+        for (auto &val : gradOutputData) {
+            val = dist(gen);
+        }
+
+        op->getOutput(0)->setGrad(std::make_shared<Tensor>());
+        op->getOutput(0)->grad()->resize(outputDims);
+        op->getOutput(0)->grad()->getImpl()->setRawPtr(gradOutputData.data(),
+                                                       outputSize);
+
+        // Compute reference gradients
+        std::vector<float> expectedGrad0(input0Size, 0.0f);
+        std::vector<float> expectedGrad1(input1Size, 0.0f);
+
+        for (std::size_t n = 0; n < 5; ++n) {
+            for (std::size_t c = 0; c < 2; ++c) {
+                for (std::size_t h = 0; h < 6; ++h) {
+                    for (std::size_t w = 0; w < 7; ++w) {
+                        std::size_t outIdx = w + 7 * (h + 6 * (c + 2 * n));
+                        std::size_t in0Idx = w + 7 * (0 + 1 * (c + 2 * n));
+                        std::size_t in1Idx = w + 7 * (h + 6 * c);
+
+                        // Gradient for input0: grad_output * input1
+                        expectedGrad0[in0Idx] +=
+                            gradOutputData[outIdx] * input1Data[in1Idx];
+
+                        // Gradient for input1: grad_output * input0
+                        expectedGrad1[in1Idx] +=
+                            gradOutputData[outIdx] * input0Data[in0Idx];
+                    }
+                }
+            }
+        }
+
+        // Perform backward pass
+        myMul->backward();
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
 
         auto expectedGrad0Tensor = std::make_shared<Tensor>();
         expectedGrad0Tensor->resize(T0->dims());
@@ -289,7 +923,12 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
         expectedGrad0Tensor->getImpl()->setRawPtr(expectedGrad0.data(),
                                                     expectedGrad0.size());
 
+<<<<<<< HEAD
         auto expectedGrad1Tensor = std::make_shared<Tensor>(T1->dims());
+=======
+        auto expectedGrad1Tensor = std::make_shared<Tensor>();
+        expectedGrad1Tensor->resize(T1->dims());
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
         expectedGrad1Tensor->setBackend("cpu");
         expectedGrad1Tensor->setDataType(DataType::Float32);
         expectedGrad1Tensor->getImpl()->setRawPtr(expectedGrad1.data(),
@@ -309,6 +948,10 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
         //           ")\n";
         // std::cout << "Input sizes: " << input0_size << " * " <<
         // input1_size << " -> " << output_size << "\n";
+<<<<<<< HEAD
+=======
+>>>>>>> 9d427c111c3c37ad141cd12a30c851f7fdf6a8fe
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
     }
 }
 
@@ -326,7 +969,17 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
                                                           std::size_t(3));
     std::uniform_int_distribution<int> boolDist(0, 1);
 
+<<<<<<< HEAD
     std::shared_ptr<Mul_Op> op = std::make_shared<Mul_Op>();
+=======
+<<<<<<< HEAD
+    // Create MatMul Operator
+    std::shared_ptr<Mul_Op> op = std::make_shared<Mul_Op>();
+=======
+    std::shared_ptr<Node> myMul = Mul();
+    auto op = std::static_pointer_cast<OperatorTensor>(myMul->getOperator());
+>>>>>>> 9d427c111c3c37ad141cd12a30c851f7fdf6a8fe
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
     op->setDataType(DataType::Float32);
     op->setBackend("cpu");
 
@@ -409,8 +1062,20 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
                 delete[] array1;
                 delete[] result;
             }
+<<<<<<< HEAD
             Log::info("number of elements over time spent: {}\n", (number_of_operation / duration.count()));
             Log::info("total time: {}μs\n", duration.count());
+=======
+<<<<<<< HEAD
+            Log::info("number of elements over time spent: {}\n", (number_of_operation / duration.count()));
+            Log::info("total time: {} μs\n", duration.count());
+=======
+            std::cout << "number of elements over time spent: "
+                      << (number_of_operation / duration.count()) << std::endl;
+            std::cout << "total time: " << duration.count() << "μs"
+                      << std::endl;
+>>>>>>> 9d427c111c3c37ad141cd12a30c851f7fdf6a8fe
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
         }
 
         SECTION("+1-D Tensor / +1-D Tensor - broadcasting") {
@@ -564,8 +1229,20 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
                                     std::multiplies<std::size_t>());
                 number_of_operation += nb_elements;
             }
+<<<<<<< HEAD
             Log::info("number of elements over time spent: {}\n", (number_of_operation / duration.count()));
             Log::info("total time: {}μs\n", duration.count());
+=======
+<<<<<<< HEAD
+            Log::info("number of elements over time spent: {}\n", (number_of_operation / duration.count()));
+            Log::info("total time: {} μs\n", duration.count());
+=======
+            std::cout << "number of elements over time spent: "
+                      << (number_of_operation / duration.count()) << std::endl;
+            std::cout << "total time: " << duration.count() << "μs"
+                      << std::endl;
+>>>>>>> 9d427c111c3c37ad141cd12a30c851f7fdf6a8fe
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
         }
         SECTION("+1-D Tensor / 1-D Tensor") {
             std::size_t number_of_operation = 0;
@@ -702,8 +1379,20 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
                 number_of_operation += nb_elements;
             }
 
+<<<<<<< HEAD
             Log::info("number of elements over time spent: {}\n", (number_of_operation / duration.count()));
             Log::info("total time: {}μs\n", duration.count());
+=======
+<<<<<<< HEAD
+            Log::info("number of elements over time spent: {}\n", (number_of_operation / duration.count()));
+            Log::info("total time: {} μs\n", duration.count());
+=======
+            std::cout << "number of elements over time spent: "
+                      << (number_of_operation / duration.count()) << std::endl;
+            std::cout << "total time: " << duration.count() << "μs"
+                      << std::endl;
+>>>>>>> 9d427c111c3c37ad141cd12a30c851f7fdf6a8fe
+>>>>>>> 30d2af827763a1f1b36c3fe7b152cd4566b3540c
         }
     }
 }