parallel_tree_learner.h 6.46 KB
Newer Older
Guolin Ke's avatar
Guolin Ke committed
1
2
3
4
5
6
7
8
9
10
11
#ifndef LIGHTGBM_TREELEARNER_PARALLEL_TREE_LEARNER_H_
#define LIGHTGBM_TREELEARNER_PARALLEL_TREE_LEARNER_H_

#include <LightGBM/utils/array_args.h>

#include <LightGBM/network.h>
#include "serial_tree_learner.h"

#include <cstring>

#include <vector>
Guolin Ke's avatar
Guolin Ke committed
12
#include <memory>
Guolin Ke's avatar
Guolin Ke committed
13
14
15
16
17

namespace LightGBM {

/*!
* \brief Feature parallel learning algorithm.
Qiwei Ye's avatar
Qiwei Ye committed
18
19
*        Different machine will find best split on different features, then sync global best split
*        It is recommonded used when #data is small or #feature is large
Guolin Ke's avatar
Guolin Ke committed
20
21
22
*/
class FeatureParallelTreeLearner: public SerialTreeLearner {
public:
Guolin Ke's avatar
Guolin Ke committed
23
  explicit FeatureParallelTreeLearner(const TreeConfig* tree_config);
Guolin Ke's avatar
Guolin Ke committed
24
25
26
27
28
29
30
31
32
33
34
35
  ~FeatureParallelTreeLearner();
  virtual void Init(const Dataset* train_data);

protected:
  void BeforeTrain() override;
  void FindBestSplitsForLeaves() override;
private:
  /*! \brief rank of local machine */
  int rank_;
  /*! \brief Number of machines of this parallel task */
  int num_machines_;
  /*! \brief Buffer for network send */
Guolin Ke's avatar
Guolin Ke committed
36
  std::vector<char> input_buffer_;
Guolin Ke's avatar
Guolin Ke committed
37
  /*! \brief Buffer for network receive */
Guolin Ke's avatar
Guolin Ke committed
38
  std::vector<char> output_buffer_;
Guolin Ke's avatar
Guolin Ke committed
39
40
41
42
};

/*!
* \brief Data parallel learning algorithm.
Qiwei Ye's avatar
Qiwei Ye committed
43
44
*        Workers use local data to construct histograms locally, then sync up global histograms.
*        It is recommonded used when #data is large or #feature is small
Guolin Ke's avatar
Guolin Ke committed
45
46
47
*/
class DataParallelTreeLearner: public SerialTreeLearner {
public:
Guolin Ke's avatar
Guolin Ke committed
48
  explicit DataParallelTreeLearner(const TreeConfig* tree_config);
Guolin Ke's avatar
Guolin Ke committed
49
50
  ~DataParallelTreeLearner();
  void Init(const Dataset* train_data) override;
Guolin Ke's avatar
Guolin Ke committed
51
  void ResetConfig(const TreeConfig* tree_config) override;
Guolin Ke's avatar
Guolin Ke committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
protected:
  void BeforeTrain() override;
  void FindBestThresholds() override;
  void FindBestSplitsForLeaves() override;
  void Split(Tree* tree, int best_Leaf, int* left_leaf, int* right_leaf) override;

  inline data_size_t GetGlobalDataCountInLeaf(int leaf_idx) const override {
    if (leaf_idx >= 0) {
      return global_data_count_in_leaf_[leaf_idx];
    } else {
      return 0;
    }
  }

private:
  /*! \brief Rank of local machine */
  int rank_;
  /*! \brief Number of machines of this parallel task */
  int num_machines_;
  /*! \brief Buffer for network send */
Guolin Ke's avatar
Guolin Ke committed
72
  std::vector<char> input_buffer_;
Guolin Ke's avatar
Guolin Ke committed
73
  /*! \brief Buffer for network receive */
Guolin Ke's avatar
Guolin Ke committed
74
  std::vector<char> output_buffer_;
Guolin Ke's avatar
Guolin Ke committed
75
76
  /*! \brief different machines will aggregate histograms for different features,
       use this to mark local aggregate features*/
Guolin Ke's avatar
Guolin Ke committed
77
  std::vector<bool> is_feature_aggregated_;
Guolin Ke's avatar
Guolin Ke committed
78
  /*! \brief Block start index for reduce scatter */
Guolin Ke's avatar
Guolin Ke committed
79
  std::vector<int> block_start_;
Guolin Ke's avatar
Guolin Ke committed
80
  /*! \brief Block size for reduce scatter */
Guolin Ke's avatar
Guolin Ke committed
81
  std::vector<int> block_len_;
Hui Xue's avatar
Hui Xue committed
82
  /*! \brief Write positions for feature histograms */
Guolin Ke's avatar
Guolin Ke committed
83
  std::vector<int> buffer_write_start_pos_;
Hui Xue's avatar
Hui Xue committed
84
  /*! \brief Read positions for local feature histograms */
Guolin Ke's avatar
Guolin Ke committed
85
  std::vector<int> buffer_read_start_pos_;
Guolin Ke's avatar
Guolin Ke committed
86
87
88
  /*! \brief Size for reduce scatter */
  int reduce_scatter_size_;
  /*! \brief Store global number of data in leaves  */
Guolin Ke's avatar
Guolin Ke committed
89
  std::vector<data_size_t> global_data_count_in_leaf_;
Guolin Ke's avatar
Guolin Ke committed
90
91
};

Guolin Ke's avatar
Guolin Ke committed
92
93
94
95
96
97
98
99
/*!
* \brief Voting based data parallel learning algorithm.
* Like data parallel, but not aggregate histograms for all features.
* Here using voting to reduce features, and only aggregate histograms for selected features.
* When #data is large and #feature is large, you can use this to have better speed-up
*/
class VotingParallelTreeLearner: public SerialTreeLearner {
public:
Guolin Ke's avatar
Guolin Ke committed
100
  explicit VotingParallelTreeLearner(const TreeConfig* tree_config);
Guolin Ke's avatar
Guolin Ke committed
101
102
  ~VotingParallelTreeLearner() { }
  void Init(const Dataset* train_data) override;
Guolin Ke's avatar
Guolin Ke committed
103
  void ResetConfig(const TreeConfig* tree_config) override;
Guolin Ke's avatar
Guolin Ke committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
protected:
  void BeforeTrain() override;
  bool BeforeFindBestSplit(int left_leaf, int right_leaf) override;
  void FindBestThresholds() override;
  void FindBestSplitsForLeaves() override;
  void Split(Tree* tree, int best_Leaf, int* left_leaf, int* right_leaf) override;

  inline data_size_t GetGlobalDataCountInLeaf(int leaf_idx) const override {
    if (leaf_idx >= 0) {
      return global_data_count_in_leaf_[leaf_idx];
    } else {
      return 0;
    }
  }
  /*!
  * \brief Perform global voting
  * \param leaf_idx index of leaf
  * \param splits All splits from local voting
  * \param out Result of gobal voting, only store feature indices
  */
  void GlobalVoting(int leaf_idx, const std::vector<SplitInfo>& splits,
    std::vector<int>* out);
  /*!
  * \brief Copy local histgram to buffer
  * \param smaller_top_features Selected features for smaller leaf
  * \param larger_top_features Selected features for larger leaf
  */
  void CopyLocalHistogram(const std::vector<int>& smaller_top_features,
    const std::vector<int>& larger_top_features);

private:
  /*! \brief Tree config used in local mode */
  TreeConfig local_tree_config_;
  /*! \brief Voting size */
  int top_k_;
  /*! \brief Rank of local machine*/
  int rank_;
  /*! \brief Number of machines */
  int num_machines_;
  /*! \brief Buffer for network send */
  std::vector<char> input_buffer_;
  /*! \brief Buffer for network receive */
  std::vector<char> output_buffer_;
  /*! \brief different machines will aggregate histograms for different features,
  use this to mark local aggregate features*/
  std::vector<bool> smaller_is_feature_aggregated_;
  /*! \brief different machines will aggregate histograms for different features,
  use this to mark local aggregate features*/
  std::vector<bool> larger_is_feature_aggregated_;
  /*! \brief Block start index for reduce scatter */
  std::vector<int> block_start_;
  /*! \brief Block size for reduce scatter */
  std::vector<int> block_len_;
  /*! \brief Read positions for feature histgrams at smaller leaf */
  std::vector<int> smaller_buffer_read_start_pos_;
  /*! \brief Read positions for feature histgrams at larger leaf */
  std::vector<int> larger_buffer_read_start_pos_;
  /*! \brief Size for reduce scatter */
  int reduce_scatter_size_;
  /*! \brief Store global number of data in leaves  */
  std::vector<data_size_t> global_data_count_in_leaf_;
  /*! \brief Store global split information for smaller leaf  */
  std::unique_ptr<LeafSplits> smaller_leaf_splits_global_;
  /*! \brief Store global split information for larger leaf  */
  std::unique_ptr<LeafSplits> larger_leaf_splits_global_;
  /*! \brief Store global histogram for smaller leaf  */
  std::unique_ptr<FeatureHistogram[]> smaller_leaf_histogram_array_global_;
  /*! \brief Store global histogram for larger leaf  */
  std::unique_ptr<FeatureHistogram[]> larger_leaf_histogram_array_global_;
};
Guolin Ke's avatar
Guolin Ke committed
174
175

}  // namespace LightGBM
Guolin Ke's avatar
Guolin Ke committed
176
#endif   // LightGBM_TREELEARNER_PARALLEL_TREE_LEARNER_H_
Guolin Ke's avatar
Guolin Ke committed
177