From e3c2ea07a0dc61d11e56d3ff853e7ddc6e22df09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz>
Date: Sun, 16 Sep 2018 19:51:49 +0200
Subject: [PATCH] Fixed bugs in calls to MPI Init/Finalize

- There is an RAII wrapper called ScopedInitializer to handle
  finalization due to C++ exceptions and to avoid calls to Finalize in
  all exit branches.
- Fixed signature of MpiCommunicator::Init to match that of MPI_Init.
---
 src/TNL/Communicators/CMakeLists.txt          |  1 +
 src/TNL/Communicators/MpiCommunicator.h       |  2 +-
 src/TNL/Communicators/NoDistrCommunicator.h   |  2 +-
 src/TNL/Communicators/ScopedInitializer.h     | 33 +++++++++++++++++++
 src/TNL/Solvers/SolverInitiator_impl.h        | 10 ++----
 src/TNL/Solvers/Solver_impl.h                 | 12 +++----
 src/Tools/tnl-init.cpp                        | 16 +++------
 .../CutDistributedGridTest.cpp                | 12 +++----
 .../CutDistributedMeshFunctionTest.cpp        | 12 +++----
 .../DistributedMeshes/CutMeshFunctionTest.cpp |  6 ++--
 .../DistributedMeshes/DirectionsTest.cpp      |  2 +-
 .../DistributedGridIOTestBase.h               | 10 ++----
 .../DistributedGridIO_MPIIOTestBase.h         | 10 ++----
 .../DistributedGridTest_1D.cpp                | 12 +++----
 .../DistributedGridTest_2D.cpp                | 12 +++----
 .../DistributedGridTest_3D.cpp                | 12 +++----
 .../DistributedVectorFieldIO_MPIIOTest.cpp    | 10 ++----
 tests/mpi/GPUmeshFunctionEvaluateTest.cu      |  7 ++--
 tests/mpi/MeshFunctionEvaluateTest.cpp        |  4 +--
 tests/mpi/mpiio-save-load-test.cpp            |  6 ++--
 tests/mpi/mpiio-save-test.h                   |  6 ++--
 21 files changed, 86 insertions(+), 111 deletions(-)
 create mode 100644 src/TNL/Communicators/ScopedInitializer.h

diff --git a/src/TNL/Communicators/CMakeLists.txt b/src/TNL/Communicators/CMakeLists.txt
index 7a58eaa2a0..fb3193b739 100644
--- a/src/TNL/Communicators/CMakeLists.txt
+++ b/src/TNL/Communicators/CMakeLists.txt
@@ -1,6 +1,7 @@
 SET( headers MpiCommunicator.h
              MpiDefs.h             
              NoDistrCommunicator.h 
+             ScopedInitializer.h
     )
 
 INSTALL( FILES ${headers} DESTINATION ${TNL_TARGET_INCLUDE_DIRECTORY}/Communicators )
diff --git a/src/TNL/Communicators/MpiCommunicator.h b/src/TNL/Communicators/MpiCommunicator.h
index 8323c28f2a..c233004a60 100644
--- a/src/TNL/Communicators/MpiCommunicator.h
+++ b/src/TNL/Communicators/MpiCommunicator.h
@@ -149,7 +149,7 @@ class MpiCommunicator
          return true;
       }
 
-      static void Init(int argc, char **argv )
+      static void Init(int& argc, char**& argv )
       {
 #ifdef HAVE_MPI
          MPI_Init( &argc, &argv );
diff --git a/src/TNL/Communicators/NoDistrCommunicator.h b/src/TNL/Communicators/NoDistrCommunicator.h
index a25b9f1bb7..aac58b916b 100644
--- a/src/TNL/Communicators/NoDistrCommunicator.h
+++ b/src/TNL/Communicators/NoDistrCommunicator.h
@@ -37,7 +37,7 @@ class NoDistrCommunicator
          return true;
       }
       
-      static void Init(int argc, char **argv, bool redirect=false) {}
+      static void Init(int& argc, char**& argv) {}
       
       static void setRedirection( bool redirect_ ) {}
       
diff --git a/src/TNL/Communicators/ScopedInitializer.h b/src/TNL/Communicators/ScopedInitializer.h
new file mode 100644
index 0000000000..2970bc6283
--- /dev/null
+++ b/src/TNL/Communicators/ScopedInitializer.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+                          ScopedInitializer.h  -  description
+                             -------------------
+    begin                : Sep 16, 2018
+    copyright            : (C) 2005 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Jakub KlinkovskĂ˝
+
+#pragma once
+
+namespace TNL {
+namespace Communicators {
+
+template< typename Communicator >
+struct ScopedInitializer
+{
+   ScopedInitializer( int& argc, char**& argv )
+   {
+      Communicator::Init( argc, argv );
+   }
+
+   ~ScopedInitializer()
+   {
+      Communicator::Finalize();
+   }
+};
+
+} // namespace Communicators
+} // namespace TNL
diff --git a/src/TNL/Solvers/SolverInitiator_impl.h b/src/TNL/Solvers/SolverInitiator_impl.h
index a061aad721..c6bc5ca7f4 100644
--- a/src/TNL/Solvers/SolverInitiator_impl.h
+++ b/src/TNL/Solvers/SolverInitiator_impl.h
@@ -186,15 +186,9 @@ class CommunicatorTypeResolver< ProblemSetter, Real, Device, Index, ConfigTag, t
    public:
       static bool run( const Config::ParameterContainer& parameters )
       {
-         if(Communicators::MpiCommunicator::isDistributed())
-         {     
-               bool ret=SolverInitiatorMeshResolver< ProblemSetter, Real, Device, Index, ConfigTag, Communicators::MpiCommunicator >::run( parameters );
-               Communicators::MpiCommunicator::Finalize();      
-               return ret;
-         }
-         Communicators::MpiCommunicator::Finalize();
+         if( Communicators::MpiCommunicator::isDistributed() )
+            return SolverInitiatorMeshResolver< ProblemSetter, Real, Device, Index, ConfigTag, Communicators::MpiCommunicator >::run( parameters );
          return SolverInitiatorMeshResolver< ProblemSetter, Real, Device, Index, ConfigTag, Communicators::NoDistrCommunicator >::run( parameters );
-         
       }
 };
 
diff --git a/src/TNL/Solvers/Solver_impl.h b/src/TNL/Solvers/Solver_impl.h
index a0e4f19532..ef865e8b7b 100644
--- a/src/TNL/Solvers/Solver_impl.h
+++ b/src/TNL/Solvers/Solver_impl.h
@@ -14,8 +14,8 @@
 #include <TNL/Solvers/SolverStarter.h>
 #include <TNL/Solvers/SolverConfig.h>
 #include <TNL/Devices/Cuda.h>
-#include <TNL/Communicators/NoDistrCommunicator.h>
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 
 namespace TNL {
 namespace Solvers {
@@ -34,19 +34,15 @@ run( int argc, char* argv[] )
    configDescription.addDelimiter( "Parallelization setup:" );
    Devices::Host::configSetup( configDescription );
    Devices::Cuda::configSetup( configDescription );
-   Communicators::NoDistrCommunicator::configSetup( configDescription );
    Communicators::MpiCommunicator::configSetup( configDescription );
-   
-   Communicators::NoDistrCommunicator::Init(argc,argv);
-   Communicators::MpiCommunicator::Init(argc,argv);
+
+   Communicators::ScopedInitializer< Communicators::MpiCommunicator > mpi( argc, argv );
 
    if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
       return false;
 
    SolverInitiator< ProblemSetter, MeshConfig > solverInitiator;
-   bool ret= solverInitiator.run( parameters );
-
-	return ret;
+   return solverInitiator.run( parameters );
 };
 
 } // namespace Solvers
diff --git a/src/Tools/tnl-init.cpp b/src/Tools/tnl-init.cpp
index ac72f7a132..7dd7032810 100644
--- a/src/Tools/tnl-init.cpp
+++ b/src/Tools/tnl-init.cpp
@@ -17,8 +17,8 @@
 #include <TNL/Meshes/DummyMesh.h>
 #include <TNL/Meshes/Grid.h>
 
-#include <TNL/Communicators/NoDistrCommunicator.h>
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 
 
 using namespace TNL;
@@ -51,18 +51,14 @@ void setupConfig( Config::ConfigDescription& config )
 
 int main( int argc, char* argv[] )
 {
-
    Config::ParameterContainer parameters;
    Config::ConfigDescription configDescription;
 
    setupConfig( configDescription );
-   
-   Communicators::NoDistrCommunicator::configSetup( configDescription );
    Communicators::MpiCommunicator::configSetup( configDescription );
-   
-   Communicators::NoDistrCommunicator::Init(argc,argv);
-   Communicators::MpiCommunicator::Init(argc,argv);   
- 
+
+   Communicators::ScopedInitializer< Communicators::MpiCommunicator > mpi(argc, argv);
+
    if( ! parseCommandLine( argc, argv, configDescription, parameters ) )
       return EXIT_FAILURE;
 
@@ -83,9 +79,5 @@ int main( int argc, char* argv[] )
    if( ! resolveMeshType( parsedMeshType, parameters ) )
       return EXIT_FAILURE;
 
-#ifdef HAVE_MPI
-   Communicators::MpiCommunicator::Finalize();
-#endif
-      
    return EXIT_SUCCESS;
 }
diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp
index bf7755e5fc..587ec807ec 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp
@@ -4,6 +4,7 @@
 #ifdef HAVE_MPI  
 
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
 
@@ -404,7 +405,7 @@ TEST(NoMPI, NoTest)
   };
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
@@ -417,14 +418,9 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv);
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp
index d78a1dff65..4907f1d269 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp
@@ -6,6 +6,7 @@
 #include <TNL/Devices/Host.h> 
 #include <TNL/Functions/CutMeshFunction.h>
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedGridIO.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
 
@@ -684,7 +685,7 @@ TEST(NoMPI, NoTest)
   };
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
@@ -697,14 +698,9 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv);
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutMeshFunctionTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutMeshFunctionTest.cpp
index 5850c956e9..ce78b85680 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/CutMeshFunctionTest.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/CutMeshFunctionTest.cpp
@@ -213,15 +213,13 @@ TEST(CutMeshFunction, 3D_2)
 
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
    ::testing::InitGoogleTest( &argc, argv );
-       int result= RUN_ALL_TESTS();
-       return result;
+   return RUN_ALL_TESTS();
 #else
-   
    throw GtestMissingError();
 #endif
 }
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DirectionsTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/DirectionsTest.cpp
index 52ed831d0b..e8625bc3d6 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DirectionsTest.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/DirectionsTest.cpp
@@ -121,7 +121,7 @@ TEST(XYZ, 3D )
 
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTestBase.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTestBase.h
index d7774436c5..537bcd9239 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTestBase.h
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTestBase.h
@@ -12,6 +12,7 @@
 #ifdef HAVE_MPI
 
 #include "DistributedGridIOTest.h"
+#include <TNL/Communicators/ScopedInitializer.h>
 
 TEST( DistributedGridIO, Save_1D )
 {
@@ -134,16 +135,11 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv );
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
        CommunicatorType::setRedirection( false );
        CommunicatorType::setupRedirection();
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTestBase.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTestBase.h
index aaf5073ec8..4e3603a7a4 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTestBase.h
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTestBase.h
@@ -10,6 +10,7 @@
 #ifdef HAVE_MPI
 
 #include "DistributedGridIO_MPIIOTest.h"
+#include <TNL/Communicators/ScopedInitializer.h>
 
 TEST( DistributedGridMPIIO, Save_1D )
 {
@@ -131,16 +132,11 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv );
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
        CommunicatorType::setRedirection( false );
        CommunicatorType::setupRedirection();
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_1D.cpp b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_1D.cpp
index e907ecc9dc..251b9f553a 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_1D.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_1D.cpp
@@ -13,6 +13,7 @@
 #ifdef HAVE_MPI    
 
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
@@ -422,7 +423,7 @@ TEST(NoMPI, NoTest)
   };
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
@@ -435,14 +436,9 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv);
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_2D.cpp b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_2D.cpp
index 3642605936..38276dd543 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_2D.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_2D.cpp
@@ -15,6 +15,7 @@
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
 
 #include "../../Functions/Functions.h"
@@ -1049,7 +1050,7 @@ TEST(NoMPI, NoTest)
   };
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
@@ -1062,14 +1063,9 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv);
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp
index 1eecf6306c..6bbd7ad257 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp
@@ -4,6 +4,7 @@
 #ifdef HAVE_MPI    
 
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
@@ -765,7 +766,7 @@ TEST(NoMPI, NoTest)
   };
 #endif
 
-#include "../../src/UnitTests/GtestMissingError.h"
+#include "../../GtestMissingError.h"
 int main( int argc, char* argv[] )
 {
 #ifdef HAVE_GTEST
@@ -778,14 +779,9 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv);
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTest.cpp
index d3a1cd5526..67098fc5db 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTest.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTest.cpp
@@ -6,6 +6,7 @@
 #ifdef HAVE_MPI
 
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include "DistributedVectorFieldIO_MPIIOTestBase.h"
 
 using namespace TNL::Communicators;
@@ -102,16 +103,11 @@ int main( int argc, char* argv[] )
        delete listeners.Release(listeners.default_result_printer());
        listeners.Append(new MinimalistBufferedPrinter);
 
-       CommunicatorType::Init(argc,argv );
+       Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
        CommunicatorType::setRedirection( false );
        CommunicatorType::setupRedirection();
     #endif
-       int result= RUN_ALL_TESTS();
-
-    #ifdef HAVE_MPI
-       CommunicatorType::Finalize();
-    #endif
-       return result;
+       return RUN_ALL_TESTS();
 #else
    
    throw GtestMissingError();
diff --git a/tests/mpi/GPUmeshFunctionEvaluateTest.cu b/tests/mpi/GPUmeshFunctionEvaluateTest.cu
index 1008b4a4c0..1dcdb95207 100644
--- a/tests/mpi/GPUmeshFunctionEvaluateTest.cu
+++ b/tests/mpi/GPUmeshFunctionEvaluateTest.cu
@@ -9,6 +9,7 @@
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Communicators/MpiCommunicator.h>
 #include <TNL/Communicators/NoDistrCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
@@ -56,7 +57,7 @@ int main ( int argc, char *argv[])
   typedef LinearFunction<double,DIMENSION> LinearFunctionType;
   typedef ConstFunction<double,DIMENSION> ConstFunctionType;
   
-  CommunicatorType::Init(argc,argv);
+  Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
 
   int size=10;
   int cycles=1;
@@ -165,12 +166,8 @@ int main ( int argc, char *argv[])
     cout <<"sync: "<<sync.getRealTime()<<endl;
     cout<<"all: "<<all.getRealTime()<<endl<<endl;
   }
-  
-
-  CommunicatorType::Finalize();
 
   return 0;
-
 }
 
 #else
diff --git a/tests/mpi/MeshFunctionEvaluateTest.cpp b/tests/mpi/MeshFunctionEvaluateTest.cpp
index 6a59ae85ce..3c06a34cb7 100644
--- a/tests/mpi/MeshFunctionEvaluateTest.cpp
+++ b/tests/mpi/MeshFunctionEvaluateTest.cpp
@@ -16,6 +16,7 @@ using namespace std;
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Communicators/MpiCommunicator.h>
 #include <TNL/Communicators/NoDistrCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/SubdomainOverlapsGetter.h>
@@ -62,7 +63,7 @@ int main ( int argc, char *argv[])
    typedef LinearFunction<double,DIMENSION> LinearFunctionType;
    typedef ConstFunction<double,DIMENSION> ConstFunctionType;
   
-   CommunicatorType::Init(argc,argv);
+   Communicators::ScopedInitializer< CommunicatorType > mpi(argc, argv);
 
    int size=9;
    int cycles=1;
@@ -173,7 +174,6 @@ int main ( int argc, char *argv[])
       cout <<"sync: "<<sync.getRealTime()<<endl;
       cout<<"all: "<<all.getRealTime()<<endl<<endl;
    }
-   CommunicatorType::Finalize();
 #else
   std::cout<<"MPI not Supported." << std::endl;
 #endif
diff --git a/tests/mpi/mpiio-save-load-test.cpp b/tests/mpi/mpiio-save-load-test.cpp
index 0e7a8dff2a..0fa7ee7f65 100644
--- a/tests/mpi/mpiio-save-load-test.cpp
+++ b/tests/mpi/mpiio-save-load-test.cpp
@@ -2,6 +2,7 @@
 #define MPIIO
 
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedGridIO.h>
@@ -38,7 +39,7 @@ int main(int argc, char **argv)
         typedef typename DistributedGridType::CoordinatesType CoordinatesType;
         typedef LinearFunction<double,DIM> LinearFunctionType;
 
-        CommunicatorType::Init(argc, argv);
+        Communicators::ScopedInitializer< CommunicatorType > mpi_init(argc, argv);
 
         Pointers::SharedPointer< LinearFunctionType, Device > linearFunctionPtr;
         MeshFunctionEvaluator< MeshFunctionType, LinearFunctionType > linearFunctionEvaluator;    
@@ -92,9 +93,6 @@ int main(int argc, char **argv)
             else
                 std::cout <<"Ok!"<<std::endl;
         }
-
-        CommunicatorType::Finalize();
-
 }
 
 #else
diff --git a/tests/mpi/mpiio-save-test.h b/tests/mpi/mpiio-save-test.h
index 6e14b537e5..a824bd5b74 100644
--- a/tests/mpi/mpiio-save-test.h
+++ b/tests/mpi/mpiio-save-test.h
@@ -2,6 +2,7 @@
 
 #define MPIIO
 #include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Communicators/ScopedInitializer.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
 #include <TNL/Meshes/DistributedMeshes/DistributedGridIO.h>
@@ -38,7 +39,7 @@ int main(int argc, char **argv)
         typedef typename DistributedGridType::CoordinatesType CoordinatesType;
         typedef LinearFunction<double,DIM> LinearFunctionType;
 
-        CommunicatorType::Init(argc, argv);
+        Communicators::ScopedInitializer< CommunicatorType > mpi_init(argc, argv);
 
         Pointers::SharedPointer< LinearFunctionType, Device > linearFunctionPtr;
         MeshFunctionEvaluator< MeshFunctionType, LinearFunctionType > linearFunctionEvaluator;    
@@ -81,9 +82,6 @@ int main(int argc, char **argv)
         
         String fileName=String("./meshFunction.tnl");
         DistributedGridIO<MeshFunctionType,MpiIO> ::save(fileName, *meshFunctionptr );
-
-        CommunicatorType::Finalize();
-
 }
 
 #else
-- 
GitLab