From 2037e9be40edbc07a1417b20cf0ca164adf0d9d7 Mon Sep 17 00:00:00 2001
From: Raphael Boucherie <raphael.boucherie@inria.fr>
Date: Wed, 2 Aug 2017 14:32:47 +0200
Subject: [PATCH] Add lapack timing and fix --n_range option

---
 timing/CMakeLists.txt        |  27 ++++++++
 timing/time_zgeqrf_lapacke.c | 127 +++++++++++++++++++++++++++++++++++
 timing/timing.c              |  51 +++++++++-----
 3 files changed, 189 insertions(+), 16 deletions(-)
 create mode 100644 timing/time_zgeqrf_lapacke.c

diff --git a/timing/CMakeLists.txt b/timing/CMakeLists.txt
index 19f3a16f7..e6621eb6d 100644
--- a/timing/CMakeLists.txt
+++ b/timing/CMakeLists.txt
@@ -229,6 +229,33 @@ endforeach()
 #-------- Tests ---------
 include(CTestLists.cmake)
 
+# Add BLAS/LAPACK timings
+set(ZSRC_LAPACKE
+  time_zgeqrf_lapacke.c
+  )
+
+precisions_rules_py(TIMINGS_LAPACKE "${ZSRC_LAPACKE}"
+  PRECISIONS "${CHAMELEON_PRECISION}")
+
+foreach(_timing ${TIMINGS_LAPACKE})
+    get_filename_component(_name_exe ${_timing} NAME_WE)
+    add_executable(${_name_exe} ${_timing})
+    add_dependencies(${_name_exe} timing_include)
+    set_property(TARGET ${_name_exe} PROPERTY LINKER_LANGUAGE Fortran)
+    target_compile_definitions(${_name_exe} PRIVATE TIMING_LAPACKE)
+    target_link_libraries(${_name_exe}
+      coreblas
+      ${LAPACKE_LIBRARIES}
+      ${TMG_LIBRARIES}
+      ${CBLAS_LIBRARIES}
+      ${LAPACK_MT_LIBRARIES}
+      ${BLAS_MT_LIBRARIES}
+      ${EXTRA_LIBRARIES}
+    )
+    install(TARGETS ${_name_exe}
+            DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/chameleon/timing)
+endforeach()
+
 ###
 ### END CMakeLists.txt
 ###
diff --git a/timing/time_zgeqrf_lapacke.c b/timing/time_zgeqrf_lapacke.c
new file mode 100644
index 000000000..1753a6958
--- /dev/null
+++ b/timing/time_zgeqrf_lapacke.c
@@ -0,0 +1,127 @@
+/**
+ *
+ * @copyright (c) 2009-2014 The University of Tennessee and The University
+ *                          of Tennessee Research Foundation.
+ *                          All rights reserved.
+ * @copyright (c) 2012-2014 Inria. All rights reserved.
+ * @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+ *
+ **/
+
+/**
+ *
+ * @precisions normal z -> c d s
+ *
+ **/
+#define _TYPE  MORSE_Complex64_t
+#define _PREC  double
+#define _LAMCH LAPACKE_dlamch_work
+
+#define _NAME  "MORSE_zgeqrf"
+/* See Lawn 41 page 120 */
+#define _FMULS FMULS_GEQRF(M, N)
+#define _FADDS FADDS_GEQRF(M, N)
+
+#include "./timing.c"
+#include "timing_zauxiliary.h"
+
+#if defined( _WIN32 ) || defined( _WIN64 )
+#include <windows.h>
+#include <time.h>
+#include <sys/timeb.h>
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+#define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+#else
+#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+#endif
+
+struct timezone
+{
+    int  tz_minuteswest; /* minutes W of Greenwich */
+    int  tz_dsttime;     /* type of dst correction */
+};
+
+int gettimeofday(struct timeval* tv, struct timezone* tz)
+{
+    FILETIME         ft;
+    unsigned __int64 tmpres = 0;
+    static int       tzflag;
+
+    if (NULL != tv)
+        {
+            GetSystemTimeAsFileTime(&ft);
+            tmpres |=  ft.dwHighDateTime;
+            tmpres <<= 32;
+            tmpres |=  ft.dwLowDateTime;
+
+            /*converting file time to unix epoch*/
+            tmpres /= 10;  /*convert into microseconds*/
+            tmpres -= DELTA_EPOCH_IN_MICROSECS;
+
+            tv->tv_sec  = (long)(tmpres / 1000000UL);
+            tv->tv_usec = (long)(tmpres % 1000000UL);
+        }
+    if (NULL != tz)
+        {
+            if (!tzflag)
+                {
+                    _tzset();
+                    tzflag++;
+                }
+            tz->tz_minuteswest = _timezone / 60;
+            tz->tz_dsttime     = _daylight;
+        }
+    return 0;
+}
+
+#else  /* Non-Windows */
+#include <sys/time.h>
+#endif
+
+/*
+ * struct timeval {time_t tv_sec; suseconds_t tv_usec;};
+ */
+double cWtime(void)
+{
+    struct timeval tp;
+    gettimeofday( &tp, NULL );
+    return tp.tv_sec + 1e-6 * tp.tv_usec;
+}
+
+static int
+RunTest(int *iparam, double *dparam, morse_time_t *t_)
+{
+    MORSE_Complex64_t *tau;
+    PASTE_CODE_IPARAM_LOCALS( iparam );
+
+    if ( M != N && check ) {
+        fprintf(stderr, "Check cannot be perfomed with M != N\n");
+        check = 0;
+    }
+
+    /* Allocate Data */
+    PASTE_CODE_ALLOCATE_MATRIX( A, 1, MORSE_Complex64_t, LDA, N );
+
+    /* Initialize Data */
+    CORE_zplrnt(M, N, A, LDA,
+                M, 0, 0, 3456);
+
+    /* Allocate Workspace */
+    tau = malloc( chameleon_min( M, N ) * sizeof(MORSE_Complex64_t) );
+
+    t = - cWtime();
+    LAPACKE_zgeqrf( LAPACK_COL_MAJOR, M, N, A, LDA, tau );
+    t += cWtime();
+    *t_ = t;
+
+    /* Check the solution */
+    if ( check )
+    {
+    }
+
+    /* Free Workspace */
+    free( tau );
+    free( A );
+
+    return 0;
+}
diff --git a/timing/timing.c b/timing/timing.c
index ca5f3d1b7..33c8ac131 100644
--- a/timing/timing.c
+++ b/timing/timing.c
@@ -63,6 +63,10 @@
 #include <getopt.h>
 #endif /* defined(CHAMELEON_HAVE_GETOPT_H) */
 
+#ifdef TIMING_LAPACKE
+int MORSE_My_Mpi_Rank() { return 0; }
+#endif
+
 static int RunTest(int *iparam, _PREC *dparam, double *t_);
 static inline void* morse_getaddr_null(const MORSE_desc_t *A, int m, int n)
 {
@@ -198,6 +202,7 @@ Test(int64_t n, int *iparam) {
         }
         gflops = flops / t[iter];
 
+#ifndef TIMING_LAPACKE
 #if defined (CHAMELEON_SCHED_STARPU)
         /* TODO: create chameleon interface encapsulating this instead */
         if (iparam[IPARAM_BOUND])
@@ -209,6 +214,7 @@ Test(int64_t n, int *iparam) {
             upper_gflops  = (flops / (tmin / 1000.0));
             sumgf_upper += upper_gflops;
         }
+#endif
 #endif
         sumt   += t[iter];
         sumgf  += gflops;
@@ -496,7 +502,7 @@ set_iparam_default(int *iparam){
     iparam[IPARAM_THRDNBR       ] = -1;
     iparam[IPARAM_THRDNBR_SUBGRP] = 1;
     iparam[IPARAM_M             ] = -1;
-    iparam[IPARAM_N             ] = 500;
+    iparam[IPARAM_N             ] = -1;
     iparam[IPARAM_K             ] = 1;
     iparam[IPARAM_LDA           ] = -1;
     iparam[IPARAM_LDB           ] = -1;
@@ -624,7 +630,8 @@ parse_arguments(int *_argc, char ***_argv, int *iparam, int *start, int *stop, i
 
 int
 main(int argc, char *argv[]) {
-    int i, m, mx, nx;
+    int i, m, n, mx, nx;
+    int status;
     int nbnode = 1;
     int start =  500;
     int stop  = 5000;
@@ -644,10 +651,12 @@ main(int argc, char *argv[]) {
     }
 #endif
 
+    n  = iparam[IPARAM_N];
     m  = iparam[IPARAM_M];
     mx = iparam[IPARAM_MX];
     nx = iparam[IPARAM_NX];
 
+#ifndef TIMING_LAPACKE
     /* Initialize MORSE */
     MORSE_Init( iparam[IPARAM_THRDNBR],
                 iparam[IPARAM_NCUDAS] );
@@ -709,27 +718,37 @@ main(int argc, char *argv[]) {
 
     if (step < 1) step = 1;
 
-    int status = Test( -1, iparam ); /* print header */
+    status = Test( -1, iparam ); /* print header */
     if (status != MORSE_SUCCESS) return status;
-    for (i = start; i <= stop; i += step)
-    {
-        if ( nx > 0 ) {
-            iparam[IPARAM_M] = i;
-            iparam[IPARAM_N] = chameleon_max(1, i/nx);
-        } else if ( mx > 0 ) {
-            iparam[IPARAM_M] = chameleon_max(1, i/mx);
-            iparam[IPARAM_N] = i;
-        } else {
-            if ( m == -1 )
+    if ( n == -1 ){
+        for (i = start; i <= stop; i += step)
+        {
+            if ( nx > 0 ) {
                 iparam[IPARAM_M] = i;
-            iparam[IPARAM_N] = i;
+            iparam[IPARAM_N] = chameleon_max(1, i/nx);
+            } else if ( mx > 0 ) {
+                iparam[IPARAM_M] = chameleon_max(1, i/mx);
+                iparam[IPARAM_N] = i;
+            } else {
+                if ( m == -1 )
+                    iparam[IPARAM_M] = i;
+                iparam[IPARAM_N] = i;
+            }
+            status = Test( iparam[IPARAM_N], iparam );
+            if (status != MORSE_SUCCESS) return status;
+            success += status;
         }
-        int status = Test( iparam[IPARAM_N], iparam );
+    } else{
+        if ( m == -1 )
+            iparam[IPARAM_M] = n;
+        iparam[IPARAM_N] = n;
+        status = Test( iparam[IPARAM_N], iparam );
         if (status != MORSE_SUCCESS) return status;
         success += status;
     }
-
+#ifndef TIMING_LAPACKE
     MORSE_Finalize();
+#endif
     return success;
 }
 
-- 
GitLab