From 2816d3e944a1f4c913f8858e15f249040433023a Mon Sep 17 00:00:00 2001
From: Mathieu Faverge <mathieu.faverge@inria.fr>
Date: Wed, 11 Mar 2020 18:58:47 +0100
Subject: [PATCH] compute/map: Improve the map function to take into account
 multiple descriptor and multiple implementations for the kernel to apply.

---
 CMakeLists.txt         |   3 +-
 compute/CMakeLists.txt |   1 +
 compute/map.c          |   4 +-
 compute/mapv.c         | 170 +++++++++++++++++++++++++++++++++++++++++
 compute/pmap.c         |  38 ++++-----
 control/common.h       |   4 +-
 include/chameleon.h    |  16 +++-
 7 files changed, 211 insertions(+), 25 deletions(-)
 create mode 100644 compute/mapv.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4a68d67ae..1d12130c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,7 +30,7 @@
 #  @author Alycia Lisito
 #  @author Loris Lucido
 #  @author Nathan Précigout
-#  @date 2023-07-04
+#  @date 2024-03-11
 #
 ###
 cmake_minimum_required(VERSION 3.5)
@@ -759,7 +759,6 @@ if(CHAMELEON_ENABLE_DOC)
 endif()
 #------------------------------------------------------------------------------
 
-
 ###############################################################################
 # Make cmake include starpu_simgrid_wrap.h (which #define main and thus makes #
 # link tests fail) only after tests.                                          #
diff --git a/compute/CMakeLists.txt b/compute/CMakeLists.txt
index d3ecdd23a..a97a9cd37 100644
--- a/compute/CMakeLists.txt
+++ b/compute/CMakeLists.txt
@@ -47,6 +47,7 @@ set(CHAMELEON_CONTROL
     ../control/chameleon_f77.c
     ../control/chameleon_mf77.c
     map.c
+    mapv.c
     pmap.c
    )
 
diff --git a/compute/map.c b/compute/map.c
index 38999d4a6..16f10b5ec 100644
--- a/compute/map.c
+++ b/compute/map.c
@@ -9,9 +9,9 @@
  *
  * @brief Chameleon map wrappers
  *
- * @version 1.2.0
+ * @version 1.3.0
  * @author Mathieu Faverge
- * @date 2022-02-22
+ * @date 2024-03-11
  *
  */
 #include "control/common.h"
diff --git a/compute/mapv.c b/compute/mapv.c
new file mode 100644
index 000000000..a27cd2d49
--- /dev/null
+++ b/compute/mapv.c
@@ -0,0 +1,170 @@
+/**
+ *
+ * @file mapv.c
+ *
+ * @copyright 2018-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
+ *                      Univ. Bordeaux. All rights reserved.
+ *
+ ***
+ *
+ * @brief Chameleon mapv wrappers
+ *
+ * @version 1.3.0
+ * @author Mathieu Faverge
+ * @date 2024-03-11
+ *
+ */
+#include "control/common.h"
+
+/**
+ ********************************************************************************
+ *
+ * @ingroup CHAMELEON_Tile
+ *
+ *  Apply a given operator on each tile of the given matrix. Operates on
+ *  matrices stored by tiles.  All matrices are passed through descriptors.  All
+ *  dimensions are taken from the descriptors.
+ *
+ *******************************************************************************
+ *
+ * @param[in] access
+ *          - ChamR: A is accessed in read-only mode.
+ *          - ChamW: A is accessed in write-only mode.
+ *           WARNING: if the descriptor is set for allocation on the fly, the
+ *           flush call included in this synchronous API will free all allocated
+ *           data, prefer asynchronous call if you want to initialiaze data
+ *           before submitting another algorithm.
+ *          - ChamRW: A is accessed in read-write mode.
+ *
+ * @param[in] uplo
+ *          - ChamUpper: Only the upper triangular part of the matrix is touched
+ *          - ChamLower: Only the lower triangular part of the matrix is touched
+ *          - ChamUpperLower: The entire the matrix is touched
+ *
+ * @param[in,out] A
+ *          On exit, the operator has been applied on each tile of the matrix A.
+ *
+ * @param[in] op_fct
+ *          The operator function to apply on each tile of the matrix.
+ *
+ * @param[in,out] op_args
+ *          The arguments structure passed to the operator function when applied
+ *          on each tile. May be updated by the operator function.
+ *
+ *******************************************************************************
+ *
+ * @retval CHAMELEON_SUCCESS successful exit
+ *
+ *******************************************************************************
+ *
+ * @sa CHAMELEON_mapv_Tile_Async
+ *
+ */
+int CHAMELEON_mapv_Tile( cham_uplo_t          uplo,
+                         int                  ndata,
+                         cham_map_data_t     *data,
+                         cham_map_operator_t *op_fct,
+                         void                *op_args )
+{
+    CHAM_context_t     *chamctxt;
+    RUNTIME_sequence_t *sequence = NULL;
+    RUNTIME_request_t   request = RUNTIME_REQUEST_INITIALIZER;
+    int                 status, i;
+
+    chamctxt = chameleon_context_self();
+    if (chamctxt == NULL) {
+        chameleon_fatal_error("CHAMELEON_mapv_Tile", "CHAMELEON not initialized");
+        return CHAMELEON_ERR_NOT_INITIALIZED;
+    }
+    chameleon_sequence_create( chamctxt, &sequence );
+
+    CHAMELEON_mapv_Tile_Async( uplo, ndata, data, op_fct, op_args, sequence, &request );
+
+    for( i=0; i<ndata; i++ ) {
+        CHAMELEON_Desc_Flush( data[i].desc, sequence );
+    }
+
+    chameleon_sequence_wait( chamctxt, sequence );
+    status = sequence->status;
+    chameleon_sequence_destroy( chamctxt, sequence );
+    return status;
+}
+
+/**
+ ********************************************************************************
+ *
+ * @ingroup CHAMELEON_Tile_Async
+ *
+ *  Apply a given operator on each tile of the given matrix. Non-blocking equivalent of
+ *  CHAMELEON_mapv_Tile().  May return before the computation is finished.
+ *  Allows for pipelining of operations at runtime.
+ *
+ *******************************************************************************
+ *
+ * @param[in] access
+ *          - ChamR: A is accessed in read-only mode.
+ *          - ChamW: A is accessed in write-only mode.
+ *          INFO: tile of A can be unallocated before the call if the
+ *          descriptor is set for allocation on the fly.
+ *          - ChamRW: A is accessed in read-write mode.
+ *
+ * @param[in] sequence
+ *          Identifies the sequence of function calls that this call belongs to
+ *          (for completion checks and exception handling purposes).
+ *
+ * @param[out] request
+ *          Identifies this function call (for exception handling purposes).
+ *
+ *******************************************************************************
+ *
+ * @retval CHAMELEON_SUCCESS successful exit
+ *
+ *******************************************************************************
+ *
+ * @sa CHAMELEON_mapv_Tile
+ *
+ */
+int CHAMELEON_mapv_Tile_Async( cham_uplo_t          uplo,
+                               int                  ndata,
+                               cham_map_data_t     *data,
+                               cham_map_operator_t *op_fct,
+                               void                *op_args,
+                               RUNTIME_sequence_t  *sequence,
+                               RUNTIME_request_t   *request )
+{
+    CHAM_context_t *chamctxt;
+    int             i;
+
+    chamctxt = chameleon_context_self();
+    if (chamctxt == NULL) {
+        chameleon_fatal_error("CHAMELEON_mapv_Tile_Async", "CHAMELEON not initialized");
+        return CHAMELEON_ERR_NOT_INITIALIZED;
+    }
+    if (sequence == NULL) {
+        chameleon_fatal_error("CHAMELEON_mapv_Tile_Async", "NULL sequence");
+        return CHAMELEON_ERR_UNALLOCATED;
+    }
+    if (request == NULL) {
+        chameleon_fatal_error("CHAMELEON_mapv_Tile_Async", "NULL request");
+        return CHAMELEON_ERR_UNALLOCATED;
+    }
+    /* Check sequence status */
+    if (sequence->status == CHAMELEON_SUCCESS) {
+        request->status = CHAMELEON_SUCCESS;
+    }
+    else {
+        return chameleon_request_fail(sequence, request, CHAMELEON_ERR_SEQUENCE_FLUSHED);
+    }
+
+    /* Check descriptors for correctness */
+    for( i=0; i<ndata; i++ ) {
+        if (chameleon_desc_check(data[i].desc) != CHAMELEON_SUCCESS) {
+            chameleon_error("CHAMELEON_mapv_Tile_Async", "invalid descriptor");
+            return chameleon_request_fail(sequence, request, CHAMELEON_ERR_ILLEGAL_VALUE);
+        }
+    }
+
+    chameleon_pmap( uplo, ndata, data, op_fct, op_args, sequence, request );
+
+    return CHAMELEON_SUCCESS;
+}
diff --git a/compute/pmap.c b/compute/pmap.c
index acbd2babb..bcc1a868e 100644
--- a/compute/pmap.c
+++ b/compute/pmap.c
@@ -9,42 +9,44 @@
  *
  * @brief Chameleon map parallel algorithm
  *
- * @version 1.2.0
+ * @version 1.3.0
  * @author Mathieu Faverge
- * @date 2022-02-22
+ * @date 2024-03-11
  *
  */
 #include "control/common.h"
 
-#define A(m, n) A,  m,  n
+#define A(m, n) A, m, n
+
 /**
- *  chameleon_pmap - Generate a random matrix by tiles.
+ *  chameleon_pmap
  */
-void chameleon_pmap( cham_access_t access, cham_uplo_t uplo, CHAM_desc_t *A,
-                     cham_unary_operator_t op_fct, void *op_args,
+void chameleon_pmap( cham_uplo_t uplo, int ndata, cham_map_data_t *data,
+                     cham_map_operator_t *op_fct, void *op_args,
                      RUNTIME_sequence_t *sequence, RUNTIME_request_t *request )
 {
     CHAM_context_t *chamctxt;
     RUNTIME_option_t options;
+    const CHAM_desc_t *A = data[0].desc;
     int m, n;
 
     chamctxt = chameleon_context_self();
     if (sequence->status != CHAMELEON_SUCCESS)
         return;
-    RUNTIME_options_init(&options, chamctxt, sequence, request);
+    RUNTIME_options_init( &options, chamctxt, sequence, request );
 
     switch( uplo ) {
     case ChamUpper:
         for (n = 0; n < A->nt; n++) {
             for (m = 0; m < n; m++) {
                 INSERT_TASK_map(
-                    &options,
-                    access, ChamUpperLower, A(m, n),
+                    &options, ChamUpperLower, m, n,
+                    ndata, data,
                     op_fct, op_args );
             }
             INSERT_TASK_map(
-                &options,
-                access, uplo, A(n, n),
+                &options, uplo, n, n,
+                ndata, data,
                 op_fct, op_args );
         }
         break;
@@ -52,13 +54,13 @@ void chameleon_pmap( cham_access_t access, cham_uplo_t uplo, CHAM_desc_t *A,
     case ChamLower:
         for (n = 0; n < A->nt; n++) {
             INSERT_TASK_map(
-                &options,
-                access, uplo, A(n, n),
+                &options, uplo, n, n,
+                ndata, data,
                 op_fct, op_args );
             for (m = n+1; m < A->mt; m++) {
                 INSERT_TASK_map(
-                    &options,
-                    access, ChamUpperLower, A(m, n),
+                    &options, ChamUpperLower, m, n,
+                    ndata, data,
                     op_fct, op_args );
             }
         }
@@ -69,12 +71,12 @@ void chameleon_pmap( cham_access_t access, cham_uplo_t uplo, CHAM_desc_t *A,
         for (m = 0; m < A->mt; m++) {
             for (n = 0; n < A->nt; n++) {
                 INSERT_TASK_map(
-                    &options,
-                    access, uplo, A(m, n),
+                    &options, ChamUpperLower, m, n,
+                    ndata, data,
                     op_fct, op_args );
             }
         }
     }
 
-    RUNTIME_options_finalize(&options, chamctxt);
+    RUNTIME_options_finalize( &options, chamctxt );
 }
diff --git a/control/common.h b/control/common.h
index 579ce524e..997eded3e 100644
--- a/control/common.h
+++ b/control/common.h
@@ -102,8 +102,8 @@ extern char *chameleon_lapack_constants[];
 extern "C" {
 #endif
 
-void chameleon_pmap( cham_access_t access, cham_uplo_t uplo, CHAM_desc_t *A,
-                     cham_unary_operator_t operator, void *op_args,
+void chameleon_pmap( cham_uplo_t uplo, int ndata, cham_map_data_t *data,
+                     cham_map_operator_t *op_fct, void *op_args,
                      RUNTIME_sequence_t *sequence, RUNTIME_request_t *request );
 
 #include "control/compute_s.h"
diff --git a/include/chameleon.h b/include/chameleon.h
index 1cc933eb7..563158007 100644
--- a/include/chameleon.h
+++ b/include/chameleon.h
@@ -18,7 +18,7 @@
  * @author Florent Pruvost
  * @author Philippe Virouleau
  * @author Lionel Eyraud-Dubois
- * @date 2023-08-22
+ * @date 2024-03-11
  *
  */
 #ifndef _chameleon_h_
@@ -93,6 +93,20 @@ int CHAMELEON_map_Tile_Async( cham_access_t         access,
                               RUNTIME_sequence_t   *sequence,
                               RUNTIME_request_t    *request );
 
+int CHAMELEON_mapv_Tile( cham_uplo_t          uplo,
+                         int                  ndata,
+                         cham_map_data_t     *data,
+                         cham_map_operator_t *op_fct,
+                         void                *op_args );
+
+int CHAMELEON_mapv_Tile_Async( cham_uplo_t          uplo,
+                               int                  ndata,
+                               cham_map_data_t     *data,
+                               cham_map_operator_t *op_fct,
+                               void                *op_args,
+                               RUNTIME_sequence_t  *sequence,
+                               RUNTIME_request_t   *request );
+
 /* ****************************************************************************
  * CHAMELEON Functions
  */
-- 
GitLab