diff --git a/include/aidge/backend/cpu/operator/PadImpl.hpp b/include/aidge/backend/cpu/operator/PadImpl.hpp
index bc0bd8cad3b630b89f728d78b59652f31bbcf410..a36ddab71ea41a64483384c9427a1876f891de7c 100644
--- a/include/aidge/backend/cpu/operator/PadImpl.hpp
+++ b/include/aidge/backend/cpu/operator/PadImpl.hpp
@@ -54,9 +54,19 @@ using PadImpl2D_cpu = OperatorImpl_cpu<Pad_Op<2>,
                             const void *,
                             void *)>;
 
+using Pad3D_Op = Pad_Op<3>;
+using PadImpl3D_cpu = OperatorImpl_cpu<Pad_Op<3>,
+    void(const std::array<DimSize_t, 6>&,
+                            const PadBorderType,
+                            const double,
+                            const std::array<DimSize_t, 5> &,
+                            const void *,
+                            void *)>;
+
 // Implementation entry point registration to Operator
 REGISTRAR(Pad1D_Op, "cpu", Aidge::PadImpl1D_cpu::create);
 REGISTRAR(Pad2D_Op, "cpu", Aidge::PadImpl2D_cpu::create);
+REGISTRAR(Pad3D_Op, "cpu", Aidge::PadImpl3D_cpu::create);
 }  // namespace Aidge
 
 #endif /* AIDGE_CPU_OPERATOR_PADIMPL_H_ */
diff --git a/include/aidge/backend/cpu/operator/PadImpl_kernels.hpp b/include/aidge/backend/cpu/operator/PadImpl_kernels.hpp
index 6d218cb1d719e8576f6c013ac5a1b9c60a739852..0c1936505632f0973c08922b2645224a86085c02 100644
--- a/include/aidge/backend/cpu/operator/PadImpl_kernels.hpp
+++ b/include/aidge/backend/cpu/operator/PadImpl_kernels.hpp
@@ -12,16 +12,27 @@
 #ifndef AIDGE_CPU_OPERATOR_PADIMPL_KERNELS_H_
 #define AIDGE_CPU_OPERATOR_PADIMPL_KERNELS_H_
 
-#include <algorithm>  // std::max, std::min
+#include <aidge/operator/Pad.hpp>
+#include <aidge/utils/ErrorHandling.hpp>
+#include <algorithm> // std::max, std::min
 #include <array>
-#include <cstddef>    // std::size_t
-#include <cstdint>    // std::int32_t
+#include <cmath>
+#include <cstddef>   // std::size_t
+#include <cstdint>   // std::int32_t
+#include <fmt/base.h>
+#include <stdexcept>
+#include <type_traits>
 
 #include "aidge/backend/cpu/operator/PadImpl.hpp"
 #include "aidge/utils/Registrar.hpp"
 #include "aidge/utils/Types.h"
 
 namespace Aidge {
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// PAD 1D
+////////////////////////////////////////////////////////////////////////////////////////////////
+
 /**
  * @brief Forward kernel for 1D Padding on CPU backend.
  * @tparam I Input data type.
@@ -187,6 +198,368 @@ REGISTRAR(PadImpl2D_cpu,
 REGISTRAR(PadImpl2D_cpu,
     {{DataType::Int32, DataFormat::NCHW}, {DataType::Int32, DataFormat::NCHW}},
     {Pad_ProdConso_cpu::defaultModel, Aidge::PadImpl2D_cpu_forward_kernel<cpptype_t<DataType::Int32>, cpptype_t<DataType::Int32>>, nullptr});
-}  // namespace Aidge
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// PAD 3D
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+template <typename I, typename O>
+static inline void
+pad3DForwardConstant(const std::array<DimSize_t, 6> &beginEndBorders,
+                     const O borderValue,
+                     const std::array<DimSize_t, 5> &iDims,
+                     const std::array<DimSize_t, 4> &iStrides,
+                     std::array<DimSize_t, 4> &iOffsets,
+                     const I *input,
+                     const std::array<DimSize_t, 3> &oDims,
+                     const std::array<DimSize_t, 4> &oStrides,
+                     std::array<DimSize_t, 4> &oOffsets,
+                     O *output) {
+
+    for (DimSize_t oX = 0; oX < oDims[0]; ++oX) {
+        oOffsets[2] = oX * oStrides[2] + oOffsets[1];
+
+        const SignedDimSize_t iX = oX - beginEndBorders[0];
+        if (iX >= 0 && iX < static_cast<SignedDimSize_t>(iDims[2])) {
+            iOffsets[2] = iX * iStrides[2] + iOffsets[1];
+        } else {
+            std::fill(output + oOffsets[2],
+                      output + oOffsets[2] + oStrides[2],
+                      borderValue);
+            continue;
+        }
+
+        for (DimSize_t oY = 0; oY < oDims[1]; ++oY) {
+            oOffsets[3] = oY * oStrides[3] + oOffsets[2];
+            const SignedDimSize_t iY = oY - beginEndBorders[1];
+            if (iY >= 0 && iY < static_cast<SignedDimSize_t>(iDims[3])) {
+                iOffsets[3] = iY * iStrides[3] + iOffsets[2];
+            } else {
+                std::fill(output + oOffsets[3],
+                          output + oOffsets[3] + oStrides[3],
+                          borderValue);
+                continue;
+            }
+
+            for (DimSize_t oZ = 0; oZ < oDims[2]; ++oZ) {
+                const SignedDimSize_t iZ = oZ - beginEndBorders[2];
+                // if in bounds, takes corresponding value, otherwise takes
+                // default value
+                output[oOffsets[3] + oZ] =
+                    (iZ >= 0 && iZ < static_cast<SignedDimSize_t>(iDims[4]))
+                        ? input[iOffsets[3] + iZ]
+                        : borderValue;
+            }
+        }
+    }
+}
+
+/**
+ * @brief small inline fctn to generate the corresponding input coordinates of
+ * an output coord in edge padding along a given dimension.
+ * @param[in] beginBorder Padding at the beginning of given dimension.
+ * @param[in] iDim Size of given dimension
+ * @param[in] oCoord output coord along given dimension
+ */
+static inline DimSize_t padEdgeComputeInputCoord(const DimSize_t beginBorder,
+                                                 const DimSize_t iDim,
+                                                 const DimSize_t oCoord) {
+    return static_cast<DimSize_t>(std::max(
+        static_cast<SignedDimSize_t>(0),
+        std::min(static_cast<SignedDimSize_t>(iDim - 1),
+                 static_cast<SignedDimSize_t>(oCoord - beginBorder))));
+}
+
+template <typename I, typename O>
+static inline void
+pad3DForwardEdge(const std::array<DimSize_t, 6> &beginEndBorders,
+                 const std::array<DimSize_t, 5> &iDims,
+                 const std::array<DimSize_t, 4> &iStrides,
+                 std::array<DimSize_t, 4> &iOffsets,
+                 const I *input,
+                 const std::array<DimSize_t, 3> &oDims,
+                 const std::array<DimSize_t, 4> &oStrides,
+                 std::array<DimSize_t, 4> &oOffsets,
+                 O *output) {
+    for (DimSize_t oX = 0; oX < oDims[0]; ++oX) {
+        oOffsets[2] = oX * oStrides[2] + oOffsets[1];
+        const DimSize_t iX =
+            padEdgeComputeInputCoord(beginEndBorders[0], iDims[2], oX);
+        iOffsets[2] = iX * iStrides[2] + iOffsets[1];
+
+        for (DimSize_t oY = 0; oY < oDims[1]; ++oY) {
+            oOffsets[3] = oY * oStrides[3] + oOffsets[2];
+            const DimSize_t iY =
+                padEdgeComputeInputCoord(beginEndBorders[1], iDims[3], oY);
+            iOffsets[3] = iY * iStrides[3] + iOffsets[2];
+
+            for (DimSize_t oZ = 0; oZ < oDims[2]; ++oZ) {
+                const DimSize_t iZ =
+                    padEdgeComputeInputCoord(beginEndBorders[2], iDims[4], oZ);
+
+                output[oOffsets[3] + oZ] = input[iOffsets[3] + iZ];
+            }
+        }
+    }
+}
+
+/**
+ * @brief small inline fctn to generate the corresponding input coordinates of
+ * an output coord in reflect padding along a given dimension.
+ * @param[in] beginBorder Padding at the beginning of given dimension.
+ * @param[in] iDim Size of given dimension
+ * @param[in] oCoord output coord along given dimension
+ */
+static inline DimSize_t
+padReflectComputeInputCoord(const DimSize_t beginBorder,
+                            const DimSize_t iDim,
+                            const DimSize_t oCoord) {
+    SignedDimSize_t iCoord =
+        std::abs(static_cast<SignedDimSize_t>(oCoord - beginBorder));
+
+    // Handle case where iCoord > iDim
+    // If so iCoord must be changed to (iDim - 1) - delta
+    // With delta = |iDim - 1 - icoord|
+    //
+    // Since iCoord > iDim - 1, |(iDim - 1) - iCoord| <=> iCoord - (iDim - 1)
+    // <=> iCoord + 1 - iDim
+    // Hence iDim - 1 - delta <=> iDim - 1 - (iCoord + 1 - iDim)
+    // <=> 2 * (iDim - 1) - iCoord
+    iCoord = (iCoord >= static_cast<SignedDimSize_t>(iDim))
+                 ? static_cast<SignedDimSize_t>(iDim + iDim - 2) - iCoord
+                 : iCoord;
+    return iCoord;
+}
+
+template <typename I, typename O>
+static inline void
+pad3DForwardReflect(const std::array<DimSize_t, 6> &beginEndBorders,
+                    const std::array<DimSize_t, 5> &iDims,
+                    const std::array<DimSize_t, 4> &iStrides,
+                    std::array<DimSize_t, 4> &iOffsets,
+                    const I *input,
+                    const std::array<DimSize_t, 3> &oDims,
+                    const std::array<DimSize_t, 4> &oStrides,
+                    std::array<DimSize_t, 4> &oOffsets,
+                    O *output) {
+
+    for (DimSize_t oX = 0; oX < oDims[0]; ++oX) {
+        oOffsets[2] = oX * oStrides[2] + oOffsets[1];
+        DimSize_t iX =
+            padReflectComputeInputCoord(beginEndBorders[0], iDims[2], oX);
+        iOffsets[2] = iX * iStrides[2] + iOffsets[1];
+
+        for (DimSize_t oY = 0; oY < oDims[1]; ++oY) {
+            oOffsets[3] = oY * oStrides[3] + oOffsets[2];
+            DimSize_t iY =
+                padReflectComputeInputCoord(beginEndBorders[1], iDims[3], oY);
+            iOffsets[3] = iY * iStrides[3] + iOffsets[2];
+
+            for (DimSize_t oZ = 0; oZ < oDims[2]; ++oZ) {
+                DimSize_t iZ = padReflectComputeInputCoord(beginEndBorders[2],
+                                                           iDims[4],
+                                                           oZ);
+                output[oOffsets[3] + oZ] = input[iOffsets[3] + iZ];
+            }
+        }
+    }
+}
+
+/**
+ * @brief small inline fctn to generate the corresponding input coordinates of
+ * an output coord in wrap padding along a given dimension.
+ * @param[in] beginBorder Padding at the beginning of given dimension.
+ * @param[in] iDim Size of given dimension
+ * @param[in] oCoord output coord along given dimension
+ */
+static inline DimSize_t padWrapComputeInputCoord(const DimSize_t beginBorder,
+                                                 const DimSize_t iDim,
+                                                 const DimSize_t oCoord) {
+    return (iDim + oCoord - beginBorder) % iDim;
+}
+
+template <typename I, typename O>
+static inline void
+pad3DForwardWrap(const std::array<DimSize_t, 6> &beginEndBorders,
+                 const std::array<DimSize_t, 5> &iDims,
+                 const std::array<DimSize_t, 4> &iStrides,
+                 std::array<DimSize_t, 4> &iOffsets,
+                 const I *input,
+                 const std::array<DimSize_t, 3> &oDims,
+                 const std::array<DimSize_t, 4> &oStrides,
+                 std::array<DimSize_t, 4> &oOffsets,
+                 O *output) {
+    for (DimSize_t oX = 0; oX < oDims[0]; ++oX) {
+        oOffsets[2] = oX * oStrides[2] + oOffsets[1];
+
+        const DimSize_t iX =
+            padWrapComputeInputCoord(beginEndBorders[0], iDims[2], oX);
+        iOffsets[2] = iX * iStrides[2] + iOffsets[1];
+
+        for (DimSize_t oY = 0; oY < oDims[1]; ++oY) {
+            oOffsets[3] = oY * oStrides[3] + oOffsets[2];
+
+            const DimSize_t iY =
+                padWrapComputeInputCoord(beginEndBorders[1], iDims[3], oY);
+
+            iOffsets[3] = iY * iStrides[3] + iOffsets[2];
+
+            for (DimSize_t oZ = 0; oZ < oDims[2]; ++oZ) {
+                const DimSize_t iZ =
+                    padWrapComputeInputCoord(beginEndBorders[2], iDims[4], oZ);
+                output[oOffsets[3] + oZ] = input[iOffsets[3] + iZ];
+            }
+        }
+    }
+}
+
+/**
+ * @brief Forward kernel for 2D Padding on CPU backend.
+ * @tparam I Input data type.
+ * @tparam O Output data type.
+ * @param attrs tuple of Parameters from the Operator
+ * @param iDims Array of input dimensions.
+ * @param input_ const input Tensor.
+ * @param output_ Output Tensor.
+ */
+template <class I, class O>
+void PadImpl3D_cpu_forward_kernel(
+    const std::array<DimSize_t, 6> &beginEndBorders,
+    const PadBorderType borderType,
+    const double borderValue,
+    const std::array<DimSize_t, 5> &iDims,
+    const void *input_,
+    void *output_) {
+    const I *input = static_cast<const I *>(input_);
+    O *output = static_cast<O *>(output_);
+
+    // not taking in count batch & channel as they are identical to iDims
+    const std::array<DimSize_t, 3> oDims = {
+        iDims[2] + beginEndBorders[0] + beginEndBorders[3],
+        iDims[3] + beginEndBorders[1] + beginEndBorders[4],
+        iDims[4] + beginEndBorders[2] + beginEndBorders[5]};
+
+    const std::array<DimSize_t, 4> oStrides = {
+        iDims[1] * oDims[0] * oDims[1] * oDims[2],
+        oDims[0] * oDims[1] * oDims[2],
+        oDims[1] * oDims[2],
+        oDims[2],
+    };
+    const std::array<DimSize_t, 4> iStrides = {
+        iDims[1] * iDims[2] * iDims[3] * iDims[4],
+        iDims[2] * iDims[3] * iDims[4],
+        iDims[3] * iDims[4],
+        iDims[4],
+    };
+
+    std::array<DimSize_t, 4> oOffsets = {0, 0, 0, 0};
+    std::array<DimSize_t, 4> iOffsets = {0, 0, 0, 0};
+
+    for (std::size_t batch = 0; batch < iDims[0]; ++batch) {
+        oOffsets[0] = batch * oStrides[0];
+        iOffsets[0] = batch * iStrides[0];
+
+        for (std::size_t ch = 0; ch < iDims[1]; ++ch) {
+            iOffsets[1] = ch * iStrides[1] + iOffsets[0];
+            oOffsets[1] = ch * oStrides[1] + oOffsets[0];
+
+            switch (borderType) {
+            case PadBorderType::Constant: {
+                pad3DForwardConstant(beginEndBorders,
+                                     static_cast<O>(borderValue),
+                                     iDims,
+                                     iStrides,
+                                     iOffsets,
+                                     input,
+                                     oDims,
+                                     oStrides,
+                                     oOffsets,
+                                     output);
+                break;
+            }
+            case PadBorderType::Zero: {
+                pad3DForwardConstant(beginEndBorders,
+                                     static_cast<O>(0),
+                                     iDims,
+                                     iStrides,
+                                     iOffsets,
+                                     input,
+                                     oDims,
+                                     oStrides,
+                                     oOffsets,
+                                     output);
+                break;
+            }
+            case PadBorderType::Edge: {
+                pad3DForwardEdge(beginEndBorders,
+                                 iDims,
+                                 iStrides,
+                                 iOffsets,
+                                 input,
+                                 oDims,
+                                 oStrides,
+                                 oOffsets,
+                                 output);
+                break;
+            }
+            case PadBorderType::Reflect: {
+                pad3DForwardReflect(beginEndBorders,
+                                    iDims,
+                                    iStrides,
+                                    iOffsets,
+                                    input,
+                                    oDims,
+                                    oStrides,
+                                    oOffsets,
+                                    output);
+                break;
+            }
+            case PadBorderType::Wrap: {
+                pad3DForwardWrap(beginEndBorders,
+                                 iDims,
+                                 iStrides,
+                                 iOffsets,
+                                 input,
+                                 oDims,
+                                 oStrides,
+                                 oOffsets,
+                                 output);
+                break;
+            }
+            default: {
+                AIDGE_THROW_OR_ABORT(
+                    std::runtime_error,
+                    "Pad3D : unsupported padding method : {}.",
+                    borderType);
+            }
+            }
+        }
+    }
+}
+
+// Kernels registration to implementation entry point
+REGISTRAR(PadImpl3D_cpu,
+          {{DataType::Float32, DataFormat::NCHW},
+           {DataType::Float32, DataFormat::NCHW}},
+          {Pad_ProdConso_cpu::defaultModel,
+           Aidge::PadImpl3D_cpu_forward_kernel<cpptype_t<DataType::Float32>,
+                                               cpptype_t<DataType::Float32>>,
+           nullptr});
+
+REGISTRAR(PadImpl3D_cpu,
+          {{DataType::Float64, DataFormat::NCHW},
+           {DataType::Float64, DataFormat::NCHW}},
+          {Pad_ProdConso_cpu::defaultModel,
+           Aidge::PadImpl3D_cpu_forward_kernel<cpptype_t<DataType::Float64>,
+                                               cpptype_t<DataType::Float64>>,
+           nullptr});
+REGISTRAR(PadImpl3D_cpu,
+          {{DataType::Int32, DataFormat::NCHW},
+           {DataType::Int32, DataFormat::NCHW}},
+          {Pad_ProdConso_cpu::defaultModel,
+           Aidge::PadImpl3D_cpu_forward_kernel<cpptype_t<DataType::Int32>,
+                                               cpptype_t<DataType::Int32>>,
+           nullptr});
+} // namespace Aidge
 
 #endif /* AIDGE_CPU_OPERATOR_PADIMPL_KERNELS_H_ */
diff --git a/src/operator/PadImpl.cpp b/src/operator/PadImpl.cpp
index 9a54437f445a1842b2f97555a0cbea8988acf50a..30f53def1a7e2f48fa0118a1fba7681b2b8dbcbc 100644
--- a/src/operator/PadImpl.cpp
+++ b/src/operator/PadImpl.cpp
@@ -74,3 +74,26 @@ template <>
 void Aidge::PadImpl2D_cpu::backward() {
     AIDGE_THROW_OR_ABORT(std::runtime_error, "Backward not yet implemented for Pad_Op<2> on backend cpu");
 }
+
+
+template <>
+void Aidge::PadImpl3D_cpu::forward() {
+    const auto& op_ = dynamic_cast<const Pad_Op<3>&>(mOp);
+    AIDGE_ASSERT(op_.getInput(0), "missing input #0 in Pad Operator.");
+
+    // Find the correct kernel type
+    const auto impl = Registrar<PadImpl3D_cpu>::create(getBestMatch(getRequiredSpec()));
+
+    // Call kernel
+    impl.forward(op_.beginEndBorders(),
+                op_.borderType(),
+                op_.borderValue(),
+                op_.getInput(0)->template dims<5>(),
+                getCPUPtr(mOp.getRawInput(0)),
+                getCPUPtr(mOp.getRawOutput(0)));
+}
+
+template <>
+void Aidge::PadImpl3D_cpu::backward() {
+    AIDGE_THROW_OR_ABORT(std::runtime_error, "Backward not yet implemented for Pad_Op<2> on backend cpu");
+}
diff --git a/unit_tests/operator/Test_PadImpl.cpp b/unit_tests/operator/Test_PadImpl.cpp
index f7823d022c8d3b228740a3df3f1d01224cd346c6..5efc5bd36fb582cb2cf27ba739064fbd410a0751 100644
--- a/unit_tests/operator/Test_PadImpl.cpp
+++ b/unit_tests/operator/Test_PadImpl.cpp
@@ -9,6 +9,9 @@
  *
  ********************************************************************************/
 
+#include <aidge/utils/ArrayHelpers.hpp>
+#include <aidge/utils/TensorUtils.hpp>
+#include <aidge/utils/Types.h>
 #include <memory>
 
 #include <catch2/catch_test_macros.hpp>
@@ -22,550 +25,694 @@
 
 using namespace Aidge;
 
-TEST_CASE("[cpu/operator] Pad(forward)", "[Pad][CPU]") {
-    SECTION("Symmetric Pad") {
-        const int pv = 0; // pad value
-
-        std::shared_ptr<Node> myPad = Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Constant, static_cast<double>(pv));
-        auto op = std::static_pointer_cast<OperatorTensor>(myPad -> getOperator());
-        std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array4D<int,2,3,5,5> { //NCHW
-            {
-                {
-                    {{  0,   1,   2,   3,   4},
-                    {  5,   6,   7,   8,   9},
-                    { 10,  11,  12,  13,  14},
-                    { 15,  16,  17,  18,  19},
-                    { 20,  21,  22,  23,  24}},
-
-                    {{ 25,  26,  27,  28,  29},
-                    { 30,  31,  32,  33,  34},
-                    { 35,  36,  37,  38,  39},
-                    { 40,  41,  42,  43,  44},
-                    { 45,  46,  47,  48,  49}},
-
-                    {{ 50,  51,  52,  53,  54},
-                    { 55,  56,  57,  58,  59},
-                    { 60,  61,  62,  63,  64},
-                    { 65,  66,  67,  68,  69},
-                    { 70,  71,  72,  73,  74}}
-                },
-                {
-                    {{ 75,  76,  77,  78,  79},
-                    { 80,  81,  82,  83,  84},
-                    { 85,  86,  87,  88,  89},
-                    { 90,  91,  92,  93,  94},
-                    { 95,  96,  97,  98,  99}},
-
-                    {{100, 101, 102, 103, 104},
-                    {105, 106, 107, 108, 109},
-                    {110, 111, 112, 113, 114},
-                    {115, 116, 117, 118, 119},
-                    {120, 121, 122, 123, 124}},
-
-                    {{125, 126, 127, 128, 129},
-                    {130, 131, 132, 133, 134},
-                    {135, 136, 137, 138, 139},
-                    {140, 141, 142, 143, 144},
-                    {145, 146, 147, 148, 149}}
-                }
-            }
-        });
-        std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array4D<int,2,3,7,7> { //NCHW
-            {
-                {
-                    {{ pv,  pv,   pv,   pv,   pv,   pv,  pv},
-                    { pv,   0,   1,   2,   3,   4,  pv},
-                    { pv,   5,   6,   7,   8,   9,  pv},
-                    { pv,  10,  11,  12,  13,  14,  pv},
-                    { pv,  15,  16,  17,  18,  19,  pv},
-                    { pv,  20,  21,  22,  23,  24,  pv},
-                    { pv,  pv,   pv,   pv,   pv,   pv,  pv}},
-
-                    {{ pv,  pv,   pv,   pv,   pv,   pv,  pv},
-                    { pv,  25,  26,  27,  28,  29,  pv},
-                    { pv,  30,  31,  32,  33,  34,  pv},
-                    { pv,  35,  36,  37,  38,  39,  pv},
-                    { pv,  40,  41,  42,  43,  44,  pv},
-                    { pv,  45,  46,  47,  48,  49,  pv},
-                    { pv,  pv,   pv,   pv,   pv,   pv,  pv}},
-
-                    {{ pv,  pv,   pv,   pv,   pv,   pv,  pv},
-                    { pv,  50,  51,  52,  53,  54,  pv},
-                    { pv,  55,  56,  57,  58,  59,  pv},
-                    { pv,  60,  61,  62,  63,  64,  pv},
-                    { pv,  65,  66,  67,  68,  69,  pv},
-                    { pv,  70,  71,  72,  73,  74,  pv},
-                    { pv,  pv,   pv,   pv,   pv,   pv,  pv}}
-                },
-                {
-                    {{ pv,  pv,   pv,   pv,   pv,   pv,  pv},
-                    { pv,  75,  76,  77,  78,  79,  pv},
-                    { pv,  80,  81,  82,  83,  84,  pv},
-                    { pv,  85,  86,  87,  88,  89,  pv},
-                    { pv,  90,  91,  92,  93,  94,  pv},
-                    { pv,  95,  96,  97,  98,  99,  pv},
-                    { pv,  pv,   pv,   pv,   pv,   pv,  pv}},
-
-                    {{ pv,  pv,   pv,   pv,   pv,   pv,  pv},
-                    {pv,  100, 101, 102, 103, 104,  pv},
-                    {pv,  105, 106, 107, 108, 109,  pv},
-                    {pv,  110, 111, 112, 113, 114,  pv},
-                    {pv,  115, 116, 117, 118, 119,  pv},
-                    {pv,  120, 121, 122, 123, 124,  pv},
-                    { pv,  pv,   pv,   pv,   pv,   pv,  pv}},
-
-                    {{ pv,  pv,   pv,   pv,   pv,   pv,  pv},
-                    {pv,  125, 126, 127, 128, 129,  pv},
-                    {pv,  130, 131, 132, 133, 134,  pv},
-                    {pv,  135, 136, 137, 138, 139,  pv},
-                    {pv,  140, 141, 142, 143, 144,  pv},
-                    {pv,  145, 146, 147, 148, 149,  pv},
-                    { pv,  pv,   pv,   pv,   pv,   pv,  pv}}
-                }
-            }
-        });
-
-        myPad->getOperator()->associateInput(0,myInput);
-        myPad->getOperator()->setDataType(DataType::Int32);
-        myPad->getOperator()->setBackend("cpu");
-        myPad->forward();
-        // myPad->getOperator()->getOutput(0)->print();
-        REQUIRE(*(op->getOutput(0)) == *myOutput);
-    }
+template <DimSize_t DIM>
+static std::shared_ptr<OperatorTensor>
+setupTestPad(std::array<DimSize_t, 2 * DIM> beginEndBorder,
+             const std::shared_ptr<Tensor> input,
+             PadBorderType padType,
+             double borderValue) {
+    input->setBackend("cpu");
+    std::shared_ptr<Node> padNode =
+        Pad<DIM>(beginEndBorder, "pad_op", padType, borderValue);
+    auto op = std::static_pointer_cast<OperatorTensor>(padNode->getOperator());
 
-    SECTION("Asymmetric Pad") {
-        const int pv = 0; // pad value
-
-        std::shared_ptr<Node> myPad = Pad<2>({1, 0, 0, 1}, "mypad", PadBorderType::Constant, static_cast<double>(pv));
-        auto op = std::static_pointer_cast<OperatorTensor>(myPad -> getOperator());
-        std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array4D<int,2,3,5,5> { //NCHW
-            {
-                {
-                    {{  0,   1,   2,   3,   4},
-                    {  5,   6,   7,   8,   9},
-                    { 10,  11,  12,  13,  14},
-                    { 15,  16,  17,  18,  19},
-                    { 20,  21,  22,  23,  24}},
-
-                    {{ 25,  26,  27,  28,  29},
-                    { 30,  31,  32,  33,  34},
-                    { 35,  36,  37,  38,  39},
-                    { 40,  41,  42,  43,  44},
-                    { 45,  46,  47,  48,  49}},
-
-                    {{ 50,  51,  52,  53,  54},
-                    { 55,  56,  57,  58,  59},
-                    { 60,  61,  62,  63,  64},
-                    { 65,  66,  67,  68,  69},
-                    { 70,  71,  72,  73,  74}}
-                },
-                {
-                    {{ 75,  76,  77,  78,  79},
-                    { 80,  81,  82,  83,  84},
-                    { 85,  86,  87,  88,  89},
-                    { 90,  91,  92,  93,  94},
-                    { 95,  96,  97,  98,  99}},
-
-                    {{100, 101, 102, 103, 104},
-                    {105, 106, 107, 108, 109},
-                    {110, 111, 112, 113, 114},
-                    {115, 116, 117, 118, 119},
-                    {120, 121, 122, 123, 124}},
-
-                    {{125, 126, 127, 128, 129},
-                    {130, 131, 132, 133, 134},
-                    {135, 136, 137, 138, 139},
-                    {140, 141, 142, 143, 144},
-                    {145, 146, 147, 148, 149}}
-                }
-            }
-        });
-        std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array4D<int,2,3,6,6> { //NCHW
-            {
-                {
-                    {{ pv,   pv,   pv,   pv,   pv,  pv},
-                    { 0,   1,   2,   3,   4,  pv},
-                    { 5,   6,   7,   8,   9,  pv},
-                    { 10,  11,  12,  13,  14,  pv},
-                    { 15,  16,  17,  18,  19,  pv},
-                    { 20,  21,  22,  23,  24,  pv}},
-
-                    {{ pv,   pv,   pv,   pv,   pv,  pv},
-                    { 25,  26,  27,  28,  29,  pv},
-                    { 30,  31,  32,  33,  34,  pv},
-                    { 35,  36,  37,  38,  39,  pv},
-                    { 40,  41,  42,  43,  44,  pv},
-                    { 45,  46,  47,  48,  49,  pv}},
-
-                    {{ pv,   pv,   pv,   pv,   pv,  pv},
-                    { 50,  51,  52,  53,  54,  pv},
-                    { 55,  56,  57,  58,  59,  pv},
-                    { 60,  61,  62,  63,  64,  pv},
-                    { 65,  66,  67,  68,  69,  pv},
-                    { 70,  71,  72,  73,  74,  pv}}
-                },
-                {
-                    {{ pv,   pv,   pv,   pv,   pv,  pv},
-                    { 75,  76,  77,  78,  79,  pv},
-                    { 80,  81,  82,  83,  84,  pv},
-                    { 85,  86,  87,  88,  89,  pv},
-                    { 90,  91,  92,  93,  94,  pv},
-                    { 95,  96,  97,  98,  99,  pv}},
-
-                    {{ pv,   pv,   pv,   pv,   pv,  pv},
-                    { 100, 101, 102, 103, 104,  pv},
-                    { 105, 106, 107, 108, 109,  pv},
-                    { 110, 111, 112, 113, 114,  pv},
-                    { 115, 116, 117, 118, 119,  pv},
-                    { 120, 121, 122, 123, 124,  pv}},
-
-                    {{ pv,   pv,   pv,   pv,   pv,  pv},
-                    { 125, 126, 127, 128, 129,  pv},
-                    { 130, 131, 132, 133, 134,  pv},
-                    { 135, 136, 137, 138, 139,  pv},
-                    { 140, 141, 142, 143, 144,  pv},
-                    { 145, 146, 147, 148, 149,  pv}}
-                }
-            }
-        });
-
-        myPad->getOperator()->associateInput(0,myInput);
-        myPad->getOperator()->setDataType(DataType::Int32);
-        myPad->getOperator()->setBackend("cpu");
-        myPad->forward();
-        // myPad->getOperator()->getOutput(0)->print();
-        REQUIRE(*(op->getOutput(0)) == *myOutput);
-    }
+    op->setDataType(DataType::Float32);
+    op->setBackend("cpu");
 
-    SECTION("Pad Edge") {
-        std::shared_ptr<Node> myPad = Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Edge);
-        auto op = std::static_pointer_cast<OperatorTensor>(myPad -> getOperator());
-        std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array4D<int,2,3,5,5> { //NCHW
-            {
-                {
-                    {{  0,   1,   2,   3,   4},
-                    {  5,   6,   7,   8,   9},
-                    { 10,  11,  12,  13,  14},
-                    { 15,  16,  17,  18,  19},
-                    { 20,  21,  22,  23,  24}},
-
-                    {{ 25,  26,  27,  28,  29},
-                    { 30,  31,  32,  33,  34},
-                    { 35,  36,  37,  38,  39},
-                    { 40,  41,  42,  43,  44},
-                    { 45,  46,  47,  48,  49}},
-
-                    {{ 50,  51,  52,  53,  54},
-                    { 55,  56,  57,  58,  59},
-                    { 60,  61,  62,  63,  64},
-                    { 65,  66,  67,  68,  69},
-                    { 70,  71,  72,  73,  74}}
-                },
-                {
-                    {{ 75,  76,  77,  78,  79},
-                    { 80,  81,  82,  83,  84},
-                    { 85,  86,  87,  88,  89},
-                    { 90,  91,  92,  93,  94},
-                    { 95,  96,  97,  98,  99}},
-
-                    {{100, 101, 102, 103, 104},
-                    {105, 106, 107, 108, 109},
-                    {110, 111, 112, 113, 114},
-                    {115, 116, 117, 118, 119},
-                    {120, 121, 122, 123, 124}},
-
-                    {{125, 126, 127, 128, 129},
-                    {130, 131, 132, 133, 134},
-                    {135, 136, 137, 138, 139},
-                    {140, 141, 142, 143, 144},
-                    {145, 146, 147, 148, 149}}
-                }
-            }
-        });
-        std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array4D<int,2,3,7,7> { //NCHW
-            {
-                {
-                    {{ 0,  0,   1,   2,   3,   4,  4},
-                    { 0,   0,   1,   2,   3,   4,  4},
-                    { 5,   5,   6,   7,   8,   9,  9},
-                    { 10,  10,  11,  12,  13,  14,  14},
-                    { 15,  15,  16,  17,  18,  19,  19},
-                    { 20,  20,  21,  22,  23,  24,  24},
-                    { 20,  20,  21,  22,  23,  24,  24}},
-
-                    {{ 25,  25,  26,  27,  28,  29,  29},
-                    { 25,  25,  26,  27,  28,  29,  29},
-                    { 30,  30,  31,  32,  33,  34,  34},
-                    { 35,  35,  36,  37,  38,  39,  39},
-                    { 40,  40,  41,  42,  43,  44,  44},
-                    { 45,  45,  46,  47,  48,  49,  49},
-                    { 45,  45,  46,  47,  48,  49, 49}},
-
-                    {{ 50,  50,  51,  52,  53,  54,  54},
-                    { 50,  50,  51,  52,  53,  54,  54},
-                    { 55,  55,  56,  57,  58,  59,  59},
-                    { 60,  60,  61,  62,  63,  64,  64},
-                    { 65,  65,  66,  67,  68,  69,  69},
-                    { 70,  70,  71,  72,  73,  74,  74},
-                    { 70,  70,  71,  72,  73,  74,  74}}
-                },
-                {
-                    {{ 75,  75,  76,  77,  78,  79,  79},
-                    { 75,  75,  76,  77,  78,  79,  79},
-                    { 80,  80,  81,  82,  83,  84,  84},
-                    { 85,  85,  86,  87,  88,  89,  89},
-                    { 90,  90,  91,  92,  93,  94,  94},
-                    { 95,  95,  96,  97,  98,  99,  99},
-                    { 95,  95,  96,  97,  98,  99,  99}},
-
-                    {{100,  100, 101, 102, 103, 104,  104},
-                    {100,  100, 101, 102, 103, 104,  104},
-                    {105,  105, 106, 107, 108, 109, 109},
-                    {110,  110, 111, 112, 113, 114,  114},
-                    {115,  115, 116, 117, 118, 119,  119},
-                    {120,  120, 121, 122, 123, 124,  124},
-                    {120,  120, 121, 122, 123, 124,  124}},
-
-                    {{125,  125, 126, 127, 128, 129,  129},
-                    {125,  125, 126, 127, 128, 129,  129},
-                    {130,  130, 131, 132, 133, 134,  134},
-                    {135,  135, 136, 137, 138, 139,  139},
-                    {140,  140, 141, 142, 143, 144,  144},
-                    {145,  145, 146, 147, 148, 149,  149},
-                    {145,  145, 146, 147, 148, 149,  149}}
-                }
-            }
-        });
-
-        myPad->getOperator()->associateInput(0,myInput);
-        myPad->getOperator()->setDataType(DataType::Int32);
-        myPad->getOperator()->setBackend("cpu");
-        myPad->forward();
-        // myPad->getOperator()->getOutput(0)->print();
-        REQUIRE(*(op->getOutput(0)) == *myOutput);
-    }
+    op->associateInput(0, input);
 
-    SECTION("Pad Reflect") {
-        std::shared_ptr<Node> myPad = Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Reflect);
-        auto op = std::static_pointer_cast<OperatorTensor>(myPad -> getOperator());
-        std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array4D<int,2,3,5,5> { //NCHW
-            {
-                {
-                    {{  0,   1,   2,   3,   4},
-                    {  5,   6,   7,   8,   9},
-                    { 10,  11,  12,  13,  14},
-                    { 15,  16,  17,  18,  19},
-                    { 20,  21,  22,  23,  24}},
-
-                    {{ 25,  26,  27,  28,  29},
-                    { 30,  31,  32,  33,  34},
-                    { 35,  36,  37,  38,  39},
-                    { 40,  41,  42,  43,  44},
-                    { 45,  46,  47,  48,  49}},
-
-                    {{ 50,  51,  52,  53,  54},
-                    { 55,  56,  57,  58,  59},
-                    { 60,  61,  62,  63,  64},
-                    { 65,  66,  67,  68,  69},
-                    { 70,  71,  72,  73,  74}}
-                },
-                {
-                    {{ 75,  76,  77,  78,  79},
-                    { 80,  81,  82,  83,  84},
-                    { 85,  86,  87,  88,  89},
-                    { 90,  91,  92,  93,  94},
-                    { 95,  96,  97,  98,  99}},
-
-                    {{100, 101, 102, 103, 104},
-                    {105, 106, 107, 108, 109},
-                    {110, 111, 112, 113, 114},
-                    {115, 116, 117, 118, 119},
-                    {120, 121, 122, 123, 124}},
-
-                    {{125, 126, 127, 128, 129},
-                    {130, 131, 132, 133, 134},
-                    {135, 136, 137, 138, 139},
-                    {140, 141, 142, 143, 144},
-                    {145, 146, 147, 148, 149}}
-                }
-            }
-        });
-        std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array4D<int,2,3,7,7> { //NCHW
-            {
-                {
-                    {
-                    { 6, 5, 6, 7, 8, 9, 5},
-                    { 1, 0, 1, 2, 3, 4, 0},
-                    { 6, 5, 6, 7, 8, 9, 5},
-                    { 11, 10, 11, 12, 13, 14, 10},
-                    { 16, 15, 16, 17, 18, 19, 15},
-                    { 21, 20, 21, 22, 23, 24, 20},
-                    { 1, 0, 1, 2, 3, 4, 0}
-                    },
-                    {
-                    { 31, 30, 31, 32, 33, 34, 30},
-                    { 26, 25, 26, 27, 28, 29, 25},
-                    { 31, 30, 31, 32, 33, 34, 30},
-                    { 36, 35, 36, 37, 38, 39, 35},
-                    { 41, 40, 41, 42, 43, 44, 40},
-                    { 46, 45, 46, 47, 48, 49, 45},
-                    { 26, 25, 26, 27, 28, 29, 25}
-                    },
-                    {
-                    { 56, 55, 56, 57, 58, 59, 55},
-                    { 51, 50, 51, 52, 53, 54, 50},
-                    { 56, 55, 56, 57, 58, 59, 55},
-                    { 61, 60, 61, 62, 63, 64, 60},
-                    { 66, 65, 66, 67, 68, 69, 65},
-                    { 71, 70, 71, 72, 73, 74, 70},
-                    { 51, 50, 51, 52, 53, 54, 50}
-                    }
-                },
-                {
-                    {
-                    { 81, 80, 81, 82, 83, 84, 80},
-                    { 76, 75, 76, 77, 78, 79, 75},
-                    { 81, 80, 81, 82, 83, 84, 80},
-                    { 86, 85, 86, 87, 88, 89, 85},
-                    { 91, 90, 91, 92, 93, 94, 90},
-                    { 96, 95, 96, 97, 98, 99, 95},
-                    { 76, 75, 76, 77, 78, 79, 75}
-                    },
-                    {
-                    { 106, 105, 106, 107, 108, 109, 105},
-                    { 101, 100, 101, 102, 103, 104, 100},
-                    { 106, 105, 106, 107, 108, 109, 105},
-                    { 111, 110, 111, 112, 113, 114, 110},
-                    { 116, 115, 116, 117, 118, 119, 115},
-                    { 121, 120, 121, 122, 123, 124, 120},
-                    { 101, 100, 101, 102, 103, 104, 100}
-                    },
-                    {
-                    { 131, 130, 131, 132, 133, 134, 130},
-                    { 126, 125, 126, 127, 128, 129, 125},
-                    { 131, 130, 131, 132, 133, 134, 130},
-                    { 136, 135, 136, 137, 138, 139, 135},
-                    { 141, 140, 141, 142, 143, 144, 140},
-                    { 146, 145, 146, 147, 148, 149, 145},
-                    { 126, 125, 126, 127, 128, 129, 125}
-                    }
-                    }
-                }
-        });
-
-        myPad->getOperator()->associateInput(0,myInput);
-        myPad->getOperator()->setDataType(DataType::Int32);
-        myPad->getOperator()->setBackend("cpu");
-        myPad->forward();
-        op->getOutput(0)->print();
-        REQUIRE(*(op->getOutput(0)) == *myOutput);
-    }
+    REQUIRE_NOTHROW(op->forwardDims(true));
 
-    SECTION("Pad Wrap") {
-        std::shared_ptr<Node> myPad = Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Wrap);
-        auto op = std::static_pointer_cast<OperatorTensor>(myPad -> getOperator());
-        std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array4D<int,2,3,5,5> { //NCHW
-            {
-                {
-                    {{  0,   1,   2,   3,   4},
-                    {  5,   6,   7,   8,   9},
-                    { 10,  11,  12,  13,  14},
-                    { 15,  16,  17,  18,  19},
-                    { 20,  21,  22,  23,  24}},
-
-                    {{ 25,  26,  27,  28,  29},
-                    { 30,  31,  32,  33,  34},
-                    { 35,  36,  37,  38,  39},
-                    { 40,  41,  42,  43,  44},
-                    { 45,  46,  47,  48,  49}},
-
-                    {{ 50,  51,  52,  53,  54},
-                    { 55,  56,  57,  58,  59},
-                    { 60,  61,  62,  63,  64},
-                    { 65,  66,  67,  68,  69},
-                    { 70,  71,  72,  73,  74}}
-                },
-                {
-                    {{ 75,  76,  77,  78,  79},
-                    { 80,  81,  82,  83,  84},
-                    { 85,  86,  87,  88,  89},
-                    { 90,  91,  92,  93,  94},
-                    { 95,  96,  97,  98,  99}},
-
-                    {{100, 101, 102, 103, 104},
-                    {105, 106, 107, 108, 109},
-                    {110, 111, 112, 113, 114},
-                    {115, 116, 117, 118, 119},
-                    {120, 121, 122, 123, 124}},
-
-                    {{125, 126, 127, 128, 129},
-                    {130, 131, 132, 133, 134},
-                    {135, 136, 137, 138, 139},
-                    {140, 141, 142, 143, 144},
-                    {145, 146, 147, 148, 149}}
-                }
-            }
-        });
-        std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array4D<int,2,3,7,7> { //NCHW
-            {
-                {
-                    {{ 24,  20,  21,  22,  23,  24,  20},
-                    { 4,   0,   1,   2,   3,   4,  0},
-                    { 9,   5,   6,   7,   8,   9,  5},
-                    { 14,  10,  11,  12,  13,  14,  10},
-                    { 19,  15,  16,  17,  18,  19,  15},
-                    { 24,  20,  21,  22,  23,  24,  20},
-                    { 4,   0,   1,   2,   3,   4,  0}},
-
-                    {{ 49,  45,  46,  47,  48,  49, 45},
-                    { 29,  25,  26,  27,  28,  29,  25},
-                    { 34,  30,  31,  32,  33,  34,  30},
-                    { 39,  35,  36,  37,  38,  39,  35},
-                    { 44,  40,  41,  42,  43,  44,  40},
-                    { 49,  45,  46,  47,  48,  49,  45},
-                    { 29,  25,  26,  27,  28,  29,  25}},
-
-                    {{ 74,  70,  71,  72,  73,  74,  70},
-                    { 54,  50,  51,  52,  53,  54,  50},
-                    { 59,  55,  56,  57,  58,  59,  55},
-                    { 64,  60,  61,  62,  63,  64,  60},
-                    { 69,  65,  66,  67,  68,  69,  65},
-                    { 74,  70,  71,  72,  73,  74,  70},
-                    { 54,  50,  51,  52,  53,  54,  50}}
-                },
-                {
-                    {{ 99,  95,  96,  97,  98,  99,  95},
-                    { 79,  75,  76,  77,  78,  79,  75},
-                    { 84,  80,  81,  82,  83,  84,  80},
-                    { 89,  85,  86,  87,  88,  89,  85},
-                    { 94,  90,  91,  92,  93,  94,  90},
-                    { 99,  95,  96,  97,  98,  99,  95},
-                    { 79,  75,  76,  77,  78,  79,  75}},
-
-                    {{124,  120, 121, 122, 123, 124,  120},
-                    {104,  100, 101, 102, 103, 104,  100},
-                    {109,  105, 106, 107, 108, 109, 105},
-                    {114,  110, 111, 112, 113, 114,  110},
-                    {119,  115, 116, 117, 118, 119,  115},
-                    {124,  120, 121, 122, 123, 124,  120},
-                    {104,  100, 101, 102, 103, 104,  100}},
-
-                    {{149,  145, 146, 147, 148, 149,  145},
-                    {129,  125, 126, 127, 128, 129,  125},
-                    {134,  130, 131, 132, 133, 134,  130},
-                    {139,  135, 136, 137, 138, 139,  135},
-                    {144,  140, 141, 142, 143, 144,  140},
-                    {149,  145, 146, 147, 148, 149,  145},
-                    {129,  125, 126, 127, 128, 129,  125}}
-                }
+    return op;
+}
+
+TEST_CASE("[cpu/operator] Pad(forward)", "[Pad][CPU]") {
+    SECTION("2D") {
+        SECTION("Symmetric Pad") {
+            const int pv = 0; // pad value
+
+            std::shared_ptr<Node> myPad = Pad<2>({1, 1, 1, 1},
+                                                 "mypad",
+                                                 PadBorderType::Constant,
+                                                 static_cast<double>(pv));
+            auto op =
+                std::static_pointer_cast<OperatorTensor>(myPad->getOperator());
+            std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 5, 5>{// NCHW
+                                         {{{{0, 1, 2, 3, 4},
+                                            {5, 6, 7, 8, 9},
+                                            {10, 11, 12, 13, 14},
+                                            {15, 16, 17, 18, 19},
+                                            {20, 21, 22, 23, 24}},
+
+                                           {{25, 26, 27, 28, 29},
+                                            {30, 31, 32, 33, 34},
+                                            {35, 36, 37, 38, 39},
+                                            {40, 41, 42, 43, 44},
+                                            {45, 46, 47, 48, 49}},
+
+                                           {{50, 51, 52, 53, 54},
+                                            {55, 56, 57, 58, 59},
+                                            {60, 61, 62, 63, 64},
+                                            {65, 66, 67, 68, 69},
+                                            {70, 71, 72, 73, 74}}},
+                                          {{{75, 76, 77, 78, 79},
+                                            {80, 81, 82, 83, 84},
+                                            {85, 86, 87, 88, 89},
+                                            {90, 91, 92, 93, 94},
+                                            {95, 96, 97, 98, 99}},
+
+                                           {{100, 101, 102, 103, 104},
+                                            {105, 106, 107, 108, 109},
+                                            {110, 111, 112, 113, 114},
+                                            {115, 116, 117, 118, 119},
+                                            {120, 121, 122, 123, 124}},
+
+                                           {{125, 126, 127, 128, 129},
+                                            {130, 131, 132, 133, 134},
+                                            {135, 136, 137, 138, 139},
+                                            {140, 141, 142, 143, 144},
+                                            {145, 146, 147, 148, 149}}}}});
+            std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 7, 7>{// NCHW
+                                         {{{{pv, pv, pv, pv, pv, pv, pv},
+                                            {pv, 0, 1, 2, 3, 4, pv},
+                                            {pv, 5, 6, 7, 8, 9, pv},
+                                            {pv, 10, 11, 12, 13, 14, pv},
+                                            {pv, 15, 16, 17, 18, 19, pv},
+                                            {pv, 20, 21, 22, 23, 24, pv},
+                                            {pv, pv, pv, pv, pv, pv, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv, pv},
+                                            {pv, 25, 26, 27, 28, 29, pv},
+                                            {pv, 30, 31, 32, 33, 34, pv},
+                                            {pv, 35, 36, 37, 38, 39, pv},
+                                            {pv, 40, 41, 42, 43, 44, pv},
+                                            {pv, 45, 46, 47, 48, 49, pv},
+                                            {pv, pv, pv, pv, pv, pv, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv, pv},
+                                            {pv, 50, 51, 52, 53, 54, pv},
+                                            {pv, 55, 56, 57, 58, 59, pv},
+                                            {pv, 60, 61, 62, 63, 64, pv},
+                                            {pv, 65, 66, 67, 68, 69, pv},
+                                            {pv, 70, 71, 72, 73, 74, pv},
+                                            {pv, pv, pv, pv, pv, pv, pv}}},
+                                          {{{pv, pv, pv, pv, pv, pv, pv},
+                                            {pv, 75, 76, 77, 78, 79, pv},
+                                            {pv, 80, 81, 82, 83, 84, pv},
+                                            {pv, 85, 86, 87, 88, 89, pv},
+                                            {pv, 90, 91, 92, 93, 94, pv},
+                                            {pv, 95, 96, 97, 98, 99, pv},
+                                            {pv, pv, pv, pv, pv, pv, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv, pv},
+                                            {pv, 100, 101, 102, 103, 104, pv},
+                                            {pv, 105, 106, 107, 108, 109, pv},
+                                            {pv, 110, 111, 112, 113, 114, pv},
+                                            {pv, 115, 116, 117, 118, 119, pv},
+                                            {pv, 120, 121, 122, 123, 124, pv},
+                                            {pv, pv, pv, pv, pv, pv, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv, pv},
+                                            {pv, 125, 126, 127, 128, 129, pv},
+                                            {pv, 130, 131, 132, 133, 134, pv},
+                                            {pv, 135, 136, 137, 138, 139, pv},
+                                            {pv, 140, 141, 142, 143, 144, pv},
+                                            {pv, 145, 146, 147, 148, 149, pv},
+                                            {pv, pv, pv, pv, pv, pv, pv}}}}});
+
+            myPad->getOperator()->associateInput(0, myInput);
+            myPad->getOperator()->setDataType(DataType::Int32);
+            myPad->getOperator()->setBackend("cpu");
+            myPad->forward();
+            // myPad->getOperator()->getOutput(0)->print();
+            REQUIRE(*(op->getOutput(0)) == *myOutput);
+        }
+
+        SECTION("Asymmetric Pad") {
+            const int pv = 0; // pad value
+
+            std::shared_ptr<Node> myPad = Pad<2>({1, 0, 0, 1},
+                                                 "mypad",
+                                                 PadBorderType::Constant,
+                                                 static_cast<double>(pv));
+            auto op =
+                std::static_pointer_cast<OperatorTensor>(myPad->getOperator());
+            std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 5, 5>{// NCHW
+                                         {{{{0, 1, 2, 3, 4},
+                                            {5, 6, 7, 8, 9},
+                                            {10, 11, 12, 13, 14},
+                                            {15, 16, 17, 18, 19},
+                                            {20, 21, 22, 23, 24}},
+
+                                           {{25, 26, 27, 28, 29},
+                                            {30, 31, 32, 33, 34},
+                                            {35, 36, 37, 38, 39},
+                                            {40, 41, 42, 43, 44},
+                                            {45, 46, 47, 48, 49}},
+
+                                           {{50, 51, 52, 53, 54},
+                                            {55, 56, 57, 58, 59},
+                                            {60, 61, 62, 63, 64},
+                                            {65, 66, 67, 68, 69},
+                                            {70, 71, 72, 73, 74}}},
+                                          {{{75, 76, 77, 78, 79},
+                                            {80, 81, 82, 83, 84},
+                                            {85, 86, 87, 88, 89},
+                                            {90, 91, 92, 93, 94},
+                                            {95, 96, 97, 98, 99}},
+
+                                           {{100, 101, 102, 103, 104},
+                                            {105, 106, 107, 108, 109},
+                                            {110, 111, 112, 113, 114},
+                                            {115, 116, 117, 118, 119},
+                                            {120, 121, 122, 123, 124}},
+
+                                           {{125, 126, 127, 128, 129},
+                                            {130, 131, 132, 133, 134},
+                                            {135, 136, 137, 138, 139},
+                                            {140, 141, 142, 143, 144},
+                                            {145, 146, 147, 148, 149}}}}});
+            std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 6, 6>{// NCHW
+                                         {{{{pv, pv, pv, pv, pv, pv},
+                                            {0, 1, 2, 3, 4, pv},
+                                            {5, 6, 7, 8, 9, pv},
+                                            {10, 11, 12, 13, 14, pv},
+                                            {15, 16, 17, 18, 19, pv},
+                                            {20, 21, 22, 23, 24, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv},
+                                            {25, 26, 27, 28, 29, pv},
+                                            {30, 31, 32, 33, 34, pv},
+                                            {35, 36, 37, 38, 39, pv},
+                                            {40, 41, 42, 43, 44, pv},
+                                            {45, 46, 47, 48, 49, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv},
+                                            {50, 51, 52, 53, 54, pv},
+                                            {55, 56, 57, 58, 59, pv},
+                                            {60, 61, 62, 63, 64, pv},
+                                            {65, 66, 67, 68, 69, pv},
+                                            {70, 71, 72, 73, 74, pv}}},
+                                          {{{pv, pv, pv, pv, pv, pv},
+                                            {75, 76, 77, 78, 79, pv},
+                                            {80, 81, 82, 83, 84, pv},
+                                            {85, 86, 87, 88, 89, pv},
+                                            {90, 91, 92, 93, 94, pv},
+                                            {95, 96, 97, 98, 99, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv},
+                                            {100, 101, 102, 103, 104, pv},
+                                            {105, 106, 107, 108, 109, pv},
+                                            {110, 111, 112, 113, 114, pv},
+                                            {115, 116, 117, 118, 119, pv},
+                                            {120, 121, 122, 123, 124, pv}},
+
+                                           {{pv, pv, pv, pv, pv, pv},
+                                            {125, 126, 127, 128, 129, pv},
+                                            {130, 131, 132, 133, 134, pv},
+                                            {135, 136, 137, 138, 139, pv},
+                                            {140, 141, 142, 143, 144, pv},
+                                            {145, 146, 147, 148, 149, pv}}}}});
+
+            myPad->getOperator()->associateInput(0, myInput);
+            myPad->getOperator()->setDataType(DataType::Int32);
+            myPad->getOperator()->setBackend("cpu");
+            myPad->forward();
+            // myPad->getOperator()->getOutput(0)->print();
+            REQUIRE(*(op->getOutput(0)) == *myOutput);
+        }
+
+        SECTION("Pad Edge") {
+            std::shared_ptr<Node> myPad =
+                Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Edge);
+            auto op =
+                std::static_pointer_cast<OperatorTensor>(myPad->getOperator());
+            std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 5, 5>{// NCHW
+                                         {{{{0, 1, 2, 3, 4},
+                                            {5, 6, 7, 8, 9},
+                                            {10, 11, 12, 13, 14},
+                                            {15, 16, 17, 18, 19},
+                                            {20, 21, 22, 23, 24}},
+
+                                           {{25, 26, 27, 28, 29},
+                                            {30, 31, 32, 33, 34},
+                                            {35, 36, 37, 38, 39},
+                                            {40, 41, 42, 43, 44},
+                                            {45, 46, 47, 48, 49}},
+
+                                           {{50, 51, 52, 53, 54},
+                                            {55, 56, 57, 58, 59},
+                                            {60, 61, 62, 63, 64},
+                                            {65, 66, 67, 68, 69},
+                                            {70, 71, 72, 73, 74}}},
+                                          {{{75, 76, 77, 78, 79},
+                                            {80, 81, 82, 83, 84},
+                                            {85, 86, 87, 88, 89},
+                                            {90, 91, 92, 93, 94},
+                                            {95, 96, 97, 98, 99}},
+
+                                           {{100, 101, 102, 103, 104},
+                                            {105, 106, 107, 108, 109},
+                                            {110, 111, 112, 113, 114},
+                                            {115, 116, 117, 118, 119},
+                                            {120, 121, 122, 123, 124}},
+
+                                           {{125, 126, 127, 128, 129},
+                                            {130, 131, 132, 133, 134},
+                                            {135, 136, 137, 138, 139},
+                                            {140, 141, 142, 143, 144},
+                                            {145, 146, 147, 148, 149}}}}});
+            std::shared_ptr<Tensor> myOutput =
+                std::make_shared<Tensor>(Array4D<int, 2, 3, 7, 7>{
+                    // NCHW
+                    {{{{0, 0, 1, 2, 3, 4, 4},
+                       {0, 0, 1, 2, 3, 4, 4},
+                       {5, 5, 6, 7, 8, 9, 9},
+                       {10, 10, 11, 12, 13, 14, 14},
+                       {15, 15, 16, 17, 18, 19, 19},
+                       {20, 20, 21, 22, 23, 24, 24},
+                       {20, 20, 21, 22, 23, 24, 24}},
+
+                      {{25, 25, 26, 27, 28, 29, 29},
+                       {25, 25, 26, 27, 28, 29, 29},
+                       {30, 30, 31, 32, 33, 34, 34},
+                       {35, 35, 36, 37, 38, 39, 39},
+                       {40, 40, 41, 42, 43, 44, 44},
+                       {45, 45, 46, 47, 48, 49, 49},
+                       {45, 45, 46, 47, 48, 49, 49}},
+
+                      {{50, 50, 51, 52, 53, 54, 54},
+                       {50, 50, 51, 52, 53, 54, 54},
+                       {55, 55, 56, 57, 58, 59, 59},
+                       {60, 60, 61, 62, 63, 64, 64},
+                       {65, 65, 66, 67, 68, 69, 69},
+                       {70, 70, 71, 72, 73, 74, 74},
+                       {70, 70, 71, 72, 73, 74, 74}}},
+                     {{{75, 75, 76, 77, 78, 79, 79},
+                       {75, 75, 76, 77, 78, 79, 79},
+                       {80, 80, 81, 82, 83, 84, 84},
+                       {85, 85, 86, 87, 88, 89, 89},
+                       {90, 90, 91, 92, 93, 94, 94},
+                       {95, 95, 96, 97, 98, 99, 99},
+                       {95, 95, 96, 97, 98, 99, 99}},
+
+                      {{100, 100, 101, 102, 103, 104, 104},
+                       {100, 100, 101, 102, 103, 104, 104},
+                       {105, 105, 106, 107, 108, 109, 109},
+                       {110, 110, 111, 112, 113, 114, 114},
+                       {115, 115, 116, 117, 118, 119, 119},
+                       {120, 120, 121, 122, 123, 124, 124},
+                       {120, 120, 121, 122, 123, 124, 124}},
+
+                      {{125, 125, 126, 127, 128, 129, 129},
+                       {125, 125, 126, 127, 128, 129, 129},
+                       {130, 130, 131, 132, 133, 134, 134},
+                       {135, 135, 136, 137, 138, 139, 139},
+                       {140, 140, 141, 142, 143, 144, 144},
+                       {145, 145, 146, 147, 148, 149, 149},
+                       {145, 145, 146, 147, 148, 149, 149}}}}});
+
+            myPad->getOperator()->associateInput(0, myInput);
+            myPad->getOperator()->setDataType(DataType::Int32);
+            myPad->getOperator()->setBackend("cpu");
+            myPad->forward();
+            // myPad->getOperator()->getOutput(0)->print();
+            REQUIRE(*(op->getOutput(0)) == *myOutput);
+        }
+
+        SECTION("Pad Reflect") {
+            std::shared_ptr<Node> myPad =
+                Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Reflect);
+            auto op =
+                std::static_pointer_cast<OperatorTensor>(myPad->getOperator());
+            std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 5, 5>{// NCHW
+                                         {{{{0, 1, 2, 3, 4},
+                                            {5, 6, 7, 8, 9},
+                                            {10, 11, 12, 13, 14},
+                                            {15, 16, 17, 18, 19},
+                                            {20, 21, 22, 23, 24}},
+
+                                           {{25, 26, 27, 28, 29},
+                                            {30, 31, 32, 33, 34},
+                                            {35, 36, 37, 38, 39},
+                                            {40, 41, 42, 43, 44},
+                                            {45, 46, 47, 48, 49}},
+
+                                           {{50, 51, 52, 53, 54},
+                                            {55, 56, 57, 58, 59},
+                                            {60, 61, 62, 63, 64},
+                                            {65, 66, 67, 68, 69},
+                                            {70, 71, 72, 73, 74}}},
+                                          {{{75, 76, 77, 78, 79},
+                                            {80, 81, 82, 83, 84},
+                                            {85, 86, 87, 88, 89},
+                                            {90, 91, 92, 93, 94},
+                                            {95, 96, 97, 98, 99}},
+
+                                           {{100, 101, 102, 103, 104},
+                                            {105, 106, 107, 108, 109},
+                                            {110, 111, 112, 113, 114},
+                                            {115, 116, 117, 118, 119},
+                                            {120, 121, 122, 123, 124}},
+
+                                           {{125, 126, 127, 128, 129},
+                                            {130, 131, 132, 133, 134},
+                                            {135, 136, 137, 138, 139},
+                                            {140, 141, 142, 143, 144},
+                                            {145, 146, 147, 148, 149}}}}});
+            std::shared_ptr<Tensor> myOutput =
+                std::make_shared<Tensor>(Array4D<int, 2, 3, 7, 7>{
+                    // NCHW
+                    {{{{6, 5, 6, 7, 8, 9, 5},
+                       {1, 0, 1, 2, 3, 4, 0},
+                       {6, 5, 6, 7, 8, 9, 5},
+                       {11, 10, 11, 12, 13, 14, 10},
+                       {16, 15, 16, 17, 18, 19, 15},
+                       {21, 20, 21, 22, 23, 24, 20},
+                       {1, 0, 1, 2, 3, 4, 0}},
+                      {{31, 30, 31, 32, 33, 34, 30},
+                       {26, 25, 26, 27, 28, 29, 25},
+                       {31, 30, 31, 32, 33, 34, 30},
+                       {36, 35, 36, 37, 38, 39, 35},
+                       {41, 40, 41, 42, 43, 44, 40},
+                       {46, 45, 46, 47, 48, 49, 45},
+                       {26, 25, 26, 27, 28, 29, 25}},
+                      {{56, 55, 56, 57, 58, 59, 55},
+                       {51, 50, 51, 52, 53, 54, 50},
+                       {56, 55, 56, 57, 58, 59, 55},
+                       {61, 60, 61, 62, 63, 64, 60},
+                       {66, 65, 66, 67, 68, 69, 65},
+                       {71, 70, 71, 72, 73, 74, 70},
+                       {51, 50, 51, 52, 53, 54, 50}}},
+                     {{{81, 80, 81, 82, 83, 84, 80},
+                       {76, 75, 76, 77, 78, 79, 75},
+                       {81, 80, 81, 82, 83, 84, 80},
+                       {86, 85, 86, 87, 88, 89, 85},
+                       {91, 90, 91, 92, 93, 94, 90},
+                       {96, 95, 96, 97, 98, 99, 95},
+                       {76, 75, 76, 77, 78, 79, 75}},
+                      {{106, 105, 106, 107, 108, 109, 105},
+                       {101, 100, 101, 102, 103, 104, 100},
+                       {106, 105, 106, 107, 108, 109, 105},
+                       {111, 110, 111, 112, 113, 114, 110},
+                       {116, 115, 116, 117, 118, 119, 115},
+                       {121, 120, 121, 122, 123, 124, 120},
+                       {101, 100, 101, 102, 103, 104, 100}},
+                      {{131, 130, 131, 132, 133, 134, 130},
+                       {126, 125, 126, 127, 128, 129, 125},
+                       {131, 130, 131, 132, 133, 134, 130},
+                       {136, 135, 136, 137, 138, 139, 135},
+                       {141, 140, 141, 142, 143, 144, 140},
+                       {146, 145, 146, 147, 148, 149, 145},
+                       {126, 125, 126, 127, 128, 129, 125}}}}});
+
+            myPad->getOperator()->associateInput(0, myInput);
+            myPad->getOperator()->setDataType(DataType::Int32);
+            myPad->getOperator()->setBackend("cpu");
+            myPad->forward();
+            op->getOutput(0)->print();
+            REQUIRE(*(op->getOutput(0)) == *myOutput);
+        }
+
+        SECTION("Pad Wrap") {
+            std::shared_ptr<Node> myPad =
+                Pad<2>({1, 1, 1, 1}, "mypad", PadBorderType::Wrap);
+            auto op =
+                std::static_pointer_cast<OperatorTensor>(myPad->getOperator());
+            std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(
+                Array4D<int, 2, 3, 5, 5>{// NCHW
+                                         {{{{0, 1, 2, 3, 4},
+                                            {5, 6, 7, 8, 9},
+                                            {10, 11, 12, 13, 14},
+                                            {15, 16, 17, 18, 19},
+                                            {20, 21, 22, 23, 24}},
+
+                                           {{25, 26, 27, 28, 29},
+                                            {30, 31, 32, 33, 34},
+                                            {35, 36, 37, 38, 39},
+                                            {40, 41, 42, 43, 44},
+                                            {45, 46, 47, 48, 49}},
+
+                                           {{50, 51, 52, 53, 54},
+                                            {55, 56, 57, 58, 59},
+                                            {60, 61, 62, 63, 64},
+                                            {65, 66, 67, 68, 69},
+                                            {70, 71, 72, 73, 74}}},
+                                          {{{75, 76, 77, 78, 79},
+                                            {80, 81, 82, 83, 84},
+                                            {85, 86, 87, 88, 89},
+                                            {90, 91, 92, 93, 94},
+                                            {95, 96, 97, 98, 99}},
+
+                                           {{100, 101, 102, 103, 104},
+                                            {105, 106, 107, 108, 109},
+                                            {110, 111, 112, 113, 114},
+                                            {115, 116, 117, 118, 119},
+                                            {120, 121, 122, 123, 124}},
+
+                                           {{125, 126, 127, 128, 129},
+                                            {130, 131, 132, 133, 134},
+                                            {135, 136, 137, 138, 139},
+                                            {140, 141, 142, 143, 144},
+                                            {145, 146, 147, 148, 149}}}}});
+            std::shared_ptr<Tensor> myOutput =
+                std::make_shared<Tensor>(Array4D<int, 2, 3, 7, 7>{
+                    // NCHW
+                    {{{{24, 20, 21, 22, 23, 24, 20},
+                       {4, 0, 1, 2, 3, 4, 0},
+                       {9, 5, 6, 7, 8, 9, 5},
+                       {14, 10, 11, 12, 13, 14, 10},
+                       {19, 15, 16, 17, 18, 19, 15},
+                       {24, 20, 21, 22, 23, 24, 20},
+                       {4, 0, 1, 2, 3, 4, 0}},
+
+                      {{49, 45, 46, 47, 48, 49, 45},
+                       {29, 25, 26, 27, 28, 29, 25},
+                       {34, 30, 31, 32, 33, 34, 30},
+                       {39, 35, 36, 37, 38, 39, 35},
+                       {44, 40, 41, 42, 43, 44, 40},
+                       {49, 45, 46, 47, 48, 49, 45},
+                       {29, 25, 26, 27, 28, 29, 25}},
+
+                      {{74, 70, 71, 72, 73, 74, 70},
+                       {54, 50, 51, 52, 53, 54, 50},
+                       {59, 55, 56, 57, 58, 59, 55},
+                       {64, 60, 61, 62, 63, 64, 60},
+                       {69, 65, 66, 67, 68, 69, 65},
+                       {74, 70, 71, 72, 73, 74, 70},
+                       {54, 50, 51, 52, 53, 54, 50}}},
+                     {{{99, 95, 96, 97, 98, 99, 95},
+                       {79, 75, 76, 77, 78, 79, 75},
+                       {84, 80, 81, 82, 83, 84, 80},
+                       {89, 85, 86, 87, 88, 89, 85},
+                       {94, 90, 91, 92, 93, 94, 90},
+                       {99, 95, 96, 97, 98, 99, 95},
+                       {79, 75, 76, 77, 78, 79, 75}},
+
+                      {{124, 120, 121, 122, 123, 124, 120},
+                       {104, 100, 101, 102, 103, 104, 100},
+                       {109, 105, 106, 107, 108, 109, 105},
+                       {114, 110, 111, 112, 113, 114, 110},
+                       {119, 115, 116, 117, 118, 119, 115},
+                       {124, 120, 121, 122, 123, 124, 120},
+                       {104, 100, 101, 102, 103, 104, 100}},
+
+                      {{149, 145, 146, 147, 148, 149, 145},
+                       {129, 125, 126, 127, 128, 129, 125},
+                       {134, 130, 131, 132, 133, 134, 130},
+                       {139, 135, 136, 137, 138, 139, 135},
+                       {144, 140, 141, 142, 143, 144, 140},
+                       {149, 145, 146, 147, 148, 149, 145},
+                       {129, 125, 126, 127, 128, 129, 125}}}}});
+
+            myPad->getOperator()->associateInput(0, myInput);
+            myPad->getOperator()->setDataType(DataType::Int32);
+            myPad->getOperator()->setBackend("cpu");
+            myPad->forward();
+            // myPad->getOperator()->getOutput(0)->print();
+            REQUIRE(*(op->getOutput(0)) == *myOutput);
+        }
+    }
+    SECTION("3D") {
+        constexpr DimSize_t DIM = 3;
+        SECTION("PadBorderType::Constant") {
+            constexpr DimSize_t batch = 1;
+            constexpr DimSize_t channel = 1;
+            constexpr std::array<DimSize_t, DIM> inDataSize = {2, 2, 2};
+            constexpr std::array<DimSize_t, 2 * DIM> beginEndBorder =
+                {1, 1, 1, 1, 1, 1};
+            constexpr std::array<DimSize_t, DIM> outDataSize = {
+                inDataSize[0] + beginEndBorder[0] + beginEndBorder[3],
+                inDataSize[1] + beginEndBorder[1] + beginEndBorder[4],
+                inDataSize[2] + beginEndBorder[2] + beginEndBorder[5]};
+            constexpr double borderValue = 10;
+
+            auto input = std::make_shared<Tensor>(
+                Array5D<float,
+                        batch,
+                        channel,
+                        inDataSize[0],
+                        inDataSize[1],
+                        inDataSize[2]>({{{{{{-1, 4}, {-2, -5}},
+
+                                           {{-2, 4}, {2, -2}}}}}}));
+            auto padOp = setupTestPad<DIM>(beginEndBorder,
+                                           input,
+                                           PadBorderType::Constant,
+                                           borderValue);
+
+            REQUIRE_NOTHROW(padOp->forward());
+
+            Tensor expectedOutput(
+                Array5D<float,
+                        batch,
+                        channel,
+                        outDataSize[0],
+                        outDataSize[1],
+                        outDataSize[2]>({{{{{{10, 10, 10, 10},
+                                             {10, 10, 10, 10},
+                                             {10, 10, 10, 10},
+                                             {10, 10, 10, 10}},
+
+                                            {{10, 10, 10, 10},
+                                             {10, -1, 4, 10},
+                                             {10, -2, -5, 10},
+                                             {10, 10, 10, 10}},
+
+                                            {{10, 10, 10, 10},
+                                             {10, -2, 4, 10},
+                                             {10, 2, -2, 10},
+                                             {10, 10, 10, 10}},
+
+                                            {{10, 10, 10, 10},
+                                             {10, 10, 10, 10},
+                                             {10, 10, 10, 10},
+                                             {10, 10, 10, 10}}}}}}));
+            CHECK(approxEq<float>(*padOp->getOutput(0), expectedOutput));
+        }
+        SECTION("PadBorderType::Edge") {
+            SECTION("small test") {
+                constexpr DimSize_t batch = 1;
+                constexpr DimSize_t channel = 1;
+                constexpr std::array<DimSize_t, DIM> inDataSize = {1, 2, 2};
+                constexpr std::array<DimSize_t, 2 * DIM> beginEndBorder =
+                    {1, 1, 1, 1, 1, 1};
+                constexpr std::array<DimSize_t, DIM> outDataSize = {
+                    inDataSize[0] + beginEndBorder[0] + beginEndBorder[3],
+                    inDataSize[1] + beginEndBorder[1] + beginEndBorder[4],
+                    inDataSize[2] + beginEndBorder[2] + beginEndBorder[5]};
+                auto input = std::make_shared<Tensor>(
+                    Array5D<float,
+                            batch,
+                            channel,
+                            inDataSize[0],
+                            inDataSize[1],
+                            inDataSize[2]>({{{{{{-1, 4}, {-2, -5}}}}}}));
+                auto padOp = setupTestPad<DIM>(beginEndBorder,
+                                               input,
+                                               PadBorderType::Edge,
+                                               0);
+
+                REQUIRE_NOTHROW(padOp->forward());
+
+                Tensor expectedOutput(
+                    Array5D<float,
+                            batch,
+                            channel,
+                            outDataSize[0],
+                            outDataSize[1],
+                            outDataSize[2]>({{{{{{-1, -1, 4, 4},
+                                                 {-1, -1, 4, 4},
+                                                 {-2, -2, -5, -5},
+                                                 {-2, -2, -5, -5}},
+
+                                                {{-1, -1, 4, 4},
+                                                 {-1, -1, 4, 4},
+                                                 {-2, -2, -5, -5},
+                                                 {-2, -2, -5, -5}},
+
+                                                {{-1, -1, 4, 4},
+                                                 {-1, -1, 4, 4},
+                                                 {-2, -2, -5, -5},
+                                                 {-2, -2, -5, -5}}}}}}));
+                CHECK(approxEq<float>(*padOp->getOutput(0), expectedOutput));
             }
-        });
-
-        myPad->getOperator()->associateInput(0,myInput);
-        myPad->getOperator()->setDataType(DataType::Int32);
-        myPad->getOperator()->setBackend("cpu");
-        myPad->forward();
-        // myPad->getOperator()->getOutput(0)->print();
-        REQUIRE(*(op->getOutput(0)) == *myOutput);
+        }
+        SECTION("PadBorderType::Reflect") {
+            constexpr DimSize_t batch = 1;
+            constexpr DimSize_t channel = 1;
+            constexpr std::array<DimSize_t, DIM> inDataSize = {1, 3, 3};
+            constexpr std::array<DimSize_t, 2 * DIM> beginEndBorder =
+                {0, 0, 2, 0, 0, 2};
+            constexpr std::array<DimSize_t, DIM> outDataSize = {
+                inDataSize[0] + beginEndBorder[0] + beginEndBorder[3],
+                inDataSize[1] + beginEndBorder[1] + beginEndBorder[4],
+                inDataSize[2] + beginEndBorder[2] + beginEndBorder[5]};
+            auto input = std::make_shared<Tensor>(Array5D<float,
+                                                          batch,
+                                                          channel,
+                                                          inDataSize[0],
+                                                          inDataSize[1],
+                                                          inDataSize[2]>(
+                {{{{{{-1, 4, -2}, {-5, -2, 4}, {2, -2, 2}}}}}}));
+            auto padOp = setupTestPad<DIM>(beginEndBorder,
+                                           input,
+                                           PadBorderType::Reflect,
+                                           0);
+
+            REQUIRE_NOTHROW(padOp->forward());
+
+            Tensor expectedOutput(
+                Array5D<float,
+                        batch,
+                        channel,
+                        outDataSize[0],
+                        outDataSize[1],
+                        outDataSize[2]>({{{{{{-2, 4, -1, 4, -2, 4, -1},
+                                             {4, -2, -5, -2, 4, -2, -5},
+                                             {2, -2, 2, -2, 2, -2, 2}}}}}}));
+            CHECK(approxEq<float>(*padOp->getOutput(0), expectedOutput));
+        }
+        SECTION("PadBorderType::Wrap") {
+            constexpr DimSize_t batch = 1;
+            constexpr DimSize_t channel = 1;
+            constexpr std::array<DimSize_t, DIM> inDataSize = {1, 3, 3};
+            constexpr std::array<DimSize_t, 2 * DIM> beginEndBorder =
+                {0, 0, 2, 0, 0, 2};
+            constexpr std::array<DimSize_t, DIM> outDataSize = {
+                inDataSize[0] + beginEndBorder[0] + beginEndBorder[3],
+                inDataSize[1] + beginEndBorder[1] + beginEndBorder[4],
+                inDataSize[2] + beginEndBorder[2] + beginEndBorder[5]};
+            auto input = std::make_shared<Tensor>(Array5D<float,
+                                                          batch,
+                                                          channel,
+                                                          inDataSize[0],
+                                                          inDataSize[1],
+                                                          inDataSize[2]>(
+                {{{{{{-1, 4, -2}, {-5, -2, 4}, {2, -2, 2}}}}}}));
+            auto padOp = setupTestPad<DIM>(beginEndBorder,
+                                           input,
+                                           PadBorderType::Wrap,
+                                           0);
+
+            REQUIRE_NOTHROW(padOp->forward());
+
+            Tensor expectedOutput(
+                Array5D<float,
+                        batch,
+                        channel,
+                        outDataSize[0],
+                        outDataSize[1],
+                        outDataSize[2]>({{{{{{4, -2, -1, 4, -2, -1, 4},
+                                             {-2, 4, -5, -2, 4, -5, -2},
+                                             {-2, 2, 2, -2, 2, 2, -2}}}}}}));
+            CHECK(approxEq<float>(*padOp->getOutput(0), expectedOutput));
+        }
     }
-}
\ No newline at end of file
+}