Clang-tidy static analysis (#3222)
* Clang-tidy static analysis * Modernise checks * Google coding standard checks * Identifier renaming according to Google style
This commit is contained in:
@@ -38,15 +38,15 @@ class SoftmaxMultiClassObj : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<bst_float>* preds,
|
||||
const MetaInfo& info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair>* out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK(preds->size() == (static_cast<size_t>(param_.num_class) * info.labels.size()))
|
||||
HostDeviceVector<GradientPair>* out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK(preds->Size() == (static_cast<size_t>(param_.num_class) * info.labels_.size()))
|
||||
<< "SoftmaxMultiClassObj: label size and pred size does not match";
|
||||
std::vector<bst_float>& preds_h = preds->data_h();
|
||||
out_gpair->resize(preds_h.size());
|
||||
std::vector<bst_gpair>& gpair = out_gpair->data_h();
|
||||
std::vector<bst_float>& preds_h = preds->HostVector();
|
||||
out_gpair->Resize(preds_h.size());
|
||||
std::vector<GradientPair>& gpair = out_gpair->HostVector();
|
||||
const int nclass = param_.num_class;
|
||||
const omp_ulong ndata = static_cast<omp_ulong>(preds_h.size() / nclass);
|
||||
const auto ndata = static_cast<omp_ulong>(preds_h.size() / nclass);
|
||||
|
||||
int label_error = 0;
|
||||
#pragma omp parallel
|
||||
@@ -58,7 +58,7 @@ class SoftmaxMultiClassObj : public ObjFunction {
|
||||
rec[k] = preds_h[i * nclass + k];
|
||||
}
|
||||
common::Softmax(&rec);
|
||||
int label = static_cast<int>(info.labels[i]);
|
||||
auto label = static_cast<int>(info.labels_[i]);
|
||||
if (label < 0 || label >= nclass) {
|
||||
label_error = label; label = 0;
|
||||
}
|
||||
@@ -67,9 +67,9 @@ class SoftmaxMultiClassObj : public ObjFunction {
|
||||
bst_float p = rec[k];
|
||||
const bst_float h = 2.0f * p * (1.0f - p) * wt;
|
||||
if (label == k) {
|
||||
gpair[i * nclass + k] = bst_gpair((p - 1.0f) * wt, h);
|
||||
gpair[i * nclass + k] = GradientPair((p - 1.0f) * wt, h);
|
||||
} else {
|
||||
gpair[i * nclass + k] = bst_gpair(p* wt, h);
|
||||
gpair[i * nclass + k] = GradientPair(p* wt, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,10 +91,10 @@ class SoftmaxMultiClassObj : public ObjFunction {
|
||||
|
||||
private:
|
||||
inline void Transform(HostDeviceVector<bst_float> *io_preds, bool prob) {
|
||||
std::vector<bst_float> &preds = io_preds->data_h();
|
||||
std::vector<bst_float> &preds = io_preds->HostVector();
|
||||
std::vector<bst_float> tmp;
|
||||
const int nclass = param_.num_class;
|
||||
const omp_ulong ndata = static_cast<omp_ulong>(preds.size() / nclass);
|
||||
const auto ndata = static_cast<omp_ulong>(preds.size() / nclass);
|
||||
if (!prob) tmp.resize(ndata);
|
||||
|
||||
#pragma omp parallel
|
||||
|
||||
@@ -40,17 +40,17 @@ class LambdaRankObj : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<bst_float>* preds,
|
||||
const MetaInfo& info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair>* out_gpair) override {
|
||||
CHECK_EQ(preds->size(), info.labels.size()) << "label size predict size not match";
|
||||
auto& preds_h = preds->data_h();
|
||||
out_gpair->resize(preds_h.size());
|
||||
std::vector<bst_gpair>& gpair = out_gpair->data_h();
|
||||
HostDeviceVector<GradientPair>* out_gpair) override {
|
||||
CHECK_EQ(preds->Size(), info.labels_.size()) << "label size predict size not match";
|
||||
auto& preds_h = preds->HostVector();
|
||||
out_gpair->Resize(preds_h.size());
|
||||
std::vector<GradientPair>& gpair = out_gpair->HostVector();
|
||||
// quick consistency when group is not available
|
||||
std::vector<unsigned> tgptr(2, 0); tgptr[1] = static_cast<unsigned>(info.labels.size());
|
||||
const std::vector<unsigned> &gptr = info.group_ptr.size() == 0 ? tgptr : info.group_ptr;
|
||||
CHECK(gptr.size() != 0 && gptr.back() == info.labels.size())
|
||||
std::vector<unsigned> tgptr(2, 0); tgptr[1] = static_cast<unsigned>(info.labels_.size());
|
||||
const std::vector<unsigned> &gptr = info.group_ptr_.size() == 0 ? tgptr : info.group_ptr_;
|
||||
CHECK(gptr.size() != 0 && gptr.back() == info.labels_.size())
|
||||
<< "group structure not consistent with #rows";
|
||||
const bst_omp_uint ngroup = static_cast<bst_omp_uint>(gptr.size() - 1);
|
||||
const auto ngroup = static_cast<bst_omp_uint>(gptr.size() - 1);
|
||||
#pragma omp parallel
|
||||
{
|
||||
// parall construct, declare random number generator here, so that each
|
||||
@@ -64,8 +64,8 @@ class LambdaRankObj : public ObjFunction {
|
||||
for (bst_omp_uint k = 0; k < ngroup; ++k) {
|
||||
lst.clear(); pairs.clear();
|
||||
for (unsigned j = gptr[k]; j < gptr[k+1]; ++j) {
|
||||
lst.push_back(ListEntry(preds_h[j], info.labels[j], j));
|
||||
gpair[j] = bst_gpair(0.0f, 0.0f);
|
||||
lst.emplace_back(preds_h[j], info.labels_[j], j);
|
||||
gpair[j] = GradientPair(0.0f, 0.0f);
|
||||
}
|
||||
std::sort(lst.begin(), lst.end(), ListEntry::CmpPred);
|
||||
rec.resize(lst.size());
|
||||
@@ -85,9 +85,9 @@ class LambdaRankObj : public ObjFunction {
|
||||
for (unsigned pid = i; pid < j; ++pid) {
|
||||
unsigned ridx = std::uniform_int_distribution<unsigned>(0, nleft + nright - 1)(rnd);
|
||||
if (ridx < nleft) {
|
||||
pairs.push_back(LambdaPair(rec[ridx].second, rec[pid].second));
|
||||
pairs.emplace_back(rec[ridx].second, rec[pid].second);
|
||||
} else {
|
||||
pairs.push_back(LambdaPair(rec[pid].second, rec[ridx+j-i].second));
|
||||
pairs.emplace_back(rec[pid].second, rec[ridx+j-i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,22 +101,22 @@ class LambdaRankObj : public ObjFunction {
|
||||
if (param_.fix_list_weight != 0.0f) {
|
||||
scale *= param_.fix_list_weight / (gptr[k + 1] - gptr[k]);
|
||||
}
|
||||
for (size_t i = 0; i < pairs.size(); ++i) {
|
||||
const ListEntry &pos = lst[pairs[i].pos_index];
|
||||
const ListEntry &neg = lst[pairs[i].neg_index];
|
||||
const bst_float w = pairs[i].weight * scale;
|
||||
for (auto & pair : pairs) {
|
||||
const ListEntry &pos = lst[pair.pos_index];
|
||||
const ListEntry &neg = lst[pair.neg_index];
|
||||
const bst_float w = pair.weight * scale;
|
||||
const float eps = 1e-16f;
|
||||
bst_float p = common::Sigmoid(pos.pred - neg.pred);
|
||||
bst_float g = p - 1.0f;
|
||||
bst_float h = std::max(p * (1.0f - p), eps);
|
||||
// accumulate gradient and hessian in both pid, and nid
|
||||
gpair[pos.rindex] += bst_gpair(g * w, 2.0f*w*h);
|
||||
gpair[neg.rindex] += bst_gpair(-g * w, 2.0f*w*h);
|
||||
gpair[pos.rindex] += GradientPair(g * w, 2.0f*w*h);
|
||||
gpair[neg.rindex] += GradientPair(-g * w, 2.0f*w*h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const char* DefaultEvalMetric(void) const override {
|
||||
const char* DefaultEvalMetric() const override {
|
||||
return "map";
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ class LambdaRankObjNDCG : public LambdaRankObj {
|
||||
void GetLambdaWeight(const std::vector<ListEntry> &sorted_list,
|
||||
std::vector<LambdaPair> *io_pairs) override {
|
||||
std::vector<LambdaPair> &pairs = *io_pairs;
|
||||
float IDCG;
|
||||
float IDCG; // NOLINT
|
||||
{
|
||||
std::vector<bst_float> labels(sorted_list.size());
|
||||
for (size_t i = 0; i < sorted_list.size(); ++i) {
|
||||
@@ -187,32 +187,32 @@ class LambdaRankObjNDCG : public LambdaRankObj {
|
||||
IDCG = CalcDCG(labels);
|
||||
}
|
||||
if (IDCG == 0.0) {
|
||||
for (size_t i = 0; i < pairs.size(); ++i) {
|
||||
pairs[i].weight = 0.0f;
|
||||
for (auto & pair : pairs) {
|
||||
pair.weight = 0.0f;
|
||||
}
|
||||
} else {
|
||||
IDCG = 1.0f / IDCG;
|
||||
for (size_t i = 0; i < pairs.size(); ++i) {
|
||||
unsigned pos_idx = pairs[i].pos_index;
|
||||
unsigned neg_idx = pairs[i].neg_index;
|
||||
for (auto & pair : pairs) {
|
||||
unsigned pos_idx = pair.pos_index;
|
||||
unsigned neg_idx = pair.neg_index;
|
||||
float pos_loginv = 1.0f / std::log2(pos_idx + 2.0f);
|
||||
float neg_loginv = 1.0f / std::log2(neg_idx + 2.0f);
|
||||
int pos_label = static_cast<int>(sorted_list[pos_idx].label);
|
||||
int neg_label = static_cast<int>(sorted_list[neg_idx].label);
|
||||
auto pos_label = static_cast<int>(sorted_list[pos_idx].label);
|
||||
auto neg_label = static_cast<int>(sorted_list[neg_idx].label);
|
||||
bst_float original =
|
||||
((1 << pos_label) - 1) * pos_loginv + ((1 << neg_label) - 1) * neg_loginv;
|
||||
float changed =
|
||||
((1 << neg_label) - 1) * pos_loginv + ((1 << pos_label) - 1) * neg_loginv;
|
||||
bst_float delta = (original - changed) * IDCG;
|
||||
if (delta < 0.0f) delta = - delta;
|
||||
pairs[i].weight = delta;
|
||||
pair.weight = delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline static bst_float CalcDCG(const std::vector<bst_float> &labels) {
|
||||
double sumdcg = 0.0;
|
||||
for (size_t i = 0; i < labels.size(); ++i) {
|
||||
const unsigned rel = static_cast<unsigned>(labels[i]);
|
||||
const auto rel = static_cast<unsigned>(labels[i]);
|
||||
if (rel != 0) {
|
||||
sumdcg += ((1 << rel) - 1) / std::log2(static_cast<bst_float>(i + 2));
|
||||
}
|
||||
@@ -238,7 +238,7 @@ class LambdaRankObjMAP : public LambdaRankObj {
|
||||
float ap_acc_add;
|
||||
/* \brief the accumulated positive instance count */
|
||||
float hits;
|
||||
MAPStats(void) {}
|
||||
MAPStats() = default;
|
||||
MAPStats(float ap_acc, float ap_acc_miss, float ap_acc_add, float hits)
|
||||
: ap_acc(ap_acc), ap_acc_miss(ap_acc_miss), ap_acc_add(ap_acc_add), hits(hits) {}
|
||||
};
|
||||
@@ -300,10 +300,10 @@ class LambdaRankObjMAP : public LambdaRankObj {
|
||||
std::vector<LambdaPair> &pairs = *io_pairs;
|
||||
std::vector<MAPStats> map_stats;
|
||||
GetMAPStats(sorted_list, &map_stats);
|
||||
for (size_t i = 0; i < pairs.size(); ++i) {
|
||||
pairs[i].weight =
|
||||
GetLambdaMAP(sorted_list, pairs[i].pos_index,
|
||||
pairs[i].neg_index, &map_stats);
|
||||
for (auto & pair : pairs) {
|
||||
pair.weight =
|
||||
GetLambdaMAP(sorted_list, pair.pos_index,
|
||||
pair.neg_index, &map_stats);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,26 +32,26 @@ struct RegLossParam : public dmlc::Parameter<RegLossParam> {
|
||||
template <typename Loss>
|
||||
class RegLossObj : public ObjFunction {
|
||||
public:
|
||||
RegLossObj() : labels_checked(false) {}
|
||||
RegLossObj() = default;
|
||||
|
||||
void Configure(
|
||||
const std::vector<std::pair<std::string, std::string> > &args) override {
|
||||
param_.InitAllowUnknown(args);
|
||||
}
|
||||
void GetGradient(HostDeviceVector<bst_float> *preds, const MetaInfo &info,
|
||||
int iter, HostDeviceVector<bst_gpair> *out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->size(), info.labels.size())
|
||||
int iter, HostDeviceVector<GradientPair> *out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->Size(), info.labels_.size())
|
||||
<< "labels are not correctly provided"
|
||||
<< "preds.size=" << preds->size()
|
||||
<< ", label.size=" << info.labels.size();
|
||||
auto& preds_h = preds->data_h();
|
||||
<< "preds.size=" << preds->Size()
|
||||
<< ", label.size=" << info.labels_.size();
|
||||
auto& preds_h = preds->HostVector();
|
||||
|
||||
this->LazyCheckLabels(info.labels);
|
||||
out_gpair->resize(preds_h.size());
|
||||
auto& gpair = out_gpair->data_h();
|
||||
const omp_ulong n = static_cast<omp_ulong>(preds_h.size());
|
||||
auto gpair_ptr = out_gpair->ptr_h();
|
||||
this->LazyCheckLabels(info.labels_);
|
||||
out_gpair->Resize(preds_h.size());
|
||||
auto& gpair = out_gpair->HostVector();
|
||||
const auto n = static_cast<omp_ulong>(preds_h.size());
|
||||
auto gpair_ptr = out_gpair->HostPointer();
|
||||
avx::Float8 scale(param_.scale_pos_weight);
|
||||
|
||||
const omp_ulong remainder = n % 8;
|
||||
@@ -59,10 +59,10 @@ class RegLossObj : public ObjFunction {
|
||||
// Use a maximum of 8 threads
|
||||
#pragma omp parallel for schedule(static) num_threads(std::min(8, nthread))
|
||||
for (omp_ulong i = 0; i < n - remainder; i += 8) {
|
||||
avx::Float8 y(&info.labels[i]);
|
||||
avx::Float8 y(&info.labels_[i]);
|
||||
avx::Float8 p = Loss::PredTransform(avx::Float8(&preds_h[i]));
|
||||
avx::Float8 w = info.weights.empty() ? avx::Float8(1.0f)
|
||||
: avx::Float8(&info.weights[i]);
|
||||
avx::Float8 w = info.weights_.empty() ? avx::Float8(1.0f)
|
||||
: avx::Float8(&info.weights_[i]);
|
||||
// Adjust weight
|
||||
w += y * (scale * w - w);
|
||||
avx::Float8 grad = Loss::FirstOrderGradient(p, y);
|
||||
@@ -70,11 +70,11 @@ class RegLossObj : public ObjFunction {
|
||||
avx::StoreGpair(gpair_ptr + i, grad * w, hess * w);
|
||||
}
|
||||
for (omp_ulong i = n - remainder; i < n; ++i) {
|
||||
auto y = info.labels[i];
|
||||
auto y = info.labels_[i];
|
||||
bst_float p = Loss::PredTransform(preds_h[i]);
|
||||
bst_float w = info.GetWeight(i);
|
||||
w += y * ((param_.scale_pos_weight * w) - w);
|
||||
gpair[i] = bst_gpair(Loss::FirstOrderGradient(p, y) * w,
|
||||
gpair[i] = GradientPair(Loss::FirstOrderGradient(p, y) * w,
|
||||
Loss::SecondOrderGradient(p, y) * w);
|
||||
}
|
||||
|
||||
@@ -85,8 +85,8 @@ class RegLossObj : public ObjFunction {
|
||||
return Loss::DefaultEvalMetric();
|
||||
}
|
||||
void PredTransform(HostDeviceVector<bst_float> *io_preds) override {
|
||||
std::vector<bst_float> &preds = io_preds->data_h();
|
||||
const bst_omp_uint ndata = static_cast<bst_omp_uint>(preds.size());
|
||||
std::vector<bst_float> &preds = io_preds->HostVector();
|
||||
const auto ndata = static_cast<bst_omp_uint>(preds.size());
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (bst_omp_uint j = 0; j < ndata; ++j) {
|
||||
preds[j] = Loss::PredTransform(preds[j]);
|
||||
@@ -98,14 +98,14 @@ class RegLossObj : public ObjFunction {
|
||||
|
||||
protected:
|
||||
void LazyCheckLabels(const std::vector<float> &labels) {
|
||||
if (labels_checked) return;
|
||||
if (labels_checked_) return;
|
||||
for (auto &y : labels) {
|
||||
CHECK(Loss::CheckLabel(y)) << Loss::LabelErrorMsg();
|
||||
}
|
||||
labels_checked = true;
|
||||
labels_checked_ = true;
|
||||
}
|
||||
RegLossParam param_;
|
||||
bool labels_checked;
|
||||
bool labels_checked_{false};
|
||||
};
|
||||
|
||||
// register the objective functions
|
||||
@@ -148,12 +148,12 @@ class PoissonRegression : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<bst_float> *preds,
|
||||
const MetaInfo &info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair> *out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->size(), info.labels.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->data_h();
|
||||
out_gpair->resize(preds->size());
|
||||
auto& gpair = out_gpair->data_h();
|
||||
HostDeviceVector<GradientPair> *out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->Size(), info.labels_.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->HostVector();
|
||||
out_gpair->Resize(preds->Size());
|
||||
auto& gpair = out_gpair->HostVector();
|
||||
// check if label in range
|
||||
bool label_correct = true;
|
||||
// start calculating gradient
|
||||
@@ -162,9 +162,9 @@ class PoissonRegression : public ObjFunction {
|
||||
for (omp_ulong i = 0; i < ndata; ++i) { // NOLINT(*)
|
||||
bst_float p = preds_h[i];
|
||||
bst_float w = info.GetWeight(i);
|
||||
bst_float y = info.labels[i];
|
||||
bst_float y = info.labels_[i];
|
||||
if (y >= 0.0f) {
|
||||
gpair[i] = bst_gpair((std::exp(p) - y) * w,
|
||||
gpair[i] = GradientPair((std::exp(p) - y) * w,
|
||||
std::exp(p + param_.max_delta_step) * w);
|
||||
} else {
|
||||
label_correct = false;
|
||||
@@ -173,7 +173,7 @@ class PoissonRegression : public ObjFunction {
|
||||
CHECK(label_correct) << "PoissonRegression: label must be nonnegative";
|
||||
}
|
||||
void PredTransform(HostDeviceVector<bst_float> *io_preds) override {
|
||||
std::vector<bst_float> &preds = io_preds->data_h();
|
||||
std::vector<bst_float> &preds = io_preds->HostVector();
|
||||
const long ndata = static_cast<long>(preds.size()); // NOLINT(*)
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long j = 0; j < ndata; ++j) { // NOLINT(*)
|
||||
@@ -186,7 +186,7 @@ class PoissonRegression : public ObjFunction {
|
||||
bst_float ProbToMargin(bst_float base_score) const override {
|
||||
return std::log(base_score);
|
||||
}
|
||||
const char* DefaultEvalMetric(void) const override {
|
||||
const char* DefaultEvalMetric() const override {
|
||||
return "poisson-nloglik";
|
||||
}
|
||||
|
||||
@@ -209,12 +209,12 @@ class CoxRegression : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<bst_float> *preds,
|
||||
const MetaInfo &info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair> *out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->size(), info.labels.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->data_h();
|
||||
out_gpair->resize(preds_h.size());
|
||||
auto& gpair = out_gpair->data_h();
|
||||
HostDeviceVector<GradientPair> *out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->Size(), info.labels_.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->HostVector();
|
||||
out_gpair->Resize(preds_h.size());
|
||||
auto& gpair = out_gpair->HostVector();
|
||||
const std::vector<size_t> &label_order = info.LabelAbsSort();
|
||||
|
||||
const omp_ulong ndata = static_cast<omp_ulong>(preds_h.size()); // NOLINT(*)
|
||||
@@ -236,7 +236,7 @@ class CoxRegression : public ObjFunction {
|
||||
const double p = preds_h[ind];
|
||||
const double exp_p = std::exp(p);
|
||||
const double w = info.GetWeight(ind);
|
||||
const double y = info.labels[ind];
|
||||
const double y = info.labels_[ind];
|
||||
const double abs_y = std::abs(y);
|
||||
|
||||
// only update the denominator after we move forward in time (labels are sorted)
|
||||
@@ -257,14 +257,14 @@ class CoxRegression : public ObjFunction {
|
||||
|
||||
const double grad = exp_p*r_k - static_cast<bst_float>(y > 0);
|
||||
const double hess = exp_p*r_k - exp_p*exp_p * s_k;
|
||||
gpair.at(ind) = bst_gpair(grad * w, hess * w);
|
||||
gpair.at(ind) = GradientPair(grad * w, hess * w);
|
||||
|
||||
last_abs_y = abs_y;
|
||||
last_exp_p = exp_p;
|
||||
}
|
||||
}
|
||||
void PredTransform(HostDeviceVector<bst_float> *io_preds) override {
|
||||
std::vector<bst_float> &preds = io_preds->data_h();
|
||||
std::vector<bst_float> &preds = io_preds->HostVector();
|
||||
const long ndata = static_cast<long>(preds.size()); // NOLINT(*)
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long j = 0; j < ndata; ++j) { // NOLINT(*)
|
||||
@@ -277,7 +277,7 @@ class CoxRegression : public ObjFunction {
|
||||
bst_float ProbToMargin(bst_float base_score) const override {
|
||||
return std::log(base_score);
|
||||
}
|
||||
const char* DefaultEvalMetric(void) const override {
|
||||
const char* DefaultEvalMetric() const override {
|
||||
return "cox-nloglik";
|
||||
}
|
||||
};
|
||||
@@ -297,12 +297,12 @@ class GammaRegression : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<bst_float> *preds,
|
||||
const MetaInfo &info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair> *out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->size(), info.labels.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->data_h();
|
||||
out_gpair->resize(preds_h.size());
|
||||
auto& gpair = out_gpair->data_h();
|
||||
HostDeviceVector<GradientPair> *out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->Size(), info.labels_.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->HostVector();
|
||||
out_gpair->Resize(preds_h.size());
|
||||
auto& gpair = out_gpair->HostVector();
|
||||
// check if label in range
|
||||
bool label_correct = true;
|
||||
// start calculating gradient
|
||||
@@ -311,9 +311,9 @@ class GammaRegression : public ObjFunction {
|
||||
for (omp_ulong i = 0; i < ndata; ++i) { // NOLINT(*)
|
||||
bst_float p = preds_h[i];
|
||||
bst_float w = info.GetWeight(i);
|
||||
bst_float y = info.labels[i];
|
||||
bst_float y = info.labels_[i];
|
||||
if (y >= 0.0f) {
|
||||
gpair[i] = bst_gpair((1 - y / std::exp(p)) * w, y / std::exp(p) * w);
|
||||
gpair[i] = GradientPair((1 - y / std::exp(p)) * w, y / std::exp(p) * w);
|
||||
} else {
|
||||
label_correct = false;
|
||||
}
|
||||
@@ -321,7 +321,7 @@ class GammaRegression : public ObjFunction {
|
||||
CHECK(label_correct) << "GammaRegression: label must be positive";
|
||||
}
|
||||
void PredTransform(HostDeviceVector<bst_float> *io_preds) override {
|
||||
std::vector<bst_float> &preds = io_preds->data_h();
|
||||
std::vector<bst_float> &preds = io_preds->HostVector();
|
||||
const long ndata = static_cast<long>(preds.size()); // NOLINT(*)
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long j = 0; j < ndata; ++j) { // NOLINT(*)
|
||||
@@ -334,7 +334,7 @@ class GammaRegression : public ObjFunction {
|
||||
bst_float ProbToMargin(bst_float base_score) const override {
|
||||
return std::log(base_score);
|
||||
}
|
||||
const char* DefaultEvalMetric(void) const override {
|
||||
const char* DefaultEvalMetric() const override {
|
||||
return "gamma-nloglik";
|
||||
}
|
||||
};
|
||||
@@ -364,27 +364,27 @@ class TweedieRegression : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<bst_float> *preds,
|
||||
const MetaInfo &info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair> *out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->size(), info.labels.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->data_h();
|
||||
out_gpair->resize(preds->size());
|
||||
auto& gpair = out_gpair->data_h();
|
||||
HostDeviceVector<GradientPair> *out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->Size(), info.labels_.size()) << "labels are not correctly provided";
|
||||
auto& preds_h = preds->HostVector();
|
||||
out_gpair->Resize(preds->Size());
|
||||
auto& gpair = out_gpair->HostVector();
|
||||
// check if label in range
|
||||
bool label_correct = true;
|
||||
// start calculating gradient
|
||||
const omp_ulong ndata = static_cast<omp_ulong>(preds->size()); // NOLINT(*)
|
||||
const omp_ulong ndata = static_cast<omp_ulong>(preds->Size()); // NOLINT(*)
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (omp_ulong i = 0; i < ndata; ++i) { // NOLINT(*)
|
||||
bst_float p = preds_h[i];
|
||||
bst_float w = info.GetWeight(i);
|
||||
bst_float y = info.labels[i];
|
||||
bst_float y = info.labels_[i];
|
||||
float rho = param_.tweedie_variance_power;
|
||||
if (y >= 0.0f) {
|
||||
bst_float grad = -y * std::exp((1 - rho) * p) + std::exp((2 - rho) * p);
|
||||
bst_float hess = -y * (1 - rho) * \
|
||||
std::exp((1 - rho) * p) + (2 - rho) * std::exp((2 - rho) * p);
|
||||
gpair[i] = bst_gpair(grad * w, hess * w);
|
||||
gpair[i] = GradientPair(grad * w, hess * w);
|
||||
} else {
|
||||
label_correct = false;
|
||||
}
|
||||
@@ -392,14 +392,14 @@ class TweedieRegression : public ObjFunction {
|
||||
CHECK(label_correct) << "TweedieRegression: label must be nonnegative";
|
||||
}
|
||||
void PredTransform(HostDeviceVector<bst_float> *io_preds) override {
|
||||
std::vector<bst_float> &preds = io_preds->data_h();
|
||||
std::vector<bst_float> &preds = io_preds->HostVector();
|
||||
const long ndata = static_cast<long>(preds.size()); // NOLINT(*)
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long j = 0; j < ndata; ++j) { // NOLINT(*)
|
||||
preds[j] = std::exp(preds[j]);
|
||||
}
|
||||
}
|
||||
const char* DefaultEvalMetric(void) const override {
|
||||
const char* DefaultEvalMetric() const override {
|
||||
std::ostringstream os;
|
||||
os << "tweedie-nloglik@" << param_.tweedie_variance_power;
|
||||
std::string metric = os.str();
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
#include "../common/host_device_vector.h"
|
||||
#include "./regression_loss.h"
|
||||
|
||||
using namespace dh;
|
||||
|
||||
namespace xgboost {
|
||||
namespace obj {
|
||||
|
||||
using dh::DVec;
|
||||
|
||||
DMLC_REGISTRY_FILE_TAG(regression_obj_gpu);
|
||||
|
||||
struct GPURegLossParam : public dmlc::Parameter<GPURegLossParam> {
|
||||
@@ -43,7 +44,7 @@ struct GPURegLossParam : public dmlc::Parameter<GPURegLossParam> {
|
||||
// GPU kernel for gradient computation
|
||||
template<typename Loss>
|
||||
__global__ void get_gradient_k
|
||||
(bst_gpair *__restrict__ out_gpair, unsigned int *__restrict__ label_correct,
|
||||
(GradientPair *__restrict__ out_gpair, unsigned int *__restrict__ label_correct,
|
||||
const float * __restrict__ preds, const float * __restrict__ labels,
|
||||
const float * __restrict__ weights, int n, float scale_pos_weight) {
|
||||
int i = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
@@ -56,7 +57,7 @@ __global__ void get_gradient_k
|
||||
w *= scale_pos_weight;
|
||||
if (!Loss::CheckLabel(label))
|
||||
atomicAnd(label_correct, 0);
|
||||
out_gpair[i] = bst_gpair
|
||||
out_gpair[i] = GradientPair
|
||||
(Loss::FirstOrderGradient(p, label) * w, Loss::SecondOrderGradient(p, label) * w);
|
||||
}
|
||||
|
||||
@@ -75,40 +76,40 @@ class GPURegLossObj : public ObjFunction {
|
||||
protected:
|
||||
// manages device data
|
||||
struct DeviceData {
|
||||
dvec<float> labels, weights;
|
||||
dvec<unsigned int> label_correct;
|
||||
DVec<float> labels, weights;
|
||||
DVec<unsigned int> label_correct;
|
||||
|
||||
// allocate everything on device
|
||||
DeviceData(bulk_allocator<memory_type::DEVICE>* ba, int device_idx, size_t n) {
|
||||
ba->allocate(device_idx, false,
|
||||
DeviceData(dh::BulkAllocator<dh::MemoryType::kDevice>* ba, int device_idx, size_t n) {
|
||||
ba->Allocate(device_idx, false,
|
||||
&labels, n,
|
||||
&weights, n,
|
||||
&label_correct, 1);
|
||||
}
|
||||
size_t size() const { return labels.size(); }
|
||||
size_t Size() const { return labels.Size(); }
|
||||
};
|
||||
|
||||
|
||||
bool copied_;
|
||||
std::unique_ptr<bulk_allocator<memory_type::DEVICE>> ba_;
|
||||
std::unique_ptr<dh::BulkAllocator<dh::MemoryType::kDevice>> ba_;
|
||||
std::unique_ptr<DeviceData> data_;
|
||||
HostDeviceVector<bst_float> preds_d_;
|
||||
HostDeviceVector<bst_gpair> out_gpair_d_;
|
||||
HostDeviceVector<GradientPair> out_gpair_d_;
|
||||
|
||||
// allocate device data for n elements, do nothing if enough memory is allocated already
|
||||
void LazyResize(int n) {
|
||||
if (data_.get() != nullptr && data_->size() >= n)
|
||||
if (data_.get() != nullptr && data_->Size() >= n)
|
||||
return;
|
||||
copied_ = false;
|
||||
// free the old data and allocate the new data
|
||||
ba_.reset(new bulk_allocator<memory_type::DEVICE>());
|
||||
ba_.reset(new dh::BulkAllocator<dh::MemoryType::kDevice>());
|
||||
data_.reset(new DeviceData(ba_.get(), 0, n));
|
||||
preds_d_.resize(n, 0.0f, param_.gpu_id);
|
||||
out_gpair_d_.resize(n, bst_gpair(), param_.gpu_id);
|
||||
preds_d_.Resize(n, 0.0f, param_.gpu_id);
|
||||
out_gpair_d_.Resize(n, GradientPair(), param_.gpu_id);
|
||||
}
|
||||
|
||||
public:
|
||||
GPURegLossObj() : copied_(false), preds_d_(0, -1), out_gpair_d_(0, -1) {}
|
||||
GPURegLossObj() : copied_(false), preds_d_(0, -1), out_gpair_d_({}, -1) {}
|
||||
|
||||
void Configure(const std::vector<std::pair<std::string, std::string> >& args) override {
|
||||
param_.InitAllowUnknown(args);
|
||||
@@ -118,32 +119,32 @@ class GPURegLossObj : public ObjFunction {
|
||||
void GetGradient(HostDeviceVector<float>* preds,
|
||||
const MetaInfo &info,
|
||||
int iter,
|
||||
HostDeviceVector<bst_gpair>* out_gpair) override {
|
||||
CHECK_NE(info.labels.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->size(), info.labels.size())
|
||||
HostDeviceVector<GradientPair>* out_gpair) override {
|
||||
CHECK_NE(info.labels_.size(), 0U) << "label set cannot be empty";
|
||||
CHECK_EQ(preds->Size(), info.labels_.size())
|
||||
<< "labels are not correctly provided"
|
||||
<< "preds.size=" << preds->size() << ", label.size=" << info.labels.size();
|
||||
size_t ndata = preds->size();
|
||||
out_gpair->resize(ndata, bst_gpair(), param_.gpu_id);
|
||||
<< "preds.size=" << preds->Size() << ", label.size=" << info.labels_.size();
|
||||
size_t ndata = preds->Size();
|
||||
out_gpair->Resize(ndata, GradientPair(), param_.gpu_id);
|
||||
LazyResize(ndata);
|
||||
GetGradientDevice(preds->ptr_d(param_.gpu_id), info, iter,
|
||||
out_gpair->ptr_d(param_.gpu_id), ndata);
|
||||
GetGradientDevice(preds->DevicePointer(param_.gpu_id), info, iter,
|
||||
out_gpair->DevicePointer(param_.gpu_id), ndata);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetGradientDevice(float* preds,
|
||||
const MetaInfo &info,
|
||||
int iter,
|
||||
bst_gpair* out_gpair, size_t n) {
|
||||
safe_cuda(cudaSetDevice(param_.gpu_id));
|
||||
GradientPair* out_gpair, size_t n) {
|
||||
dh::safe_cuda(cudaSetDevice(param_.gpu_id));
|
||||
DeviceData& d = *data_;
|
||||
d.label_correct.fill(1);
|
||||
d.label_correct.Fill(1);
|
||||
// only copy the labels and weights once, similar to how the data is copied
|
||||
if (!copied_) {
|
||||
thrust::copy(info.labels.begin(), info.labels.begin() + n,
|
||||
thrust::copy(info.labels_.begin(), info.labels_.begin() + n,
|
||||
d.labels.tbegin());
|
||||
if (info.weights.size() > 0) {
|
||||
thrust::copy(info.weights.begin(), info.weights.begin() + n,
|
||||
if (info.weights_.size() > 0) {
|
||||
thrust::copy(info.weights_.begin(), info.weights_.begin() + n,
|
||||
d.weights.tbegin());
|
||||
}
|
||||
copied_ = true;
|
||||
@@ -151,11 +152,11 @@ class GPURegLossObj : public ObjFunction {
|
||||
|
||||
// run the kernel
|
||||
const int block = 256;
|
||||
get_gradient_k<Loss><<<div_round_up(n, block), block>>>
|
||||
(out_gpair, d.label_correct.data(), preds,
|
||||
d.labels.data(), info.weights.size() > 0 ? d.weights.data() : nullptr,
|
||||
get_gradient_k<Loss><<<dh::DivRoundUp(n, block), block>>>
|
||||
(out_gpair, d.label_correct.Data(), preds,
|
||||
d.labels.Data(), info.weights_.size() > 0 ? d.weights.Data() : nullptr,
|
||||
n, param_.scale_pos_weight);
|
||||
safe_cuda(cudaGetLastError());
|
||||
dh::safe_cuda(cudaGetLastError());
|
||||
|
||||
// copy output data from the GPU
|
||||
unsigned int label_correct_h;
|
||||
@@ -173,15 +174,15 @@ class GPURegLossObj : public ObjFunction {
|
||||
}
|
||||
|
||||
void PredTransform(HostDeviceVector<float> *io_preds) override {
|
||||
PredTransformDevice(io_preds->ptr_d(param_.gpu_id), io_preds->size());
|
||||
PredTransformDevice(io_preds->DevicePointer(param_.gpu_id), io_preds->Size());
|
||||
}
|
||||
|
||||
void PredTransformDevice(float* preds, size_t n) {
|
||||
safe_cuda(cudaSetDevice(param_.gpu_id));
|
||||
dh::safe_cuda(cudaSetDevice(param_.gpu_id));
|
||||
const int block = 256;
|
||||
pred_transform_k<Loss><<<div_round_up(n, block), block>>>(preds, n);
|
||||
safe_cuda(cudaGetLastError());
|
||||
safe_cuda(cudaDeviceSynchronize());
|
||||
pred_transform_k<Loss><<<dh::DivRoundUp(n, block), block>>>(preds, n);
|
||||
dh::safe_cuda(cudaGetLastError());
|
||||
dh::safe_cuda(cudaDeviceSynchronize());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user