From 7934e8f55d985ac8d1b8a56810a5aa72d70fedce Mon Sep 17 00:00:00 2001
From: Michael Kuron <mkuron@icp.uni-stuttgart.de>
Date: Tue, 22 May 2018 15:39:09 +0200
Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20call=20MPI=5FType=5Ffree=20afte?=
 =?UTF-8?q?r=20MPI=5FFinalize?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Vector2, Vector3 and Matrix3 define their own MPITrait::type functions that return an MPI_Datatype for them. It is created the first time the function is called and put into a static variable. It is therefore destroyed after the main() function exits, which is usually after MPI_Finalize has been called. Freeing the MPI_Datatype is therefore not possible and mpi::datatype cannot be used.
---
 src/core/math/Matrix3.h | 27 +++++++++++++++++++++++++++
 src/core/math/Vector2.h |  8 ++++----
 src/core/math/Vector3.h |  8 ++++----
 3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/src/core/math/Matrix3.h b/src/core/math/Matrix3.h
index 27a29b945..fe3c0e00c 100644
--- a/src/core/math/Matrix3.h
+++ b/src/core/math/Matrix3.h
@@ -1839,3 +1839,30 @@ namespace mpi {
       };
 }
 }
+
+//======================================================================================================================
+//
+//  MPI Datatype
+//
+//======================================================================================================================
+
+namespace walberla {
+
+   template< typename T>
+   struct MPITrait< Matrix3<T> >
+   {
+      static inline MPI_Datatype type()
+      {
+         // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize
+         static MPI_Datatype datatype;
+         static bool initialized = false;
+
+         if( ! initialized ) {
+            MPI_Type_contiguous(9, MPITrait<T>::type(), &datatype );
+            MPI_Type_commit( &datatype );
+            initialized = true;
+         }
+         return datatype;
+      }
+   };
+} // namespace walberla
diff --git a/src/core/math/Vector2.h b/src/core/math/Vector2.h
index 1ad6f9cab..145bf302f 100644
--- a/src/core/math/Vector2.h
+++ b/src/core/math/Vector2.h
@@ -1696,13 +1696,13 @@ namespace walberla {
    {
       static inline MPI_Datatype type()
       {
-         static mpi::Datatype datatype;
+         // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize
+         static MPI_Datatype datatype;
          static bool initialized = false;
 
          if( ! initialized ) {
-            MPI_Datatype newDatatype;
-            MPI_Type_contiguous(2, MPITrait<T>::type(), &newDatatype );
-            datatype.init( newDatatype );
+            MPI_Type_contiguous(2, MPITrait<T>::type(), &datatype );
+            MPI_Type_commit( &datatype );
             initialized = true;
          }
          return datatype;
diff --git a/src/core/math/Vector3.h b/src/core/math/Vector3.h
index f5b1ea819..662d2dfa5 100644
--- a/src/core/math/Vector3.h
+++ b/src/core/math/Vector3.h
@@ -1895,13 +1895,13 @@ namespace walberla {
    {
       static inline MPI_Datatype type()
       {
-         static mpi::Datatype datatype;
+         // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize
+         static MPI_Datatype datatype;
          static bool initialized = false;
 
          if( ! initialized ) {
-            MPI_Datatype newDatatype;
-            MPI_Type_contiguous(3, MPITrait<T>::type(), &newDatatype );
-            datatype.init( newDatatype );
+            MPI_Type_contiguous(3, MPITrait<T>::type(), &datatype );
+            MPI_Type_commit( &datatype );
             initialized = true;
          }
          return datatype;
-- 
GitLab