Implement a general array view. (#7365)

* Replace existing matrix and vector view.

This is to prepare for handling higher dimension data and prediction when we support multi-target models.
This commit is contained in:
Jiaming Yuan
2021-11-05 04:16:11 +08:00
committed by GitHub
parent 232144ca09
commit b06040b6d0
11 changed files with 418 additions and 146 deletions

View File

@@ -243,7 +243,10 @@ class GBLinear : public GradientBooster {
// The bias is the last weight
out_scores->resize(model_.weight.size() - learner_model_param_->num_output_group, 0);
auto n_groups = learner_model_param_->num_output_group;
MatrixView<float> scores{out_scores, {learner_model_param_->num_feature, n_groups}};
linalg::TensorView<float, 2> scores{
*out_scores,
{learner_model_param_->num_feature, n_groups},
GenericParameter::kCpuId};
for (size_t i = 0; i < learner_model_param_->num_feature; ++i) {
for (bst_group_t g = 0; g < n_groups; ++g) {
scores(i, g) = model_[i][g];

View File

@@ -229,16 +229,19 @@ void GBTree::DoBoost(DMatrix* p_fmat,
auto device = tparam_.tree_method != TreeMethod::kGPUHist
? GenericParameter::kCpuId
: generic_param_->gpu_id;
auto out = MatrixView<float>(
&predt->predictions,
{static_cast<size_t>(p_fmat->Info().num_row_), static_cast<size_t>(ngroup)}, device);
auto out = linalg::TensorView<float, 2>{
device == GenericParameter::kCpuId ? predt->predictions.HostSpan()
: predt->predictions.DeviceSpan(),
{static_cast<size_t>(p_fmat->Info().num_row_),
static_cast<size_t>(ngroup)},
device};
CHECK_NE(ngroup, 0);
if (ngroup == 1) {
std::vector<std::unique_ptr<RegTree>> ret;
BoostNewTrees(in_gpair, p_fmat, 0, &ret);
const size_t num_new_trees = ret.size();
new_trees.push_back(std::move(ret));
auto v_predt = VectorView<float>{out, 0};
auto v_predt = out.Slice(linalg::All(), 0);
if (updaters_.size() > 0 && num_new_trees == 1 &&
predt->predictions.Size() > 0 &&
updaters_.back()->UpdatePredictionCache(p_fmat, v_predt)) {
@@ -257,7 +260,7 @@ void GBTree::DoBoost(DMatrix* p_fmat,
BoostNewTrees(&tmp, p_fmat, gid, &ret);
const size_t num_new_trees = ret.size();
new_trees.push_back(std::move(ret));
auto v_predt = VectorView<float>{out, static_cast<size_t>(gid)};
auto v_predt = out.Slice(linalg::All(), gid);
if (!(updaters_.size() > 0 && predt->predictions.Size() > 0 &&
num_new_trees == 1 &&
updaters_.back()->UpdatePredictionCache(p_fmat, v_predt))) {

View File

@@ -12,15 +12,14 @@ namespace gbm {
void GPUCopyGradient(HostDeviceVector<GradientPair> const *in_gpair,
bst_group_t n_groups, bst_group_t group_id,
HostDeviceVector<GradientPair> *out_gpair) {
MatrixView<GradientPair const> in{
in_gpair,
{n_groups, 1ul},
auto mat = linalg::TensorView<GradientPair const, 2>(
in_gpair->ConstDeviceSpan(),
{in_gpair->Size() / n_groups, static_cast<size_t>(n_groups)},
in_gpair->DeviceIdx()};
auto v_in = VectorView<GradientPair const>{in, group_id};
in_gpair->DeviceIdx());
auto v_in = mat.Slice(linalg::All(), group_id);
out_gpair->Resize(v_in.Size());
auto d_out = out_gpair->DeviceSpan();
dh::LaunchN(v_in.Size(), [=] __device__(size_t i) { d_out[i] = v_in[i]; });
dh::LaunchN(v_in.Size(), [=] __device__(size_t i) { d_out[i] = v_in(i); });
}
void GPUDartPredictInc(common::Span<float> out_predts,