| 139 | } |
| 140 | |
| 141 | void Bagging(int iter) override { |
| 142 | bag_data_cnt_ = num_data_; |
| 143 | // not subsample for first iterations |
| 144 | if (iter < static_cast<int>(1.0f / config_->learning_rate)) { return; } |
| 145 | |
| 146 | const data_size_t min_inner_size = 100; |
| 147 | data_size_t inner_size = (num_data_ + num_threads_ - 1) / num_threads_; |
| 148 | if (inner_size < min_inner_size) { inner_size = min_inner_size; } |
| 149 | OMP_INIT_EX(); |
| 150 | #pragma omp parallel for schedule(static, 1) |
| 151 | for (int i = 0; i < num_threads_; ++i) { |
| 152 | OMP_LOOP_EX_BEGIN(); |
| 153 | left_cnts_buf_[i] = 0; |
| 154 | right_cnts_buf_[i] = 0; |
| 155 | data_size_t cur_start = i * inner_size; |
| 156 | if (cur_start > num_data_) { continue; } |
| 157 | data_size_t cur_cnt = inner_size; |
| 158 | if (cur_start + cur_cnt > num_data_) { cur_cnt = num_data_ - cur_start; } |
| 159 | Random cur_rand(config_->bagging_seed + iter * num_threads_ + i); |
| 160 | data_size_t cur_left_count = BaggingHelper(&cur_rand, cur_start, cur_cnt, |
| 161 | tmp_indices_.data() + cur_start, tmp_indice_right_.data() + cur_start); |
| 162 | offsets_buf_[i] = cur_start; |
| 163 | left_cnts_buf_[i] = cur_left_count; |
| 164 | right_cnts_buf_[i] = cur_cnt - cur_left_count; |
| 165 | OMP_LOOP_EX_END(); |
| 166 | } |
| 167 | OMP_THROW_EX(); |
| 168 | data_size_t left_cnt = 0; |
| 169 | left_write_pos_buf_[0] = 0; |
| 170 | right_write_pos_buf_[0] = 0; |
| 171 | for (int i = 1; i < num_threads_; ++i) { |
| 172 | left_write_pos_buf_[i] = left_write_pos_buf_[i - 1] + left_cnts_buf_[i - 1]; |
| 173 | right_write_pos_buf_[i] = right_write_pos_buf_[i - 1] + right_cnts_buf_[i - 1]; |
| 174 | } |
| 175 | left_cnt = left_write_pos_buf_[num_threads_ - 1] + left_cnts_buf_[num_threads_ - 1]; |
| 176 | |
| 177 | #pragma omp parallel for schedule(static, 1) |
| 178 | for (int i = 0; i < num_threads_; ++i) { |
| 179 | OMP_LOOP_EX_BEGIN(); |
| 180 | if (left_cnts_buf_[i] > 0) { |
| 181 | std::memcpy(bag_data_indices_.data() + left_write_pos_buf_[i], |
| 182 | tmp_indices_.data() + offsets_buf_[i], left_cnts_buf_[i] * sizeof(data_size_t)); |
| 183 | } |
| 184 | if (right_cnts_buf_[i] > 0) { |
| 185 | std::memcpy(bag_data_indices_.data() + left_cnt + right_write_pos_buf_[i], |
| 186 | tmp_indice_right_.data() + offsets_buf_[i], right_cnts_buf_[i] * sizeof(data_size_t)); |
| 187 | } |
| 188 | OMP_LOOP_EX_END(); |
| 189 | } |
| 190 | OMP_THROW_EX(); |
| 191 | bag_data_cnt_ = left_cnt; |
| 192 | // set bagging data to tree learner |
| 193 | if (!is_use_subset_) { |
| 194 | tree_learner_->SetBaggingData(bag_data_indices_.data(), bag_data_cnt_); |
| 195 | } else { |
| 196 | // get subset |
| 197 | #ifdef TIMETAG |
| 198 | auto start_time = std::chrono::steady_clock::now(); |
nothing calls this directly
no test coverage detected