forked from microsoft/LightGBM
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CUDA] Add rmse metric for new CUDA version (microsoft#5611)
* add rmse metric for new cuda version * add Init for CUDAMetricInterface * fix lint errors
- Loading branch information
Showing
17 changed files
with
230 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/*! | ||
* Copyright (c) 2021 Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE file in the project root for | ||
* license information. | ||
*/ | ||
|
||
#ifndef LIGHTGBM_CUDA_CUDA_METRIC_HPP_ | ||
#define LIGHTGBM_CUDA_CUDA_METRIC_HPP_ | ||
|
||
#ifdef USE_CUDA_EXP | ||
|
||
#include <LightGBM/metric.h> | ||
|
||
namespace LightGBM { | ||
|
||
template <typename HOST_METRIC> | ||
class CUDAMetricInterface: public HOST_METRIC { | ||
public: | ||
explicit CUDAMetricInterface(const Config& config): HOST_METRIC(config) { | ||
cuda_labels_ = nullptr; | ||
cuda_weights_ = nullptr; | ||
} | ||
|
||
void Init(const Metadata& metadata, data_size_t num_data) override { | ||
HOST_METRIC::Init(metadata, num_data); | ||
cuda_labels_ = metadata.cuda_metadata()->cuda_label(); | ||
cuda_weights_ = metadata.cuda_metadata()->cuda_weights(); | ||
} | ||
|
||
bool IsCUDAMetric() const { return true; } | ||
|
||
protected: | ||
const label_t* cuda_labels_; | ||
const label_t* cuda_weights_; | ||
}; | ||
|
||
} // namespace LightGBM | ||
|
||
#endif // USE_CUDA_EXP | ||
|
||
#endif // LIGHTGBM_CUDA_CUDA_METRIC_HPP_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/*! | ||
* Copyright (c) 2022 Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE file in the project root for | ||
* license information. | ||
*/ | ||
|
||
#ifdef USE_CUDA_EXP | ||
|
||
#include <vector> | ||
|
||
#include "cuda_regression_metric.hpp" | ||
|
||
namespace LightGBM { | ||
|
||
template <typename HOST_METRIC, typename CUDA_METRIC> | ||
void CUDARegressionMetricInterface<HOST_METRIC, CUDA_METRIC>::Init(const Metadata& metadata, data_size_t num_data) { | ||
CUDAMetricInterface<HOST_METRIC>::Init(metadata, num_data); | ||
const int max_num_reduce_blocks = (this->num_data_ + NUM_DATA_PER_EVAL_THREAD - 1) / NUM_DATA_PER_EVAL_THREAD; | ||
if (this->cuda_weights_ == nullptr) { | ||
reduce_block_buffer_.Resize(max_num_reduce_blocks); | ||
} else { | ||
reduce_block_buffer_.Resize(max_num_reduce_blocks * 2); | ||
} | ||
const int max_num_reduce_blocks_inner = (max_num_reduce_blocks + NUM_DATA_PER_EVAL_THREAD - 1) / NUM_DATA_PER_EVAL_THREAD; | ||
if (this->cuda_weights_ == nullptr) { | ||
reduce_block_buffer_inner_.Resize(max_num_reduce_blocks_inner); | ||
} else { | ||
reduce_block_buffer_inner_.Resize(max_num_reduce_blocks_inner * 2); | ||
} | ||
} | ||
|
||
template <typename HOST_METRIC, typename CUDA_METRIC> | ||
std::vector<double> CUDARegressionMetricInterface<HOST_METRIC, CUDA_METRIC>::Eval(const double* score, const ObjectiveFunction* objective) const { | ||
const double* score_convert = objective->ConvertOutputCUDA(this->num_data_, score, score_convert_buffer_.RawData()); | ||
const double eval_score = LaunchEvalKernel(score_convert); | ||
return std::vector<double>{eval_score}; | ||
} | ||
|
||
CUDARMSEMetric::CUDARMSEMetric(const Config& config): CUDARegressionMetricInterface<RMSEMetric, CUDARMSEMetric>(config) {} | ||
|
||
} // namespace LightGBM | ||
|
||
#endif // USE_CUDA_EXP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/*! | ||
* Copyright (c) 2022 Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE file in the project root for | ||
* license information. | ||
*/ | ||
|
||
#ifdef USE_CUDA_EXP | ||
|
||
#include <LightGBM/cuda/cuda_algorithms.hpp> | ||
|
||
#include "cuda_regression_metric.hpp" | ||
|
||
namespace LightGBM { | ||
|
||
template <typename CUDA_METRIC, bool USE_WEIGHTS> | ||
__global__ void EvalKernel(const data_size_t num_data, const label_t* labels, const label_t* weights, | ||
const double* scores, double* reduce_block_buffer) { | ||
__shared__ double shared_mem_buffer[32]; | ||
const data_size_t index = static_cast<data_size_t>(threadIdx.x + blockIdx.x * blockDim.x); | ||
double point_metric = 0.0; | ||
if (index < num_data) { | ||
point_metric = CUDA_METRIC::MetricOnPointCUDA(labels[index], scores[index]); | ||
} | ||
const double block_sum_point_metric = ShuffleReduceSum<double>(point_metric, shared_mem_buffer, NUM_DATA_PER_EVAL_THREAD); | ||
reduce_block_buffer[blockIdx.x] = block_sum_point_metric; | ||
if (USE_WEIGHTS) { | ||
double weight = 0.0; | ||
if (index < num_data) { | ||
weight = static_cast<double>(weights[index]); | ||
const double block_sum_weight = ShuffleReduceSum<double>(weight, shared_mem_buffer, NUM_DATA_PER_EVAL_THREAD); | ||
reduce_block_buffer[blockIdx.x + blockDim.x] = block_sum_weight; | ||
} | ||
} | ||
} | ||
|
||
template <typename HOST_METRIC, typename CUDA_METRIC> | ||
double CUDARegressionMetricInterface<HOST_METRIC, CUDA_METRIC>::LaunchEvalKernel(const double* score) const { | ||
const int num_blocks = (this->num_data_ + NUM_DATA_PER_EVAL_THREAD - 1) / NUM_DATA_PER_EVAL_THREAD; | ||
if (this->cuda_weights_ != nullptr) { | ||
EvalKernel<CUDA_METRIC, true><<<num_blocks, NUM_DATA_PER_EVAL_THREAD>>>( | ||
this->num_data_, this->cuda_labels_, this->cuda_weights_, score, reduce_block_buffer_.RawData()); | ||
} else { | ||
EvalKernel<CUDA_METRIC, false><<<num_blocks, NUM_DATA_PER_EVAL_THREAD>>>( | ||
this->num_data_, this->cuda_labels_, this->cuda_weights_, score, reduce_block_buffer_.RawData()); | ||
} | ||
ShuffleReduceSumGlobal<double, double>(reduce_block_buffer_.RawData(), num_blocks, reduce_block_buffer_inner_.RawData()); | ||
double sum_loss = 0.0; | ||
CopyFromCUDADeviceToHost<double>(&sum_loss, reduce_block_buffer_inner_.RawData(), 1, __FILE__, __LINE__); | ||
double sum_weight = static_cast<double>(this->num_data_); | ||
if (this->cuda_weights_ != nullptr) { | ||
ShuffleReduceSumGlobal<double, double>(reduce_block_buffer_.RawData() + num_blocks, num_blocks, reduce_block_buffer_inner_.RawData()); | ||
CopyFromCUDADeviceToHost<double>(&sum_weight, reduce_block_buffer_inner_.RawData(), 1, __FILE__, __LINE__); | ||
} | ||
return this->AverageLoss(sum_loss, sum_weight); | ||
} | ||
|
||
template double CUDARegressionMetricInterface<RMSEMetric, CUDARMSEMetric>::LaunchEvalKernel(const double* score) const; | ||
|
||
} // namespace LightGBM | ||
|
||
#endif // USE_CUDA_EXP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/*! | ||
* Copyright (c) 2022 Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See LICENSE file in the project root for | ||
* license information. | ||
*/ | ||
|
||
#ifndef LIGHTGBM_METRIC_CUDA_CUDA_REGRESSION_METRIC_HPP_ | ||
#define LIGHTGBM_METRIC_CUDA_CUDA_REGRESSION_METRIC_HPP_ | ||
|
||
#ifdef USE_CUDA_EXP | ||
|
||
#include <LightGBM/cuda/cuda_metric.hpp> | ||
#include <LightGBM/cuda/cuda_utils.h> | ||
|
||
#include <vector> | ||
|
||
#include "../regression_metric.hpp" | ||
|
||
#define NUM_DATA_PER_EVAL_THREAD (1024) | ||
|
||
namespace LightGBM { | ||
|
||
template <typename HOST_METRIC, typename CUDA_METRIC> | ||
class CUDARegressionMetricInterface: public CUDAMetricInterface<HOST_METRIC> { | ||
public: | ||
explicit CUDARegressionMetricInterface(const Config& config): CUDAMetricInterface<HOST_METRIC>(config) {} | ||
|
||
virtual ~CUDARegressionMetricInterface() {} | ||
|
||
void Init(const Metadata& metadata, data_size_t num_data) override; | ||
|
||
std::vector<double> Eval(const double* score, const ObjectiveFunction* objective) const override; | ||
|
||
protected: | ||
double LaunchEvalKernel(const double* score_convert) const; | ||
|
||
CUDAVector<double> score_convert_buffer_; | ||
CUDAVector<double> reduce_block_buffer_; | ||
CUDAVector<double> reduce_block_buffer_inner_; | ||
}; | ||
|
||
class CUDARMSEMetric: public CUDARegressionMetricInterface<RMSEMetric, CUDARMSEMetric> { | ||
public: | ||
explicit CUDARMSEMetric(const Config& config); | ||
|
||
virtual ~CUDARMSEMetric() {} | ||
|
||
__device__ static double MetricOnPointCUDA(label_t label, double score) { | ||
return (score - static_cast<double>(label)); | ||
} | ||
}; | ||
|
||
} // namespace LightGBM | ||
|
||
#endif // USE_CUDA_EXP | ||
|
||
#endif // LIGHTGBM_METRIC_CUDA_CUDA_REGRESSION_METRIC_HPP_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters