From f53f2cb6289fd688e98003b4d83e2c608556867e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Fri, 23 Mar 2018 19:30:17 +0100
Subject: [PATCH] - start FPE Management - set of dirty CLI tests - signal
 management dirty tests

---
 .#CMakeLists.txt     |  1 -
 .gitignore           |  1 +
 CMakeLists.txt       | 12 +++++++++++
 main.cpp             | 47 ++++++++++++++++++++++++++++++++++++++---
 pastis_config.hpp.in |  6 ++++++
 utils/CMakeLists.txt |  4 ++++
 utils/FPEManager.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++
 utils/FPEManager.hpp | 10 +++++++++
 8 files changed, 127 insertions(+), 4 deletions(-)
 delete mode 120000 .#CMakeLists.txt
 create mode 100644 pastis_config.hpp.in
 create mode 100644 utils/FPEManager.cpp
 create mode 100644 utils/FPEManager.hpp

diff --git a/.#CMakeLists.txt b/.#CMakeLists.txt
deleted file mode 120000
index 6091011a8..000000000
--- a/.#CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-delpinos@u-sterne.bruyeres.cea.fr.23888:1521446211
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index ced9e610d..d55e76cb5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 build/
 CMakeFiles/
 CMakeCache.txt
+.\#*
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f1052af9..7c6cf426e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,7 @@ project (Pastis
   VERSION 0.0.2)
 
 set(PASTIS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(PASTIS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
 
 # Rang (colors? Useless thus necessary!)
 include_directories(${PASTIS_SOURCE_DIR}/packages/rang/include)
@@ -34,6 +35,17 @@ include_directories(utils)
 include(GetKokkosCompilerFlags)
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
 
+# ---------------- Checks for includes ----------------
+
+# Checks for FPE
+include(CheckIncludeFile)
+check_include_file(fenv.h PASTIS_HAS_FENV_H)
+
+# Generates pastis_config.hpp
+configure_file("${PASTIS_SOURCE_DIR}/pastis_config.hpp.in"
+  "${CMAKE_CURRENT_BINARY_DIR}/pastis_config.hpp"
+  @ONLY)
+
 # ------------------- Source files --------------------
 # Pastis binary
 add_executable(
diff --git a/main.cpp b/main.cpp
index 840b426d1..38b62c63e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -2,6 +2,7 @@
 #include <Kokkos_Core.hpp>
 #include <RevisionInfo.hpp>
 #include <rang.hpp>
+#include <FPEManager.hpp>
 
 #include <CLI/CLI.hpp>
 
@@ -113,17 +114,54 @@ void computeExplicitFluxes(const Kokkos::View<double*>& xr,
     });
 }
 
+#warning clean-up and add warning message when release version is run
+#include <csignal>
+ void signal_handler(int s) {
+   std::cerr << rang::style::reset
+	     << rang::fg::reset
+	     << rang::style::bold;
+   std::cerr << "to attach gdb to this process run\n";
+   std::cerr << "\tgdb -pid "
+	     << rang::fg::red
+	     << getpid()
+	     << rang::fg::reset
+	     << '\n';
+   std::cerr << "else press Control-C to exit\n";
+   std::cerr << rang::style::reset;
+   
+   ::sigset_t sig; 
+   ::sigaddset(&sig,SIGSTOP); 
+   ::sigsuspend(&sig); 
+ }
 
 int main(int argc, char *argv[])
 {
   CLI::App app{"Pastis help"};
 
-  long number = 1000;
-  app.add_option("-n,--number", number, "A big integer");
+  long unsigned number = 0;
+  app.add_option("number,-n,--number", number, "Number of cells");//->required();
+  bool disable_fpe = false;
+  app.add_flag("--disable-fpe", disable_fpe=false, "Traps floating point exceptions");
   int threads=-1;
   app.add_option("--threads", threads, "Number of Kokkos threads");
 
-  CLI11_PARSE(app, argc, argv);
+  std::cerr << "disable_fpe=" << disable_fpe << '\n' << std::flush;
+
+  //  signal_handler(SIGFPE);
+
+  std::atexit([](){std::cout << rang::style::reset;});
+  try {
+    app.parse(argc, argv);
+  } catch (const CLI::ParseError &e) {
+    std::cout << (e.get_exit_code()==0 ? rang::fg::blue : rang::fg::red);
+    return app.exit(e);
+  }
+
+  if (disable_fpe) {
+    FPEManager::disable();
+  } else {
+    FPEManager::enable();
+  }
 
   std::cout << "Code version: "
 	    << rang::style::bold << RevisionInfo::version() << rang::style::reset << '\n';
@@ -229,6 +267,9 @@ int main(int argc, char *argv[])
   int iteration=0;
 
   while((t<tmax) and (iteration<itermax)) {
+    double test=3;
+    test /= t;
+    std::cout << test << '\n';
     double dt = 0.4*acoustic_dt(Vj, cj);
     if (t+dt<tmax) {
       t+=dt;
diff --git a/pastis_config.hpp.in b/pastis_config.hpp.in
new file mode 100644
index 000000000..b415195c0
--- /dev/null
+++ b/pastis_config.hpp.in
@@ -0,0 +1,6 @@
+#ifndef PASTIS_CONFIG_HPP
+#define PASTIS_CONFIG_HPP
+
+#cmakedefine PASTIS_HAS_FENV_H
+
+#endif // PASTIS_CONFIG_HPP
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index 22b66dac7..7d0e57bf4 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 add_library(
   PastisUtils
+  FPEManager.cpp
   RevisionInfo.cpp)
 
 # --------------- get git revision info ---------------
@@ -61,9 +62,12 @@ list(
   SOURCES
   ${CMAKE_CURRENT_BINARY_DIR}/pastis_git_revision.hpp
   ${CMAKE_CURRENT_BINARY_DIR}/pastis_version.hpp
+  ${PASTIS_BINARY_DIR}/pastis_config.hpp
   )
 
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
+include_directories(${PASTIS_BINARY_DIR})
+include_directories(${PASTIS_SOURCE_DIR}/packages/rang/include)
 
 # Additional dependencies
 add_dependencies(
diff --git a/utils/FPEManager.cpp b/utils/FPEManager.cpp
new file mode 100644
index 000000000..355b2b6e1
--- /dev/null
+++ b/utils/FPEManager.cpp
@@ -0,0 +1,50 @@
+#include <FPEManager.hpp>
+#include <pastis_config.hpp>
+#include <rang.hpp>
+
+#ifdef PASTIS_HAS_FENV_H
+#include <fenv.h>
+
+#define MANAGED_FPE (FE_DIVBYZERO|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW)
+
+void FPEManager::enable()
+{
+  std::cout << "FE management: "
+	    << rang::style::bold
+	    << rang::fgB::green
+	    << "enabled"
+	    << rang::fg::reset
+	    << rang::style::reset << '\n';
+  ::feenableexcept(MANAGED_FPE);
+}
+
+void FPEManager::disable()
+{
+  std::cout << "FE management: "
+	    << rang::style::bold
+	    << rang::fgB::red
+	    << "disabled"
+	    << rang::fg::reset
+	    << rang::style::reset << '\n';
+  ::fedisableexcept(MANAGED_FPE);
+}
+
+#else  // PASTIS_HAS_FENV_H
+
+void FPEManager::enable()
+{
+  std::cout << "FE management: enabled "
+	    << rang::fg::red
+	    << "[not supported]"
+	    << rang::fg::reset << '\n';
+}
+
+void FPEManager::disable()
+{
+  std::cout << "FE management: disable "
+	    << rang::fg::red
+	    << "[not supported]"
+	    << rang::fg::reset << '\n';
+}
+
+#endif // PASTIS_HAS_FENV_H
diff --git a/utils/FPEManager.hpp b/utils/FPEManager.hpp
new file mode 100644
index 000000000..e2edb238d
--- /dev/null
+++ b/utils/FPEManager.hpp
@@ -0,0 +1,10 @@
+#ifndef FPEMANAGER_HPP
+#define FPEMANAGER_HPP
+
+struct FPEManager
+{
+  static void enable();
+  static void disable();
+};
+
+#endif // FPEMANAGER_HPP
-- 
GitLab