From c4143bfe021ec3f9823f6f500bb4808f2fc172e0 Mon Sep 17 00:00:00 2001
From: Cristian C Lalescu <Cristian.Lalescu@ds.mpg.de>
Date: Thu, 20 Sep 2018 15:31:30 +0200
Subject: [PATCH] introduce parameter for fftw_plan_rigor

---
 bfps/DNS.py                                  |  1 +
 bfps/PP.py                                   |  1 +
 bfps/TEST.py                                 |  1 +
 bfps/cpp/fftw_interface.hpp                  |  2 ++
 bfps/cpp/fftw_tools.cpp                      |  7 +++++
 bfps/cpp/fftw_tools.hpp                      |  2 ++
 bfps/cpp/full_code/NSVE.cpp                  |  6 ++--
 bfps/cpp/full_code/NSVE.hpp                  |  1 +
 bfps/cpp/full_code/NSVE_field_stats.cpp      |  4 ++-
 bfps/cpp/full_code/NSVE_field_stats.hpp      |  2 ++
 bfps/cpp/full_code/field_output_test.cpp     |  2 +-
 bfps/cpp/full_code/field_test.cpp            |  4 +--
 bfps/cpp/full_code/filter_test.cpp           |  2 +-
 bfps/cpp/full_code/joint_acc_vel_stats.cpp   |  2 +-
 bfps/cpp/full_code/native_binary_to_hdf5.cpp |  2 +-
 bfps/cpp/full_code/symmetrize_test.cpp       |  6 ++--
 bfps/cpp/full_code/symmetrize_test.hpp       |  1 +
 bfps/cpp/full_code/test_interpolation.cpp    |  6 ++--
 bfps/cpp/hdf5_tools.cpp                      | 31 +++++++++++++-------
 setup.py                                     |  2 +-
 20 files changed, 59 insertions(+), 26 deletions(-)

diff --git a/bfps/DNS.py b/bfps/DNS.py
index e6ace758..b22a309a 100644
--- a/bfps/DNS.py
+++ b/bfps/DNS.py
@@ -120,6 +120,7 @@ class DNS(_code):
         return None
     def generate_default_parameters(self):
         # these parameters are relevant for all DNS classes
+        self.parameters['fftw_planner_type'] = 'FFTW_ESTIMATE'
         self.parameters['dealias_type'] = int(1)
         self.parameters['dkx'] = float(1.0)
         self.parameters['dky'] = float(1.0)
diff --git a/bfps/PP.py b/bfps/PP.py
index 27a35928..867864e0 100644
--- a/bfps/PP.py
+++ b/bfps/PP.py
@@ -118,6 +118,7 @@ class PP(_code):
         return None
     def generate_default_parameters(self):
         # these parameters are relevant for all PP classes
+        self.parameters['fftw_planner_type'] = 'FFTW_ESTIMATE'
         self.parameters['dealias_type'] = int(1)
         self.parameters['dkx'] = float(1.0)
         self.parameters['dky'] = float(1.0)
diff --git a/bfps/TEST.py b/bfps/TEST.py
index cd4d3e4a..2a8b37ba 100644
--- a/bfps/TEST.py
+++ b/bfps/TEST.py
@@ -119,6 +119,7 @@ class TEST(_code):
         return None
     def generate_default_parameters(self):
         # these parameters are relevant for all TEST classes
+        self.parameters['fftw_planner_type'] = 'FFTW_ESTIMATE'
         self.parameters['dealias_type'] = int(1)
         self.parameters['dkx'] = float(1.0)
         self.parameters['dky'] = float(1.0)
diff --git a/bfps/cpp/fftw_interface.hpp b/bfps/cpp/fftw_interface.hpp
index 7f5e0144..0a840dd5 100644
--- a/bfps/cpp/fftw_interface.hpp
+++ b/bfps/cpp/fftw_interface.hpp
@@ -26,6 +26,8 @@
 #define FFTW_INTERFACE_HPP
 
 #include <fftw3-mpi.h>
+#include <map>
+#include <string>
 
 #ifdef USE_FFTWESTIMATE
 #define DEFAULT_FFTW_FLAG FFTW_ESTIMATE
diff --git a/bfps/cpp/fftw_tools.cpp b/bfps/cpp/fftw_tools.cpp
index 61e03d29..9f6e9bfd 100644
--- a/bfps/cpp/fftw_tools.cpp
+++ b/bfps/cpp/fftw_tools.cpp
@@ -31,6 +31,13 @@
 
 #define NDEBUG
 
+std::map<std::string, unsigned> fftw_planner_string_to_flag = {
+    {"FFTW_ESTIMATE", FFTW_ESTIMATE},
+    {"FFTW_MEASURE", FFTW_MEASURE},
+    {"FFTW_PATIENT", FFTW_PATIENT},
+    {"parameter does not exist", DEFAULT_FFTW_FLAG},
+};
+
 template <class rnumber>
 int clip_zero_padding(
         field_descriptor<rnumber> *f,
diff --git a/bfps/cpp/fftw_tools.hpp b/bfps/cpp/fftw_tools.hpp
index d0f3dbf3..f4480714 100644
--- a/bfps/cpp/fftw_tools.hpp
+++ b/bfps/cpp/fftw_tools.hpp
@@ -34,6 +34,8 @@
 
 extern int myrank, nprocs;
 
+extern std::map<std::string, unsigned> fftw_planner_string_to_flag;
+
 /* given two arrays of the same dimension, we do a simple resize in
  * Fourier space: either chop off high modes, or pad with zeros.
  * the arrays are assumed to use 3D mpi fftw layout.
diff --git a/bfps/cpp/full_code/NSVE.cpp b/bfps/cpp/full_code/NSVE.cpp
index d9cb72a2..74593b37 100644
--- a/bfps/cpp/full_code/NSVE.cpp
+++ b/bfps/cpp/full_code/NSVE.cpp
@@ -2,6 +2,7 @@
 #include <cmath>
 #include "NSVE.hpp"
 #include "scope_timer.hpp"
+#include "fftw_tools.hpp"
 
 
 template <typename rnumber>
@@ -37,11 +38,11 @@ int NSVE<rnumber>::initialize(void)
             simname.c_str(),
             nx, ny, nz,
             dkx, dky, dkz,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     this->tmp_vec_field = new field<rnumber, FFTW, THREE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
 
 
     this->fs->checkpoints_per_file = checkpoints_per_file;
@@ -161,6 +162,7 @@ int NSVE<rnumber>::read_parameters(void)
     this->max_vorticity_estimate = hdf5_tools::read_value<double>(parameter_file, "parameters/max_vorticity_estimate");
     std::string tmp = hdf5_tools::read_string(parameter_file, "parameters/forcing_type");
     snprintf(this->forcing_type, 511, "%s", tmp.c_str());
+    this->fftw_plan_type = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_type");
     H5Fclose(parameter_file);
     return EXIT_SUCCESS;
 }
diff --git a/bfps/cpp/full_code/NSVE.hpp b/bfps/cpp/full_code/NSVE.hpp
index 062627fd..c3ad7a0a 100644
--- a/bfps/cpp/full_code/NSVE.hpp
+++ b/bfps/cpp/full_code/NSVE.hpp
@@ -53,6 +53,7 @@ class NSVE: public direct_numerical_simulation
         double max_velocity_estimate;
         double max_vorticity_estimate;
         double nu;
+        std::string fftw_plan_type;
 
         /* other stuff */
         vorticity_equation<rnumber, FFTW> *fs;
diff --git a/bfps/cpp/full_code/NSVE_field_stats.cpp b/bfps/cpp/full_code/NSVE_field_stats.cpp
index 15980a20..142c51e7 100644
--- a/bfps/cpp/full_code/NSVE_field_stats.cpp
+++ b/bfps/cpp/full_code/NSVE_field_stats.cpp
@@ -1,6 +1,7 @@
 #include <string>
 #include <cmath>
 #include "NSVE_field_stats.hpp"
+#include "fftw_tools.hpp"
 #include "scope_timer.hpp"
 
 
@@ -12,7 +13,7 @@ int NSVE_field_stats<rnumber>::initialize(void)
     this->vorticity = new field<rnumber, FFTW, THREE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     this->vorticity->real_space_representation = false;
     hid_t parameter_file = H5Fopen(
             (this->simname + std::string(".h5")).c_str(),
@@ -43,6 +44,7 @@ int NSVE_field_stats<rnumber>::initialize(void)
                 this->vorticity->clayout->starts,
                 this->vorticity->clayout->comm);
     }
+    this->fftw_plan_type = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_type");
     H5Fclose(parameter_file);
     return EXIT_SUCCESS;
 }
diff --git a/bfps/cpp/full_code/NSVE_field_stats.hpp b/bfps/cpp/full_code/NSVE_field_stats.hpp
index d544c0c7..ae519fc7 100644
--- a/bfps/cpp/full_code/NSVE_field_stats.hpp
+++ b/bfps/cpp/full_code/NSVE_field_stats.hpp
@@ -42,6 +42,8 @@ class NSVE_field_stats: public postprocess
     private:
         field_binary_IO<rnumber, COMPLEX, THREE> *bin_IO;
     public:
+        std::string fftw_plan_type;
+
         field<rnumber, FFTW, THREE> *vorticity;
 
         NSVE_field_stats(
diff --git a/bfps/cpp/full_code/field_output_test.cpp b/bfps/cpp/full_code/field_output_test.cpp
index 30df4e75..72406099 100644
--- a/bfps/cpp/full_code/field_output_test.cpp
+++ b/bfps/cpp/full_code/field_output_test.cpp
@@ -36,7 +36,7 @@ int field_output_test<rnumber>::do_work(void)
     field<rnumber, FFTW, ONE> *scal_field = new field<rnumber, FFTW, ONE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     std::default_random_engine rgen;
     std::normal_distribution<rnumber> rdist;
     rgen.seed(1);
diff --git a/bfps/cpp/full_code/field_test.cpp b/bfps/cpp/full_code/field_test.cpp
index 1627bc40..a9d531bc 100644
--- a/bfps/cpp/full_code/field_test.cpp
+++ b/bfps/cpp/full_code/field_test.cpp
@@ -44,11 +44,11 @@ int field_test<rnumber>::do_work(void)
     field<rnumber, FFTW, ONE> *scal_field = new field<rnumber, FFTW, ONE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     field<rnumber, FFTW, ONE> *scal_field_alt = new field<rnumber, FFTW, ONE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     std::default_random_engine rgen;
     std::normal_distribution<rnumber> rdist;
     rgen.seed(2);
diff --git a/bfps/cpp/full_code/filter_test.cpp b/bfps/cpp/full_code/filter_test.cpp
index 4db13843..6dbd05a9 100644
--- a/bfps/cpp/full_code/filter_test.cpp
+++ b/bfps/cpp/full_code/filter_test.cpp
@@ -12,7 +12,7 @@ int filter_test<rnumber>::initialize(void)
     this->scal_field = new field<rnumber, FFTW, ONE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     this->kk = new kspace<FFTW, SMOOTH>(
             this->scal_field->clayout, this->dkx, this->dky, this->dkz);
 
diff --git a/bfps/cpp/full_code/joint_acc_vel_stats.cpp b/bfps/cpp/full_code/joint_acc_vel_stats.cpp
index 1c28527e..fff2e2f5 100644
--- a/bfps/cpp/full_code/joint_acc_vel_stats.cpp
+++ b/bfps/cpp/full_code/joint_acc_vel_stats.cpp
@@ -110,7 +110,7 @@ int joint_acc_vel_stats<rnumber>::work_on_current_iteration(void)
     vel = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            this->vorticity->fftw_plan_rigor);
     invert_curl(kk, this->ve->cvorticity, vel);
     vel->ift();
 
diff --git a/bfps/cpp/full_code/native_binary_to_hdf5.cpp b/bfps/cpp/full_code/native_binary_to_hdf5.cpp
index fb5a39c2..fe8e1c41 100644
--- a/bfps/cpp/full_code/native_binary_to_hdf5.cpp
+++ b/bfps/cpp/full_code/native_binary_to_hdf5.cpp
@@ -12,7 +12,7 @@ int native_binary_to_hdf5<rnumber>::initialize(void)
     this->vec_field = new field<rnumber, FFTW, THREE>(
             nx, ny, nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     this->vec_field->real_space_representation = false;
     this->bin_IO = new field_binary_IO<rnumber, COMPLEX, THREE>(
             this->vec_field->clayout->sizes,
diff --git a/bfps/cpp/full_code/symmetrize_test.cpp b/bfps/cpp/full_code/symmetrize_test.cpp
index 821161da..45225fcb 100644
--- a/bfps/cpp/full_code/symmetrize_test.cpp
+++ b/bfps/cpp/full_code/symmetrize_test.cpp
@@ -2,6 +2,7 @@
 #include <cmath>
 #include <random>
 #include "symmetrize_test.hpp"
+#include "fftw_tools.hpp"
 #include "scope_timer.hpp"
 
 
@@ -31,6 +32,7 @@ int symmetrize_test<rnumber>::read_parameters()
             H5P_DEFAULT);
     this->random_seed = hdf5_tools::read_value<int>(
             parameter_file, "/parameters/random_seed");
+    this->fftw_plan_type = hdf5_tools::read_string(parameter_file, "parameters/fftw_plan_type");
     H5Fclose(parameter_file);
     return EXIT_SUCCESS;
 }
@@ -44,13 +46,13 @@ int symmetrize_test<rnumber>::do_work(void)
     field<rnumber, FFTW, THREE> *test_field0 = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     DEBUG_MSG("finished allocating field0\n");
     DEBUG_MSG("about to allocate field1\n");
     field<rnumber, FFTW, THREE> *test_field1 = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            fftw_planner_string_to_flag[this->fftw_plan_type]);
     DEBUG_MSG("finished allocating field1\n");
     std::default_random_engine rgen;
     std::normal_distribution<rnumber> rdist;
diff --git a/bfps/cpp/full_code/symmetrize_test.hpp b/bfps/cpp/full_code/symmetrize_test.hpp
index d3fbbaeb..f674d365 100644
--- a/bfps/cpp/full_code/symmetrize_test.hpp
+++ b/bfps/cpp/full_code/symmetrize_test.hpp
@@ -42,6 +42,7 @@ template <typename rnumber>
 class symmetrize_test: public test
 {
     public:
+        std::string fftw_plan_type;
         int random_seed;
 
         symmetrize_test(
diff --git a/bfps/cpp/full_code/test_interpolation.cpp b/bfps/cpp/full_code/test_interpolation.cpp
index 5ef11de4..2acd3c27 100644
--- a/bfps/cpp/full_code/test_interpolation.cpp
+++ b/bfps/cpp/full_code/test_interpolation.cpp
@@ -30,18 +30,18 @@ int test_interpolation<rnumber>::initialize(void)
     this->vorticity = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
     this->vorticity->real_space_representation = false;
 
     this->velocity = new field<rnumber, FFTW, THREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
 
     this->nabla_u = new field<rnumber, FFTW, THREExTHREE>(
             this->nx, this->ny, this->nz,
             this->comm,
-            DEFAULT_FFTW_FLAG);
+            FFTW_ESTIMATE);
 
     this->kk = new kspace<FFTW, SMOOTH>(
             this->vorticity->clayout, this->dkx, this->dky, this->dkz);
diff --git a/bfps/cpp/hdf5_tools.cpp b/bfps/cpp/hdf5_tools.cpp
index c2ef6aae..25acaf21 100644
--- a/bfps/cpp/hdf5_tools.cpp
+++ b/bfps/cpp/hdf5_tools.cpp
@@ -208,17 +208,26 @@ std::string hdf5_tools::read_string(
         const hid_t group,
         const std::string dset_name)
 {
-    hid_t dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
-    hid_t space = H5Dget_space(dset);
-    hid_t memtype = H5Dget_type(dset);
-    char *string_data = (char*)malloc(256);
-    H5Dread(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &string_data);
-    std::string std_string_data = std::string(string_data);
-    free(string_data);
-    H5Sclose(space);
-    H5Tclose(memtype);
-    H5Dclose(dset);
-    return std_string_data;
+    if (H5Lexists(group, dset_name.c_str(), H5P_DEFAULT))
+    {
+        hid_t dset = H5Dopen(group, dset_name.c_str(), H5P_DEFAULT);
+        hid_t space = H5Dget_space(dset);
+        hid_t memtype = H5Dget_type(dset);
+        char *string_data = (char*)malloc(256);
+        H5Dread(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &string_data);
+        std::string std_string_data = std::string(string_data);
+        free(string_data);
+        H5Sclose(space);
+        H5Tclose(memtype);
+        H5Dclose(dset);
+        return std_string_data;
+    }
+    else
+    {
+        DEBUG_MSG("attempted to read dataset %s which does not exist.\n",
+                dset_name.c_str());
+        return std::string("parameter does not exist");
+    }
 }
 
 template
diff --git a/setup.py b/setup.py
index 110f18d5..afb25f70 100644
--- a/setup.py
+++ b/setup.py
@@ -273,7 +273,7 @@ class CompileLibCommand(distutils.cmd.Command):
 
 def get_file_dependency_list(src_file):
     p = subprocess.Popen(
-            ['g++', '-Ibfps/cpp', '-MM', 'bfps/cpp/' + src_file + '.cpp'],
+            ['g++', '-std=c++11', '-Ibfps/cpp', '-MM', 'bfps/cpp/' + src_file + '.cpp'],
             stdout = subprocess.PIPE)
     out, err = p.communicate()
     p.terminate()
-- 
GitLab