MCPcopy Create free account
hub / github.com/antmachineintelligence/mtgbmcode / GPUHistogram

Method GPUHistogram

src/treelearner/gpu_tree_learner.cpp:126–191  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

124}
125
126void GPUTreeLearner::GPUHistogram(data_size_t leaf_num_data, bool use_all_features) {
127 // we have already copied ordered gradients, ordered hessians and indices to GPU
128 // decide the best number of workgroups working on one feature4 tuple
129 // set work group size based on feature size
130 // each 2^exp_workgroups_per_feature workgroups work on a feature4 tuple
131 int exp_workgroups_per_feature = GetNumWorkgroupsPerFeature(leaf_num_data);
132 int num_workgroups = (1 << exp_workgroups_per_feature) * num_dense_feature4_;
133 if (num_workgroups > preallocd_max_num_wg_) {
134 preallocd_max_num_wg_ = num_workgroups;
135 Log::Info("Increasing preallocd_max_num_wg_ to %d for launching more workgroups", preallocd_max_num_wg_);
136 device_subhistograms_.reset(new boost::compute::vector<char>(
137 preallocd_max_num_wg_ * dword_features_ * device_bin_size_ * hist_bin_entry_sz_, ctx_));
138 // we need to refresh the kernel arguments after reallocating
139 for (int i = 0; i <= kMaxLogWorkgroupsPerFeature; ++i) {
140 // The only argument that needs to be changed later is num_data_
141 histogram_kernels_[i].set_arg(7, *device_subhistograms_);
142 histogram_allfeats_kernels_[i].set_arg(7, *device_subhistograms_);
143 histogram_fulldata_kernels_[i].set_arg(7, *device_subhistograms_);
144 }
145 }
146 #if GPU_DEBUG >= 4
147 printf("Setting exp_workgroups_per_feature to %d, using %u work groups\n", exp_workgroups_per_feature, num_workgroups);
148 printf("Constructing histogram with %d examples\n", leaf_num_data);
149 #endif
150
151 // the GPU kernel will process all features in one call, and each
152 // 2^exp_workgroups_per_feature (compile time constant) workgroup will
153 // process one feature4 tuple
154
155 if (use_all_features) {
156 histogram_allfeats_kernels_[exp_workgroups_per_feature].set_arg(4, leaf_num_data);
157 } else {
158 histogram_kernels_[exp_workgroups_per_feature].set_arg(4, leaf_num_data);
159 }
160 // for the root node, indices are not copied
161 if (leaf_num_data != num_data_) {
162 indices_future_.wait();
163 }
164 // for constant hessian, hessians are not copied except for the root node
165 if (!is_constant_hessian_) {
166 hessians_future_.wait();
167 }
168 gradients_future_.wait();
169 // there will be 2^exp_workgroups_per_feature = num_workgroups / num_dense_feature4 sub-histogram per feature4
170 // and we will launch num_feature workgroups for this kernel
171 // will launch threads for all features
172 // the queue should be asynchrounous, and we will can WaitAndGetHistograms() before we start processing dense feature groups
173 if (leaf_num_data == num_data_) {
174 kernel_wait_obj_ = boost::compute::wait_list(queue_.enqueue_1d_range_kernel(histogram_fulldata_kernels_[exp_workgroups_per_feature], 0, num_workgroups * 256, 256));
175 } else {
176 if (use_all_features) {
177 kernel_wait_obj_ = boost::compute::wait_list(
178 queue_.enqueue_1d_range_kernel(histogram_allfeats_kernels_[exp_workgroups_per_feature], 0, num_workgroups * 256, 256));
179 } else {
180 kernel_wait_obj_ = boost::compute::wait_list(
181 queue_.enqueue_1d_range_kernel(histogram_kernels_[exp_workgroups_per_feature], 0, num_workgroups * 256, 256));
182 }
183 }

Callers

nothing calls this directly

Calls 6

wait_listClass · 0.85
resetMethod · 0.80
set_argMethod · 0.45
waitMethod · 0.45

Tested by

no test coverage detected