diff --git a/compute/CMakeLists.txt b/compute/CMakeLists.txt
index 815eb60bf947d77c444e078598ea6894c521fd9b..e42f0917b0af8a3d213cfb6a8235a92158a29af2 100644
--- a/compute/CMakeLists.txt
+++ b/compute/CMakeLists.txt
@@ -38,6 +38,7 @@ set(CHAMELEON_CONTROL
     ../control/control.c
     ../control/descriptor.c
     ../control/descriptor_rec.c
+    ../control/descriptor_helpers.c
     ../control/workspace.c
     ../control/tile.c
     ../control/chameleon_f77.c
diff --git a/control/descriptor.c b/control/descriptor.c
index 7e4e6117b9549a106f63ddb4eeb71c58749cfb82..09130a5c374f87d68ed712f20368fc8c6182fe8f 100644
--- a/control/descriptor.c
+++ b/control/descriptor.c
@@ -113,27 +113,6 @@ void chameleon_desc_init_tiles( CHAM_desc_t *desc, blkrankof_fct_t rankof )
     }
 }
 
-/**
- *  Internal function to return MPI rank of element A(m,n) with m,n = block indices
- */
-int chameleon_getrankof_2d( const CHAM_desc_t *A, int m, int n )
-{
-    int mm = m + A->i / A->mb;
-    int nn = n + A->j / A->nb;
-    return (mm % A->p) * A->q + (nn % A->q);
-}
-
-/**
- *  Internal function to return MPI rank of element DIAG(m,0) with m,n = block indices
- */
-int chameleon_getrankof_2d_diag( const CHAM_desc_t *A, int m, int n )
-{
-    int mm = m + A->i / A->mb;
-    assert( m == n );
-    (void)n;
-    return (mm % A->p) * A->q + (mm % A->q);
-}
-
 /**
  ******************************************************************************
  *
diff --git a/control/descriptor.h b/control/descriptor.h
index 1e0d883f61db4ff6365fbeaf76e4323124f48240..50eb614b6d9b890dadd69d764e49f5107f9a4dd7 100644
--- a/control/descriptor.h
+++ b/control/descriptor.h
@@ -37,20 +37,6 @@ extern "C" {
 /**
  *  Internal routines
  */
-inline static void* chameleon_geteltaddr(const CHAM_desc_t *A, int m, int n, int eltsize);
-inline static void* chameleon_getaddr_cm    (const CHAM_desc_t *A, int m, int n);
-inline static void* chameleon_getaddr_ccrb  (const CHAM_desc_t *A, int m, int n);
-inline static void* chameleon_getaddr_null  (const CHAM_desc_t *A, int m, int n);
-inline static void* chameleon_getaddr_diag  (const CHAM_desc_t *A, int m, int n);
-inline static int   chameleon_getblkldd_cm  (const CHAM_desc_t *A, int m);
-inline static int   chameleon_getblkldd_ccrb(const CHAM_desc_t *A, int m);
-
-/**
- *  Data distributions
- */
-int chameleon_getrankof_2d(const CHAM_desc_t *desc, int m, int n);
-int chameleon_getrankof_2d_diag(const CHAM_desc_t *desc, int m, int n);
-
 static inline int chameleon_getrankof_tile(const CHAM_desc_t *desc, int m, int n) {
     CHAM_tile_t *tile = desc->get_blktile( desc, m, n );
     assert( tile != NULL );
@@ -87,78 +73,6 @@ CHAM_desc_t* chameleon_desc_submatrix( CHAM_desc_t *descA, int i, int j, int m,
 void         chameleon_desc_destroy  ( CHAM_desc_t *desc );
 int          chameleon_desc_check    ( const CHAM_desc_t *desc );
 
-/**
- *  Internal function to return address of block (m,n) with m,n = block indices
- */
-inline static void* chameleon_getaddr_ccrb(const CHAM_desc_t *A, int m, int n)
-{
-    size_t mm = m + A->i / A->mb;
-    size_t nn = n + A->j / A->nb;
-    size_t eltsize = CHAMELEON_Element_Size(A->dtyp);
-    size_t offset = 0;
-
-#if defined(CHAMELEON_USE_MPI)
-    assert( A->myrank == A->get_rankof( A, mm, nn) );
-    mm = mm / A->p;
-    nn = nn / A->q;
-#endif
-
-    if (mm < (size_t)(A->llm1)) {
-        if (nn < (size_t)(A->lln1))
-            offset = (size_t)(A->bsiz) * (mm + (size_t)(A->llm1) * nn);
-        else
-            offset = A->A12 + ((size_t)(A->mb * (A->lln%A->nb)) * mm);
-    }
-    else {
-        if (nn < (size_t)(A->lln1))
-            offset = A->A21 + ((size_t)((A->llm%A->mb) * A->nb) * nn);
-        else
-            offset = A->A22;
-    }
-
-    return (void*)((intptr_t)A->mat + (offset*eltsize) );
-}
-
-/**
- *  Internal function to return address of block (m,n) with m,n = block indices
- */
-inline static void *chameleon_getaddr_cm(const CHAM_desc_t *A, int m, int n)
-{
-    size_t mm = m + A->i / A->mb;
-    size_t nn = n + A->j / A->nb;
-    size_t eltsize = CHAMELEON_Element_Size(A->dtyp);
-    size_t offset = 0;
-
-#if defined(CHAMELEON_USE_MPI)
-    assert( A->myrank == A->get_rankof( A, mm, nn) );
-    mm = mm / A->p;
-    nn = nn / A->q;
-#endif
-
-    offset = (size_t)(A->llm * A->nb) * nn + (size_t)(A->mb) * mm;
-    return (void*)((intptr_t)A->mat + (offset*eltsize) );
-}
-
-/**
- *  Internal function to return address of block (m,n) with m,n = block indices
- */
-inline static void *chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n )
-{
-    assert( m == n );
-    (void)n;
-    return chameleon_getaddr_ccrb( A, m, 0 );
-}
-
-/**
- *  Internal function to return address of block (m,n) with m,n = block indices
- *  This version lets the runtime allocate on-demand.
- */
-inline static void *chameleon_getaddr_null(const CHAM_desc_t *A, int m, int n)
-{
-    (void)A; (void)m; (void)n;
-    return NULL;
-}
-
 /**
  *  Internal function to return address of block (m,n) with m,n = block indices
  */
@@ -204,20 +118,6 @@ inline static void* chameleon_geteltaddr(const CHAM_desc_t *A, int m, int n, int
     return (void*)((intptr_t)A->mat + (offset*eltsize) );
 }
 
-/**
- *  Internal function to return the leading dimension of element A(m,*) with m,n = block indices
- */
-inline static int chameleon_getblkldd_ccrb(const CHAM_desc_t *A, int m)
-{
-    int mm = m + A->i / A->mb;
-    return ( ((mm+1) == A->lmt) && ((A->lm % A->mb) != 0)) ? A->lm % A->mb : A->mb;
-}
-
-inline static int chameleon_getblkldd_cm(const CHAM_desc_t *A, int m) {
-    (void)m;
-    return A->llm;
-}
-
 /**
  * Detect if the tile is local or not
  */
diff --git a/control/descriptor_helpers.c b/control/descriptor_helpers.c
new file mode 100644
index 0000000000000000000000000000000000000000..36a7023ce0386b79a7ed944c63965bc7d7740a88
--- /dev/null
+++ b/control/descriptor_helpers.c
@@ -0,0 +1,263 @@
+/**
+ *
+ * @file descriptor_helpers.c
+ *
+ * @copyright 2009-2014 The University of Tennessee and The University of
+ *                      Tennessee Research Foundation. All rights reserved.
+ * @copyright 2012-2022 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ ***
+ *
+ * @brief Chameleon descriptors routines
+ *
+ * @version 1.2.0
+ * @author Mathieu Faverge
+ * @author Cedric Castagnede
+ * @author Florent Pruvost
+ * @author Guillaume Sylvand
+ * @author Raphael Boucherie
+ * @author Samuel Thibault
+ * @date 2022-02-22
+ *
+ ***
+ *
+ * @defgroup Descriptor
+ * @brief Group descriptor routines exposed to users
+ *
+ */
+#define _GNU_SOURCE 1
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include "control/common.h"
+#include "control/descriptor.h"
+#include "chameleon/runtime.h"
+
+/**
+ * @brief Return the rank of the tile A( m, n ) in a classic 2D Block Cyclic
+ * distribution PxQ.
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile.
+ *
+ * @param[in] m
+ *        The row index of the tile.
+ *
+ * @param[in] n
+ *        The column index of the tile.
+ *
+ * @return The rank of the tile A( m, n )
+ *
+ */
+int chameleon_getrankof_2d( const CHAM_desc_t *A, int m, int n )
+{
+    int mm = m + A->i / A->mb;
+    int nn = n + A->j / A->nb;
+    return (mm % A->p) * A->q + (nn % A->q);
+}
+
+/**
+ * @brief Return the rank associated to the diagonal tile ( m, m ) of a classic
+ * 2D Block Cyclic distribution PxQ.
+ *
+ * @param[in] A
+ *        A specific matrix descriptor that holds only diagonal tiles. Thus, n is never used.
+ *
+ * @param[in] m
+ *        The row and column index of the tile.
+ *
+ * @param[in] n
+ *        Unused
+ *
+ * @return The rank of the tile A( m, m )
+ *
+ */
+int chameleon_getrankof_2d_diag( const CHAM_desc_t *A, int m, int n )
+{
+    int mm = m + A->i / A->mb;
+    (void)n;
+    return (mm % A->p) * A->q + (mm % A->q);
+}
+
+/**
+ * @brief Return the address of the tile A( m, n ) in a tile storage.
+ *
+ * @WARNING The only mapping valid with this data storage is the 2D block cyclic
+ * storage as soon as multiple nodes are involved (see chameleon_getrankof_2d()).
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile.
+ *
+ * @param[in] m
+ *        The row index of the tile.
+ *
+ * @param[in] n
+ *        The column index of the tile.
+ *
+ * @return The address of the tile A( m, n )
+ *
+ */
+void* chameleon_getaddr_ccrb( const CHAM_desc_t *A, int m, int n )
+{
+    size_t mm = m + A->i / A->mb;
+    size_t nn = n + A->j / A->nb;
+    size_t eltsize = CHAMELEON_Element_Size(A->dtyp);
+    size_t offset  = 0;
+
+#if defined(CHAMELEON_USE_MPI)
+    assert( A->myrank == A->get_rankof( A, mm, nn ) );
+    mm = mm / A->p;
+    nn = nn / A->q;
+#endif
+
+    if (mm < (size_t)(A->llm1)) {
+        if (nn < (size_t)(A->lln1))
+            offset = (size_t)(A->bsiz) * (mm + (size_t)(A->llm1) * nn );
+        else
+            offset = A->A12 + ((size_t)(A->mb * (A->lln%A->nb)) * mm );
+    }
+    else {
+        if (nn < (size_t)(A->lln1))
+            offset = A->A21 + ((size_t)((A->llm%A->mb) * A->nb) * nn );
+        else
+            offset = A->A22;
+    }
+
+    return (void*)((intptr_t)A->mat + (offset*eltsize) );
+}
+
+/**
+ * @brief Return the address of the tile A( m, n ) in a column major storage.
+ *
+ * @WARNING The only mapping valid with this data storage is the 2D block cyclic
+ * storage as soon as multiple nodes are involved (see chameleon_getrankof_2d()).
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile.
+ *
+ * @param[in] m
+ *        The row index of the tile.
+ *
+ * @param[in] n
+ *        The column index of the tile.
+ *
+ * @return The address of the tile A( m, n )
+ *
+ */
+void *chameleon_getaddr_cm( const CHAM_desc_t *A, int m, int n )
+{
+    size_t mm = m + A->i / A->mb;
+    size_t nn = n + A->j / A->nb;
+    size_t eltsize = CHAMELEON_Element_Size(A->dtyp);
+    size_t offset = 0;
+
+#if defined(CHAMELEON_USE_MPI)
+    assert( A->myrank == A->get_rankof( A, mm, nn ) );
+    mm = mm / A->p;
+    nn = nn / A->q;
+#endif
+
+    offset = (size_t)(A->llm * A->nb) * nn + (size_t)(A->mb) * mm;
+    return (void*)((intptr_t)A->mat + (offset*eltsize) );
+}
+
+/**
+ * @brief Return the address of the tile A( m, m ) in a tile storage.
+ *
+ * @WARNING The only mapping valid with this data storage is the diagonal 2D block cyclic
+ * storage as soon as multiple nodes are involved (see chameleon_getrankof_2d_diag()).
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile.
+ *
+ * @param[in] m
+ *        The row and column index of the tile.
+ *
+ * @param[in] n
+ *        Unused.
+ *
+ * @return The address of the tile A( m, n )
+ *
+ */
+void *chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n )
+{
+    (void)n;
+    return chameleon_getaddr_ccrb( A, m, 0 );
+}
+
+/**
+ * @brief Return the address of the tile A( m, m ) in a dynamic storage.
+ *
+ * Template that returns a NULL address for all tiles. This is used jointly with
+ * the StarPU runtime system to allocate data on the fly and it can be used with
+ * any data mapping.
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile (unused).
+ *
+ * @param[in] m
+ *        The row index of the tile (unused).
+ *
+ * @param[in] n
+ *        The column index of the tile (unused).
+ *
+ * @return A null pointer
+ *
+ */
+void *chameleon_getaddr_null( const CHAM_desc_t *A, int m, int n )
+{
+    (void)A; (void)m; (void)n;
+    return NULL;
+}
+
+/**
+ * @brief Return the leading dimension of the tile A( m, m ) stored in a tiled storage.
+ *
+ * This functions returns the leading dimension of the tile A( m, n ) and since
+ * the tiled storage is compatible with any mapping strategy, this function is
+ * also valid for any mapping.
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile.
+ *
+ * @param[in] m
+ *        The row index of the tile.
+ *
+ * @param[in] n
+ *        The column index of the tile.
+ *
+ * @return The leading dimension of the tile A( m, n ).
+ *
+ */
+int chameleon_getblkldd_ccrb( const CHAM_desc_t *A, int m )
+{
+    int mm = m + A->i / A->mb;
+    return ( ((mm+1) == A->lmt) && ((A->lm % A->mb) != 0)) ? A->lm % A->mb : A->mb;
+}
+
+/**
+ * @brief Return the leading dimension of the tile A( m, m ) stored in a column major storage.
+ *
+ * This functions returns the leading dimension of the tile A( m, n ) gfor
+ * column major storage. It can be only be used jointly with
+ * chameleon_getaddr_cm() and chameleon_getrankof_2d().
+ *
+ * @param[in] A
+ *        The matrix descriptor in which to find the tile.
+ *
+ * @param[in] m
+ *        The row index of the tile.
+ *
+ * @param[in] n
+ *        The column index of the tile.
+ *
+ * @return The leading dimension of the tile A( m, n ).
+ *
+ */
+int chameleon_getblkldd_cm( const CHAM_desc_t *A, int m )
+{
+    (void)m;
+    return A->llm;
+}
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 19dce38527e59cc76d83a3a1a23588429fbd547c..da47c6e21722c9acaf99a785540e92b2c2a25171 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -58,6 +58,7 @@ set(CHAMELEON_HDRS
   chameleon/timer.h
   chameleon/types.h
   chameleon/flops.h
+  chameleon/descriptor_helpers.h
   )
 
 # Add generated headers
diff --git a/include/chameleon.h b/include/chameleon.h
index 175cb73f7d18148bffea2c780a24f26c9a14fbea..2dd55582aa680933212a0ae1d90d2e5881609348 100644
--- a/include/chameleon.h
+++ b/include/chameleon.h
@@ -30,6 +30,7 @@
 #include "chameleon/constants.h"
 #include "chameleon/types.h"
 #include "chameleon/struct.h"
+#include "chameleon/descriptor_helpers.h"
 
 /* ****************************************************************************
  * CHAMELEON runtime common API
diff --git a/include/chameleon/descriptor_helpers.h b/include/chameleon/descriptor_helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..575ed18a3afba3994512177c680a7fdedbd683d8
--- /dev/null
+++ b/include/chameleon/descriptor_helpers.h
@@ -0,0 +1,74 @@
+/**
+ *
+ * @file descriptor_helpers.h
+ *
+ * @copyright 2009-2014 The University of Tennessee and The University of
+ *                      Tennessee Research Foundation. All rights reserved.
+ * @copyright 2012-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ ***
+ *
+ * @brief Set of functions to help the user to declare matrix descriptors (allocation, mapping... )
+ *
+ * @version 1.0.0
+ * @author Jakub Kurzak
+ * @author Mathieu Faverge
+ * @author Cedric Castagnede
+ * @author Florent Pruvost
+ * @author Guillaume Sylvand
+ * @author Raphael Boucherie
+ * @author Samuel Thibault
+ * @date 2020-03-03
+ *
+ * @addtogroup chameleon_descriptors
+ * @{
+ *   @brief Set of predefined functions to produce standard matrix mappings
+ *
+ *   This module provides the set of functions to produce standard mapping of
+ *   the matrix tiles among processors, as well as associated function to: get a
+ *   tile address within a specific storage, get a tile leading dimension, ...
+ *
+ */
+#ifndef _chameleon_descriptor_helpers_h_
+#define _chameleon_descriptor_helpers_h_
+
+#include <chameleon/struct.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name Mapping functions
+ * @{
+ */
+int chameleon_getrankof_2d      ( const CHAM_desc_t *A, int m, int n );
+int chameleon_getrankof_2d_diag ( const CHAM_desc_t *A, int m, int n );
+
+/**
+ * @}
+ * @name Block address functions
+ * @{
+ */
+void* chameleon_getaddr_cm  ( const CHAM_desc_t *A, int m, int n );
+void* chameleon_getaddr_ccrb( const CHAM_desc_t *A, int m, int n );
+void* chameleon_getaddr_null( const CHAM_desc_t *A, int m, int n );
+void* chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n );
+
+/**
+ * @}
+ * @name Leading dimension functions
+ * @{
+ */
+int chameleon_getblkldd_cm  ( const CHAM_desc_t *A, int m );
+int chameleon_getblkldd_ccrb( const CHAM_desc_t *A, int m );
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _chameleon_descriptor_helpers_h_ */
diff --git a/testing/testing_zprint.c b/testing/testing_zprint.c
index 46ae4f9838de05fa32c061032e4931863bba6e8d..ccc9c7fa0a2ec6aab08bdb901b4dfb19728fc32c 100644
--- a/testing/testing_zprint.c
+++ b/testing/testing_zprint.c
@@ -22,34 +22,6 @@
 #include "testing_zcheck.h"
 #include <chameleon/flops.h>
 
-/**
- *  Internal function to return address of block (m,n) with m,n = block indices
- */
-inline static void *
-chameleon_getaddr_cm( const CHAM_desc_t *A, int m, int n )
-{
-    size_t mm      = m + A->i / A->mb;
-    size_t nn      = n + A->j / A->nb;
-    size_t eltsize = CHAMELEON_Element_Size( A->dtyp );
-    size_t offset  = 0;
-
-#if defined(CHAMELEON_USE_MPI)
-    assert( A->myrank == A->get_rankof( A, mm, nn ) );
-    mm = mm / A->p;
-    nn = nn / A->q;
-#endif
-
-    offset = (size_t)( A->llm * A->nb ) * nn + (size_t)( A->mb ) * mm;
-    return (void *)( (intptr_t)A->mat + ( offset * eltsize ) );
-}
-
-inline static int
-chameleon_getblkldd_cm( const CHAM_desc_t *A, int m )
-{
-    (void)m;
-    return A->llm;
-}
-
 int
 testing_zprint_desc( run_arg_list_t *args, int check )
 {