From 5a5fbd6af6cd3d1ce5e21f2815654ae7227b21b9 Mon Sep 17 00:00:00 2001
From: Thomas Purcell <purcell@fhi-berlin.mpg.de>
Date: Mon, 28 Sep 2020 11:10:56 +0200
Subject: [PATCH] set up node value arrays for OMP

Modify CMakeLists.txt files to incldue open MP
Add a thread count for centeral storage arrays
---
 CMakeLists.txt                                |  8 ++++++
 src/CMakeLists.txt                            |  4 +--
 .../value_storage/nodes_value_containers.cpp  | 25 ++++++++++---------
 .../value_storage/nodes_value_containers.hpp  | 12 +++++----
 4 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index cdfbf418..b4671acd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,14 @@ else(EXTERNAL_BOOST)
     set(EXTERNAL_BOOST FALSE)
 endif()
 
+# Check for FindOpenMP
+find_package(OpenMP REQUIRED)
+if (OPENMP_FOUND)
+    # include_directories("${OPENMP_INCLUDES}")
+    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+endif(OPENMP_FOUND)
+
 if(USE_PYTHON)
     # Check python  settings
     find_package(PythonInterp 3 REQUIRED)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fe0364d2..90cbbe94 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -31,7 +31,7 @@ set_target_properties(sisso++
     RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
 )
 
-target_link_libraries(sisso++  ${LAPACK_LIBRARIES} ${MPI_LIBRARIES} -Wl,--rpath=${Boost_LIB_DIR} -Wl,--rpath=${LAPACK_DIR} ${Boost_LIBRARIES} ${COIN_CLP_LIBRARIES})
+target_link_libraries(sisso++  ${LAPACK_LIBRARIES} ${MPI_LIBRARIES} -Wl,--rpath=${Boost_LIB_DIR} -Wl,--rpath=${LAPACK_DIR} ${Boost_LIBRARIES} ${COIN_CLP_LIBRARIES} ${OPENMP_LIBRARIES})
 install(TARGETS sisso++ DESTINATION ${CMAKE_CURRENT_LIST_DIR}/../bin/)
 
 if(USE_PYTHON)
@@ -59,7 +59,7 @@ if(USE_PYTHON)
         PREFIX ""
         SUFFIX ".so"
     )
-    target_link_libraries(_sisso ${MPI_LIBRARIES} -Wl,--rpath=${PYTHON_PREFIX}/lib/ ${LAPACK_LIBRARIES} ${PYTHON_LIBRARIES}  -Wl,--rpath=${Boost_LIB_DIR} ${Boost_LIBRARIES} ${Boost_PYTHON_LIBRARIES} ${COIN_CLP_LIBRARIES})
+    target_link_libraries(_sisso ${MPI_LIBRARIES} -Wl,--rpath=${PYTHON_PREFIX}/lib/ ${LAPACK_LIBRARIES} ${PYTHON_LIBRARIES}  -Wl,--rpath=${Boost_LIB_DIR} ${Boost_LIBRARIES} ${Boost_PYTHON_LIBRARIES} ${COIN_CLP_LIBRARIES} ${OPENMP_LIBRARIES})
     install(TARGETS _sisso DESTINATION "${PYTHON_INSTDIR}/cpp_sisso")
     install(
         DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/python/ DESTINATION ${PYTHON_INSTDIR}/cpp_sisso
diff --git a/src/feature_creation/node/value_storage/nodes_value_containers.cpp b/src/feature_creation/node/value_storage/nodes_value_containers.cpp
index a0fca7d1..1b4426b1 100644
--- a/src/feature_creation/node/value_storage/nodes_value_containers.cpp
+++ b/src/feature_creation/node/value_storage/nodes_value_containers.cpp
@@ -5,6 +5,7 @@ int node_value_arrs::N_SAMPLES = 0;
 int node_value_arrs::N_STORE_FEATURES = 0;
 int node_value_arrs::N_RUNGS_STORED = 0;
 int node_value_arrs::N_SAMPLES_TEST = 0;
+int node_value_arrs::MAX_N_THREADS = omp_get_max_threads();
 
 std::vector<int> node_value_arrs::TEMP_STORAGE_REG;
 std::vector<int> node_value_arrs::TEMP_STORAGE_TEST_REG;
@@ -25,11 +26,11 @@ void node_value_arrs::initialize_values_arr(int n_samples, int n_samples_test, i
     VALUES_ARR = std::vector<double>(N_STORE_FEATURES * N_SAMPLES);
     TEST_VALUES_ARR = std::vector<double>(N_STORE_FEATURES * N_SAMPLES_TEST);
 
-    TEMP_STORAGE_ARR = std::vector<double>(3 * N_STORE_FEATURES * N_SAMPLES);
-    TEMP_STORAGE_REG = std::vector<int>(3 * N_STORE_FEATURES, -1);
+    TEMP_STORAGE_ARR = std::vector<double>(MAX_N_THREADS * 3 * N_STORE_FEATURES * N_SAMPLES);
+    TEMP_STORAGE_REG = std::vector<int>(MAX_N_THREADS * 3 * N_STORE_FEATURES, -1);
 
-    TEMP_STORAGE_TEST_ARR = std::vector<double>(3 * N_STORE_FEATURES * N_SAMPLES_TEST);
-    TEMP_STORAGE_TEST_REG = std::vector<int>(3 * N_STORE_FEATURES, -1);
+    TEMP_STORAGE_TEST_ARR = std::vector<double>(MAX_N_THREADS * 3 * N_STORE_FEATURES * N_SAMPLES_TEST);
+    TEMP_STORAGE_TEST_REG = std::vector<int>(MAX_N_THREADS * 3 * N_STORE_FEATURES, -1);
 }
 
 void node_value_arrs::resize_values_arr(int n_dims, int n_feat, bool use_temp)
@@ -47,16 +48,16 @@ void node_value_arrs::resize_values_arr(int n_dims, int n_feat, bool use_temp)
 
     if(use_temp)
     {
-        TEMP_STORAGE_ARR.resize(3 * N_STORE_FEATURES * N_SAMPLES);
+        TEMP_STORAGE_ARR.resize(MAX_N_THREADS * 3 * N_STORE_FEATURES * N_SAMPLES);
         TEMP_STORAGE_ARR.shrink_to_fit();
 
-        TEMP_STORAGE_REG.resize(3 * N_STORE_FEATURES, - 1);
+        TEMP_STORAGE_REG.resize(MAX_N_THREADS * 3 * N_STORE_FEATURES, - 1);
         TEMP_STORAGE_REG.shrink_to_fit();
 
-        TEMP_STORAGE_TEST_ARR.resize(3 * N_STORE_FEATURES * N_SAMPLES_TEST);
+        TEMP_STORAGE_TEST_ARR.resize(MAX_N_THREADS * 3 * N_STORE_FEATURES * N_SAMPLES_TEST);
         TEMP_STORAGE_TEST_ARR.shrink_to_fit();
 
-        TEMP_STORAGE_TEST_REG.resize(3 * N_STORE_FEATURES, - 1);
+        TEMP_STORAGE_TEST_REG.resize(MAX_N_THREADS * 3 * N_STORE_FEATURES, - 1);
         TEMP_STORAGE_TEST_REG.shrink_to_fit();
     }
     else
@@ -66,22 +67,22 @@ void node_value_arrs::resize_values_arr(int n_dims, int n_feat, bool use_temp)
     }
 }
 
-double* node_value_arrs::get_value_ptr(int arr_ind, int feat_ind, int offset)
+double* node_value_arrs::get_value_ptr(int arr_ind, int feat_ind, int offset, int thread)
 {
     if(arr_ind < N_STORE_FEATURES)
         return  access_value_arr(arr_ind);
 
     temp_storage_reg(arr_ind, offset) = feat_ind;
-    return access_temp_storage((arr_ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES);
+    return access_temp_storage((arr_ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES) + thread * N_STORE_FEATURES * 3;
 }
 
-double* node_value_arrs::get_test_value_ptr(int arr_ind, int feat_ind, int offset)
+double* node_value_arrs::get_test_value_ptr(int arr_ind, int feat_ind, int offset, int thread)
 {
     if(arr_ind < N_STORE_FEATURES)
         return  access_test_value_arr(arr_ind);
 
     temp_storage_test_reg(arr_ind, offset) = feat_ind;
-    return access_temp_storage_test((arr_ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES);
+    return access_temp_storage_test((arr_ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES) + thread * N_STORE_FEATURES * 3;
 }
 
 void node_value_arrs::initialize_d_matrix_arr()
diff --git a/src/feature_creation/node/value_storage/nodes_value_containers.hpp b/src/feature_creation/node/value_storage/nodes_value_containers.hpp
index 32af493c..c36a0603 100644
--- a/src/feature_creation/node/value_storage/nodes_value_containers.hpp
+++ b/src/feature_creation/node/value_storage/nodes_value_containers.hpp
@@ -14,6 +14,8 @@
 #include <memory>
 #include <vector>
 
+#include <omp.h>
+
 #include<utils/enum.hpp>
 
 namespace node_value_arrs
@@ -31,7 +33,7 @@ namespace node_value_arrs
     extern int N_SAMPLES_TEST; //!< Number of test samples for each feature
     extern int N_STORE_FEATURES; //!< Number of features with stored values
     extern int N_RUNGS_STORED; //!< Number of rungs with values stored
-
+    extern int MAX_N_THREADS; //!< Get the maximum number of threads possible
     /**
      * @brief Initialize the node value arrays
      * @details Using the size of the initial feature space constructor the storage arrays
@@ -75,7 +77,7 @@ namespace node_value_arrs
      *
      * @return The register element for a given feature index and offset
      */
-    inline int& temp_storage_reg(int ind, int offset = 0){return TEMP_STORAGE_REG[(ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES];}
+    inline int& temp_storage_reg(int ind, int offset = 0, int thread = omp_get_thread_num()){return TEMP_STORAGE_REG[(ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES + thread * N_STORE_FEATURES * 3];}
 
     /**
      * @brief Get a reference slot/feature register of the test data
@@ -85,7 +87,7 @@ namespace node_value_arrs
      *
      * @return The register element for a given feature index and offset
      */
-    inline int& temp_storage_test_reg(int ind, int offset = 0){return TEMP_STORAGE_TEST_REG[(ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES];}
+    inline int& temp_storage_test_reg(int ind, int offset = 0, int thread = omp_get_thread_num()){return TEMP_STORAGE_TEST_REG[(ind % N_STORE_FEATURES) + (offset % 3) * N_STORE_FEATURES + thread * N_STORE_FEATURES * 3];}
 
     /**
      * @brief Access element of the permanent training data storage array
@@ -132,7 +134,7 @@ namespace node_value_arrs
      *
      * @return The value pointer
      */
-    double* get_value_ptr(int arr_ind, int feat_ind, int offset = 0);
+    double* get_value_ptr(int arr_ind, int feat_ind, int offset = 0, int thread = omp_get_thread_num());
 
     /**
      * @brief Get a Node's test_value_ptr
@@ -143,7 +145,7 @@ namespace node_value_arrs
      *
      * @return The value pointer
      */
-    double* get_test_value_ptr(int arr_ind, int feat_ind, int offset = 0);
+    double* get_test_value_ptr(int arr_ind, int feat_ind, int offset = 0, int thread = omp_get_thread_num());
 
     /**
      * @brief Get the pointer to a particular selected Node from sis
-- 
GitLab