OmniSciDB  a667adc9c8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
anonymous_namespace{ResultSetReduction.cpp} Namespace Reference

Functions

bool use_multithreaded_reduction (const size_t entry_count)
 
size_t get_row_qw_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)
 
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)
 
ALWAYS_INLINE void fill_empty_key_32 (int32_t *key_ptr_i32, const size_t key_count)
 
ALWAYS_INLINE void fill_empty_key_64 (int64_t *key_ptr_i64, const size_t key_count)
 
int64_t get_component (const int8_t *group_by_buffer, const size_t comp_sz, const size_t index=0)
 
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)
 
ALWAYS_INLINE void check_watchdog ()
 
ALWAYS_INLINE void check_watchdog_with_seed (const size_t sample_seed)
 
GroupValueInfo get_matching_group_value_columnar_reduction (int64_t *groups_buffer, const uint32_t h, const int64_t *key, const uint32_t key_qw_count, const size_t entry_count)
 
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)
 
template<typename T = int64_t>
GroupValueInfo get_matching_group_value_reduction (int64_t *groups_buffer, const uint32_t h, const T *key, const uint32_t key_count, 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)
 
GroupValueInfo get_matching_group_value_reduction (int64_t *groups_buffer, const uint32_t h, 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)
 

Function Documentation

ALWAYS_INLINE void anonymous_namespace{ResultSetReduction.cpp}::check_watchdog ( )

Definition at line 380 of file ResultSetReduction.cpp.

References dynamic_watchdog(), and UNLIKELY.

Referenced by ResultSetStorage::reduceEntriesNoCollisionsColWise().

380  {
381  if (UNLIKELY(dynamic_watchdog())) {
382  // TODO(alex): distinguish between the deadline and interrupt
383  throw std::runtime_error(
384  "Query execution has exceeded the time limit or was interrupted during result "
385  "set reduction");
386  }
387 }
__device__ bool dynamic_watchdog()
#define UNLIKELY(x)
Definition: likely.h:25

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ALWAYS_INLINE void anonymous_namespace{ResultSetReduction.cpp}::check_watchdog_with_seed ( const size_t  sample_seed)

Definition at line 389 of file ResultSetReduction.cpp.

References dynamic_watchdog(), and UNLIKELY.

Referenced by ResultSetStorage::reduceOneEntryBaseline().

389  {
390  if (UNLIKELY((sample_seed & 0x3F) == 0 && dynamic_watchdog())) {
391  // TODO(alex): distinguish between the deadline and interrupt
392  throw std::runtime_error(
393  "Query execution has exceeded the time limit or was interrupted during result "
394  "set reduction");
395  }
396 }
__device__ bool dynamic_watchdog()
#define UNLIKELY(x)
Definition: likely.h:25

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ALWAYS_INLINE void anonymous_namespace{ResultSetReduction.cpp}::fill_empty_key_32 ( int32_t *  key_ptr_i32,
const size_t  key_count 
)

Definition at line 91 of file ResultSetReduction.cpp.

References EMPTY_KEY_32, and i.

Referenced by result_set::fill_empty_key(), and ResultSetStorage::initializeRowWise().

91  {
92  for (size_t i = 0; i < key_count; ++i) {
93  key_ptr_i32[i] = EMPTY_KEY_32;
94  }
95 }
#define EMPTY_KEY_32

+ Here is the caller graph for this function:

ALWAYS_INLINE void anonymous_namespace{ResultSetReduction.cpp}::fill_empty_key_64 ( int64_t *  key_ptr_i64,
const size_t  key_count 
)

Definition at line 98 of file ResultSetReduction.cpp.

References EMPTY_KEY_64, and i.

Referenced by result_set::fill_empty_key(), and ResultSetStorage::initializeRowWise().

98  {
99  for (size_t i = 0; i < key_count; ++i) {
100  key_ptr_i64[i] = EMPTY_KEY_64;
101  }
102 }
#define EMPTY_KEY_64

+ Here is the caller graph for this function:

void anonymous_namespace{ResultSetReduction.cpp}::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 
)

Definition at line 67 of file ResultSetReduction.cpp.

References QueryMemoryDescriptor::didOutputColumnar(), get_row_qw_count(), get_slot_off_quad(), QueryMemoryDescriptor::getBufferColSlotCount(), QueryMemoryDescriptor::getGroupbyColCount(), i, and slot_offset_colwise().

Referenced by get_matching_group_value_reduction(), ResultSetStorage::moveOneEntryToBuffer(), and ResultSetStorage::reduceOneEntryBaseline().

72  {
73  const auto slot_count = query_mem_desc.getBufferColSlotCount();
74  const auto key_count = query_mem_desc.getGroupbyColCount();
75  if (query_mem_desc.didOutputColumnar()) {
76  for (size_t i = 0, dst_slot_off = 0; i < slot_count;
77  ++i, dst_slot_off += dst_entry_count) {
78  dst_entry[dst_slot_off] =
79  src_buff[slot_offset_colwise(src_entry_idx, i, key_count, src_entry_count)];
80  }
81  } else {
82  const auto row_ptr = src_buff + get_row_qw_count(query_mem_desc) * src_entry_idx;
83  const auto slot_off_quad = get_slot_off_quad(query_mem_desc);
84  for (size_t i = 0; i < slot_count; ++i) {
85  dst_entry[i] = row_ptr[slot_off_quad + i];
86  }
87  }
88 }
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 getGroupbyColCount() const
size_t get_row_qw_count(const QueryMemoryDescriptor &query_mem_desc)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int64_t anonymous_namespace{ResultSetReduction.cpp}::get_component ( const int8_t *  group_by_buffer,
const size_t  comp_sz,
const size_t  index = 0 
)
inline

Definition at line 104 of file ResultSetReduction.cpp.

References CHECK.

Referenced by ResultSetStorage::reduceSingleRow().

106  {
107  int64_t ret = std::numeric_limits<int64_t>::min();
108  switch (comp_sz) {
109  case 1: {
110  ret = group_by_buffer[index];
111  break;
112  }
113  case 2: {
114  const int16_t* buffer_ptr = reinterpret_cast<const int16_t*>(group_by_buffer);
115  ret = buffer_ptr[index];
116  break;
117  }
118  case 4: {
119  const int32_t* buffer_ptr = reinterpret_cast<const int32_t*>(group_by_buffer);
120  ret = buffer_ptr[index];
121  break;
122  }
123  case 8: {
124  const int64_t* buffer_ptr = reinterpret_cast<const int64_t*>(group_by_buffer);
125  ret = buffer_ptr[index];
126  break;
127  }
128  default:
129  CHECK(false);
130  }
131  return ret;
132 }
#define CHECK(condition)
Definition: Logger.h:197

+ Here is the caller graph for this function:

GroupValueInfo anonymous_namespace{ResultSetReduction.cpp}::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 
)

Definition at line 645 of file ResultSetReduction.cpp.

References get_matching_group_value_columnar_reduction(), and key_hash().

Referenced by ResultSetStorage::reduceOneEntryBaseline().

649  {
650  uint32_t h = key_hash(key, key_qw_count, sizeof(int64_t)) % groups_buffer_entry_count;
652  groups_buffer, h, key, key_qw_count, groups_buffer_entry_count);
653  if (matching_gvi.first) {
654  return matching_gvi;
655  }
656  uint32_t h_probe = (h + 1) % groups_buffer_entry_count;
657  while (h_probe != h) {
659  groups_buffer, h_probe, key, key_qw_count, groups_buffer_entry_count);
660  if (matching_gvi.first) {
661  return matching_gvi;
662  }
663  h_probe = (h_probe + 1) % groups_buffer_entry_count;
664  }
665  return {nullptr, true};
666 }
GroupValueInfo get_matching_group_value_columnar_reduction(int64_t *groups_buffer, const uint32_t h, const int64_t *key, const uint32_t key_qw_count, const size_t entry_count)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE uint32_t key_hash(const int64_t *key, const uint32_t key_count, const uint32_t key_byte_width)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

GroupValueInfo anonymous_namespace{ResultSetReduction.cpp}::get_matching_group_value_columnar_reduction ( int64_t *  groups_buffer,
const uint32_t  h,
const int64_t *  key,
const uint32_t  key_qw_count,
const size_t  entry_count 
)

Definition at line 618 of file ResultSetReduction.cpp.

References EMPTY_KEY_64, i, and mapd_cas.

Referenced by get_group_value_columnar_reduction().

622  {
623  auto off = h;
624  const auto old_key = mapd_cas(&groups_buffer[off], EMPTY_KEY_64, *key);
625  if (old_key == EMPTY_KEY_64) {
626  for (size_t i = 0; i < key_qw_count; ++i) {
627  groups_buffer[off] = key[i];
628  off += entry_count;
629  }
630  return {&groups_buffer[off], true};
631  }
632  off = h;
633  for (size_t i = 0; i < key_qw_count; ++i) {
634  if (groups_buffer[off] != key[i]) {
635  return {nullptr, true};
636  }
637  off += entry_count;
638  }
639  return {&groups_buffer[off], false};
640 }
#define EMPTY_KEY_64
#define mapd_cas(address, compare, val)

+ Here is the caller graph for this function:

template<typename T = int64_t>
GroupValueInfo anonymous_namespace{ResultSetReduction.cpp}::get_matching_group_value_reduction ( int64_t *  groups_buffer,
const uint32_t  h,
const T *  key,
const uint32_t  key_count,
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 
)

Definition at line 687 of file ResultSetReduction.cpp.

References cas_cst, fill_slots(), get_slot_off_quad(), QueryMemoryDescriptor::getEntryCount(), i, load_cst, query_mem_desc, store_cst, and omnisci.dtypes::T.

Referenced by result_set::get_group_value_reduction(), and get_matching_group_value_reduction().

696  {
697  auto off = h * row_size_quad;
698  T empty_key = get_empty_key<T>();
699  T write_pending = get_empty_key<T>() - 1;
700  auto row_ptr = reinterpret_cast<T*>(groups_buffer + off);
701  const auto slot_off_quad = get_slot_off_quad(query_mem_desc);
702  const bool success = cas_cst(row_ptr, &empty_key, write_pending);
703  if (success) {
704  fill_slots(groups_buffer + off + slot_off_quad,
705  query_mem_desc.getEntryCount(),
706  that_buff_i64,
707  that_entry_idx,
708  that_entry_count,
710  if (key_count > 1) {
711  memcpy(row_ptr + 1, key + 1, (key_count - 1) * sizeof(T));
712  }
713  store_cst(row_ptr, *key);
714  return {groups_buffer + off + slot_off_quad, true};
715  }
716  while (load_cst(row_ptr) == write_pending) {
717  // spin until the winning thread has finished writing the entire key and the init
718  // value
719  }
720  for (size_t i = 0; i < key_count; ++i) {
721  if (load_cst(row_ptr + i) != key[i]) {
722  return {nullptr, true};
723  }
724  }
725  return {groups_buffer + off + slot_off_quad, false};
726 }
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)
size_t get_slot_off_quad(const QueryMemoryDescriptor &query_mem_desc)
#define store_cst(ptr, val)
#define cas_cst(ptr, expected, desired)
#define load_cst(ptr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

GroupValueInfo anonymous_namespace{ResultSetReduction.cpp}::get_matching_group_value_reduction ( int64_t *  groups_buffer,
const uint32_t  h,
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 
)
inline

Definition at line 732 of file ResultSetReduction.cpp.

References CHECK, and get_matching_group_value_reduction().

742  {
743  switch (key_width) {
744  case 4:
745  return get_matching_group_value_reduction(groups_buffer,
746  h,
747  reinterpret_cast<const int32_t*>(key),
748  key_count,
749  query_mem_desc,
750  that_buff_i64,
751  that_entry_idx,
752  that_entry_count,
753  row_size_quad);
754  case 8:
755  return get_matching_group_value_reduction(groups_buffer,
756  h,
757  key,
758  key_count,
759  query_mem_desc,
760  that_buff_i64,
761  that_entry_idx,
762  that_entry_count,
763  row_size_quad);
764  default:
765  CHECK(false);
766  return {nullptr, true};
767  }
768 }
GroupValueInfo get_matching_group_value_reduction(int64_t *groups_buffer, const uint32_t h, const T *key, const uint32_t key_count, 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)
#define CHECK(condition)
Definition: Logger.h:197

+ Here is the call graph for this function:

size_t anonymous_namespace{ResultSetReduction.cpp}::get_row_qw_count ( const QueryMemoryDescriptor query_mem_desc)

Definition at line 49 of file ResultSetReduction.cpp.

References CHECK_EQ, and get_row_bytes().

Referenced by fill_slots(), and ResultSetStorage::moveEntriesToBuffer().

49  {
50  const auto row_bytes = get_row_bytes(query_mem_desc);
51  CHECK_EQ(size_t(0), row_bytes % 8);
52  return row_bytes / 8;
53 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::vector<int64_t> anonymous_namespace{ResultSetReduction.cpp}::make_key ( const int64_t *  buff,
const size_t  entry_count,
const size_t  key_count 
)

Definition at line 55 of file ResultSetReduction.cpp.

References i.

Referenced by ResultSetStorage::moveOneEntryToBuffer(), and ResultSetStorage::reduceOneEntryBaseline().

57  {
58  std::vector<int64_t> key;
59  size_t off = 0;
60  for (size_t i = 0; i < key_count; ++i) {
61  key.push_back(buff[off]);
62  off += entry_count;
63  }
64  return key;
65 }

+ Here is the caller graph for this function:

void anonymous_namespace{ResultSetReduction.cpp}::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 
)

Definition at line 134 of file ResultSetReduction.cpp.

References Executor::compilation_mutex_, Executor::ERR_INTERRUPTED, Executor::ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES, ReductionCode::func_ptr, ReductionInterpreter::EvalValue::int_val, ReductionCode::ir_reduce_loop, ReductionInterpreter::MakeEvalValue(), and ReductionInterpreter::run().

Referenced by ResultSetStorage::reduce().

142  {
143  int err = 0;
144  if (reduction_code.func_ptr) {
145  err = reduction_code.func_ptr(this_buff,
146  that_buff,
147  start_entry_index,
148  end_entry_index,
149  that_entry_count,
150  this_qmd,
151  that_qmd,
152  serialized_varlen_buffer);
153  } else {
154  // Calls LLVM methods that are not thread safe, ensure nothing else compiles while we
155  // run this reduction
156  std::lock_guard<std::mutex> compilation_lock(Executor::compilation_mutex_);
157  auto ret = ReductionInterpreter::run(
158  reduction_code.ir_reduce_loop.get(),
161  ReductionInterpreter::MakeEvalValue(start_entry_index),
162  ReductionInterpreter::MakeEvalValue(end_entry_index),
163  ReductionInterpreter::MakeEvalValue(that_entry_count),
166  ReductionInterpreter::MakeEvalValue(serialized_varlen_buffer)});
167  err = ret.int_val;
168  }
169  if (err) {
171  throw std::runtime_error("Multiple distinct values encountered");
172  }
173  if (err == Executor::ERR_INTERRUPTED) {
174  throw std::runtime_error(
175  "Query execution has interrupted during result set reduction");
176  }
177  throw std::runtime_error(
178  "Query execution has exceeded the time limit or was interrupted during result "
179  "set reduction");
180  }
181 }
static const int32_t ERR_INTERRUPTED
Definition: Execute.h:1117
std::unique_ptr< Function > ir_reduce_loop
static EvalValue run(const Function *function, const std::vector< EvalValue > &inputs)
static EvalValue MakeEvalValue(const T &val)
static const int32_t ERR_SINGLE_VALUE_FOUND_MULTIPLE_VALUES
Definition: Execute.h:1122
static std::mutex compilation_mutex_
Definition: Execute.h:1125

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool anonymous_namespace{ResultSetReduction.cpp}::use_multithreaded_reduction ( const size_t  entry_count)

Definition at line 45 of file ResultSetReduction.cpp.

Referenced by ResultSetStorage::moveEntriesToBuffer(), and ResultSetStorage::reduce().

45  {
46  return entry_count > 100000;
47 }

+ Here is the caller graph for this function: