diff --git a/testings/CMakeLists.txt b/testings/CMakeLists.txt
index 59ed2e4a187111a491535103cd576ebd2a9e90a7..3bd2e5a2367a48a46b3a9799df9ed671124ff24b 100644
--- a/testings/CMakeLists.txt
+++ b/testings/CMakeLists.txt
@@ -12,9 +12,10 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 set(TESTINGS
+  draw_hqr.c
+  draw_systolic.c
   testing_pivgen.c
   testing_tileinit.c
-  testing_treedraw.c
   )
 
 foreach (_file ${TESTINGS})
diff --git a/testings/common.c b/testings/common.c
new file mode 100644
index 0000000000000000000000000000000000000000..53cc61fdda9a711f5a49966c19bf1fe2209a8c6b
--- /dev/null
+++ b/testings/common.c
@@ -0,0 +1,229 @@
+/**
+ *
+ * @file common.c
+ *
+ * @copyright 2017      Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ * @version 0.1.0
+ * @author Mathieu Faverge
+ * @date 2017-04-27
+ *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "common.h"
+
+#if defined(LIBHQR_HAVE_GETOPT_H)
+#include <getopt.h>
+#endif  /* defined(LIBHQR_HAVE_GETOPT_H) */
+
+#ifndef max
+#define max( _a, _b ) ((_a) < (_b) ? (_a) : (_b))
+#endif
+
+/**
+ * @brief Print usage details of the testings
+ */
+static void
+print_usage(void)
+{
+    fprintf(stderr,
+            "Mandatory argument:\n"
+            " -N                : Dimension (NT) of the matrices (required)\n"
+            "Optional arguments:\n"
+            " -P --grid-rows    : Rows (P) in the PxQ process grid (default: 1)\n"
+            " -Q --grid-cols    : Cols (Q) in the PxQ process grid (default: 1)\n"
+            " -c --cores        : Number of cores per node for automatically configured  trees (default: 1)\n"
+            "\n"
+            " -M                : Dimension (MT) of the matrices (default: NT)\n"
+            "\n"
+            " -a --qr_a         : Size of TS domain. (default: -1)\n"
+            " -p --qr_p         : Size of the high level tree for distributed mode (default: -1)\n"
+            " -d --domino       : Enable/Disable the domino between upper and lower trees. (default: -1)\n"
+            " -r --tsrr         : Enable/Disable the round-robin on TS domain (under dev.). (default: Disabled)\n"
+            " -l --treel        : Tree used for low level reduction inside nodes (default: -1).\n"
+            " -L --treeh        : Tree used for high level reduction between nodes, only if qr_p > 1 (default: -1).\n"
+            "                      (0: Flat, 1: Greedy, 2: Fibonacci, 3: Binary, 4: Replicated greedy)\n"
+            "\n"
+            " -x --check        : verify the results\n"
+            " -v --verbose      : extra verbose output\n"
+            " -h --help         : this message\n"
+            "\n"
+            );
+}
+
+#define GETOPT_STRING "M:N:P:Q:c:a:p:d::rl:L:xv::h"
+#if defined(LIBHQR_HAVE_GETOPT_LONG)
+static struct option long_options[] =
+{
+    /* Generic Options */
+    {"M",           required_argument,  0, 'M'},
+    {"N",           required_argument,  0, 'N'},
+    {"grid-rows",   required_argument,  0, 'P'},
+    {"P",           required_argument,  0, 'P'},
+    {"grid-cols",   required_argument,  0, 'Q'},
+    {"Q",           required_argument,  0, 'Q'},
+    {"c",           required_argument,  0, 'c'},
+    {"cores",       required_argument,  0, 'c'},
+
+    /* HQR options */
+    {"a",           required_argument,  0, 'a'},
+    {"qr_a",        required_argument,  0, 'a'},
+    {"p",           required_argument,  0, 'p'},
+    {"qr_p",        required_argument,  0, 'p'},
+    {"d",           optional_argument,  0, 'd'},
+    {"domino",      optional_argument,  0, 'd'},
+    {"r",           no_argument,        0, 'r'},
+    {"tsrr",        no_argument,        0, 'r'},
+    {"l",           required_argument,  0, 'l'},
+    {"treel",       required_argument,  0, 'l'},
+    {"L",           required_argument,  0, 'L'},
+    {"treeh",       required_argument,  0, 'L'},
+
+    /* Auxiliary options */
+    {"check",       no_argument,        0, 'x'},
+    {"x",           no_argument,        0, 'x'},
+    {"verbose",     optional_argument,  0, 'v'},
+    {"v",           optional_argument,  0, 'v'},
+    {"help",        no_argument,        0, 'h'},
+    {"h",           no_argument,        0, 'h'},
+    {0, 0, 0, 0}
+};
+#endif  /* defined(LIBHQR_HAVE_GETOPT_LONG) */
+
+/**
+ * @brief Set default values
+ */
+static void
+iparam_default(int *iparam)
+{
+    /* Just in case someone forget to add the initialization :) */
+    memset(iparam, 0, IPARAM_SIZEOF * sizeof(int));
+    iparam[IPARAM_NNODES]       = 1;
+    iparam[IPARAM_NCORES]       = 1;
+    iparam[IPARAM_P]            = 1;
+    iparam[IPARAM_Q]            = 1;
+    iparam[IPARAM_MT]           = -'N';
+    iparam[IPARAM_NT]           = 1;
+    iparam[IPARAM_CHECK]        = 0;
+    iparam[IPARAM_VERBOSE]      = 0;
+    iparam[IPARAM_LOWLVL_TREE]  = -1;
+    iparam[IPARAM_HIGHLVL_TREE] = -1;
+    iparam[IPARAM_QR_TS_SZE]    = -1;
+    iparam[IPARAM_QR_HLVL_SZE]  = -'P';
+    iparam[IPARAM_QR_DOMINO]    = -1;
+    iparam[IPARAM_QR_TSRR]      = 0;
+}
+
+/**
+ * @brief Parse options
+ */
+void
+parse_arguments(int *_argc, char ***_argv, int *iparam)
+{
+    int opt = 0;
+    int c;
+    int argc = *_argc;
+    char **argv = *_argv;
+
+    iparam_default( iparam );
+
+    do {
+#if defined(LIBHQR_HAVE_GETOPT_LONG)
+        c = getopt_long_only(argc, argv, "",
+                             long_options, &opt);
+#else
+        c = getopt(argc, argv, GETOPT_STRING);
+        (void) opt;
+#endif  /* defined(LIBHQR_HAVE_GETOPT_LONG) */
+
+        switch(c)
+        {
+            case 'c': iparam[IPARAM_NCORES] = atoi(optarg); break;
+            case 'P': iparam[IPARAM_P]      = atoi(optarg); break;
+            case 'Q': iparam[IPARAM_Q]      = atoi(optarg); break;
+            case 'M': iparam[IPARAM_MT]     = atoi(optarg); break;
+            case 'N': iparam[IPARAM_NT]     = atoi(optarg); break;
+            case 'x': iparam[IPARAM_CHECK]  = 1; iparam[IPARAM_VERBOSE] = max(2, iparam[IPARAM_VERBOSE]); break;
+
+                /* HQR parameters */
+            case 'a': iparam[IPARAM_QR_TS_SZE]    = atoi(optarg); break;
+            case 'p': iparam[IPARAM_QR_HLVL_SZE]  = atoi(optarg); break;
+            case 'd': iparam[IPARAM_QR_DOMINO]    = atoi(optarg) ? 1 : 0; break;
+            case 'r': iparam[IPARAM_QR_TSRR]      = 1; break;
+            case 'l': iparam[IPARAM_LOWLVL_TREE]  = atoi(optarg); break;
+            case 'L': iparam[IPARAM_HIGHLVL_TREE] = atoi(optarg); break;
+
+            case 'v':
+                if(optarg)  iparam[IPARAM_VERBOSE] = atoi(optarg);
+                else        iparam[IPARAM_VERBOSE] = 2;
+                break;
+
+            case 'h': print_usage(); exit(0);
+            case '?': /* getopt_long already printed an error message. */
+                exit(1);
+            default:
+                break; /* Assume anything else is parsec/mpi stuff */
+        }
+    } while(-1 != c);
+
+    if(-'N' == iparam[IPARAM_MT]) iparam[IPARAM_MT] = iparam[IPARAM_NT];
+    if(-'P' == iparam[IPARAM_QR_HLVL_SZE]) iparam[IPARAM_QR_HLVL_SZE] = iparam[IPARAM_P];
+    if(-'Q' == iparam[IPARAM_QR_HLVL_SZE]) iparam[IPARAM_QR_HLVL_SZE] = iparam[IPARAM_Q];
+
+    iparam[IPARAM_NNODES] = iparam[IPARAM_P] * iparam[IPARAM_Q];
+}
+
+/*
+static void
+print_arguments(int* iparam)
+{
+    int verbose = iparam[IPARAM_RANK] ? 0 : iparam[IPARAM_VERBOSE];
+
+    if(verbose)
+        fprintf(stderr, "#+++++ cores detected       : %d\n", iparam[IPARAM_NCORES]);
+
+    if(verbose > 1) fprintf(stderr, "#+++++ nodes x cores + gpu  : %d x %d + %d (%d+%d)\n"
+                                    "#+++++ P x Q                : %d x %d (%d/%d)\n",
+                            iparam[IPARAM_NNODES],
+                            iparam[IPARAM_NCORES],
+                            iparam[IPARAM_NGPUS],
+                            iparam[IPARAM_NNODES] * iparam[IPARAM_NCORES],
+                            iparam[IPARAM_NNODES] * iparam[IPARAM_NGPUS],
+                            iparam[IPARAM_P], iparam[IPARAM_Q],
+                            iparam[IPARAM_Q] * iparam[IPARAM_P], iparam[IPARAM_NNODES]);
+
+    if(verbose)
+    {
+        fprintf(stderr, "#+++++ M x N x K|NRHS       : %d x %d x %d\n",
+                iparam[IPARAM_M], iparam[IPARAM_N], iparam[IPARAM_K]);
+    }
+
+    if(verbose > 2)
+    {
+        if(iparam[IPARAM_LDB] && iparam[IPARAM_LDC])
+            fprintf(stderr, "#+++++ LDA , LDB , LDC      : %d , %d , %d\n", iparam[IPARAM_LDA], iparam[IPARAM_LDB], iparam[IPARAM_LDC]);
+        else if(iparam[IPARAM_LDB])
+            fprintf(stderr, "#+++++ LDA , LDB            : %d , %d\n", iparam[IPARAM_LDA], iparam[IPARAM_LDB]);
+        else
+            fprintf(stderr, "#+++++ LDA                  : %d\n", iparam[IPARAM_LDA]);
+    }
+
+    if(verbose)
+    {
+        if(iparam[IPARAM_IB] > 0)
+            fprintf(stderr, "#+++++ MB x NB , IB         : %d x %d , %d\n",
+                            iparam[IPARAM_MB], iparam[IPARAM_NB], iparam[IPARAM_IB]);
+        else
+            fprintf(stderr, "#+++++ MB x NB              : %d x %d\n",
+                    iparam[IPARAM_MB], iparam[IPARAM_NB]);
+        if(iparam[IPARAM_SNB] * iparam[IPARAM_SMB] != 1)
+            fprintf(stderr, "#+++++ SMB x SNB            : %d x %d\n", iparam[IPARAM_SMB], iparam[IPARAM_SNB]);
+        if((iparam[IPARAM_HNB] != iparam[IPARAM_NB]) || (iparam[IPARAM_HMB] != iparam[IPARAM_MB]))
+            fprintf(stderr, "#+++++ HMB x HNB            : %d x %d\n", iparam[IPARAM_HMB], iparam[IPARAM_HNB]);
+    }
+}
+ */
diff --git a/testings/common.h b/testings/common.h
new file mode 100644
index 0000000000000000000000000000000000000000..72dad3d246fa3b8cb8cb45c12d0a1693874d9d47
--- /dev/null
+++ b/testings/common.h
@@ -0,0 +1,58 @@
+/**
+ *
+ * @file common.h
+ *
+ * @copyright 2017      Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ * @version 0.1.0
+ * @author Mathieu Faverge
+ * @date 2017-04-27
+ *
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+/**
+ * @brief List of integer options
+ */
+typedef enum iparam_e {
+  IPARAM_NNODES,       /**< Number of nodes                             */
+  IPARAM_NCORES,       /**< Number of cores                             */
+  IPARAM_P,            /**< Rows in the process grid                    */
+  IPARAM_Q,            /**< Columns in the process grid                 */
+  IPARAM_MT,           /**< Number of tile rows of the matrix           */
+  IPARAM_NT,           /**< Number of tile columns of the matrix        */
+  IPARAM_CHECK,        /**< Checking activated or not                   */
+  IPARAM_VERBOSE,      /**< How much noise do we want?                  */
+  IPARAM_LOWLVL_TREE,  /**< Tree used for reduction inside nodes        */
+  IPARAM_HIGHLVL_TREE, /**< Tree used for reduction between nodes       */
+  IPARAM_QR_TS_SZE,    /**< Size of TS domain                           */
+  IPARAM_QR_HLVL_SZE,  /**< Size of the high level tree                 */
+  IPARAM_QR_DOMINO,    /**< Enable/disable the domino tree              */
+  IPARAM_QR_TSRR,      /**< Enable/disable the round-robin on TS domain */
+  IPARAM_SIZEOF        /**< Size of the parameter array                 */
+} iparam_e;
+
+#define PASTE_CODE_IPARAM_LOCALS(iparam)                                \
+    int nodes = iparam[IPARAM_NNODES];                                  \
+    int cores = iparam[IPARAM_NCORES];                                  \
+    int P     = iparam[IPARAM_P];                                       \
+    int Q     = iparam[IPARAM_Q];                                       \
+    int MT    = iparam[IPARAM_MT];                                      \
+    int NT    = iparam[IPARAM_NT];                                      \
+    int check = iparam[IPARAM_CHECK];                                   \
+    int loud  = iparam[IPARAM_VERBOSE];                                 \
+    int llvl  = iparam[IPARAM_LOWLVL_TREE];                             \
+    int hlvl  = iparam[IPARAM_HIGHLVL_TREE];                            \
+    int qr_a  = iparam[IPARAM_QR_TS_SZE];                               \
+    int qr_p  = iparam[IPARAM_QR_HLVL_SZE];                             \
+    int domino= iparam[IPARAM_QR_DOMINO];                               \
+    int tsrr  = iparam[IPARAM_QR_TSRR];                                 \
+    (void)nodes;(void)cores;(void)P;(void)Q;(void)MT;(void)NT;          \
+    (void)llvl;(void)hlvl;(void)qr_a;(void)qr_p;(void)domino;(void)tsrr;\
+    (void)loud;(void)check;
+
+void parse_arguments(int *_argc, char ***_argv, int *iparam);
+
+#endif /* _COMMON_H_ */
diff --git a/testings/draw_hqr.c b/testings/draw_hqr.c
new file mode 100644
index 0000000000000000000000000000000000000000..7a515c39ee116e4458b64bba32bfdd3569feb43d
--- /dev/null
+++ b/testings/draw_hqr.c
@@ -0,0 +1,44 @@
+/**
+ *
+ * @file drawhqr.c
+ *
+ * Binary to draw hierarchical trees.
+ *
+ * @copyright 2017      Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ * @version 1.0.0
+ * @author Raphael Boucherie
+ * @author Mathieu Faverge
+ * @date 2017-04-04
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libhqr.h>
+#include <libhqr_draw.h>
+#include "common.h"
+
+int
+main(int argc, char ** argv)
+{
+    libhqr_tree_t qrtree;
+    libhqr_tiledesc_t matrix;
+    int iparam[IPARAM_SIZEOF];
+
+    /* Get options */
+    parse_arguments( &argc, &argv, iparam );
+    PASTE_CODE_IPARAM_LOCALS( iparam );
+
+    matrix.nodes = nodes;
+    matrix.p     = P;
+    matrix.mt    = MT;
+    matrix.nt    = NT;
+
+    libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, llvl, hlvl, qr_a, qr_p, domino, tsrr );
+    libhqr_print_tree( &qrtree, &matrix );
+    libhqr_hqr_finalize( &qrtree );
+
+    return 1;
+}
diff --git a/testings/draw_systolic.c b/testings/draw_systolic.c
new file mode 100644
index 0000000000000000000000000000000000000000..08a24aa14543bc3383afd28cbcb46688ed690cf5
--- /dev/null
+++ b/testings/draw_systolic.c
@@ -0,0 +1,44 @@
+/**
+ *
+ * @file drawsystolic.c
+ *
+ * Binary to draw systolic trees.
+ *
+ * @copyright 2017      Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ * @version 1.0.0
+ * @author Raphael Boucherie
+ * @author Mathieu Faverge
+ * @date 2017-04-04
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libhqr.h>
+#include <libhqr_draw.h>
+#include "common.h"
+
+int
+main(int argc, char ** argv)
+{
+    libhqr_tree_t qrtree;
+    libhqr_tiledesc_t matrix;
+    int iparam[IPARAM_SIZEOF];
+
+    /* Get options */
+    parse_arguments( &argc, &argv, iparam );
+    PASTE_CODE_IPARAM_LOCALS( iparam );
+
+    matrix.nodes = nodes;
+    matrix.p     = P;
+    matrix.mt    = MT;
+    matrix.nt    = NT;
+
+    libhqr_systolic_init( &qrtree, LIBHQR_QR, &matrix, P, Q );
+    libhqr_print_tree( &qrtree, &matrix );
+    libhqr_systolic_finalize( &qrtree );
+
+    return 1;
+}
diff --git a/testings/testing_treedraw.c b/testings/testing_treedraw.c
deleted file mode 100644
index a9b1ed3bf94bda6aa1ef540b345630e55a353c5e..0000000000000000000000000000000000000000
--- a/testings/testing_treedraw.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- *
- * @file testting_treedraw.c
- *
- * Testing file for drawing functions and drawing tree
- *
- * @copyright 2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
- *                      Univ. Bordeaux. All rights reserved.
- *
- * @version 1.0.0
- * @author Raphael Boucherie
- * @author Mathieu Faverge
- * @date 2017-04-04
- *
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "libhqr.h"
-#include "libhqr_draw.h"
-
-int
-main(int argc, char ** argv)
-{
-    libhqr_tree_t qrtree;
-    libhqr_tiledesc_t matrix;
-    matrix.nodes = 1;
-    matrix.p     = 1;
-    matrix.mt    = 16;
-    matrix.nt    = 4;
-    libhqr_hqr_init( &qrtree, LIBHQR_QR, &matrix, LIBHQR_BINARY_TREE, LIBHQR_FLAT_TREE, 1, 2, 0, 0);
-    libhqr_print_tree( &qrtree, &matrix);
-    libhqr_hqr_finalize( &qrtree );
-    return 1;
-}