#include "xgboost/predictor.h"
#include <dmlc/registry.h>
#include <cstdint>
#include <string>
#include "../gbm/gbtree_model.h"
#include "xgboost/base.h"
#include "xgboost/context.h"
#include "xgboost/data.h"
#include "xgboost/host_device_vector.h"
#include "xgboost/learner.h"
#include "xgboost/linalg.h"
#include "xgboost/logging.h"
namespace dmlc {
DMLC_REGISTRY_ENABLE(::xgboost::PredictorReg);
}
namespace xgboost {
void Predictor::Configure(Args const&) {}
Predictor* Predictor::Create(std::string const& name, Context const* ctx) {
auto* e = ::dmlc::Registry<PredictorReg>::Get()->Find(name);
if (e == nullptr) {
LOG(FATAL) << "Unknown predictor type " << name;
}
auto p_predictor = (e->body)(ctx);
return p_predictor;
}
template <int32_t D>
void ValidateBaseMarginShape(linalg::Tensor<float, D> const& margin, bst_idx_t n_samples,
bst_group_t n_groups) {
std::string expected{"Invalid shape of base_margin. Expected: (" + std::to_string(n_samples) +
", " + std::to_string(n_groups) + ")"};
CHECK_EQ(margin.Shape(0), n_samples) << expected;
CHECK_EQ(margin.Shape(1), n_groups) << expected;
}
void Predictor::InitOutPredictions(const MetaInfo& info, HostDeviceVector<bst_float>* out_preds,
const gbm::GBTreeModel& model) const {
CHECK_NE(model.learner_model_param->num_output_group, 0);
auto n = static_cast<size_t>(model.learner_model_param->OutputLength() * info.num_row_);
const HostDeviceVector<bst_float>* base_margin = info.base_margin_.Data();
if (ctx_->Device().IsCUDA()) {
out_preds->SetDevice(ctx_->Device());
}
if (!base_margin->Empty()) {
out_preds->Resize(n);
ValidateBaseMarginShape(info.base_margin_, info.num_row_,
model.learner_model_param->OutputLength());
out_preds->Copy(*base_margin);
} else {
out_preds->Resize(n);
auto base_score = model.learner_model_param->BaseScore(DeviceOrd::CPU())(0);
out_preds->Fill(base_score);
}
}
}
namespace xgboost::predictor {
#ifdef XGBOOST_USE_CUDA
DMLC_REGISTRY_LINK_TAG(gpu_predictor);
#endif DMLC_REGISTRY_LINK_TAG(cpu_predictor);
}