From a8db8b4c4a0d189aba420a182eea556ccaca75ba Mon Sep 17 00:00:00 2001
From: Ludovic Hussonnois <ludovic.hussonnois@c-s.fr>
Date: Fri, 10 Feb 2017 17:36:52 +0100
Subject: [PATCH] TEST: Update fft-debug test.

---
 .../app/otbDomainTransform.cxx                |   8 +-
 Modules/IO/TestKernel/include/otbTestMain.h   |   1 +
 Modules/MPI/MPIConfig/include/otbMPIConfig.h  |   5 +
 Modules/MPI/MPIConfig/src/otbMPIConfig.cxx    | 121 ++++++++++--------
 .../src/otbApplicationLauncherCommandLine.cxx |  18 +--
 5 files changed, 86 insertions(+), 67 deletions(-)

diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
index 2f611618e2..41ee75c1b2 100644
--- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
+++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
@@ -27,6 +27,7 @@
 #include <itkInverseFFTImageFilter.h>
 #include <itkUnaryFunctorImageFilter.h>
 #include <itkFFTShiftImageFilter.h>
+#include <itkFFTWGlobalConfiguration.h>
 
 #include "otbComplexToVectorImageCastFilter.h"
 
@@ -79,11 +80,9 @@ private:
 
   ~DomainTransform() ITK_OVERRIDE
     {
-      // Clean up all threads allocated threads.
-      CleanupFFTThreads();
     }
 
-  void CleanupFFTThreads()
+  void CleanupFFTWThreads()
   {
     std::cout << "Start cleanup threads" << std::endl;
     // This is a trick to make sure fftw will cleanup its threads when application
@@ -374,6 +373,9 @@ private:
         SetParameterOutputImage<TOutputImage>("out", invFilter->GetOutput());
         }
       }
+
+      // at the end, cleanup FFTW Threads
+      CleanupFFTWThreads();
     }
 
   template<otb::Wavelet::Wavelet TWaveletOperator>
diff --git a/Modules/IO/TestKernel/include/otbTestMain.h b/Modules/IO/TestKernel/include/otbTestMain.h
index 42f7e894aa..c30763f41a 100644
--- a/Modules/IO/TestKernel/include/otbTestMain.h
+++ b/Modules/IO/TestKernel/include/otbTestMain.h
@@ -424,6 +424,7 @@ int main(int ac, char* av[])
     std::cout << "-------------  End control baseline tests    -------------" << std::endl;
 
 #ifdef OTB_USE_MPI
+      otb::MPIConfig::Instance()->terminate();
     }
 #endif
     return result;
diff --git a/Modules/MPI/MPIConfig/include/otbMPIConfig.h b/Modules/MPI/MPIConfig/include/otbMPIConfig.h
index 3b53299fdd..c5bd1ab1e8 100644
--- a/Modules/MPI/MPIConfig/include/otbMPIConfig.h
+++ b/Modules/MPI/MPIConfig/include/otbMPIConfig.h
@@ -53,6 +53,9 @@ public:
   /** Initialize MPI Processus */
   void Init(int& argc, char** &argv, bool abortOnException = true);
 
+  /** Shuts down the MPI environment. */
+  void terminate();
+
   /** Abort all MPI processus. */
   void abort(int errCode);
 
@@ -85,6 +88,8 @@ private:
   bool m_abortOnException;
   // Boolean to test if the MPI environment is initialized
   bool m_initialized;
+  // Boolean to test if the MPI environment is terminated
+  bool m_terminated;
 
   static Pointer m_Singleton;
 };
diff --git a/Modules/MPI/MPIConfig/src/otbMPIConfig.cxx b/Modules/MPI/MPIConfig/src/otbMPIConfig.cxx
index 75fc3a1c3e..1375ae3a58 100644
--- a/Modules/MPI/MPIConfig/src/otbMPIConfig.cxx
+++ b/Modules/MPI/MPIConfig/src/otbMPIConfig.cxx
@@ -80,74 +80,91 @@ MPIConfig::MPIConfig()
   :  m_MyRank(0),
      m_NbProcs(0),
      m_abortOnException(true),
-     m_initialized(false)
+     m_initialized(false),
+     m_terminated(false)
 {
 }
 
 /** Shuts down the MPI environment. */
 MPIConfig::~MPIConfig()
 {
-   if (m_initialized)
-   {
-     if (std::uncaught_exception() && m_abortOnException)
-     {
-       abort(EXIT_FAILURE);
-     }
-     else
-     {
-       std::cout << "Start Finalize MPI" << std::endl;
-       std::flush(std::cout);
-       int finalized;
-       OTB_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
-       if (!finalized)
-       {
-         std::cout << "Start 2nd End Finalize MPI" << std::endl;
-         //OTB_MPI_CHECK_RESULT(MPI_Finalize,());
-         std::cout << "End 2nd  Finalize MPI" << std::endl;
-       }
-       std::cout << "End Finalize MPI" << std::endl;
-       std::flush(std::cout);
-     }
-   }
+  terminate();
 }
 
 /** Initialize MPI environment */
-void MPIConfig::Init(int& argc, char** &argv, bool abortOnException) {
-   // Abort on exception
-   m_abortOnException = abortOnException;
-   // Initialize
-   int initialized;
-   OTB_MPI_CHECK_RESULT(MPI_Initialized,(&initialized));
-   m_initialized = (initialized == 1);
-   if (!m_initialized) {
-     OTB_MPI_CHECK_RESULT(MPI_Init, (&argc, &argv));
-     m_initialized = true;
-   }
-   // Get MPI rank
-   int irank = 0;
-   OTB_MPI_CHECK_RESULT(MPI_Comm_rank, (MPI_COMM_WORLD , &irank));
+void MPIConfig::Init(int &argc, char **&argv, bool abortOnException) {
+  if( !m_terminated )
+    {
+    std::cout << "MPI Initialization : " << this << std::endl;
+    std::flush(std::cout);
+    // Abort on exception
+    m_abortOnException = abortOnException;
+    // Initialize
+    int initialized;
+    OTB_MPI_CHECK_RESULT( MPI_Initialized, ( &initialized ));
+    m_initialized = ( initialized == 1 );
+    if( !m_initialized )
+      {
+      OTB_MPI_CHECK_RESULT( MPI_Init, ( &argc, &argv ));
+      m_initialized = true;
+      }
+    // Get MPI rank
+    int irank = 0;
+    OTB_MPI_CHECK_RESULT( MPI_Comm_rank, ( MPI_COMM_WORLD, &irank ));
 
-   if(irank<0)
-     {
-     logError("Negative MPI rank");
-     abort(EXIT_FAILURE);
-     }
+    if( irank < 0 )
+      {
+      logError( "Negative MPI rank" );
+      abort( EXIT_FAILURE );
+      }
 
-   m_MyRank = static_cast<unsigned int>(irank);
+    m_MyRank = static_cast<unsigned int>(irank);
 
-   // Get MPI NbProocs
+    // Get MPI NbProocs
 
-   int inbprocs=0;
+    int inbprocs = 0;
 
-   OTB_MPI_CHECK_RESULT(MPI_Comm_size, (MPI_COMM_WORLD , &inbprocs));
+    OTB_MPI_CHECK_RESULT( MPI_Comm_size, ( MPI_COMM_WORLD, &inbprocs ));
 
-   if(inbprocs<1)
-     {
-     logError("Negative or null number of processes");
-     abort(EXIT_FAILURE);
-     }
+    if( inbprocs < 1 )
+      {
+      logError( "Negative or null number of processes" );
+      abort( EXIT_FAILURE );
+      }
 
-   m_NbProcs = static_cast<unsigned int>(inbprocs);
+    m_NbProcs = static_cast<unsigned int>(inbprocs);
+    }
+}
+
+/** Shuts down the MPI environment. */
+void MPIConfig::terminate()
+{
+  if( m_initialized && !m_terminated )
+    {
+    std::cout << "Terminate : " << this << std::endl;
+    std::flush(std::cout);
+    if( std::uncaught_exception() && m_abortOnException )
+      {
+      std::cout << "Abord" << std::endl;
+      abort( EXIT_FAILURE );
+      }
+    else
+      {
+      std::cout << "Start Finalize MPI" << std::endl;
+      std::flush( std::cout );
+      int finalized;
+      OTB_MPI_CHECK_RESULT( MPI_Finalized, ( &finalized ));
+      if( !finalized )
+        {
+        std::cout << "Start 2nd End Finalize MPI" << std::endl;
+        OTB_MPI_CHECK_RESULT( MPI_Finalize, ( ));
+        std::cout << "End 2nd  Finalize MPI" << std::endl;
+        }
+      std::cout << "End Finalize MPI" << std::endl;
+      std::flush( std::cout );
+      }
+      m_terminated = true;
+    }
 }
 
 void MPIConfig::abort(int errCode)
diff --git a/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx b/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx
index 05d439d7fa..3d66679172 100644
--- a/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx
+++ b/Modules/Wrappers/CommandLine/src/otbApplicationLauncherCommandLine.cxx
@@ -303,19 +303,13 @@ int main(int argc, char* argv[])
   LauncherType::Pointer launcher = LauncherType::New();
 
   //if (launcher->Load(exp) == true)
-    if (launcher->Load(vexp) == true)
-    {
-    if (launcher->ExecuteAndWriteOutput() == false)
-      {
-      return EXIT_FAILURE;
-      }
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
+  bool sucess = launcher->Load(vexp) && launcher->ExecuteAndWriteOutput();
 
-  return EXIT_SUCCESS;
+  // shutdown MPI after application finished
+  #ifdef OTB_USE_MPI
+  otb::MPIConfig::Instance()->terminate();
+  #endif
+  return sucess ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
 const std::string GetChildNodeTextOf(TiXmlElement *parentElement, std::string key)
-- 
GitLab