diff --git a/include/aidge/operator/AvgPooling.hpp b/include/aidge/operator/AvgPooling.hpp
index 981f71762757795461226f2b052bda7f4bc9cd89..483ccac6a8c5cac3f28b1de62e4f33c667a18f6b 100644
--- a/include/aidge/operator/AvgPooling.hpp
+++ b/include/aidge/operator/AvgPooling.hpp
@@ -33,12 +33,21 @@ enum class AvgPoolingAttr {
      * Specifies the step size of the sliding window along each spatial dimension.
      */
     StrideDims,
-
+    /**
+     * @brief Dilation along each spatial axis. Default value is 1.
+     */
+    Dilations,
     /**
      * @brief Kernel dimensions for the pooling operation.
      * Specifies the size of the pooling window along each spatial dimension.
      */
-    KernelDims
+    KernelDims,
+    /**
+     * @brief Flag indicating whether to use ceil or floor when calculating output size.
+     * - `true`: Use `ceil` for output size calculation.
+     * - `false`: Use `floor` for output size calculation.
+     */
+    CeilMode
 };
 
 /**
@@ -67,7 +76,9 @@ private:
      */
     using Attributes_ = StaticAttributes<AvgPoolingAttr,
                                              std::array<DimSize_t, DIM>,
-                                             std::array<DimSize_t, DIM>>;
+                                             std::array<DimSize_t, DIM>,
+                                             std::array<DimSize_t, DIM>,
+                                             bool>;
     template <AvgPoolingAttr e>
     using attr = typename Attributes_::template attr<e>;
 
@@ -89,11 +100,15 @@ public:
      * Defaults to 1 for each dimension.
      */
     constexpr AvgPooling_Op(const std::array<DimSize_t, DIM> &kernel_dims,
-                            const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t, DIM>(1))
+                            const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t, DIM>(1),
+                            const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t, DIM>(1),
+                            bool ceil_mode = false)
         : OperatorTensor(Type, {InputCategory::Data}, 1),
           mAttributes(std::make_shared<Attributes_>(
                         attr<AvgPoolingAttr::StrideDims>(stride_dims),
-                        attr<AvgPoolingAttr::KernelDims>(kernel_dims)))
+                        attr<AvgPoolingAttr::KernelDims>(kernel_dims),
+                        attr<AvgPoolingAttr::Dilations>(dilations),
+                        attr<AvgPoolingAttr::CeilMode>(ceil_mode)))
     {}
 
     /**
@@ -155,11 +170,23 @@ public:
     inline std::array<DimSize_t, DIM>& strideDims() const { return mAttributes->template getAttr<AvgPoolingAttr::StrideDims>(); }
 
     /**
-     * @brief Accessor for the kernel dimensions.
-     * @return An array representing the kernel dimensions.
+     * @brief Accessor for dilations.
+     * @return An array representing spatial dilations.
+     */
+    inline std::array<DimSize_t, DIM>& dilations() const { return mAttributes->template getAttr<AvgPoolingAttr::Dilations>(); }
+
+    /**
+     * @brief Accessor for kernel dimensions.
+     * @return An array representing kernel dimensions.
      */
     inline std::array<DimSize_t, DIM>& kernelDims() const { return mAttributes->template getAttr<AvgPoolingAttr::KernelDims>(); }
 
+    /**
+     * @brief Accessor for ceil mode flag.
+     * @return Boolean value indicating whether ceil mode is enabled.
+     */
+    inline bool& ceilMode() const { return mAttributes->template getAttr<AvgPoolingAttr::CeilMode>(); }
+
     /**
      * @brief Retrieves the names of the input tensors.
      * @return A vector of strings representing the input tensors names.
@@ -180,31 +207,39 @@ public:
 /**
  * @brief Creates an AvgPooling operator node.
  * @tparam DIM Number of dimensions for the pooling operation.
- * @param kernel_dims Size of the pooling window for each spatial dimension.
- * @param name Name of the operator node. Defaults to an empty string.
- * @param stride_dims Step size (stride) for sliding the pooling window across the input dimensions. Defaults to 1 for each dimension.
+ * @param[in] kernel_dims Size of the pooling window for each spatial dimension.
+ * @param[in] name Name of the operator node. Defaults to an empty string.
+ * @param[in] stride_dims Step size (stride) for sliding the pooling window across the input dimensions. Defaults to 1 for each dimension.
+ * @param[in] dilations Spatial dilations for the pooling operation.
+ * @param[in] ceil_mode Indicates whether to use ceil mode for output size calculation.
  * @return A shared pointer to the created operator node.
  */
 template <std::array<DimSize_t, 1>::size_type DIM>
 std::shared_ptr<Node> AvgPooling(const std::array<DimSize_t, DIM> &kernel_dims,
                                  const std::string& name = "",
-                                 const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1));
+                                 const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+                                 const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
+                                 bool ceil_mode=false);
 
 /**
  * @brief Overload of AvgPooling for C-style arrays.
  * @tparam DIM Number of dimensions for the pooling operation.
- * @param kernel_dims C-style array specifying the kernel dimensions.
- * @param name Name of the operator node. Defaults to an empty string.
- * @param stride_dims Step size (stride) for sliding the pooling window across the input dimensions. Defaults to 1 for each dimension.
+ * @param[in] kernel_dims C-style array specifying the kernel dimensions.
+ * @param[in] name Name of the operator node. Defaults to an empty string.
+ * @param[in] stride_dims Step size (stride) for sliding the pooling window across the input dimensions. Defaults to 1 for each dimension.
+ * @param[in] dilations Spatial dilations for the pooling operation.
+ * @param[in] ceil_mode Indicates whether to use ceil mode for output size calculation.
  * @return A shared pointer to the created operator node.
  */
 template <DimSize_t DIM>
 inline std::shared_ptr<Node> AvgPooling(
     DimSize_t const (&kernel_dims)[DIM],
     const std::string& name = "",
-    const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1)) {
+    const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+    const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
+    bool ceil_mode=false) {
     static_assert(DIM<=MaxDim,"Too many kernel dimensions required by AvgPooling, not supported");
-    return AvgPooling(to_array(kernel_dims), name, stride_dims);
+    return AvgPooling(to_array(kernel_dims), name, stride_dims, dilations, ceil_mode);
 }
 }  // namespace Aidge
 
@@ -221,10 +256,7 @@ namespace {
  * @brief String representation of the AvgPooling attributes.
  */
 template <>
-const char *const EnumStrings<Aidge::AvgPoolingAttr>::data[] = {
-    "stride_dims",
-    "kernel_dims"
-};
+const char *const EnumStrings<Aidge::AvgPoolingAttr>::data[] = { "stride_dims", "kernel_dims", "dilations", "ceil_mode" };
 }
 
 #endif /* AIDGE_CORE_OPERATOR_AVGPOOLING_H_ */
diff --git a/include/aidge/operator/MetaOperatorDefs.hpp b/include/aidge/operator/MetaOperatorDefs.hpp
index 9597b533c14b27d282985b13cd8e1199ed5360a8..79c97f1f3bc72d634f9362c90f0ed142bf4b9d8f 100644
--- a/include/aidge/operator/MetaOperatorDefs.hpp
+++ b/include/aidge/operator/MetaOperatorDefs.hpp
@@ -164,6 +164,7 @@ PaddedConvDepthWise(const DimSize_t nb_channels,
  * @param[in] kernel_dims The dimensions of the pooling window.
  * @param[in] name Optional name for the operation.
  * @param[in] stride_dims The stride dimensions for pooling (default is 1).
+ * @param[in] dilations The spatial dilations for pooling (default is 1).
  * @param[in] padding_dims Padding dimensions before pooling (default is 0).
  * @return A shared pointer to the Node representing the padded average pooling operation.
  */
@@ -171,6 +172,7 @@ template <std::array<DimSize_t, 1>::size_type DIM>
 extern std::shared_ptr<Node> PaddedAvgPooling(const std::array<DimSize_t, DIM> &kernel_dims,
                                   const std::string& name = "",
                                   const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+                                  const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
                                   const std::array<DimSize_t, 2*DIM> &padding_dims = create_array<DimSize_t,2*DIM>(0));
 
 /**
@@ -180,12 +182,14 @@ extern std::shared_ptr<Node> PaddedAvgPooling(const std::array<DimSize_t, DIM> &
  *
  * @param[in] kernel_dims The dimensions of the pooling window.
  * @param[in] stride_dims The stride dimensions for pooling (default is 1).
+ * @param[in] dilations The spatial dilations for pooling (default is 1).
  * @param[in] padding_dims Padding dimensions before pooling (default is 0).
  * @return A shared pointer to the MetaOperator_Op representing the padded average pooling operation.
  */
 template <std::array<DimSize_t, 1>::size_type DIM>
 extern std::shared_ptr<MetaOperator_Op> PaddedAvgPooling_Op(const std::array<DimSize_t, DIM> &kernel_dims,
                                   const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+                                  const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
                                   const std::array<DimSize_t, 2*DIM> &padding_dims = create_array<DimSize_t,2*DIM>(0));
 
 // Helper function for average pooling with C-style array for kernel_dims, enabling automatic DIM deduction.
@@ -195,6 +199,8 @@ PaddedAvgPooling(DimSize_t const (&kernel_dims)[DIM],
                  const std::string &name = "",
                  const std::array<DimSize_t, DIM> &stride_dims =
                      create_array<DimSize_t, DIM>(1),
+                 const std::array<DimSize_t, DIM> &dilations =
+                     create_array<DimSize_t, DIM>(1),
                  const std::array<DimSize_t, 2 * DIM> &padding_dims =
                      create_array<DimSize_t, 2 * DIM>(0));
 
@@ -208,6 +214,7 @@ PaddedAvgPooling(DimSize_t const (&kernel_dims)[DIM],
  * @param[in] kernel_dims The dimensions of the pooling window.
  * @param[in] name Optional name for the operation.
  * @param[in] stride_dims The stride dimensions for pooling (default is 1).
+ * @param[in] dilations The spatial dilations for pooling (default is 1).
  * @param[in] padding_dims Padding dimensions before pooling (default is 0).
  * @param[in] ceil_mode Whether to use ceiling mode for pooling (default is false).
  * @return A shared pointer to the Node representing the padded max pooling operation.
@@ -216,11 +223,12 @@ template <std::array<DimSize_t, 1>::size_type DIM>
 inline std::shared_ptr<Node> PaddedMaxPooling(const std::array<DimSize_t, DIM> &kernel_dims,
                                   const std::string& name = "",
                                   const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+                                  const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
                                   const std::array<DimSize_t, 2*DIM> &padding_dims = create_array<DimSize_t,2*DIM>(0),
                                   bool ceil_mode = false) {
     auto graph = Sequential({
         Pad<DIM>(padding_dims, (!name.empty()) ? name + "_pad" : ""),
-        MaxPooling(kernel_dims, (!name.empty()) ? name + "_maxpooling" : "", stride_dims, ceil_mode)
+        MaxPooling(kernel_dims, (!name.empty()) ? name + "_maxpooling" : "", stride_dims, dilations, ceil_mode)
     });
 
     return MetaOperator(("PaddedMaxPooling" + std::to_string(DIM) + "D").c_str(), graph, {}, name);
@@ -233,6 +241,7 @@ inline std::shared_ptr<Node> PaddedMaxPooling(const std::array<DimSize_t, DIM> &
  *
  * @param[in] kernel_dims The dimensions of the pooling window.
  * @param[in] stride_dims The stride dimensions for pooling (default is 1).
+ * @param[in] dilations The spatial dilations for pooling (default is 1).
  * @param[in] padding_dims Padding dimensions before pooling (default is 0).
  * @param[in] ceil_mode Whether to use ceiling mode for pooling (default is false).
  * @return A shared pointer to the MetaOperator_Op representing the padded max pooling operation.
@@ -240,11 +249,12 @@ inline std::shared_ptr<Node> PaddedMaxPooling(const std::array<DimSize_t, DIM> &
 template <std::array<DimSize_t, 1>::size_type DIM>
 inline std::shared_ptr<MetaOperator_Op> PaddedMaxPooling_Op(const std::array<DimSize_t, DIM> &kernel_dims,
                                   const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+                                  const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
                                   const std::array<DimSize_t, 2*DIM> &padding_dims = create_array<DimSize_t,2*DIM>(0),
                                   bool ceil_mode = false) {
     auto graph = Sequential({
         Pad<DIM>(padding_dims, ""),
-        MaxPooling(kernel_dims, "", stride_dims, ceil_mode)
+        MaxPooling(kernel_dims, "", stride_dims, dilations, ceil_mode)
     });
     return std::make_shared<MetaOperator_Op>(("PaddedMaxPooling" + std::to_string(DIM) + "D").c_str(), graph);
 }
@@ -255,9 +265,10 @@ inline std::shared_ptr<Node> PaddedMaxPooling(
     DimSize_t const (&kernel_dims)[DIM],
     const std::string& name = "",
     const std::array<DimSize_t, DIM> &stride_dims = create_array<DimSize_t,DIM>(1),
+    const std::array<DimSize_t, DIM> &dilations = create_array<DimSize_t,DIM>(1),
     const std::array<DimSize_t, 2*DIM> &padding_dims = create_array<DimSize_t,2*DIM>(0),
     bool ceil_mode= false) {
-    return PaddedMaxPooling(to_array(kernel_dims), name, stride_dims, padding_dims, ceil_mode);
+    return PaddedMaxPooling(to_array(kernel_dims), name, stride_dims, padding_dims, dilations, ceil_mode);
 }
 
 /**
diff --git a/python_binding/operator/pybind_AvgPooling.cpp b/python_binding/operator/pybind_AvgPooling.cpp
index 24549e3f4f331ee1170a07e61a6190a607274fe3..dd227e4f48e1c94f5ab4a79c888305c394823331 100644
--- a/python_binding/operator/pybind_AvgPooling.cpp
+++ b/python_binding/operator/pybind_AvgPooling.cpp
@@ -47,11 +47,19 @@ template <DimIdx_t DIM> void declare_AvgPoolingOp(py::module &m) {
         :param stride_dims: The stride of the pooling operation. Specifies how much the kernel moves in each step.
                              By default, the stride is set to 1 for all dimensions.
         :type stride_dims: List[int], optional
+        :param dilations: The dilation value along each spatial axis of filter.
+        :type dilations: List[int], optional
+        :param ceil_mode: Whether to use ceil or floor when calculating the output dimensions.
+        :type ceil_mode: bool, optional
         )mydelimiter")
     .def(py::init<const std::array<DimSize_t, DIM> &,
-                  const std::array<DimSize_t, DIM> &>(),
+                  const std::array<DimSize_t, DIM> &,
+                  const std::array<DimSize_t, DIM> &,
+                  bool>(),
             py::arg("kernel_dims"),
-            py::arg("stride_dims") = create_array<DimSize_t, DIM>(1))
+            py::arg("stride_dims") = create_array<DimSize_t, DIM>(1),
+            py::arg("stride_dims") = create_array<DimSize_t, DIM>(1),
+            py::arg("ceil_mode") = false)
     .def("get_inputs_name", &AvgPooling_Op<DIM>::getInputsName)
     .def("get_outputs_name", &AvgPooling_Op<DIM>::getOutputsName)
     .def_readonly_static("Type", &AvgPooling_Op<DIM>::Type);
@@ -60,14 +68,19 @@ template <DimIdx_t DIM> void declare_AvgPoolingOp(py::module &m) {
 
   m.def(("AvgPooling" + std::to_string(DIM) + "D").c_str(), [](const std::vector<DimSize_t>& kernel_dims,
                                                                   const std::string& name,
-                                                                  const std::vector<DimSize_t>& stride_dims) {
+                                                                  const std::vector<DimSize_t>& stride_dims,
+                                                                  const std::vector<DimSize_t>& dilations,
+                                                                  bool ceil_mode) {
         AIDGE_ASSERT(kernel_dims.size() == DIM, "kernel_dims size [{}] does not match DIM [{}]", kernel_dims.size(), DIM);
         AIDGE_ASSERT(stride_dims.size() == DIM, "stride_dims size [{}] does not match DIM [{}]", stride_dims.size(), DIM);
+        AIDGE_ASSERT(dilations.size() == DIM, "dilations size [{}] does not match DIM [{}]", dilations.size(), DIM);
 
-        return AvgPooling<DIM>(to_array<DIM>(kernel_dims.begin()), name, to_array<DIM>(stride_dims.begin()));
+        return AvgPooling<DIM>(to_array<DIM>(kernel_dims.begin()), name, to_array<DIM>(stride_dims.begin()), to_array<DIM>(dilations.begin()), ceil_mode);
     }, py::arg("kernel_dims"),
        py::arg("name") = "",
        py::arg("stride_dims") = std::vector<DimSize_t>(DIM, 1),
+       py::arg("dilations") = std::vector<DimSize_t>(DIM, 1),
+       py::arg("ceil_mode") = false,
        R"mydelimiter(
         Initialize a node containing an AvgPooling operator.
 
@@ -75,6 +88,10 @@ template <DimIdx_t DIM> void declare_AvgPoolingOp(py::module &m) {
 
         :param kernel_dims: Size of the kernel applied during pooling.
         :type kernel_dims: List[int]
+        :param dilations: The dilation value along each spatial axis of filter.
+        :type dilations: List[int]
+        :param ceil_mode: Whether to use ceil or floor when calculating the output dimensions.
+        :type ceil_mode: bool
         :param name: Name of the operator node (optional).
         :type name: str
         :param stride_dims: Stride dimensions for the pooling operation.
diff --git a/src/operator/AvgPooling.cpp b/src/operator/AvgPooling.cpp
index 78266e3fb391d6f33da9e65b2125dd57885ac89e..6ed5f8f70f18089585e19553b7cfea9ffe459556 100644
--- a/src/operator/AvgPooling.cpp
+++ b/src/operator/AvgPooling.cpp
@@ -47,17 +47,28 @@ std::shared_ptr<Aidge::Operator> Aidge::AvgPooling_Op<DIM>::clone() const {
 template <Aidge::DimIdx_t DIM>
 bool Aidge::AvgPooling_Op<DIM>::forwardDims(bool /*allowDataDependency*/) {
     if (inputsAssociated()) {
-        std::array<DimSize_t, DIM + 2> outputDims;
+        std::array<DimSize_t, DIM + 2> outputDims{};
         const std::array<DimSize_t, DIM + 2> inputDims(getInput(0)->template dims<DIM+2>());
-        outputDims[0] = inputDims[0];
-        outputDims[1] = inputDims[1];
 
-        for (std::size_t dim = 0; dim < mAttributes->template getAttr<AvgPoolingAttr::KernelDims>().size() ; ++dim) {
+        std::function<float(float)> roundingFunction;
+        if (mAttributes->template getAttr<AvgPoolingAttr::CeilMode>()) {
+            roundingFunction = [](float x) { return std::ceil(x); };
+        } else {
+            roundingFunction = [](float x) { return std::floor(x); };
+        }
+
+        for (std::size_t dim = 0; dim < mAttributes->template getAttr<AvgPoolingAttr::KernelDims>().size(); ++dim) {
+            const auto kernelDim = mAttributes->template getAttr<AvgPoolingAttr::KernelDims>()[dim];
+            const auto strideDim = mAttributes->template getAttr<AvgPoolingAttr::StrideDims>()[dim];
+            const auto dilationDim = mAttributes->template getAttr<AvgPoolingAttr::Dilations>()[dim];
+
             outputDims[dim+2] = 1 + static_cast<DimSize_t>(
-                                        std::floor(static_cast<float>(inputDims[dim+2] -
-                                                            mAttributes->template getAttr<AvgPoolingAttr::KernelDims>()[dim]) /
-                                        static_cast<float>(mAttributes->template getAttr<AvgPoolingAttr::StrideDims>()[dim])));
+                                            roundingFunction(static_cast<float>(inputDims[dim+2] -
+                                                                    (kernelDim - 1) * dilationDim - 1) /
+                                            static_cast<float>(strideDim)));
         }
+        outputDims[1] = inputDims[1];
+        outputDims[0] = inputDims[0];
         getOutput(0)->resize(outputDims);
         return true;
     }
@@ -128,10 +139,12 @@ template class Aidge::AvgPooling_Op<4>;
 template <std::array<Aidge::DimSize_t, 1>::size_type DIM>
 std::shared_ptr<Aidge::Node> Aidge::AvgPooling(const std::array<Aidge::DimSize_t, DIM> &kernel_dims,
                                            const std::string& name,
-                                           const std::array<Aidge::DimSize_t, DIM> &stride_dims) {
+                                           const std::array<Aidge::DimSize_t, DIM> &stride_dims,
+                                           const std::array<Aidge::DimSize_t, DIM> &dilations,
+                                           bool ceil_mode) {
     AIDGE_ASSERT(DIM<=MaxDim, "Too many kernel dimensions required by {}, not supported", AvgPooling_Op<DIM>::Type);
-    return std::make_shared<Node>(std::make_shared<AvgPooling_Op<static_cast<DimIdx_t>(DIM)>>(kernel_dims, stride_dims), name);
+    return std::make_shared<Node>(std::make_shared<AvgPooling_Op<static_cast<DimIdx_t>(DIM)>>(kernel_dims, stride_dims, dilations, ceil_mode), name);
 }
-template std::shared_ptr<Aidge::Node> Aidge::AvgPooling<1>(const std::array<Aidge::DimSize_t, 1>&, const std::string&, const std::array<Aidge::DimSize_t, 1>&);
-template std::shared_ptr<Aidge::Node> Aidge::AvgPooling<2>(const std::array<Aidge::DimSize_t, 2>&, const std::string&, const std::array<Aidge::DimSize_t, 2>&);
-template std::shared_ptr<Aidge::Node> Aidge::AvgPooling<3>(const std::array<Aidge::DimSize_t, 3>&, const std::string&, const std::array<Aidge::DimSize_t, 3>&);
+template std::shared_ptr<Aidge::Node> Aidge::AvgPooling<1>(const std::array<Aidge::DimSize_t, 1>&, const std::string&, const std::array<Aidge::DimSize_t, 1>&, const std::array<Aidge::DimSize_t, 1>&, bool);
+template std::shared_ptr<Aidge::Node> Aidge::AvgPooling<2>(const std::array<Aidge::DimSize_t, 2>&, const std::string&, const std::array<Aidge::DimSize_t, 2>&, const std::array<Aidge::DimSize_t, 2>&, bool);
+template std::shared_ptr<Aidge::Node> Aidge::AvgPooling<3>(const std::array<Aidge::DimSize_t, 3>&, const std::string&, const std::array<Aidge::DimSize_t, 3>&, const std::array<Aidge::DimSize_t, 3>&, bool);