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

#include <ResultSetStorage.h>

+ Collaboration diagram for ResultSetStorage:

Public Member Functions

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)
 
void reduceOneApproxMedianSlot (int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
 

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

 ResultSetStorage (const std::vector< TargetInfo > &targets, const QueryMemoryDescriptor &query_mem_desc, int8_t *buff, const bool buff_is_provided)
 
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 91 of file ResultSetStorage.h.

Constructor & Destructor Documentation

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

Definition at line 45 of file ResultSetStorage.cpp.

49  : targets_(targets)
50  , query_mem_desc_(query_mem_desc)
51  , buff_(buff)
52  , buff_is_provided_(buff_is_provided)
const std::vector< TargetInfo > targets_
std::vector< int64_t > target_init_vals_
const bool buff_is_provided_
std::vector< int64_t > initialize_target_values_for_storage(const std::vector< TargetInfo > &targets)
QueryMemoryDescriptor query_mem_desc_

Member Function Documentation

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

Definition at line 59 of file ResultSetStorage.cpp.

References CHECK, and count_distinct_sets_mapping_.

60  {
61  const auto it_ok = count_distinct_sets_mapping_.emplace(remote_ptr, ptr);
62  CHECK(it_ok.second);
63 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
#define CHECK(condition)
Definition: Logger.h:203
size_t ResultSetStorage::binSearchRowCount ( ) const
private

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

2145  {
2148 
2149  if (!query_mem_desc_.getEntryCount()) {
2150  return 0;
2151  }
2152 
2154  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2155  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2156  });
2157  } else {
2158  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2159  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2160  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2161  });
2162  }
2163 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
#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
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

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

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

Referenced by reduceEntriesNoCollisionsColWise().

497  {
499  for (size_t group_idx = 0; group_idx < query_mem_desc_.getGroupbyColCount();
500  group_idx++) {
501  // if the column corresponds to a group key
502  const auto column_offset_bytes =
504  auto lhs_key_ptr = this_buff + column_offset_bytes;
505  auto rhs_key_ptr = that_buff + column_offset_bytes;
506  switch (query_mem_desc_.groupColWidth(group_idx)) {
507  case 8:
508  *(reinterpret_cast<int64_t*>(lhs_key_ptr) + entry_idx) =
509  *(reinterpret_cast<const int64_t*>(rhs_key_ptr) + entry_idx);
510  break;
511  case 4:
512  *(reinterpret_cast<int32_t*>(lhs_key_ptr) + entry_idx) =
513  *(reinterpret_cast<const int32_t*>(rhs_key_ptr) + entry_idx);
514  break;
515  case 2:
516  *(reinterpret_cast<int16_t*>(lhs_key_ptr) + entry_idx) =
517  *(reinterpret_cast<const int16_t*>(rhs_key_ptr) + entry_idx);
518  break;
519  case 1:
520  *(reinterpret_cast<int8_t*>(lhs_key_ptr) + entry_idx) =
521  *(reinterpret_cast<const int8_t*>(rhs_key_ptr) + entry_idx);
522  break;
523  default:
524  CHECK(false);
525  break;
526  }
527  }
528 }
int8_t groupColWidth(const size_t key_idx) const
size_t getGroupbyColCount() const
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_
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 1186 of file ResultSetReduction.cpp.

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

1186  {
1188  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1189  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1190  const auto key_count = query_mem_desc_.getGroupbyColCount();
1191  CHECK_EQ(slot_count + key_count, entry.size());
1192  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1193 
1194  for (size_t i = 0; i < key_count; i++) {
1195  const auto key_offset = key_offset_colwise(0, i, 1);
1196  this_buff[key_offset] = entry[i];
1197  }
1198 
1199  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1200  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1201  this_buff[slot_offset] = entry[key_count + i];
1202  }
1203 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
std::vector< int64_t > target_init_vals_
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)
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

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

Definition at line 1133 of file ResultSetReduction.cpp.

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

1133  {
1134  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1135  const auto key_count = query_mem_desc_.getGroupbyColCount();
1136  CHECK_EQ(slot_count + key_count, entry.size());
1137  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1139  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1140  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1141  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1142  for (size_t i = 0; i < key_count; ++i) {
1143  this_buff[key_off + i] = entry[i];
1144  }
1145  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1146  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1147  this_buff[first_slot_off + i] = entry[key_count + i];
1148  }
1149 }
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:211
std::vector< int64_t > target_init_vals_
size_t getEffectiveKeyWidth() const
size_t getGroupbyColCount() const
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:203
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

size_t ResultSetStorage::getEntryCount ( ) const
inline

Definition at line 108 of file ResultSetStorage.h.

References QueryMemoryDescriptor::getEntryCount(), and query_mem_desc_.

108 { return query_mem_desc_.getEntryCount(); }
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

int8_t * ResultSetStorage::getUnderlyingBuffer ( ) const

Definition at line 55 of file ResultSetStorage.cpp.

References buff_.

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

55  {
56  return buff_;
57 }

+ Here is the caller graph for this function:

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

Definition at line 1225 of file ResultSetReduction.cpp.

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

1225  {
1226  CHECK(entry_slots);
1228  size_t slot_off = 0;
1229  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1230  entry_slots[slot_off] = target_init_vals_[j];
1231  slot_off += query_mem_desc_.getEntryCount();
1232  }
1233  } else {
1234  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1235  entry_slots[j] = target_init_vals_[j];
1236  }
1237  }
1238 }
std::vector< int64_t > target_init_vals_
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

Definition at line 1205 of file ResultSetReduction.cpp.

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

1205  {
1206  const auto key_count = query_mem_desc_.getGroupbyColCount();
1207  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1209  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1210  const auto first_key_off =
1212  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1213  this_buff[first_key_off + i] = EMPTY_KEY_64;
1214  }
1215  }
1216  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1217  const auto first_val_off =
1218  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1219  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1220  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1221  }
1222  }
1223 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
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)
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

Definition at line 1151 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(), i, generate_TableFunctionsFactory_init::j, query_mem_desc_, and target_init_vals_.

1151  {
1152  const auto key_count = query_mem_desc_.getGroupbyColCount();
1153  const auto row_size = get_row_bytes(query_mem_desc_);
1154  CHECK_EQ(row_size % 8, 0u);
1155  const auto key_bytes_with_padding =
1159  case 4: {
1160  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1161  auto row_ptr = buff_ + i * row_size;
1162  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1163  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1164  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1165  slot_ptr[j] = target_init_vals_[j];
1166  }
1167  }
1168  break;
1169  }
1170  case 8: {
1171  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1172  auto row_ptr = buff_ + i * row_size;
1173  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1174  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1175  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1176  slot_ptr[j] = target_init_vals_[j];
1177  }
1178  }
1179  break;
1180  }
1181  default:
1182  CHECK(false);
1183  }
1184 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
std::vector< int64_t > target_init_vals_
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)
#define CHECK(condition)
Definition: Logger.h:203
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_

+ 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 2033 of file ResultSetIteration.cpp.

References CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), EMPTY_KEY_32, EMPTY_KEY_64, result_set::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().

2033  {
2036  return false;
2037  }
2039  return isEmptyEntryColumnar(entry_idx, buff);
2040  }
2045  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2046  target_init_vals_.size());
2047  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2048  const auto target_slot_off = result_set::get_byteoff_of_slot(
2050  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2054  } else {
2055  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2057  case 4:
2060  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2061  case 8:
2062  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2063  default:
2064  CHECK(false);
2065  return true;
2066  }
2067  }
2068 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
#define CHECK_GE(x, y)
Definition: Logger.h:216
size_t getEffectiveKeyWidth() const
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
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:213
#define CHECK(condition)
Definition: Logger.h:203
#define EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
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 2165 of file ResultSetIteration.cpp.

2165  {
2166  return isEmptyEntry(entry_idx, buff_);
2167 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
bool ResultSetStorage::isEmptyEntryColumnar ( const size_t  entry_idx,
const int8_t *  buff 
) const
private

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

2075  {
2079  return false;
2080  }
2085  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2086  target_init_vals_.size());
2087  const auto col_buff = advance_col_buff_to_slot(
2089  const auto entry_buff =
2090  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2092  return read_int_from_buff(entry_buff,
2096  } else {
2097  // it's enough to find the first group key which is empty
2099  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2100  } else {
2102  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2103  switch (query_mem_desc_.groupColWidth(0)) {
2104  case 8:
2105  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2106  case 4:
2107  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2108  case 2:
2109  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2110  case 1:
2111  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2112  default:
2113  CHECK(false);
2114  }
2115  }
2116  return false;
2117  }
2118  return false;
2119 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
std::vector< int64_t > target_init_vals_
#define CHECK_GE(x, y)
Definition: Logger.h:216
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:213
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:203
#define EMPTY_KEY_32
QueryMemoryDescriptor query_mem_desc_
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 65 of file ResultSetStorage.cpp.

References count_distinct_sets_mapping_.

65  {
66  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
67  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
68  // remote ptr that do not not exists. Return 0 if no pointer found
69  if (it == count_distinct_sets_mapping_.end()) {
70  return int64_t(0);
71  }
72  return it->second;
73 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
template<class KeyType >
void ResultSetStorage::moveEntriesToBuffer ( int8_t *  new_buff,
const size_t  new_entry_count 
) const

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

931  {
933  CHECK_GT(new_entry_count, query_mem_desc_.getEntryCount());
934  auto new_buff_i64 = reinterpret_cast<int64_t*>(new_buff);
935  const auto key_count = query_mem_desc_.getGroupbyColCount();
938  const auto src_buff = reinterpret_cast<const int64_t*>(buff_);
939  const auto row_qw_count = get_row_qw_count(query_mem_desc_);
940  const auto key_byte_width = query_mem_desc_.getEffectiveKeyWidth();
941 
943  const size_t thread_count = cpu_threads();
944  std::vector<std::future<void>> move_threads;
945 
946  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
947  const auto thread_entry_count =
948  (query_mem_desc_.getEntryCount() + thread_count - 1) / thread_count;
949  const auto start_index = thread_idx * thread_entry_count;
950  const auto end_index =
951  std::min(start_index + thread_entry_count, query_mem_desc_.getEntryCount());
952  move_threads.emplace_back(std::async(
953  std::launch::async,
954  [this,
955  src_buff,
956  new_buff_i64,
957  new_entry_count,
958  start_index,
959  end_index,
960  key_count,
961  row_qw_count,
962  key_byte_width] {
963  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
964  moveOneEntryToBuffer<KeyType>(entry_idx,
965  new_buff_i64,
966  new_entry_count,
967  key_count,
968  row_qw_count,
969  src_buff,
970  key_byte_width);
971  }
972  }));
973  }
974  for (auto& move_thread : move_threads) {
975  move_thread.wait();
976  }
977  for (auto& move_thread : move_threads) {
978  move_thread.get();
979  }
980  } else {
981  for (size_t entry_idx = 0; entry_idx < query_mem_desc_.getEntryCount(); ++entry_idx) {
982  moveOneEntryToBuffer<KeyType>(entry_idx,
983  new_buff_i64,
984  new_entry_count,
985  key_count,
986  row_qw_count,
987  src_buff,
988  key_byte_width);
989  }
990  }
991 }
size_t getEffectiveKeyWidth() const
#define CHECK_GT(x, y)
Definition: Logger.h:215
size_t getGroupbyColCount() const
QueryDescriptionType getQueryDescriptionType() const
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:203
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
int cpu_threads()
Definition: thread_count.h:24
QueryMemoryDescriptor query_mem_desc_

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

1000  {
1001  const auto key_off =
1003  ? key_offset_colwise(entry_index, 0, query_mem_desc_.getEntryCount())
1004  : row_qw_count * entry_index;
1005  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
1006  if (*key_ptr == get_empty_key<KeyType>()) {
1007  return;
1008  }
1009  int64_t* new_entries_ptr{nullptr};
1011  const auto key =
1012  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
1013  new_entries_ptr =
1014  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
1015  } else {
1016  new_entries_ptr = get_group_value(new_buff_i64,
1017  new_entry_count,
1018  &src_buff[key_off],
1019  key_count,
1020  key_byte_width,
1021  row_qw_count);
1022  }
1023  CHECK(new_entries_ptr);
1024  fill_slots(new_entries_ptr,
1025  new_entry_count,
1026  src_buff,
1027  entry_index,
1029  query_mem_desc_);
1030 }
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)
RUNTIME_EXPORT 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)
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:203
RUNTIME_EXPORT 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)
QueryMemoryDescriptor query_mem_desc_

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

References buff_, CHECK, CHECK_EQ, CHECK_GE, CHECK_GT, cpu_threads(), QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getQueryDescriptionType(), GroupByBaselineHash, GroupByPerfectHash, i, 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().

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

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

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

406  {
407  // TODO(adb / saman): Support column wise output when serializing distributed agg
408  // functions
409  CHECK(serialized_varlen_buffer.empty());
410 
411  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
412 
413  auto this_crt_col_ptr = get_cols_ptr(this_buff, query_mem_desc_);
414  auto that_crt_col_ptr = get_cols_ptr(that_buff, query_mem_desc_);
415  for (size_t target_idx = 0; target_idx < targets_.size(); ++target_idx) {
416  const auto& agg_info = targets_[target_idx];
417  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_idx);
418 
419  bool two_slot_target{false};
420  if (agg_info.is_agg &&
421  (agg_info.agg_kind == kAVG ||
422  (agg_info.agg_kind == kSAMPLE && agg_info.sql_type.is_varlen()))) {
423  // Note that this assumes if one of the slot pairs in a given target is an array,
424  // all slot pairs are arrays. Currently this is true for all geo targets, but we
425  // should better codify and store this information in the future
426  two_slot_target = true;
427  }
429  throw std::runtime_error(
430  "Query execution was interrupted during result set reduction");
431  }
433  check_watchdog();
434  }
435  for (size_t target_slot_idx = slots_for_col.front();
436  target_slot_idx < slots_for_col.back() + 1;
437  target_slot_idx += 2) {
438  const auto this_next_col_ptr = advance_to_next_columnar_target_buff(
439  this_crt_col_ptr, query_mem_desc_, target_slot_idx);
440  const auto that_next_col_ptr = advance_to_next_columnar_target_buff(
441  that_crt_col_ptr, query_mem_desc_, target_slot_idx);
442  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
443  if (isEmptyEntryColumnar(entry_idx, that_buff)) {
444  continue;
445  }
447  // copy the key from right hand side
448  copyKeyColWise(entry_idx, this_buff, that_buff);
449  }
450  auto this_ptr1 =
451  this_crt_col_ptr +
452  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
453  auto that_ptr1 =
454  that_crt_col_ptr +
455  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
456  int8_t* this_ptr2{nullptr};
457  const int8_t* that_ptr2{nullptr};
458  if (UNLIKELY(two_slot_target)) {
459  this_ptr2 =
460  this_next_col_ptr +
461  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
462  that_ptr2 =
463  that_next_col_ptr +
464  entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
465  }
466  reduceOneSlot(this_ptr1,
467  this_ptr2,
468  that_ptr1,
469  that_ptr2,
470  agg_info,
471  target_idx,
472  target_slot_idx,
473  target_slot_idx,
474  that,
475  slots_for_col.front(),
476  serialized_varlen_buffer);
477  }
478 
479  this_crt_col_ptr = this_next_col_ptr;
480  that_crt_col_ptr = that_next_col_ptr;
481  if (UNLIKELY(two_slot_target)) {
482  this_crt_col_ptr = advance_to_next_columnar_target_buff(
483  this_crt_col_ptr, query_mem_desc_, target_slot_idx + 1);
484  that_crt_col_ptr = advance_to_next_columnar_target_buff(
485  that_crt_col_ptr, query_mem_desc_, target_slot_idx + 1);
486  }
487  }
488  }
489 }
const std::vector< TargetInfo > targets_
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)
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:77
bool g_enable_non_kernel_time_query_interrupt
Definition: Execute.cpp:115
__device__ bool check_interrupt()
void copyKeyColWise(const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
#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:203
T get_cols_ptr(T buff, const QueryMemoryDescriptor &query_mem_desc)
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

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

Definition at line 1589 of file ResultSetReduction.cpp.

References CHECK, CHECK_LT, const, QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), and query_mem_desc_.

Referenced by reduceOneSlot().

1592  {
1594  static_assert(sizeof(int64_t) == sizeof(quantile::TDigest*));
1595  auto* incoming = *reinterpret_cast<quantile::TDigest* const*>(that_ptr1);
1596  CHECK(incoming) << "this_ptr1=" << (void*)this_ptr1
1597  << ", that_ptr1=" << (void const*)that_ptr1
1598  << ", target_logical_idx=" << target_logical_idx;
1599  if (incoming->centroids().capacity()) {
1600  auto* accumulator = *reinterpret_cast<quantile::TDigest**>(this_ptr1);
1601  CHECK(accumulator) << "this_ptr1=" << (void*)this_ptr1
1602  << ", that_ptr1=" << (void const*)that_ptr1
1603  << ", target_logical_idx=" << target_logical_idx;
1604  accumulator->allocate();
1605  accumulator->mergeTDigest(*incoming);
1606  }
1607 }
#define const
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:213
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

+ Here is the caller 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 1609 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlot().

1612  {
1614  const auto& old_count_distinct_desc =
1615  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1616  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1617  const auto& new_count_distinct_desc =
1618  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1619  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1620  CHECK(this_ptr1 && that_ptr1);
1621  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1622  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1624  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1625 }
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:213
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

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

References CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog_with_seed(), QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::fill_slots(), g_enable_dynamic_watchdog, 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().

823  {
825  check_watchdog_with_seed(that_entry_idx);
826  }
827  const auto key_count = query_mem_desc_.getGroupbyColCount();
832  const auto key_off =
834  if (isEmptyEntry(that_entry_idx, that_buff)) {
835  return;
836  }
837  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
838  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
839  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
840  auto [this_entry_slots, empty_entry] = get_group_value_columnar_reduction(
841  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
842  CHECK(this_entry_slots);
843  if (empty_entry) {
844  fill_slots(this_entry_slots,
846  that_buff_i64,
847  that_entry_idx,
848  that_entry_count,
850  return;
851  }
853  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
854 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
ALWAYS_INLINE void check_watchdog_with_seed(const size_t sample_seed)
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)
bool g_enable_dynamic_watchdog
Definition: Execute.cpp:77
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
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:203
QueryMemoryDescriptor query_mem_desc_

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

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

Referenced by reduceOneEntryBaseline().

860  {
862  const auto key_count = query_mem_desc_.getGroupbyColCount();
863  size_t j = 0;
864  size_t init_agg_val_idx = 0;
865  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
866  ++target_logical_idx) {
867  const auto& target_info = targets_[target_logical_idx];
868  const auto that_slot_off = slot_offset_colwise(
869  that_entry_idx, init_agg_val_idx, key_count, that_entry_count);
870  const auto this_slot_off = init_agg_val_idx * query_mem_desc_.getEntryCount();
871  reduceOneSlotBaseline(this_entry_slots,
872  this_slot_off,
873  that_buff,
874  that_entry_count,
875  that_slot_off,
876  target_info,
877  target_logical_idx,
878  j,
879  init_agg_val_idx,
880  that);
882  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
883  } else {
884  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
885  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
886  }
887  }
888  j = advance_slot(j, target_info, false);
889  }
890 }
const std::vector< TargetInfo > targets_
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:203
QueryMemoryDescriptor query_mem_desc_

+ 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 1445 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(), result_set::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, kAPPROX_MEDIAN, kAVG, kCOUNT, kMAX, kMIN, kSAMPLE, kSINGLE_VALUE, kSUM, LOG, query_mem_desc_, reduceOneApproxMedianSlot(), reduceOneCountDistinctSlot(), reduceOneSlotSingleValue(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, QueryMemoryDescriptor::targetGroupbyIndicesSize(), toString(), and UNREACHABLE.

Referenced by reduceEntriesNoCollisionsColWise(), and reduceOneSlotBaseline().

1456  {
1458  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1459  return;
1460  }
1461  }
1462  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1463  const bool float_argument_input = takes_float_argument(target_info);
1464  const auto chosen_bytes = result_set::get_width_for_slot(
1465  target_slot_idx, float_argument_input, query_mem_desc_);
1466  int64_t init_val = target_init_vals_[init_agg_val_idx]; // skip_val for nullable types
1467 
1468  if (target_info.is_agg && target_info.agg_kind == kSINGLE_VALUE) {
1470  this_ptr1, target_info, target_logical_idx, init_agg_val_idx, that_ptr1);
1471  } else if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1472  switch (target_info.agg_kind) {
1473  case kCOUNT:
1474  case kAPPROX_COUNT_DISTINCT: {
1475  if (is_distinct_target(target_info)) {
1476  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1477  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1478  break;
1479  }
1480  CHECK_EQ(int64_t(0), init_val);
1481  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1482  break;
1483  }
1484  case kAVG: {
1485  // Ignore float argument compaction for count component for fear of its overflow
1486  AGGREGATE_ONE_COUNT(this_ptr2,
1487  that_ptr2,
1488  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1489  }
1490  // fall thru
1491  case kSUM: {
1493  sum, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1494  break;
1495  }
1496  case kMIN: {
1497  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1499  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1500  } else {
1502  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1503  }
1504  break;
1505  }
1506  case kMAX: {
1507  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1509  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1510  } else {
1512  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1513  }
1514  break;
1515  }
1516  case kAPPROX_MEDIAN:
1517  CHECK_EQ(static_cast<int8_t>(sizeof(int64_t)), chosen_bytes);
1518  reduceOneApproxMedianSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1519  break;
1520  default:
1521  UNREACHABLE() << toString(target_info.agg_kind);
1522  }
1523  } else {
1524  switch (chosen_bytes) {
1525  case 1: {
1527  const auto rhs_proj_col = *reinterpret_cast<const int8_t*>(that_ptr1);
1528  if (rhs_proj_col != init_val) {
1529  *reinterpret_cast<int8_t*>(this_ptr1) = rhs_proj_col;
1530  }
1531  break;
1532  }
1533  case 2: {
1535  const auto rhs_proj_col = *reinterpret_cast<const int16_t*>(that_ptr1);
1536  if (rhs_proj_col != init_val) {
1537  *reinterpret_cast<int16_t*>(this_ptr1) = rhs_proj_col;
1538  }
1539  break;
1540  }
1541  case 4: {
1542  CHECK(target_info.agg_kind != kSAMPLE ||
1544  const auto rhs_proj_col = *reinterpret_cast<const int32_t*>(that_ptr1);
1545  if (rhs_proj_col != init_val) {
1546  *reinterpret_cast<int32_t*>(this_ptr1) = rhs_proj_col;
1547  }
1548  break;
1549  }
1550  case 8: {
1551  auto rhs_proj_col = *reinterpret_cast<const int64_t*>(that_ptr1);
1552  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) &&
1553  !serialized_varlen_buffer.empty()) {
1554  size_t length_to_elems{0};
1555  if (target_info.sql_type.is_geometry()) {
1556  // TODO: Assumes hard-coded sizes for geometry targets
1557  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1558  } else {
1559  const auto& elem_ti = target_info.sql_type.get_elem_type();
1560  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1561  }
1562 
1563  CHECK_LT(static_cast<size_t>(rhs_proj_col), serialized_varlen_buffer.size());
1564  const auto& varlen_bytes_str = serialized_varlen_buffer[rhs_proj_col];
1565  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
1566  *reinterpret_cast<int64_t*>(this_ptr1) =
1567  reinterpret_cast<const int64_t>(str_ptr);
1568  *reinterpret_cast<int64_t*>(this_ptr2) =
1569  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
1570  } else {
1571  if (rhs_proj_col != init_val) {
1572  *reinterpret_cast<int64_t*>(this_ptr1) = rhs_proj_col;
1573  }
1574  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen())) {
1575  CHECK(this_ptr2 && that_ptr2);
1576  *reinterpret_cast<int64_t*>(this_ptr2) =
1577  *reinterpret_cast<const int64_t*>(that_ptr2);
1578  }
1579  }
1580 
1581  break;
1582  }
1583  default:
1584  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1585  }
1586  }
1587 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
std::string toString(const ExtArgumentType &sig_type)
std::vector< int64_t > target_init_vals_
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:194
bool is_varlen() const
Definition: sqltypes.h:514
#define UNREACHABLE()
Definition: Logger.h:247
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:134
Definition: sqldefs.h:73
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
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:130
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:213
void reduceOneApproxMedianSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_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
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:76
#define CHECK(condition)
Definition: Logger.h:203
bool is_geometry() const
Definition: sqltypes.h:501
#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:489
Definition: sqldefs.h:74
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:713
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_

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

901  {
903  int8_t* this_ptr2{nullptr};
904  const int8_t* that_ptr2{nullptr};
905  if (target_info.is_agg &&
906  (target_info.agg_kind == kAVG ||
907  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
908  const auto this_count_off = query_mem_desc_.getEntryCount();
909  const auto that_count_off = that_entry_count;
910  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
911  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
912  }
913  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
914  this_ptr2,
915  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
916  that_ptr2,
917  target_info,
918  target_logical_idx,
919  target_slot_idx,
920  init_agg_val_idx,
921  that,
922  target_slot_idx, // dummy, for now
923  {});
924 }
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:514
bool is_agg
Definition: TargetInfo.h:40
SQLAgg agg_kind
Definition: TargetInfo.h:41
#define CHECK(condition)
Definition: Logger.h:203
Definition: sqldefs.h:72
QueryMemoryDescriptor query_mem_desc_

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

References CHECK, logger::FATAL, result_set::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().

1401  {
1402  const bool float_argument_input = takes_float_argument(target_info);
1403  const auto chosen_bytes = result_set::get_width_for_slot(
1404  target_slot_idx, float_argument_input, query_mem_desc_);
1405  auto init_val = target_init_vals_[init_agg_val_idx];
1406 
1407  auto reduce = [&](auto const& size_tag) {
1408  using CastTarget = std::decay_t<decltype(size_tag)>;
1409  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1410  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1411  if (rhs_proj_col == init_val) {
1412  // ignore
1413  } else if (lhs_proj_col == init_val) {
1414  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1415  } else if (lhs_proj_col != rhs_proj_col) {
1416  throw std::runtime_error("Multiple distinct values encountered");
1417  }
1418  };
1419 
1420  switch (chosen_bytes) {
1421  case 1: {
1423  reduce(int8_t());
1424  break;
1425  }
1426  case 2: {
1428  reduce(int16_t());
1429  break;
1430  }
1431  case 4: {
1432  reduce(int32_t());
1433  break;
1434  }
1435  case 8: {
1436  CHECK(!target_info.sql_type.is_varlen());
1437  reduce(int64_t());
1438  break;
1439  }
1440  default:
1441  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1442  }
1443 }
std::vector< int64_t > target_init_vals_
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
#define LOG(tag)
Definition: Logger.h:194
bool is_varlen() const
Definition: sqltypes.h:514
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:134
void reduce(const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer, const ReductionCode &reduction_code) const
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:203
QueryMemoryDescriptor query_mem_desc_

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

References 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().

1634  {
1635  const size_t agg_col_count{agg_vals.size()};
1636  const auto row_size = query_mem_desc.getRowSize();
1637  CHECK_EQ(agg_col_count, query_mem_desc.getSlotCount());
1638  CHECK_GE(agg_col_count, targets.size());
1639  CHECK_EQ(is_columnar, query_mem_desc.didOutputColumnar());
1640  CHECK(query_mem_desc.hasKeylessHash());
1641  std::vector<int64_t> partial_agg_vals(agg_col_count, 0);
1642  bool discard_row = true;
1643  for (int8_t warp_idx = 0; warp_idx < warp_count; ++warp_idx) {
1644  bool discard_partial_result = true;
1645  for (size_t target_idx = 0, agg_col_idx = 0;
1646  target_idx < targets.size() && agg_col_idx < agg_col_count;
1647  ++target_idx, ++agg_col_idx) {
1648  const auto& agg_info = targets[target_idx];
1649  const bool float_argument_input = takes_float_argument(agg_info);
1650  const auto chosen_bytes = float_argument_input
1651  ? sizeof(float)
1652  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1653  auto partial_bin_val = get_component(
1654  row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx), chosen_bytes);
1655  partial_agg_vals[agg_col_idx] = partial_bin_val;
1656  if (is_distinct_target(agg_info)) {
1657  CHECK_EQ(int8_t(1), warp_count);
1658  CHECK(agg_info.is_agg && (agg_info.agg_kind == kCOUNT ||
1659  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1660  partial_bin_val = count_distinct_set_size(
1661  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1662  if (replace_bitmap_ptr_with_bitmap_sz) {
1663  partial_agg_vals[agg_col_idx] = partial_bin_val;
1664  }
1665  }
1666  if (kAVG == agg_info.agg_kind) {
1667  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1668  ++agg_col_idx;
1669  partial_bin_val = partial_agg_vals[agg_col_idx] =
1670  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1671  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1672  }
1673  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1674  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1675  CHECK(agg_info.is_agg);
1676  discard_partial_result = false;
1677  }
1678  }
1679  row_ptr += row_size;
1680  if (discard_partial_result) {
1681  continue;
1682  }
1683  discard_row = false;
1684  for (size_t target_idx = 0, agg_col_idx = 0;
1685  target_idx < targets.size() && agg_col_idx < agg_col_count;
1686  ++target_idx, ++agg_col_idx) {
1687  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1688  const auto& agg_info = targets[target_idx];
1689  const bool float_argument_input = takes_float_argument(agg_info);
1690  const auto chosen_bytes = float_argument_input
1691  ? sizeof(float)
1692  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1693  const auto& chosen_type = get_compact_type(agg_info);
1694  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1695  try {
1696  switch (agg_info.agg_kind) {
1697  case kCOUNT:
1700  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1701  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1702  agg_init_vals[agg_col_idx],
1703  chosen_bytes,
1704  agg_info);
1705  break;
1706  case kAVG:
1707  // Ignore float argument compaction for count component for fear of its
1708  // overflow
1710  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1711  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1712  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1713  // fall thru
1714  case kSUM:
1716  sum,
1717  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1718  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1719  agg_init_vals[agg_col_idx],
1720  chosen_bytes,
1721  agg_info);
1722  break;
1723  case kMIN:
1724  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1726  min,
1727  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1728  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1729  agg_init_vals[agg_col_idx],
1730  chosen_bytes,
1731  agg_info);
1732  } else {
1734  min,
1735  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1736  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1737  agg_init_vals[agg_col_idx],
1738  chosen_bytes,
1739  agg_info);
1740  }
1741  break;
1742  case kMAX:
1743  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1745  max,
1746  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1747  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1748  agg_init_vals[agg_col_idx],
1749  chosen_bytes,
1750  agg_info);
1751  } else {
1753  max,
1754  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1755  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1756  agg_init_vals[agg_col_idx],
1757  chosen_bytes,
1758  agg_info);
1759  }
1760  break;
1761  default:
1762  CHECK(false);
1763  break;
1764  }
1765  } catch (std::runtime_error& e) {
1766  // TODO(miyu): handle the case where chosen_bytes < 8
1767  LOG(ERROR) << e.what();
1768  }
1769  if (chosen_type.is_integer() || chosen_type.is_decimal()) {
1770  switch (chosen_bytes) {
1771  case 8:
1772  break;
1773  case 4: {
1774  int32_t ret = *reinterpret_cast<const int32_t*>(&agg_vals[agg_col_idx]);
1775  if (!(agg_info.agg_kind == kCOUNT && ret != agg_init_vals[agg_col_idx])) {
1776  agg_vals[agg_col_idx] = static_cast<int64_t>(ret);
1777  }
1778  break;
1779  }
1780  default:
1781  CHECK(false);
1782  }
1783  }
1784  if (kAVG == agg_info.agg_kind) {
1785  ++agg_col_idx;
1786  }
1787  } else {
1788  if (agg_info.agg_kind == kSAMPLE) {
1789  CHECK(!agg_info.sql_type.is_varlen())
1790  << "Interleaved bins reduction not supported for variable length "
1791  "arguments "
1792  "to SAMPLE";
1793  }
1794  if (agg_vals[agg_col_idx]) {
1795  if (agg_info.agg_kind == kSAMPLE) {
1796  continue;
1797  }
1798  CHECK_EQ(agg_vals[agg_col_idx], partial_bin_val);
1799  } else {
1800  agg_vals[agg_col_idx] = partial_bin_val;
1801  }
1802  }
1803  }
1804  }
1805  return discard_row;
1806 }
#define CHECK_EQ(x, y)
Definition: Logger.h:211
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:194
#define CHECK_GE(x, y)
Definition: Logger.h:216
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:134
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:130
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:203
#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 532 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(), i, isEmptyEntry(), generate_TableFunctionsFactory_init::j, kSAMPLE, query_mem_desc_, row_ptr_rowwise(), and targets_.

533  {
534  if (serialized_varlen_buffer.empty()) {
535  return;
536  }
537 
539  auto entry_count = query_mem_desc_.getEntryCount();
540  CHECK_GT(entry_count, size_t(0));
541  CHECK(buff_);
542 
543  // Row-wise iteration, consider moving to separate function
544  for (size_t i = 0; i < entry_count; ++i) {
545  if (isEmptyEntry(i, buff_)) {
546  continue;
547  }
548  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
549  const auto key_bytes_with_padding = align_to_int64(key_bytes);
550  auto rowwise_targets_ptr =
551  row_ptr_rowwise(buff_, query_mem_desc_, i) + key_bytes_with_padding;
552  size_t target_slot_idx = 0;
553  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
554  ++target_logical_idx) {
555  const auto& target_info = targets_[target_logical_idx];
556  if (target_info.sql_type.is_varlen() && target_info.is_agg) {
557  CHECK(target_info.agg_kind == kSAMPLE);
558  auto ptr1 = rowwise_targets_ptr;
559  auto slot_idx = target_slot_idx;
560  auto ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
561  auto offset = *reinterpret_cast<const int64_t*>(ptr1);
562 
563  const auto& elem_ti = target_info.sql_type.get_elem_type();
564  size_t length_to_elems =
565  target_info.sql_type.is_string() || target_info.sql_type.is_geometry()
566  ? 1
567  : elem_ti.get_size();
568  if (target_info.sql_type.is_geometry()) {
569  for (int j = 0; j < target_info.sql_type.get_physical_coord_cols(); j++) {
570  if (j > 0) {
571  ptr1 = ptr2 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 1);
572  ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 2);
573  slot_idx += 2;
574  length_to_elems = 4;
575  }
576  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
577  const auto& varlen_bytes_str = serialized_varlen_buffer[offset++];
578  const auto str_ptr =
579  reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
580  CHECK(ptr1);
581  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
582  CHECK(ptr2);
583  *reinterpret_cast<int64_t*>(ptr2) =
584  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
585  }
586  } else {
587  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
588  const auto& varlen_bytes_str = serialized_varlen_buffer[offset];
589  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
590  CHECK(ptr1);
591  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
592  CHECK(ptr2);
593  *reinterpret_cast<int64_t*>(ptr2) =
594  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
595  }
596  }
597 
598  rowwise_targets_ptr = advance_target_ptr_row_wise(
599  rowwise_targets_ptr, target_info, target_slot_idx, query_mem_desc_, false);
600  target_slot_idx = advance_slot(target_slot_idx, target_info, false);
601  }
602  }
603 
604  return;
605 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
const std::vector< TargetInfo > targets_
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:215
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:213
#define CHECK(condition)
Definition: Logger.h:203
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_

+ Here is the call graph for this function:

void ResultSetStorage::updateEntryCount ( const size_t  new_entry_count)
inline

Definition at line 122 of file ResultSetStorage.h.

References query_mem_desc_, and QueryMemoryDescriptor::setEntryCount().

122  {
123  query_mem_desc_.setEntryCount(new_entry_count);
124  }
void setEntryCount(const size_t val)
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

Friends And Related Function Documentation

friend class ResultSet
friend

Definition at line 236 of file ResultSetStorage.h.

friend class ResultSetManager
friend

Definition at line 237 of file ResultSetStorage.h.

Member Data Documentation

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 227 of file ResultSetStorage.h.

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

Definition at line 234 of file ResultSetStorage.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: