diff --git a/cmake/toolchains/gnu_no_py.cmake b/cmake/toolchains/gnu_no_py.cmake
index edcf00a351e3927b5952b5eaa4998214d92e6142..1b1f1b4cd75a8a7cfe17626f52b4b16d9a55e7bf 100644
--- a/cmake/toolchains/gnu_no_py.cmake
+++ b/cmake/toolchains/gnu_no_py.cmake
@@ -2,7 +2,7 @@
 # Basic Flags #
 ###############
 set(CMAKE_CXX_COMPILER g++ CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-O2" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-O3 -march=native" CACHE STRING "")
 
 #################
 # Feature Flags #
diff --git a/cmake/toolchains/gnu_py.cmake b/cmake/toolchains/gnu_py.cmake
index 2ca262adfbc372f9745482c8993354d38166e664..82f700ab13ca092d6f726914a21f7df5b3cc8ca3 100644
--- a/cmake/toolchains/gnu_py.cmake
+++ b/cmake/toolchains/gnu_py.cmake
@@ -2,7 +2,7 @@
 # Basic Flags #
 ###############
 set(CMAKE_CXX_COMPILER g++ CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-O2" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-O3 -march=native" CACHE STRING "")
 
 #################
 # Feature Flags #
diff --git a/cmake/toolchains/intel_no_py.cmake b/cmake/toolchains/intel_no_py.cmake
index 4c39f09cca2f18171b4b17fdbd5ade5f2b3ecc83..ae4767c18f87928ae985836211a8f179085c6cbc 100644
--- a/cmake/toolchains/intel_no_py.cmake
+++ b/cmake/toolchains/intel_no_py.cmake
@@ -2,7 +2,7 @@
 # Basic Flags #
 ###############
 set(CMAKE_CXX_COMPILER icpc CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-O3" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-O3 -xhost" CACHE STRING "")
 
 #################
 # Feature Flags #
diff --git a/cmake/toolchains/intel_py.cmake b/cmake/toolchains/intel_py.cmake
index 98cffb24c2125138dc1ec4619b275bb3fee565c2..01f1e1ca5a0539d6f3cf91acfff20f4d406d3396 100644
--- a/cmake/toolchains/intel_py.cmake
+++ b/cmake/toolchains/intel_py.cmake
@@ -2,7 +2,7 @@
 # Basic Flags #
 ###############
 set(CMAKE_CXX_COMPILER icpc CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-O3" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-O3 -xhost" CACHE STRING "")
 
 #################
 # Feature Flags #
diff --git a/src/mpi_interface/MPI_ops.cpp b/src/mpi_interface/MPI_ops.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..72e26475ef3c0d628b3ea174751980c9bb8937b1
--- /dev/null
+++ b/src/mpi_interface/MPI_ops.cpp
@@ -0,0 +1,10 @@
+#include<mpi_interface/MPI_ops.hpp>
+
+void mpi_reduce_op::set_op(double cross_cor_max)
+{        
+    _cross_cor_max = cross_cor_max;
+    if(_cross_cor_max < 0.99999)
+        _is_valid = comp_feats::valid_feature_against_selected_feat_sc_list;
+    else
+        _is_valid = comp_feats::valid_feature_against_selected_max_corr_1_feat_sc_list;
+}
\ No newline at end of file
diff --git a/src/mpi_interface/MPI_ops.hpp b/src/mpi_interface/MPI_ops.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..cb345d808041306163ac959b835bd1104fd33271
--- /dev/null
+++ b/src/mpi_interface/MPI_ops.hpp
@@ -0,0 +1,55 @@
+/** @file mpi_interface/MPI_Ops.hpp
+ *  @brief Define MPI reduce all operator to facilitate a distributed sorting algorithm
+ *
+ *  This is based off of a project from Meisam Farzalipour Tabriz at the MPCDF (mpi_topk)
+ *
+ *  @author Thomas A. R. Purcell (tpurcell)
+ *  @bug No known bugs.
+ */
+#ifndef SISSO_MPI_OPS
+#define SISSO_MPI_OPS
+
+#include <boost/mpi.hpp>
+#include <feature_creation/node/Node.hpp>
+#include <utils/compare_features.hpp>
+
+namespace mpi_reduce_op
+{
+    std::function<bool(double*, int, double, node_sc_pair*, node_sc_pair*, double)> _is_valid; //!< Function used to calculate the scores for SIS without changing omp environment
+    double _cross_cor_max; //!< The maximum cross correlation between features
+
+    inline bool my_sorter(node_sc_pair node_1, node_sc_pair node_2){ return (std::get<1>(node_1) < std::get<1>(node_2)); }
+
+    template <int N>
+    void select_top_N(void* input_list, void* output_list, int* length, MPI_Datatype* datatype)
+    {
+        std::vector<node_sc_pair> merged_list;
+        const int top_items_number = N;
+
+        for(int ii=0; ii < *length; ++ii)
+        {
+            const int index_first = ii * top_items_number;
+            const int index_last = index_first + top_items_number;
+
+            merged_list.insert(merged_list.end(), static_cast<node_sc_pair*>(input_list)+index_first, static_cast<node_sc_pair*>(input_list)+index_last);
+            merged_list.insert(merged_list.end(), static_cast<node_sc_pair*>(output_list)+index_first, static_cast<node_sc_pair*>(output_list)+index_last);
+            std::sort(merged_list.begin(), merged_list.end(), my_sorter);
+            int ind = index_first;
+            int mi = 0;
+            while(ind != index_last)
+            {
+                const node_ptr cur_node = std::get<0>(merged_list[mi]);
+                if(_is_valid(cur_node->value_ptr(), cur_node->n_samp(), _cross_cor_max, static_cast<node_sc_pair*>(output_list) + index_first, static_cast<node_sc_pair*>(output_list) + ind, std::get<1>(merged_list[mi])))
+                {
+                    static_cast<node_sc_pair*>(output_list)[ind] = merged_list[mi];
+                    ++ind;
+                }
+                ++mi;
+            }
+        }
+    }
+
+    void set_op(double cross_cor_max);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/utils/compare_features.cpp b/src/utils/compare_features.cpp
index 79a73c670b51917ae92620ae257064d64280c8af..8f01c547cd77213efa1b86769f57f67b2d1ea80e 100644
--- a/src/utils/compare_features.cpp
+++ b/src/utils/compare_features.cpp
@@ -83,10 +83,10 @@ bool comp_feats::valid_feature_against_selected_max_corr_1_feat_sc_list(double*
 
     for(auto feat_sc = start; feat_sc < end; ++feat_sc)
     {
-        if(abs(cur_score - std::get<1>(feat_sc)) > 1e-5)
+        if(abs(cur_score - feat_sc->second) > 1e-5)
             continue;
 
-        if((base_val - std::abs(util_funcs::r(std::get<0>(feat_sc)->value_ptr(1), val_ptr, n_samp))) < 1e-9)
+        if((base_val - std::abs(util_funcs::r(feat_sc->first->value_ptr(1), val_ptr, n_samp))) < 1e-9)
             return false;
     }
     return true;
@@ -98,7 +98,7 @@ bool comp_feats::valid_feature_against_selected_feat_sc_list(double* val_ptr, in
 
     for(auto feat_sc = start; feat_sc < end; ++feat_sc)
     {
-        if((base_val - std::abs(util_funcs::r(std::get<1>(feat_sc)->value_ptr(1), val_ptr, n_samp))) < (1.0 - cross_cor_max + 1e-10))
+        if((base_val - std::abs(util_funcs::r(feat_sc->first->value_ptr(1), val_ptr, n_samp))) < (1.0 - cross_cor_max + 1e-10))
             return false;
     }
     return true;
diff --git a/src/utils/compare_features.hpp b/src/utils/compare_features.hpp
index a46429692e294ea3e11296f7950a9ad051ca8c11..993a4ef21a2617f74f7b45fd5a682a84097d49fb 100644
--- a/src/utils/compare_features.hpp
+++ b/src/utils/compare_features.hpp
@@ -7,12 +7,12 @@
 #ifndef UTILS_FEAT_COMP
 #define UTILS_FEAT_COMP
 
-#include <tuple>
+#include <utility>
 
 #include <feature_creation/node/Node.hpp>
 #include <classification/utils.hpp>
 
-typedef std::tuple<node_ptr, double> node_sc_pair;
+typedef std::pair<node_ptr, double> node_sc_pair;
 
 namespace comp_feats
 {