From 3e6305c64d6f1adae85b25f7baeeae922c737d04 Mon Sep 17 00:00:00 2001
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Wed, 15 Feb 2017 19:19:24 +0100
Subject: [PATCH 1/6] Add Out-of-Core option

Add MORSE_Desc_Create_OOC, which is like MORSE_Desc_Create, but does not
actually allocate a matrix, thus letting the runtime allocate on-demand the
tiles, possibly pushing them to the disk.

Add a --ooc option to tests to enable this.
---
 control/descriptor.c                        | 87 +++++++++++++++++++++
 control/descriptor.h                        | 10 +++
 docs/texinfo/chapters/configuration.texi    | 23 ++++++
 docs/texinfo/chapters/using.texi            |  3 +
 example/out_of_core/out_of_core.h           |  9 ---
 include/morse.h.in                          |  4 +
 include/morse_struct.h                      |  1 +
 runtime/starpu/control/runtime_descriptor.c |  4 +
 timing/timing.c                             |  5 ++
 timing/timing.h                             |  7 +-
 10 files changed, 143 insertions(+), 10 deletions(-)

diff --git a/control/descriptor.c b/control/descriptor.c
index e5f4146b2..2d330b8c3 100644
--- a/control/descriptor.c
+++ b/control/descriptor.c
@@ -379,6 +379,93 @@ int MORSE_Desc_Create(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, i
     return MORSE_SUCCESS;
 }
 
+/** ***************************************************************************
+ *
+ * @ingroup Descriptor
+ *
+ *  MORSE_Desc_Create_OOC - Create matrix descriptor for matrix which may not fit memory
+ *
+ ******************************************************************************
+ *
+ * @param[out] desc
+ *          On exit, descriptor of the matrix.
+ *
+ * @param[in] dtyp
+ *          Data type of the matrix:
+ *          @arg MorseRealFloat:     single precision real (S),
+ *          @arg MorseRealDouble:    double precision real (D),
+ *          @arg MorseComplexFloat:  single precision complex (C),
+ *          @arg MorseComplexDouble: double precision complex (Z).
+ *
+ * @param[in] nb
+ *          Number of rows and columns in a tile.
+ *
+ * @param[in] m
+ *          Number of rows of the entire matrix.
+ *
+ * @param[in] n
+ *          Number of columns of the entire matrix.
+ *
+ * @param[in] p
+ *          2d-block cyclic partitioning, number of tiles in rows.
+ *
+ * @param[in] q
+ *          2d-block cyclic partitioning, number of tiles in columns.
+ *
+ * @param[in] (*get_rankof)( const MORSE_desc_t *A, int m, int n)
+ *          A function that return the MPI rank of the tile A(m,n).
+ *
+ ******************************************************************************
+ *
+ * @return
+ *          \retval MORSE_SUCCESS successful exit
+ *
+ *****************************************************************************/
+int MORSE_Desc_Create_OOC(MORSE_desc_t **desc, MORSE_enum dtyp, int mb, int nb, int bsiz,
+                          int lm, int ln, int i, int j, int m, int n, int p, int q,
+                          int (*get_rankof)( const MORSE_desc_t*, int, int ))
+{
+#if !defined (CHAMELEON_SCHED_STARPU)
+    morse_error("MORSE_Desc_Create_Tiles", "Only StarPU supports on-demand tile allocation");
+    return MORSE_ERR_NOT_INITIALIZED;
+#else
+    MORSE_context_t *morse;
+    int status;
+
+    morse = morse_context_self();
+    if (morse == NULL) {
+        morse_error("MORSE_Desc_Create_Tiles", "MORSE not initialized");
+        return MORSE_ERR_NOT_INITIALIZED;
+    }
+    /* Allocate memory and initialize the descriptor */
+    *desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
+    if (*desc == NULL) {
+        morse_error("MORSE_Desc_Create_Tiles", "malloc() failed");
+        return MORSE_ERR_OUT_OF_RESOURCES;
+    }
+    **desc = morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
+        morse_getaddr_null, NULL, get_rankof);
+
+    /* memory of the matrix is completely handled by runtime */
+    (**desc).use_mat = 0;
+    (**desc).alloc_mat = 0;
+    (**desc).mat = NULL;
+
+    (**desc).ooc = 1;
+
+    /* Create scheduler structure like registering data */
+    RUNTIME_desc_create( *desc );
+
+    status = morse_desc_check(*desc);
+    if (status != MORSE_SUCCESS) {
+        morse_error("MORSE_Desc_Create_Tiles", "invalid descriptor");
+        return status;
+    }
+
+    return MORSE_SUCCESS;
+#endif
+}
+
 /** ***************************************************************************
  *
  * @ingroup Descriptor
diff --git a/control/descriptor.h b/control/descriptor.h
index 7d1cb2057..0d3d2173b 100644
--- a/control/descriptor.h
+++ b/control/descriptor.h
@@ -41,6 +41,7 @@ extern "C" {
 inline static void* morse_geteltaddr(const MORSE_desc_t *A, int m, int n, int eltsize);
 inline static void* morse_getaddr_cm    (const MORSE_desc_t *A, int m, int n);
 inline static void* morse_getaddr_ccrb  (const MORSE_desc_t *A, int m, int n);
+inline static void* morse_getaddr_null  (const MORSE_desc_t *A, int m, int n);
 inline static int   morse_getblkldd_cm  (const MORSE_desc_t *A, int m);
 inline static int   morse_getblkldd_ccrb(const MORSE_desc_t *A, int m);
 
@@ -120,6 +121,15 @@ inline static void *morse_getaddr_cm(const MORSE_desc_t *A, int m, int n)
     return (void*)((intptr_t)A->mat + (offset*eltsize) );
 }
 
+/*******************************************************************************
+ *  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 *morse_getaddr_null(const MORSE_desc_t *A, int m, int n)
+{
+    return NULL;
+}
+
 /*******************************************************************************
  *  Internal function to return address of element A(m,n) with m,n = matrix indices
  **/
diff --git a/docs/texinfo/chapters/configuration.texi b/docs/texinfo/chapters/configuration.texi
index a147cf1f9..d57a476a9 100644
--- a/docs/texinfo/chapters/configuration.texi
+++ b/docs/texinfo/chapters/configuration.texi
@@ -344,3 +344,26 @@ Database of models is subject to change, it should be enrich in a near future.
 
 One can additionally decide to enable the magma kernels by setting the cmake
 option @option{-DCHAMELEON_SIMULATION_MAGMA=ON} .
+
+@node Use out of core support with StarPU
+@section Use out of core support with StarPU
+
+If the matrix can not fit in the main memory, StarPU can automatically evict
+tiles to the disk. The following variables need to be set:
+@itemize @bullet
+@item @env{STARPU_DISK_SWAP} environment variable to a place where to store
+evicted tiles, for example:
+  @example
+  @env{STARPU_DISK_SWAP}=/tmp
+  @end example
+@item @env{STARPU_DISK_SWAP_BACKEND} environment variable to the I/O method,
+for example:
+  @example
+  @env{STARPU_DISK_SWAP_BACKEND}=unistd_o_direct
+  @end example
+@item @env{STARPU_LIMIT_CPU_MEM} environment variable to the amount of memory
+that can be used in MBytes, for example:
+  @example
+  @env{STARPU_LIMIT_CPU_MEM}=1000
+  @end example
+@end itemize
diff --git a/docs/texinfo/chapters/using.texi b/docs/texinfo/chapters/using.texi
index 47bf96ddf..4cfd8e662 100644
--- a/docs/texinfo/chapters/using.texi
+++ b/docs/texinfo/chapters/using.texi
@@ -435,6 +435,9 @@ This can be achieved from different ways.
 @item Use the existing function @code{MORSE_Desc_Create}: means the
 matrix data are considered contiguous in memory as it is considered in PLASMA
 (@ref{Tile Data Layout}).
+@item Use the existing function @code{MORSE_Desc_Create_OOC}: means the
+matrix data is allocated on-demand in memory tile by tile, and possibly pushed
+to disk if that does not fit memory.
 @item Use the existing function @code{MORSE_Desc_Create_User}: it is more
 flexible than @code{Desc_Create} because you can give your own way to access to
 tile data so that your tiles can be allocated wherever you want in memory, see
diff --git a/example/out_of_core/out_of_core.h b/example/out_of_core/out_of_core.h
index dcb9e9702..95a25dcbc 100644
--- a/example/out_of_core/out_of_core.h
+++ b/example/out_of_core/out_of_core.h
@@ -260,13 +260,4 @@ print_o_direct_wont_work(void) {
                     "multiples of 4096. Tip : chose 'n' and 'nb' as both multiples of 32.\n");
 }
 
-/******************************************************************************
- *  Ffunction to return address of block (m,n) -> here NULL because memory is
- *  directly handled by StarPU
- **/
-inline static void* morse_getaddr_null(const MORSE_desc_t *A, int m, int n)
-{
-    return (void*)( NULL );
-}
-
 #endif /* OOC_H */
diff --git a/include/morse.h.in b/include/morse.h.in
index 9473b6e1c..35a07e405 100644
--- a/include/morse.h.in
+++ b/include/morse.h.in
@@ -85,6 +85,10 @@ int MORSE_Element_Size(int type);
 int MORSE_Desc_Create  (MORSE_desc_t **desc, void *mat, MORSE_enum dtyp,
                         int mb, int nb, int bsiz, int lm, int ln,
                         int i, int j, int m, int n, int p, int q);
+int MORSE_Desc_Create_OOC (MORSE_desc_t **desc, MORSE_enum dtyp,
+                           int mb, int nb, int bsiz, int lm, int ln,
+                           int i, int j, int m, int n, int p, int q,
+                           int (*get_rankof)( const MORSE_desc_t*, int, int ));
 int MORSE_Desc_Create_User(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, int nb, int bsiz,
                            int lm, int ln, int i, int j, int m, int n, int p, int q,
                            void* (*get_blkaddr)( const MORSE_desc_t*, int, int ),
diff --git a/include/morse_struct.h b/include/morse_struct.h
index f307645d2..2aacefcdf 100644
--- a/include/morse_struct.h
+++ b/include/morse_struct.h
@@ -108,6 +108,7 @@ struct morse_desc_s {
     int alloc_mat;    // 1 if we handle the allocation of mat - else 0
     int register_mat; // 1 if we have to register mat - else 0 (handled by the application)
     int myrank;       // MPI rank of the descriptor
+    int ooc;          // 1 if the matrix is not to fit in memory
     void *schedopt;   // scheduler (QUARK|StarPU) specific structure
 };
 
diff --git a/runtime/starpu/control/runtime_descriptor.c b/runtime/starpu/control/runtime_descriptor.c
index 3f6a1e285..dc7d6ba8e 100644
--- a/runtime/starpu/control/runtime_descriptor.c
+++ b/runtime/starpu/control/runtime_descriptor.c
@@ -279,6 +279,10 @@ int RUNTIME_desc_getoncpu( MORSE_desc_t *desc )
     int lnt = desc->lnt;
     int m, n;
 
+    if (desc->ooc)
+        /* May not even fit */
+        return MORSE_SUCCESS;
+
     for (n = 0; n < lnt; n++)
         for (m = 0; m < lmt; m++)
         {
diff --git a/timing/timing.c b/timing/timing.c
index d27120296..d2b73d49b 100644
--- a/timing/timing.c
+++ b/timing/timing.c
@@ -475,6 +475,7 @@ main(int argc, char *argv[]) {
     iparam[IPARAM_TRACE         ] = 0;
     iparam[IPARAM_DAG           ] = 0;
     iparam[IPARAM_ASYNC         ] = 1;
+    iparam[IPARAM_OOC           ] = 0;
     iparam[IPARAM_MX            ] = -1;
     iparam[IPARAM_NX            ] = -1;
     iparam[IPARAM_RHBLK         ] = 0;
@@ -549,6 +550,10 @@ main(int argc, char *argv[]) {
             iparam[IPARAM_ASYNC] = 0;
         } else if (startswith( argv[i], "--async" )) {
             iparam[IPARAM_ASYNC] = 1;
+        } else if (startswith( argv[i], "--ooc" )) {
+            iparam[IPARAM_OOC] = 1;
+        } else if (startswith( argv[i], "--noooc" )) {
+            iparam[IPARAM_OOC] = 0;
         } else if (startswith( argv[i], "--n_range=" )) {
             get_range( strchr( argv[i], '=' ) + 1, &start, &stop, &step );
         } else if (startswith( argv[i], "--m=" )) {
diff --git a/timing/timing.h b/timing/timing.h
index 3d33748a6..e4c0dc6fb 100644
--- a/timing/timing.h
+++ b/timing/timing.h
@@ -38,6 +38,7 @@ enum iparam_timing {
     IPARAM_TRACE,          /* Generate trace on the first non warmup run */
     IPARAM_DAG,            /* Do we require to output the DOT file?      */
     IPARAM_ASYNC,          /* Asynchronous calls                         */
+    IPARAM_OOC,            /* Out of Core                                */
     IPARAM_MX,             /* */
     IPARAM_NX,             /* */
     IPARAM_RHBLK,          /* Householder reduction parameter for QR/LQ  */
@@ -97,6 +98,7 @@ enum dparam_timing {
     int64_t MT    = (M%MB==0) ? (M/MB) : (M/MB+1); \
     int64_t NT    = (N%NB==0) ? (N/NB) : (N/NB+1); \
     int bigmat     = iparam[IPARAM_BIGMAT];         \
+    int ooc       = iparam[IPARAM_OOC];            \
     int check     = iparam[IPARAM_CHECK];          \
     int loud      = iparam[IPARAM_VERBOSE];        \
     (void)M;(void)N;(void)K;(void)NRHS;            \
@@ -109,7 +111,10 @@ enum dparam_timing {
     MORSE_desc_t *_desc_ = NULL;                                        \
     int status ## _desc_ ; \
     if( _cond_ ) {                                                      \
-       if (!bigmat) \
+       if (ooc) \
+           status ## _desc_ = MORSE_Desc_Create_OOC(&(_desc_), _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
+                   P, Q, NULL);\
+       else if (!bigmat) \
            status ## _desc_ = MORSE_Desc_Create_User(&(_desc_), NULL, _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
                           P, Q, morse_getaddr_null, NULL, NULL);\
        else \
-- 
GitLab


From 85cbb1a28f1aee98ba68ce69c0cc3cf4390b0540 Mon Sep 17 00:00:00 2001
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Thu, 16 Feb 2017 11:04:48 +0100
Subject: [PATCH 2/6] Check the tiles sizes for OOC

---
 runtime/starpu/control/runtime_descriptor.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/runtime/starpu/control/runtime_descriptor.c b/runtime/starpu/control/runtime_descriptor.c
index dc7d6ba8e..62b84a752 100644
--- a/runtime/starpu/control/runtime_descriptor.c
+++ b/runtime/starpu/control/runtime_descriptor.c
@@ -22,6 +22,7 @@
  *
  **/
 #include <stdlib.h>
+#include <unistd.h>
 #include "runtime/starpu/include/morse_starpu.h"
 
 #if defined(CHAMELEON_USE_MPI)
@@ -118,6 +119,21 @@ void RUNTIME_desc_create( MORSE_desc_t *desc )
         }
     }
 #endif
+    if (desc->ooc) {
+        int lastmm = desc->lm - (desc->lmt-1) * desc->mb;
+        int lastnn = desc->ln - (desc->lnt-1) * desc->nb;
+        int64_t eltsze = MORSE_Element_Size(desc->dtyp);
+        int pagesize = getpagesize();
+
+        if ((desc->mb * desc->nb * eltsze) % pagesize != 0
+         || (lastmm   * desc->nb * eltsze) % pagesize != 0
+         || (desc->mb * lastnn   * eltsze) % pagesize != 0
+         || (lastmm   * lastnn   * eltsze) % pagesize != 0)
+        {
+            morse_error("RUNTIME_desc_create", "Matrix and tile size not suitable for out-of-core: all tiles have to be multiples of 4096. Tip : choose 'n' and 'nb' as both multiples of 32.");
+            return;
+        }
+    }
 
 #if defined(CHAMELEON_USE_MPI)
     /*
-- 
GitLab


From e427eecba4676f8df0f12e6de98cee9ea4aebc4d Mon Sep 17 00:00:00 2001
From: Mathieu Faverge <mathieu.faverge@inria.fr>
Date: Wed, 12 Apr 2017 12:03:36 +0200
Subject: [PATCH 3/6] Some cleanup/factorization in descriptor.c

---
 control/descriptor.c | 343 +++++++++++++++++++++++++++----------------
 1 file changed, 216 insertions(+), 127 deletions(-)

diff --git a/control/descriptor.c b/control/descriptor.c
index 2d330b8c3..8065d710c 100644
--- a/control/descriptor.c
+++ b/control/descriptor.c
@@ -38,49 +38,89 @@
 
 static int nbdesc = 0;
 
-/*******************************************************************************
- *  Internal static descriptor initializer
- **/
-MORSE_desc_t morse_desc_init(MORSE_enum dtyp, int mb, int nb, int bsiz,
-                             int lm, int ln, int i, int j,
-                             int m,  int n,  int p, int q)
-{
-  return morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
-                              morse_getaddr_ccrb, morse_getblkldd_ccrb, morse_getrankof_2d);
-}
-
-/*******************************************************************************
- *  Internal static descriptor initializer for a block diagonal matrix
- **/
-MORSE_desc_t morse_desc_init_diag(MORSE_enum dtyp, int mb, int nb, int bsiz,
-                                  int lm, int ln, int i, int j,
-                                  int m,  int n,  int p, int q)
-{
-  return morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
-                              morse_getaddr_ccrb, morse_getblkldd_ccrb, morse_getrankof_2d_diag);
-}
-
-/*******************************************************************************
- *  Static descriptor initializer for users
- **/
+/**
+ ******************************************************************************
+ *
+ * @ingroup internal_descriptor
+ *
+ * morse_desc_init_user - Internal function to create tiled matrix descriptor
+ * with generic function for data distribution and storage format.
+ *
+ ******************************************************************************
+ *
+ * @param[in] dtyp
+ *          Data type of the matrix:
+ *          @arg MorseRealFloat:     single precision real (S),
+ *          @arg MorseRealDouble:    double precision real (D),
+ *          @arg MorseComplexFloat:  single precision complex (C),
+ *          @arg MorseComplexDouble: double precision complex (Z).
+ *
+ * @param[in] mb
+ *          Number of rows in a tile.
+ *
+ * @param[in] nb
+ *          Number of columns in a tile.
+ *
+ * @param[in] bsiz
+ *          Size in bytes including padding.
+ *
+ * @param[in] lm
+ *          Number of rows of the entire matrix.
+ *
+ * @param[in] ln
+ *          Number of columns of the entire matrix.
+ *
+ * @param[in] i
+ *          Row index to the beginning of the submatrix.
+ *
+ * @param[in] j
+ *          Column indes to the beginning of the submatrix.
+ *
+ * @param[in] m
+ *          Number of rows of the submatrix.
+ *
+ * @param[in] n
+ *          Number of columns of the submatrix.
+ *
+ * @param[in] p
+ *          2D-block cyclic distribution in rows.
+ *
+ * @param[in] q
+ *          2D-block cyclic distribution in columns.
+ *
+ * @param[in] (*get_blkaddr)( const MORSE_desc_t *A, int m, int n)
+ *          A function which return the address of the data corresponding to
+ *          the tile A(m,n).
+ *
+ * @param[in] (*get_blkldd)( const MORSE_desc_t *A, int m )
+ *          A function that return the leading dimension of the tile A(m,*).
+ *
+ * @param[in] (*get_rankof)( const MORSE_desc_t *A, int m, int n)
+ *          A function that return the MPI rank of the tile A(m,n).
+ *
+ ******************************************************************************
+ *
+ * @return  The descriptor with the matrix description parameters set.
+ *
+ *****************************************************************************/
 MORSE_desc_t morse_desc_init_user(MORSE_enum dtyp, int mb, int nb, int bsiz,
                                   int lm, int ln, int i, int j,
                                   int m,  int n,  int p, int q,
                                   void* (*get_blkaddr)( const MORSE_desc_t*, int, int ),
-                                  int (*get_blkldd)( const MORSE_desc_t*, int ),
-                                  int (*get_rankof)( const MORSE_desc_t*, int, int ))
+                                  int   (*get_blkldd) ( const MORSE_desc_t*, int      ),
+                                  int   (*get_rankof) ( const MORSE_desc_t*, int, int ))
 {
     MORSE_desc_t desc;
     // If one of the function get_* is NULL, we switch back to the default, like in morse_desc_init()
     desc.get_blkaddr = get_blkaddr ? get_blkaddr : morse_getaddr_ccrb;
-    desc.get_blkldd  = get_blkldd ? get_blkldd : morse_getblkldd_ccrb;
-    desc.get_rankof  = get_rankof ? get_rankof : morse_getrankof_2d;
+    desc.get_blkldd  = get_blkldd  ? get_blkldd  : morse_getblkldd_ccrb;
+    desc.get_rankof  = get_rankof  ? get_rankof  : morse_getrankof_2d;
     // Matrix properties
     desc.dtyp = dtyp;
-    // seems useless
+    // Should be given as parameter to follow get_blkaddr (unused)
     desc.styp = MorseCCRB;
-    desc.mb = mb;
-    desc.nb = nb;
+    desc.mb   = mb;
+    desc.nb   = nb;
     desc.bsiz = bsiz;
     // Large matrix parameters
     desc.lm = lm;
@@ -99,9 +139,10 @@ MORSE_desc_t morse_desc_init_user(MORSE_enum dtyp, int mb, int nb, int bsiz,
 
     desc.id = nbdesc; nbdesc++;
     desc.occurences = 0;
-    desc.use_mat = 1;
-    desc.alloc_mat = 1;
+    desc.use_mat      = 1;
+    desc.alloc_mat    = 1;
     desc.register_mat = 1;
+    desc.ooc          = 0;
 
     RUNTIME_comm_rank( &(desc.myrank) );
 
@@ -130,12 +171,12 @@ MORSE_desc_t morse_desc_init_user(MORSE_enum dtyp, int mb, int nb, int bsiz,
         desc.llm1 = (desc.llm/mb);
         desc.lln1 = (desc.lln/nb);
     } else {
-      desc.llmt = 0;
-      desc.llnt = 0;
-      desc.llm  = 0;
-      desc.lln  = 0;
-      desc.llm1 = 0;
-      desc.lln1 = 0;
+        desc.llmt = 0;
+        desc.llnt = 0;
+        desc.llm  = 0;
+        desc.lln  = 0;
+        desc.llm1 = 0;
+        desc.lln1 = 0;
     }
 
     // Matrix address
@@ -149,10 +190,32 @@ MORSE_desc_t morse_desc_init_user(MORSE_enum dtyp, int mb, int nb, int bsiz,
     return desc;
 }
 
+/*******************************************************************************
+ *  Internal static descriptor initializer
+ **/
+MORSE_desc_t morse_desc_init(MORSE_enum dtyp, int mb, int nb, int bsiz,
+                             int lm, int ln, int i, int j,
+                             int m,  int n,  int p, int q)
+{
+    return morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
+                                morse_getaddr_ccrb, morse_getblkldd_ccrb, morse_getrankof_2d);
+}
+
+/*******************************************************************************
+ *  Internal static descriptor initializer for a block diagonal matrix
+ **/
+MORSE_desc_t morse_desc_init_diag(MORSE_enum dtyp, int mb, int nb, int bsiz,
+                                  int lm, int ln, int i, int j,
+                                  int m,  int n,  int p, int q)
+{
+    return morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
+                                morse_getaddr_ccrb, morse_getblkldd_ccrb, morse_getrankof_2d_diag);
+}
+
 /*******************************************************************************
  *  Internal static descriptor initializer for submatrices
  **/
-MORSE_desc_t* morse_desc_submatrix(MORSE_desc_t *descA, int i, int j, int m, int n )
+MORSE_desc_t* morse_desc_submatrix(MORSE_desc_t *descA, int i, int j, int m, int n)
 {
     MORSE_desc_t *descB = malloc(sizeof(MORSE_desc_t));
     int mb, nb;
@@ -237,7 +300,7 @@ int morse_desc_mat_alloc( MORSE_desc_t *desc )
 {
 
     size_t size = (size_t)(desc->llm) * (size_t)(desc->lln)
-      * (size_t)MORSE_Element_Size(desc->dtyp);
+        * (size_t)MORSE_Element_Size(desc->dtyp);
     if ((desc->mat = RUNTIME_mat_alloc(size)) == NULL) {
         morse_error("morse_desc_mat_alloc", "malloc() failed");
         return MORSE_ERR_OUT_OF_RESOURCES;
@@ -255,12 +318,12 @@ int morse_desc_mat_alloc( MORSE_desc_t *desc )
  **/
 int morse_desc_mat_free( MORSE_desc_t *desc )
 {
-
     RUNTIME_desc_destroy( desc );
 
-    if (desc->mat != NULL  &&
-        desc->use_mat == 1 &&
-        desc->alloc_mat == 1) {
+    if ( (desc->mat       != NULL) &&
+         (desc->use_mat   == 1   ) &&
+         (desc->alloc_mat == 1   ) )
+    {
         size_t size = (size_t)(desc->llm) * (size_t)(desc->lln)
             * (size_t)MORSE_Element_Size(desc->dtyp);
 
@@ -270,11 +333,12 @@ int morse_desc_mat_free( MORSE_desc_t *desc )
     return MORSE_SUCCESS;
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
- *  MORSE_Desc_Create - Create matrix descriptor.
+ *  MORSE_Desc_Create - Create tiled matrix descriptor.
  *
  ******************************************************************************
  *
@@ -331,65 +395,81 @@ int morse_desc_mat_free( MORSE_desc_t *desc )
  *          \retval MORSE_SUCCESS successful exit
  *
  *****************************************************************************/
-int MORSE_Desc_Create(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, int nb, int bsiz,
+int MORSE_Desc_Create(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, int mb, int nb, int bsiz,
                       int lm, int ln, int i, int j, int m, int n, int p, int q)
 {
     MORSE_context_t *morse;
+    MORSE_desc_t *desc;
     int status;
 
+    *descptr = NULL;
+
     morse = morse_context_self();
     if (morse == NULL) {
         morse_error("MORSE_Desc_Create", "MORSE not initialized");
         return MORSE_ERR_NOT_INITIALIZED;
     }
+
     /* Allocate memory and initialize the descriptor */
-    *desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
-    if (*desc == NULL) {
+    desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
+    if (desc == NULL) {
         morse_error("MORSE_Desc_Create", "malloc() failed");
         return MORSE_ERR_OUT_OF_RESOURCES;
     }
-    **desc = morse_desc_init(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q);
+    *desc = morse_desc_init(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q);
 
     if (mat == NULL) {
 
-        size_t size = (size_t)((*desc)->llm) * (size_t)((*desc)->lln)
-            * (size_t)MORSE_Element_Size((*desc)->dtyp);
+        size_t size = (size_t)(desc->llm) * (size_t)(desc->lln)
+            * (size_t)MORSE_Element_Size(desc->dtyp);
 
-        if (((*desc)->mat = RUNTIME_mat_alloc(size)) == NULL) {
+        if ((desc->mat = RUNTIME_mat_alloc(size)) == NULL) {
             morse_error("MORSE_Desc_Create", "malloc() failed");
             return MORSE_ERR_OUT_OF_RESOURCES;
         }
-        (*desc)->alloc_mat = 1;
+        desc->use_mat      = 1;
+        desc->alloc_mat    = 1;
+        desc->register_mat = 0;
 
     } else {
-        (*desc)->mat = mat;
-        /* memory of the matrix is handle by users */
-        (*desc)->alloc_mat = 0;
+        desc->mat = mat;
+        /* memory of the matrix is handled by users */
+        desc->alloc_mat    = 0;
+        desc->use_mat      = 1;
+        desc->register_mat = 0;
     }
 
     /* Create scheduler structure like registering data */
-    RUNTIME_desc_create( *desc );
+    RUNTIME_desc_create( desc );
 
-    status = morse_desc_check(*desc);
+    status = morse_desc_check( desc );
     if (status != MORSE_SUCCESS) {
         morse_error("MORSE_Desc_Create", "invalid descriptor");
+        MORSE_Desc_Destroy( &desc );
         return status;
     }
 
+    *descptr = desc;
     return MORSE_SUCCESS;
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
- *  MORSE_Desc_Create_OOC - Create matrix descriptor for matrix which may not fit memory
+ *  MORSE_Desc_Create_User - Create generic tiled matrix descriptor for general
+ *  applications.
  *
  ******************************************************************************
  *
  * @param[out] desc
  *          On exit, descriptor of the matrix.
  *
+ * @param[in] mat
+ *          Memory location of the matrix. If mat is NULL, the space to store
+ *          the data is automatically allocated by the call to the function.
+ *
  * @param[in] dtyp
  *          Data type of the matrix:
  *          @arg MorseRealFloat:     single precision real (S),
@@ -412,6 +492,13 @@ int MORSE_Desc_Create(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, i
  * @param[in] q
  *          2d-block cyclic partitioning, number of tiles in columns.
  *
+ * @param[in] (*get_blkaddr)( const MORSE_desc_t *A, int m, int n)
+ *          A function which return the address of the data corresponding to
+ *          the tile A(m,n).
+ *
+ * @param[in] (*get_blkldd)( const MORSE_desc_t *A, int m)
+ *          A function that return the leading dimension of the tile A(m,*).
+ *
  * @param[in] (*get_rankof)( const MORSE_desc_t *A, int m, int n)
  *          A function that return the MPI rank of the tile A(m,n).
  *
@@ -421,66 +508,70 @@ int MORSE_Desc_Create(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, i
  *          \retval MORSE_SUCCESS successful exit
  *
  *****************************************************************************/
-int MORSE_Desc_Create_OOC(MORSE_desc_t **desc, MORSE_enum dtyp, int mb, int nb, int bsiz,
-                          int lm, int ln, int i, int j, int m, int n, int p, int q,
-                          int (*get_rankof)( const MORSE_desc_t*, int, int ))
+int MORSE_Desc_Create_User(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, int mb, int nb, int bsiz,
+                           int lm, int ln, int i, int j, int m, int n, int p, int q,
+                           void* (*get_blkaddr)( const MORSE_desc_t*, int, int ),
+                           int   (*get_blkldd) ( const MORSE_desc_t*, int      ),
+                           int   (*get_rankof) ( const MORSE_desc_t*, int, int ))
 {
-#if !defined (CHAMELEON_SCHED_STARPU)
-    morse_error("MORSE_Desc_Create_Tiles", "Only StarPU supports on-demand tile allocation");
-    return MORSE_ERR_NOT_INITIALIZED;
-#else
     MORSE_context_t *morse;
+    MORSE_desc_t *desc;
     int status;
 
+    *descptr = NULL;
+
     morse = morse_context_self();
     if (morse == NULL) {
-        morse_error("MORSE_Desc_Create_Tiles", "MORSE not initialized");
+        morse_error("MORSE_Desc_Create", "MORSE not initialized");
         return MORSE_ERR_NOT_INITIALIZED;
     }
+
     /* Allocate memory and initialize the descriptor */
-    *desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
-    if (*desc == NULL) {
-        morse_error("MORSE_Desc_Create_Tiles", "malloc() failed");
+    desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
+    if (desc == NULL) {
+        morse_error("MORSE_Desc_Create", "malloc() failed");
         return MORSE_ERR_OUT_OF_RESOURCES;
     }
-    **desc = morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
-        morse_getaddr_null, NULL, get_rankof);
 
-    /* memory of the matrix is completely handled by runtime */
-    (**desc).use_mat = 0;
-    (**desc).alloc_mat = 0;
-    (**desc).mat = NULL;
+    *desc = morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
+                                 get_blkaddr, get_blkldd, get_rankof);
+
+    /* if the user gives a pointer to the overall data (tiles) we can use it */
+    desc->use_mat = (mat == NULL) ? 0 : 1;
 
-    (**desc).ooc = 1;
+    /* memory of the matrix is handled by the user */
+    desc->alloc_mat = 0;
 
-    /* Create scheduler structure like registering data */
-    RUNTIME_desc_create( *desc );
+    /* users data can have multiple forms: let him register tiles */
+    desc->register_mat = 0;
+
+    desc->mat = mat;
+
+    /* Create runtime specific structure like registering data */
+    RUNTIME_desc_create( desc );
 
-    status = morse_desc_check(*desc);
+    status = morse_desc_check( desc );
     if (status != MORSE_SUCCESS) {
-        morse_error("MORSE_Desc_Create_Tiles", "invalid descriptor");
+        morse_error("MORSE_Desc_Create", "invalid descriptor");
+        MORSE_Desc_Destroy( &desc );
         return status;
     }
 
+    *descptr = desc;
     return MORSE_SUCCESS;
-#endif
 }
 
 /** ***************************************************************************
  *
  * @ingroup Descriptor
  *
- *  MORSE_Desc_Create_User - Create matrix descriptor for general applications.
+ *  MORSE_Desc_Create_OOC - Create matrix descriptor for matrix which may not fit memory
  *
  ******************************************************************************
  *
  * @param[out] desc
  *          On exit, descriptor of the matrix.
  *
- * @param[in] mat
- *          Memory location of the matrix. If mat is NULL, the space to store
- *          the data is automatically allocated by the call to the function.
- *
  * @param[in] dtyp
  *          Data type of the matrix:
  *          @arg MorseRealFloat:     single precision real (S),
@@ -497,19 +588,12 @@ int MORSE_Desc_Create_OOC(MORSE_desc_t **desc, MORSE_enum dtyp, int mb, int nb,
  * @param[in] n
  *          Number of columns of the entire matrix.
  *
-  * @param[in] p
+ * @param[in] p
  *          2d-block cyclic partitioning, number of tiles in rows.
  *
  * @param[in] q
  *          2d-block cyclic partitioning, number of tiles in columns.
  *
- * @param[in] (*get_blkaddr)( const MORSE_desc_t *A, int m, int n)
- *          A function which return the address of the data corresponding to
- *          the tile A(m,n).
- *
- * @param[in] (*get_blkldd)( const MORSE_desc_t *A, int m)
- *          A function that return the leading dimension of the tile A(m,*).
- *
  * @param[in] (*get_rankof)( const MORSE_desc_t *A, int m, int n)
  *          A function that return the MPI rank of the tile A(m,n).
  *
@@ -519,50 +603,55 @@ int MORSE_Desc_Create_OOC(MORSE_desc_t **desc, MORSE_enum dtyp, int mb, int nb,
  *          \retval MORSE_SUCCESS successful exit
  *
  *****************************************************************************/
-int MORSE_Desc_Create_User(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, int nb, int bsiz,
-                           int lm, int ln, int i, int j, int m, int n, int p, int q,
-                           void* (*get_blkaddr)( const MORSE_desc_t*, int, int ),
-                           int (*get_blkldd)( const MORSE_desc_t*, int ),
-                           int (*get_rankof)( const MORSE_desc_t*, int, int ))
+int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int nb, int bsiz,
+                          int lm, int ln, int i, int j, int m, int n, int p, int q,
+                          int (*get_rankof)( const MORSE_desc_t*, int, int ))
 {
+#if !defined (CHAMELEON_SCHED_STARPU)
+    morse_error("MORSE_Desc_Create_Tiles", "Only StarPU supports on-demand tile allocation");
+    return MORSE_ERR_NOT_INITIALIZED;
+#else
     MORSE_context_t *morse;
+    MORSE_desc_t *desc;
     int status;
 
+    *descptr = NULL;
+
     morse = morse_context_self();
     if (morse == NULL) {
-        morse_error("MORSE_Desc_Create", "MORSE not initialized");
+        morse_error("MORSE_Desc_Create_Tiles", "MORSE not initialized");
         return MORSE_ERR_NOT_INITIALIZED;
     }
     /* Allocate memory and initialize the descriptor */
-    *desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
-    if (*desc == NULL) {
-        morse_error("MORSE_Desc_Create", "malloc() failed");
+    desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
+    if (desc == NULL) {
+        morse_error("MORSE_Desc_Create_Tiles", "malloc() failed");
         return MORSE_ERR_OUT_OF_RESOURCES;
     }
-    **desc = morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
-        get_blkaddr, get_blkldd, get_rankof);
-
-    /* if the user gives a pointer to the overall data (tiles) we can use it */
-    (**desc).use_mat = (mat == NULL) ? 0 : 1;
-
-    /* memory of the matrix is handle by users */
-    (**desc).alloc_mat = 0;
+    *desc = morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
+                                 morse_getaddr_null, NULL, get_rankof);
 
-    /* users data can have multiple forms: let him register tiles */
-    (**desc).register_mat = 0;
+    /* memory of the matrix is completely handled by runtime */
+    desc->use_mat      = 0;
+    desc->alloc_mat    = 0;
+    desc->register_mat = 0;
 
-    (**desc).mat = mat;
+    desc->mat = NULL;
+    desc->ooc = 1;
 
     /* Create scheduler structure like registering data */
-    RUNTIME_desc_create( *desc );
+    RUNTIME_desc_create( desc );
 
-    status = morse_desc_check(*desc);
+    status = morse_desc_check( desc );
     if (status != MORSE_SUCCESS) {
-        morse_error("MORSE_Desc_Create", "invalid descriptor");
+        morse_error("MORSE_Desc_Create_Tiles", "invalid descriptor");
+        MORSE_Desc_Destroy( &desc );
         return status;
     }
 
+    *descptr = desc;
     return MORSE_SUCCESS;
+#endif
 }
 
 /** ***************************************************************************
@@ -622,7 +711,7 @@ int MORSE_Desc_Destroy(MORSE_desc_t **desc)
  *
  *****************************************************************************/
 int MORSE_Desc_Acquire (MORSE_desc_t  *desc) {
-  return RUNTIME_desc_acquire( desc );
+    return RUNTIME_desc_acquire( desc );
 }
 
 /** ***************************************************************************
@@ -645,7 +734,7 @@ int MORSE_Desc_Acquire (MORSE_desc_t  *desc) {
  *
  *****************************************************************************/
 int MORSE_Desc_Release (MORSE_desc_t  *desc) {
-  return RUNTIME_desc_release( desc );
+    return RUNTIME_desc_release( desc );
 }
 
 /** ***************************************************************************
@@ -667,7 +756,7 @@ int MORSE_Desc_Release (MORSE_desc_t  *desc) {
  *
  *****************************************************************************/
 int MORSE_Desc_Getoncpu(MORSE_desc_t  *desc) {
-  return RUNTIME_desc_getoncpu( desc );
+    return RUNTIME_desc_getoncpu( desc );
 }
 
 /** ***************************************************************************
@@ -694,6 +783,6 @@ int MORSE_Desc_Getoncpu(MORSE_desc_t  *desc) {
  *
  *****************************************************************************/
 void MORSE_user_tag_size(int user_tag_width, int user_tag_sep) {
-  RUNTIME_user_tag_size(user_tag_width, user_tag_sep);
-  return;
+    RUNTIME_user_tag_size(user_tag_width, user_tag_sep);
+    return;
 }
-- 
GitLab


From 14ffa8ef0a4a7cabe34de858bab9ab7abd69a4a1 Mon Sep 17 00:00:00 2001
From: Mathieu Faverge <mathieu.faverge@inria.fr>
Date: Wed, 12 Apr 2017 13:18:59 +0200
Subject: [PATCH 4/6] Minor on documentation

---
 control/descriptor.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/control/descriptor.c b/control/descriptor.c
index 8065d710c..fc9adb216 100644
--- a/control/descriptor.c
+++ b/control/descriptor.c
@@ -41,7 +41,7 @@ static int nbdesc = 0;
 /**
  ******************************************************************************
  *
- * @ingroup internal_descriptor
+ * @ingroup Descriptor
  *
  * morse_desc_init_user - Internal function to create tiled matrix descriptor
  * with generic function for data distribution and storage format.
@@ -561,11 +561,13 @@ int MORSE_Desc_Create_User(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, i
     return MORSE_SUCCESS;
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
- *  MORSE_Desc_Create_OOC - Create matrix descriptor for matrix which may not fit memory
+ *  MORSE_Desc_Create_OOC - Create matrix descriptor for tiled matrix which may
+ *  not fit memory.
  *
  ******************************************************************************
  *
@@ -654,7 +656,8 @@ int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int n
 #endif
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
@@ -692,7 +695,8 @@ int MORSE_Desc_Destroy(MORSE_desc_t **desc)
     return MORSE_SUCCESS;
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
@@ -714,7 +718,8 @@ int MORSE_Desc_Acquire (MORSE_desc_t  *desc) {
     return RUNTIME_desc_acquire( desc );
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
@@ -737,7 +742,8 @@ int MORSE_Desc_Release (MORSE_desc_t  *desc) {
     return RUNTIME_desc_release( desc );
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
@@ -759,14 +765,15 @@ int MORSE_Desc_Getoncpu(MORSE_desc_t  *desc) {
     return RUNTIME_desc_getoncpu( desc );
 }
 
-/** ***************************************************************************
+/**
+ *****************************************************************************
  *
  * @ingroup Descriptor
  *
  *  MORSE_user_tag_size - Set the sizes for the MPI tags
- *  Default value: tag_width=31, tag_sep=24, meaning that the MPI tag is stored in 31 bits,
- *  with 24 bits for the tile tag and 7 for the descriptor.
- *  This function must be called before any descriptor creation.
+ *  Default value: tag_width=31, tag_sep=24, meaning that the MPI tag is stored
+ *  in 31 bits, with 24 bits for the tile tag and 7 for the descriptor.  This
+ *  function must be called before any descriptor creation.
  *
  ******************************************************************************
  *
-- 
GitLab


From 9b177ce0417d8b7aa8e9ed1b49bd8bba53b6ba4e Mon Sep 17 00:00:00 2001
From: Mathieu Faverge <mathieu.faverge@inria.fr>
Date: Fri, 14 Apr 2017 17:47:31 +0200
Subject: [PATCH 5/6] Add missing const to error/warning messages

---
 control/auxiliary.c | 6 +++---
 control/auxiliary.h | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/control/auxiliary.c b/control/auxiliary.c
index 14fd016ed..b00ed6efe 100644
--- a/control/auxiliary.c
+++ b/control/auxiliary.c
@@ -53,7 +53,7 @@
  *          Warning message to display.
  *
  ******************************************************************************/
-void morse_warning(const char *func_name, char* msg_text)
+void morse_warning(const char *func_name, const char *msg_text)
 {
     MORSE_context_t *morse;
 
@@ -78,7 +78,7 @@ void morse_warning(const char *func_name, char* msg_text)
  *          Warning message to display.
  *
  ******************************************************************************/
-void morse_error(const char *func_name, char* msg_text)
+void morse_error(const char *func_name, const char *msg_text)
 {
     fprintf(stderr, "MORSE ERROR: %s(): %s\n", func_name, msg_text);
 }
@@ -96,7 +96,7 @@ void morse_error(const char *func_name, char* msg_text)
  *          Warning message to display.
  *
  ******************************************************************************/
-void morse_fatal_error(const char *func_name, char* msg_text)
+void morse_fatal_error(const char *func_name, const char *msg_text)
 {
     fprintf(stderr, "MORSE FATAL ERROR: %s(): %s\n", func_name, msg_text);
     exit(0);
diff --git a/control/auxiliary.h b/control/auxiliary.h
index 653bb38a0..147fe1694 100644
--- a/control/auxiliary.h
+++ b/control/auxiliary.h
@@ -36,9 +36,9 @@ extern "C" {
 /*******************************************************************************
  *  Internal routines
  **/
-void morse_warning      (const char *func_name, char* msg_text);
-void morse_error        (const char *func_name, char* msg_text);
-void morse_fatal_error  (const char *func_name, char* msg_text);
+void morse_warning      (const char *func_name, const char* msg_text);
+void morse_error        (const char *func_name, const char* msg_text);
+void morse_fatal_error  (const char *func_name, const char* msg_text);
 int  morse_rank         (MORSE_context_t *morse);
 int  morse_tune         (MORSE_enum func, int M, int N, int NRHS);
 
-- 
GitLab


From 0e6d45c15a73138fe945d7709765d02e70911c44 Mon Sep 17 00:00:00 2001
From: Mathieu Faverge <mathieu.faverge@inria.fr>
Date: Fri, 14 Apr 2017 17:48:00 +0200
Subject: [PATCH 6/6] Add a new OOC_User function and simplifies OOC

---
 control/descriptor.c | 73 ++++++++++++++++++++++++++++++++++++--------
 include/morse.h.in   | 11 ++++---
 timing/timing.h      | 22 ++++++-------
 3 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/control/descriptor.c b/control/descriptor.c
index fc9adb216..b7963cf76 100644
--- a/control/descriptor.c
+++ b/control/descriptor.c
@@ -522,14 +522,14 @@ int MORSE_Desc_Create_User(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, i
 
     morse = morse_context_self();
     if (morse == NULL) {
-        morse_error("MORSE_Desc_Create", "MORSE not initialized");
+        morse_error("MORSE_Desc_Create_User", "MORSE not initialized");
         return MORSE_ERR_NOT_INITIALIZED;
     }
 
     /* Allocate memory and initialize the descriptor */
     desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
     if (desc == NULL) {
-        morse_error("MORSE_Desc_Create", "malloc() failed");
+        morse_error("MORSE_Desc_Create_User", "malloc() failed");
         return MORSE_ERR_OUT_OF_RESOURCES;
     }
 
@@ -552,7 +552,7 @@ int MORSE_Desc_Create_User(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, i
 
     status = morse_desc_check( desc );
     if (status != MORSE_SUCCESS) {
-        morse_error("MORSE_Desc_Create", "invalid descriptor");
+        morse_error("MORSE_Desc_Create_User", "invalid descriptor");
         MORSE_Desc_Destroy( &desc );
         return status;
     }
@@ -566,8 +566,8 @@ int MORSE_Desc_Create_User(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, i
  *
  * @ingroup Descriptor
  *
- *  MORSE_Desc_Create_OOC - Create matrix descriptor for tiled matrix which may
- *  not fit memory.
+ *  MORSE_Desc_Create_OOC_User - Create matrix descriptor for tiled matrix which
+ *  may not fit memory.
  *
  ******************************************************************************
  *
@@ -605,12 +605,12 @@ int MORSE_Desc_Create_User(MORSE_desc_t **descptr, void *mat, MORSE_enum dtyp, i
  *          \retval MORSE_SUCCESS successful exit
  *
  *****************************************************************************/
-int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int nb, int bsiz,
-                          int lm, int ln, int i, int j, int m, int n, int p, int q,
-                          int (*get_rankof)( const MORSE_desc_t*, int, int ))
+int MORSE_Desc_Create_OOC_User(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int nb, int bsiz,
+                               int lm, int ln, int i, int j, int m, int n, int p, int q,
+                               int (*get_rankof)( const MORSE_desc_t*, int, int ))
 {
 #if !defined (CHAMELEON_SCHED_STARPU)
-    morse_error("MORSE_Desc_Create_Tiles", "Only StarPU supports on-demand tile allocation");
+    morse_error("MORSE_Desc_Create_OOC_User", "Only StarPU supports on-demand tile allocation");
     return MORSE_ERR_NOT_INITIALIZED;
 #else
     MORSE_context_t *morse;
@@ -621,13 +621,13 @@ int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int n
 
     morse = morse_context_self();
     if (morse == NULL) {
-        morse_error("MORSE_Desc_Create_Tiles", "MORSE not initialized");
+        morse_error("MORSE_Desc_Create_OOC_User", "MORSE not initialized");
         return MORSE_ERR_NOT_INITIALIZED;
     }
     /* Allocate memory and initialize the descriptor */
     desc = (MORSE_desc_t*)malloc(sizeof(MORSE_desc_t));
     if (desc == NULL) {
-        morse_error("MORSE_Desc_Create_Tiles", "malloc() failed");
+        morse_error("MORSE_Desc_Create_OOC_User", "malloc() failed");
         return MORSE_ERR_OUT_OF_RESOURCES;
     }
     *desc = morse_desc_init_user(dtyp, mb, nb, bsiz, lm, ln, i, j, m, n, p, q,
@@ -646,7 +646,7 @@ int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int n
 
     status = morse_desc_check( desc );
     if (status != MORSE_SUCCESS) {
-        morse_error("MORSE_Desc_Create_Tiles", "invalid descriptor");
+        morse_error("MORSE_Desc_Create_OOC_User", "invalid descriptor");
         MORSE_Desc_Destroy( &desc );
         return status;
     }
@@ -656,6 +656,55 @@ int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int n
 #endif
 }
 
+/**
+ *****************************************************************************
+ *
+ * @ingroup Descriptor
+ *
+ *  MORSE_Desc_Create_OOC - Create matrix descriptor for tiled matrix which may
+ *  not fit memory.
+ *
+ ******************************************************************************
+ *
+ * @param[out] desc
+ *          On exit, descriptor of the matrix.
+ *
+ * @param[in] dtyp
+ *          Data type of the matrix:
+ *          @arg MorseRealFloat:     single precision real (S),
+ *          @arg MorseRealDouble:    double precision real (D),
+ *          @arg MorseComplexFloat:  single precision complex (C),
+ *          @arg MorseComplexDouble: double precision complex (Z).
+ *
+ * @param[in] nb
+ *          Number of rows and columns in a tile.
+ *
+ * @param[in] m
+ *          Number of rows of the entire matrix.
+ *
+ * @param[in] n
+ *          Number of columns of the entire matrix.
+ *
+ * @param[in] p
+ *          2d-block cyclic partitioning, number of tiles in rows.
+ *
+ * @param[in] q
+ *          2d-block cyclic partitioning, number of tiles in columns.
+ *
+ ******************************************************************************
+ *
+ * @return
+ *          \retval MORSE_SUCCESS successful exit
+ *
+ *****************************************************************************/
+int MORSE_Desc_Create_OOC(MORSE_desc_t **descptr, MORSE_enum dtyp, int mb, int nb, int bsiz,
+                          int lm, int ln, int i, int j, int m, int n, int p, int q)
+{
+    return MORSE_Desc_Create_OOC_User( descptr, dtyp, mb, nb, bsiz,
+                                       lm, ln, i, j, m, n, p, q,
+                                       morse_getrankof_2d );
+}
+
 /**
  *****************************************************************************
  *
diff --git a/include/morse.h.in b/include/morse.h.in
index 35a07e405..b0460b695 100644
--- a/include/morse.h.in
+++ b/include/morse.h.in
@@ -85,15 +85,18 @@ int MORSE_Element_Size(int type);
 int MORSE_Desc_Create  (MORSE_desc_t **desc, void *mat, MORSE_enum dtyp,
                         int mb, int nb, int bsiz, int lm, int ln,
                         int i, int j, int m, int n, int p, int q);
-int MORSE_Desc_Create_OOC (MORSE_desc_t **desc, MORSE_enum dtyp,
-                           int mb, int nb, int bsiz, int lm, int ln,
-                           int i, int j, int m, int n, int p, int q,
-                           int (*get_rankof)( const MORSE_desc_t*, int, int ));
 int MORSE_Desc_Create_User(MORSE_desc_t **desc, void *mat, MORSE_enum dtyp, int mb, int nb, int bsiz,
                            int lm, int ln, int i, int j, int m, int n, int p, int q,
                            void* (*get_blkaddr)( const MORSE_desc_t*, int, int ),
                            int (*get_blkldd)( const MORSE_desc_t*, int ),
                            int (*get_rankof)( const MORSE_desc_t*, int, int ));
+int MORSE_Desc_Create_OOC(MORSE_desc_t **desc, MORSE_enum dtyp,
+                          int mb, int nb, int bsiz, int lm, int ln,
+                          int i, int j, int m, int n, int p, int q);
+int MORSE_Desc_Create_OOC_User(MORSE_desc_t **desc, MORSE_enum dtyp,
+                               int mb, int nb, int bsiz, int lm, int ln,
+                               int i, int j, int m, int n, int p, int q,
+                               int (*get_rankof)( const MORSE_desc_t*, int, int ));
 int MORSE_Desc_Destroy (MORSE_desc_t **desc);
 int MORSE_Desc_Acquire (MORSE_desc_t  *desc);
 int MORSE_Desc_Release (MORSE_desc_t  *desc);
diff --git a/timing/timing.h b/timing/timing.h
index e4c0dc6fb..1b4bacb35 100644
--- a/timing/timing.h
+++ b/timing/timing.h
@@ -109,18 +109,18 @@ enum dparam_timing {
 /* Paste code to allocate a matrix in desc if cond_init is true */
 #define PASTE_CODE_ALLOCATE_MATRIX_TILE(_desc_, _cond_, _type_, _type2_, _lda_, _m_, _n_) \
     MORSE_desc_t *_desc_ = NULL;                                        \
-    int status ## _desc_ ; \
+    int status ## _desc_ ;                                              \
     if( _cond_ ) {                                                      \
-       if (ooc) \
-           status ## _desc_ = MORSE_Desc_Create_OOC(&(_desc_), _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
-                   P, Q, NULL);\
-       else if (!bigmat) \
-           status ## _desc_ = MORSE_Desc_Create_User(&(_desc_), NULL, _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
-                          P, Q, morse_getaddr_null, NULL, NULL);\
-       else \
-           status ## _desc_ = MORSE_Desc_Create(&(_desc_), NULL, _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
-                    P, Q);\
-        if (status ## _desc_ != MORSE_SUCCESS) return (status ## _desc_);          \
+        if (ooc)                                                        \
+            status ## _desc_ = MORSE_Desc_Create_OOC(&(_desc_), _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
+                                                     P, Q);             \
+        else if (!bigmat)                                               \
+            status ## _desc_ = MORSE_Desc_Create_User(&(_desc_), NULL, _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
+                                                      P, Q, morse_getaddr_null, NULL, NULL); \
+        else                                                            \
+            status ## _desc_ = MORSE_Desc_Create(&(_desc_), NULL, _type2_, MB, NB, MB*NB, _lda_, _n_, 0, 0, _m_, _n_, \
+                                                 P, Q);                 \
+        if (status ## _desc_ != MORSE_SUCCESS) return (status ## _desc_); \
     }
 
 #define PASTE_CODE_FREE_MATRIX(_desc_)                                  \
-- 
GitLab