From b47e8600ef9048344758feb2d95d79a7649b32ce Mon Sep 17 00:00:00 2001
From: "raphael.bach" <raphael.bach@etu.hesge.ch>
Date: Sun, 26 Jun 2022 01:49:22 +0200
Subject: [PATCH] Add `fmpi_task_finalize()`

---
 examples/array_sum/main.c |  5 ++++-
 include/fmpi_task.h       | 14 ++++++++++++++
 src/fmpi_task.c           | 29 +++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/examples/array_sum/main.c b/examples/array_sum/main.c
index 5310347..7779ce2 100644
--- a/examples/array_sum/main.c
+++ b/examples/array_sum/main.c
@@ -3,6 +3,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <mpi.h>
 // fmpi
 #include <fmpi.h>
 // Internal
@@ -37,7 +38,9 @@ int main(int argc, char * argv[])
         fmpi_data_1d_in(ctx, in, in_size)
     );
     fmpi_run_task(ctx, &array_sum_task);
-    printf("rank=%d sum=%ld\n", fmpi_world_rank(ctx), out);
+    printf("rank=%d local sum=%ld\n", fmpi_world_rank(ctx), out);
+    fmpi_task_finalize(ctx, &array_sum_task, FMPI_TASK_OP_SUM);
+    fmpi_root_printf(ctx, "global sum=%ld\n", out);
     fmpi_exit(&ctx);
     return EXIT_SUCCESS;
 }
diff --git a/include/fmpi_task.h b/include/fmpi_task.h
index 223e2de..5f65604 100644
--- a/include/fmpi_task.h
+++ b/include/fmpi_task.h
@@ -50,6 +50,13 @@
 /*==============================================================================
     TYPE
 ==============================================================================*/
+/*------------------------------------------------------------------------------
+    fmpi_task_op
+------------------------------------------------------------------------------*/
+typedef enum fmpi_task_op {
+    FMPI_TASK_OP_NONE = 0,
+    FMPI_TASK_OP_SUM
+} fmpi_task_op;
 /*------------------------------------------------------------------------------
     fmpi_task_args
 ------------------------------------------------------------------------------*/
@@ -183,6 +190,13 @@ int fmpi_task_run_sync(const struct fmpi_ctx * ctx, const struct fmpi_task * tas
  * }
  */
 int fmpi_task_run_async(const struct fmpi_ctx * ctx, const struct fmpi_task * task);
+/*------------------------------------------------------------------------------
+    fmpi_task_finalize()
+------------------------------------------------------------------------------*/
+int fmpi_task_finalize(
+    const struct fmpi_ctx * ctx, const struct fmpi_task * task,
+    enum fmpi_task_op op
+);
 /*==============================================================================
     MACRO
 ==============================================================================*/
diff --git a/src/fmpi_task.c b/src/fmpi_task.c
index 0a71d3c..cd6f59b 100644
--- a/src/fmpi_task.c
+++ b/src/fmpi_task.c
@@ -170,3 +170,32 @@ int fmpi_task_run_async(
     assert(task != NULL);
     return task->func(ctx, &task->args);
 }
+/*------------------------------------------------------------------------------
+    fmpi_task_finalize()
+------------------------------------------------------------------------------*/
+int fmpi_task_finalize(
+    const struct fmpi_ctx * const ctx, const struct fmpi_task * const task,
+    const enum fmpi_task_op op
+){
+    assert(ctx != NULL);
+    assert(task != NULL);
+    if(op == FMPI_TASK_OP_NONE) {
+        return 0;
+    }
+    if(op == FMPI_TASK_OP_SUM) {
+        if(fmpi_mpi_is_root(ctx->mpi)) {
+            MPI_Reduce(
+                MPI_IN_PLACE, task->args.out.raw, (int)task->args.out.cnt,
+                fmpi_mpi_type(task->args.out.type.base), MPI_SUM,
+                ctx->mpi->root, MPI_COMM_WORLD
+            );
+        } else {
+            MPI_Reduce(
+                task->args.out.raw, task->args.out.raw, (int)task->args.out.cnt,
+                fmpi_mpi_type(task->args.out.type.base), MPI_SUM,
+                ctx->mpi->root, MPI_COMM_WORLD
+            );
+        }
+    }
+    return 0;
+}
-- 
GitLab