OmniSciDB  95562058bd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ResultSetStorage Class Reference

#include <ResultSet.h>

+ Collaboration diagram for ResultSetStorage:

Public Member Functions

 ResultSetStorage (const std::vector< TargetInfo > &targets, const QueryMemoryDescriptor &query_mem_desc, int8_t *buff, const bool buff_is_provided)
 
void reduce (const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code) const
 
void rewriteAggregateBufferOffsets (const std::vector< std::string > &serialized_varlen_buffer) const
 
int8_t * getUnderlyingBuffer () const
 
size_t getEntryCount () const
 
template<class KeyType >
void moveEntriesToBuffer (int8_t *new_buff, const size_t new_entry_count) const
 
template<class KeyType >
void moveOneEntryToBuffer (const size_t entry_index, int64_t *new_buff_i64, const size_t new_entry_count, const size_t key_count, const size_t row_qw_count, const int64_t *src_buff, const size_t key_byte_width) const
 
void updateEntryCount (const size_t new_entry_count)
 

Static Public Member Functions

static bool reduceSingleRow (const int8_t *row_ptr, const int8_t warp_count, const bool is_columnar, const bool replace_bitmap_ptr_with_bitmap_sz, std::vector< int64_t > &agg_vals, const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &agg_init_vals)
 

Private Member Functions

void reduceEntriesNoCollisionsColWise (int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const size_t start_index, const size_t end_index, const std::vector< std::string > &serialized_varlen_buffer) const
 
void copyKeyColWise (const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
 
bool isEmptyEntry (const size_t entry_idx, const int8_t *buff) const
 
bool isEmptyEntry (const size_t entry_idx) const
 
bool isEmptyEntryColumnar (const size_t entry_idx, const int8_t *buff) const
 
void reduceOneEntryBaseline (int8_t *this_buff, const int8_t *that_buff, const size_t i, const size_t that_entry_count, const ResultSetStorage &that) const
 
void reduceOneEntrySlotsBaseline (int64_t *this_entry_slots, const int64_t *that_buff, const size_t that_entry_idx, const size_t that_entry_count, const ResultSetStorage &that) const
 
void initializeBaselineValueSlots (int64_t *this_entry_slots) const
 
void reduceOneSlotBaseline (int64_t *this_buff, const size_t this_slot, const int64_t *that_buff, const size_t that_entry_count, const size_t that_slot, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that) const
 
ALWAYS_INLINE void reduceOneSlotSingleValue (int8_t *this_ptr1, const TargetInfo &target_info, const size_t target_slot_idx, const size_t init_agg_val_idx, const int8_t *that_ptr1) const
 
ALWAYS_INLINE void reduceOneSlot (int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
 
void reduceOneCountDistinctSlot (int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
 
void fillOneEntryRowWise (const std::vector< int64_t > &entry)
 
void fillOneEntryColWise (const std::vector< int64_t > &entry)
 
void initializeRowWise () const
 
void initializeColWise () const
 
void addCountDistinctSetPointerMapping (const int64_t remote_ptr, const int64_t ptr)
 
int64_t mappedPtr (const int64_t) const
 
size_t binSearchRowCount () const
 

Private Attributes

const std::vector< TargetInfotargets_
 
QueryMemoryDescriptor query_mem_desc_
 
int8_t * buff_
 
const bool buff_is_provided_
 
std::vector< int64_t > target_init_vals_
 
std::unordered_map< int64_t,
int64_t > 
count_distinct_sets_mapping_
 

Friends

class ResultSet
 
class ResultSetManager
 

Detailed Description

Definition at line 80 of file ResultSet.h.

Constructor & Destructor Documentation

ResultSetStorage::ResultSetStorage ( const std::vector< TargetInfo > &  targets,
const QueryMemoryDescriptor query_mem_desc,
int8_t *  buff,
const bool  buff_is_provided 
)

Definition at line 80 of file ResultSet.cpp.

84  : targets_(targets)
85  , query_mem_desc_(query_mem_desc)
86  , buff_(buff)
87  , buff_is_provided_(buff_is_provided)
std::vector< int64_t > initialize_target_values_for_storage(const std::vector< TargetInfo > &targets)
Definition: ResultSet.cpp:47
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:207
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
const bool buff_is_provided_
Definition: ResultSet.h:210
int8_t * buff_
Definition: ResultSet.h:209
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

Member Function Documentation

void ResultSetStorage::addCountDistinctSetPointerMapping ( const int64_t  remote_ptr,
const int64_t  ptr 
)
private

Definition at line 975 of file ResultSet.cpp.

References CHECK, and count_distinct_sets_mapping_.

976  {
977  const auto it_ok = count_distinct_sets_mapping_.emplace(remote_ptr, ptr);
978  CHECK(it_ok.second);
979 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:217
#define CHECK(condition)
Definition: Logger.h:197
size_t ResultSetStorage::binSearchRowCount ( ) const
private

Definition at line 2201 of file ResultSetIteration.cpp.

References CHECK, CHECK_EQ, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_64, QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getQueryDescriptionType(), anonymous_namespace{ResultSetIteration.cpp}::make_bin_search(), Projection, ResultSet::query_mem_desc_, and row_ptr_rowwise().

2201  {
2204 
2205  if (!query_mem_desc_.getEntryCount()) {
2206  return 0;
2207  }
2208 
2210  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2211  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2212  });
2213  } else {
2214  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2215  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2216  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2217  });
2218  }
2219 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
#define EMPTY_KEY_64
size_t make_bin_search(size_t l, size_t r, T &&is_empty_fn)
size_t getEffectiveKeyWidth() const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
QueryDescriptionType getQueryDescriptionType() const
int8_t * buff_
Definition: ResultSet.h:209
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::copyKeyColWise ( const size_t  entry_idx,
int8_t *  this_buff,
const int8_t *  that_buff 
) const
private

Definition at line 479 of file ResultSetReduction.cpp.

References CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getPrependedGroupColOffInBytes(), QueryMemoryDescriptor::groupColWidth(), and query_mem_desc_.

Referenced by reduceEntriesNoCollisionsColWise().

481  {
483  for (size_t group_idx = 0; group_idx < query_mem_desc_.getGroupbyColCount();
484  group_idx++) {
485  // if the column corresponds to a group key
486  const auto column_offset_bytes =
488  auto lhs_key_ptr = this_buff + column_offset_bytes;
489  auto rhs_key_ptr = that_buff + column_offset_bytes;
490  switch (query_mem_desc_.groupColWidth(group_idx)) {
491  case 8:
492  *(reinterpret_cast<int64_t*>(lhs_key_ptr) + entry_idx) =
493  *(reinterpret_cast<const int64_t*>(rhs_key_ptr) + entry_idx);
494  break;
495  case 4:
496  *(reinterpret_cast<int32_t*>(lhs_key_ptr) + entry_idx) =
497  *(reinterpret_cast<const int32_t*>(rhs_key_ptr) + entry_idx);
498  break;
499  case 2:
500  *(reinterpret_cast<int16_t*>(lhs_key_ptr) + entry_idx) =
501  *(reinterpret_cast<const int16_t*>(rhs_key_ptr) + entry_idx);
502  break;
503  case 1:
504  *(reinterpret_cast<int8_t*>(lhs_key_ptr) + entry_idx) =
505  *(reinterpret_cast<const int8_t*>(rhs_key_ptr) + entry_idx);
506  break;
507  default:
508  CHECK(false);
509  break;
510  }
511  }
512 }
int8_t groupColWidth(const size_t key_idx) const
size_t getGroupbyColCount() const
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::fillOneEntryColWise ( const std::vector< int64_t > &  entry)
private

Definition at line 1144 of file ResultSetReduction.cpp.

References buff_, CHECK, CHECK_EQ, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getBufferColSlotCount(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), key_offset_colwise(), query_mem_desc_, slot_offset_colwise(), and target_init_vals_.

1144  {
1146  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1147  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1148  const auto key_count = query_mem_desc_.getGroupbyColCount();
1149  CHECK_EQ(slot_count + key_count, entry.size());
1150  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1151 
1152  for (size_t i = 0; i < key_count; i++) {
1153  const auto key_offset = key_offset_colwise(0, i, 1);
1154  this_buff[key_offset] = entry[i];
1155  }
1156 
1157  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1158  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1159  this_buff[slot_offset] = entry[key_count + i];
1160  }
1161 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
size_t getGroupbyColCount() const
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
int8_t * buff_
Definition: ResultSet.h:209
#define CHECK(condition)
Definition: Logger.h:197
size_t getBufferColSlotCount() const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::fillOneEntryRowWise ( const std::vector< int64_t > &  entry)
private

Definition at line 1091 of file ResultSetReduction.cpp.

References buff_, CHECK, CHECK_EQ, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getBufferColSlotCount(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), key_offset_rowwise(), query_mem_desc_, slot_offset_rowwise(), and target_init_vals_.

1091  {
1092  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1093  const auto key_count = query_mem_desc_.getGroupbyColCount();
1094  CHECK_EQ(slot_count + key_count, entry.size());
1095  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1097  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1098  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1099  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1100  for (size_t i = 0; i < key_count; ++i) {
1101  this_buff[key_off + i] = entry[i];
1102  }
1103  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1104  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1105  this_buff[first_slot_off + i] = entry[key_count + i];
1106  }
1107 }
size_t slot_offset_rowwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t slot_count)
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
size_t getEffectiveKeyWidth() const
size_t getGroupbyColCount() const
int8_t * buff_
Definition: ResultSet.h:209
size_t key_offset_rowwise(const size_t entry_idx, const size_t key_count, const size_t slot_count)
#define CHECK(condition)
Definition: Logger.h:197
size_t getBufferColSlotCount() const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

size_t ResultSetStorage::getEntryCount ( ) const
inline

Definition at line 96 of file ResultSet.h.

References QueryMemoryDescriptor::getEntryCount(), and query_mem_desc_.

96 { return query_mem_desc_.getEntryCount(); }
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

int8_t * ResultSetStorage::getUnderlyingBuffer ( ) const

Definition at line 90 of file ResultSet.cpp.

References buff_.

Referenced by anonymous_namespace{Execute.cpp}::permute_storage_columnar(), and anonymous_namespace{Execute.cpp}::permute_storage_row_wise().

90  {
91  return buff_;
92 }
int8_t * buff_
Definition: ResultSet.h:209

+ Here is the caller graph for this function:

void ResultSetStorage::initializeBaselineValueSlots ( int64_t *  this_entry_slots) const
private

Definition at line 1183 of file ResultSetReduction.cpp.

References CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), query_mem_desc_, and target_init_vals_.

1183  {
1184  CHECK(entry_slots);
1186  size_t slot_off = 0;
1187  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1188  entry_slots[slot_off] = target_init_vals_[j];
1189  slot_off += query_mem_desc_.getEntryCount();
1190  }
1191  } else {
1192  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1193  entry_slots[j] = target_init_vals_[j];
1194  }
1195  }
1196 }
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

Definition at line 1163 of file ResultSetReduction.cpp.

References buff_, CHECK, EMPTY_KEY_64, QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::hasKeylessHash(), key_offset_colwise(), query_mem_desc_, slot_offset_colwise(), and target_init_vals_.

1163  {
1164  const auto key_count = query_mem_desc_.getGroupbyColCount();
1165  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1167  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1168  const auto first_key_off =
1170  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1171  this_buff[first_key_off + i] = EMPTY_KEY_64;
1172  }
1173  }
1174  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1175  const auto first_val_off =
1176  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1177  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1178  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1179  }
1180  }
1181 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
size_t getGroupbyColCount() const
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
int8_t * buff_
Definition: ResultSet.h:209
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

Definition at line 1109 of file ResultSetReduction.cpp.

References align_to_int64(), buff_, CHECK, CHECK_EQ, anonymous_namespace{ResultSetReduction.cpp}::fill_empty_key_32(), anonymous_namespace{ResultSetReduction.cpp}::fill_empty_key_64(), get_key_bytes_rowwise(), get_row_bytes(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::hasKeylessHash(), query_mem_desc_, and target_init_vals_.

1109  {
1110  const auto key_count = query_mem_desc_.getGroupbyColCount();
1111  const auto row_size = get_row_bytes(query_mem_desc_);
1112  CHECK_EQ(row_size % 8, 0u);
1113  const auto key_bytes_with_padding =
1117  case 4: {
1118  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1119  auto row_ptr = buff_ + i * row_size;
1120  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1121  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1122  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1123  slot_ptr[j] = target_init_vals_[j];
1124  }
1125  }
1126  break;
1127  }
1128  case 8: {
1129  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1130  auto row_ptr = buff_ + i * row_size;
1131  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1132  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1133  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1134  slot_ptr[j] = target_init_vals_[j];
1135  }
1136  }
1137  break;
1138  }
1139  default:
1140  CHECK(false);
1141  }
1142 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
size_t getEffectiveKeyWidth() const
ALWAYS_INLINE void fill_empty_key_32(int32_t *key_ptr_i32, const size_t key_count)
size_t getGroupbyColCount() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
int8_t * buff_
Definition: ResultSet.h:209
#define CHECK(condition)
Definition: Logger.h:197
ALWAYS_INLINE void fill_empty_key_64(int64_t *key_ptr_i64, const size_t key_count)
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

bool ResultSetStorage::isEmptyEntry ( const size_t  entry_idx,
const int8_t *  buff 
) const
private

Definition at line 2089 of file ResultSetIteration.cpp.

References CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_32, EMPTY_KEY_64, get_byteoff_of_slot(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), GroupByPerfectHash, QueryMemoryDescriptor::hasKeylessHash(), NonGroupedAggregate, ResultSet::query_mem_desc_, read_int_from_buff(), and row_ptr_rowwise().

Referenced by reduceOneEntryBaseline(), and rewriteAggregateBufferOffsets().

2089  {
2092  return false;
2093  }
2095  return isEmptyEntryColumnar(entry_idx, buff);
2096  }
2101  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2102  target_init_vals_.size());
2103  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2104  const auto target_slot_off =
2106  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2110  } else {
2111  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2113  case 4:
2116  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2117  case 8:
2118  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2119  default:
2120  CHECK(false);
2121  return true;
2122  }
2123  }
2124 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
#define CHECK_GE(x, y)
Definition: Logger.h:210
size_t getEffectiveKeyWidth() const
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:207
#define CHECK(condition)
Definition: Logger.h:197
#define EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208
int32_t getTargetIdxForKey() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool ResultSetStorage::isEmptyEntry ( const size_t  entry_idx) const
private

Definition at line 2221 of file ResultSetIteration.cpp.

2221  {
2222  return isEmptyEntry(entry_idx, buff_);
2223 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
int8_t * buff_
Definition: ResultSet.h:209
bool ResultSetStorage::isEmptyEntryColumnar ( const size_t  entry_idx,
const int8_t *  buff 
) const
private

Definition at line 2130 of file ResultSetIteration.cpp.

References anonymous_namespace{ResultSetIteration.cpp}::advance_col_buff_to_slot(), CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_16, EMPTY_KEY_32, EMPTY_KEY_64, EMPTY_KEY_8, QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getPrependedGroupColOffInBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), GroupByPerfectHash, QueryMemoryDescriptor::groupColWidth(), QueryMemoryDescriptor::hasKeylessHash(), NonGroupedAggregate, Projection, ResultSet::query_mem_desc_, read_int_from_buff(), and ResultSet::targets_.

Referenced by reduceEntriesNoCollisionsColWise().

2131  {
2135  return false;
2136  }
2141  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2142  target_init_vals_.size());
2143  const auto col_buff = advance_col_buff_to_slot(
2145  const auto entry_buff =
2146  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2148  return read_int_from_buff(entry_buff,
2152  } else {
2153  // it's enough to find the first group key which is empty
2155  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2156  } else {
2158  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2159  switch (query_mem_desc_.groupColWidth(0)) {
2160  case 8:
2161  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2162  case 4:
2163  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2164  case 2:
2165  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2166  case 1:
2167  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2168  default:
2169  CHECK(false);
2170  }
2171  }
2172  return false;
2173  }
2174  return false;
2175 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:207
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
#define CHECK_GE(x, y)
Definition: Logger.h:210
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
const int8_t * col_buff
const int8_t * advance_col_buff_to_slot(const int8_t *buff, const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const size_t slot_idx, const bool separate_varlen_storage)
int8_t groupColWidth(const size_t key_idx) const
size_t getGroupbyColCount() const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define EMPTY_KEY_8
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:207
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:197
#define EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208
int32_t getTargetIdxForKey() const
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int64_t ResultSetStorage::mappedPtr ( const int64_t  remote_ptr) const
private

Definition at line 981 of file ResultSet.cpp.

References count_distinct_sets_mapping_.

981  {
982  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
983  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
984  // remote ptr that do not not exists. Return 0 if no pointer found
985  if (it == count_distinct_sets_mapping_.end()) {
986  return int64_t(0);
987  }
988  return it->second;
989 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:217
template<class KeyType >
void ResultSetStorage::moveEntriesToBuffer ( int8_t *  new_buff,
const size_t  new_entry_count 
) const

Definition at line 889 of file ResultSetReduction.cpp.

References buff_, CHECK, CHECK_GT, cpu_threads(), anonymous_namespace{ResultSetReduction.cpp}::get_row_qw_count(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), query_mem_desc_, and anonymous_namespace{ResultSetReduction.cpp}::use_multithreaded_reduction().

890  {
892  CHECK_GT(new_entry_count, query_mem_desc_.getEntryCount());
893  auto new_buff_i64 = reinterpret_cast<int64_t*>(new_buff);
894  const auto key_count = query_mem_desc_.getGroupbyColCount();
897  const auto src_buff = reinterpret_cast<const int64_t*>(buff_);
898  const auto row_qw_count = get_row_qw_count(query_mem_desc_);
899  const auto key_byte_width = query_mem_desc_.getEffectiveKeyWidth();
900 
902  const size_t thread_count = cpu_threads();
903  std::vector<std::future<void>> move_threads;
904 
905  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
906  const auto thread_entry_count =
907  (query_mem_desc_.getEntryCount() + thread_count - 1) / thread_count;
908  const auto start_index = thread_idx * thread_entry_count;
909  const auto end_index =
910  std::min(start_index + thread_entry_count, query_mem_desc_.getEntryCount());
911  move_threads.emplace_back(std::async(
912  std::launch::async,
913  [this,
914  src_buff,
915  new_buff_i64,
916  new_entry_count,
917  start_index,
918  end_index,
919  key_count,
920  row_qw_count,
921  key_byte_width] {
922  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
923  moveOneEntryToBuffer<KeyType>(entry_idx,
924  new_buff_i64,
925  new_entry_count,
926  key_count,
927  row_qw_count,
928  src_buff,
929  key_byte_width);
930  }
931  }));
932  }
933  for (auto& move_thread : move_threads) {
934  move_thread.wait();
935  }
936  for (auto& move_thread : move_threads) {
937  move_thread.get();
938  }
939  } else {
940  for (size_t entry_idx = 0; entry_idx < query_mem_desc_.getEntryCount(); ++entry_idx) {
941  moveOneEntryToBuffer<KeyType>(entry_idx,
942  new_buff_i64,
943  new_entry_count,
944  key_count,
945  row_qw_count,
946  src_buff,
947  key_byte_width);
948  }
949  }
950 }
size_t getEffectiveKeyWidth() const
#define CHECK_GT(x, y)
Definition: Logger.h:209
size_t getGroupbyColCount() const
QueryDescriptionType getQueryDescriptionType() const
int8_t * buff_
Definition: ResultSet.h:209
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:197
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
int cpu_threads()
Definition: thread_count.h:24
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

template<class KeyType >
void ResultSetStorage::moveOneEntryToBuffer ( const size_t  entry_index,
int64_t *  new_buff_i64,
const size_t  new_entry_count,
const size_t  key_count,
const size_t  row_qw_count,
const int64_t *  src_buff,
const size_t  key_byte_width 
) const

Definition at line 953 of file ResultSetReduction.cpp.

References CHECK, QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::fill_slots(), get_group_value(), get_group_value_columnar(), QueryMemoryDescriptor::getEntryCount(), key_offset_colwise(), anonymous_namespace{ResultSetReduction.cpp}::make_key(), and query_mem_desc_.

959  {
960  const auto key_off =
963  : row_qw_count * entry_index;
964  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
965  if (*key_ptr == get_empty_key<KeyType>()) {
966  return;
967  }
968  int64_t* new_entries_ptr{nullptr};
970  const auto key =
971  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
972  new_entries_ptr =
973  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
974  } else {
975  new_entries_ptr = get_group_value(new_buff_i64,
976  new_entry_count,
977  &src_buff[key_off],
978  key_count,
979  key_byte_width,
980  row_qw_count,
981  nullptr);
982  }
983  CHECK(new_entries_ptr);
984  fill_slots(new_entries_ptr,
985  new_entry_count,
986  src_buff,
987  entry_index,
990 }
NEVER_INLINE DEVICE int64_t * get_group_value_columnar(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
void fill_slots(int64_t *dst_entry, const size_t dst_entry_count, const int64_t *src_buff, const size_t src_entry_idx, const size_t src_entry_count, const QueryMemoryDescriptor &query_mem_desc)
std::vector< int64_t > make_key(const int64_t *buff, const size_t entry_count, const size_t key_count)
NEVER_INLINE DEVICE int64_t * get_group_value(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_count, const uint32_t key_width, const uint32_t row_size_quad, const int64_t *init_vals)
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::reduce ( const ResultSetStorage that,
const std::vector< std::string > &  serialized_varlen_buffer,
const ReductionCode reduction_code 
) const

Definition at line 202 of file ResultSetReduction.cpp.

References buff_, CHECK, CHECK_EQ, CHECK_GE, CHECK_GT, cpu_threads(), QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, GroupByPerfectHash, ReductionCode::ir_reduce_loop, NonGroupedAggregate, query_mem_desc_, reduceOneEntryBaseline(), anonymous_namespace{ResultSetReduction.cpp}::run_reduction_code(), and anonymous_namespace{ResultSetReduction.cpp}::use_multithreaded_reduction().

Referenced by reduceOneSlotSingleValue().

204  {
205  auto entry_count = query_mem_desc_.getEntryCount();
206  CHECK_GT(entry_count, size_t(0));
214  }
215  const auto that_entry_count = that.query_mem_desc_.getEntryCount();
218  CHECK_GE(entry_count, that_entry_count);
219  break;
220  default:
221  CHECK_EQ(entry_count, that_entry_count);
222  }
223  auto this_buff = buff_;
224  CHECK(this_buff);
225  auto that_buff = that.buff_;
226  CHECK(that_buff);
229  if (!serialized_varlen_buffer.empty()) {
230  throw std::runtime_error(
231  "Projection of variable length targets with baseline hash group by is not yet "
232  "supported in Distributed mode");
233  }
234  if (use_multithreaded_reduction(that_entry_count)) {
235  const size_t thread_count = cpu_threads();
236  std::vector<std::future<void>> reduction_threads;
237  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
238  const auto thread_entry_count =
239  (that_entry_count + thread_count - 1) / thread_count;
240  const auto start_index = thread_idx * thread_entry_count;
241  const auto end_index =
242  std::min(start_index + thread_entry_count, that_entry_count);
243  reduction_threads.emplace_back(std::async(
244  std::launch::async,
245  [this,
246  this_buff,
247  that_buff,
248  start_index,
249  end_index,
250  that_entry_count,
251  &reduction_code,
252  &that] {
253  if (reduction_code.ir_reduce_loop) {
254  run_reduction_code(reduction_code,
255  this_buff,
256  that_buff,
257  start_index,
258  end_index,
259  that_entry_count,
261  &that.query_mem_desc_,
262  nullptr);
263  } else {
264  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
266  this_buff, that_buff, entry_idx, that_entry_count, that);
267  }
268  }
269  }));
270  }
271  for (auto& reduction_thread : reduction_threads) {
272  reduction_thread.wait();
273  }
274  for (auto& reduction_thread : reduction_threads) {
275  reduction_thread.get();
276  }
277  } else {
278  if (reduction_code.ir_reduce_loop) {
279  run_reduction_code(reduction_code,
280  this_buff,
281  that_buff,
282  0,
283  that_entry_count,
284  that_entry_count,
286  &that.query_mem_desc_,
287  nullptr);
288  } else {
289  for (size_t i = 0; i < that_entry_count; ++i) {
290  reduceOneEntryBaseline(this_buff, that_buff, i, that_entry_count, that);
291  }
292  }
293  }
294  return;
295  }
296  if (use_multithreaded_reduction(entry_count)) {
297  const size_t thread_count = cpu_threads();
298  std::vector<std::future<void>> reduction_threads;
299  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
300  const auto thread_entry_count = (entry_count + thread_count - 1) / thread_count;
301  const auto start_index = thread_idx * thread_entry_count;
302  const auto end_index = std::min(start_index + thread_entry_count, entry_count);
304  reduction_threads.emplace_back(std::async(std::launch::async,
305  [this,
306  this_buff,
307  that_buff,
308  start_index,
309  end_index,
310  &that,
311  &serialized_varlen_buffer] {
313  this_buff,
314  that_buff,
315  that,
316  start_index,
317  end_index,
318  serialized_varlen_buffer);
319  }));
320  } else {
321  reduction_threads.emplace_back(std::async(std::launch::async,
322  [this,
323  this_buff,
324  that_buff,
325  start_index,
326  end_index,
327  that_entry_count,
328  &reduction_code,
329  &that,
330  &serialized_varlen_buffer] {
331  CHECK(reduction_code.ir_reduce_loop);
333  reduction_code,
334  this_buff,
335  that_buff,
336  start_index,
337  end_index,
338  that_entry_count,
340  &that.query_mem_desc_,
341  &serialized_varlen_buffer);
342  }));
343  }
344  }
345  for (auto& reduction_thread : reduction_threads) {
346  reduction_thread.wait();
347  }
348  for (auto& reduction_thread : reduction_threads) {
349  reduction_thread.get();
350  }
351  } else {
354  that_buff,
355  that,
356  0,
358  serialized_varlen_buffer);
359  } else {
360  CHECK(reduction_code.ir_reduce_loop);
361  run_reduction_code(reduction_code,
362  this_buff,
363  that_buff,
364  0,
365  entry_count,
366  that_entry_count,
368  &that.query_mem_desc_,
369  &serialized_varlen_buffer);
370  }
371  }
372 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
void run_reduction_code(const ReductionCode &reduction_code, int8_t *this_buff, const int8_t *that_buff, const int32_t start_entry_index, const int32_t end_entry_index, const int32_t that_entry_count, const void *this_qmd, const void *that_qmd, const void *serialized_varlen_buffer)
void reduceEntriesNoCollisionsColWise(int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const size_t start_index, const size_t end_index, const std::vector< std::string > &serialized_varlen_buffer) const
void reduceOneEntryBaseline(int8_t *this_buff, const int8_t *that_buff, const size_t i, const size_t that_entry_count, const ResultSetStorage &that) const
std::unique_ptr< Function > ir_reduce_loop
#define CHECK_GE(x, y)
Definition: Logger.h:210
#define CHECK_GT(x, y)
Definition: Logger.h:209
QueryDescriptionType getQueryDescriptionType() const
int8_t * buff_
Definition: ResultSet.h:209
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:197
int cpu_threads()
Definition: thread_count.h:24
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceEntriesNoCollisionsColWise ( int8_t *  this_buff,
const int8_t *  that_buff,
const ResultSetStorage that,
const size_t  start_index,
const size_t  end_index,
const std::vector< std::string > &  serialized_varlen_buffer 
) const
private

Definition at line 388 of file ResultSetReduction.cpp.

References advance_to_next_columnar_target_buff(), CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog(), copyKeyColWise(), get_cols_ptr(), QueryMemoryDescriptor::getColSlotContext(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::hasKeylessHash(), isEmptyEntryColumnar(), kAVG, kSAMPLE, LIKELY, query_mem_desc_, reduceOneSlot(), targets_, and UNLIKELY.

394  {
395  // TODO(adb / saman): Support column wise output when serializing distributed agg
396  // functions
397  CHECK(serialized_varlen_buffer.empty());
398 
399  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
400 
401  auto this_crt_col_ptr = get_cols_ptr(this_buff, query_mem_desc_);
402  auto that_crt_col_ptr = get_cols_ptr(that_buff, query_mem_desc_);
403  for (size_t target_idx = 0; target_idx < targets_.size(); ++target_idx) {
404  const auto& agg_info = targets_[target_idx];
405  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_idx);
406 
407  bool two_slot_target{false};
408  if (agg_info.is_agg &&
409  (agg_info.agg_kind == kAVG ||
410  (agg_info.agg_kind == kSAMPLE && agg_info.sql_type.is_varlen()))) {
411  // Note that this assumes if one of the slot pairs in a given target is an array,
412  // all slot pairs are arrays. Currently this is true for all geo targets, but we
413  // should better codify and store this information in the future
414  two_slot_target = true;
415  }
416 
417  for (size_t target_slot_idx = slots_for_col.front();
418  target_slot_idx < slots_for_col.back() + 1;
419  target_slot_idx += 2) {
420  const auto this_next_col_ptr = advance_to_next_columnar_target_buff(
421  this_crt_col_ptr, query_mem_desc_, target_slot_idx);
422  const auto that_next_col_ptr = advance_to_next_columnar_target_buff(
423  that_crt_col_ptr, query_mem_desc_, target_slot_idx);
424 
425  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
426  check_watchdog(entry_idx);
427  if (isEmptyEntryColumnar(entry_idx, that_buff)) {
428  continue;
429  }
431  // copy the key from right hand side
432  copyKeyColWise(entry_idx, this_buff, that_buff);
433  }
434  auto this_ptr1 =
435  this_crt_col_ptr +
436  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
437  auto that_ptr1 =
438  that_crt_col_ptr +
439  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
440  int8_t* this_ptr2{nullptr};
441  const int8_t* that_ptr2{nullptr};
442  if (UNLIKELY(two_slot_target)) {
443  this_ptr2 =
444  this_next_col_ptr +
445  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
446  that_ptr2 =
447  that_next_col_ptr +
448  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
449  }
450  reduceOneSlot(this_ptr1,
451  this_ptr2,
452  that_ptr1,
453  that_ptr2,
454  agg_info,
455  target_idx,
456  target_slot_idx,
457  target_slot_idx,
458  that,
459  slots_for_col.front(),
460  serialized_varlen_buffer);
461  }
462 
463  this_crt_col_ptr = this_next_col_ptr;
464  that_crt_col_ptr = that_next_col_ptr;
465  if (UNLIKELY(two_slot_target)) {
466  this_crt_col_ptr = advance_to_next_columnar_target_buff(
467  this_crt_col_ptr, query_mem_desc_, target_slot_idx + 1);
468  that_crt_col_ptr = advance_to_next_columnar_target_buff(
469  that_crt_col_ptr, query_mem_desc_, target_slot_idx + 1);
470  }
471  }
472  }
473 }
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:207
ALWAYS_INLINE void reduceOneSlot(int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
T advance_to_next_columnar_target_buff(T target_ptr, const QueryMemoryDescriptor &query_mem_desc, const size_t target_slot_idx)
void copyKeyColWise(const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
ALWAYS_INLINE void check_watchdog(const size_t sample_seed)
#define LIKELY(x)
Definition: likely.h:24
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define UNLIKELY(x)
Definition: likely.h:25
const ColSlotContext & getColSlotContext() const
#define CHECK(condition)
Definition: Logger.h:197
T get_cols_ptr(T buff, const QueryMemoryDescriptor &query_mem_desc)
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::reduceOneCountDistinctSlot ( int8_t *  this_ptr1,
const int8_t *  that_ptr1,
const size_t  target_logical_idx,
const ResultSetStorage that 
) const
private

Definition at line 1543 of file ResultSetReduction.cpp.

References CHECK, CHECK_LT, count_distinct_set_union(), QueryMemoryDescriptor::getCountDistinctDescriptor(), QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), Invalid, and query_mem_desc_.

Referenced by reduceOneSlot().

1546  {
1548  const auto& old_count_distinct_desc =
1549  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1550  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1551  const auto& new_count_distinct_desc =
1552  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1553  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1554  CHECK(this_ptr1 && that_ptr1);
1555  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1556  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1558  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1559 }
void count_distinct_set_union(const int64_t new_set_handle, const int64_t old_set_handle, const CountDistinctDescriptor &new_count_distinct_desc, const CountDistinctDescriptor &old_count_distinct_desc)
size_t getCountDistinctDescriptorsSize() const
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:207
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneEntryBaseline ( int8_t *  this_buff,
const int8_t *  that_buff,
const size_t  i,
const size_t  that_entry_count,
const ResultSetStorage that 
) const
private

Definition at line 780 of file ResultSetReduction.cpp.

References CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog(), QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::fill_slots(), anonymous_namespace{ResultSetReduction.cpp}::get_group_value_columnar_reduction(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), isEmptyEntry(), key_offset_colwise(), anonymous_namespace{ResultSetReduction.cpp}::make_key(), query_mem_desc_, and reduceOneEntrySlotsBaseline().

Referenced by reduce().

784  {
785  check_watchdog(that_entry_idx);
786  const auto key_count = query_mem_desc_.getGroupbyColCount();
791  const auto key_off =
793  if (isEmptyEntry(that_entry_idx, that_buff)) {
794  return;
795  }
796  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
797  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
798  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
799  auto [this_entry_slots, empty_entry] = get_group_value_columnar_reduction(
800  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
801  CHECK(this_entry_slots);
802  if (empty_entry) {
803  fill_slots(this_entry_slots,
805  that_buff_i64,
806  that_entry_idx,
807  that_entry_count,
809  return;
810  }
812  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
813 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
void fill_slots(int64_t *dst_entry, const size_t dst_entry_count, const int64_t *src_buff, const size_t src_entry_idx, const size_t src_entry_count, const QueryMemoryDescriptor &query_mem_desc)
GroupValueInfo get_group_value_columnar_reduction(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
std::vector< int64_t > make_key(const int64_t *buff, const size_t entry_count, const size_t key_count)
void reduceOneEntrySlotsBaseline(int64_t *this_entry_slots, const int64_t *that_buff, const size_t that_entry_idx, const size_t that_entry_count, const ResultSetStorage &that) const
size_t getGroupbyColCount() const
ALWAYS_INLINE void check_watchdog(const size_t sample_seed)
QueryDescriptionType getQueryDescriptionType() const
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneEntrySlotsBaseline ( int64_t *  this_entry_slots,
const int64_t *  that_buff,
const size_t  that_entry_idx,
const size_t  that_entry_count,
const ResultSetStorage that 
) const
private

Definition at line 815 of file ResultSetReduction.cpp.

References advance_slot(), CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getTargetGroupbyIndex(), query_mem_desc_, reduceOneSlotBaseline(), slot_offset_colwise(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), and targets_.

Referenced by reduceOneEntryBaseline().

819  {
821  const auto key_count = query_mem_desc_.getGroupbyColCount();
822  size_t j = 0;
823  size_t init_agg_val_idx = 0;
824  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
825  ++target_logical_idx) {
826  const auto& target_info = targets_[target_logical_idx];
827  const auto that_slot_off = slot_offset_colwise(
828  that_entry_idx, init_agg_val_idx, key_count, that_entry_count);
829  const auto this_slot_off = init_agg_val_idx * query_mem_desc_.getEntryCount();
830  reduceOneSlotBaseline(this_entry_slots,
831  this_slot_off,
832  that_buff,
833  that_entry_count,
834  that_slot_off,
835  target_info,
836  target_logical_idx,
837  j,
838  init_agg_val_idx,
839  that);
841  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
842  } else {
843  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
844  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
845  }
846  }
847  j = advance_slot(j, target_info, false);
848  }
849 }
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:207
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
int64_t getTargetGroupbyIndex(const size_t target_idx) const
void reduceOneSlotBaseline(int64_t *this_buff, const size_t this_slot, const int64_t *that_buff, const size_t that_entry_count, const size_t that_slot, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that) const
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
size_t getGroupbyColCount() const
size_t targetGroupbyIndicesSize() const
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneSlot ( int8_t *  this_ptr1,
int8_t *  this_ptr2,
const int8_t *  that_ptr1,
const int8_t *  that_ptr2,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const ResultSetStorage that,
const size_t  first_slot_idx_for_target,
const std::vector< std::string > &  serialized_varlen_buffer 
) const
private

Definition at line 1403 of file ResultSetReduction.cpp.

References TargetInfo::agg_kind, AGGREGATE_ONE_COUNT, AGGREGATE_ONE_NULLABLE_VALUE, AGGREGATE_ONE_NULLABLE_VALUE_SMALL, CHECK, CHECK_EQ, CHECK_LT, logger::FATAL, SQLTypeInfo::get_elem_type(), get_width_for_slot(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getTargetGroupbyIndex(), TargetInfo::is_agg, is_distinct_target(), SQLTypeInfo::is_geometry(), SQLTypeInfo::is_string(), SQLTypeInfo::is_varlen(), QueryMemoryDescriptor::isLogicalSizedColumnsAllowed(), kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kMAX, kMIN, kSAMPLE, kSINGLE_VALUE, kSUM, LOG, query_mem_desc_, reduceOneCountDistinctSlot(), reduceOneSlotSingleValue(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, and QueryMemoryDescriptor::targetGroupbyIndicesSize().

Referenced by reduceEntriesNoCollisionsColWise(), and reduceOneSlotBaseline().

1414  {
1416  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1417  return;
1418  }
1419  }
1420  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1421  const bool float_argument_input = takes_float_argument(target_info);
1422  const auto chosen_bytes =
1423  get_width_for_slot(target_slot_idx, float_argument_input, query_mem_desc_);
1424  auto init_val = target_init_vals_[init_agg_val_idx];
1425 
1426  if (target_info.is_agg && target_info.agg_kind == kSINGLE_VALUE) {
1428  this_ptr1, target_info, target_logical_idx, init_agg_val_idx, that_ptr1);
1429  } else if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1430  switch (target_info.agg_kind) {
1431  case kCOUNT:
1432  case kAPPROX_COUNT_DISTINCT: {
1433  if (is_distinct_target(target_info)) {
1434  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1435  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1436  break;
1437  }
1438  CHECK_EQ(int64_t(0), init_val);
1439  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1440  break;
1441  }
1442  case kAVG: {
1443  // Ignore float argument compaction for count component for fear of its overflow
1444  AGGREGATE_ONE_COUNT(this_ptr2,
1445  that_ptr2,
1446  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1447  }
1448  // fall thru
1449  case kSUM: {
1451  sum, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1452  break;
1453  }
1454  case kMIN: {
1455  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1457  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1458  } else {
1460  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1461  }
1462  break;
1463  }
1464  case kMAX: {
1465  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1467  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1468  } else {
1470  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1471  }
1472  break;
1473  }
1474  default:
1475  CHECK(false);
1476  }
1477  } else {
1478  switch (chosen_bytes) {
1479  case 1: {
1481  const auto rhs_proj_col = *reinterpret_cast<const int8_t*>(that_ptr1);
1482  if (rhs_proj_col != init_val) {
1483  *reinterpret_cast<int8_t*>(this_ptr1) = rhs_proj_col;
1484  }
1485  break;
1486  }
1487  case 2: {
1489  const auto rhs_proj_col = *reinterpret_cast<const int16_t*>(that_ptr1);
1490  if (rhs_proj_col != init_val) {
1491  *reinterpret_cast<int16_t*>(this_ptr1) = rhs_proj_col;
1492  }
1493  break;
1494  }
1495  case 4: {
1496  CHECK(target_info.agg_kind != kSAMPLE ||
1498  const auto rhs_proj_col = *reinterpret_cast<const int32_t*>(that_ptr1);
1499  if (rhs_proj_col != init_val) {
1500  *reinterpret_cast<int32_t*>(this_ptr1) = rhs_proj_col;
1501  }
1502  break;
1503  }
1504  case 8: {
1505  auto rhs_proj_col = *reinterpret_cast<const int64_t*>(that_ptr1);
1506  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) &&
1507  !serialized_varlen_buffer.empty()) {
1508  size_t length_to_elems{0};
1509  if (target_info.sql_type.is_geometry()) {
1510  // TODO: Assumes hard-coded sizes for geometry targets
1511  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1512  } else {
1513  const auto& elem_ti = target_info.sql_type.get_elem_type();
1514  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1515  }
1516 
1517  CHECK_LT(static_cast<size_t>(rhs_proj_col), serialized_varlen_buffer.size());
1518  const auto& varlen_bytes_str = serialized_varlen_buffer[rhs_proj_col];
1519  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
1520  *reinterpret_cast<int64_t*>(this_ptr1) =
1521  reinterpret_cast<const int64_t>(str_ptr);
1522  *reinterpret_cast<int64_t*>(this_ptr2) =
1523  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
1524  } else {
1525  if (rhs_proj_col != init_val) {
1526  *reinterpret_cast<int64_t*>(this_ptr1) = rhs_proj_col;
1527  }
1528  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen())) {
1529  CHECK(this_ptr2 && that_ptr2);
1530  *reinterpret_cast<int64_t*>(this_ptr2) =
1531  *reinterpret_cast<const int64_t*>(that_ptr2);
1532  }
1533  }
1534 
1535  break;
1536  }
1537  default:
1538  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1539  }
1540  }
1541 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
int64_t getTargetGroupbyIndex(const size_t target_idx) const
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
#define LOG(tag)
Definition: Logger.h:188
bool is_varlen() const
Definition: sqltypes.h:432
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:133
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
Definition: sqldefs.h:73
bool is_agg
Definition: TargetInfo.h:40
void reduceOneCountDistinctSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
size_t targetGroupbyIndicesSize() const
Definition: sqldefs.h:75
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:129
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
SQLAgg agg_kind
Definition: TargetInfo.h:41
#define AGGREGATE_ONE_NULLABLE_VALUE(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK_LT(x, y)
Definition: Logger.h:207
ALWAYS_INLINE void reduceOneSlotSingleValue(int8_t *this_ptr1, const TargetInfo &target_info, const size_t target_slot_idx, const size_t init_agg_val_idx, const int8_t *that_ptr1) const
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:76
#define CHECK(condition)
Definition: Logger.h:197
bool is_geometry() const
Definition: sqltypes.h:429
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
bool is_string() const
Definition: sqltypes.h:417
Definition: sqldefs.h:74
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:624
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneSlotBaseline ( int64_t *  this_buff,
const size_t  this_slot,
const int64_t *  that_buff,
const size_t  that_entry_count,
const size_t  that_slot,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const ResultSetStorage that 
) const
private

Definition at line 851 of file ResultSetReduction.cpp.

References TargetInfo::agg_kind, CHECK, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), TargetInfo::is_agg, SQLTypeInfo::is_varlen(), kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), and TargetInfo::sql_type.

Referenced by reduceOneEntrySlotsBaseline().

860  {
862  int8_t* this_ptr2{nullptr};
863  const int8_t* that_ptr2{nullptr};
864  if (target_info.is_agg &&
865  (target_info.agg_kind == kAVG ||
866  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
867  const auto this_count_off = query_mem_desc_.getEntryCount();
868  const auto that_count_off = that_entry_count;
869  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
870  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
871  }
872  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
873  this_ptr2,
874  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
875  that_ptr2,
876  target_info,
877  target_logical_idx,
878  target_slot_idx,
879  init_agg_val_idx,
880  that,
881  target_slot_idx, // dummy, for now
882  {});
883 }
ALWAYS_INLINE void reduceOneSlot(int8_t *this_ptr1, int8_t *this_ptr2, const int8_t *that_ptr1, const int8_t *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const size_t init_agg_val_idx, const ResultSetStorage &that, const size_t first_slot_idx_for_target, const std::vector< std::string > &serialized_varlen_buffer) const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
bool is_varlen() const
Definition: sqltypes.h:432
bool is_agg
Definition: TargetInfo.h:40
SQLAgg agg_kind
Definition: TargetInfo.h:41
#define CHECK(condition)
Definition: Logger.h:197
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::reduceOneSlotSingleValue ( int8_t *  this_ptr1,
const TargetInfo target_info,
const size_t  target_slot_idx,
const size_t  init_agg_val_idx,
const int8_t *  that_ptr1 
) const
private

Definition at line 1355 of file ResultSetReduction.cpp.

References CHECK, logger::FATAL, get_width_for_slot(), SQLTypeInfo::is_varlen(), QueryMemoryDescriptor::isLogicalSizedColumnsAllowed(), LOG, query_mem_desc_, reduce(), TargetInfo::sql_type, takes_float_argument(), and target_init_vals_.

Referenced by reduceOneSlot().

1359  {
1360  const bool float_argument_input = takes_float_argument(target_info);
1361  const auto chosen_bytes =
1362  get_width_for_slot(target_slot_idx, float_argument_input, query_mem_desc_);
1363  auto init_val = target_init_vals_[init_agg_val_idx];
1364 
1365  auto reduce = [&](auto const& size_tag) {
1366  using CastTarget = std::decay_t<decltype(size_tag)>;
1367  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1368  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1369  if (rhs_proj_col == init_val) {
1370  // ignore
1371  } else if (lhs_proj_col == init_val) {
1372  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1373  } else if (lhs_proj_col != rhs_proj_col) {
1374  throw std::runtime_error("Multiple distinct values encountered");
1375  }
1376  };
1377 
1378  switch (chosen_bytes) {
1379  case 1: {
1381  reduce(int8_t());
1382  break;
1383  }
1384  case 2: {
1386  reduce(int16_t());
1387  break;
1388  }
1389  case 4: {
1390  reduce(int32_t());
1391  break;
1392  }
1393  case 8: {
1394  CHECK(!target_info.sql_type.is_varlen());
1395  reduce(int64_t());
1396  break;
1397  }
1398  default:
1399  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1400  }
1401 }
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:211
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
#define LOG(tag)
Definition: Logger.h:188
bool is_varlen() const
Definition: sqltypes.h:432
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:133
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
void reduce(const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code) const
#define CHECK(condition)
Definition: Logger.h:197
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool ResultSetStorage::reduceSingleRow ( const int8_t *  row_ptr,
const int8_t  warp_count,
const bool  is_columnar,
const bool  replace_bitmap_ptr_with_bitmap_sz,
std::vector< int64_t > &  agg_vals,
const QueryMemoryDescriptor query_mem_desc,
const std::vector< TargetInfo > &  targets,
const std::vector< int64_t > &  agg_init_vals 
)
static

Definition at line 1561 of file ResultSetReduction.cpp.

References agg_col_count, AGGREGATE_ONE_COUNT, AGGREGATE_ONE_NULLABLE_COUNT, AGGREGATE_ONE_NULLABLE_VALUE, AGGREGATE_ONE_NULLABLE_VALUE_SMALL, CHECK, CHECK_EQ, CHECK_GE, count_distinct_set_size(), QueryMemoryDescriptor::didOutputColumnar(), logger::ERROR, get_compact_type(), anonymous_namespace{ResultSetReduction.cpp}::get_component(), QueryMemoryDescriptor::getColOnlyOffInBytes(), QueryMemoryDescriptor::getCountDistinctDescriptor(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getRowSize(), QueryMemoryDescriptor::getSlotCount(), QueryMemoryDescriptor::getTargetIdxForKey(), QueryMemoryDescriptor::hasKeylessHash(), is_distinct_target(), kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kMAX, kMIN, kSAMPLE, kSUM, LOG, and takes_float_argument().

Referenced by QueryExecutionContext::groupBufferToDeinterleavedResults().

1568  {
1569  const size_t agg_col_count{agg_vals.size()};
1570  const auto row_size = query_mem_desc.getRowSize();
1571  CHECK_EQ(agg_col_count, query_mem_desc.getSlotCount());
1572  CHECK_GE(agg_col_count, targets.size());
1573  CHECK_EQ(is_columnar, query_mem_desc.didOutputColumnar());
1574  CHECK(query_mem_desc.hasKeylessHash());
1575  std::vector<int64_t> partial_agg_vals(agg_col_count, 0);
1576  bool discard_row = true;
1577  for (int8_t warp_idx = 0; warp_idx < warp_count; ++warp_idx) {
1578  bool discard_partial_result = true;
1579  for (size_t target_idx = 0, agg_col_idx = 0;
1580  target_idx < targets.size() && agg_col_idx < agg_col_count;
1581  ++target_idx, ++agg_col_idx) {
1582  const auto& agg_info = targets[target_idx];
1583  const bool float_argument_input = takes_float_argument(agg_info);
1584  const auto chosen_bytes = float_argument_input
1585  ? sizeof(float)
1586  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1587  auto partial_bin_val = get_component(
1588  row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx), chosen_bytes);
1589  partial_agg_vals[agg_col_idx] = partial_bin_val;
1590  if (is_distinct_target(agg_info)) {
1591  CHECK_EQ(int8_t(1), warp_count);
1592  CHECK(agg_info.is_agg && (agg_info.agg_kind == kCOUNT ||
1593  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1594  partial_bin_val = count_distinct_set_size(
1595  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1596  if (replace_bitmap_ptr_with_bitmap_sz) {
1597  partial_agg_vals[agg_col_idx] = partial_bin_val;
1598  }
1599  }
1600  if (kAVG == agg_info.agg_kind) {
1601  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1602  ++agg_col_idx;
1603  partial_bin_val = partial_agg_vals[agg_col_idx] =
1604  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1605  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1606  }
1607  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1608  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1609  CHECK(agg_info.is_agg);
1610  discard_partial_result = false;
1611  }
1612  }
1613  row_ptr += row_size;
1614  if (discard_partial_result) {
1615  continue;
1616  }
1617  discard_row = false;
1618  for (size_t target_idx = 0, agg_col_idx = 0;
1619  target_idx < targets.size() && agg_col_idx < agg_col_count;
1620  ++target_idx, ++agg_col_idx) {
1621  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1622  const auto& agg_info = targets[target_idx];
1623  const bool float_argument_input = takes_float_argument(agg_info);
1624  const auto chosen_bytes = float_argument_input
1625  ? sizeof(float)
1626  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1627  const auto& chosen_type = get_compact_type(agg_info);
1628  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1629  try {
1630  switch (agg_info.agg_kind) {
1631  case kCOUNT:
1634  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1635  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1636  agg_init_vals[agg_col_idx],
1637  chosen_bytes,
1638  agg_info);
1639  break;
1640  case kAVG:
1641  // Ignore float argument compaction for count component for fear of its
1642  // overflow
1644  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1645  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1646  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1647  // fall thru
1648  case kSUM:
1650  sum,
1651  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1652  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1653  agg_init_vals[agg_col_idx],
1654  chosen_bytes,
1655  agg_info);
1656  break;
1657  case kMIN:
1658  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1660  min,
1661  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1662  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1663  agg_init_vals[agg_col_idx],
1664  chosen_bytes,
1665  agg_info);
1666  } else {
1668  min,
1669  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1670  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1671  agg_init_vals[agg_col_idx],
1672  chosen_bytes,
1673  agg_info);
1674  }
1675  break;
1676  case kMAX:
1677  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1679  max,
1680  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1681  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1682  agg_init_vals[agg_col_idx],
1683  chosen_bytes,
1684  agg_info);
1685  } else {
1687  max,
1688  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1689  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1690  agg_init_vals[agg_col_idx],
1691  chosen_bytes,
1692  agg_info);
1693  }
1694  break;
1695  default:
1696  CHECK(false);
1697  break;
1698  }
1699  } catch (std::runtime_error& e) {
1700  // TODO(miyu): handle the case where chosen_bytes < 8
1701  LOG(ERROR) << e.what();
1702  }
1703  if (chosen_type.is_integer() || chosen_type.is_decimal()) {
1704  switch (chosen_bytes) {
1705  case 8:
1706  break;
1707  case 4: {
1708  int32_t ret = *reinterpret_cast<const int32_t*>(&agg_vals[agg_col_idx]);
1709  if (!(agg_info.agg_kind == kCOUNT && ret != agg_init_vals[agg_col_idx])) {
1710  agg_vals[agg_col_idx] = static_cast<int64_t>(ret);
1711  }
1712  break;
1713  }
1714  default:
1715  CHECK(false);
1716  }
1717  }
1718  if (kAVG == agg_info.agg_kind) {
1719  ++agg_col_idx;
1720  }
1721  } else {
1722  if (agg_info.agg_kind == kSAMPLE) {
1723  CHECK(!agg_info.sql_type.is_varlen())
1724  << "Interleaved bins reduction not supported for variable length "
1725  "arguments "
1726  "to SAMPLE";
1727  }
1728  if (agg_vals[agg_col_idx]) {
1729  if (agg_info.agg_kind == kSAMPLE) {
1730  continue;
1731  }
1732  CHECK_EQ(agg_vals[agg_col_idx], partial_bin_val);
1733  } else {
1734  agg_vals[agg_col_idx] = partial_bin_val;
1735  }
1736  }
1737  }
1738  }
1739  return discard_row;
1740 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
const int64_t const uint32_t const uint32_t const uint32_t agg_col_count
int64_t get_component(const int8_t *group_by_buffer, const size_t comp_sz, const size_t index=0)
#define LOG(tag)
Definition: Logger.h:188
#define CHECK_GE(x, y)
Definition: Logger.h:210
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:133
size_t getColOnlyOffInBytes(const size_t col_idx) const
Definition: sqldefs.h:73
const SQLTypeInfo get_compact_type(const TargetInfo &target)
int64_t count_distinct_set_size(const int64_t set_handle, const CountDistinctDescriptor &count_distinct_desc)
Definition: CountDistinct.h:75
Definition: sqldefs.h:75
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:129
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define AGGREGATE_ONE_NULLABLE_VALUE(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:76
#define AGGREGATE_ONE_NULLABLE_COUNT(val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK(condition)
Definition: Logger.h:197
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
Definition: sqldefs.h:74
Definition: sqldefs.h:72
int32_t getTargetIdxForKey() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetStorage::rewriteAggregateBufferOffsets ( const std::vector< std::string > &  serialized_varlen_buffer) const

Definition at line 516 of file ResultSetReduction.cpp.

References advance_slot(), advance_target_ptr_row_wise(), align_to_int64(), buff_, CHECK, CHECK_GT, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), get_key_bytes_rowwise(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), isEmptyEntry(), kSAMPLE, query_mem_desc_, row_ptr_rowwise(), and targets_.

517  {
518  if (serialized_varlen_buffer.empty()) {
519  return;
520  }
521 
523  auto entry_count = query_mem_desc_.getEntryCount();
524  CHECK_GT(entry_count, size_t(0));
525  CHECK(buff_);
526 
527  // Row-wise iteration, consider moving to separate function
528  for (size_t i = 0; i < entry_count; ++i) {
529  if (isEmptyEntry(i, buff_)) {
530  continue;
531  }
532  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
533  const auto key_bytes_with_padding = align_to_int64(key_bytes);
534  auto rowwise_targets_ptr =
535  row_ptr_rowwise(buff_, query_mem_desc_, i) + key_bytes_with_padding;
536  size_t target_slot_idx = 0;
537  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
538  ++target_logical_idx) {
539  const auto& target_info = targets_[target_logical_idx];
540  if (target_info.sql_type.is_varlen() && target_info.is_agg) {
541  CHECK(target_info.agg_kind == kSAMPLE);
542  auto ptr1 = rowwise_targets_ptr;
543  auto slot_idx = target_slot_idx;
544  auto ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
545  auto offset = *reinterpret_cast<const int64_t*>(ptr1);
546 
547  const auto& elem_ti = target_info.sql_type.get_elem_type();
548  size_t length_to_elems =
549  target_info.sql_type.is_string() || target_info.sql_type.is_geometry()
550  ? 1
551  : elem_ti.get_size();
552  if (target_info.sql_type.is_geometry()) {
553  for (int j = 0; j < target_info.sql_type.get_physical_coord_cols(); j++) {
554  if (j > 0) {
555  ptr1 = ptr2 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 1);
556  ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 2);
557  slot_idx += 2;
558  length_to_elems = 4;
559  }
560  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
561  const auto& varlen_bytes_str = serialized_varlen_buffer[offset++];
562  const auto str_ptr =
563  reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
564  CHECK(ptr1);
565  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
566  CHECK(ptr2);
567  *reinterpret_cast<int64_t*>(ptr2) =
568  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
569  }
570  } else {
571  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
572  const auto& varlen_bytes_str = serialized_varlen_buffer[offset];
573  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
574  CHECK(ptr1);
575  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
576  CHECK(ptr2);
577  *reinterpret_cast<int64_t*>(ptr2) =
578  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
579  }
580  }
581 
582  rowwise_targets_ptr = advance_target_ptr_row_wise(
583  rowwise_targets_ptr, target_info, target_slot_idx, query_mem_desc_, false);
584  target_slot_idx = advance_slot(target_slot_idx, target_info, false);
585  }
586  }
587 
588  return;
589 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:207
T advance_target_ptr_row_wise(T target_ptr, const TargetInfo &target_info, const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc, const bool separate_varlen_storage)
#define CHECK_GT(x, y)
Definition: Logger.h:209
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
#define CHECK_LT(x, y)
Definition: Logger.h:207
int8_t * buff_
Definition: ResultSet.h:209
#define CHECK(condition)
Definition: Logger.h:197
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

void ResultSetStorage::updateEntryCount ( const size_t  new_entry_count)
inline

Definition at line 110 of file ResultSet.h.

References query_mem_desc_, and QueryMemoryDescriptor::setEntryCount().

110  {
111  query_mem_desc_.setEntryCount(new_entry_count);
112  }
void setEntryCount(const size_t val)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:208

+ Here is the call graph for this function:

Friends And Related Function Documentation

friend class ResultSet
friend

Definition at line 219 of file ResultSet.h.

friend class ResultSetManager
friend

Definition at line 220 of file ResultSet.h.

Member Data Documentation

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 210 of file ResultSet.h.

std::unordered_map<int64_t, int64_t> ResultSetStorage::count_distinct_sets_mapping_
private

Definition at line 217 of file ResultSet.h.

Referenced by addCountDistinctSetPointerMapping(), and mappedPtr().

std::vector<int64_t> ResultSetStorage::target_init_vals_
private
const std::vector<TargetInfo> ResultSetStorage::targets_
private

The documentation for this class was generated from the following files: