14 #ifndef XGBOOST_COMMON_GROUP_DATA_H_
15 #define XGBOOST_COMMON_GROUP_DATA_H_
32 template<
typename ValueType,
typename SizeType = bst_u
long,
bool is_row_major = false>
46 std::vector<ValueType> *p_data,
47 size_t base_row_offset = 0)
50 base_row_offset_(base_row_offset) {}
60 thread_rptr_.resize(nthread);
61 const size_t full_size = is_row_major ? max_key : max_key - std::min(base_row_offset_, max_key);
62 thread_displacement_ = is_row_major ? full_size / nthread : 0;
63 for (std::size_t i = 0; i < thread_rptr_.size() - 1; ++i) {
64 const size_t thread_size = is_row_major ? thread_displacement_ : full_size;
65 thread_rptr_[i].resize(thread_size, 0);
67 const size_t last_thread_size = is_row_major ? (full_size - (nthread - 1)*thread_displacement_)
69 thread_rptr_[nthread - 1].resize(last_thread_size, 0);
78 void AddBudget(std::size_t key,
int threadid, SizeType nelem = 1) {
79 std::vector<SizeType> &trptr = thread_rptr_[threadid];
80 size_t offset_key = is_row_major ? (key - base_row_offset_ - threadid*thread_displacement_)
81 : (key - base_row_offset_);
82 if (trptr.size() < offset_key + 1) {
83 trptr.resize(offset_key + 1, 0);
85 trptr[offset_key] += nelem;
91 size_t expected_rows = 0;
92 for (std::size_t tid = 0; tid < thread_rptr_.size(); ++tid) {
93 expected_rows += thread_rptr_[tid].size();
96 SizeType rptr_fill_value = rptr_.empty() ? 0 : rptr_.back();
97 rptr_.resize(expected_rows + base_row_offset_ + 1, rptr_fill_value);
99 std::size_t count = 0;
100 size_t offset_idx = base_row_offset_ + 1;
101 for (std::size_t tid = 0; tid < thread_rptr_.size(); ++tid) {
102 std::vector<SizeType> &trptr = thread_rptr_[tid];
103 for (std::size_t i = 0; i < trptr.size(); ++i) {
104 std::size_t thread_count = trptr[i];
105 trptr[i] = count + rptr_fill_value;
106 count += thread_count;
107 if (offset_idx < rptr_.size()) {
108 rptr_[offset_idx++] += count;
112 data_.resize(rptr_.back());
115 SizeType rptr_fill_value = rptr_.empty() ? 0 : rptr_.back();
116 for (std::size_t tid = 0; tid < thread_rptr_.size(); ++tid) {
117 if (rptr_.size() <= thread_rptr_[tid].size() + base_row_offset_) {
118 rptr_.resize(thread_rptr_[tid].size() + base_row_offset_ + 1,
123 std::size_t count = 0;
124 for (std::size_t i = base_row_offset_; i + 1 < rptr_.size(); ++i) {
125 for (std::size_t tid = 0; tid < thread_rptr_.size(); ++tid) {
126 std::vector<SizeType> &trptr = thread_rptr_[tid];
127 if (i < trptr.size() +
129 std::size_t thread_count =
130 trptr[i - base_row_offset_];
131 trptr[i - base_row_offset_] = count + rptr_.back();
132 count += thread_count;
135 rptr_[i + 1] += count;
137 data_.resize(rptr_.back());
149 void Push(std::size_t key, ValueType&& value,
int threadid) {
150 size_t offset_key = is_row_major ? (key - base_row_offset_ - threadid * thread_displacement_)
151 : (key - base_row_offset_);
152 SizeType &rp = thread_rptr_[threadid][offset_key];
153 data_[rp++] = std::move(value);
158 std::vector<SizeType> &rptr_;
160 std::vector<ValueType> &data_;
162 std::vector<std::vector<SizeType> > thread_rptr_;
164 size_t base_row_offset_;
166 size_t thread_displacement_;
170 #endif // XGBOOST_COMMON_GROUP_DATA_H_