OmniSciDB  b24e664e58
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
QueryFragmentDescriptor.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 MapD Technologies, 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 
23 #ifndef QUERYENGINE_QUERYFRAGMENTDESCRIPTOR_H
24 #define QUERYENGINE_QUERYFRAGMENTDESCRIPTOR_H
25 
26 #include <deque>
27 #include <map>
28 #include <memory>
29 #include <optional>
30 #include <set>
31 #include <unordered_map>
32 #include <vector>
33 
34 #include "../CompilationOptions.h"
35 #include "Shared/Logger.h"
36 
37 namespace Fragmenter_Namespace {
38 class FragmentInfo;
39 }
40 
41 namespace Data_Namespace {
42 struct MemoryInfo;
43 }
44 
45 class Executor;
46 struct InputTableInfo;
47 struct RelAlgExecutionUnit;
48 
50  int table_id;
51  std::vector<size_t> fragment_ids;
52 };
53 
54 using FragmentsList = std::vector<FragmentsPerTable>;
55 using TableFragments = std::deque<Fragmenter_Namespace::FragmentInfo>;
56 
58  int device_id;
60  std::optional<size_t> outer_tuple_count; // only for fragments with an exact tuple
61  // count available in metadata
62 };
63 
65  public:
67  const std::vector<InputTableInfo>& query_infos,
68  const std::vector<Data_Namespace::MemoryInfo>& gpu_mem_infos,
69  const double gpu_input_mem_limit_percent);
70 
71  static void computeAllTablesFragments(
72  std::map<int, const TableFragments*>& all_tables_fragments,
73  const RelAlgExecutionUnit& ra_exe_unit,
74  const std::vector<InputTableInfo>& query_infos);
75 
76  void buildFragmentKernelMap(const RelAlgExecutionUnit& ra_exe_unit,
77  const std::vector<uint64_t>& frag_offsets,
78  const int device_count,
79  const ExecutorDeviceType& device_type,
80  const bool enable_multifrag_kernels,
81  const bool enable_inner_join_fragment_skipping,
82  Executor* executor);
83 
88  template <typename DISPATCH_FCN>
89  void assignFragsToMultiDispatch(DISPATCH_FCN f) const {
90  for (const auto& device_itr : execution_kernels_per_device_) {
91  const auto& execution_kernels = device_itr.second;
92  CHECK_EQ(execution_kernels.size(), size_t(1));
93 
94  const auto& fragments_list = execution_kernels.front().fragments;
95  f(device_itr.first, fragments_list, rowid_lookup_key_);
96  }
97  }
98 
105  template <typename DISPATCH_FCN>
106  void assignFragsToKernelDispatch(DISPATCH_FCN f,
107  const RelAlgExecutionUnit& ra_exe_unit) const {
108  if (execution_kernels_per_device_.empty()) {
109  return;
110  }
111 
112  size_t tuple_count = 0;
113 
114  std::unordered_map<int, size_t> execution_kernel_index;
115  for (const auto& device_itr : execution_kernels_per_device_) {
116  CHECK(execution_kernel_index.insert(std::make_pair(device_itr.first, size_t(0)))
117  .second);
118  }
119 
120  bool dispatch_finished = false;
121  while (!dispatch_finished) {
122  dispatch_finished = true;
123  for (const auto& device_itr : execution_kernels_per_device_) {
124  auto& kernel_idx = execution_kernel_index[device_itr.first];
125  if (kernel_idx < device_itr.second.size()) {
126  dispatch_finished = false;
127  const auto& execution_kernel = device_itr.second[kernel_idx++];
128  f(device_itr.first, execution_kernel.fragments, rowid_lookup_key_);
129 
130  if (terminateDispatchMaybe(tuple_count, ra_exe_unit, execution_kernel)) {
131  return;
132  }
133  }
134  }
135  }
136  }
137 
139  return rowid_lookup_key_ < 0 && !execution_kernels_per_device_.empty();
140  }
141 
142  protected:
144  int64_t rowid_lookup_key_ = -1;
145 
146  std::map<int, const TableFragments*> selected_tables_fragments_;
147 
148  std::map<int, std::vector<ExecutionKernel>> execution_kernels_per_device_;
149 
151  std::map<size_t, size_t> tuple_count_per_device_;
152  std::map<size_t, size_t> available_gpu_mem_bytes_;
153 
154  void buildFragmentPerKernelMap(const RelAlgExecutionUnit& ra_exe_unit,
155  const std::vector<uint64_t>& frag_offsets,
156  const int device_count,
157  const ExecutorDeviceType& device_type,
158  Executor* executor);
159 
160  void buildMultifragKernelMap(const RelAlgExecutionUnit& ra_exe_unit,
161  const std::vector<uint64_t>& frag_offsets,
162  const int device_count,
163  const ExecutorDeviceType& device_type,
164  const bool enable_inner_join_fragment_skipping,
165  Executor* executor);
166 
167  bool terminateDispatchMaybe(size_t& tuple_count,
168  const RelAlgExecutionUnit& ra_exe_unit,
169  const ExecutionKernel& kernel) const;
170 
172  const int device_id,
173  const size_t num_cols);
174 };
175 
176 #endif // QUERYENGINE_QUERYFRAGMENTDESCRIPTOR_H
QueryFragmentDescriptor(const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &query_infos, const std::vector< Data_Namespace::MemoryInfo > &gpu_mem_infos, const double gpu_input_mem_limit_percent)
std::map< int, const TableFragments * > selected_tables_fragments_
#define CHECK_EQ(x, y)
Definition: Logger.h:198
std::map< size_t, size_t > tuple_count_per_device_
ExecutorDeviceType
void buildMultifragKernelMap(const RelAlgExecutionUnit &ra_exe_unit, const std::vector< uint64_t > &frag_offsets, const int device_count, const ExecutorDeviceType &device_type, const bool enable_inner_join_fragment_skipping, Executor *executor)
void assignFragsToKernelDispatch(DISPATCH_FCN f, const RelAlgExecutionUnit &ra_exe_unit) const
std::vector< FragmentsPerTable > FragmentsList
CHECK(cgen_state)
void buildFragmentPerKernelMap(const RelAlgExecutionUnit &ra_exe_unit, const std::vector< uint64_t > &frag_offsets, const int device_count, const ExecutorDeviceType &device_type, Executor *executor)
Used by Fragmenter classes to store info about each fragment - the fragment id and number of tuples(r...
Definition: Fragmenter.h:79
std::deque< Fragmenter_Namespace::FragmentInfo > TableFragments
void checkDeviceMemoryUsage(const Fragmenter_Namespace::FragmentInfo &fragment, const int device_id, const size_t num_cols)
bool terminateDispatchMaybe(size_t &tuple_count, const RelAlgExecutionUnit &ra_exe_unit, const ExecutionKernel &kernel) const
std::optional< size_t > outer_tuple_count
void assignFragsToMultiDispatch(DISPATCH_FCN f) const
std::map< int, std::vector< ExecutionKernel > > execution_kernels_per_device_
std::vector< size_t > fragment_ids
void buildFragmentKernelMap(const RelAlgExecutionUnit &ra_exe_unit, const std::vector< uint64_t > &frag_offsets, const int device_count, const ExecutorDeviceType &device_type, const bool enable_multifrag_kernels, const bool enable_inner_join_fragment_skipping, Executor *executor)
std::map< size_t, size_t > available_gpu_mem_bytes_
static void computeAllTablesFragments(std::map< int, const TableFragments * > &all_tables_fragments, const RelAlgExecutionUnit &ra_exe_unit, const std::vector< InputTableInfo > &query_infos)