Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/io/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,21 @@ void Config::CheckParamConflict(const std::unordered_map<std::string, std::strin
if (max_depth > 0 && monotone_penalty >= max_depth) {
Log::Warning("Monotone penalty greater than tree depth. Monotone features won't be used.");
}
if (device_type == std::string("cuda") && !monotone_constraints.empty()) {
if (monotone_constraints_method != std::string("basic")) {
Log::Fatal("CUDA only supports the \"basic\" monotone_constraints_method. "
"Got \"%s\". Use device_type=cpu for intermediate/advanced methods.",
monotone_constraints_method.c_str());
}
if (monotone_penalty > 0.0) {
Log::Fatal("monotone_penalty is not supported with device_type=cuda. "
"Set monotone_penalty=0 or use device_type=cpu.");
}
if (use_quantized_grad) {
Log::Fatal("monotone_constraints is not supported with use_quantized_grad on "
"device_type=cuda. Disable one of them or use device_type=cpu.");
}
}
if (min_data_in_leaf <= 0 && min_sum_hessian_in_leaf <= kEpsilon) {
Log::Warning(
"Cannot set both min_data_in_leaf and min_sum_hessian_in_leaf to 0. "
Expand Down
31 changes: 30 additions & 1 deletion src/treelearner/cuda/cuda_best_split_finder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ CUDABestSplitFinder::CUDABestSplitFinder(
if (has_categorical_feature_ && config->use_quantized_grad) {
Log::Fatal("Quantized training on GPU with categorical features is not supported yet.");
}
// Build a per-inner-feature monotone constraint vector. config->monotone_constraints
// is indexed by REAL feature index (see FeatureHistogram feature-meta init), so map
// each inner feature through RealFeatureIndex.
use_monotone_constraints_ = !config->monotone_constraints.empty();
monotone_constraints_.resize(num_features_, 0);
if (use_monotone_constraints_) {
for (int inner_feature_index = 0; inner_feature_index < num_features_; ++inner_feature_index) {
const int real_feature_index = train_data->RealFeatureIndex(inner_feature_index);
monotone_constraints_[inner_feature_index] =
config->monotone_constraints[real_feature_index];
}
}
}

CUDABestSplitFinder::~CUDABestSplitFinder() {
Expand Down Expand Up @@ -147,6 +159,8 @@ void CUDABestSplitFinder::InitCUDAFeatureMetaInfo() {
new_task->mfb_offset = feature_mfb_offsets_[inner_feature_index];
new_task->default_bin = feature_default_bins_[inner_feature_index];
new_task->num_bin = num_bin;
new_task->monotone_type = use_monotone_constraints_ ?
monotone_constraints_[inner_feature_index] : 0;
++cur_task_index;

new_task = &split_find_tasks_[cur_task_index];
Expand All @@ -162,6 +176,8 @@ void CUDABestSplitFinder::InitCUDAFeatureMetaInfo() {
new_task->default_bin = feature_default_bins_[inner_feature_index];
new_task->mfb_offset = feature_mfb_offsets_[inner_feature_index];
new_task->num_bin = num_bin;
new_task->monotone_type = use_monotone_constraints_ ?
monotone_constraints_[inner_feature_index] : 0;
++cur_task_index;
} else {
SplitFindTask* new_task = &split_find_tasks_[cur_task_index];
Expand All @@ -177,6 +193,8 @@ void CUDABestSplitFinder::InitCUDAFeatureMetaInfo() {
new_task->mfb_offset = feature_mfb_offsets_[inner_feature_index];
new_task->default_bin = feature_default_bins_[inner_feature_index];
new_task->num_bin = num_bin;
new_task->monotone_type = use_monotone_constraints_ ?
monotone_constraints_[inner_feature_index] : 0;
++cur_task_index;

new_task = &split_find_tasks_[cur_task_index];
Expand All @@ -192,6 +210,8 @@ void CUDABestSplitFinder::InitCUDAFeatureMetaInfo() {
new_task->mfb_offset = feature_mfb_offsets_[inner_feature_index];
new_task->default_bin = feature_default_bins_[inner_feature_index];
new_task->num_bin = num_bin;
new_task->monotone_type = use_monotone_constraints_ ?
monotone_constraints_[inner_feature_index] : 0;
++cur_task_index;
}
} else {
Expand All @@ -218,6 +238,10 @@ void CUDABestSplitFinder::InitCUDAFeatureMetaInfo() {
new_task.mfb_offset = feature_mfb_offsets_[inner_feature_index];
new_task.default_bin = feature_default_bins_[inner_feature_index];
new_task.num_bin = num_bin;
// categorical features carry no monotone semantics (matching the CPU path,
// where monotone constraints only affect numerical splits)
new_task.monotone_type = (use_monotone_constraints_ && !new_task.is_categorical) ?
monotone_constraints_[inner_feature_index] : 0;
++cur_task_index;
}
}
Expand Down Expand Up @@ -346,6 +370,10 @@ void CUDABestSplitFinder::FindBestSplitsForLeaf(
const uint8_t larger_num_bits_in_histogram_bins,
const bool smaller_leaf_below_max_depth,
const bool larger_leaf_below_max_depth,
const double smaller_leaf_constraint_min,
const double smaller_leaf_constraint_max,
const double larger_leaf_constraint_min,
const double larger_leaf_constraint_max,
const bool synchronize) {
const bool is_smaller_leaf_valid = (num_data_in_smaller_leaf > min_data_in_leaf_ &&
sum_hessians_in_smaller_leaf > min_sum_hessian_in_leaf_ &&
Expand All @@ -359,7 +387,8 @@ void CUDABestSplitFinder::FindBestSplitsForLeaf(
grad_scale, hess_scale, smaller_num_bits_in_histogram_bins, larger_num_bits_in_histogram_bins, num_data_in_smaller_leaf, num_data_in_larger_leaf);
} else {
LaunchFindBestSplitsForLeafKernel(smaller_leaf_splits, larger_leaf_splits,
smaller_leaf_index, larger_leaf_index, is_smaller_leaf_valid, is_larger_leaf_valid, num_data_in_smaller_leaf, num_data_in_larger_leaf);
smaller_leaf_index, larger_leaf_index, is_smaller_leaf_valid, is_larger_leaf_valid, num_data_in_smaller_leaf, num_data_in_larger_leaf,
smaller_leaf_constraint_min, smaller_leaf_constraint_max, larger_leaf_constraint_min, larger_leaf_constraint_max);
}
global_timer.Start("CUDABestSplitFinder::LaunchSyncBestSplitForLeafKernel");
LaunchSyncBestSplitForLeafKernel(smaller_leaf_index, larger_leaf_index, is_smaller_leaf_valid, is_larger_leaf_valid);
Expand Down
Loading
Loading