OmniSciDB  0fdbebe030
 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
 
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 47 of file ResultSet.cpp.

References kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kSAMPLE, null_val_bit_pattern(), takes_float_argument(), target_init_vals_, and targets_.

51  : targets_(targets)
52  , query_mem_desc_(query_mem_desc)
53  , buff_(buff)
54  , buff_is_provided_(buff_is_provided) {
55  for (const auto& target_info : targets_) {
56  if (target_info.agg_kind == kCOUNT ||
57  target_info.agg_kind == kAPPROX_COUNT_DISTINCT) {
58  target_init_vals_.push_back(0);
59  continue;
60  }
61  if (!target_info.sql_type.get_notnull()) {
62  int64_t init_val =
63  null_val_bit_pattern(target_info.sql_type, takes_float_argument(target_info));
64  target_init_vals_.push_back(target_info.is_agg ? init_val : 0);
65  } else {
66  target_init_vals_.push_back(target_info.is_agg ? 0xdeadbeef : 0);
67  }
68  if (target_info.agg_kind == kAVG) {
69  target_init_vals_.push_back(0);
70  } else if (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_geometry()) {
71  for (int i = 1; i < 2 * target_info.sql_type.get_physical_coord_cols(); i++) {
72  target_init_vals_.push_back(0);
73  }
74  } else if (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) {
75  target_init_vals_.push_back(0);
76  }
77  }
78 }
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:121
int64_t null_val_bit_pattern(const SQLTypeInfo &ti, const bool float_argument_input)
const bool buff_is_provided_
Definition: ResultSet.h:208
int8_t * buff_
Definition: ResultSet.h:207
Definition: sqldefs.h:76
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ Here is the call graph for this function:

Member Function Documentation

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

Definition at line 867 of file ResultSet.cpp.

References CHECK(), and count_distinct_sets_mapping_.

868  {
869  const auto it_ok = count_distinct_sets_mapping_.emplace(remote_ptr, ptr);
870  CHECK(it_ok.second);
871 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:215
CHECK(cgen_state)

+ Here is the call graph for this function:

size_t ResultSetStorage::binSearchRowCount ( ) const
private

Definition at line 2200 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().

2200  {
2203 
2204  if (!query_mem_desc_.getEntryCount()) {
2205  return 0;
2206  }
2207 
2209  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2210  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2211  });
2212  } else {
2213  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2214  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2215  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2216  });
2217  }
2218 }
#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
CHECK(cgen_state)
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:207
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 476 of file ResultSetReduction.cpp.

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

Referenced by reduceEntriesNoCollisionsColWise().

478  {
480  for (size_t group_idx = 0; group_idx < query_mem_desc_.getGroupbyColCount();
481  group_idx++) {
482  // if the column corresponds to a group key
483  const auto column_offset_bytes =
485  auto lhs_key_ptr = this_buff + column_offset_bytes;
486  auto rhs_key_ptr = that_buff + column_offset_bytes;
487  switch (query_mem_desc_.groupColWidth(group_idx)) {
488  case 8:
489  *(reinterpret_cast<int64_t*>(lhs_key_ptr) + entry_idx) =
490  *(reinterpret_cast<const int64_t*>(rhs_key_ptr) + entry_idx);
491  break;
492  case 4:
493  *(reinterpret_cast<int32_t*>(lhs_key_ptr) + entry_idx) =
494  *(reinterpret_cast<const int32_t*>(rhs_key_ptr) + entry_idx);
495  break;
496  case 2:
497  *(reinterpret_cast<int16_t*>(lhs_key_ptr) + entry_idx) =
498  *(reinterpret_cast<const int16_t*>(rhs_key_ptr) + entry_idx);
499  break;
500  case 1:
501  *(reinterpret_cast<int8_t*>(lhs_key_ptr) + entry_idx) =
502  *(reinterpret_cast<const int8_t*>(rhs_key_ptr) + entry_idx);
503  break;
504  default:
505  CHECK(false);
506  break;
507  }
508  }
509 }
int8_t groupColWidth(const size_t key_idx) const
CHECK(cgen_state)
size_t getGroupbyColCount() const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206
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 1141 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_.

1141  {
1143  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1144  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1145  const auto key_count = query_mem_desc_.getGroupbyColCount();
1146  CHECK_EQ(slot_count + key_count, entry.size());
1147  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1148 
1149  for (size_t i = 0; i < key_count; i++) {
1150  const auto key_offset = key_offset_colwise(0, i, 1);
1151  this_buff[key_offset] = entry[i];
1152  }
1153 
1154  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1155  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1156  this_buff[slot_offset] = entry[key_count + i];
1157  }
1158 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
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)
CHECK(cgen_state)
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:207
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ Here is the call graph for this function:

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

Definition at line 1088 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_.

1088  {
1089  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1090  const auto key_count = query_mem_desc_.getGroupbyColCount();
1091  CHECK_EQ(slot_count + key_count, entry.size());
1092  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1094  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1095  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1096  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1097  for (size_t i = 0; i < key_count; ++i) {
1098  this_buff[key_off + i] = entry[i];
1099  }
1100  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1101  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1102  this_buff[first_slot_off + i] = entry[key_count + i];
1103  }
1104 }
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:209
size_t getEffectiveKeyWidth() const
CHECK(cgen_state)
size_t getGroupbyColCount() const
int8_t * buff_
Definition: ResultSet.h:207
size_t key_offset_rowwise(const size_t entry_idx, const size_t key_count, const size_t slot_count)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ Here is the call graph for this function:

int8_t * ResultSetStorage::getUnderlyingBuffer ( ) const

Definition at line 80 of file ResultSet.cpp.

References buff_.

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

80  {
81  return buff_;
82 }
int8_t * buff_
Definition: ResultSet.h:207

+ Here is the caller graph for this function:

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

Definition at line 1180 of file ResultSetReduction.cpp.

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

1180  {
1181  CHECK(entry_slots);
1183  size_t slot_off = 0;
1184  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1185  entry_slots[slot_off] = target_init_vals_[j];
1186  slot_off += query_mem_desc_.getEntryCount();
1187  }
1188  } else {
1189  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1190  entry_slots[j] = target_init_vals_[j];
1191  }
1192  }
1193 }
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
CHECK(cgen_state)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

Definition at line 1160 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_.

1160  {
1161  const auto key_count = query_mem_desc_.getGroupbyColCount();
1162  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1164  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1165  const auto first_key_off =
1167  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1168  this_buff[first_key_off + i] = EMPTY_KEY_64;
1169  }
1170  }
1171  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1172  const auto first_val_off =
1173  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1174  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1175  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1176  }
1177  }
1178 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
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)
CHECK(cgen_state)
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:207
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

Definition at line 1106 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_.

1106  {
1107  const auto key_count = query_mem_desc_.getGroupbyColCount();
1108  const auto row_size = get_row_bytes(query_mem_desc_);
1109  CHECK_EQ(row_size % 8, 0u);
1110  const auto key_bytes_with_padding =
1114  case 4: {
1115  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1116  auto row_ptr = buff_ + i * row_size;
1117  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1118  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1119  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1120  slot_ptr[j] = target_init_vals_[j];
1121  }
1122  }
1123  break;
1124  }
1125  case 8: {
1126  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1127  auto row_ptr = buff_ + i * row_size;
1128  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1129  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1130  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1131  slot_ptr[j] = target_init_vals_[j];
1132  }
1133  }
1134  break;
1135  }
1136  default:
1137  CHECK(false);
1138  }
1139 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
size_t getEffectiveKeyWidth() const
ALWAYS_INLINE void fill_empty_key_32(int32_t *key_ptr_i32, const size_t key_count)
CHECK(cgen_state)
size_t getGroupbyColCount() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
int8_t * buff_
Definition: ResultSet.h:207
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:206

+ 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 2088 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().

2088  {
2091  return false;
2092  }
2094  return isEmptyEntryColumnar(entry_idx, buff);
2095  }
2100  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2101  target_init_vals_.size());
2102  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2103  const auto target_slot_off =
2105  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2109  } else {
2110  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2112  case 4:
2115  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2116  case 8:
2117  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2118  default:
2119  CHECK(false);
2120  return true;
2121  }
2122  }
2123 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
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)
CHECK(cgen_state)
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 EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206
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 2220 of file ResultSetIteration.cpp.

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

Definition at line 2129 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().

2130  {
2134  return false;
2135  }
2140  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2141  target_init_vals_.size());
2142  const auto col_buff = advance_col_buff_to_slot(
2144  const auto entry_buff =
2145  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2147  return read_int_from_buff(entry_buff,
2151  } else {
2152  // it's enough to find the first group key which is empty
2154  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2155  } else {
2157  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2158  switch (query_mem_desc_.groupColWidth(0)) {
2159  case 8:
2160  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2161  case 4:
2162  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2163  case 2:
2164  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2165  case 1:
2166  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2167  default:
2168  CHECK(false);
2169  }
2170  }
2171  return false;
2172  }
2173  return false;
2174 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:205
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
#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
CHECK(cgen_state)
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 EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206
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 873 of file ResultSet.cpp.

References count_distinct_sets_mapping_.

873  {
874  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
875  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
876  // remote ptr that do not not exists. Return 0 if no pointer found
877  if (it == count_distinct_sets_mapping_.end()) {
878  return int64_t(0);
879  }
880  return it->second;
881 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:215
template<class KeyType >
void ResultSetStorage::moveEntriesToBuffer ( int8_t *  new_buff,
const size_t  new_entry_count 
) const

Definition at line 886 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().

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

+ 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 950 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_.

956  {
957  const auto key_off =
960  : row_qw_count * entry_index;
961  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
962  if (*key_ptr == get_empty_key<KeyType>()) {
963  return;
964  }
965  int64_t* new_entries_ptr{nullptr};
967  const auto key =
968  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
969  new_entries_ptr =
970  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
971  } else {
972  new_entries_ptr = get_group_value(new_buff_i64,
973  new_entry_count,
974  &src_buff[key_off],
975  key_count,
976  key_byte_width,
977  row_qw_count,
978  nullptr);
979  }
980  CHECK(new_entries_ptr);
981  fill_slots(new_entries_ptr,
982  new_entry_count,
983  src_buff,
984  entry_index,
987 }
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)
CHECK(cgen_state)
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)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 199 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().

201  {
202  auto entry_count = query_mem_desc_.getEntryCount();
203  CHECK_GT(entry_count, size_t(0));
211  }
212  const auto that_entry_count = that.query_mem_desc_.getEntryCount();
215  CHECK_GE(entry_count, that_entry_count);
216  break;
217  default:
218  CHECK_EQ(entry_count, that_entry_count);
219  }
220  auto this_buff = buff_;
221  CHECK(this_buff);
222  auto that_buff = that.buff_;
223  CHECK(that_buff);
226  if (!serialized_varlen_buffer.empty()) {
227  throw std::runtime_error(
228  "Projection of variable length targets with baseline hash group by is not yet "
229  "supported in Distributed mode");
230  }
231  if (use_multithreaded_reduction(that_entry_count)) {
232  const size_t thread_count = cpu_threads();
233  std::vector<std::future<void>> reduction_threads;
234  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
235  const auto thread_entry_count =
236  (that_entry_count + thread_count - 1) / thread_count;
237  const auto start_index = thread_idx * thread_entry_count;
238  const auto end_index =
239  std::min(start_index + thread_entry_count, that_entry_count);
240  reduction_threads.emplace_back(std::async(
241  std::launch::async,
242  [this,
243  this_buff,
244  that_buff,
245  start_index,
246  end_index,
247  that_entry_count,
248  &reduction_code,
249  &that] {
250  if (reduction_code.ir_reduce_loop) {
251  run_reduction_code(reduction_code,
252  this_buff,
253  that_buff,
254  start_index,
255  end_index,
256  that_entry_count,
258  &that.query_mem_desc_,
259  nullptr);
260  } else {
261  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
263  this_buff, that_buff, entry_idx, that_entry_count, that);
264  }
265  }
266  }));
267  }
268  for (auto& reduction_thread : reduction_threads) {
269  reduction_thread.wait();
270  }
271  for (auto& reduction_thread : reduction_threads) {
272  reduction_thread.get();
273  }
274  } else {
275  if (reduction_code.ir_reduce_loop) {
276  run_reduction_code(reduction_code,
277  this_buff,
278  that_buff,
279  0,
280  that_entry_count,
281  that_entry_count,
283  &that.query_mem_desc_,
284  nullptr);
285  } else {
286  for (size_t i = 0; i < that_entry_count; ++i) {
287  reduceOneEntryBaseline(this_buff, that_buff, i, that_entry_count, that);
288  }
289  }
290  }
291  return;
292  }
293  if (use_multithreaded_reduction(entry_count)) {
294  const size_t thread_count = cpu_threads();
295  std::vector<std::future<void>> reduction_threads;
296  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
297  const auto thread_entry_count = (entry_count + thread_count - 1) / thread_count;
298  const auto start_index = thread_idx * thread_entry_count;
299  const auto end_index = std::min(start_index + thread_entry_count, entry_count);
301  reduction_threads.emplace_back(std::async(std::launch::async,
302  [this,
303  this_buff,
304  that_buff,
305  start_index,
306  end_index,
307  &that,
308  &serialized_varlen_buffer] {
310  this_buff,
311  that_buff,
312  that,
313  start_index,
314  end_index,
315  serialized_varlen_buffer);
316  }));
317  } else {
318  reduction_threads.emplace_back(std::async(std::launch::async,
319  [this,
320  this_buff,
321  that_buff,
322  start_index,
323  end_index,
324  that_entry_count,
325  &reduction_code,
326  &that,
327  &serialized_varlen_buffer] {
328  CHECK(reduction_code.ir_reduce_loop);
330  reduction_code,
331  this_buff,
332  that_buff,
333  start_index,
334  end_index,
335  that_entry_count,
337  &that.query_mem_desc_,
338  &serialized_varlen_buffer);
339  }));
340  }
341  }
342  for (auto& reduction_thread : reduction_threads) {
343  reduction_thread.wait();
344  }
345  for (auto& reduction_thread : reduction_threads) {
346  reduction_thread.get();
347  }
348  } else {
351  that_buff,
352  that,
353  0,
355  serialized_varlen_buffer);
356  } else {
357  CHECK(reduction_code.ir_reduce_loop);
358  run_reduction_code(reduction_code,
359  this_buff,
360  that_buff,
361  0,
362  entry_count,
363  that_entry_count,
365  &that.query_mem_desc_,
366  &serialized_varlen_buffer);
367  }
368  }
369 }
#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
CHECK(cgen_state)
QueryDescriptionType getQueryDescriptionType() const
int8_t * buff_
Definition: ResultSet.h:207
bool use_multithreaded_reduction(const size_t entry_count)
int cpu_threads()
Definition: thread_count.h:25
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 385 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.

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

+ 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 1540 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlot().

1543  {
1545  const auto& old_count_distinct_desc =
1546  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1547  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1548  const auto& new_count_distinct_desc =
1549  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1550  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1551  CHECK(this_ptr1 && that_ptr1);
1552  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1553  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1555  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1556 }
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)
CHECK(cgen_state)
size_t getCountDistinctDescriptorsSize() const
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
#define CHECK_LT(x, y)
Definition: Logger.h:207
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 777 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().

781  {
782  check_watchdog(that_entry_idx);
783  const auto key_count = query_mem_desc_.getGroupbyColCount();
788  const auto key_off =
790  if (isEmptyEntry(that_entry_idx, that_buff)) {
791  return;
792  }
793  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
794  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
795  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
796  auto [this_entry_slots, empty_entry] = get_group_value_columnar_reduction(
797  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
798  CHECK(this_entry_slots);
799  if (empty_entry) {
800  fill_slots(this_entry_slots,
802  that_buff_i64,
803  that_entry_idx,
804  that_entry_count,
806  return;
807  }
809  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
810 }
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
CHECK(cgen_state)
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)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 812 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().

816  {
818  const auto key_count = query_mem_desc_.getGroupbyColCount();
819  size_t j = 0;
820  size_t init_agg_val_idx = 0;
821  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
822  ++target_logical_idx) {
823  const auto& target_info = targets_[target_logical_idx];
824  const auto that_slot_off = slot_offset_colwise(
825  that_entry_idx, init_agg_val_idx, key_count, that_entry_count);
826  const auto this_slot_off = init_agg_val_idx * query_mem_desc_.getEntryCount();
827  reduceOneSlotBaseline(this_entry_slots,
828  this_slot_off,
829  that_buff,
830  that_entry_count,
831  that_slot_off,
832  target_info,
833  target_logical_idx,
834  j,
835  init_agg_val_idx,
836  that);
838  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
839  } else {
840  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
841  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
842  }
843  }
844  j = advance_slot(j, target_info, false);
845  }
846 }
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:205
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)
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)
CHECK(cgen_state)
size_t getGroupbyColCount() const
size_t targetGroupbyIndicesSize() const
ssize_t getTargetGroupbyIndex(const size_t target_idx) const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 1400 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().

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

+ 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 848 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().

857  {
859  int8_t* this_ptr2{nullptr};
860  const int8_t* that_ptr2{nullptr};
861  if (target_info.is_agg &&
862  (target_info.agg_kind == kAVG ||
863  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
864  const auto this_count_off = query_mem_desc_.getEntryCount();
865  const auto that_count_off = that_entry_count;
866  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
867  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
868  }
869  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
870  this_ptr2,
871  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
872  that_ptr2,
873  target_info,
874  target_logical_idx,
875  target_slot_idx,
876  init_agg_val_idx,
877  that,
878  target_slot_idx, // dummy, for now
879  {});
880 }
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:413
bool is_agg
Definition: TargetInfo.h:40
CHECK(cgen_state)
SQLAgg agg_kind
Definition: TargetInfo.h:41
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 1352 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().

1356  {
1357  const bool float_argument_input = takes_float_argument(target_info);
1358  const auto chosen_bytes =
1359  get_width_for_slot(target_slot_idx, float_argument_input, query_mem_desc_);
1360  auto init_val = target_init_vals_[init_agg_val_idx];
1361 
1362  auto reduce = [&](auto const& size_tag) {
1363  using CastTarget = std::decay_t<decltype(size_tag)>;
1364  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1365  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1366  if (rhs_proj_col == init_val) {
1367  // ignore
1368  } else if (lhs_proj_col == init_val) {
1369  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1370  } else if (lhs_proj_col != rhs_proj_col) {
1371  throw std::runtime_error("Multiple distinct values encountered");
1372  }
1373  };
1374 
1375  switch (chosen_bytes) {
1376  case 1: {
1378  reduce(int8_t());
1379  break;
1380  }
1381  case 2: {
1383  reduce(int16_t());
1384  break;
1385  }
1386  case 4: {
1387  reduce(int32_t());
1388  break;
1389  }
1390  case 8: {
1391  CHECK(!target_info.sql_type.is_varlen());
1392  reduce(int64_t());
1393  break;
1394  }
1395  default:
1396  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1397  }
1398 }
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:209
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
#define LOG(tag)
Definition: Logger.h:188
bool is_varlen() const
Definition: sqltypes.h:413
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:121
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
CHECK(cgen_state)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ 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 1558 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().

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

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

+ Here is the call graph for this function:

void ResultSetStorage::updateEntryCount ( const size_t  new_entry_count)
inline

Definition at line 108 of file ResultSet.h.

References query_mem_desc_, and QueryMemoryDescriptor::setEntryCount().

108  {
109  query_mem_desc_.setEntryCount(new_entry_count);
110  }
void setEntryCount(const size_t val)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:206

+ Here is the call graph for this function:

Friends And Related Function Documentation

friend class ResultSet
friend

Definition at line 217 of file ResultSet.h.

friend class ResultSetManager
friend

Definition at line 218 of file ResultSet.h.

Member Data Documentation

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 208 of file ResultSet.h.

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

Definition at line 215 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: