/*! * Copyright 2017-2023 by Contributors * \file hist_util.h */ #ifndef PLUGIN_SYCL_COMMON_HIST_UTIL_H_ #define PLUGIN_SYCL_COMMON_HIST_UTIL_H_ #include #include #include #include "../data.h" #include "row_set.h" #include "../../src/common/hist_util.h" #include "../data/gradient_index.h" #include namespace xgboost { namespace sycl { namespace common { template using GHistRow = USMVector, memory_type>; using BinTypeSize = ::xgboost::common::BinTypeSize; class ColumnMatrix; /*! * \brief Fill histogram with zeroes */ template void InitHist(::sycl::queue qu, GHistRow* hist, size_t size, ::sycl::event* event); /*! * \brief Copy histogram from src to dst */ template void CopyHist(::sycl::queue qu, GHistRow* dst, const GHistRow& src, size_t size); /*! * \brief Compute subtraction: dst = src1 - src2 */ template ::sycl::event SubtractionHist(::sycl::queue qu, GHistRow* dst, const GHistRow& src1, const GHistRow& src2, size_t size, ::sycl::event event_priv); /*! * \brief Histograms of gradient statistics for multiple nodes */ template class HistCollection { public: using GHistRowT = GHistRow; // Access histogram for i-th node GHistRowT& operator[](bst_uint nid) { return *(data_.at(nid)); } const GHistRowT& operator[](bst_uint nid) const { return *(data_.at(nid)); } // Initialize histogram collection void Init(::sycl::queue qu, uint32_t nbins) { qu_ = qu; if (nbins_ != nbins) { nbins_ = nbins; data_.clear(); } } // Create an empty histogram for i-th node ::sycl::event AddHistRow(bst_uint nid) { ::sycl::event event; if (data_.count(nid) == 0) { data_[nid] = std::make_shared(&qu_, nbins_, xgboost::detail::GradientPairInternal(0, 0), &event); } else { data_[nid]->Resize(&qu_, nbins_, xgboost::detail::GradientPairInternal(0, 0), &event); } return event; } private: /*! \brief Number of all bins over all features */ uint32_t nbins_ = 0; std::unordered_map> data_; ::sycl::queue qu_; }; /*! * \brief Stores temporary histograms to compute them in parallel */ template class ParallelGHistBuilder { public: using GHistRowT = GHistRow; void Init(::sycl::queue qu, size_t nbins) { qu_ = qu; if (nbins != nbins_) { hist_buffer_.Init(qu_, nbins); nbins_ = nbins; } } void Reset(size_t nblocks) { hist_device_buffer_.Resize(&qu_, nblocks * nbins_ * 2); } GHistRowT& GetDeviceBuffer() { return hist_device_buffer_; } protected: /*! \brief Number of bins in each histogram */ size_t nbins_ = 0; /*! \brief Buffers for histograms for all nodes processed */ HistCollection hist_buffer_; /*! \brief Buffer for additional histograms for Parallel processing */ GHistRowT hist_device_buffer_; ::sycl::queue qu_; }; /*! * \brief Builder for histograms of gradient statistics */ template class GHistBuilder { public: template using GHistRowT = GHistRow; GHistBuilder() = default; GHistBuilder(::sycl::queue qu, uint32_t nbins) : qu_{qu}, nbins_{nbins} {} // Construct a histogram via histogram aggregation ::sycl::event BuildHist(const USMVector& gpair_device, const RowSetCollection::Elem& row_indices, const GHistIndexMatrix& gmat, GHistRowT* HistCollection, bool isDense, GHistRowT* hist_buffer, ::sycl::event event, bool force_atomic_use = false); // Construct a histogram via subtraction trick void SubtractionTrick(GHistRowT* self, const GHistRowT& sibling, const GHistRowT& parent); uint32_t GetNumBins() const { return nbins_; } private: /*! \brief Number of all bins over all features */ uint32_t nbins_ { 0 }; ::sycl::queue qu_; }; } // namespace common } // namespace sycl } // namespace xgboost #endif // PLUGIN_SYCL_COMMON_HIST_UTIL_H_