OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultSetReductionJIT.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "CgenState.h"
20 #include "CodeCache.h"
21 #include "ResultSetReductionOps.h"
22 
24 #include "Shared/TargetInfo.h"
25 
26 #include <llvm/ExecutionEngine/ExecutionEngine.h>
27 #include <llvm/IR/Module.h>
28 #include <llvm/IR/Value.h>
29 
30 struct ReductionCode {
31  // Function which reduces 'that_buff' into 'this_buff', for rows between
32  // [start_entry_index, end_entry_index).
33  using FuncPtr = int32_t (*)(int8_t* this_buff,
34  const int8_t* that_buff,
35  const int32_t start_entry_index,
36  const int32_t end_entry_index,
37  const int32_t that_entry_count,
38  const void* this_qmd,
39  const void* that_qmd,
40  const void* serialized_varlen_buffer);
41 
43  llvm::Function* llvm_reduce_loop;
45  llvm::Module* module;
46  std::unique_ptr<Function> ir_is_empty;
47  std::unique_ptr<Function> ir_reduce_one_entry;
48  std::unique_ptr<Function> ir_reduce_one_entry_idx;
49  std::unique_ptr<Function> ir_reduce_loop;
50 };
51 
53  public:
55  const std::vector<TargetInfo>& targets,
56  const std::vector<int64_t>& target_init_vals,
57  const size_t executor_id);
58  virtual ~ResultSetReductionJIT() = default;
59 
60  // Generate the code for the result set reduction loop.
61  virtual ReductionCode codegen() const;
62 
63  protected:
64  // Generate a function which checks whether a row is empty.
65  void isEmpty(const ReductionCode& reduction_code) const;
66 
67  // Generate a function which reduces two rows given by their start pointer, for the
68  // perfect hash layout.
69  void reduceOneEntryNoCollisions(const ReductionCode& reduction_code) const;
70 
71  // Generate a function which reduces two rows given by the start pointer of the result
72  // buffers they are part of and the indices inside those buffers.
73  void reduceOneEntryNoCollisionsIdx(const ReductionCode& reduction_code) const;
74 
75  // Generate a function for the reduction of an entire result set chunk.
76  void reduceLoop(const ReductionCode& reduction_code) const;
77 
78  size_t executor_id_;
79 
80  private:
81  // Used to implement 'reduceOneEntryNoCollisions'.
82  void reduceOneEntryTargetsNoCollisions(Function* ir_reduce_one_entry,
83  Value* this_targets_start_ptr,
84  Value* that_targets_start_ptr) const;
85 
86  // Same as above, for the baseline layout.
87  void reduceOneEntryBaseline(const ReductionCode& reduction_code) const;
88 
89  // Same as above, for the baseline layout.
90  void reduceOneEntryBaselineIdx(const ReductionCode& reduction_code) const;
91 
92  // Generate reduction code for a single slot.
93  void reduceOneSlot(Value* this_ptr1,
94  Value* this_ptr2,
95  Value* that_ptr1,
96  Value* that_ptr2,
97  const TargetInfo& target_info,
98  const size_t target_logical_idx,
99  const size_t target_slot_idx,
100  const size_t init_agg_val_idx,
101  const size_t first_slot_idx_for_target,
102  Function* ir_reduce_one_entry) const;
103 
104  // Generate reduction code for a single aggregate (with the exception of sample) slot.
105  void reduceOneAggregateSlot(Value* this_ptr1,
106  Value* this_ptr2,
107  Value* that_ptr1,
108  Value* that_ptr2,
109  const TargetInfo& target_info,
110  const size_t target_logical_idx,
111  const size_t target_slot_idx,
112  const int64_t init_val,
113  const int8_t chosen_bytes,
114  Function* ir_reduce_one_entry) const;
115 
116  // Generate reduction code for a count distinct slot.
117  void reduceOneCountDistinctSlot(Value* this_ptr1,
118  Value* that_ptr1,
119  const size_t target_logical_idx,
120  Function* ir_reduce_one_entry) const;
121 
122  void reduceOneApproxQuantileSlot(Value* this_ptr1,
123  Value* that_ptr1,
124  const size_t target_logical_idx,
125  Function* ir_reduce_one_entry) const;
126 
127  void reduceOneModeSlot(Value* this_ptr1,
128  Value* that_ptr1,
129  const size_t target_logical_idx,
130  Function* ir_reduce_one_entry) const;
131 
132  void finalizeReductionCode(ReductionCode& reduction_code,
133  const llvm::Function* ir_is_empty,
134  const llvm::Function* ir_reduce_one_entry,
135  const llvm::Function* ir_reduce_one_entry_idx,
136  const CodeCacheKey& key) const;
137 
138  std::string cacheKey() const;
139 
141  const std::vector<TargetInfo> targets_;
142  const std::vector<int64_t> target_init_vals_;
143 };
144 
151  public:
153  const std::vector<TargetInfo>& targets,
154  const std::vector<int64_t>& target_init_vals,
155  const size_t executor_id)
156  : ResultSetReductionJIT(query_mem_desc, targets, target_init_vals, executor_id)
157  , query_mem_desc_(query_mem_desc) {
162  }
169  ReductionCode codegen() const override;
170 
171  private:
173 };
GroupByPerfectHash
Definition: enums.h:58
CgenState * cgen_state
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 reduceOneEntryNoCollisions(const ReductionCode &reduction_code) const
std::unique_ptr< Function > ir_reduce_loop
void reduceOneEntryBaselineIdx(const ReductionCode &reduction_code) const
void reduceLoop(const ReductionCode &reduction_code) const
llvm::Function * llvm_reduce_loop
void reduceOneEntryNoCollisionsIdx(const ReductionCode &reduction_code) const
std::vector< std::string > CodeCacheKey
Definition: CodeCache.h:24
std::string cacheKey() const
std::unique_ptr< Function > ir_reduce_one_entry
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
const QueryMemoryDescriptor & query_mem_desc_
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_
std::unique_ptr< Function > ir_is_empty
virtual ~ResultSetReductionJIT()=default
void reduceOneCountDistinctSlot(Value *this_ptr1, Value *that_ptr1, const size_t target_logical_idx, Function *ir_reduce_one_entry) const
GpuReductionHelperJIT(const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &target_init_vals, const size_t executor_id)
ReductionCode codegen() const override
std::unique_ptr< Function > ir_reduce_one_entry_idx
void reduceOneEntryTargetsNoCollisions(Function *ir_reduce_one_entry, Value *this_targets_start_ptr, Value *that_targets_start_ptr) const
QueryDescriptionType getQueryDescriptionType() const
virtual ReductionCode codegen() const
llvm::Module * module
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
Descriptor for the result set buffer layout.
void isEmpty(const ReductionCode &reduction_code) const
#define CHECK(condition)
Definition: Logger.h:291
void reduceOneEntryBaseline(const ReductionCode &reduction_code) const
ResultSetReductionJIT(const QueryMemoryDescriptor &query_mem_desc, const std::vector< TargetInfo > &targets, const std::vector< int64_t > &target_init_vals, const size_t executor_id)
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
const std::vector< TargetInfo > targets_