From ed9347fcb60745f33890bf82b7b115a5b9163628 Mon Sep 17 00:00:00 2001 From: Thomas <purcell@fhi-berlin.mpg.de> Date: Thu, 16 Sep 2021 09:50:16 +0200 Subject: [PATCH] Make sc_node_pair a struct not a pair Makes some of the comparisions easier --- .../feature_space/FeatureSpace.cpp | 18 ++-- src/mpi_interface/MPI_Ops.cpp | 5 +- src/mpi_interface/MPI_Ops.hpp | 20 ---- src/utils/compare_features.cpp | 12 +-- src/utils/compare_features.hpp | 93 ++++++++++++++++++- .../googletest/utils/test_compare_features.cc | 3 +- 6 files changed, 112 insertions(+), 39 deletions(-) diff --git a/src/feature_creation/feature_space/FeatureSpace.cpp b/src/feature_creation/feature_space/FeatureSpace.cpp index f210241c..a5e71e64 100644 --- a/src/feature_creation/feature_space/FeatureSpace.cpp +++ b/src/feature_creation/feature_space/FeatureSpace.cpp @@ -1308,11 +1308,15 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) if(_mpi_comm->size() > 1) { // Collect the best features from all ranks - std::vector<node_sc_pair> local_sel(_n_sis_select, std::make_tuple<node_ptr, double>(nullptr, std::numeric_limits<double>::max())); - for(int ff = 0; ff < phi_sel.size(); ++ff) - { - local_sel[ff] = mpi_reduce_op::make_node_sc_pair(phi_sel[ff], scores_sel[ff]); - } + std::vector<node_sc_pair> local_sel(_n_sis_select); + std::transform( + phi_sel.begin(), + phi_sel.end(), + scores_sel.begin(), + local_sel.begin(), + [](node_ptr feat, double sc){return node_sc_pair(feat, sc);} + ); + std::vector<node_sc_pair> selected(_n_sis_select); mpi::all_reduce( *_mpi_comm, @@ -1326,7 +1330,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) cur_feat_local = 0; for(auto& sel : selected) { - _phi_selected.push_back(std::get<0>(sel)); + _phi_selected.push_back(sel._feat); _phi_selected.back()->set_selected(true); _phi_selected.back()->set_d_mat_ind(cur_feat); _phi_selected.back()->set_value(); @@ -1342,7 +1346,7 @@ void FeatureSpace::sis(std::shared_ptr<LossFunction> loss) for(auto& sel : selected) { out_file_stream << std::setw(14) <<std::left << cur_feat << _phi_selected[cur_feat]->postfix_expr() << std::endl; - sum_file_stream << std::setw(14) <<std::left << cur_feat << std::setw(24) << std::setprecision(18) << std::left << prefact * std::get<1>(sel); + sum_file_stream << std::setw(14) <<std::left << cur_feat << std::setw(24) << std::setprecision(18) << std::left << prefact * sel._score; sum_file_stream << _phi_selected[cur_feat]->expr() << std::endl; ++cur_feat; diff --git a/src/mpi_interface/MPI_Ops.cpp b/src/mpi_interface/MPI_Ops.cpp index f2b71fed..2b413fb3 100644 --- a/src/mpi_interface/MPI_Ops.cpp +++ b/src/mpi_interface/MPI_Ops.cpp @@ -65,15 +65,14 @@ std::vector<node_sc_pair> mpi_reduce_op::select_top_feats(std::vector<node_sc_pa // Merge input vectors and sort in_vec_2.insert(in_vec_2.end(), in_vec_1.begin(), in_vec_1.end()); - std::sort(in_vec_2.begin(), in_vec_2.end(), my_sorter); + std::sort(in_vec_2.begin(), in_vec_2.end()); // Populate the output vector int ff = 0; int out_ind = 0; while((out_ind < N_SIS_SELECT) && (ff < in_vec_2.size())) { - const node_ptr cur_node = std::get<0>(in_vec_2[ff]); - if(cur_node && IS_VALID(cur_node->value_ptr(), cur_node->n_samp(), CROSS_COR_MAX, out_vec, std::get<1>(in_vec_2[ff]))) + if(in_vec_2[ff]._feat && IS_VALID(in_vec_2[ff]._feat->value_ptr(), in_vec_2[ff]._feat->n_samp(), CROSS_COR_MAX, out_vec, in_vec_2[ff]._score)) { out_vec.push_back(in_vec_2[ff]); ++out_ind; diff --git a/src/mpi_interface/MPI_Ops.hpp b/src/mpi_interface/MPI_Ops.hpp index cfa62b5b..37d4758c 100644 --- a/src/mpi_interface/MPI_Ops.hpp +++ b/src/mpi_interface/MPI_Ops.hpp @@ -35,26 +35,6 @@ namespace mpi_reduce_op extern double CROSS_COR_MAX; //!< The maximum cross correlation between features extern int N_SIS_SELECT; //!< The number of features to select - /** - * @brief Create a node_sc pair from a node_ptr and a score value - * - * @param feat the node_ptr for the pair - * @param sc the score for the pair - * - * @return The resulting pair - */ - inline node_sc_pair make_node_sc_pair(node_ptr feat, double sc){return std::make_tuple(feat, sc);} - - /** - * @brief The function for sorting different node_sc pointers - * - * @param node_1 first node to compare - * @param node_2 second node to compare - * - * @return True if the score of node_1 is less then the score of node_2 - */ - 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)); } - /** * @brief Get the top features of the combined input vectors * diff --git a/src/utils/compare_features.cpp b/src/utils/compare_features.cpp index fa5d9660..359e9573 100644 --- a/src/utils/compare_features.cpp +++ b/src/utils/compare_features.cpp @@ -146,13 +146,13 @@ bool comp_feats::valid_feature_against_selected_pearson_max_corr_1_mpi_op( for(auto& feat_sc : out_vec) { - if(abs(cur_score - std::get<1>(feat_sc)) > 1e-5) + if(abs(cur_score - feat_sc._score) > 1e-5) { continue; } double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, std::get<0>(feat_sc)->value_ptr(-1, true), n_samp, mean, stand_dev)) + base_val - std::abs(util_funcs::r(val_ptr, feat_sc._feat->value_ptr(-1, true), n_samp, mean, stand_dev)) ); if(std::abs(comp_value) < 5.0e-9) { @@ -239,7 +239,7 @@ bool comp_feats::valid_feature_against_selected_pearson_mpi_op( for(auto& feat_sc : out_vec) { double comp_value = ( - base_val - std::abs(util_funcs::r(val_ptr, std::get<0>(feat_sc)->value_ptr(-1, true), n_samp, mean, stand_dev)) + base_val - std::abs(util_funcs::r(val_ptr, feat_sc._feat->value_ptr(-1, true), n_samp, mean, stand_dev)) ); if(std::abs(comp_value) < (1.0 - cross_cor_max + 5.0e-9)) { @@ -352,13 +352,13 @@ bool comp_feats::valid_feature_against_selected_spearman_max_corr_1_mpi_op( for(auto& feat_sc : out_vec) { - if(abs(std::floor(cur_score) - std::floor(std::get<1>(feat_sc))) > 1e-5) + if(abs(std::floor(cur_score) - std::floor(feat_sc._score)) > 1e-5) { continue; } util_funcs::rank( - std::get<0>(feat_sc)->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp + feat_sc._feat->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp ); double comp_value = ( base_val - std::abs(util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp)) @@ -470,7 +470,7 @@ bool comp_feats::valid_feature_against_selected_spearman_mpi_op( for(auto& feat_sc : out_vec) { util_funcs::rank( - std::get<0>(feat_sc)->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp + feat_sc._feat->value_ptr(-1, true), &RANK[omp_get_thread_num() * 4 * n_samp], &INDEX[omp_get_thread_num() * 2 * n_samp], n_samp ); double comp_value = ( base_val - std::abs(util_funcs::r(&RANK[omp_get_thread_num() * 4 * n_samp], &RANK[(omp_get_thread_num() * 4 + 2) * n_samp], n_samp)) diff --git a/src/utils/compare_features.hpp b/src/utils/compare_features.hpp index b0084cb2..d8292039 100644 --- a/src/utils/compare_features.hpp +++ b/src/utils/compare_features.hpp @@ -26,7 +26,98 @@ #include "feature_creation/node/Node.hpp" -typedef std::tuple<node_ptr, double> node_sc_pair; +struct node_sc_pair +{ + /** + * @brief Serialization function to send over MPI + * + * @param ar Archive representation of node + */ + template <typename Archive> + void serialize(Archive& ar, const unsigned int version) + { + ar & _feat; + ar & _score; + } + node_ptr _feat; //!< The feature + double _score; //!< The score + + /** + * @brief Default Constructor + */ + node_sc_pair(): + _feat(nullptr), + _score(0.0) + {} + + /** + * @brief Constructor + * + * @param feat The feature + * @param score The score + */ + node_sc_pair(node_ptr feat, double score): + _feat(feat), + _score(score) + {} + + /** + * @brief Copy Constructor + * + * @param o Node to be copied + */ + node_sc_pair(const node_sc_pair& o) = default; + + /** + * @brief Move Constructor + * + * @param o Node to be copied + */ + node_sc_pair(node_sc_pair&& o) = default; + + /** + * @brief Copy Assignment operator + * + * @param o Node to be copied + */ + node_sc_pair& operator= (const node_sc_pair& o) = default; + + /** + * @brief Move Assignment operator + * + * @param o Node to be moved + */ + node_sc_pair& operator= (node_sc_pair&& o) = default; + + /** + * @brief Less than operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is less than pair_2.score + */ + inline bool operator<(node_sc_pair pair_2){return _score < pair_2._score;} + /** + * @brief Greater than operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is greater than pair_2.score + */ + inline bool operator>(node_sc_pair pair_2){return _score > pair_2._score;} + /** + * @brief Less than or equal to operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is less than or equal to pair_2.score + */ + inline bool operator<=(node_sc_pair pair_2){return _score <= pair_2._score;} + /** + * @brief Greater than or equal to operator + * + * @param pair_2 node_sc_pair to compare against + * @return True if _score is greater than or equal to pair_2.score + */ + inline bool operator>=(node_sc_pair pair_2){return _score >= pair_2._score;} +}; namespace comp_feats { diff --git a/tests/googletest/utils/test_compare_features.cc b/tests/googletest/utils/test_compare_features.cc index cbf0ff1a..2c6bfb9e 100644 --- a/tests/googletest/utils/test_compare_features.cc +++ b/tests/googletest/utils/test_compare_features.cc @@ -27,11 +27,10 @@ namespace { std::vector<double> scores = {0.9897782665572893}; std::vector<node_ptr> selected(1); - std::vector<node_sc_pair> mpi_op_sel(1); node_value_arrs::initialize_values_arr({4}, {0}, 1, 0, false); selected[0] = std::make_shared<FeatureNode>(0, "A", val_3, std::vector<double>(), Unit()); - mpi_op_sel[0] = mpi_reduce_op::make_node_sc_pair(selected[0], scores[0]); + std::vector<node_sc_pair> mpi_op_sel(1, node_sc_pair(selected[0], scores[0])); node_value_arrs::initialize_d_matrix_arr(); node_value_arrs::resize_d_matrix_arr(1); -- GitLab