diff --git a/include/aidge/backend/cpu.hpp b/include/aidge/backend/cpu.hpp
index 7cd492f4ea035a0624fe68fc35b0a4246fe084a8..5a7ac3958b76e94c8389b0287fdac40c8c3a5ad8 100644
--- a/include/aidge/backend/cpu.hpp
+++ b/include/aidge/backend/cpu.hpp
@@ -29,6 +29,7 @@
 #include "aidge/backend/cpu/operator/ProducerImpl.hpp"
 #include "aidge/backend/cpu/operator/ReLUImpl.hpp"
 #include "aidge/backend/cpu/operator/ScalingImpl.hpp"
+#include "aidge/backend/cpu/operator/SqrtImpl.hpp"
 #include "aidge/backend/cpu/operator/SoftmaxImpl.hpp"
 #include "aidge/backend/cpu/operator/SubImpl.hpp"
 
diff --git a/include/aidge/backend/cpu/operator/SqrtImpl.hpp b/include/aidge/backend/cpu/operator/SqrtImpl.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1880408cd52f537c6d4965438ece88151d4df6e3
--- /dev/null
+++ b/include/aidge/backend/cpu/operator/SqrtImpl.hpp
@@ -0,0 +1,50 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_CPU_OPERATOR_SQRTIMPL_H_
+#define AIDGE_CPU_OPERATOR_SQRTIMPL_H_
+
+#include "aidge/backend/OperatorImpl.hpp"
+#include "aidge/operator/Sqrt.hpp"
+#include "aidge/utils/Registrar.hpp"
+#include "aidge/utils/Types.h"
+#include <memory>
+#include <vector>
+
+namespace Aidge {
+// class Sqrt_Op;
+
+// compute kernel registry for forward and backward
+class SqrtImplForward_cpu
+    : public Registrable<SqrtImplForward_cpu, std::tuple<DataType, DataType>, void(const std::size_t, const void*, void*)> {
+};
+class SqrtImplBackward_cpu
+    : public Registrable<SqrtImplBackward_cpu, std::tuple<DataType, DataType>, void(const std::size_t, const void*, void*)> {
+};
+
+class SqrtImpl_cpu : public OperatorImpl {
+public:
+    SqrtImpl_cpu(const Sqrt_Op& op) : OperatorImpl(op) {}
+
+    static std::unique_ptr<SqrtImpl_cpu> create(const Sqrt_Op& op) {
+        return std::make_unique<SqrtImpl_cpu>(op);
+    }
+
+    NbElts_t getNbRequiredProtected(const IOIndex_t inputIdx) const override final;
+    void forward() override;
+};
+
+namespace {
+static Registrar<Sqrt_Op> registrarSqrtImpl_cpu("cpu", Aidge::SqrtImpl_cpu::create);
+}
+}  // namespace Aidge
+
+#endif /* AIDGE_CPU_OPERATOR_SQRTIMPL_H_ */
diff --git a/include/aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp b/include/aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a180fc2cc206ef27b52d506a981f9f50f7bf8a3e
--- /dev/null
+++ b/include/aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp
@@ -0,0 +1,44 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_CPU_OPERATOR_SQRTIMPL_FORWARD_KERNEL_H_
+#define AIDGE_CPU_OPERATOR_SQRTIMPL_FORWARD_KERNEL_H_
+
+#include "aidge/utils/Registrar.hpp"
+#include <cmath>
+
+#include "aidge/backend/cpu/operator/SqrtImpl.hpp"
+
+namespace Aidge {
+template <class I, class O>
+void SqrtImpl_cpu_forward_kernel(std::size_t inputLenght,
+                                     const void* input_,
+                                     void* output_) {
+
+    const I* input = static_cast<const I*>(input_);
+    O* output = static_cast<O*>(output_);
+
+    for (std::size_t i = 0; i < inputLenght; ++i) {
+        output[i] = std::sqrt(input[i]);
+    }
+}
+
+namespace {
+static Registrar<SqrtImplForward_cpu> registrarSqrtImplForward_cpu_Float32(
+        {DataType::Float32, DataType::Float32}, Aidge::SqrtImpl_cpu_forward_kernel<float, float>);
+static Registrar<SqrtImplForward_cpu> registrarSqrtImplForward_cpu_Int32(
+        {DataType::Int32, DataType::Int32}, Aidge::SqrtImpl_cpu_forward_kernel<int, int>);
+static Registrar<SqrtImplForward_cpu> registrarSqrtImplForward_cpu_Float64(
+        {DataType::Float64, DataType::Float64}, Aidge::SqrtImpl_cpu_forward_kernel<double, double>);
+}  // namespace
+}  // namespace Aidge
+
+#endif /* AIDGE_CPU_OPERATOR_SQRTIMPL_FORWARD_KERNEL_H_ */
diff --git a/src/operator/SqrtImpl.cpp b/src/operator/SqrtImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..75d1d2fb20b6748c931124847198b3168d9bdba7
--- /dev/null
+++ b/src/operator/SqrtImpl.cpp
@@ -0,0 +1,41 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <cassert>
+#include <chrono>  // std::chrono::milliseconds
+#include <numeric> // std::accumulate
+#include <thread>  // std::this_thread::sleep_for
+#include <vector>
+
+#include "aidge/operator/Sqrt.hpp"
+#include "aidge/utils/Types.h"
+
+#include "aidge/backend/cpu/operator/SqrtImpl.hpp"
+#include "aidge/backend/cpu/operator/SqrtImpl_forward_kernels.hpp"
+
+Aidge::NbElts_t Aidge::SqrtImpl_cpu::getNbRequiredProtected(const Aidge::IOIndex_t /*inputIdx*/) const {
+    // this implementation can be in-place
+    return 0;
+}
+
+void Aidge::SqrtImpl_cpu::forward() {
+    assert(mOp.getInput(0) && "missing input #0");
+
+    // Find the correct kernel type
+    auto kernelFunc = Registrar<SqrtImplForward_cpu>::create({
+        mOp.getInput(0)->dataType(),
+        mOp.getOutput(0)->dataType()});
+
+    // Call kernel
+    kernelFunc(mOp.getInput(0)->size(),
+        mOp.getInput(0)->getImpl()->rawPtr(),
+        mOp.getOutput(0)->getImpl()->rawPtr());
+}
\ No newline at end of file
diff --git a/unit_tests/operator/Test_SqrtImpl.cpp b/unit_tests/operator/Test_SqrtImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cf17499aba50359547218adc6b3938176e729ed3
--- /dev/null
+++ b/unit_tests/operator/Test_SqrtImpl.cpp
@@ -0,0 +1,121 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <catch2/catch_test_macros.hpp>
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/operator/Sqrt.hpp"
+
+#include "aidge/backend/cpu.hpp"
+
+#include <memory>
+
+using namespace Aidge;
+
+TEST_CASE("[cpu/operator] Sqrt(forward)") {
+    SECTION("2D Tensor") {
+        std::shared_ptr<Tensor> input = std::make_shared<Tensor>(Array2D<float,2,2> {
+            {
+                {16.00000000,  0.62226844},
+                { 0.00000000,  1.84539008}
+            }
+        });
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array2D<float,2,2> {
+            {
+                {4.00000000, 0.78883994},
+                {0.00000000, 1.35845140}
+            }
+        });
+
+        std::shared_ptr<Node> mySqrt = Sqrt();
+        mySqrt->getOperator()->setDatatype(DataType::Float32);
+        mySqrt->getOperator()->setBackend("cpu");
+        mySqrt->getOperator()->associateInput(0,input);
+        mySqrt->getOperator()->computeOutputDims();
+        mySqrt->forward();
+
+        float* resPtr = static_cast<float*>(mySqrt->getOperator()->getOutput(0)->getImpl()->rawPtr());
+        float* expectedPtr = static_cast<float*>(expectedOutput->getImpl()->rawPtr());
+        for (std::size_t i = 0; i< 4; ++i) {
+            REQUIRE(std::abs(resPtr[i]-expectedPtr[i]) < 0.00001);
+        }
+
+    }
+
+    SECTION("4D Tensor") {
+        std::shared_ptr<Tensor> input = std::make_shared<Tensor>(Array4D<float,2,3,3,3> {
+            {
+                {
+                    {{0.06218481, 0.46850157, 0.60914326},
+                     {0.57470602, 0.09943211, 0.59992820},
+                     {0.99623793, 0.54931718, 0.89343822}},
+                    {{0.75176072, 0.38237786, 0.84824580},
+                     {0.10619396, 0.11959118, 0.93499404},
+                     {0.65563291, 0.02913034, 0.17093092}},
+                    {{0.36303985, 0.92073035, 0.79146117},
+                     {0.88962847, 0.94561219, 0.92033130},
+                     {0.52903181, 0.13397896, 0.76086712}}
+                },
+                {
+                    {{0.31242222, 0.80526417, 0.48411584},
+                     {0.84375203, 0.65408552, 0.55028963},
+                     {0.77546734, 0.06203610, 0.83163154}},
+                    {{0.46342927, 0.53631741, 0.39145601},
+                     {0.14204198, 0.84214240, 0.94185621},
+                     {0.05068624, 0.99889028, 0.38464361}},
+                    {{0.37591159, 0.51769549, 0.30288595},
+                     {0.96883464, 0.35154045, 0.55648762},
+                     {0.13022375, 0.73467660, 0.02705121}}
+                }
+            }
+        });
+
+        std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>(Array4D<float,2,3,3,3> {
+            {
+                {
+                    {{0.24936883, 0.6844717,  0.7804763},
+                     {0.75809366, 0.31532857, 0.7745503},
+                     {0.9981172,  0.7411593,  0.9452186}},
+                    {{0.86704135, 0.6183671,  0.9210026},
+                     {0.32587415, 0.34581956, 0.9669509},
+                     {0.80971164, 0.17067613, 0.41343793}},
+                    {{0.60252786, 0.9595469,  0.88964105},
+                     {0.9432012,  0.97242594, 0.95933896},
+                     {0.7273457,  0.36603138, 0.87227696}}
+                },
+                {
+                    {{0.55894744, 0.89736515, 0.69578433},
+                     {0.91855973, 0.8087555,  0.7418151},
+                     {0.88060623, 0.24907047, 0.91193837}},
+                    {{0.6807564,  0.73233694, 0.6256645},
+                     {0.37688458, 0.9176832,  0.9704928},
+                     {0.22513604, 0.99944496, 0.62019646}},
+                    {{0.6131163,  0.7195106,  0.5503507},
+                     {0.984294,   0.59290844, 0.745981},
+                     {0.3608653,  0.8571328,  0.16447252}}
+                }
+            }
+        });
+
+        std::shared_ptr<Node> mySqrt = Sqrt();
+        mySqrt->getOperator()->setDatatype(DataType::Float32);
+        mySqrt->getOperator()->setBackend("cpu");
+        mySqrt->getOperator()->associateInput(0,input);
+        mySqrt->getOperator()->computeOutputDims();
+        mySqrt->forward();
+
+        float* resPtr = static_cast<float*>(mySqrt->getOperator()->getOutput(0)->getImpl()->rawPtr());
+        float* expectedPtr = static_cast<float*>(expectedOutput->getImpl()->rawPtr());
+        for (std::size_t i = 0; i< 54; ++i) {
+            REQUIRE(std::abs(resPtr[i]-expectedPtr[i]) < 0.00001);
+        }
+    }
+}
\ No newline at end of file