OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultSetReductionJIT Class Reference

#include <ResultSetReductionJIT.h>

+ Inheritance diagram for ResultSetReductionJIT:
+ Collaboration diagram for ResultSetReductionJIT:

Public Member Functions

 ResultSetReductionJIT (const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &target_init_vals, const size_t executor_id)
 
virtual ~ResultSetReductionJIT ()=default
 
virtual ReductionCode codegen () const
 

Protected Member Functions

void isEmpty (const ReductionCode &reduction_code) const
 
void reduceOneEntryNoCollisions (const ReductionCode &reduction_code) const
 
void reduceOneEntryNoCollisionsIdx (const ReductionCode &reduction_code) const
 
void reduceLoop (const ReductionCode &reduction_code) const
 

Protected Attributes

size_t executor_id_
 

Private Member Functions

void reduceOneEntryTargetsNoCollisions (Function *ir_reduce_one_entry, Value *this_targets_start_ptr, Value *that_targets_start_ptr) const
 
void reduceOneEntryBaseline (const ReductionCode &reduction_code) const
 
void reduceOneEntryBaselineIdx (const ReductionCode &reduction_code) const
 
void reduceOneSlot (Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *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 size_t first_slot_idx_for_target, Function *ir_reduce_one_entry) const
 
void reduceOneAggregateSlot (Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const int64_t init_val, const int8_t chosen_bytes, Function *ir_reduce_one_entry) const
 
void reduceOneCountDistinctSlot (Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
 
void reduceOneApproxQuantileSlot (Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
 
void reduceOneModeSlot (Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
 
void finalizeReductionCode (ReductionCode &reduction_code, const llvm::Function *ir_is_empty, const llvm::Function *ir_reduce_one_entry, const llvm::Function *ir_reduce_one_entry_idx, const CodeCacheKey &key) const
 
std::string cacheKey () const
 

Private Attributes

const QueryMemoryDescriptor query_mem_desc_
 
const std::vector< TargetInfotargets_
 
const std::vector< int64_t > target_init_vals_
 

Detailed Description

Definition at line 52 of file ResultSetReductionJIT.h.

Constructor & Destructor Documentation

ResultSetReductionJIT::ResultSetReductionJIT ( const QueryMemoryDescriptor query_mem_desc,
const std::vector< TargetInfo > &  targets,
const std::vector< int64_t > &  target_init_vals,
const size_t  executor_id 
)

Definition at line 527 of file ResultSetReductionJIT.cpp.

531  : executor_id_(executor_id)
532  , query_mem_desc_(query_mem_desc)
533  , targets_(targets)
534  , target_init_vals_(target_init_vals) {}
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
const std::vector< TargetInfo > targets_
virtual ResultSetReductionJIT::~ResultSetReductionJIT ( )
virtualdefault

Member Function Documentation

std::string ResultSetReductionJIT::cacheKey ( ) const
private

Definition at line 1308 of file ResultSetReductionJIT.cpp.

References join(), query_mem_desc_, QueryMemoryDescriptor::reductionKey(), anonymous_namespace{ResultSetReductionJIT.cpp}::target_info_key(), target_init_vals_, targets_, to_string(), and shared::transform().

Referenced by codegen().

1308  {
1309  std::vector<std::string> target_init_vals_strings;
1311  target_init_vals_.end(),
1312  std::back_inserter(target_init_vals_strings),
1313  [](const int64_t v) { return std::to_string(v); });
1314  const auto target_init_vals_key =
1315  boost::algorithm::join(target_init_vals_strings, ", ");
1316  std::vector<std::string> targets_strings;
1318  targets_.begin(),
1319  targets_.end(),
1320  std::back_inserter(targets_strings),
1321  [](const TargetInfo& target_info) { return target_info_key(target_info); });
1322  const auto targets_key = boost::algorithm::join(targets_strings, ", ");
1323  return query_mem_desc_.reductionKey() + "\n" + target_init_vals_key + "\n" +
1324  targets_key;
1325 }
std::string join(T const &container, std::string const &delim)
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
std::string target_info_key(const TargetInfo &target_info)
OUTPUT transform(INPUT const &input, FUNC const &func)
Definition: misc.h:329
std::string reductionKey() const
const std::vector< TargetInfo > targets_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ReductionCode ResultSetReductionJIT::codegen ( ) const
virtual

Reimplemented in GpuReductionHelperJIT.

Definition at line 567 of file ResultSetReductionJIT.cpp.

References AUTOMATIC_IR_METADATA, AUTOMATIC_IR_METADATA_DONE, QueryMemoryDescriptor::blocksShareMemory(), cacheKey(), anonymous_namespace{ResultSetReductionJIT.cpp}::create_llvm_function(), QueryMemoryDescriptor::didOutputColumnar(), executor_id_, f(), logger::FATAL, finalizeReductionCode(), QueryMemoryDescriptor::getEntryCount(), QueryMemoryDescriptor::getExecutor(), Executor::getExecutor(), QueryEngine::getInstance(), QueryMemoryDescriptor::getQueryDescriptionType(), heavyai::GroupByBaselineHash, heavyai::GroupByPerfectHash, anonymous_namespace{ResultSetReductionJIT.cpp}::INTERP_THRESHOLD, anonymous_namespace{ResultSetReductionJIT.cpp}::is_aggregate_query(), isEmpty(), LOG, heavyai::NonGroupedAggregate, query_mem_desc_, reduceLoop(), reduceOneEntryBaseline(), reduceOneEntryBaselineIdx(), reduceOneEntryNoCollisions(), reduceOneEntryNoCollisionsIdx(), anonymous_namespace{ResultSetReductionJIT.cpp}::setup_functions_ir(), and translate_function().

Referenced by anonymous_namespace{Execute.cpp}::get_reduction_code(), and ResultSetManager::reduce().

567  {
568  const auto hash_type = query_mem_desc_.getQueryDescriptionType();
570  return {};
571  }
572  auto reduction_code = setup_functions_ir(hash_type);
573  isEmpty(reduction_code);
577  reduceOneEntryNoCollisions(reduction_code);
578  reduceOneEntryNoCollisionsIdx(reduction_code);
579  break;
580  }
582  reduceOneEntryBaseline(reduction_code);
583  reduceOneEntryBaselineIdx(reduction_code);
584  break;
585  }
586  default: {
587  LOG(FATAL) << "Unexpected query description type";
588  }
589  }
590  reduceLoop(reduction_code);
591  // For small result sets, avoid native code generation and use the interpreter instead.
594  return reduction_code;
595  }
596  auto executor = Executor::getExecutor(executor_id_);
597  CodeCacheKey key{cacheKey()};
598  std::lock_guard<std::mutex> compilation_lock(executor->compilation_mutex_);
599  const auto compilation_context =
600  QueryEngine::getInstance()->s_code_accessor->get_or_wait(key);
601  if (compilation_context) {
602  reduction_code.func_ptr =
603  reinterpret_cast<ReductionCode::FuncPtr>(compilation_context->get()->func());
604  return reduction_code;
605  }
606  auto cgen_state_ = std::unique_ptr<CgenState>(new CgenState({}, false, executor.get()));
607  auto cgen_state = reduction_code.cgen_state = cgen_state_.get();
608  cgen_state->set_module_shallow_copy(executor->get_rt_module());
609  reduction_code.module = cgen_state->module_;
610 
611  AUTOMATIC_IR_METADATA(cgen_state);
612  auto ir_is_empty = create_llvm_function(reduction_code.ir_is_empty.get(), cgen_state);
613  auto ir_reduce_one_entry =
614  create_llvm_function(reduction_code.ir_reduce_one_entry.get(), cgen_state);
615  auto ir_reduce_one_entry_idx =
616  create_llvm_function(reduction_code.ir_reduce_one_entry_idx.get(), cgen_state);
617  auto ir_reduce_loop =
618  create_llvm_function(reduction_code.ir_reduce_loop.get(), cgen_state);
619  std::unordered_map<const Function*, llvm::Function*> f;
620  f.emplace(reduction_code.ir_is_empty.get(), ir_is_empty);
621  f.emplace(reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry);
622  f.emplace(reduction_code.ir_reduce_one_entry_idx.get(), ir_reduce_one_entry_idx);
623  f.emplace(reduction_code.ir_reduce_loop.get(), ir_reduce_loop);
624  translate_function(reduction_code.ir_is_empty.get(), ir_is_empty, reduction_code, f);
626  reduction_code.ir_reduce_one_entry.get(), ir_reduce_one_entry, reduction_code, f);
627  translate_function(reduction_code.ir_reduce_one_entry_idx.get(),
628  ir_reduce_one_entry_idx,
629  reduction_code,
630  f);
632  reduction_code.ir_reduce_loop.get(), ir_reduce_loop, reduction_code, f);
633  reduction_code.llvm_reduce_loop = ir_reduce_loop;
635  reduction_code.cgen_state = nullptr;
637  reduction_code, ir_is_empty, ir_reduce_one_entry, ir_reduce_one_entry_idx, key);
638  return reduction_code;
639 }
GroupByPerfectHash
Definition: enums.h:58
bool is_aggregate_query(const QueryDescriptionType hash_type)
NonGroupedAggregate
Definition: enums.h:58
void reduceOneEntryNoCollisions(const ReductionCode &reduction_code) const
void reduceOneEntryBaselineIdx(const ReductionCode &reduction_code) const
#define LOG(tag)
Definition: Logger.h:285
void reduceLoop(const ReductionCode &reduction_code) const
void reduceOneEntryNoCollisionsIdx(const ReductionCode &reduction_code) const
std::vector< std::string > CodeCacheKey
Definition: CodeCache.h:24
std::string cacheKey() const
int32_t(*)(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) FuncPtr
const QueryMemoryDescriptor query_mem_desc_
void translate_function(const Function *function, llvm::Function *llvm_function, const ReductionCode &reduction_code, const std::unordered_map< const Function *, llvm::Function * > &f)
static std::shared_ptr< Executor > getExecutor(const ExecutorId id, const std::string &debug_dir="", const std::string &debug_file="", const SystemParameters &system_parameters=SystemParameters())
Definition: Execute.cpp:513
ReductionCode setup_functions_ir(const QueryDescriptionType hash_type)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
QueryDescriptionType getQueryDescriptionType() const
#define AUTOMATIC_IR_METADATA_DONE()
void finalizeReductionCode(ReductionCode &reduction_code, const llvm::Function *ir_is_empty, const llvm::Function *ir_reduce_one_entry, const llvm::Function *ir_reduce_one_entry_idx, const CodeCacheKey &key) const
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
GroupByBaselineHash
Definition: enums.h:58
void isEmpty(const ReductionCode &reduction_code) const
void reduceOneEntryBaseline(const ReductionCode &reduction_code) const
static std::shared_ptr< QueryEngine > getInstance()
Definition: QueryEngine.h:89
llvm::Function * create_llvm_function(const Function *function, CgenState *cgen_state)
const Executor * getExecutor() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::finalizeReductionCode ( ReductionCode reduction_code,
const llvm::Function *  ir_is_empty,
const llvm::Function *  ir_reduce_one_entry,
const llvm::Function *  ir_reduce_one_entry_idx,
const CodeCacheKey key 
) const
private

Definition at line 1257 of file ResultSetReductionJIT.cpp.

References CPU, CodeGenerator::generateNativeCPUCode(), logger::IR, ReductionCode::llvm_reduce_loop, LOG, ReductionCode::module, ReductionJIT, serialize_llvm_object(), and VLOG.

Referenced by codegen().

1262  {
1263  CompilationOptions co{
1265  VLOG(3) << "Reduction Loop:\n"
1266  << serialize_llvm_object(reduction_code.llvm_reduce_loop);
1267  VLOG(3) << "Reduction Is Empty Func:\n" << serialize_llvm_object(ir_is_empty);
1268  VLOG(3) << "Reduction One Entry Func:\n" << serialize_llvm_object(ir_reduce_one_entry);
1269  VLOG(3) << "Reduction One Entry Idx Func:\n"
1270  << serialize_llvm_object(ir_reduce_one_entry_idx);
1271 #ifdef NDEBUG
1272  LOG(IR) << "Reduction Loop:\n"
1273  << serialize_llvm_object(reduction_code.llvm_reduce_loop);
1274  LOG(IR) << "Reduction Is Empty Func:\n" << serialize_llvm_object(ir_is_empty);
1275  LOG(IR) << "Reduction One Entry Func:\n" << serialize_llvm_object(ir_reduce_one_entry);
1276  LOG(IR) << "Reduction One Entry Idx Func:\n"
1277  << serialize_llvm_object(ir_reduce_one_entry_idx);
1278 #else
1279  LOG(IR) << serialize_llvm_object(reduction_code.module);
1280 #endif
1282  reduction_code.llvm_reduce_loop, {reduction_code.llvm_reduce_loop}, co);
1283  auto cpu_compilation_context = std::make_shared<CpuCompilationContext>(std::move(ee));
1284  cpu_compilation_context->setFunctionPointer(reduction_code.llvm_reduce_loop);
1285  reduction_code.func_ptr =
1286  reinterpret_cast<ReductionCode::FuncPtr>(cpu_compilation_context->func());
1287  CHECK(reduction_code.llvm_reduce_loop->getParent() == reduction_code.module);
1288  auto executor = Executor::getExecutor(executor_id_);
1289  QueryEngine::getInstance()->s_code_accessor->reset(key,
1290  std::move(cpu_compilation_context));
1291 }
#define LOG(tag)
Definition: Logger.h:285
llvm::Function * llvm_reduce_loop
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
int32_t(*)(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) FuncPtr
static std::shared_ptr< Executor > getExecutor(const ExecutorId id, const std::string &debug_dir="", const std::string &debug_file="", const SystemParameters &system_parameters=SystemParameters())
Definition: Execute.cpp:513
llvm::Module * module
std::string serialize_llvm_object(const T *llvm_obj)
#define CHECK(condition)
Definition: Logger.h:291
static std::shared_ptr< QueryEngine > getInstance()
Definition: QueryEngine.h:89
#define VLOG(n)
Definition: Logger.h:388

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::isEmpty ( const ReductionCode reduction_code) const
protected

Definition at line 641 of file ResultSetReductionJIT.cpp.

References CHECK, CHECK_GE, CHECK_LT, QueryMemoryDescriptor::didOutputColumnar(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i32(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i64(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_read_int_from_buff(), EMPTY_KEY_32, EMPTY_KEY_64, ICmp::EQ, logger::FATAL, result_set::get_byteoff_of_slot(), QueryMemoryDescriptor::getEffectiveKeyWidth(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getQueryDescriptionType(), QueryMemoryDescriptor::getTargetIdxForKey(), heavyai::GroupByPerfectHash, QueryMemoryDescriptor::hasKeylessHash(), Int32, Int64, ReductionCode::ir_is_empty, anonymous_namespace{ResultSetReductionJIT.cpp}::is_aggregate_query(), LOG, query_mem_desc_, and target_init_vals_.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

641  {
642  auto ir_is_empty = reduction_code.ir_is_empty.get();
645  Value* key{nullptr};
646  Value* empty_key_val{nullptr};
647  const auto keys_ptr = ir_is_empty->arg(0);
652  CHECK_LT(static_cast<size_t>(query_mem_desc_.getTargetIdxForKey()),
653  target_init_vals_.size());
654  const int64_t target_slot_off = result_set::get_byteoff_of_slot(
656  const auto slot_ptr = ir_is_empty->add<GetElementPtr>(
657  keys_ptr,
658  ir_is_empty->addConstant<ConstantInt>(target_slot_off, Type::Int32),
659  "is_empty_slot_ptr");
660  const auto compact_sz =
662  key = emit_read_int_from_buff(slot_ptr, compact_sz, ir_is_empty);
663  empty_key_val = ir_is_empty->addConstant<ConstantInt>(
665  } else {
667  case 4: {
670  key = emit_load_i32(keys_ptr, ir_is_empty);
671  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_32, Type::Int32);
672  break;
673  }
674  case 8: {
675  key = emit_load_i64(keys_ptr, ir_is_empty);
676  empty_key_val = ir_is_empty->addConstant<ConstantInt>(EMPTY_KEY_64, Type::Int64);
677  break;
678  }
679  default:
680  LOG(FATAL) << "Invalid key width";
681  }
682  }
683  const auto ret =
684  ir_is_empty->add<ICmp>(ICmp::Predicate::EQ, key, empty_key_val, "is_key_empty");
685  ir_is_empty->add<Ret>(ret);
686 }
GroupByPerfectHash
Definition: enums.h:58
bool is_aggregate_query(const QueryDescriptionType hash_type)
#define EMPTY_KEY_64
Value * emit_read_int_from_buff(Value *ptr, const int8_t compact_sz, Function *function)
#define LOG(tag)
Definition: Logger.h:285
#define CHECK_GE(x, y)
Definition: Logger.h:306
size_t getEffectiveKeyWidth() const
const std::vector< int64_t > target_init_vals_
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
Value * emit_load_i32(Value *ptr, Function *function)
size_t get_byteoff_of_slot(const size_t slot_idx, const QueryMemoryDescriptor &query_mem_desc)
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
QueryDescriptionType getQueryDescriptionType() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
Value * emit_load_i64(Value *ptr, Function *function)
#define CHECK(condition)
Definition: Logger.h:291
#define EMPTY_KEY_32
int32_t getTargetIdxForKey() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceLoop ( const ReductionCode reduction_code) const
protected

Definition at line 1033 of file ResultSetReductionJIT.cpp.

References anonymous_namespace{ResultSetReductionJIT.cpp}::generate_loop_body(), Int32, ReductionCode::ir_reduce_loop, and ReductionCode::ir_reduce_one_entry_idx.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

1033  {
1034  auto ir_reduce_loop = reduction_code.ir_reduce_loop.get();
1035  const auto this_buff_arg = ir_reduce_loop->arg(0);
1036  const auto that_buff_arg = ir_reduce_loop->arg(1);
1037  const auto start_index_arg = ir_reduce_loop->arg(2);
1038  const auto end_index_arg = ir_reduce_loop->arg(3);
1039  const auto that_entry_count_arg = ir_reduce_loop->arg(4);
1040  const auto this_qmd_handle_arg = ir_reduce_loop->arg(5);
1041  const auto that_qmd_handle_arg = ir_reduce_loop->arg(6);
1042  const auto serialized_varlen_buffer_arg = ir_reduce_loop->arg(7);
1043  For* for_loop =
1044  static_cast<For*>(ir_reduce_loop->add<For>(start_index_arg, end_index_arg, ""));
1045  generate_loop_body(for_loop,
1046  ir_reduce_loop,
1047  reduction_code.ir_reduce_one_entry_idx.get(),
1048  this_buff_arg,
1049  that_buff_arg,
1050  start_index_arg,
1051  that_entry_count_arg,
1052  this_qmd_handle_arg,
1053  that_qmd_handle_arg,
1054  serialized_varlen_buffer_arg);
1055  ir_reduce_loop->add<Ret>(ir_reduce_loop->addConstant<ConstantInt>(0, Type::Int32));
1056 }
std::unique_ptr< Function > ir_reduce_loop
void generate_loop_body(For *for_loop, Function *ir_reduce_loop, Function *ir_reduce_one_entry_idx, Value *this_buff, Value *that_buff, Value *start_index, Value *that_entry_count, Value *this_qmd_handle, Value *that_qmd_handle, Value *serialized_varlen_buffer)
std::unique_ptr< Function > ir_reduce_one_entry_idx

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneAggregateSlot ( Value this_ptr1,
Value this_ptr2,
Value that_ptr1,
Value that_ptr2,
const TargetInfo target_info,
const size_t  target_logical_idx,
const size_t  target_slot_idx,
const int64_t  init_val,
const int8_t  chosen_bytes,
Function ir_reduce_one_entry 
) const
private

Definition at line 1133 of file ResultSetReductionJIT.cpp.

References TargetInfo::agg_kind, CHECK_EQ, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_aggregate_one_count(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_aggregate_one_nullable_value(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), is_distinct_target(), kAPPROX_COUNT_DISTINCT, kAPPROX_QUANTILE, kAVG, kCOUNT, kCOUNT_IF, kMAX, kMIN, kMODE, kSUM, kSUM_IF, query_mem_desc_, reduceOneApproxQuantileSlot(), reduceOneCountDistinctSlot(), reduceOneModeSlot(), and UNREACHABLE.

Referenced by reduceOneSlot().

1142  {
1143  auto agg_kind = target_info.agg_kind;
1144  switch (agg_kind) {
1145  case kCOUNT:
1146  case kCOUNT_IF:
1148  if (is_distinct_target(target_info)) {
1149  CHECK_EQ(static_cast<size_t>(chosen_bytes), sizeof(int64_t));
1151  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1152  break;
1153  }
1154  CHECK_EQ(int64_t(0), init_val);
1155  emit_aggregate_one_count(this_ptr1, that_ptr1, chosen_bytes, ir_reduce_one_entry);
1156  break;
1157  case kAPPROX_QUANTILE:
1158  CHECK_EQ(sizeof(int64_t), static_cast<size_t>(chosen_bytes));
1160  this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1161  break;
1162  case kMODE:
1163  reduceOneModeSlot(this_ptr1, that_ptr1, target_logical_idx, ir_reduce_one_entry);
1164  break;
1165  case kAVG:
1166  // Ignore float argument compaction for count component for fear of its overflow
1167  emit_aggregate_one_count(this_ptr2,
1168  that_ptr2,
1169  query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx),
1170  ir_reduce_one_entry);
1171  agg_kind = kSUM;
1172  // fall thru
1173  case kSUM:
1174  case kMIN:
1175  case kMAX:
1176  // for conditional aggregation, we already "conditionally" aggregate value for each
1177  // resultset, so reduction just can use the non-conditional aggregation logic
1178  case kSUM_IF:
1180  this_ptr1,
1181  that_ptr1,
1182  init_val,
1183  chosen_bytes,
1184  target_info,
1185  ir_reduce_one_entry);
1186  break;
1187  default:
1188  UNREACHABLE() << "Invalid aggregate type: " << agg_kind;
1189  }
1190 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
#define UNREACHABLE()
Definition: Logger.h:338
const QueryMemoryDescriptor query_mem_desc_
Definition: sqldefs.h:78
void reduceOneCountDistinctSlot(Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
void emit_aggregate_one_nullable_value(SQLAgg const sql_agg, Value *val_ptr, Value *other_ptr, const int64_t init_val, const size_t chosen_bytes, const TargetInfo &agg_info, Function *ir_reduce_one_entry)
Definition: sqldefs.h:80
bool is_distinct_target(const TargetInfo &target_info)
Definition: TargetInfo.h:102
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
SQLAgg agg_kind
Definition: TargetInfo.h:51
Definition: sqldefs.h:81
void emit_aggregate_one_count(Value *val_ptr, Value *other_ptr, const size_t chosen_bytes, Function *ir_reduce_one_entry)
Definition: sqldefs.h:79
Definition: sqldefs.h:77
void reduceOneApproxQuantileSlot(Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
Definition: sqldefs.h:86
void reduceOneModeSlot(Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneApproxQuantileSlot ( Value this_ptr1,
Value that_ptr1,
const size_t  target_logical_idx,
Function ir_reduce_one_entry 
) const
private

Definition at line 1214 of file ResultSetReductionJIT.cpp.

References CHECK_LT, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i64(), QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), Int64, query_mem_desc_, and Void.

Referenced by reduceOneAggregateSlot().

1218  {
1220  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1221  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1222  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1223  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1224  ir_reduce_one_entry->add<ExternalCall>(
1225  "approx_quantile_jit_rt",
1226  Type::Void,
1227  std::vector<const Value*>{
1228  new_set_handle,
1229  old_set_handle,
1230  that_qmd_arg,
1231  this_qmd_arg,
1232  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1233  "");
1234 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
Value * emit_load_i64(Value *ptr, Function *function)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneCountDistinctSlot ( Value this_ptr1,
Value that_ptr1,
const size_t  target_logical_idx,
Function ir_reduce_one_entry 
) const
private

Definition at line 1192 of file ResultSetReductionJIT.cpp.

References CHECK_LT, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i64(), QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), Int64, query_mem_desc_, and Void.

Referenced by reduceOneAggregateSlot().

1196  {
1198  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1199  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1200  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1201  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1202  ir_reduce_one_entry->add<ExternalCall>(
1203  "count_distinct_set_union_jit_rt",
1204  Type::Void,
1205  std::vector<const Value*>{
1206  new_set_handle,
1207  old_set_handle,
1208  that_qmd_arg,
1209  this_qmd_arg,
1210  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1211  "");
1212 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
Value * emit_load_i64(Value *ptr, Function *function)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneEntryBaseline ( const ReductionCode reduction_code) const
private

Definition at line 803 of file ResultSetReductionJIT.cpp.

References advance_slot(), QueryMemoryDescriptor::getTargetGroupbyIndex(), Int32, ReductionCode::ir_reduce_one_entry, kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), targets_, and to_string().

Referenced by codegen().

804  {
805  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
806  const auto this_targets_ptr_arg = ir_reduce_one_entry->arg(0);
807  const auto that_targets_ptr_arg = ir_reduce_one_entry->arg(1);
808  Value* this_ptr1 = this_targets_ptr_arg;
809  Value* that_ptr1 = that_targets_ptr_arg;
810  size_t j = 0;
811  size_t init_agg_val_idx = 0;
812  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
813  ++target_logical_idx) {
814  const auto& target_info = targets_[target_logical_idx];
815  Value* this_ptr2{nullptr};
816  Value* that_ptr2{nullptr};
817  if (target_info.is_agg &&
818  (target_info.agg_kind == kAVG ||
819  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
820  const auto desc = "target_" + std::to_string(target_logical_idx) + "_second_slot";
821  const auto second_slot_rel_off =
822  ir_reduce_one_entry->addConstant<ConstantInt>(sizeof(int64_t), Type::Int32);
823  this_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
824  this_ptr1, second_slot_rel_off, "this_" + desc);
825  that_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
826  that_ptr1, second_slot_rel_off, "that_" + desc);
827  }
828  reduceOneSlot(this_ptr1,
829  this_ptr2,
830  that_ptr1,
831  that_ptr2,
832  target_info,
833  target_logical_idx,
834  j,
835  init_agg_val_idx,
836  j,
837  ir_reduce_one_entry);
838  if (target_logical_idx + 1 == targets_.size()) {
839  break;
840  }
842  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
843  } else {
844  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
845  init_agg_val_idx = advance_slot(init_agg_val_idx, target_info, false);
846  }
847  }
848  j = advance_slot(j, target_info, false);
849  const auto next_desc =
850  "target_" + std::to_string(target_logical_idx + 1) + "_first_slot";
851  auto next_slot_rel_off = ir_reduce_one_entry->addConstant<ConstantInt>(
852  init_agg_val_idx * sizeof(int64_t), Type::Int32);
853  this_ptr1 = ir_reduce_one_entry->add<GetElementPtr>(
854  this_targets_ptr_arg, next_slot_rel_off, next_desc);
855  that_ptr1 = ir_reduce_one_entry->add<GetElementPtr>(
856  that_targets_ptr_arg, next_slot_rel_off, next_desc);
857  }
858  ir_reduce_one_entry->add<Ret>(
859  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32));
860 }
void reduceOneSlot(Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *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 size_t first_slot_idx_for_target, Function *ir_reduce_one_entry) const
int64_t getTargetGroupbyIndex(const size_t target_idx) const
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
size_t advance_slot(const size_t j, const TargetInfo &target_info, const bool separate_varlen_storage)
size_t targetGroupbyIndicesSize() const
Definition: sqldefs.h:77
const std::vector< TargetInfo > targets_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneEntryBaselineIdx ( const ReductionCode reduction_code) const
private

Definition at line 896 of file ResultSetReductionJIT.cpp.

References Cast::BitCast, CHECK, QueryMemoryDescriptor::didOutputColumnar(), get_row_bytes(), get_slot_off_quad(), QueryMemoryDescriptor::getGroupbyColCount(), QueryMemoryDescriptor::getQueryDescriptionType(), heavyai::GroupByBaselineHash, QueryMemoryDescriptor::hasKeylessHash(), Int1, Int32, Int64, Int64Ptr, Int8, Int8Ptr, ReductionCode::ir_is_empty, ReductionCode::ir_reduce_one_entry, ReductionCode::ir_reduce_one_entry_idx, BinaryOperator::Mul, query_mem_desc_, Cast::SExt, Cast::Trunc, and Void.

Referenced by codegen().

897  {
898  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
903  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
904  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
905  const auto that_entry_idx = ir_reduce_one_entry_idx->arg(2);
906  const auto that_entry_count = ir_reduce_one_entry_idx->arg(3);
907  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
908  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
909  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
910  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
912  const auto that_entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
913  Cast::CastOp::SExt, that_entry_idx, Type::Int64, "that_entry_idx_64");
914  const auto that_row_off_in_bytes =
915  ir_reduce_one_entry_idx->add<BinaryOperator>(BinaryOperator::BinaryOp::Mul,
916  that_entry_idx_64,
917  row_bytes,
918  "that_row_off_in_bytes");
919  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
920  that_buff, that_row_off_in_bytes, "that_row_ptr");
921  const auto that_is_empty =
922  ir_reduce_one_entry_idx->add<Call>(reduction_code.ir_is_empty.get(),
923  std::vector<const Value*>{that_row_ptr},
924  "that_is_empty");
925  ir_reduce_one_entry_idx->add<ReturnEarly>(
926  that_is_empty,
927  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
928  "");
929  const auto key_count = query_mem_desc_.getGroupbyColCount();
930  const auto one_element =
931  ir_reduce_one_entry_idx->addConstant<ConstantInt>(1, Type::Int32);
932  const auto this_targets_ptr_i64_ptr = ir_reduce_one_entry_idx->add<Alloca>(
933  Type::Int64Ptr, one_element, "this_targets_ptr_out");
934  const auto this_is_empty_ptr =
935  ir_reduce_one_entry_idx->add<Alloca>(Type::Int8, one_element, "this_is_empty_out");
936  ir_reduce_one_entry_idx->add<ExternalCall>(
937  "get_group_value_reduction_rt",
938  Type::Void,
939  std::vector<const Value*>{
940  this_buff,
941  that_row_ptr,
942  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_count, Type::Int32),
943  this_qmd_handle,
944  that_buff,
945  that_entry_idx,
946  that_entry_count,
947  row_bytes,
948  this_targets_ptr_i64_ptr,
949  this_is_empty_ptr},
950  "");
951  const auto this_targets_ptr_i64 = ir_reduce_one_entry_idx->add<Load>(
952  this_targets_ptr_i64_ptr, "this_targets_ptr_i64");
953  auto this_is_empty =
954  ir_reduce_one_entry_idx->add<Load>(this_is_empty_ptr, "this_is_empty");
955  this_is_empty = ir_reduce_one_entry_idx->add<Cast>(
956  Cast::CastOp::Trunc, this_is_empty, Type::Int1, "this_is_empty_bool");
957  ir_reduce_one_entry_idx->add<ReturnEarly>(
958  this_is_empty,
959  ir_reduce_one_entry_idx->addConstant<ConstantInt>(0, Type::Int32),
960  "");
961  const auto key_qw_count = get_slot_off_quad(query_mem_desc_);
962  const auto this_targets_ptr = ir_reduce_one_entry_idx->add<Cast>(
963  Cast::CastOp::BitCast, this_targets_ptr_i64, Type::Int8Ptr, "this_targets_ptr");
964  const auto key_byte_count = key_qw_count * sizeof(int64_t);
965  const auto key_byte_count_lv =
966  ir_reduce_one_entry_idx->addConstant<ConstantInt>(key_byte_count, Type::Int32);
967  const auto that_targets_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
968  that_row_ptr, key_byte_count_lv, "that_targets_ptr");
969  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
970  reduction_code.ir_reduce_one_entry.get(),
971  std::vector<const Value*>{this_targets_ptr,
972  that_targets_ptr,
973  this_qmd_handle,
974  that_qmd_handle,
975  serialized_varlen_buffer_arg},
976  "");
977  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
978 }
size_t get_slot_off_quad(const QueryMemoryDescriptor &query_mem_desc)
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
size_t getGroupbyColCount() const
std::unique_ptr< Function > ir_reduce_one_entry_idx
QueryDescriptionType getQueryDescriptionType() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
GroupByBaselineHash
Definition: enums.h:58
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneEntryNoCollisions ( const ReductionCode reduction_code) const
protected

Definition at line 688 of file ResultSetReductionJIT.cpp.

References align_to_int64(), get_key_bytes_rowwise(), Int32, ReductionCode::ir_is_empty, ReductionCode::ir_reduce_one_entry, query_mem_desc_, and reduceOneEntryTargetsNoCollisions().

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

689  {
690  auto ir_reduce_one_entry = reduction_code.ir_reduce_one_entry.get();
691  const auto this_row_ptr = ir_reduce_one_entry->arg(0);
692  const auto that_row_ptr = ir_reduce_one_entry->arg(1);
693  const auto that_is_empty =
694  ir_reduce_one_entry->add<Call>(reduction_code.ir_is_empty.get(),
695  std::vector<const Value*>{that_row_ptr},
696  "that_is_empty");
697  ir_reduce_one_entry->add<ReturnEarly>(
698  that_is_empty, ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32), "");
699 
700  const auto key_bytes = get_key_bytes_rowwise(query_mem_desc_);
701  if (key_bytes) { // copy the key from right hand side
702  ir_reduce_one_entry->add<MemCpy>(
703  this_row_ptr,
704  that_row_ptr,
705  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes, Type::Int32));
706  }
707 
708  const auto key_bytes_with_padding = align_to_int64(key_bytes);
709  const auto key_bytes_lv =
710  ir_reduce_one_entry->addConstant<ConstantInt>(key_bytes_with_padding, Type::Int32);
711  const auto this_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
712  this_row_ptr, key_bytes_lv, "this_targets_start");
713  const auto that_targets_start_ptr = ir_reduce_one_entry->add<GetElementPtr>(
714  that_row_ptr, key_bytes_lv, "that_targets_start");
715 
717  ir_reduce_one_entry, this_targets_start_ptr, that_targets_start_ptr);
718 }
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_is_empty
void reduceOneEntryTargetsNoCollisions(Function *ir_reduce_one_entry, Value *this_targets_start_ptr, Value *that_targets_start_ptr) const
size_t get_key_bytes_rowwise(const QueryMemoryDescriptor &query_mem_desc)
FORCE_INLINE HOST DEVICE T align_to_int64(T addr)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneEntryNoCollisionsIdx ( const ReductionCode reduction_code) const
protected

Definition at line 862 of file ResultSetReductionJIT.cpp.

References CHECK, get_row_bytes(), QueryMemoryDescriptor::getQueryDescriptionType(), heavyai::GroupByPerfectHash, Int64, ReductionCode::ir_reduce_one_entry, ReductionCode::ir_reduce_one_entry_idx, BinaryOperator::Mul, heavyai::NonGroupedAggregate, query_mem_desc_, and Cast::SExt.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

863  {
864  auto ir_reduce_one_entry_idx = reduction_code.ir_reduce_one_entry_idx.get();
869  const auto this_buff = ir_reduce_one_entry_idx->arg(0);
870  const auto that_buff = ir_reduce_one_entry_idx->arg(1);
871  const auto entry_idx = ir_reduce_one_entry_idx->arg(2);
872  const auto this_qmd_handle = ir_reduce_one_entry_idx->arg(4);
873  const auto that_qmd_handle = ir_reduce_one_entry_idx->arg(5);
874  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry_idx->arg(6);
875  const auto row_bytes = ir_reduce_one_entry_idx->addConstant<ConstantInt>(
877  const auto entry_idx_64 = ir_reduce_one_entry_idx->add<Cast>(
878  Cast::CastOp::SExt, entry_idx, Type::Int64, "entry_idx_64");
879  const auto row_off_in_bytes = ir_reduce_one_entry_idx->add<BinaryOperator>(
880  BinaryOperator::BinaryOp::Mul, entry_idx_64, row_bytes, "row_off_in_bytes");
881  const auto this_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
882  this_buff, row_off_in_bytes, "this_row_ptr");
883  const auto that_row_ptr = ir_reduce_one_entry_idx->add<GetElementPtr>(
884  that_buff, row_off_in_bytes, "that_row_ptr");
885  const auto reduce_rc = ir_reduce_one_entry_idx->add<Call>(
886  reduction_code.ir_reduce_one_entry.get(),
887  std::vector<const Value*>{this_row_ptr,
888  that_row_ptr,
889  this_qmd_handle,
890  that_qmd_handle,
891  serialized_varlen_buffer_arg},
892  "");
893  ir_reduce_one_entry_idx->add<Ret>(reduce_rc);
894 }
GroupByPerfectHash
Definition: enums.h:58
NonGroupedAggregate
Definition: enums.h:58
std::unique_ptr< Function > ir_reduce_one_entry
const QueryMemoryDescriptor query_mem_desc_
std::unique_ptr< Function > ir_reduce_one_entry_idx
QueryDescriptionType getQueryDescriptionType() const
size_t get_row_bytes(const QueryMemoryDescriptor &query_mem_desc)
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneEntryTargetsNoCollisions ( Function ir_reduce_one_entry,
Value this_targets_start_ptr,
Value that_targets_start_ptr 
) const
private

Definition at line 720 of file ResultSetReductionJIT.cpp.

References QueryMemoryDescriptor::getColSlotContext(), QueryMemoryDescriptor::getPaddedSlotWidthBytes(), QueryMemoryDescriptor::getTargetGroupbyIndex(), Int32, kAVG, kSAMPLE, query_mem_desc_, reduceOneSlot(), QueryMemoryDescriptor::targetGroupbyIndicesSize(), targets_, to_string(), and UNLIKELY.

Referenced by reduceOneEntryNoCollisions().

723  {
724  const auto& col_slot_context = query_mem_desc_.getColSlotContext();
725  Value* this_targets_ptr = this_targets_start_ptr;
726  Value* that_targets_ptr = that_targets_start_ptr;
727  size_t init_agg_val_idx = 0;
728  for (size_t target_logical_idx = 0; target_logical_idx < targets_.size();
729  ++target_logical_idx) {
730  const auto& target_info = targets_[target_logical_idx];
731  const auto& slots_for_col = col_slot_context.getSlotsForCol(target_logical_idx);
732  Value* this_ptr2{nullptr};
733  Value* that_ptr2{nullptr};
734 
735  bool two_slot_target{false};
736  if (target_info.is_agg &&
737  (target_info.agg_kind == kAVG ||
738  (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()))) {
739  // Note that this assumes if one of the slot pairs in a given target is an array,
740  // all slot pairs are arrays. Currently this is true for all geo targets, but we
741  // should better codify and store this information in the future
742  two_slot_target = true;
743  }
744 
745  for (size_t target_slot_idx = slots_for_col.front();
746  target_slot_idx < slots_for_col.back() + 1;
747  target_slot_idx += 2) {
748  const auto slot_off_val = query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx);
749  const auto slot_off =
750  ir_reduce_one_entry->addConstant<ConstantInt>(slot_off_val, Type::Int32);
751  if (UNLIKELY(two_slot_target)) {
752  const auto desc = "target_" + std::to_string(target_logical_idx) + "_second_slot";
753  this_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
754  this_targets_ptr, slot_off, "this_" + desc);
755  that_ptr2 = ir_reduce_one_entry->add<GetElementPtr>(
756  that_targets_ptr, slot_off, "that_" + desc);
757  }
758  reduceOneSlot(this_targets_ptr,
759  this_ptr2,
760  that_targets_ptr,
761  that_ptr2,
762  target_info,
763  target_logical_idx,
764  target_slot_idx,
765  init_agg_val_idx,
766  slots_for_col.front(),
767  ir_reduce_one_entry);
768  auto increment_agg_val_idx_maybe =
769  [&init_agg_val_idx, &target_logical_idx, this](const int slot_count) {
771  query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) < 0) {
772  init_agg_val_idx += slot_count;
773  }
774  };
775  if (target_logical_idx + 1 == targets_.size() &&
776  target_slot_idx + 1 >= slots_for_col.back()) {
777  break;
778  }
779  const auto next_desc =
780  "target_" + std::to_string(target_logical_idx + 1) + "_first_slot";
781  if (UNLIKELY(two_slot_target)) {
782  increment_agg_val_idx_maybe(2);
783  const auto two_slot_off = ir_reduce_one_entry->addConstant<ConstantInt>(
784  slot_off_val + query_mem_desc_.getPaddedSlotWidthBytes(target_slot_idx + 1),
785  Type::Int32);
786  this_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
787  this_targets_ptr, two_slot_off, "this_" + next_desc);
788  that_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
789  that_targets_ptr, two_slot_off, "that_" + next_desc);
790  } else {
791  increment_agg_val_idx_maybe(1);
792  this_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
793  this_targets_ptr, slot_off, "this_" + next_desc);
794  that_targets_ptr = ir_reduce_one_entry->add<GetElementPtr>(
795  that_targets_ptr, slot_off, "that_" + next_desc);
796  }
797  }
798  }
799  ir_reduce_one_entry->add<Ret>(
800  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32));
801 }
void reduceOneSlot(Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *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 size_t first_slot_idx_for_target, Function *ir_reduce_one_entry) const
int64_t getTargetGroupbyIndex(const size_t target_idx) const
const QueryMemoryDescriptor query_mem_desc_
std::string to_string(char const *&&v)
size_t targetGroupbyIndicesSize() const
const int8_t getPaddedSlotWidthBytes(const size_t slot_idx) const
#define UNLIKELY(x)
Definition: likely.h:25
const ColSlotContext & getColSlotContext() const
Definition: sqldefs.h:77
const std::vector< TargetInfo > targets_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneModeSlot ( Value this_ptr1,
Value that_ptr1,
const size_t  target_logical_idx,
Function ir_reduce_one_entry 
) const
private

Definition at line 1236 of file ResultSetReductionJIT.cpp.

References CHECK_LT, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_load_i64(), QueryMemoryDescriptor::getCountDistinctDescriptorsSize(), Int64, query_mem_desc_, and Void.

Referenced by reduceOneAggregateSlot().

1239  {
1241  const auto old_set_handle = emit_load_i64(this_ptr1, ir_reduce_one_entry);
1242  const auto new_set_handle = emit_load_i64(that_ptr1, ir_reduce_one_entry);
1243  const auto this_qmd_arg = ir_reduce_one_entry->arg(2);
1244  const auto that_qmd_arg = ir_reduce_one_entry->arg(3);
1245  ir_reduce_one_entry->add<ExternalCall>(
1246  "mode_jit_rt",
1247  Type::Void,
1248  std::vector<const Value*>{
1249  new_set_handle,
1250  old_set_handle,
1251  that_qmd_arg,
1252  this_qmd_arg,
1253  ir_reduce_one_entry->addConstant<ConstantInt>(target_logical_idx, Type::Int64)},
1254  "");
1255 }
const QueryMemoryDescriptor query_mem_desc_
size_t getCountDistinctDescriptorsSize() const
#define CHECK_LT(x, y)
Definition: Logger.h:303
Value * emit_load_i64(Value *ptr, Function *function)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void ResultSetReductionJIT::reduceOneSlot ( Value this_ptr1,
Value this_ptr2,
Value that_ptr1,
Value 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 size_t  first_slot_idx_for_target,
Function ir_reduce_one_entry 
) const
private

Definition at line 1058 of file ResultSetReductionJIT.cpp.

References TargetInfo::agg_kind, CHECK, CHECK_LT, anonymous_namespace{ResultSetReductionJIT.cpp}::emit_checked_write_projection(), anonymous_namespace{ResultSetReductionJIT.cpp}::emit_write_projection(), SQLTypeInfo::get_elem_type(), result_set::get_width_for_slot(), QueryMemoryDescriptor::getTargetGroupbyIndex(), Int32, Int64, TargetInfo::is_agg, SQLTypeInfo::is_geometry(), SQLTypeInfo::is_string(), SQLTypeInfo::is_varlen(), kSAMPLE, kSINGLE_VALUE, ICmp::NE, query_mem_desc_, reduceOneAggregateSlot(), TargetInfo::sql_type, takes_float_argument(), target_init_vals_, QueryMemoryDescriptor::targetGroupbyIndicesSize(), and Void.

Referenced by reduceOneEntryBaseline(), and reduceOneEntryTargetsNoCollisions().

1067  {
1069  if (query_mem_desc_.getTargetGroupbyIndex(target_logical_idx) >= 0) {
1070  return;
1071  }
1072  }
1073  const bool float_argument_input = takes_float_argument(target_info);
1074  const auto chosen_bytes = result_set::get_width_for_slot(
1075  target_slot_idx, float_argument_input, query_mem_desc_);
1076  CHECK_LT(init_agg_val_idx, target_init_vals_.size());
1077  auto init_val = target_init_vals_[init_agg_val_idx];
1078  if (target_info.is_agg &&
1079  (target_info.agg_kind != kSINGLE_VALUE && target_info.agg_kind != kSAMPLE)) {
1080  reduceOneAggregateSlot(this_ptr1,
1081  this_ptr2,
1082  that_ptr1,
1083  that_ptr2,
1084  target_info,
1085  target_logical_idx,
1086  target_slot_idx,
1087  init_val,
1088  chosen_bytes,
1089  ir_reduce_one_entry);
1090  } else if (target_info.agg_kind == kSINGLE_VALUE) {
1091  const auto checked_rc = emit_checked_write_projection(
1092  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1093 
1094  auto checked_rc_bool = ir_reduce_one_entry->add<ICmp>(
1096  checked_rc,
1097  ir_reduce_one_entry->addConstant<ConstantInt>(0, Type::Int32),
1098  "");
1099 
1100  ir_reduce_one_entry->add<ReturnEarly>(checked_rc_bool, checked_rc, "");
1101 
1102  } else {
1104  this_ptr1, that_ptr1, init_val, chosen_bytes, ir_reduce_one_entry);
1105  if (target_info.agg_kind == kSAMPLE && target_info.sql_type.is_varlen()) {
1106  CHECK(this_ptr2 && that_ptr2);
1107  size_t length_to_elems{0};
1108  if (target_info.sql_type.is_geometry()) {
1109  // TODO: Assumes hard-coded sizes for geometry targets
1110  length_to_elems = target_slot_idx == first_slot_idx_for_target ? 1 : 4;
1111  } else {
1112  const auto& elem_ti = target_info.sql_type.get_elem_type();
1113  length_to_elems = target_info.sql_type.is_string() ? 1 : elem_ti.get_size();
1114  }
1115  const auto serialized_varlen_buffer_arg = ir_reduce_one_entry->arg(4);
1116  ir_reduce_one_entry->add<ExternalCall>(
1117  "serialized_varlen_buffer_sample",
1118  Type::Void,
1119  std::vector<const Value*>{
1120  serialized_varlen_buffer_arg,
1121  this_ptr1,
1122  this_ptr2,
1123  that_ptr1,
1124  that_ptr2,
1125  ir_reduce_one_entry->addConstant<ConstantInt>(init_val, Type::Int64),
1126  ir_reduce_one_entry->addConstant<ConstantInt>(length_to_elems,
1127  Type::Int64)},
1128  "");
1129  }
1130  }
1131 }
int64_t getTargetGroupbyIndex(const size_t target_idx) const
SQLTypeInfo sql_type
Definition: TargetInfo.h:52
bool is_varlen() const
Definition: sqltypes.h:631
const std::vector< int64_t > target_init_vals_
void reduceOneAggregateSlot(Value *this_ptr1, Value *this_ptr2, Value *that_ptr1, Value *that_ptr2, const TargetInfo &target_info, const size_t target_logical_idx, const size_t target_slot_idx, const int64_t init_val, const int8_t chosen_bytes, Function *ir_reduce_one_entry) const
bool takes_float_argument(const TargetInfo &target_info)
Definition: TargetInfo.h:106
const Value * emit_checked_write_projection(Value *slot_pi8, Value *other_pi8, const int64_t init_val, const size_t chosen_bytes, Function *ir_reduce_one_entry)
const QueryMemoryDescriptor query_mem_desc_
int8_t get_width_for_slot(const size_t target_slot_idx, const bool float_argument_input, const QueryMemoryDescriptor &query_mem_desc)
bool is_agg
Definition: TargetInfo.h:50
size_t targetGroupbyIndicesSize() const
void emit_write_projection(Value *slot_pi8, Value *other_pi8, const int64_t init_val, const size_t chosen_bytes, Function *ir_reduce_one_entry)
SQLAgg agg_kind
Definition: TargetInfo.h:51
#define CHECK_LT(x, y)
Definition: Logger.h:303
#define CHECK(condition)
Definition: Logger.h:291
bool is_geometry() const
Definition: sqltypes.h:597
bool is_string() const
Definition: sqltypes.h:561
SQLTypeInfo get_elem_type() const
Definition: sqltypes.h:977

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

size_t ResultSetReductionJIT::executor_id_
protected

Definition at line 78 of file ResultSetReductionJIT.h.

Referenced by codegen(), and GpuReductionHelperJIT::codegen().

const std::vector<int64_t> ResultSetReductionJIT::target_init_vals_
private

Definition at line 142 of file ResultSetReductionJIT.h.

Referenced by cacheKey(), isEmpty(), and reduceOneSlot().

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

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