diff --git a/include/aidge/scheduler/MemoryManager.hpp b/include/aidge/scheduler/MemoryManager.hpp
index 94add56e8afdebb8e42f7ae49a32da2aeed9e9cb..2e397d1dbaa1cc8d8f586d15363cbd2245963152 100644
--- a/include/aidge/scheduler/MemoryManager.hpp
+++ b/include/aidge/scheduler/MemoryManager.hpp
@@ -19,6 +19,25 @@
 #include "aidge/graph/Node.hpp"
 
 namespace Aidge {
+/**
+ * @brief The MemoryManager can be used to generate an optimized static memory 
+ * layout for a computing graph in a global memory space.
+ * The are some assumptions:
+ * - A MemoryManager represents a single global memory space, filled with 
+ *   contiguous, non-overlapping MemorySpace chunks.
+ * - A MemorySpace contains one or multiple MemoryPlane, each MemoryPlane
+ *   corresponding to the allocation of a specific Tensor. When a Tensor can re-
+ *   use the memory of the preceding one (for in-place or partially in-place
+ *   operators), multiple overlapping MemoryPlane can be created in the same 
+ *   MemorySpace (remember, MemorySpace **cannot** be overlapping!).
+ * - A MemoryPlane is tailored for handling (N)HWC data with two properties:
+ *   - Possibility of wrapping: on the H axis (each W*C block is contiguous).
+ *   - Possibility of concatenation: on the C axis (C1+C2+...+Cn).
+ * - All the sizes and offets specified in a MemoryManager are expressed in
+ *   number of data elements, or **words**, meaning currently a uniform data 
+ *   precision is expected in a MemoryManager (for instance, if the precision is
+ *   16-bits, each data element will be 2 bytes, which will be the size of a word).
+ */
 class MemoryManager {
 public:
     typedef int Clock_T;
@@ -45,18 +64,45 @@ public:
             allocated(clock_),
             released(-1) {}
 
+        /// Offset of the MemorySpace in the MemoryManager global memory space (in words)
         unsigned int offset;
+        /// Size of the MemorySpace (in words)
         unsigned int size;
         std::set<std::shared_ptr<Node> > dependencies;
         Clock_T allocated;
         Clock_T released;
     };
 
-    // MemoryPlane belongs to a MemorySpace. Any number of potentially
-    // overlapping planes can be associated to a MemorySpace.
-    // MemoryPlane can be non-contiguous (in case of stride, or wrapping, when
-    // offset + size > memSpace.size).
-    // MemoryPlane cannot be re-arranged inside a MemorySpace.
+    /**
+     * @brief MemoryPlane belongs to a MemorySpace. Any number of potentiall
+     * overlapping planes can be associated to a MemorySpace.
+     * MemoryPlane can be non-contiguous (in case of stride, or wrapping, when
+     * offset + size > memSpace.size).
+     * MemoryPlane cannot be re-arranged inside a MemorySpace.
+     * 
+     * A MemoryPlane is tailored for handling (N)HWC data with two properties:
+     * - Possibility of wrapping: on the H axis (each W*C block is contiguous).
+     * - Possibility of concatenation: on the C axis (C1+C2+...+Cn).
+     * 
+     * Detail of (N)HWC data handling:
+     * - \p length is the size of contiguous and non-breakable memory line (W in HWC);
+     * - \p count is the number of memory lines of size \p length constituting a memory block (H in HWC);
+     * - \p stride is the number of channels, or memory blocks, *in total*, 
+     *   of \p count lines of size \p length (C in NHWC);
+     * - \p size is the number of channels, or memory blocks, *in this MemoryPlane*,
+     *   of \p count lines of size \p length.
+     *   In the case of concatenation, there can be multiple overlapping MemoryPlane
+     *   with different size, like NHWC = NHW(C1+C2):
+     *   - MemoryPlane#1: \p size = C1 and \p stride = C=C1+C2
+     *   - MemoryPlane#2: \p size = C2 and \p stride = C=C1+C2
+     *                    (with an additionnal relative offset of +C1)
+     * In this mode, wrapping can only occur on the H (\p count) axis. W*C chunks
+     * are garanteed to be contiguous (\p length * \p stride).
+     * 
+     * By default, \p stride = \p size, \p count = 1 and \p length = 1, meaning
+     * there is no NHWC layout and the MemoryPlane can be wrapped **anywhere**.
+     * In this case, \p size is the total size of the MemoryPlane (H*W*C, in words).
+     */
     struct MemoryPlane {
         MemoryPlane(std::shared_ptr<MemorySpace> memSpace_,
                     Clock_T clock_,
@@ -92,36 +138,91 @@ public:
                 <= memSpace->offset + memSpace->size);
         }
 
+        /**
+         * @brief Get the total size of the MemoryPlane, including the stride.
+         * 
+         * @return unsigned int Total size in words
+         */
         inline unsigned int getSize() const {
             return stride * length * count;
         }
 
+        /**
+         * @brief Get the useful size of the MemoryPlane, as if its memory blocks
+         * were contiguous, without stride.
+         * 
+         * @return unsigned int Useful size in words
+         */
         inline unsigned int getUsefulSize() const {
             return size * length * count;
         }
 
+        /**
+         * @brief Get the absolute offset of the beginning of the memory plane.
+         * 
+         * @return unsigned int Contiguous offset in words
+         */
         inline unsigned int getContiguousOffset() const {
             return memSpace->offset + offset;
         }
 
+        /**
+         * @brief Get the size of the contiguous part of the memory plane, from
+         * its beginning to the limit of the MemorySpace size.
+         * If the MemoryPlane fill the MemorySpace without wrapping, the contiguous
+         * size will be the same as the total size of the MemoryPlane.
+         * 
+         * @return unsigned int Contiguous size in words
+         */
         inline unsigned int getContiguousSize() const {
             return std::min(getSize(), getLimit());
         }
 
+        /**
+         * @brief Get the absolute offset of the wrapped part of the memory plane.
+         * Since the wrapped part of the memory plane begins at the beginning of
+         * the MemorySpace, the returned offset is always the same as the MemorySpace
+         * offset.
+         * 
+         * @return unsigned int Wrapped offset in words
+         */
         inline unsigned int getWrappedOffset() const {
             return memSpace->offset;
         }
 
+        /**
+         * @brief Get the size of the wrapped part of the memory plane, from
+         * the beginning of the MemorySpace to the total size of the MemoryPlane,
+         * including the stride.
+         * If the MemoryPlane fill the MemorySpace without wrapping, the wrapped
+         * size will 0.
+         * 
+         * @return unsigned int Wrapped size in words
+         */
         inline unsigned int getWrappedSize() const {
             return getSize() - getContiguousSize();
         }
 
+        /**
+         * @brief Get the absolute offset after the end of the memory plane (if it
+         * is wrapped, the offset will correspond to the end of the wrapped part).
+         * The word at the final offset is not included in the MemoryPlane.
+         * 
+         * @return unsigned int Final offset in words
+         */
         inline unsigned int getFinalOffset() const {
             return (getWrappedSize() > 0)
                 ? getWrappedOffset() + getWrappedSize()
                 : getContiguousOffset() + getContiguousSize();
         }
 
+        /**
+         * @brief Get the absolute offset after the end of the contiguous part
+         * of the memory plane.
+         * The word at the upper offset is not included in the MemoryPlane.
+         * 
+         * @return unsigned int Upper offset in words
+         */
         inline unsigned int getUpperOffset() const {
             return (getContiguousOffset() + getContiguousSize());
         }
@@ -146,10 +247,29 @@ public:
 
         std::shared_ptr<MemorySpace> memSpace;
         Clock_T allocated;
+        /// Relative offset of the MemoryPlane in the MemorySpace (in words)
         unsigned int offset;
+        /// Number of channels, or memory blocks, *in this MemoryPlane*,
+        /// of \p count lines of size \p length.
+        /// In the case of concatenation, there can be multiple overlapping MemoryPlane
+        /// with different size, like NHWC = NHW(C1+C2):
+        /// - MemoryPlane#1: \p size = C1 and \p stride = C=C1+C2
+        /// - MemoryPlane#2: \p size = C2 and \p stride = C=C1+C2
+        ///                  (with an additionnal relative offset of +C1)
+        /// By default, \p stride = \p size, \p count = 1 and \p length = 1, meaning
+        /// there is no NHWC layout and the MemoryPlane can be wrapped **anywhere**.
+        /// In this case, \p size is the total size of the MemoryPlane (H*W*C, in words).
         unsigned int size;
+        /// Number of channels, or memory blocks *in total*,
+        /// of \p count lines of size \p length (the C in NHWC).
+        /// There should be C blocks of H*W size.
         unsigned int stride;
+        /// Size of an elementary, contiguous and non-breakable, memory line 
+        /// (the W in NHWC), in words. A MemoryPlane wrapping cannot occur in
+        /// the middle of a memory line.
         unsigned int length;
+        /// Number of memory lines of size \p length constituting a memory block
+        /// (the H in NHWC). The size of a memory block is H*W.
         unsigned int count;
     };