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:
Rory Mitchell
2018-04-19 18:57:13 +12:00
committed by GitHub
parent 3242b0a378
commit ccf80703ef
97 changed files with 3407 additions and 3354 deletions

View File

@@ -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

View File

@@ -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);
}
}
};

View File

@@ -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();

View File

@@ -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());
}