| 853 | |
| 854 | |
| 855 | void SerialTreeLearner::RenewTreeOutput(Tree* tree, const ObjectiveFunction* obj, std::function<double(const label_t*, int)> residual_getter, |
| 856 | data_size_t total_num_data, const data_size_t* bag_indices, data_size_t bag_cnt) const { |
| 857 | if (obj != nullptr && obj->IsRenewTreeOutput()) { |
| 858 | CHECK(tree->num_leaves() <= data_partition_->num_leaves()); |
| 859 | const data_size_t* bag_mapper = nullptr; |
| 860 | if (total_num_data != num_data_) { |
| 861 | CHECK(bag_cnt == num_data_); |
| 862 | bag_mapper = bag_indices; |
| 863 | } |
| 864 | std::vector<int> n_nozeroworker_perleaf(tree->num_leaves(), 1); |
| 865 | int num_machines = Network::num_machines(); |
| 866 | #pragma omp parallel for schedule(static) |
| 867 | for (int i = 0; i < tree->num_leaves(); ++i) { |
| 868 | const double output = static_cast<double>(tree->LeafOutput(i)); |
| 869 | data_size_t cnt_leaf_data = 0; |
| 870 | auto index_mapper = data_partition_->GetIndexOnLeaf(i, &cnt_leaf_data); |
| 871 | if (cnt_leaf_data > 0) { |
| 872 | // bag_mapper[index_mapper[i]] |
| 873 | const double new_output = obj->RenewTreeOutput(output, residual_getter, index_mapper, bag_mapper, cnt_leaf_data); |
| 874 | tree->SetLeafOutput(i, new_output); |
| 875 | } else { |
| 876 | CHECK(num_machines > 1); |
| 877 | tree->SetLeafOutput(i, 0.0); |
| 878 | n_nozeroworker_perleaf[i] = 0; |
| 879 | } |
| 880 | } |
| 881 | if (num_machines > 1) { |
| 882 | std::vector<double> outputs(tree->num_leaves()); |
| 883 | for (int i = 0; i < tree->num_leaves(); ++i) { |
| 884 | outputs[i] = static_cast<double>(tree->LeafOutput(i)); |
| 885 | } |
| 886 | outputs = Network::GlobalSum(&outputs); |
| 887 | n_nozeroworker_perleaf = Network::GlobalSum(&n_nozeroworker_perleaf); |
| 888 | for (int i = 0; i < tree->num_leaves(); ++i) { |
| 889 | tree->SetLeafOutput(i, outputs[i] / n_nozeroworker_perleaf[i]); |
| 890 | } |
| 891 | } |
| 892 | } |
| 893 | } |
| 894 | |
| 895 | } // namespace LightGBM |
no test coverage detected