[GPU-Plugin] Add GPU accelerated prediction (#2593)

* [GPU-Plugin] Add GPU accelerated prediction

* Improve allocation message

* Update documentation

* Resolve linker error for predictor

* Add unit tests
This commit is contained in:
Rory Mitchell
2017-08-16 12:31:59 +12:00
committed by GitHub
parent 71e5e622b1
commit ef23e424f1
25 changed files with 876 additions and 203 deletions

View File

@@ -6,33 +6,31 @@
*/
#pragma once
#include <xgboost/base.h>
#include <xgboost/data.h>
#include <functional>
#include <memory>
#include <vector>
#include <string>
#include <utility>
#include <vector>
#include "../../src/gbm/gbtree_model.h"
// Forward declarations
namespace xgboost {
class DMatrix;
class TreeUpdater;
}
namespace xgboost {
namespace gbm {
struct GBTreeModel;
}
} // namespace xgboost
namespace xgboost {
/**
* \class Predictor
*
* \brief Performs prediction on individual training instances or batches of instances for GBTree.
* The predictor also manages a prediction cache associated with input matrices. If possible,
* it will use previously calculated predictions instead of calculating new predictions.
* Prediction functions all take a GBTreeModel and a DMatrix as input and output a vector of
* predictions. The predictor does not modify any state of the model itself.
* \brief Performs prediction on individual training instances or batches of
* instances for GBTree. The predictor also manages a prediction cache
* associated with input matrices. If possible, it will use previously
* calculated predictions instead of calculating new predictions.
* Prediction functions all take a GBTreeModel and a DMatrix as input and
* output a vector of predictions. The predictor does not modify any state of
* the model itself.
*/
class Predictor {
@@ -40,36 +38,47 @@ class Predictor {
virtual ~Predictor() {}
/**
* \fn void Predictor::InitCache(const std::vector<std::shared_ptr<DMatrix> > &cache);
* \fn virtual void Predictor::Init(const std::vector<std::pair<std::string,
* std::string> >&cfg ,const std::vector<std::shared_ptr<DMatrix> > &cache);
*
* \brief Register input matrices in prediction cache.
* \brief Configure and register input matrices in prediction cache.
*
* \param cfg The configuration.
* \param cache Vector of DMatrix's to be used in prediction.
*/
void InitCache(const std::vector<std::shared_ptr<DMatrix> > &cache);
virtual void Init(const std::vector<std::pair<std::string, std::string>>& cfg,
const std::vector<std::shared_ptr<DMatrix>>& cache);
/**
* \fn virtual void Predictor::PredictBatch( DMatrix* dmat, std::vector<bst_float>* out_preds, const gbm::GBTreeModel &model, int tree_begin, unsigned ntree_limit = 0) = 0;
* \fn virtual void Predictor::PredictBatch( DMatrix* dmat,
* std::vector<bst_float>* out_preds, const gbm::GBTreeModel &model, int
* tree_begin, unsigned ntree_limit = 0) = 0;
*
* \brief Generate batch predictions for a given feature matrix. May use cached predictions if available instead of calculating from scratch.
* \brief Generate batch predictions for a given feature matrix. May use
* cached predictions if available instead of calculating from scratch.
*
* \param [in,out] dmat Feature matrix.
* \param [in,out] out_preds The output preds.
* \param model The model to predict from.
* \param tree_begin The tree begin index.
* \param ntree_limit (Optional) The ntree limit. 0 means do not limit trees.
* \param ntree_limit (Optional) The ntree limit. 0 means do not
* limit trees.
*/
virtual void PredictBatch(
DMatrix* dmat, std::vector<bst_float>* out_preds, const gbm::GBTreeModel &model,
int tree_begin, unsigned ntree_limit = 0) = 0;
virtual void PredictBatch(DMatrix* dmat, std::vector<bst_float>* out_preds,
const gbm::GBTreeModel& model, int tree_begin,
unsigned ntree_limit = 0) = 0;
/**
* \fn virtual void Predictor::UpdatePredictionCache( const gbm::GBTreeModel &model, std::vector<std::unique_ptr<TreeUpdater> >* updaters, int num_new_trees) = 0;
* \fn virtual void Predictor::UpdatePredictionCache( const gbm::GBTreeModel
* &model, std::vector<std::unique_ptr<TreeUpdater> >* updaters, int
* num_new_trees) = 0;
*
* \brief Update the internal prediction cache using newly added trees. Will use the tree updater
* to do this if possible. Should be called as a part of the tree boosting process to facilitate the look up of predictions at a later time.
* \brief Update the internal prediction cache using newly added trees. Will
* use the tree updater to do this if possible. Should be called as a part of
* the tree boosting process to facilitate the look up of predictions
* at a later time.
*
* \param model The model.
* \param [in,out] updaters The updater sequence for gradient boosting.
@@ -77,15 +86,19 @@ class Predictor {
*/
virtual void UpdatePredictionCache(
const gbm::GBTreeModel &model, std::vector<std::unique_ptr<TreeUpdater> >* updaters,
const gbm::GBTreeModel& model,
std::vector<std::unique_ptr<TreeUpdater>>* updaters,
int num_new_trees) = 0;
/**
* \fn virtual void Predictor::PredictInstance( const SparseBatch::Inst& inst, std::vector<bst_float>* out_preds, const gbm::GBTreeModel& model, unsigned ntree_limit = 0, unsigned root_index = 0) = 0;
* \fn virtual void Predictor::PredictInstance( const SparseBatch::Inst&
* inst, std::vector<bst_float>* out_preds, const gbm::GBTreeModel& model,
* unsigned ntree_limit = 0, unsigned root_index = 0) = 0;
*
* \brief online prediction function, predict score for one instance at a time NOTE: use the batch
* prediction interface if possible, batch prediction is usually more efficient than online
* prediction This function is NOT threadsafe, make sure you only call from one thread.
* \brief online prediction function, predict score for one instance at a time
* NOTE: use the batch prediction interface if possible, batch prediction is
* usually more efficient than online prediction This function is NOT
* threadsafe, make sure you only call from one thread.
*
* \param inst The instance to predict.
* \param [in,out] out_preds The output preds.
@@ -94,15 +107,19 @@ class Predictor {
* \param root_index (Optional) Zero-based index of the root.
*/
virtual void PredictInstance(
const SparseBatch::Inst& inst, std::vector<bst_float>* out_preds,
const gbm::GBTreeModel& model, unsigned ntree_limit = 0, unsigned root_index = 0) = 0;
virtual void PredictInstance(const SparseBatch::Inst& inst,
std::vector<bst_float>* out_preds,
const gbm::GBTreeModel& model,
unsigned ntree_limit = 0,
unsigned root_index = 0) = 0;
/**
* \fn virtual void Predictor::PredictLeaf(DMatrix* dmat, std::vector<bst_float>* out_preds, const gbm::GBTreeModel& model, unsigned ntree_limit = 0) = 0;
* \fn virtual void Predictor::PredictLeaf(DMatrix* dmat,
* std::vector<bst_float>* out_preds, const gbm::GBTreeModel& model, unsigned
* ntree_limit = 0) = 0;
*
* \brief predict the leaf index of each tree, the output will be nsample * ntree vector this is
* only valid in gbtree predictor.
* \brief predict the leaf index of each tree, the output will be nsample *
* ntree vector this is only valid in gbtree predictor.
*
* \param [in,out] dmat The input feature matrix.
* \param [in,out] out_preds The output preds.
@@ -111,13 +128,17 @@ class Predictor {
*/
virtual void PredictLeaf(DMatrix* dmat, std::vector<bst_float>* out_preds,
const gbm::GBTreeModel& model, unsigned ntree_limit = 0) = 0;
const gbm::GBTreeModel& model,
unsigned ntree_limit = 0) = 0;
/**
* \fn virtual void Predictor::PredictContribution( DMatrix* dmat, std::vector<bst_float>* out_contribs, const gbm::GBTreeModel& model, unsigned ntree_limit = 0) = 0;
* \fn virtual void Predictor::PredictContribution( DMatrix* dmat,
* std::vector<bst_float>* out_contribs, const gbm::GBTreeModel& model,
* unsigned ntree_limit = 0) = 0;
*
* \brief feature contributions to individual predictions; the output will be a vector of length
* (nfeats + 1) * num_output_group * nsample, arranged in that order.
* \brief feature contributions to individual predictions; the output will be
* a vector of length (nfeats + 1) * num_output_group * nsample, arranged in
* that order.
*
* \param [in,out] dmat The input feature matrix.
* \param [in,out] out_contribs The output feature contribs.
@@ -125,9 +146,10 @@ class Predictor {
* \param ntree_limit (Optional) The ntree limit.
*/
virtual void PredictContribution(
DMatrix* dmat, std::vector<bst_float>* out_contribs,
const gbm::GBTreeModel& model, unsigned ntree_limit = 0) = 0;
virtual void PredictContribution(DMatrix* dmat,
std::vector<bst_float>* out_contribs,
const gbm::GBTreeModel& model,
unsigned ntree_limit = 0) = 0;
/**
* \fn static Predictor* Predictor::Create(std::string name);
@@ -139,6 +161,32 @@ class Predictor {
static Predictor* Create(std::string name);
protected:
/**
* \fn bool PredictFromCache(DMatrix* dmat, std::vector<bst_float>*
* out_preds, const gbm::GBTreeModel& model, unsigned ntree_limit = 0)
*
* \brief Attempt to predict from cache.
*
* \return True if it succeeds, false if it fails.
*/
bool PredictFromCache(DMatrix* dmat, std::vector<bst_float>* out_preds,
const gbm::GBTreeModel& model,
unsigned ntree_limit = 0);
/**
* \fn void Predictor::InitOutPredictions(const MetaInfo& info,
* std::vector<bst_float>* out_preds, const gbm::GBTreeModel& model) const;
*
* \brief Init out predictions according to base margin.
*
* \param info Dmatrix info possibly containing base margin.
* \param [in,out] out_preds The out preds.
* \param model The model.
*/
void InitOutPredictions(const MetaInfo& info,
std::vector<bst_float>* out_preds,
const gbm::GBTreeModel& model) const;
/**
* \struct PredictionCacheEntry
*
@@ -151,8 +199,8 @@ class Predictor {
};
/**
* \brief Map of matrices and associated cached predictions to facilitate storing and looking up
* predictions.
* \brief Map of matrices and associated cached predictions to facilitate
* storing and looking up predictions.
*/
std::unordered_map<DMatrix*, PredictionCacheEntry> cache_;

View File

@@ -271,6 +271,10 @@ class TreeModel {
inline const Node& operator[](int nid) const {
return nodes[nid];
}
/*! \brief get const reference to nodes */
inline const std::vector<Node>& GetNodes() const { return nodes; }
/*! \brief get node statistics given nid */
inline NodeStat& stat(int nid) {
return stats[nid];