Dispatch between template implementations
| 198 | |
| 199 | // Dispatch between template implementations |
| 200 | void DispatchArrayLayout(HostModel const &model, std::size_t const predict_offset, |
| 201 | common::Span<RegTree::FVec> fvec_tloc, std::size_t const block_size, |
| 202 | linalg::MatrixView<float> out_predt, const std::vector<int> &tree_depth, |
| 203 | bool any_missing, common::OptionalWeights tree_weights) { |
| 204 | auto n_trees = model.tree_end - model.tree_begin; |
| 205 | CHECK_EQ(n_trees, model.Trees().size()); |
| 206 | /* |
| 207 | * We transform trees to array layout for each block of data to avoid memory overheads. |
| 208 | * It makes the array layout inefficient for block_size == 1 |
| 209 | */ |
| 210 | const bool use_array_tree_layout = block_size > 1; |
| 211 | if (use_array_tree_layout) { |
| 212 | CHECK_EQ(n_trees, tree_depth.size()); |
| 213 | // Recheck if the current block has missing values. |
| 214 | if (any_missing) { |
| 215 | any_missing = false; |
| 216 | for (std::size_t i = 0; i < block_size; ++i) { |
| 217 | any_missing |= fvec_tloc[i].HasMissing(); |
| 218 | if (any_missing) { |
| 219 | break; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | if (any_missing) { |
| 224 | PredictBlockByAllTrees<true, true>(model, predict_offset, fvec_tloc, block_size, out_predt, |
| 225 | tree_depth, tree_weights); |
| 226 | } else { |
| 227 | PredictBlockByAllTrees<true, false>(model, predict_offset, fvec_tloc, block_size, out_predt, |
| 228 | tree_depth, tree_weights); |
| 229 | } |
| 230 | } else { |
| 231 | PredictBlockByAllTrees<false, true>(model, predict_offset, fvec_tloc, block_size, out_predt, |
| 232 | tree_depth, tree_weights); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | bool ShouldUseBlock(DMatrix *p_fmat) { |
| 237 | // Threshold to use block-based prediction. |
no test coverage detected