OmniSciDB  ab4938a6a3
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 <ostream>
31 #include <set>
32 #include <unordered_map>
33 #include <vector>
34 
35 #include "../CompilationOptions.h"
36 #include "Shared/Logger.h"
37 
38 namespace Fragmenter_Namespace {
39 class FragmentInfo;
40 }
41 
42 namespace Data_Namespace {
43 struct MemoryInfo;
44 }
45 
46 class Executor;
47 struct InputTableInfo;
48 struct RelAlgExecutionUnit;
49 
51  int table_id;
52  std::vector<size_t> fragment_ids;
53 };
54 
55 using FragmentsList = std::vector<FragmentsPerTable>;
56 using TableFragments = std::vector<Fragmenter_Namespace::FragmentInfo>;
57 
59  int device_id;
61  std::optional<size_t> outer_tuple_count; // only for fragments with an exact tuple
62  // count available in metadata
63 };
64 
66  public:
68  const std::vector<InputTableInfo>& query_infos,
69  const std::vector<Data_Namespace::MemoryInfo>& gpu_mem_infos,
70  const double gpu_input_mem_limit_percent,
71  const std::vector<size_t> allowed_outer_fragment_indices);
72 
73  static void computeAllTablesFragments(
74  std::map<int, const TableFragments*>& all_tables_fragments,
75  const RelAlgExecutionUnit& ra_exe_unit,
76  const std::vector<InputTableInfo>& query_infos);
77 
78  void buildFragmentKernelMap(const RelAlgExecutionUnit& ra_exe_unit,
79  const std::vector<uint64_t>& frag_offsets,
80  const int device_count,
81  const ExecutorDeviceType& device_type,
82  const bool enable_multifrag_kernels,
83  const bool enable_inner_join_fragment_skipping,
84  Executor* executor);
85 
90  template <typename DISPATCH_FCN>
91  void assignFragsToMultiDispatch(DISPATCH_FCN f) const {
92  for (const auto& device_itr : execution_kernels_per_device_) {
93  const auto& execution_kernels = device_itr.second;
94  CHECK_EQ(execution_kernels.size(), size_t(1));
95 
96  const auto& fragments_list = execution_kernels.front().fragments;
97  f(device_itr.first, fragments_list, rowid_lookup_key_);
98  }
99  }
100 
107  template <typename DISPATCH_FCN>
108  void assignFragsToKernelDispatch(DISPATCH_FCN f,
109  const RelAlgExecutionUnit& ra_exe_unit) const {
110  if (execution_kernels_per_device_.empty()) {
111  return;
112  }
113 
114  size_t tuple_count = 0;
115 
116  std::unordered_map<int, size_t> execution_kernel_index;
117  for (const auto& device_itr : execution_kernels_per_device_) {
118  CHECK(execution_kernel_index.insert(std::make_pair(device_itr.first, size_t(0)))
119  .second);
120  }
121 
122  bool dispatch_finished = false;
123  while (!dispatch_finished) {
124  dispatch_finished = true;
125  for (const auto& device_itr : execution_kernels_per_device_) {
126  auto& kernel_idx = execution_kernel_index[device_itr.first];
127  if (kernel_idx < device_itr.second.size()) {
128  dispatch_finished = false;
129  const auto& execution_kernel = device_itr.second[kernel_idx++];
130  f(device_itr.first, execution_kernel.fragments, rowid_lookup_key_);
131  if (terminateDispatchMaybe(tuple_count, ra_exe_unit, execution_kernel)) {
132  return;
133  }
134  }
135  }
136  }
137  }
138 
140  return rowid_lookup_key_ < 0 && !execution_kernels_per_device_.empty();
141  }
142 
143  protected:
144  std::vector<size_t> allowed_outer_fragment_indices_;
145  size_t outer_fragments_size_ = 0;
146  int64_t rowid_lookup_key_ = -1;
147 
148  std::map<int, const TableFragments*> selected_tables_fragments_;
149 
150  std::map<int, std::vector<ExecutionKernel>> execution_kernels_per_device_;
151 
153  std::map<size_t, size_t> tuple_count_per_device_;
154  std::map<size_t, size_t> available_gpu_mem_bytes_;
155 
156  void buildFragmentPerKernelMapForUnion(const RelAlgExecutionUnit& ra_exe_unit,
157  const std::vector<uint64_t>& frag_offsets,
158  const int device_count,
159  const ExecutorDeviceType& device_type,
160  Executor* executor);
161 
162  void buildFragmentPerKernelMap(const RelAlgExecutionUnit& ra_exe_unit,
163  const std::vector<uint64_t>& frag_offsets,
164  const int device_count,
165  const ExecutorDeviceType& device_type,
166  Executor* executor);
167 
168  void buildMultifragKernelMap(const RelAlgExecutionUnit& ra_exe_unit,
169  const std::vector<uint64_t>& frag_offsets,
170  const int device_count,
171  const ExecutorDeviceType& device_type,
172  const bool enable_inner_join_fragment_skipping,
173  Executor* executor);
174 
175  bool terminateDispatchMaybe(size_t& tuple_count,
176  const RelAlgExecutionUnit& ra_exe_unit,
177  const ExecutionKernel& kernel) const;
178 
179  void checkDeviceMemoryUsage(const Fragmenter_Namespace::FragmentInfo& fragment,
180  const int device_id,
181  const size_t num_cols);
182 };
183 
184 std::ostream& operator<<(std::ostream&, FragmentsPerTable const&);
185 
186 #endif // QUERYENGINE_QUERYFRAGMENTDESCRIPTOR_H
std::map< int, const TableFragments * > selected_tables_fragments_
#define CHECK_EQ(x, y)
Definition: Logger.h:205
std::map< size_t, size_t > tuple_count_per_device_
ExecutorDeviceType
void assignFragsToMultiDispatch(DISPATCH_FCN f) const
std::vector< Fragmenter_Namespace::FragmentInfo > TableFragments
std::vector< FragmentsPerTable > FragmentsList
Used by Fragmenter classes to store info about each fragment - the fragment id and number of tuples(r...
Definition: Fragmenter.h:78
std::optional< size_t > outer_tuple_count
void assignFragsToKernelDispatch(DISPATCH_FCN f, const RelAlgExecutionUnit &ra_exe_unit) const
#define CHECK(condition)
Definition: Logger.h:197
std::map< int, std::vector< ExecutionKernel > > execution_kernels_per_device_
std::vector< size_t > allowed_outer_fragment_indices_
std::vector< size_t > fragment_ids
std::map< size_t, size_t > available_gpu_mem_bytes_
std::ostream & operator<<(std::ostream &, FragmentsPerTable const &)