OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 size_t executor_id) 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 reduceOneApproxQuantileSlot (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 size_t executor_id) 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
 
const VarlenOutputInfogetVarlenOutputInfo () 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_
 
std::shared_ptr< VarlenOutputInfovarlen_output_info_
 

Friends

class ResultSet
 
class ResultSetManager
 

Detailed Description

Definition at line 96 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 53 of file ResultSetStorage.cpp.

57  : targets_(targets)
58  , query_mem_desc_(query_mem_desc)
59  , buff_(buff)
60  , 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 67 of file ResultSetStorage.cpp.

References CHECK, and count_distinct_sets_mapping_.

68  {
69  const auto it_ok = count_distinct_sets_mapping_.emplace(remote_ptr, ptr);
70  CHECK(it_ok.second);
71 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
#define CHECK(condition)
Definition: Logger.h:291
size_t ResultSetStorage::binSearchRowCount ( ) const
private

Definition at line 2575 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(), heavyai::Projection, ResultSet::query_mem_desc_, and row_ptr_rowwise().

2575  {
2576  // Note that table function result sets should never use this path as the row count
2577  // can be known statically (as the output buffers do not contain empty entries)
2580 
2581  if (!query_mem_desc_.getEntryCount()) {
2582  return 0;
2583  }
2584 
2586  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2587  return reinterpret_cast<const int64_t*>(buff_)[idx] == EMPTY_KEY_64;
2588  });
2589  } else {
2590  return make_bin_search(0, query_mem_desc_.getEntryCount(), [this](size_t idx) {
2591  const auto keys_ptr = row_ptr_rowwise(buff_, query_mem_desc_, idx);
2592  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2593  });
2594  }
2595 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
#define EMPTY_KEY_64
size_t make_bin_search(size_t l, size_t r, T &&is_empty_fn)
Projection
Definition: enums.h:58
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:291
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 505 of file ResultSetReduction.cpp.

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

Referenced by reduceEntriesNoCollisionsColWise().

507  {
509  for (size_t group_idx = 0; group_idx < query_mem_desc_.getGroupbyColCount();
510  group_idx++) {
511  // if the column corresponds to a group key
512  const auto column_offset_bytes =
514  auto lhs_key_ptr = this_buff + column_offset_bytes;
515  auto rhs_key_ptr = that_buff + column_offset_bytes;
516  switch (query_mem_desc_.groupColWidth(group_idx)) {
517  case 8:
518  *(reinterpret_cast<int64_t*>(lhs_key_ptr) + entry_idx) =
519  *(reinterpret_cast<const int64_t*>(rhs_key_ptr) + entry_idx);
520  break;
521  case 4:
522  *(reinterpret_cast<int32_t*>(lhs_key_ptr) + entry_idx) =
523  *(reinterpret_cast<const int32_t*>(rhs_key_ptr) + entry_idx);
524  break;
525  case 2:
526  *(reinterpret_cast<int16_t*>(lhs_key_ptr) + entry_idx) =
527  *(reinterpret_cast<const int16_t*>(rhs_key_ptr) + entry_idx);
528  break;
529  case 1:
530  *(reinterpret_cast<int8_t*>(lhs_key_ptr) + entry_idx) =
531  *(reinterpret_cast<const int8_t*>(rhs_key_ptr) + entry_idx);
532  break;
533  default:
534  CHECK(false);
535  break;
536  }
537  }
538 }
int8_t groupColWidth(const size_t key_idx) const
size_t getGroupbyColCount() const
#define CHECK(condition)
Definition: Logger.h:291
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 1195 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_.

1195  {
1197  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1198  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1199  const auto key_count = query_mem_desc_.getGroupbyColCount();
1200  CHECK_EQ(slot_count + key_count, entry.size());
1201  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1202 
1203  for (size_t i = 0; i < key_count; i++) {
1204  const auto key_offset = key_offset_colwise(0, i, 1);
1205  this_buff[key_offset] = entry[i];
1206  }
1207 
1208  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1209  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1210  this_buff[slot_offset] = entry[key_count + i];
1211  }
1212 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:291
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 1142 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_.

1142  {
1143  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1144  const auto key_count = query_mem_desc_.getGroupbyColCount();
1145  CHECK_EQ(slot_count + key_count, entry.size());
1146  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1148  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1149  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1150  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1151  for (size_t i = 0; i < key_count; ++i) {
1152  this_buff[key_off + i] = entry[i];
1153  }
1154  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1155  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1156  this_buff[first_slot_off + i] = entry[key_count + i];
1157  }
1158 }
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:301
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:291
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

size_t ResultSetStorage::getEntryCount ( ) const
inline

Definition at line 114 of file ResultSetStorage.h.

References QueryMemoryDescriptor::getEntryCount(), and query_mem_desc_.

114 { 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 63 of file ResultSetStorage.cpp.

References buff_.

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

63  {
64  return buff_;
65 }

+ Here is the caller graph for this function:

const VarlenOutputInfo* ResultSetStorage::getVarlenOutputInfo ( ) const
inlineprivate

Definition at line 223 of file ResultSetStorage.h.

References varlen_output_info_.

223  {
224  return varlen_output_info_.get();
225  }
std::shared_ptr< VarlenOutputInfo > varlen_output_info_
void ResultSetStorage::initializeBaselineValueSlots ( int64_t *  this_entry_slots) const
private

Definition at line 1234 of file ResultSetReduction.cpp.

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

1234  {
1235  CHECK(entry_slots);
1237  size_t slot_off = 0;
1238  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1239  entry_slots[slot_off] = target_init_vals_[j];
1240  slot_off += query_mem_desc_.getEntryCount();
1241  }
1242  } else {
1243  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1244  entry_slots[j] = target_init_vals_[j];
1245  }
1246  }
1247 }
std::vector< int64_t > target_init_vals_
#define CHECK(condition)
Definition: Logger.h:291
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeColWise ( ) const
private

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

1214  {
1215  const auto key_count = query_mem_desc_.getGroupbyColCount();
1216  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1218  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1219  const auto first_key_off =
1221  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1222  this_buff[first_key_off + i] = EMPTY_KEY_64;
1223  }
1224  }
1225  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1226  const auto first_val_off =
1227  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1228  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1229  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1230  }
1231  }
1232 }
#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:291
QueryMemoryDescriptor query_mem_desc_

+ Here is the call graph for this function:

void ResultSetStorage::initializeRowWise ( ) const
private

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

1160  {
1161  const auto key_count = query_mem_desc_.getGroupbyColCount();
1162  const auto row_size = get_row_bytes(query_mem_desc_);
1163  CHECK_EQ(row_size % 8, 0u);
1164  const auto key_bytes_with_padding =
1168  case 4: {
1169  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1170  auto row_ptr = buff_ + i * row_size;
1171  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1172  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1173  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1174  slot_ptr[j] = target_init_vals_[j];
1175  }
1176  }
1177  break;
1178  }
1179  case 8: {
1180  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1181  auto row_ptr = buff_ + i * row_size;
1182  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1183  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1184  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1185  slot_ptr[j] = target_init_vals_[j];
1186  }
1187  }
1188  break;
1189  }
1190  default:
1191  CHECK(false);
1192  }
1193 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:291
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 2457 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(), heavyai::GroupByPerfectHash, QueryMemoryDescriptor::hasKeylessHash(), heavyai::NonGroupedAggregate, ResultSet::query_mem_desc_, read_int_from_buff(), and row_ptr_rowwise().

Referenced by reduceOneEntryBaseline(), and rewriteAggregateBufferOffsets().

2457  {
2460  return false;
2461  }
2463  return isEmptyEntryColumnar(entry_idx, buff);
2464  }
2469  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2470  target_init_vals_.size());
2471  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2472  const auto target_slot_off = result_set::get_byteoff_of_slot(
2474  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
2478  } else {
2479  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
2481  case 4:
2484  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
2485  case 8:
2486  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
2487  default:
2488  CHECK(false);
2489  return true;
2490  }
2491  }
2492 }
GroupByPerfectHash
Definition: enums.h:58
#define EMPTY_KEY_64
NonGroupedAggregate
Definition: enums.h:58
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:306
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:303
#define CHECK(condition)
Definition: Logger.h:291
#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 2597 of file ResultSetIteration.cpp.

2597  {
2598  return isEmptyEntry(entry_idx, buff_);
2599 }
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 2498 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(), heavyai::GroupByPerfectHash, QueryMemoryDescriptor::groupColWidth(), QueryMemoryDescriptor::hasKeylessHash(), heavyai::NonGroupedAggregate, heavyai::Projection, ResultSet::query_mem_desc_, read_int_from_buff(), heavyai::TableFunction, and ResultSet::targets_.

Referenced by reduceEntriesNoCollisionsColWise().

2499  {
2503  return false;
2504  }
2506  // For table functions the entry count should always be set to the actual output size
2507  // (i.e. there are not empty entries), so just assume value is non-empty
2508  CHECK_LT(entry_idx, getEntryCount());
2509  return false;
2510  }
2515  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
2516  target_init_vals_.size());
2517  const auto col_buff = advance_col_buff_to_slot(
2519  const auto entry_buff =
2520  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
2522  return read_int_from_buff(entry_buff,
2526  } else {
2527  // it's enough to find the first group key which is empty
2529  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
2530  } else {
2532  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
2533  switch (query_mem_desc_.groupColWidth(0)) {
2534  case 8:
2535  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
2536  case 4:
2537  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
2538  case 2:
2539  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
2540  case 1:
2541  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
2542  default:
2543  CHECK(false);
2544  }
2545  }
2546  return false;
2547  }
2548  return false;
2549 }
GroupByPerfectHash
Definition: enums.h:58
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
NonGroupedAggregate
Definition: enums.h:58
std::vector< int64_t > target_init_vals_
#define CHECK_GE(x, y)
Definition: Logger.h:306
Projection
Definition: enums.h:58
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
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)
TableFunction
Definition: enums.h:58
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
size_t getEntryCount() const
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:291
#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 73 of file ResultSetStorage.cpp.

References count_distinct_sets_mapping_.

73  {
74  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
75  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
76  // remote ptr that do not not exists. Return 0 if no pointer found
77  if (it == count_distinct_sets_mapping_.end()) {
78  return int64_t(0);
79  }
80  return it->second;
81 }
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 940 of file ResultSetReduction.cpp.

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

941  {
943  CHECK_GT(new_entry_count, query_mem_desc_.getEntryCount());
944  auto new_buff_i64 = reinterpret_cast<int64_t*>(new_buff);
945  const auto key_count = query_mem_desc_.getGroupbyColCount();
948  const auto src_buff = reinterpret_cast<const int64_t*>(buff_);
949  const auto row_qw_count = get_row_qw_count(query_mem_desc_);
950  const auto key_byte_width = query_mem_desc_.getEffectiveKeyWidth();
951 
953  const size_t thread_count = cpu_threads();
954  std::vector<std::future<void>> move_threads;
955 
956  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
957  const auto thread_entry_count =
958  (query_mem_desc_.getEntryCount() + thread_count - 1) / thread_count;
959  const auto start_index = thread_idx * thread_entry_count;
960  const auto end_index =
961  std::min(start_index + thread_entry_count, query_mem_desc_.getEntryCount());
962  move_threads.emplace_back(std::async(
964  [this,
965  src_buff,
966  new_buff_i64,
967  new_entry_count,
968  start_index,
969  end_index,
970  key_count,
971  row_qw_count,
972  key_byte_width] {
973  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
974  moveOneEntryToBuffer<KeyType>(entry_idx,
975  new_buff_i64,
976  new_entry_count,
977  key_count,
978  row_qw_count,
979  src_buff,
980  key_byte_width);
981  }
982  }));
983  }
984  for (auto& move_thread : move_threads) {
985  move_thread.wait();
986  }
987  for (auto& move_thread : move_threads) {
988  move_thread.get();
989  }
990  } else {
991  for (size_t entry_idx = 0; entry_idx < query_mem_desc_.getEntryCount(); ++entry_idx) {
992  moveOneEntryToBuffer<KeyType>(entry_idx,
993  new_buff_i64,
994  new_entry_count,
995  key_count,
996  row_qw_count,
997  src_buff,
998  key_byte_width);
999  }
1000  }
1001 }
size_t getEffectiveKeyWidth() const
#define CHECK_GT(x, y)
Definition: Logger.h:305
future< Result > async(Fn &&fn, Args &&...args)
size_t getGroupbyColCount() const
QueryDescriptionType getQueryDescriptionType() const
GroupByBaselineHash
Definition: enums.h:58
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:291
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
int cpu_threads()
Definition: thread_count.h:25
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 1004 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_.

1010  {
1011  const auto key_off =
1013  ? key_offset_colwise(entry_index, 0, query_mem_desc_.getEntryCount())
1014  : row_qw_count * entry_index;
1015  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
1016  if (*key_ptr == get_empty_key<KeyType>()) {
1017  return;
1018  }
1019  int64_t* new_entries_ptr{nullptr};
1021  const auto key =
1022  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
1023  new_entries_ptr =
1024  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
1025  } else {
1026  new_entries_ptr = get_group_value(new_buff_i64,
1027  new_entry_count,
1028  &src_buff[key_off],
1029  key_count,
1030  key_byte_width,
1031  row_qw_count);
1032  }
1033  CHECK(new_entries_ptr);
1034  fill_slots(new_entries_ptr,
1035  new_entry_count,
1036  src_buff,
1037  entry_index,
1039  query_mem_desc_);
1040 }
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:291
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 size_t  executor_id 
) const

Definition at line 202 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlotSingleValue().

205  {
206  auto entry_count = query_mem_desc_.getEntryCount();
207  CHECK_GT(entry_count, size_t(0));
215  }
216  const auto that_entry_count = that.query_mem_desc_.getEntryCount();
219  CHECK_GE(entry_count, that_entry_count);
220  break;
221  default:
222  CHECK_EQ(entry_count, that_entry_count);
223  }
224  auto this_buff = buff_;
225  CHECK(this_buff);
226  auto that_buff = that.buff_;
227  CHECK(that_buff);
230  if (!serialized_varlen_buffer.empty()) {
231  throw std::runtime_error(
232  "Projection of variable length targets with baseline hash group by is not yet "
233  "supported in Distributed mode");
234  }
235  if (use_multithreaded_reduction(that_entry_count)) {
236  const size_t thread_count = cpu_threads();
237  std::vector<std::future<void>> reduction_threads;
238  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
239  const auto thread_entry_count =
240  (that_entry_count + thread_count - 1) / thread_count;
241  const auto start_index = thread_idx * thread_entry_count;
242  const auto end_index =
243  std::min(start_index + thread_entry_count, that_entry_count);
244  reduction_threads.emplace_back(std::async(
246  [this,
247  this_buff,
248  that_buff,
249  start_index,
250  end_index,
251  that_entry_count,
252  executor_id,
253  &reduction_code,
254  &that] {
255  if (reduction_code.ir_reduce_loop) {
256  run_reduction_code(executor_id,
257  reduction_code,
258  this_buff,
259  that_buff,
260  start_index,
261  end_index,
262  that_entry_count,
264  &that.query_mem_desc_,
265  nullptr);
266  } else {
267  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
269  this_buff, that_buff, entry_idx, that_entry_count, that);
270  }
271  }
272  }));
273  }
274  for (auto& reduction_thread : reduction_threads) {
275  reduction_thread.wait();
276  }
277  for (auto& reduction_thread : reduction_threads) {
278  reduction_thread.get();
279  }
280  } else {
281  if (reduction_code.ir_reduce_loop) {
282  run_reduction_code(executor_id,
283  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,
316  &executor_id] {
318  this_buff,
319  that_buff,
320  that,
321  start_index,
322  end_index,
323  serialized_varlen_buffer,
324  executor_id);
325  }));
326  } else {
327  reduction_threads.emplace_back(std::async(std::launch::async,
328  [this,
329  this_buff,
330  that_buff,
331  start_index,
332  end_index,
333  that_entry_count,
334  executor_id,
335  &reduction_code,
336  &that,
337  &serialized_varlen_buffer] {
338  CHECK(reduction_code.ir_reduce_loop);
340  executor_id,
341  reduction_code,
342  this_buff,
343  that_buff,
344  start_index,
345  end_index,
346  that_entry_count,
348  &that.query_mem_desc_,
349  &serialized_varlen_buffer);
350  }));
351  }
352  }
353  for (auto& reduction_thread : reduction_threads) {
354  reduction_thread.wait();
355  }
356  for (auto& reduction_thread : reduction_threads) {
357  reduction_thread.get();
358  }
359  } else {
362  that_buff,
363  that,
364  0,
366  serialized_varlen_buffer,
367  executor_id);
368  } else {
369  CHECK(reduction_code.ir_reduce_loop);
370  run_reduction_code(executor_id,
371  reduction_code,
372  this_buff,
373  that_buff,
374  0,
375  entry_count,
376  that_entry_count,
378  &that.query_mem_desc_,
379  &serialized_varlen_buffer);
380  }
381  }
382 }
GroupByPerfectHash
Definition: enums.h:58
#define CHECK_EQ(x, y)
Definition: Logger.h:301
NonGroupedAggregate
Definition: enums.h:58
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:306
#define CHECK_GT(x, y)
Definition: Logger.h:305
future< Result > async(Fn &&fn, Args &&...args)
QueryDescriptionType getQueryDescriptionType() const
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 size_t executor_id) const
GroupByBaselineHash
Definition: enums.h:58
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:291
void run_reduction_code(const size_t executor_id, 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)
int cpu_threads()
Definition: thread_count.h:25
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 size_t  executor_id 
) const
private

Definition at line 406 of file ResultSetReduction.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 1600 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlot().

1603  {
1605  static_assert(sizeof(int64_t) == sizeof(quantile::TDigest*));
1606  auto* incoming = *reinterpret_cast<quantile::TDigest* const*>(that_ptr1);
1607  CHECK(incoming) << "this_ptr1=" << (void*)this_ptr1
1608  << ", that_ptr1=" << (void const*)that_ptr1
1609  << ", target_logical_idx=" << target_logical_idx;
1610  if (incoming->centroids().capacity()) {
1611  auto* accumulator = *reinterpret_cast<quantile::TDigest**>(this_ptr1);
1612  CHECK(accumulator) << "this_ptr1=" << (void*)this_ptr1
1613  << ", that_ptr1=" << (void const*)that_ptr1
1614  << ", target_logical_idx=" << target_logical_idx;
1615  accumulator->allocate();
1616  accumulator->mergeTDigest(*incoming);
1617  }
1618 }
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
#define CHECK(condition)
Definition: Logger.h:291
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 1620 of file ResultSetReduction.cpp.

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

Referenced by reduceOneSlot().

1623  {
1625  const auto& old_count_distinct_desc =
1626  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1627  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1628  const auto& new_count_distinct_desc =
1629  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1630  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1631  CHECK(this_ptr1 && that_ptr1);
1632  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1633  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1635  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1636 }
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:303
#define CHECK(condition)
Definition: Logger.h:291
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 829 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(), heavyai::GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), isEmptyEntry(), key_offset_colwise(), anonymous_namespace{ResultSetReduction.cpp}::make_key(), query_mem_desc_, and reduceOneEntrySlotsBaseline().

Referenced by reduce().

833  {
835  check_watchdog_with_seed(that_entry_idx);
836  }
837  const auto key_count = query_mem_desc_.getGroupbyColCount();
842  const auto key_off =
844  if (isEmptyEntry(that_entry_idx, that_buff)) {
845  return;
846  }
847  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
848  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
849  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
850  auto [this_entry_slots, empty_entry] = get_group_value_columnar_reduction(
851  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
852  CHECK(this_entry_slots);
853  if (empty_entry) {
854  fill_slots(this_entry_slots,
856  that_buff_i64,
857  that_entry_idx,
858  that_entry_count,
860  return;
861  }
863  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
864 }
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:81
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)
GroupByBaselineHash
Definition: enums.h:58
#define CHECK(condition)
Definition: Logger.h:291
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 866 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().

870  {
872  const auto key_count = query_mem_desc_.getGroupbyColCount();
873  size_t j = 0;
874  size_t init_agg_val_idx = 0;
875  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
876  ++target_logical_idx) {
877  const auto& target_info = targets_[target_logical_idx];
878  const auto that_slot_off = slot_offset_colwise(
879  that_entry_idx, init_agg_val_idx, key_count, that_entry_count);
880  const auto this_slot_off = init_agg_val_idx * query_mem_desc_.getEntryCount();
881  reduceOneSlotBaseline(this_entry_slots,
882  this_slot_off,
883  that_buff,
884  that_entry_count,
885  that_slot_off,
886  target_info,
887  target_logical_idx,
888  j,
889  init_agg_val_idx,
890  that);
892  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
893  } else {
894  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
895  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
896  }
897  }
898  j = advance_slot(j, target_info, false);
899  }
900 }
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:291
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 1454 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_QUANTILE, kAVG, kCOUNT, kCOUNT_IF, kMAX, kMIN, kSAMPLE, kSINGLE_VALUE, kSUM, kSUM_IF, LOG, query_mem_desc_, reduceOneApproxQuantileSlot(), reduceOneCountDistinctSlot(), reduceOneSlotSingleValue(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, QueryMemoryDescriptor::targetGroupbyIndicesSize(), toString(), and UNREACHABLE.

Referenced by reduceEntriesNoCollisionsColWise(), and reduceOneSlotBaseline().

1465  {
1467  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1468  return;
1469  }
1470  }
1471  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1472  const bool float_argument_input = takes_float_argument(target_info);
1473  const auto chosen_bytes = result_set::get_width_for_slot(
1474  target_slot_idx, float_argument_input, query_mem_desc_);
1475  int64_t init_val = target_init_vals_[init_agg_val_idx]; // skip_val for nullable types
1476 
1477  if (target_info.is_agg && target_info.agg_kind == kSINGLE_VALUE) {
1479  this_ptr1, target_info, target_logical_idx, init_agg_val_idx, that_ptr1);
1480  } else if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1481  switch (target_info.agg_kind) {
1482  case kCOUNT:
1483  case kCOUNT_IF:
1484  case kAPPROX_COUNT_DISTINCT: {
1485  if (is_distinct_target(target_info)) {
1486  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1487  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1488  break;
1489  }
1490  CHECK_EQ(int64_t(0), init_val);
1491  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1492  break;
1493  }
1494  case kAVG: {
1495  // Ignore float argument compaction for count component for fear of its overflow
1496  AGGREGATE_ONE_COUNT(this_ptr2,
1497  that_ptr2,
1498  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1499  }
1500  // fall thru
1501  case kSUM:
1502  case kSUM_IF: {
1504  sum, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1505  break;
1506  }
1507  case kMIN: {
1508  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1510  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1511  } else {
1513  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1514  }
1515  break;
1516  }
1517  case kMAX: {
1518  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1520  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1521  } else {
1523  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1524  }
1525  break;
1526  }
1527  case kAPPROX_QUANTILE:
1528  CHECK_EQ(static_cast<int8_t>(sizeof(int64_t)), chosen_bytes);
1529  reduceOneApproxQuantileSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1530  break;
1531  default:
1532  UNREACHABLE() << toString(target_info.agg_kind);
1533  }
1534  } else {
1535  switch (chosen_bytes) {
1536  case 1: {
1538  const auto rhs_proj_col = *reinterpret_cast<const int8_t*>(that_ptr1);
1539  if (rhs_proj_col != init_val) {
1540  *reinterpret_cast<int8_t*>(this_ptr1) = rhs_proj_col;
1541  }
1542  break;
1543  }
1544  case 2: {
1546  const auto rhs_proj_col = *reinterpret_cast<const int16_t*>(that_ptr1);
1547  if (rhs_proj_col != init_val) {
1548  *reinterpret_cast<int16_t*>(this_ptr1) = rhs_proj_col;
1549  }
1550  break;
1551  }
1552  case 4: {
1553  CHECK(target_info.agg_kind != kSAMPLE ||
1555  const auto rhs_proj_col = *reinterpret_cast<const int32_t*>(that_ptr1);
1556  if (rhs_proj_col != init_val) {
1557  *reinterpret_cast<int32_t*>(this_ptr1) = rhs_proj_col;
1558  }
1559  break;
1560  }
1561  case 8: {
1562  auto rhs_proj_col = *reinterpret_cast<const int64_t*>(that_ptr1);
1563  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) &&
1564  !serialized_varlen_buffer.empty()) {
1565  size_t length_to_elems{0};
1566  if (target_info.sql_type.is_geometry()) {
1567  // TODO: Assumes hard-coded sizes for geometry targets
1568  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1569  } else {
1570  const auto& elem_ti = target_info.sql_type.get_elem_type();
1571  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1572  }
1573 
1574  CHECK_LT(static_cast<size_t>(rhs_proj_col), serialized_varlen_buffer.size());
1575  const auto& varlen_bytes_str = serialized_varlen_buffer[rhs_proj_col];
1576  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
1577  *reinterpret_cast<int64_t*>(this_ptr1) =
1578  reinterpret_cast<const int64_t>(str_ptr);
1579  *reinterpret_cast<int64_t*>(this_ptr2) =
1580  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
1581  } else {
1582  if (rhs_proj_col != init_val) {
1583  *reinterpret_cast<int64_t*>(this_ptr1) = rhs_proj_col;
1584  }
1585  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen())) {
1586  CHECK(this_ptr2 && that_ptr2);
1587  *reinterpret_cast<int64_t*>(this_ptr2) =
1588  *reinterpret_cast<const int64_t*>(that_ptr2);
1589  }
1590  }
1591 
1592  break;
1593  }
1594  default:
1595  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1596  }
1597  }
1598 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:52
#define LOG(tag)
Definition: Logger.h:285
bool is_varlen() const
Definition: sqltypes.h:631
#define UNREACHABLE()
Definition: Logger.h:338
void reduceOneApproxQuantileSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
Definition: sqldefs.h:78
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:50
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:80
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:102
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
std::string toString(const Executor::ExtModuleKinds &kind)
Definition: Execute.h:1703
SQLAgg agg_kind
Definition: TargetInfo.h:51
#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:303
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:81
#define CHECK(condition)
Definition: Logger.h:291
bool is_geometry() const
Definition: sqltypes.h:597
#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:561
Definition: sqldefs.h:79
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:977
Definition: sqldefs.h:77
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 902 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().

911  {
913  int8_t* this_ptr2{nullptr};
914  const int8_t* that_ptr2{nullptr};
915  if (target_info.is_agg &&
916  (target_info.agg_kind == kAVG ||
917  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
918  const auto this_count_off = query_mem_desc_.getEntryCount();
919  const auto that_count_off = that_entry_count;
920  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
921  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
922  }
923  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
924  this_ptr2,
925  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
926  that_ptr2,
927  target_info,
928  target_logical_idx,
929  target_slot_idx,
930  init_agg_val_idx,
931  that,
932  target_slot_idx, // dummy, for now
933  {});
934 }
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:52
bool is_varlen() const
Definition: sqltypes.h:631
bool is_agg
Definition: TargetInfo.h:50
SQLAgg agg_kind
Definition: TargetInfo.h:51
#define CHECK(condition)
Definition: Logger.h:291
Definition: sqldefs.h:77
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 1406 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().

1410  {
1411  const bool float_argument_input = takes_float_argument(target_info);
1412  const auto chosen_bytes = result_set::get_width_for_slot(
1413  target_slot_idx, float_argument_input, query_mem_desc_);
1414  auto init_val = target_init_vals_[init_agg_val_idx];
1415 
1416  auto reduce = [&](auto const& size_tag) {
1417  using CastTarget = std::decay_t<decltype(size_tag)>;
1418  const auto lhs_proj_col = *reinterpret_cast<const CastTarget*>(this_ptr1);
1419  const auto rhs_proj_col = *reinterpret_cast<const CastTarget*>(that_ptr1);
1420  if (rhs_proj_col == init_val) {
1421  // ignore
1422  } else if (lhs_proj_col == init_val) {
1423  *reinterpret_cast<CastTarget*>(this_ptr1) = rhs_proj_col;
1424  } else if (lhs_proj_col != rhs_proj_col) {
1425  throw std::runtime_error("Multiple distinct values encountered");
1426  }
1427  };
1428 
1429  switch (chosen_bytes) {
1430  case 1: {
1432  reduce(int8_t());
1433  break;
1434  }
1435  case 2: {
1437  reduce(int16_t());
1438  break;
1439  }
1440  case 4: {
1441  reduce(int32_t());
1442  break;
1443  }
1444  case 8: {
1445  CHECK(!target_info.sql_type.is_varlen());
1446  reduce(int64_t());
1447  break;
1448  }
1449  default:
1450  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1451  }
1452 }
std::vector< int64_t > target_init_vals_
bool isLogicalSizedColumnsAllowed() const
SQLTypeInfo sql_type
Definition: TargetInfo.h:52
#define LOG(tag)
Definition: Logger.h:285
bool is_varlen() const
Definition: sqltypes.h:631
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
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 size_t executor_id) const
#define CHECK(condition)
Definition: Logger.h:291
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 1638 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, kCOUNT_IF, kMAX, kMIN, kSAMPLE, kSUM, kSUM_IF, LOG, and takes_float_argument().

Referenced by QueryExecutionContext::groupBufferToDeinterleavedResults().

1645  {
1646  const size_t agg_col_count{agg_vals.size()};
1647  const auto row_size = query_mem_desc.getRowSize();
1648  CHECK_EQ(agg_col_count, query_mem_desc.getSlotCount());
1649  CHECK_GE(agg_col_count, targets.size());
1650  CHECK_EQ(is_columnar, query_mem_desc.didOutputColumnar());
1651  CHECK(query_mem_desc.hasKeylessHash());
1652  std::vector<int64_t> partial_agg_vals(agg_col_count, 0);
1653  bool discard_row = true;
1654  for (int8_t warp_idx = 0; warp_idx < warp_count; ++warp_idx) {
1655  bool discard_partial_result = true;
1656  for (size_t target_idx = 0, agg_col_idx = 0;
1657  target_idx < targets.size() && agg_col_idx < agg_col_count;
1658  ++target_idx, ++agg_col_idx) {
1659  const auto& agg_info = targets[target_idx];
1660  const bool float_argument_input = takes_float_argument(agg_info);
1661  const auto chosen_bytes = float_argument_input
1662  ? sizeof(float)
1663  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1664  auto partial_bin_val = get_component(
1665  row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx), chosen_bytes);
1666  partial_agg_vals[agg_col_idx] = partial_bin_val;
1667  if (is_distinct_target(agg_info)) {
1668  CHECK_EQ(int8_t(1), warp_count);
1669  CHECK(agg_info.is_agg &&
1670  (agg_info.agg_kind == kCOUNT || agg_info.agg_kind == kCOUNT_IF ||
1671  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1672  partial_bin_val = count_distinct_set_size(
1673  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1674  if (replace_bitmap_ptr_with_bitmap_sz) {
1675  partial_agg_vals[agg_col_idx] = partial_bin_val;
1676  }
1677  }
1678  if (kAVG == agg_info.agg_kind) {
1679  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1680  ++agg_col_idx;
1681  partial_bin_val = partial_agg_vals[agg_col_idx] =
1682  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1683  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1684  }
1685  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1686  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1687  CHECK(agg_info.is_agg);
1688  discard_partial_result = false;
1689  }
1690  }
1691  row_ptr += row_size;
1692  if (discard_partial_result) {
1693  continue;
1694  }
1695  discard_row = false;
1696  for (size_t target_idx = 0, agg_col_idx = 0;
1697  target_idx < targets.size() && agg_col_idx < agg_col_count;
1698  ++target_idx, ++agg_col_idx) {
1699  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1700  const auto& agg_info = targets[target_idx];
1701  const bool float_argument_input = takes_float_argument(agg_info);
1702  const auto chosen_bytes = float_argument_input
1703  ? sizeof(float)
1704  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1705  const auto& chosen_type = get_compact_type(agg_info);
1706  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1707  try {
1708  switch (agg_info.agg_kind) {
1709  case kCOUNT:
1710  case kCOUNT_IF:
1713  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1714  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1715  agg_init_vals[agg_col_idx],
1716  chosen_bytes,
1717  agg_info);
1718  break;
1719  case kAVG:
1720  // Ignore float argument compaction for count component for fear of its
1721  // overflow
1723  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1724  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1725  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1726  // fall thru
1727  case kSUM:
1728  case kSUM_IF:
1730  sum,
1731  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1732  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1733  agg_init_vals[agg_col_idx],
1734  chosen_bytes,
1735  agg_info);
1736  break;
1737  case kMIN:
1738  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1740  min,
1741  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1742  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1743  agg_init_vals[agg_col_idx],
1744  chosen_bytes,
1745  agg_info);
1746  } else {
1748  min,
1749  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1750  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1751  agg_init_vals[agg_col_idx],
1752  chosen_bytes,
1753  agg_info);
1754  }
1755  break;
1756  case kMAX:
1757  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1759  max,
1760  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1761  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1762  agg_init_vals[agg_col_idx],
1763  chosen_bytes,
1764  agg_info);
1765  } else {
1767  max,
1768  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1769  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1770  agg_init_vals[agg_col_idx],
1771  chosen_bytes,
1772  agg_info);
1773  }
1774  break;
1775  default:
1776  CHECK(false);
1777  break;
1778  }
1779  } catch (std::runtime_error& e) {
1780  // TODO(miyu): handle the case where chosen_bytes < 8
1781  LOG(ERROR) << e.what();
1782  }
1783  if (chosen_type.is_integer() || chosen_type.is_decimal()) {
1784  switch (chosen_bytes) {
1785  case 8:
1786  break;
1787  case 4: {
1788  int32_t ret = *reinterpret_cast<const int32_t*>(&agg_vals[agg_col_idx]);
1789  if (!(shared::is_any<kCOUNT, kCOUNT_IF>(agg_info.agg_kind) &&
1790  ret != agg_init_vals[agg_col_idx])) {
1791  agg_vals[agg_col_idx] = static_cast<int64_t>(ret);
1792  }
1793  break;
1794  }
1795  default:
1796  CHECK(false);
1797  }
1798  }
1799  if (kAVG == agg_info.agg_kind) {
1800  ++agg_col_idx;
1801  }
1802  } else {
1803  if (agg_info.agg_kind == kSAMPLE) {
1804  CHECK(!agg_info.sql_type.is_varlen())
1805  << "Interleaved bins reduction not supported for variable length "
1806  "arguments "
1807  "to SAMPLE";
1808  }
1809  if (agg_vals[agg_col_idx]) {
1810  if (agg_info.agg_kind == kSAMPLE) {
1811  continue;
1812  }
1813  CHECK_EQ(agg_vals[agg_col_idx], partial_bin_val);
1814  } else {
1815  agg_vals[agg_col_idx] = partial_bin_val;
1816  }
1817  }
1818  }
1819  }
1820  return discard_row;
1821 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
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:285
#define CHECK_GE(x, y)
Definition: Logger.h:306
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
size_t getColOnlyOffInBytes(const size_t col_idx) const
Definition: sqldefs.h:78
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:80
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:102
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:81
#define AGGREGATE_ONE_NULLABLE_COUNT(val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK(condition)
Definition: Logger.h:291
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL(agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
Definition: sqldefs.h:79
Definition: sqldefs.h:77
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 542 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_.

543  {
544  if (serialized_varlen_buffer.empty()) {
545  return;
546  }
547 
549  auto entry_count = query_mem_desc_.getEntryCount();
550  CHECK_GT(entry_count, size_t(0));
551  CHECK(buff_);
552 
553  // Row-wise iteration, consider moving to separate function
554  for (size_t i = 0; i < entry_count; ++i) {
555  if (isEmptyEntry(i, buff_)) {
556  continue;
557  }
558  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
559  const auto key_bytes_with_padding = align_to_int64(key_bytes);
560  auto rowwise_targets_ptr =
561  row_ptr_rowwise(buff_, query_mem_desc_, i) + key_bytes_with_padding;
562  size_t target_slot_idx = 0;
563  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
564  ++target_logical_idx) {
565  const auto& target_info = targets_[target_logical_idx];
566  if (target_info.sql_type.is_varlen() && target_info.is_agg) {
567  CHECK(target_info.agg_kind == kSAMPLE);
568  auto ptr1 = rowwise_targets_ptr;
569  auto slot_idx = target_slot_idx;
570  auto ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx);
571  auto offset = *reinterpret_cast<const int64_t*>(ptr1);
572 
573  const auto& elem_ti = target_info.sql_type.get_elem_type();
574  size_t length_to_elems =
575  target_info.sql_type.is_string() || target_info.sql_type.is_geometry()
576  ? 1
577  : elem_ti.get_size();
578  if (target_info.sql_type.is_geometry()) {
579  for (int j = 0; j < target_info.sql_type.get_physical_coord_cols(); j++) {
580  if (j > 0) {
581  ptr1 = ptr2 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 1);
582  ptr2 = ptr1 + query_mem_desc_.getPaddedSlotWidthBytes(slot_idx + 2);
583  slot_idx += 2;
584  length_to_elems = 4;
585  }
586  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
587  const auto& varlen_bytes_str = serialized_varlen_buffer[offset++];
588  const auto str_ptr =
589  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  } else {
597  CHECK_LT(static_cast<size_t>(offset), serialized_varlen_buffer.size());
598  const auto& varlen_bytes_str = serialized_varlen_buffer[offset];
599  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
600  CHECK(ptr1);
601  *reinterpret_cast<int64_t*>(ptr1) = reinterpret_cast<const int64_t>(str_ptr);
602  CHECK(ptr2);
603  *reinterpret_cast<int64_t*>(ptr2) =
604  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
605  }
606  }
607 
608  rowwise_targets_ptr = advance_target_ptr_row_wise(
609  rowwise_targets_ptr, target_info, target_slot_idx, query_mem_desc_, false);
610  target_slot_idx = advance_slot(target_slot_idx, target_info, false);
611  }
612  }
613 
614  return;
615 }
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:305
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:303
#define CHECK(condition)
Definition: Logger.h:291
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 128 of file ResultSetStorage.h.

References query_mem_desc_, and QueryMemoryDescriptor::setEntryCount().

128  {
129  query_mem_desc_.setEntryCount(new_entry_count);
130  }
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 250 of file ResultSetStorage.h.

friend class ResultSetManager
friend

Definition at line 251 of file ResultSetStorage.h.

Member Data Documentation

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 238 of file ResultSetStorage.h.

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

Definition at line 245 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
std::shared_ptr<VarlenOutputInfo> ResultSetStorage::varlen_output_info_
private

Definition at line 248 of file ResultSetStorage.h.

Referenced by getVarlenOutputInfo().


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