OmniSciDB  c07336695a
ResultSetStorage Class Reference

#include <ResultSet.h>

+ Collaboration diagram for ResultSetStorage:

Public Member Functions

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

Static Public Member Functions

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

Private Member Functions

void reduceEntriesNoCollisionsColWise (int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const size_t start_index, const size_t end_index, const std::vector< std::string > &serialized_varlen_buffer) const
 
void copyKeyColWise (const size_t entry_idx, int8_t *this_buff, const int8_t *that_buff) const
 
void reduceOneEntryNoCollisionsRowWise (const size_t i, int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer) 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 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
 

Private Attributes

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

Friends

class ResultSet
 
class ResultSetManager
 

Detailed Description

Definition at line 80 of file ResultSet.h.

Constructor & Destructor Documentation

◆ ResultSetStorage()

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

Definition at line 44 of file ResultSet.cpp.

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

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

Member Function Documentation

◆ addCountDistinctSetPointerMapping()

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

Definition at line 841 of file ResultSet.cpp.

References CHECK.

Referenced by updateEntryCount().

842  {
843  const auto it_ok = count_distinct_sets_mapping_.emplace(remote_ptr, ptr);
844  CHECK(it_ok.second);
845 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:213
#define CHECK(condition)
Definition: Logger.h:187
+ Here is the caller graph for this function:

◆ copyKeyColWise()

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

Definition at line 489 of file ResultSetReduction.cpp.

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

Referenced by reduceEntriesNoCollisionsColWise(), and updateEntryCount().

491  {
493  for (size_t group_idx = 0; group_idx < query_mem_desc_.getGroupbyColCount();
494  group_idx++) {
495  // if the column corresponds to a group key
496  const auto column_offset_bytes =
498  auto lhs_key_ptr = this_buff + column_offset_bytes;
499  auto rhs_key_ptr = that_buff + column_offset_bytes;
500  switch (query_mem_desc_.groupColWidth(group_idx)) {
501  case 8:
502  *(reinterpret_cast<int64_t*>(lhs_key_ptr) + entry_idx) =
503  *(reinterpret_cast<const int64_t*>(rhs_key_ptr) + entry_idx);
504  break;
505  case 4:
506  *(reinterpret_cast<int32_t*>(lhs_key_ptr) + entry_idx) =
507  *(reinterpret_cast<const int32_t*>(rhs_key_ptr) + entry_idx);
508  break;
509  case 2:
510  *(reinterpret_cast<int16_t*>(lhs_key_ptr) + entry_idx) =
511  *(reinterpret_cast<const int16_t*>(rhs_key_ptr) + entry_idx);
512  break;
513  case 1:
514  *(reinterpret_cast<int8_t*>(lhs_key_ptr) + entry_idx) =
515  *(reinterpret_cast<const int8_t*>(rhs_key_ptr) + entry_idx);
516  break;
517  default:
518  CHECK(false);
519  break;
520  }
521  }
522 }
int8_t groupColWidth(const size_t key_idx) const
#define CHECK(condition)
Definition: Logger.h:187
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fillOneEntryColWise()

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

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

Referenced by updateEntryCount().

1277  {
1279  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1280  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1281  const auto key_count = query_mem_desc_.getGroupbyColCount();
1282  CHECK_EQ(slot_count + key_count, entry.size());
1283  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1284 
1285  for (size_t i = 0; i < key_count; i++) {
1286  const auto key_offset = key_offset_colwise(0, i, 1);
1287  this_buff[key_offset] = entry[i];
1288  }
1289 
1290  for (size_t i = 0; i < target_init_vals_.size(); i++) {
1291  const auto slot_offset = slot_offset_colwise(0, i, key_count, 1);
1292  this_buff[slot_offset] = entry[key_count + i];
1293  }
1294 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
int8_t * buff_
Definition: ResultSet.h:205
#define CHECK(condition)
Definition: Logger.h:187
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fillOneEntryRowWise()

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

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

Referenced by updateEntryCount().

1224  {
1225  const auto slot_count = query_mem_desc_.getBufferColSlotCount();
1226  const auto key_count = query_mem_desc_.getGroupbyColCount();
1227  CHECK_EQ(slot_count + key_count, entry.size());
1228  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1230  CHECK_EQ(size_t(1), query_mem_desc_.getEntryCount());
1231  const auto key_off = key_offset_rowwise(0, key_count, slot_count);
1232  CHECK_EQ(query_mem_desc_.getEffectiveKeyWidth(), sizeof(int64_t));
1233  for (size_t i = 0; i < key_count; ++i) {
1234  this_buff[key_off + i] = entry[i];
1235  }
1236  const auto first_slot_off = slot_offset_rowwise(0, 0, key_count, slot_count);
1237  for (size_t i = 0; i < target_init_vals_.size(); ++i) {
1238  this_buff[first_slot_off + i] = entry[key_count + i];
1239  }
1240 }
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:195
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
int8_t * buff_
Definition: ResultSet.h:205
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:187
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
size_t getEffectiveKeyWidth() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getUnderlyingBuffer()

int8_t * ResultSetStorage::getUnderlyingBuffer ( ) const

Definition at line 77 of file ResultSet.cpp.

References buff_.

77  {
78  return buff_;
79 }
int8_t * buff_
Definition: ResultSet.h:205

◆ initializeBaselineValueSlots()

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

Definition at line 1316 of file ResultSetReduction.cpp.

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

Referenced by updateEntryCount().

1316  {
1317  CHECK(entry_slots);
1319  size_t slot_off = 0;
1320  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1321  entry_slots[slot_off] = target_init_vals_[j];
1322  slot_off += query_mem_desc_.getEntryCount();
1323  }
1324  } else {
1325  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1326  entry_slots[j] = target_init_vals_[j];
1327  }
1328  }
1329 }
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
#define CHECK(condition)
Definition: Logger.h:187
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initializeColWise()

void ResultSetStorage::initializeColWise ( ) const
private

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

Referenced by updateEntryCount().

1296  {
1297  const auto key_count = query_mem_desc_.getGroupbyColCount();
1298  auto this_buff = reinterpret_cast<int64_t*>(buff_);
1300  for (size_t key_idx = 0; key_idx < key_count; ++key_idx) {
1301  const auto first_key_off =
1303  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1304  this_buff[first_key_off + i] = EMPTY_KEY_64;
1305  }
1306  }
1307  for (size_t target_idx = 0; target_idx < target_init_vals_.size(); ++target_idx) {
1308  const auto first_val_off =
1309  slot_offset_colwise(0, target_idx, key_count, query_mem_desc_.getEntryCount());
1310  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1311  this_buff[first_val_off + i] = target_init_vals_[target_idx];
1312  }
1313  }
1314 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
size_t slot_offset_colwise(const size_t entry_idx, const size_t slot_idx, const size_t key_count, const size_t entry_count)
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
int8_t * buff_
Definition: ResultSet.h:205
#define CHECK(condition)
Definition: Logger.h:187
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initializeRowWise()

void ResultSetStorage::initializeRowWise ( ) const
private

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

Referenced by updateEntryCount().

1242  {
1243  const auto key_count = query_mem_desc_.getGroupbyColCount();
1244  const auto row_size = get_row_bytes(query_mem_desc_);
1245  CHECK_EQ(row_size % 8, 0u);
1246  const auto key_bytes_with_padding =
1250  case 4: {
1251  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1252  auto row_ptr = buff_ + i * row_size;
1253  fill_empty_key_32(reinterpret_cast<int32_t*>(row_ptr), key_count);
1254  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1255  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1256  slot_ptr[j] = target_init_vals_[j];
1257  }
1258  }
1259  break;
1260  }
1261  case 8: {
1262  for (size_t i = 0; i < query_mem_desc_.getEntryCount(); ++i) {
1263  auto row_ptr = buff_ + i * row_size;
1264  fill_empty_key_64(reinterpret_cast<int64_t*>(row_ptr), key_count);
1265  auto slot_ptr = reinterpret_cast<int64_t*>(row_ptr + key_bytes_with_padding);
1266  for (size_t j = 0; j < target_init_vals_.size(); ++j) {
1267  slot_ptr[j] = target_init_vals_[j];
1268  }
1269  }
1270  break;
1271  }
1272  default:
1273  CHECK(false);
1274  }
1275 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
ALWAYS_INLINE void fill_empty_key_32(int32_t *key_ptr_i32, const size_t key_count)
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
int8_t * buff_
Definition: ResultSet.h:205
#define CHECK(condition)
Definition: Logger.h:187
ALWAYS_INLINE void fill_empty_key_64(int64_t *key_ptr_i64, const size_t key_count)
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
size_t getEffectiveKeyWidth() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isEmptyEntry() [1/2]

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

Definition at line 1867 of file ResultSetIteration.cpp.

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

Referenced by reduceOneEntryBaseline(), reduceOneEntryNoCollisionsRowWise(), rewriteAggregateBufferOffsets(), and updateEntryCount().

1867  {
1870  return false;
1871  }
1873  return isEmptyEntryColumnar(entry_idx, buff);
1874  }
1879  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
1880  target_init_vals_.size());
1881  const auto rowwise_target_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
1882  const auto target_slot_off =
1884  return read_int_from_buff(rowwise_target_ptr + target_slot_off,
1888  } else {
1889  const auto keys_ptr = row_ptr_rowwise(buff, query_mem_desc_, entry_idx);
1891  case 4:
1894  return *reinterpret_cast<const int32_t*>(keys_ptr) == EMPTY_KEY_32;
1895  case 8:
1896  return *reinterpret_cast<const int64_t*>(keys_ptr) == EMPTY_KEY_64;
1897  default:
1898  CHECK(false);
1899  return true;
1900  }
1901  }
1902 }
#define EMPTY_KEY_64
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
#define CHECK_GE(x, y)
Definition: Logger.h:200
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
int32_t getTargetIdxForKey() const
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define CHECK(condition)
Definition: Logger.h:187
#define EMPTY_KEY_32
bool isEmptyEntryColumnar(const size_t entry_idx, const int8_t *buff) const
QueryDescriptionType getQueryDescriptionType() const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
size_t getEffectiveKeyWidth() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isEmptyEntry() [2/2]

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

Definition at line 1955 of file ResultSetIteration.cpp.

1955  {
1956  return isEmptyEntry(entry_idx, buff_);
1957 }
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
int8_t * buff_
Definition: ResultSet.h:205

◆ isEmptyEntryColumnar()

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

Definition at line 1908 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::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getPrependedGroupColOffInBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), GroupByPerfectHash, QueryMemoryDescriptor::groupColWidth(), QueryMemoryDescriptor::groupColWidthsSize(), QueryMemoryDescriptor::hasKeylessHash(), NonGroupedAggregate, Projection, ResultSet::query_mem_desc_, read_int_from_buff(), and ResultSet::targets_.

Referenced by reduceEntriesNoCollisionsColWise(), and updateEntryCount().

1909  {
1913  return false;
1914  }
1919  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
1920  target_init_vals_.size());
1921  const auto col_buff = advance_col_buff_to_slot(
1923  const auto entry_buff =
1924  col_buff + entry_idx * query_mem_desc_.getPaddedSlotWidthBytes(
1926  return read_int_from_buff(entry_buff,
1930  } else {
1931  // it's enough to find the first group key which is empty
1933  return reinterpret_cast<const int64_t*>(buff)[entry_idx] == EMPTY_KEY_64;
1934  } else {
1936  const auto target_buff = buff + query_mem_desc_.getPrependedGroupColOffInBytes(0);
1937  switch (query_mem_desc_.groupColWidth(0)) {
1938  case 8:
1939  return reinterpret_cast<const int64_t*>(target_buff)[entry_idx] == EMPTY_KEY_64;
1940  case 4:
1941  return reinterpret_cast<const int32_t*>(target_buff)[entry_idx] == EMPTY_KEY_32;
1942  case 2:
1943  return reinterpret_cast<const int16_t*>(target_buff)[entry_idx] == EMPTY_KEY_16;
1944  case 1:
1945  return reinterpret_cast<const int8_t*>(target_buff)[entry_idx] == EMPTY_KEY_8;
1946  default:
1947  CHECK(false);
1948  }
1949  }
1950  return false;
1951  }
1952  return false;
1953 }
#define EMPTY_KEY_64
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:203
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
#define CHECK_GE(x, y)
Definition: Logger.h:200
int64_t read_int_from_buff(const int8_t *ptr, const int8_t compact_sz)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
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)
#define EMPTY_KEY_8
int8_t groupColWidth(const size_t key_idx) const
int32_t getTargetIdxForKey() const
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define EMPTY_KEY_16
#define CHECK(condition)
Definition: Logger.h:187
#define EMPTY_KEY_32
QueryDescriptionType getQueryDescriptionType() const
size_t getPrependedGroupColOffInBytes(const size_t group_idx) const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mappedPtr()

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

Definition at line 847 of file ResultSet.cpp.

Referenced by updateEntryCount().

847  {
848  const auto it = count_distinct_sets_mapping_.find(remote_ptr);
849  // Due to the removal of completely zero bitmaps in a distributed transfer there will be
850  // remote ptr that do not not exists. Return 0 if no pointer found
851  if (it == count_distinct_sets_mapping_.end()) {
852  return int64_t(0);
853  }
854  return it->second;
855 }
std::unordered_map< int64_t, int64_t > count_distinct_sets_mapping_
Definition: ResultSet.h:213
+ Here is the caller graph for this function:

◆ moveEntriesToBuffer()

template<class KeyType >
void ResultSetStorage::moveEntriesToBuffer ( int8_t *  new_buff,
const size_t  new_entry_count 
) const

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

1019  {
1021  CHECK_GT(new_entry_count, query_mem_desc_.getEntryCount());
1022  auto new_buff_i64 = reinterpret_cast<int64_t*>(new_buff);
1023  const auto key_count = query_mem_desc_.getGroupbyColCount();
1026  const auto src_buff = reinterpret_cast<const int64_t*>(buff_);
1027  const auto row_qw_count = get_row_qw_count(query_mem_desc_);
1028  const auto key_byte_width = query_mem_desc_.getEffectiveKeyWidth();
1029 
1031  const size_t thread_count = cpu_threads();
1032  std::vector<std::future<void>> move_threads;
1033 
1034  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
1035  const auto thread_entry_count =
1036  (query_mem_desc_.getEntryCount() + thread_count - 1) / thread_count;
1037  const auto start_index = thread_idx * thread_entry_count;
1038  const auto end_index =
1039  std::min(start_index + thread_entry_count, query_mem_desc_.getEntryCount());
1040  move_threads.emplace_back(std::async(
1041  std::launch::async,
1042  [this,
1043  src_buff,
1044  new_buff_i64,
1045  new_entry_count,
1046  start_index,
1047  end_index,
1048  key_count,
1049  row_qw_count,
1050  key_byte_width] {
1051  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
1052  moveOneEntryToBuffer<KeyType>(entry_idx,
1053  new_buff_i64,
1054  new_entry_count,
1055  key_count,
1056  row_qw_count,
1057  src_buff,
1058  key_byte_width);
1059  }
1060  }));
1061  }
1062  for (auto& move_thread : move_threads) {
1063  move_thread.wait();
1064  }
1065  for (auto& move_thread : move_threads) {
1066  move_thread.get();
1067  }
1068  } else {
1069  for (size_t entry_idx = 0; entry_idx < query_mem_desc_.getEntryCount(); ++entry_idx) {
1070  moveOneEntryToBuffer<KeyType>(entry_idx,
1071  new_buff_i64,
1072  new_entry_count,
1073  key_count,
1074  row_qw_count,
1075  src_buff,
1076  key_byte_width);
1077  }
1078  }
1079 }
#define CHECK_GT(x, y)
Definition: Logger.h:199
int8_t * buff_
Definition: ResultSet.h:205
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:187
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
QueryDescriptionType getQueryDescriptionType() const
int cpu_threads()
Definition: thread_count.h:23
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
size_t getEffectiveKeyWidth() const
+ Here is the call graph for this function:

◆ moveOneEntryToBuffer()

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 1082 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_.

1088  {
1089  const auto key_off =
1091  ? key_offset_colwise(entry_index, 0, query_mem_desc_.getEntryCount())
1092  : row_qw_count * entry_index;
1093  const auto key_ptr = reinterpret_cast<const KeyType*>(&src_buff[key_off]);
1094  if (*key_ptr == get_empty_key<KeyType>()) {
1095  return;
1096  }
1097  int64_t* new_entries_ptr{nullptr};
1099  const auto key =
1100  make_key(&src_buff[key_off], query_mem_desc_.getEntryCount(), key_count);
1101  new_entries_ptr =
1102  get_group_value_columnar(new_buff_i64, new_entry_count, &key[0], key_count);
1103  } else {
1104  new_entries_ptr = get_group_value(new_buff_i64,
1105  new_entry_count,
1106  &src_buff[key_off],
1107  key_count,
1108  key_byte_width,
1109  row_qw_count,
1110  nullptr);
1111  }
1112  CHECK(new_entries_ptr);
1113  fill_slots(new_entries_ptr,
1114  new_entry_count,
1115  src_buff,
1116  entry_index,
1118  query_mem_desc_);
1119 }
NEVER_INLINE DEVICE int64_t * get_group_value_columnar(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
void fill_slots(int64_t *dst_entry, const size_t dst_entry_count, const int64_t *src_buff, const size_t src_entry_idx, const size_t src_entry_count, const QueryMemoryDescriptor &query_mem_desc)
std::vector< int64_t > make_key(const int64_t *buff, const size_t entry_count, const size_t key_count)
NEVER_INLINE DEVICE int64_t * get_group_value(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_count, const uint32_t key_width, const uint32_t row_size_quad, const int64_t *init_vals)
size_t key_offset_colwise(const size_t entry_idx, const size_t key_idx, const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:187
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:

◆ reduce()

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

Definition at line 200 of file ResultSetReduction.cpp.

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

202  {
203  auto entry_count = query_mem_desc_.getEntryCount();
204  CHECK_GT(entry_count, size_t(0));
212  }
213  const auto that_entry_count = that.query_mem_desc_.getEntryCount();
216  CHECK_GE(entry_count, that_entry_count);
217  break;
218  default:
219  CHECK_EQ(entry_count, that_entry_count);
220  }
221  auto this_buff = buff_;
222  CHECK(this_buff);
223  auto that_buff = that.buff_;
224  CHECK(that_buff);
227  if (!serialized_varlen_buffer.empty()) {
228  throw std::runtime_error(
229  "Projection of variable length targets with baseline hash group by is not yet "
230  "supported in Distributed mode");
231  }
232  if (use_multithreaded_reduction(that_entry_count)) {
233  const size_t thread_count = cpu_threads();
234  std::vector<std::future<void>> reduction_threads;
235  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
236  const auto thread_entry_count =
237  (that_entry_count + thread_count - 1) / thread_count;
238  const auto start_index = thread_idx * thread_entry_count;
239  const auto end_index =
240  std::min(start_index + thread_entry_count, that_entry_count);
241  reduction_threads.emplace_back(std::async(
242  std::launch::async,
243  [this,
244  this_buff,
245  that_buff,
246  start_index,
247  end_index,
248  that_entry_count,
249  &reduction_code,
250  &that] {
251  if (reduction_code.execution_engine) {
252  run_reduction_code(reduction_code,
253  this_buff,
254  that_buff,
255  start_index,
256  end_index,
257  that_entry_count,
258  &query_mem_desc_,
259  &that.query_mem_desc_,
260  nullptr);
261  } else {
262  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
263  reduceOneEntryBaseline(
264  this_buff, that_buff, entry_idx, that_entry_count, that);
265  }
266  }
267  }));
268  }
269  for (auto& reduction_thread : reduction_threads) {
270  reduction_thread.wait();
271  }
272  for (auto& reduction_thread : reduction_threads) {
273  reduction_thread.get();
274  }
275  } else {
276  if (reduction_code.execution_engine) {
277  run_reduction_code(reduction_code,
278  this_buff,
279  that_buff,
280  0,
281  that_entry_count,
282  that_entry_count,
284  &that.query_mem_desc_,
285  nullptr);
286  } else {
287  for (size_t i = 0; i < that_entry_count; ++i) {
288  reduceOneEntryBaseline(this_buff, that_buff, i, that_entry_count, that);
289  }
290  }
291  }
292  return;
293  }
294  if (use_multithreaded_reduction(entry_count)) {
295  const size_t thread_count = cpu_threads();
296  std::vector<std::future<void>> reduction_threads;
297  for (size_t thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
298  const auto thread_entry_count = (entry_count + thread_count - 1) / thread_count;
299  const auto start_index = thread_idx * thread_entry_count;
300  const auto end_index = std::min(start_index + thread_entry_count, entry_count);
302  reduction_threads.emplace_back(std::async(std::launch::async,
303  [this,
304  this_buff,
305  that_buff,
306  start_index,
307  end_index,
308  &that,
309  &serialized_varlen_buffer] {
311  this_buff,
312  that_buff,
313  that,
314  start_index,
315  end_index,
316  serialized_varlen_buffer);
317  }));
318  } else {
319  reduction_threads.emplace_back(std::async(
320  std::launch::async,
321  [this,
322  this_buff,
323  that_buff,
324  start_index,
325  end_index,
326  that_entry_count,
327  &reduction_code,
328  &that,
329  &serialized_varlen_buffer] {
330  if (reduction_code.execution_engine) {
331  run_reduction_code(reduction_code,
332  this_buff,
333  that_buff,
334  start_index,
335  end_index,
336  that_entry_count,
337  &query_mem_desc_,
338  &that.query_mem_desc_,
339  &serialized_varlen_buffer);
340  } else {
341  for (size_t entry_idx = start_index; entry_idx < end_index; ++entry_idx) {
342  reduceOneEntryNoCollisionsRowWise(
343  entry_idx, this_buff, that_buff, that, serialized_varlen_buffer);
344  }
345  }
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  if (reduction_code.execution_engine) {
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  } else {
375  for (size_t i = 0; i < entry_count; ++i) {
377  i, this_buff, that_buff, that, serialized_varlen_buffer);
378  }
379  }
380  }
381  }
382 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
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 reduceOneEntryBaseline(int8_t *this_buff, const int8_t *that_buff, const size_t i, const size_t that_entry_count, const ResultSetStorage &that) const
#define CHECK_GE(x, y)
Definition: Logger.h:200
#define CHECK_GT(x, y)
Definition: Logger.h:199
void reduceOneEntryNoCollisionsRowWise(const size_t i, int8_t *this_buff, const int8_t *that_buff, const ResultSetStorage &that, const std::vector< std::string > &serialized_varlen_buffer) const
int8_t * buff_
Definition: ResultSet.h:205
bool use_multithreaded_reduction(const size_t entry_count)
#define CHECK(condition)
Definition: Logger.h:187
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
QueryDescriptionType getQueryDescriptionType() const
int cpu_threads()
Definition: thread_count.h:23
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
llvm::ExecutionEngine * execution_engine
+ Here is the call graph for this function:

◆ reduceEntriesNoCollisionsColWise()

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

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

Referenced by reduce(), and updateEntryCount().

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

◆ reduceOneCountDistinctSlot()

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

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

Referenced by reduceOneSlot(), and updateEntryCount().

1627  {
1629  const auto& old_count_distinct_desc =
1630  query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1631  CHECK(old_count_distinct_desc.impl_type_ != CountDistinctImplType::Invalid);
1632  const auto& new_count_distinct_desc =
1633  that.query_mem_desc_.getCountDistinctDescriptor(target_logical_idx);
1634  CHECK(old_count_distinct_desc.impl_type_ == new_count_distinct_desc.impl_type_);
1635  CHECK(this_ptr1 && that_ptr1);
1636  auto old_set_ptr = reinterpret_cast<const int64_t*>(this_ptr1);
1637  auto new_set_ptr = reinterpret_cast<const int64_t*>(that_ptr1);
1639  *new_set_ptr, *old_set_ptr, new_count_distinct_desc, old_count_distinct_desc);
1640 }
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
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define CHECK(condition)
Definition: Logger.h:187
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryBaseline()

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

References CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog(), QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::fill_slots(), anonymous_namespace{ResultSetReduction.cpp}::get_group_value_columnar_reduction(), get_group_value_reduction(), anonymous_namespace{ResultSetReduction.cpp}::get_row_qw_count(), QueryMemoryDescriptor::getEffectiveKeyWidth(), 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(), and updateEntryCount().

887  {
888  check_watchdog(that_entry_idx);
889  const auto key_count = query_mem_desc_.getGroupbyColCount();
893  const auto key_off =
896  : get_row_qw_count(query_mem_desc_) * that_entry_idx;
897  if (isEmptyEntry(that_entry_idx, that_buff)) {
898  return;
899  }
900  int64_t* this_entry_slots{nullptr};
901  auto this_buff_i64 = reinterpret_cast<int64_t*>(this_buff);
902  auto that_buff_i64 = reinterpret_cast<const int64_t*>(that_buff);
903  bool empty_entry = false;
905  const auto key = make_key(&that_buff_i64[key_off], that_entry_count, key_count);
906  std::tie(this_entry_slots, empty_entry) = get_group_value_columnar_reduction(
907  this_buff_i64, query_mem_desc_.getEntryCount(), &key[0], key_count);
908  } else {
909  const uint32_t row_size_quad = get_row_qw_count(query_mem_desc_);
910  std::tie(this_entry_slots, empty_entry) =
911  get_group_value_reduction(this_buff_i64,
913  &that_buff_i64[key_off],
914  key_count,
917  that_buff_i64,
918  that_entry_idx,
919  that_entry_count,
920  row_size_quad);
921  }
922  CHECK(this_entry_slots);
923  if (empty_entry) {
925  fill_slots(this_entry_slots,
927  that_buff_i64,
928  that_entry_idx,
929  that_entry_count,
931  }
932  return;
933  }
935  this_entry_slots, that_buff_i64, that_entry_idx, that_entry_count, that);
936 }
GroupValueInfo get_group_value_reduction(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_count, const size_t key_width, const QueryMemoryDescriptor &query_mem_desc, const int64_t *that_buff_i64, const size_t that_entry_idx, const size_t that_entry_count, const uint32_t row_size_quad)
void fill_slots(int64_t *dst_entry, const size_t dst_entry_count, const int64_t *src_buff, const size_t src_entry_idx, const size_t src_entry_count, const QueryMemoryDescriptor &query_mem_desc)
GroupValueInfo get_group_value_columnar_reduction(int64_t *groups_buffer, const uint32_t groups_buffer_entry_count, const int64_t *key, const uint32_t key_qw_count)
std::vector< int64_t > make_key(const int64_t *buff, const size_t entry_count, const size_t key_count)
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) 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
ALWAYS_INLINE void check_watchdog(const size_t sample_seed)
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:187
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
QueryDescriptionType getQueryDescriptionType() const
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
size_t getEffectiveKeyWidth() const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntryNoCollisionsRowWise()

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

Definition at line 603 of file ResultSetReduction.cpp.

References align_to_int64(), CHECK, anonymous_namespace{ResultSetReduction.cpp}::check_watchdog(), QueryMemoryDescriptor::didOutputColumnar(), get_key_bytes_rowwise(), QueryMemoryDescriptor::getColSlotContext(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getTargetGroupbyIndex(), isEmptyEntry(), kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), row_ptr_rowwise(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), targets_, and UNLIKELY.

Referenced by reduce(), and updateEntryCount().

608  {
609  check_watchdog(entry_idx);
611  if (isEmptyEntry(entry_idx, that_buff)) {
612  return;
613  }
614 
615  const auto this_row_ptr = row_ptr_rowwise(this_buff, query_mem_desc_, entry_idx);
616  const auto that_row_ptr = row_ptr_rowwise(that_buff, query_mem_desc_, entry_idx);
617 
618  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
619  if (key_bytes) { // copy the key from right hand side
620  memcpy(this_row_ptr, that_row_ptr, key_bytes);
621  }
622 
623  const auto key_bytes_with_padding = align_to_int64(key_bytes);
624  auto this_targets_ptr = this_row_ptr + key_bytes_with_padding;
625  auto that_targets_ptr = that_row_ptr + key_bytes_with_padding;
626 
627  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
628 
629  size_t init_agg_val_idx = 0;
630  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
631  ++target_logical_idx) {
632  const auto& target_info = targets_[target_logical_idx];
633  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_logical_idx);
634  int8_t* this_ptr2{nullptr};
635  const int8_t* that_ptr2{nullptr};
636 
637  bool two_slot_target{false};
638  if (target_info.is_agg &&
639  (target_info.agg_kind == kAVG ||
640  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
641  // Note that this assumes if one of the slot pairs in a given target is an array,
642  // all slot pairs are arrays. Currently this is true for all geo targets, but we
643  // should better codify and store this information in the future
644  two_slot_target = true;
645  }
646 
647  for (size_t target_slot_idx = slots_for_col.front();
648  target_slot_idx < slots_for_col.back() + 1;
649  target_slot_idx += 2) {
650  if (UNLIKELY(two_slot_target)) {
651  this_ptr2 =
652  this_targets_ptr + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
653  that_ptr2 =
654  that_targets_ptr + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
655  }
656  reduceOneSlot(this_targets_ptr,
657  this_ptr2,
658  that_targets_ptr,
659  that_ptr2,
660  target_info,
661  target_logical_idx,
662  target_slot_idx,
663  init_agg_val_idx,
664  that,
665  slots_for_col.front(),
666  serialized_varlen_buffer);
667  auto increment_agg_val_idx_maybe =
668  [&init_agg_val_idx, &target_logical_idx, this](const int slot_count) {
670  query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
671  init_agg_val_idx += slot_count;
672  }
673  };
674  if (UNLIKELY(two_slot_target)) {
675  increment_agg_val_idx_maybe(2);
676  this_targets_ptr = this_targets_ptr +
677  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx) +
678  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
679  that_targets_ptr = that_targets_ptr +
680  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx) +
681  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1);
682  } else {
683  increment_agg_val_idx_maybe(1);
684  this_targets_ptr =
685  this_targets_ptr + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
686  that_targets_ptr =
687  that_targets_ptr + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
688  ;
689  }
690  }
691  }
692 }
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:203
ssize_t getTargetGroupbyIndex(const size_t target_idx) const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
bool isEmptyEntry(const size_t entry_idx, const int8_t *buff) const
ALWAYS_INLINE void check_watchdog(const size_t sample_seed)
size_t targetGroupbyIndicesSize() const
T row_ptr_rowwise(T buff, const QueryMemoryDescriptor &query_mem_desc, const size_t entry_idx)
#define UNLIKELY(x)
Definition: likely.h:20
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
#define CHECK(condition)
Definition: Logger.h:187
const ColSlotContext & getColSlotContext() const
Definition: sqldefs.h:71
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneEntrySlotsBaseline()

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

References advance_slot(), QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReduction.cpp}::get_row_qw_count(), get_slot_off_quad(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getTargetGroupbyIndex(), query_mem_desc_, reduceOneSlotBaseline(), slot_offset_colwise(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), and targets_.

Referenced by reduceOneEntryBaseline(), and updateEntryCount().

942  {
943  const auto key_count = query_mem_desc_.getGroupbyColCount();
944  size_t j = 0;
945  size_t init_agg_val_idx = 0;
946  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
947  ++target_logical_idx) {
948  const auto& target_info = targets_[target_logical_idx];
949  const auto that_slot_off =
952  that_entry_idx, init_agg_val_idx, key_count, that_entry_count)
953  : get_row_qw_count(query_mem_desc_) * that_entry_idx +
954  get_slot_off_quad(query_mem_desc_) + init_agg_val_idx;
955  const auto this_slot_off = query_mem_desc_.didOutputColumnar()
956  ? init_agg_val_idx * query_mem_desc_.getEntryCount()
957  : init_agg_val_idx;
958  reduceOneSlotBaseline(this_entry_slots,
959  this_slot_off,
960  that_buff,
961  that_entry_count,
962  that_slot_off,
963  target_info,
964  target_logical_idx,
965  j,
966  init_agg_val_idx,
967  that);
969  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
970  } else {
971  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
972  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
973  }
974  }
975  j = advance_slot(j, target_info, false);
976  }
977 }
const std::vector< TargetInfo > targets_
Definition: ResultSet.h:203
ssize_t getTargetGroupbyIndex(const size_t target_idx) const
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 get_slot_off_quad(const QueryMemoryDescriptor &query_mem_desc)
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
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 targetGroupbyIndicesSize() const
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneSlot()

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 1488 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, SQLTypeInfoCore< TYPE_FACET_PACK >::get_elem_type(), get_width_for_slot(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getTargetGroupbyIndex(), TargetInfo::is_agg, is_distinct_target(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_geometry(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_string(), SQLTypeInfoCore< TYPE_FACET_PACK >::is_varlen(), QueryMemoryDescriptor::isLogicalSizedColumnsAllowed(), kAPPROX_COUNT_DISTINCT, kAVG, kCOUNT, kMAX, kMIN, kSAMPLE, kSUM, LOG, query_mem_desc_, reduceOneCountDistinctSlot(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, and QueryMemoryDescriptor::targetGroupbyIndicesSize().

Referenced by reduceEntriesNoCollisionsColWise(), reduceOneEntryNoCollisionsRowWise(), reduceOneSlotBaseline(), and updateEntryCount().

1499  {
1501  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1502  return;
1503  }
1504  }
1505  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1506  const bool float_argument_input = takes_float_argument(target_info);
1507  const auto chosen_bytes =
1508  get_width_for_slot(target_slot_idx, float_argument_input, query_mem_desc_);
1509  auto init_val = target_init_vals_[init_agg_val_idx];
1510  if (target_info.is_agg && target_info.agg_kind != kSAMPLE) {
1511  switch (target_info.agg_kind) {
1512  case kCOUNT:
1513  case kAPPROX_COUNT_DISTINCT: {
1514  if (is_distinct_target(target_info)) {
1515  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1516  reduceOneCountDistinctSlot(this_ptr1, that_ptr1, target_logical_idx, that);
1517  break;
1518  }
1519  CHECK_EQ(int64_t(0), init_val);
1520  AGGREGATE_ONE_COUNT(this_ptr1, that_ptr1, chosen_bytes);
1521  break;
1522  }
1523  case kAVG: {
1524  // Ignore float argument compaction for count component for fear of its overflow
1525  AGGREGATE_ONE_COUNT(this_ptr2,
1526  that_ptr2,
1527  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx));
1528  }
1529  // fall thru
1530  case kSUM: {
1532  sum, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1533  break;
1534  }
1535  case kMIN: {
1536  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1538  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1539  } else {
1541  min, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1542  }
1543  break;
1544  }
1545  case kMAX: {
1546  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1548  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1549  } else {
1551  max, this_ptr1, that_ptr1, init_val, chosen_bytes, target_info);
1552  }
1553  break;
1554  }
1555  default:
1556  CHECK(false);
1557  }
1558  } else {
1559  switch (chosen_bytes) {
1560  case 1: {
1562  const auto rhs_proj_col = *reinterpret_cast<const int8_t*>(that_ptr1);
1563  if (rhs_proj_col != init_val) {
1564  *reinterpret_cast<int8_t*>(this_ptr1) = rhs_proj_col;
1565  }
1566  break;
1567  }
1568  case 2: {
1570  const auto rhs_proj_col = *reinterpret_cast<const int16_t*>(that_ptr1);
1571  if (rhs_proj_col != init_val) {
1572  *reinterpret_cast<int16_t*>(this_ptr1) = rhs_proj_col;
1573  }
1574  break;
1575  }
1576  case 4: {
1577  CHECK(target_info.agg_kind != kSAMPLE ||
1579  const auto rhs_proj_col = *reinterpret_cast<const int32_t*>(that_ptr1);
1580  if (rhs_proj_col != init_val) {
1581  *reinterpret_cast<int32_t*>(this_ptr1) = rhs_proj_col;
1582  }
1583  break;
1584  }
1585  case 8: {
1586  auto rhs_proj_col = *reinterpret_cast<const int64_t*>(that_ptr1);
1587  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) &&
1588  !serialized_varlen_buffer.empty()) {
1589  size_t length_to_elems{0};
1590  if (target_info.sql_type.is_geometry()) {
1591  // TODO: Assumes hard-coded sizes for geometry targets
1592  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1593  } else {
1594  const auto& elem_ti = target_info.sql_type.get_elem_type();
1595  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1596  }
1597 
1598  CHECK_LT(static_cast<size_t>(rhs_proj_col), serialized_varlen_buffer.size());
1599  const auto& varlen_bytes_str = serialized_varlen_buffer[rhs_proj_col];
1600  const auto str_ptr = reinterpret_cast<const int8_t*>(varlen_bytes_str.c_str());
1601  *reinterpret_cast<int64_t*>(this_ptr1) =
1602  reinterpret_cast<const int64_t>(str_ptr);
1603  *reinterpret_cast<int64_t*>(this_ptr2) =
1604  static_cast<int64_t>(varlen_bytes_str.size() / length_to_elems);
1605  } else {
1606  if (rhs_proj_col != init_val) {
1607  *reinterpret_cast<int64_t*>(this_ptr1) = rhs_proj_col;
1608  }
1609  if ((target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen())) {
1610  CHECK(this_ptr2 && that_ptr2);
1611  *reinterpret_cast<int64_t*>(this_ptr2) =
1612  *reinterpret_cast<const int64_t*>(that_ptr2);
1613  }
1614  }
1615 
1616  break;
1617  }
1618  default:
1619  LOG(FATAL) << "Invalid slot width: " << chosen_bytes;
1620  }
1621  }
1622 }
#define CHECK_EQ(x, y)
Definition: Logger.h:195
ssize_t getTargetGroupbyIndex(const size_t target_idx) const
std::vector< int64_t > target_init_vals_
Definition: ResultSet.h:207
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
#define LOG(tag)
Definition: Logger.h:182
bool is_varlen() const
Definition: sqltypes.h:460
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:120
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Definition: sqldefs.h:71
#define AGGREGATE_ONE_NULLABLE_VALUE( agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
bool is_agg
Definition: TargetInfo.h:40
Definition: sqldefs.h:71
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:116
SQLTypeInfoCore get_elem_type() const
Definition: sqltypes.h:628
size_t targetGroupbyIndicesSize() const
SQLAgg agg_kind
Definition: TargetInfo.h:41
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL( agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
void reduceOneCountDistinctSlot(int8_t *this_ptr1, const int8_t *that_ptr1, const size_t target_logical_idx, const ResultSetStorage &that) const
#define CHECK_LT(x, y)
Definition: Logger.h:197
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:71
#define CHECK(condition)
Definition: Logger.h:187
bool is_geometry() const
Definition: sqltypes.h:458
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
Definition: sqldefs.h:71
Definition: sqldefs.h:71
bool is_string() const
Definition: sqltypes.h:446
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceOneSlotBaseline()

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

References TargetInfo::agg_kind, QueryMemoryDescriptor::didOutputColumnar(), QueryMemoryDescriptor::getEntryCount(), TargetInfo::is_agg, SQLTypeInfoCore< TYPE_FACET_PACK >::is_varlen(), kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), and TargetInfo::sql_type.

Referenced by reduceOneEntrySlotsBaseline(), and updateEntryCount().

988  {
989  int8_t* this_ptr2{nullptr};
990  const int8_t* that_ptr2{nullptr};
991  if (target_info.is_agg &&
992  (target_info.agg_kind == kAVG ||
993  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
994  const auto this_count_off =
996  const auto that_count_off =
997  query_mem_desc_.didOutputColumnar() ? that_entry_count : 1;
998  this_ptr2 = reinterpret_cast<int8_t*>(&this_buff[this_slot + this_count_off]);
999  that_ptr2 = reinterpret_cast<const int8_t*>(&that_buff[that_slot + that_count_off]);
1000  }
1001  reduceOneSlot(reinterpret_cast<int8_t*>(&this_buff[this_slot]),
1002  this_ptr2,
1003  reinterpret_cast<const int8_t*>(&that_buff[that_slot]),
1004  that_ptr2,
1005  target_info,
1006  target_logical_idx,
1007  target_slot_idx,
1008  init_agg_val_idx,
1009  that,
1010  target_slot_idx, // dummy, for now
1011  {});
1012 }
SQLTypeInfo sql_type
Definition: TargetInfo.h:42
bool is_varlen() const
Definition: sqltypes.h:460
bool is_agg
Definition: TargetInfo.h:40
SQLAgg agg_kind
Definition: TargetInfo.h:41
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
Definition: sqldefs.h:71
QueryMemoryDescriptor query_mem_desc_
Definition: ResultSet.h:204
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduceSingleRow()

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

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

Referenced by QueryExecutionContext::groupBufferToDeinterleavedResults(), and updateEntryCount().

1649  {
1650  const size_t agg_col_count{agg_vals.size()};
1651  const auto row_size = query_mem_desc.getRowSize();
1652  CHECK_EQ(agg_col_count, query_mem_desc.getSlotCount());
1653  CHECK_GE(agg_col_count, targets.size());
1654  CHECK_EQ(is_columnar, query_mem_desc.didOutputColumnar());
1655  CHECK(query_mem_desc.hasKeylessHash());
1656  std::vector<int64_t> partial_agg_vals(agg_col_count, 0);
1657  bool discard_row = true;
1658  for (int8_t warp_idx = 0; warp_idx < warp_count; ++warp_idx) {
1659  bool discard_partial_result = true;
1660  for (size_t target_idx = 0, agg_col_idx = 0;
1661  target_idx < targets.size() && agg_col_idx < agg_col_count;
1662  ++target_idx, ++agg_col_idx) {
1663  const auto& agg_info = targets[target_idx];
1664  const bool float_argument_input = takes_float_argument(agg_info);
1665  const auto chosen_bytes = float_argument_input
1666  ? sizeof(float)
1667  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1668  auto partial_bin_val = get_component(
1669  row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx), chosen_bytes);
1670  partial_agg_vals[agg_col_idx] = partial_bin_val;
1671  if (is_distinct_target(agg_info)) {
1672  CHECK_EQ(int8_t(1), warp_count);
1673  CHECK(agg_info.is_agg && (agg_info.agg_kind == kCOUNT ||
1674  agg_info.agg_kind == kAPPROX_COUNT_DISTINCT));
1675  partial_bin_val = count_distinct_set_size(
1676  partial_bin_val, query_mem_desc.getCountDistinctDescriptor(target_idx));
1677  if (replace_bitmap_ptr_with_bitmap_sz) {
1678  partial_agg_vals[agg_col_idx] = partial_bin_val;
1679  }
1680  }
1681  if (kAVG == agg_info.agg_kind) {
1682  CHECK(agg_info.is_agg && !agg_info.is_distinct);
1683  ++agg_col_idx;
1684  partial_bin_val = partial_agg_vals[agg_col_idx] =
1685  get_component(row_ptr + query_mem_desc.getColOnlyOffInBytes(agg_col_idx),
1686  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1687  }
1688  if (agg_col_idx == static_cast<size_t>(query_mem_desc.getTargetIdxForKey()) &&
1689  partial_bin_val != agg_init_vals[query_mem_desc.getTargetIdxForKey()]) {
1690  CHECK(agg_info.is_agg);
1691  discard_partial_result = false;
1692  }
1693  }
1694  row_ptr += row_size;
1695  if (discard_partial_result) {
1696  continue;
1697  }
1698  discard_row = false;
1699  for (size_t target_idx = 0, agg_col_idx = 0;
1700  target_idx < targets.size() && agg_col_idx < agg_col_count;
1701  ++target_idx, ++agg_col_idx) {
1702  auto partial_bin_val = partial_agg_vals[agg_col_idx];
1703  const auto& agg_info = targets[target_idx];
1704  const bool float_argument_input = takes_float_argument(agg_info);
1705  const auto chosen_bytes = float_argument_input
1706  ? sizeof(float)
1707  : query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx);
1708  const auto& chosen_type = get_compact_type(agg_info);
1709  if (agg_info.is_agg && agg_info.agg_kind != kSAMPLE) {
1710  try {
1711  switch (agg_info.agg_kind) {
1712  case kCOUNT:
1715  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1716  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1717  agg_init_vals[agg_col_idx],
1718  chosen_bytes,
1719  agg_info);
1720  break;
1721  case kAVG:
1722  // Ignore float argument compaction for count component for fear of its
1723  // overflow
1725  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx + 1]),
1726  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx + 1]),
1727  query_mem_desc.getPaddedSlotWidthBytes(agg_col_idx));
1728  // fall thru
1729  case kSUM:
1731  sum,
1732  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1733  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1734  agg_init_vals[agg_col_idx],
1735  chosen_bytes,
1736  agg_info);
1737  break;
1738  case kMIN:
1739  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1741  min,
1742  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1743  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1744  agg_init_vals[agg_col_idx],
1745  chosen_bytes,
1746  agg_info);
1747  } else {
1749  min,
1750  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1751  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1752  agg_init_vals[agg_col_idx],
1753  chosen_bytes,
1754  agg_info);
1755  }
1756  break;
1757  case kMAX:
1758  if (static_cast<size_t>(chosen_bytes) <= sizeof(int16_t)) {
1760  max,
1761  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1762  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1763  agg_init_vals[agg_col_idx],
1764  chosen_bytes,
1765  agg_info);
1766  } else {
1768  max,
1769  reinterpret_cast<int8_t*>(&agg_vals[agg_col_idx]),
1770  reinterpret_cast<int8_t*>(&partial_agg_vals[agg_col_idx]),
1771  agg_init_vals[agg_col_idx],
1772  chosen_bytes,
1773  agg_info);
1774  }
1775  break;
1776  default:
1777  CHECK(false);
1778  break;
1779  }
1780  } catch (std::runtime_error& e) {
1781  // TODO(miyu): handle the case where chosen_bytes < 8
1782  LOG(ERROR) << e.what();
1783  }
1784  if (chosen_type.is_integer() || chosen_type.is_decimal()) {
1785  switch (chosen_bytes) {
1786  case 8:
1787  break;
1788  case 4: {
1789  int32_t ret = *reinterpret_cast<const int32_t*>(&agg_vals[agg_col_idx]);
1790  if (!(agg_info.agg_kind == kCOUNT && 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:195
const int64_t const uint32_t const uint32_t const uint32_t agg_col_count
int64_t get_component(const int8_t *group_by_buffer, const size_t comp_sz, const size_t index=0)
#define LOG(tag)
Definition: Logger.h:182
#define CHECK_GE(x, y)
Definition: Logger.h:200
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:120
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
Definition: sqldefs.h:71
const SQLTypeInfo get_compact_type(const TargetInfo &target)
#define AGGREGATE_ONE_NULLABLE_VALUE( agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
int64_t count_distinct_set_size(const int64_t set_handle, const CountDistinctDescriptor &count_distinct_desc)
Definition: CountDistinct.h:75
Definition: sqldefs.h:71
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:116
#define AGGREGATE_ONE_NULLABLE_VALUE_SMALL( agg_kind__, val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
int32_t getTargetIdxForKey() const
size_t getColOnlyOffInBytes(const size_t col_idx) const
#define AGGREGATE_ONE_COUNT(val_ptr__, other_ptr__, chosen_bytes__)
Definition: sqldefs.h:71
#define AGGREGATE_ONE_NULLABLE_COUNT( val_ptr__, other_ptr__, init_val__, chosen_bytes__, agg_info__)
#define CHECK(condition)
Definition: Logger.h:187
const CountDistinctDescriptor & getCountDistinctDescriptor(const size_t idx) const
Definition: sqldefs.h:71
Definition: sqldefs.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rewriteAggregateBufferOffsets()

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

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

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

◆ updateEntryCount()

void ResultSetStorage::updateEntryCount ( const size_t  new_entry_count)
inline

Friends And Related Function Documentation

◆ ResultSet

◆ ResultSetManager

friend class ResultSetManager
friend

Definition at line 216 of file ResultSet.h.

Member Data Documentation

◆ buff_

◆ buff_is_provided_

const bool ResultSetStorage::buff_is_provided_
private

Definition at line 206 of file ResultSet.h.

◆ count_distinct_sets_mapping_

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

Definition at line 213 of file ResultSet.h.

◆ query_mem_desc_

◆ target_init_vals_

std::vector<int64_t> ResultSetStorage::target_init_vals_
private

◆ targets_

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

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