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

#include <PerfectJoinHashTable.h>

+ Inheritance diagram for PerfectJoinHashTable:
+ Collaboration diagram for PerfectJoinHashTable:

Classes

struct  AlternativeCacheKeyForPerfectHashJoin
 

Public Member Functions

std::string toString (const ExecutorDeviceType device_type, const int device_id=0, bool raw=false) const override
 
std::set
< DecodedJoinHashBufferEntry
toSet (const ExecutorDeviceType device_type, const int device_id) const override
 
llvm::Value * codegenSlot (const CompilationOptions &, const size_t) override
 
HashJoinMatchingSet codegenMatchingSet (const CompilationOptions &, const size_t) override
 
int getInnerTableId () const noexceptoverride
 
int getInnerTableRteIdx () const noexceptoverride
 
HashType getHashType () const noexceptoverride
 
Data_Namespace::MemoryLevel getMemoryLevel () const noexceptoverride
 
int getDeviceCount () const noexceptoverride
 
size_t offsetBufferOff () const noexceptoverride
 
size_t countBufferOff () const noexceptoverride
 
size_t payloadBufferOff () const noexceptoverride
 
std::string getHashJoinType () const final
 
virtual ~PerfectJoinHashTable ()
 
- Public Member Functions inherited from HashJoin
virtual std::string toStringFlat64 (const ExecutorDeviceType device_type, const int device_id) const
 
virtual std::string toStringFlat32 (const ExecutorDeviceType device_type, const int device_id) const
 
JoinColumn fetchJoinColumn (const Analyzer::ColumnVar *hash_col, const std::vector< Fragmenter_Namespace::FragmentInfo > &fragment_info, const Data_Namespace::MemoryLevel effective_memory_level, const int device_id, std::vector< std::shared_ptr< Chunk_NS::Chunk >> &chunks_owner, DeviceAllocator *dev_buff_owner, std::vector< std::shared_ptr< void >> &malloc_owner, Executor *executor, ColumnCacheMap *column_cache)
 
HashTablegetHashTableForDevice (const size_t device_id) const
 
size_t getJoinHashBufferSize (const ExecutorDeviceType device_type)
 
size_t getJoinHashBufferSize (const ExecutorDeviceType device_type, const int device_id) const
 
int8_t * getJoinHashBuffer (const ExecutorDeviceType device_type, const int device_id) const
 
void freeHashBufferMemory ()
 

Static Public Member Functions

static std::shared_ptr
< PerfectJoinHashTable
getInstance (const std::shared_ptr< Analyzer::BinOper > qual_bin_oper, const std::vector< InputTableInfo > &query_infos, const Data_Namespace::MemoryLevel memory_level, const JoinType join_type, const HashType preferred_hash_type, const int device_count, ColumnCacheMap &column_cache, Executor *executor, const HashTableBuildDagMap &hashtable_build_dag_map, const TableIdToNodeMap &table_id_to_node_map)
 Make hash table from an in-flight SQL query's parse tree etc. More...
 
static HashtableRecyclergetHashTableCache ()
 
static HashingSchemeRecyclergetHashingSchemeCache ()
 
static auto getCacheInvalidator () -> std::function< void()>
 
- Static Public Member Functions inherited from HashJoin
static bool layoutRequiresAdditionalBuffers (HashType layout) noexcept
 
static std::string getHashTypeString (HashType ht) noexcept
 
static HashJoinMatchingSet codegenMatchingSet (const std::vector< llvm::Value * > &hash_join_idx_args_in, const bool is_sharded, const bool col_is_nullable, const bool is_bw_eq, const int64_t sub_buff_size, Executor *executor, const bool is_bucketized=false)
 
static llvm::Value * codegenHashTableLoad (const size_t table_idx, Executor *executor)
 
static std::shared_ptr< HashJoingetInstance (const std::shared_ptr< Analyzer::BinOper > qual_bin_oper, const std::vector< InputTableInfo > &query_infos, const Data_Namespace::MemoryLevel memory_level, const JoinType join_type, const HashType preferred_hash_type, const int device_count, ColumnCacheMap &column_cache, Executor *executor, const HashTableBuildDagMap &hashtable_build_dag_map, const RegisteredQueryHint &query_hint, const TableIdToNodeMap &table_id_to_node_map)
 Make hash table from an in-flight SQL query's parse tree etc. More...
 
static std::shared_ptr< HashJoingetSyntheticInstance (std::string_view table1, std::string_view column1, std::string_view table2, std::string_view column2, const Data_Namespace::MemoryLevel memory_level, const HashType preferred_hash_type, const int device_count, ColumnCacheMap &column_cache, Executor *executor)
 Make hash table from named tables and columns (such as for testing). More...
 
static std::shared_ptr< HashJoingetSyntheticInstance (const std::shared_ptr< Analyzer::BinOper > qual_bin_oper, const Data_Namespace::MemoryLevel memory_level, const HashType preferred_hash_type, const int device_count, ColumnCacheMap &column_cache, Executor *executor)
 Make hash table from named tables and columns (such as for testing). More...
 
static std::pair< std::string,
std::shared_ptr< HashJoin > > 
getSyntheticInstance (std::vector< std::shared_ptr< Analyzer::BinOper >>, const Data_Namespace::MemoryLevel memory_level, const HashType preferred_hash_type, const int device_count, ColumnCacheMap &column_cache, Executor *executor)
 
static int getInnerTableId (const std::vector< InnerOuter > &inner_outer_pairs)
 
static void checkHashJoinReplicationConstraint (const int table_id, const size_t shard_count, const Executor *executor)
 
static InnerOuter normalizeColumnPair (const Analyzer::Expr *lhs, const Analyzer::Expr *rhs, const Catalog_Namespace::Catalog &cat, const TemporaryTables *temporary_tables, const bool is_overlaps_join=false)
 
static std::vector< InnerOuternormalizeColumnPairs (const Analyzer::BinOper *condition, const Catalog_Namespace::Catalog &cat, const TemporaryTables *temporary_tables)
 
static CompositeKeyInfo getCompositeKeyInfo (const std::vector< InnerOuter > &inner_outer_pairs, const Executor *executor)
 

Private Member Functions

ColumnsForDevice fetchColumnsForDevice (const std::vector< Fragmenter_Namespace::FragmentInfo > &fragments, const int device_id, DeviceAllocator *dev_buff_owner, const Catalog_Namespace::Catalog &catalog)
 
void reifyForDevice (const ChunkKey &hash_table_key, const ColumnsForDevice &columns_for_device, const HashType layout, const int device_id, const logger::ThreadId parent_thread_id)
 
int initHashTableForDevice (const ChunkKey &chunk_key, const JoinColumn &join_column, const InnerOuter &cols, const HashType layout, const Data_Namespace::MemoryLevel effective_memory_level, const int device_id)
 
Data_Namespace::MemoryLevel getEffectiveMemoryLevel (const std::vector< InnerOuter > &inner_outer_pairs) const
 
 PerfectJoinHashTable (const std::shared_ptr< Analyzer::BinOper > qual_bin_oper, const Analyzer::ColumnVar *col_var, const std::vector< InputTableInfo > &query_infos, const Data_Namespace::MemoryLevel memory_level, const JoinType join_type, const HashType preferred_hash_type, const ExpressionRange &col_range, ColumnCacheMap &column_cache, Executor *executor, const int device_count, QueryPlanHash hashtable_cache_key, HashtableCacheMetaInfo hashtable_cache_meta_info, const TableIdToNodeMap &table_id_to_node_map)
 
ChunkKey genChunkKey (const std::vector< Fragmenter_Namespace::FragmentInfo > &fragments, const Analyzer::Expr *outer_col, const Analyzer::ColumnVar *inner_col) const
 
void reify ()
 
std::shared_ptr< PerfectHashTableinitHashTableOnCpuFromCache (QueryPlanHash key, CacheItemType item_type, DeviceIdentifier device_identifier)
 
void putHashTableOnCpuToCache (QueryPlanHash key, CacheItemType item_type, std::shared_ptr< PerfectHashTable > hashtable_ptr, DeviceIdentifier device_identifier, size_t hashtable_building_time)
 
const InputTableInfogetInnerQueryInfo (const Analyzer::ColumnVar *inner_col) const
 
size_t shardCount () const
 
llvm::Value * codegenHashTableLoad (const size_t table_idx)
 
std::vector< llvm::Value * > getHashJoinArgs (llvm::Value *hash_ptr, const Analyzer::Expr *key_col, const int shard_count, const CompilationOptions &co)
 
bool isBitwiseEq () const override
 
size_t getComponentBufferSize () const noexceptoverride
 
HashTablegetHashTableForDevice (const size_t device_id) const
 

Static Private Member Functions

static QueryPlanHash getAlternativeCacheKey (AlternativeCacheKeyForPerfectHashJoin &info)
 

Private Attributes

std::vector< InnerOuterinner_outer_pairs_
 
std::shared_ptr
< Analyzer::BinOper
qual_bin_oper_
 
const JoinType join_type_
 
std::shared_ptr
< Analyzer::ColumnVar
col_var_
 
const std::vector
< InputTableInfo > & 
query_infos_
 
const Data_Namespace::MemoryLevel memory_level_
 
HashType hash_type_
 
std::mutex cpu_hash_table_buff_mutex_
 
ExpressionRange col_range_
 
Executorexecutor_
 
ColumnCacheMapcolumn_cache_
 
const int device_count_
 
bool needs_dict_translation_
 
const TableIdToNodeMap table_id_to_node_map_
 
QueryPlanHash hashtable_cache_key_
 
HashtableCacheMetaInfo hashtable_cache_meta_info_
 

Static Private Attributes

static std::unique_ptr
< HashtableRecycler
hash_table_cache_
 
static std::unique_ptr
< HashingSchemeRecycler
hash_table_layout_cache_
 

Additional Inherited Members

- Protected Attributes inherited from HashJoin
std::vector< std::shared_ptr
< HashTable > > 
hash_tables_for_device_
 

Detailed Description

Definition at line 50 of file PerfectJoinHashTable.h.

Constructor & Destructor Documentation

virtual PerfectJoinHashTable::~PerfectJoinHashTable ( )
inlinevirtual

Definition at line 122 of file PerfectJoinHashTable.h.

122 {}
PerfectJoinHashTable::PerfectJoinHashTable ( const std::shared_ptr< Analyzer::BinOper qual_bin_oper,
const Analyzer::ColumnVar col_var,
const std::vector< InputTableInfo > &  query_infos,
const Data_Namespace::MemoryLevel  memory_level,
const JoinType  join_type,
const HashType  preferred_hash_type,
const ExpressionRange col_range,
ColumnCacheMap column_cache,
Executor executor,
const int  device_count,
QueryPlanHash  hashtable_cache_key,
HashtableCacheMetaInfo  hashtable_cache_meta_info,
const TableIdToNodeMap table_id_to_node_map 
)
inlineprivate

Definition at line 150 of file PerfectJoinHashTable.h.

References CHECK, CHECK_GT, device_count_, ExpressionRange::getType(), HashJoin::hash_tables_for_device_, and Integer.

Referenced by getInstance().

163  : qual_bin_oper_(qual_bin_oper)
164  , join_type_(join_type)
165  , col_var_(std::dynamic_pointer_cast<Analyzer::ColumnVar>(col_var->deep_copy()))
166  , query_infos_(query_infos)
167  , memory_level_(memory_level)
168  , hash_type_(preferred_hash_type)
169  , col_range_(col_range)
170  , executor_(executor)
171  , column_cache_(column_cache)
172  , device_count_(device_count)
173  , needs_dict_translation_(false)
174  , table_id_to_node_map_(table_id_to_node_map)
175  , hashtable_cache_key_(hashtable_cache_key)
176  , hashtable_cache_meta_info_(hashtable_cache_meta_info) {
180  }
const Data_Namespace::MemoryLevel memory_level_
std::shared_ptr< Analyzer::BinOper > qual_bin_oper_
QueryPlanHash hashtable_cache_key_
const TableIdToNodeMap table_id_to_node_map_
std::vector< std::shared_ptr< HashTable > > hash_tables_for_device_
Definition: HashJoin.h:296
std::shared_ptr< Analyzer::Expr > deep_copy() const override
Definition: Analyzer.cpp:60
#define CHECK_GT(x, y)
Definition: Logger.h:223
HashtableCacheMetaInfo hashtable_cache_meta_info_
const std::vector< InputTableInfo > & query_infos_
ColumnCacheMap & column_cache_
std::shared_ptr< Analyzer::ColumnVar > col_var_
ExpressionRangeType getType() const
#define CHECK(condition)
Definition: Logger.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Function Documentation

llvm::Value * PerfectJoinHashTable::codegenHashTableLoad ( const size_t  table_idx)
private

Definition at line 765 of file PerfectJoinHashTable.cpp.

References AUTOMATIC_IR_METADATA, CHECK, HashJoin::codegenHashTableLoad(), executor_, and get_arg_by_name().

Referenced by codegenMatchingSet(), and codegenSlot().

765  {
766  AUTOMATIC_IR_METADATA(executor_->cgen_state_.get());
767  const auto hash_ptr = HashJoin::codegenHashTableLoad(table_idx, executor_);
768  if (hash_ptr->getType()->isIntegerTy(64)) {
769  return hash_ptr;
770  }
771  CHECK(hash_ptr->getType()->isPointerTy());
772  return executor_->cgen_state_->ir_builder_.CreatePtrToInt(
773  get_arg_by_name(executor_->cgen_state_->row_func_, "join_hash_tables"),
774  llvm::Type::getInt64Ty(executor_->cgen_state_->context_));
775 }
static llvm::Value * codegenHashTableLoad(const size_t table_idx, Executor *executor)
Definition: HashJoin.cpp:215
llvm::Value * get_arg_by_name(llvm::Function *func, const std::string &name)
Definition: Execute.h:166
#define AUTOMATIC_IR_METADATA(CGENSTATE)
#define CHECK(condition)
Definition: Logger.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

HashJoinMatchingSet PerfectJoinHashTable::codegenMatchingSet ( const CompilationOptions co,
const size_t  index 
)
overridevirtual

Implements HashJoin.

Definition at line 829 of file PerfectJoinHashTable.cpp.

References AUTOMATIC_IR_METADATA, CHECK, codegenHashTableLoad(), HashJoin::codegenMatchingSet(), executor_, anonymous_namespace{HashJoin.cpp}::get_cols(), get_max_rte_scan_table(), getComponentBufferSize(), getHashJoinArgs(), isBitwiseEq(), kDATE, qual_bin_oper_, self_join_not_covered_by_left_deep_tree(), and shardCount().

830  {
831  AUTOMATIC_IR_METADATA(executor_->cgen_state_.get());
832  const auto cols = get_cols(
833  qual_bin_oper_.get(), *executor_->getCatalog(), executor_->temporary_tables_);
834  auto key_col = cols.second;
835  CHECK(key_col);
836  auto val_col = cols.first;
837  CHECK(val_col);
838  auto pos_ptr = codegenHashTableLoad(index);
839  CHECK(pos_ptr);
840  const int shard_count = shardCount();
841  const auto key_col_var = dynamic_cast<const Analyzer::ColumnVar*>(key_col);
842  const auto val_col_var = dynamic_cast<const Analyzer::ColumnVar*>(val_col);
843  if (key_col_var && val_col_var &&
845  key_col_var,
846  val_col_var,
847  get_max_rte_scan_table(executor_->cgen_state_->scan_idx_to_hash_pos_))) {
848  throw std::runtime_error(
849  "Query execution fails because the query contains not supported self-join "
850  "pattern. We suspect the query requires multiple left-deep join tree due to "
851  "the "
852  "join condition of the self-join and is not supported for now. Please consider "
853  "rewriting table order in "
854  "FROM clause.");
855  }
856  auto hash_join_idx_args = getHashJoinArgs(pos_ptr, key_col, shard_count, co);
857  const int64_t sub_buff_size = getComponentBufferSize();
858  const auto& key_col_ti = key_col->get_type_info();
859 
860  auto bucketize = (key_col_ti.get_type() == kDATE);
861  return HashJoin::codegenMatchingSet(hash_join_idx_args,
862  shard_count,
863  !key_col_ti.get_notnull(),
864  isBitwiseEq(),
865  sub_buff_size,
866  executor_,
867  bucketize);
868 }
llvm::Value * codegenHashTableLoad(const size_t table_idx)
virtual HashJoinMatchingSet codegenMatchingSet(const CompilationOptions &, const size_t)=0
bool self_join_not_covered_by_left_deep_tree(const Analyzer::ColumnVar *key_side, const Analyzer::ColumnVar *val_side, const int max_rte_covered)
size_t getComponentBufferSize() const noexceptoverride
std::shared_ptr< Analyzer::BinOper > qual_bin_oper_
const int get_max_rte_scan_table(std::unordered_map< int, llvm::Value * > &scan_idx_to_hash_pos)
std::vector< llvm::Value * > getHashJoinArgs(llvm::Value *hash_ptr, const Analyzer::Expr *key_col, const int shard_count, const CompilationOptions &co)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
Definition: sqltypes.h:53
#define CHECK(condition)
Definition: Logger.h:211
InnerOuter get_cols(const Analyzer::BinOper *qual_bin_oper, const Catalog_Namespace::Catalog &cat, const TemporaryTables *temporary_tables)
Definition: HashJoin.cpp:780
bool isBitwiseEq() const override

+ Here is the call graph for this function:

llvm::Value * PerfectJoinHashTable::codegenSlot ( const CompilationOptions co,
const size_t  index 
)
overridevirtual

Implements HashJoin.

Definition at line 966 of file PerfectJoinHashTable.cpp.

References AUTOMATIC_IR_METADATA, CHECK, CHECK_EQ, CodeGenerator::codegen(), codegenHashTableLoad(), executor_, anonymous_namespace{HashJoin.cpp}::get_cols(), get_max_rte_scan_table(), Analyzer::Expr::get_type_info(), getHashJoinArgs(), getHashType(), isBitwiseEq(), kDATE, OneToOne, qual_bin_oper_, self_join_not_covered_by_left_deep_tree(), and shardCount().

967  {
968  AUTOMATIC_IR_METADATA(executor_->cgen_state_.get());
969  using namespace std::string_literals;
970 
972  const auto cols = get_cols(
973  qual_bin_oper_.get(), *executor_->getCatalog(), executor_->temporary_tables_);
974  auto key_col = cols.second;
975  CHECK(key_col);
976  auto val_col = cols.first;
977  CHECK(val_col);
978  CodeGenerator code_generator(executor_);
979  const auto key_col_var = dynamic_cast<const Analyzer::ColumnVar*>(key_col);
980  const auto val_col_var = dynamic_cast<const Analyzer::ColumnVar*>(val_col);
981  if (key_col_var && val_col_var &&
983  key_col_var,
984  val_col_var,
985  get_max_rte_scan_table(executor_->cgen_state_->scan_idx_to_hash_pos_))) {
986  throw std::runtime_error(
987  "Query execution fails because the query contains not supported self-join "
988  "pattern. We suspect the query requires multiple left-deep join tree due to "
989  "the "
990  "join condition of the self-join and is not supported for now. Please consider "
991  "rewriting table order in "
992  "FROM clause.");
993  }
994  const auto key_lvs = code_generator.codegen(key_col, true, co);
995  CHECK_EQ(size_t(1), key_lvs.size());
996  auto hash_ptr = codegenHashTableLoad(index);
997  CHECK(hash_ptr);
998  const int shard_count = shardCount();
999  const auto hash_join_idx_args = getHashJoinArgs(hash_ptr, key_col, shard_count, co);
1000 
1001  const auto& key_col_ti = key_col->get_type_info();
1002  std::string fname((key_col_ti.get_type() == kDATE) ? "bucketized_hash_join_idx"s
1003  : "hash_join_idx"s);
1004 
1005  if (isBitwiseEq()) {
1006  fname += "_bitwise";
1007  }
1008  if (shard_count) {
1009  fname += "_sharded";
1010  }
1011 
1012  if (!isBitwiseEq() && !key_col_ti.get_notnull()) {
1013  fname += "_nullable";
1014  }
1015  return executor_->cgen_state_->emitCall(fname, hash_join_idx_args);
1016 }
llvm::Value * codegenHashTableLoad(const size_t table_idx)
#define CHECK_EQ(x, y)
Definition: Logger.h:219
bool self_join_not_covered_by_left_deep_tree(const Analyzer::ColumnVar *key_side, const Analyzer::ColumnVar *val_side, const int max_rte_covered)
std::shared_ptr< Analyzer::BinOper > qual_bin_oper_
const int get_max_rte_scan_table(std::unordered_map< int, llvm::Value * > &scan_idx_to_hash_pos)
HashType getHashType() const noexceptoverride
std::vector< llvm::Value * > getHashJoinArgs(llvm::Value *hash_ptr, const Analyzer::Expr *key_col, const int shard_count, const CompilationOptions &co)
#define AUTOMATIC_IR_METADATA(CGENSTATE)
Definition: sqltypes.h:53
#define CHECK(condition)
Definition: Logger.h:211
InnerOuter get_cols(const Analyzer::BinOper *qual_bin_oper, const Catalog_Namespace::Catalog &cat, const TemporaryTables *temporary_tables)
Definition: HashJoin.cpp:780
bool isBitwiseEq() const override

+ Here is the call graph for this function:

size_t PerfectJoinHashTable::countBufferOff ( ) const
overridevirtualnoexcept

Implements HashJoin.

Definition at line 874 of file PerfectJoinHashTable.cpp.

References getComponentBufferSize().

Referenced by toSet(), and toString().

874  {
875  return getComponentBufferSize();
876 }
size_t getComponentBufferSize() const noexceptoverride

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ColumnsForDevice PerfectJoinHashTable::fetchColumnsForDevice ( const std::vector< Fragmenter_Namespace::FragmentInfo > &  fragments,
const int  device_id,
DeviceAllocator dev_buff_owner,
const Catalog_Namespace::Catalog catalog 
)
private

Definition at line 455 of file PerfectJoinHashTable.cpp.

References column_cache_, executor_, HashJoin::fetchJoinColumn(), get_column_descriptor_maybe(), get_join_column_type_kind(), getEffectiveMemoryLevel(), inline_fixed_encoding_null_val(), inner_outer_pairs_, and isBitwiseEq().

Referenced by reify().

459  {
460  const auto effective_memory_level = getEffectiveMemoryLevel(inner_outer_pairs_);
461  std::vector<JoinColumn> join_columns;
462  std::vector<std::shared_ptr<Chunk_NS::Chunk>> chunks_owner;
463  std::vector<JoinColumnTypeInfo> join_column_types;
464  std::vector<JoinBucketInfo> join_bucket_info;
465  std::vector<std::shared_ptr<void>> malloc_owner;
466  for (const auto& inner_outer_pair : inner_outer_pairs_) {
467  const auto inner_col = inner_outer_pair.first;
468  const auto inner_cd = get_column_descriptor_maybe(
469  inner_col->get_column_id(), inner_col->get_table_id(), catalog);
470  if (inner_cd && inner_cd->isVirtualCol) {
472  }
473  join_columns.emplace_back(fetchJoinColumn(inner_col,
474  fragments,
475  effective_memory_level,
476  device_id,
477  chunks_owner,
478  dev_buff_owner,
479  malloc_owner,
480  executor_,
481  &column_cache_));
482  const auto& ti = inner_col->get_type_info();
483  join_column_types.emplace_back(JoinColumnTypeInfo{static_cast<size_t>(ti.get_size()),
484  0,
485  0,
487  isBitwiseEq(),
488  0,
490  }
491  return {join_columns, join_column_types, chunks_owner, join_bucket_info, malloc_owner};
492 }
Data_Namespace::MemoryLevel getEffectiveMemoryLevel(const std::vector< InnerOuter > &inner_outer_pairs) const
JoinColumn fetchJoinColumn(const Analyzer::ColumnVar *hash_col, const std::vector< Fragmenter_Namespace::FragmentInfo > &fragment_info, const Data_Namespace::MemoryLevel effective_memory_level, const int device_id, std::vector< std::shared_ptr< Chunk_NS::Chunk >> &chunks_owner, DeviceAllocator *dev_buff_owner, std::vector< std::shared_ptr< void >> &malloc_owner, Executor *executor, ColumnCacheMap *column_cache)
Definition: HashJoin.cpp:54
const ColumnDescriptor * get_column_descriptor_maybe(const int col_id, const int table_id, const Catalog_Namespace::Catalog &cat)
Definition: Execute.h:220
std::vector< InnerOuter > inner_outer_pairs_
ColumnCacheMap & column_cache_
ColumnType get_join_column_type_kind(const SQLTypeInfo &ti)
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
bool isBitwiseEq() const override

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ChunkKey PerfectJoinHashTable::genChunkKey ( const std::vector< Fragmenter_Namespace::FragmentInfo > &  fragments,
const Analyzer::Expr outer_col,
const Analyzer::ColumnVar inner_col 
) const
private

Definition at line 709 of file PerfectJoinHashTable.cpp.

References CHECK, CHECK_EQ, executor_, Analyzer::ColumnVar::get_column_id(), Analyzer::ColumnVar::get_table_id(), Analyzer::Expr::get_type_info(), getInnerQueryInfo(), Fragmenter_Namespace::TableInfo::getNumTuples(), InputTableInfo::info, and kENCODING_DICT.

Referenced by reify().

712  {
713  ChunkKey chunk_key{executor_->getCatalog()->getCurrentDB().dbId,
714  inner_col->get_table_id(),
715  inner_col->get_column_id()};
716  const auto& ti = inner_col->get_type_info();
717  if (ti.is_string()) {
718  CHECK_EQ(kENCODING_DICT, ti.get_compression());
719  size_t outer_elem_count = 0;
720  const auto outer_col = dynamic_cast<const Analyzer::ColumnVar*>(outer_col_expr);
721  CHECK(outer_col);
722  const auto& outer_query_info = getInnerQueryInfo(outer_col).info;
723  for (auto& frag : outer_query_info.fragments) {
724  outer_elem_count = frag.getNumTuples();
725  }
726  chunk_key.push_back(outer_elem_count);
727  }
728  if (fragments.size() < 2) {
729  chunk_key.push_back(fragments.front().fragmentId);
730  }
731  return chunk_key;
732 }
int get_table_id() const
Definition: Analyzer.h:193
#define CHECK_EQ(x, y)
Definition: Logger.h:219
std::vector< int > ChunkKey
Definition: types.h:37
Fragmenter_Namespace::TableInfo info
Definition: InputMetadata.h:35
const InputTableInfo & getInnerQueryInfo(const Analyzer::ColumnVar *inner_col) const
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
#define CHECK(condition)
Definition: Logger.h:211
int get_column_id() const
Definition: Analyzer.h:194

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static QueryPlanHash PerfectJoinHashTable::getAlternativeCacheKey ( AlternativeCacheKeyForPerfectHashJoin info)
inlinestaticprivate

Definition at line 224 of file PerfectJoinHashTable.h.

References PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::chunk_key, PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::col_range, Analyzer::Expr::get_type_info(), PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::inner_col, SQLTypeInfo::is_string(), PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::join_type, PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::num_elements, PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::optype, PerfectJoinHashTable::AlternativeCacheKeyForPerfectHashJoin::outer_col, toString(), ExpressionRange::toString(), and Analyzer::ColumnVar::toString().

Referenced by reify().

225  {
226  auto hash = boost::hash_value(::toString(info.chunk_key));
227  boost::hash_combine(hash, info.inner_col->toString());
228  if (info.inner_col->get_type_info().is_string()) {
229  boost::hash_combine(hash, info.outer_col->toString());
230  }
231  boost::hash_combine(hash, info.col_range.toString());
232  boost::hash_combine(hash, info.num_elements);
233  boost::hash_combine(hash, ::toString(info.optype));
234  boost::hash_combine(hash, ::toString(info.join_type));
235  return hash;
236  }
std::string toString(const ExecutorDeviceType device_type, const int device_id=0, bool raw=false) const override

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static auto PerfectJoinHashTable::getCacheInvalidator ( ) -> std::function<void()>
inlinestatic

Definition at line 110 of file PerfectJoinHashTable.h.

References CHECK, hash_table_cache_, and hash_table_layout_cache_.

110  {
113  return []() -> void {
114  auto layout_cache_invalidator = hash_table_layout_cache_->getCacheInvalidator();
115  layout_cache_invalidator();
116 
117  auto main_cache_invalidator = hash_table_cache_->getCacheInvalidator();
118  main_cache_invalidator();
119  };
120  }
static std::unique_ptr< HashtableRecycler > hash_table_cache_
static std::unique_ptr< HashingSchemeRecycler > hash_table_layout_cache_
#define CHECK(condition)
Definition: Logger.h:211
size_t PerfectJoinHashTable::getComponentBufferSize ( ) const
overrideprivatevirtualnoexcept

Implements HashJoin.

Definition at line 882 of file PerfectJoinHashTable.cpp.

References HashJoin::hash_tables_for_device_, and OneToMany.

Referenced by codegenMatchingSet(), countBufferOff(), and payloadBufferOff().

882  {
883  if (hash_tables_for_device_.empty()) {
884  return 0;
885  }
886  auto hash_table = hash_tables_for_device_.front();
887  if (hash_table && hash_table->getLayout() == HashType::OneToMany) {
888  return hash_table->getEntryCount() * sizeof(int32_t);
889  } else {
890  return 0;
891  }
892 }
std::vector< std::shared_ptr< HashTable > > hash_tables_for_device_
Definition: HashJoin.h:296

+ Here is the caller graph for this function:

int PerfectJoinHashTable::getDeviceCount ( ) const
inlineoverridevirtualnoexcept

Implements HashJoin.

Definition at line 91 of file PerfectJoinHashTable.h.

References device_count_.

91 { return device_count_; };
Data_Namespace::MemoryLevel PerfectJoinHashTable::getEffectiveMemoryLevel ( const std::vector< InnerOuter > &  inner_outer_pairs) const
private

Definition at line 443 of file PerfectJoinHashTable.cpp.

References Data_Namespace::CPU_LEVEL, executor_, memory_level_, needs_dict_translation_, and needs_dictionary_translation().

Referenced by fetchColumnsForDevice(), and reifyForDevice().

444  {
445  for (const auto& inner_outer_pair : inner_outer_pairs) {
447  inner_outer_pair.first, inner_outer_pair.second, executor_)) {
450  }
451  }
452  return memory_level_;
453 }
const Data_Namespace::MemoryLevel memory_level_
bool needs_dictionary_translation(const Analyzer::ColumnVar *inner_col, const Analyzer::Expr *outer_col_expr, const Executor *executor)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static HashingSchemeRecycler* PerfectJoinHashTable::getHashingSchemeCache ( )
inlinestatic

Definition at line 105 of file PerfectJoinHashTable.h.

References CHECK, and hash_table_layout_cache_.

105  {
107  return hash_table_layout_cache_.get();
108  }
static std::unique_ptr< HashingSchemeRecycler > hash_table_layout_cache_
#define CHECK(condition)
Definition: Logger.h:211
std::vector< llvm::Value * > PerfectJoinHashTable::getHashJoinArgs ( llvm::Value *  hash_ptr,
const Analyzer::Expr key_col,
const int  shard_count,
const CompilationOptions co 
)
private

Definition at line 777 of file PerfectJoinHashTable.cpp.

References AUTOMATIC_IR_METADATA, CHECK_EQ, col_range_, device_count_, executor_, anonymous_namespace{PerfectJoinHashTable.cpp}::get_bucketized_hash_entry_info(), anonymous_namespace{PerfectJoinHashTable.cpp}::get_hash_entry_count(), get_logical_type_info(), SQLTypeInfo::get_type(), Analyzer::Expr::get_type_info(), ExpressionRange::getIntMax(), ExpressionRange::getIntMin(), inline_fixed_encoding_null_val(), isBitwiseEq(), and kDATE.

Referenced by codegenMatchingSet(), and codegenSlot().

781  {
782  AUTOMATIC_IR_METADATA(executor_->cgen_state_.get());
783  CodeGenerator code_generator(executor_);
784  const auto key_lvs = code_generator.codegen(key_col, true, co);
785  CHECK_EQ(size_t(1), key_lvs.size());
786  auto const& key_col_ti = key_col->get_type_info();
787  auto hash_entry_info =
789 
790  std::vector<llvm::Value*> hash_join_idx_args{
791  hash_ptr,
792  executor_->cgen_state_->castToTypeIn(key_lvs.front(), 64),
793  executor_->cgen_state_->llInt(col_range_.getIntMin()),
794  executor_->cgen_state_->llInt(col_range_.getIntMax())};
795  if (shard_count) {
796  const auto expected_hash_entry_count =
798  const auto entry_count_per_shard =
799  (expected_hash_entry_count + shard_count - 1) / shard_count;
800  hash_join_idx_args.push_back(
801  executor_->cgen_state_->llInt<uint32_t>(entry_count_per_shard));
802  hash_join_idx_args.push_back(executor_->cgen_state_->llInt<uint32_t>(shard_count));
803  hash_join_idx_args.push_back(executor_->cgen_state_->llInt<uint32_t>(device_count_));
804  }
805  auto key_col_logical_ti = get_logical_type_info(key_col->get_type_info());
806  if (!key_col_logical_ti.get_notnull() || isBitwiseEq()) {
807  hash_join_idx_args.push_back(executor_->cgen_state_->llInt(
808  inline_fixed_encoding_null_val(key_col_logical_ti)));
809  }
810  auto special_date_bucketization_case = key_col_ti.get_type() == kDATE;
811  if (isBitwiseEq()) {
812  if (special_date_bucketization_case) {
813  hash_join_idx_args.push_back(executor_->cgen_state_->llInt(
814  col_range_.getIntMax() / hash_entry_info.bucket_normalization + 1));
815  } else {
816  hash_join_idx_args.push_back(
817  executor_->cgen_state_->llInt(col_range_.getIntMax() + 1));
818  }
819  }
820 
821  if (special_date_bucketization_case) {
822  hash_join_idx_args.emplace_back(
823  executor_->cgen_state_->llInt(hash_entry_info.bucket_normalization));
824  }
825 
826  return hash_join_idx_args;
827 }
int64_t getIntMin() const
#define CHECK_EQ(x, y)
Definition: Logger.h:219
size_t get_hash_entry_count(const ExpressionRange &col_range, const bool is_bw_eq)
HashEntryInfo get_bucketized_hash_entry_info(SQLTypeInfo const &context_ti, ExpressionRange const &col_range, bool const is_bw_eq)
SQLTypeInfo get_logical_type_info(const SQLTypeInfo &type_info)
Definition: sqltypes.h:1064
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:329
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:77
Definition: sqltypes.h:53
int64_t getIntMax() const
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
bool isBitwiseEq() const override

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string PerfectJoinHashTable::getHashJoinType ( ) const
inlinefinalvirtual

Implements HashJoin.

Definition at line 99 of file PerfectJoinHashTable.h.

99 { return "Perfect"; }
static HashtableRecycler* PerfectJoinHashTable::getHashTableCache ( )
inlinestatic

Definition at line 101 of file PerfectJoinHashTable.h.

References CHECK, and hash_table_cache_.

Referenced by QueryRunner::QueryRunner::getCachedHashtableWithoutCacheKey(), QueryRunner::QueryRunner::getCachedPerfectHashTable(), QueryRunner::QueryRunner::getCacheItemMetric(), and QueryRunner::QueryRunner::getNumberOfCachedPerfectHashTables().

101  {
103  return hash_table_cache_.get();
104  }
static std::unique_ptr< HashtableRecycler > hash_table_cache_
#define CHECK(condition)
Definition: Logger.h:211

+ Here is the caller graph for this function:

HashTable * PerfectJoinHashTable::getHashTableForDevice ( const size_t  device_id) const
private

Definition at line 894 of file PerfectJoinHashTable.cpp.

References CHECK_LT, and HashJoin::hash_tables_for_device_.

Referenced by toSet(), and toString().

894  {
895  CHECK_LT(device_id, hash_tables_for_device_.size());
896  return hash_tables_for_device_[device_id].get();
897 }
std::vector< std::shared_ptr< HashTable > > hash_tables_for_device_
Definition: HashJoin.h:296
#define CHECK_LT(x, y)
Definition: Logger.h:221

+ Here is the caller graph for this function:

HashType PerfectJoinHashTable::getHashType ( ) const
inlineoverridevirtualnoexcept

Implements HashJoin.

Definition at line 85 of file PerfectJoinHashTable.h.

References hash_type_.

Referenced by codegenSlot().

85 { return hash_type_; }

+ Here is the caller graph for this function:

const InputTableInfo & PerfectJoinHashTable::getInnerQueryInfo ( const Analyzer::ColumnVar inner_col) const
private

Definition at line 1018 of file PerfectJoinHashTable.cpp.

References get_inner_query_info(), Analyzer::ColumnVar::get_table_id(), and query_infos_.

Referenced by genChunkKey(), and reify().

1019  {
1020  return get_inner_query_info(inner_col->get_table_id(), query_infos_);
1021 }
int get_table_id() const
Definition: Analyzer.h:193
const InputTableInfo & get_inner_query_info(const int inner_table_id, const std::vector< InputTableInfo > &query_infos)
const std::vector< InputTableInfo > & query_infos_

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int PerfectJoinHashTable::getInnerTableId ( ) const
inlineoverridevirtualnoexcept

Implements HashJoin.

Definition at line 77 of file PerfectJoinHashTable.h.

References col_var_.

Referenced by reify().

77  {
78  return col_var_.get()->get_table_id();
79  };
std::shared_ptr< Analyzer::ColumnVar > col_var_

+ Here is the caller graph for this function:

int PerfectJoinHashTable::getInnerTableRteIdx ( ) const
inlineoverridevirtualnoexcept

Implements HashJoin.

Definition at line 81 of file PerfectJoinHashTable.h.

References col_var_.

81  {
82  return col_var_.get()->get_rte_idx();
83  };
std::shared_ptr< Analyzer::ColumnVar > col_var_
std::shared_ptr< PerfectJoinHashTable > PerfectJoinHashTable::getInstance ( const std::shared_ptr< Analyzer::BinOper qual_bin_oper,
const std::vector< InputTableInfo > &  query_infos,
const Data_Namespace::MemoryLevel  memory_level,
const JoinType  join_type,
const HashType  preferred_hash_type,
const int  device_count,
ColumnCacheMap column_cache,
Executor executor,
const HashTableBuildDagMap hashtable_build_dag_map,
const TableIdToNodeMap table_id_to_node_map 
)
static

Make hash table from an in-flight SQL query's parse tree etc.

Definition at line 147 of file PerfectJoinHashTable.cpp.

References CHECK, CHECK_EQ, anonymous_namespace{PerfectJoinHashTable.cpp}::get_bucketized_hash_entry_info(), anonymous_namespace{HashJoin.cpp}::get_cols(), getExpressionRange(), HashtableRecycler::getHashtableCacheKey(), HashJoin::getHashTypeString(), HashEntryInfo::getNormalizedHashEntryCount(), Data_Namespace::GPU_LEVEL, Invalid, IS_EQUIVALENCE, kBW_EQ, ExpressionRange::makeIntRange(), PerfectJoinHashTable(), VLOG, and VLOGGING.

Referenced by HashJoin::getInstance().

157  {
158  CHECK(IS_EQUIVALENCE(qual_bin_oper->get_optype()));
159  const auto cols =
160  get_cols(qual_bin_oper.get(), *executor->getCatalog(), executor->temporary_tables_);
161  const auto inner_col = cols.first;
162  CHECK(inner_col);
163  const auto& ti = inner_col->get_type_info();
164  auto col_range =
165  getExpressionRange(ti.is_string() ? cols.second : inner_col, query_infos, executor);
166  if (col_range.getType() == ExpressionRangeType::Invalid) {
167  throw HashJoinFail(
168  "Could not compute range for the expressions involved in the equijoin");
169  }
170  if (ti.is_string()) {
171  // The nullable info must be the same as the source column.
172  const auto source_col_range = getExpressionRange(inner_col, query_infos, executor);
173  if (source_col_range.getType() == ExpressionRangeType::Invalid) {
174  throw HashJoinFail(
175  "Could not compute range for the expressions involved in the equijoin");
176  }
177  if (source_col_range.getIntMin() > source_col_range.getIntMax()) {
178  // If the inner column expression range is empty, use the inner col range
179  CHECK_EQ(source_col_range.getIntMin(), int64_t(0));
180  CHECK_EQ(source_col_range.getIntMax(), int64_t(-1));
181  col_range = source_col_range;
182  } else {
183  col_range = ExpressionRange::makeIntRange(
184  std::min(source_col_range.getIntMin(), col_range.getIntMin()),
185  std::max(source_col_range.getIntMax(), col_range.getIntMax()),
186  0,
187  source_col_range.hasNulls());
188  }
189  }
190  // We can't allocate more than 2GB contiguous memory on GPU and each entry is 4 bytes.
191  const auto max_hash_entry_count =
193  ? static_cast<size_t>(std::numeric_limits<int32_t>::max() / sizeof(int32_t))
194  : static_cast<size_t>(std::numeric_limits<int32_t>::max());
195 
196  auto bucketized_entry_count_info = get_bucketized_hash_entry_info(
197  ti, col_range, qual_bin_oper->get_optype() == kBW_EQ);
198  auto bucketized_entry_count = bucketized_entry_count_info.getNormalizedHashEntryCount();
199 
200  if (bucketized_entry_count > max_hash_entry_count) {
201  throw TooManyHashEntries();
202  }
203 
204  if (qual_bin_oper->get_optype() == kBW_EQ &&
205  col_range.getIntMax() >= std::numeric_limits<int64_t>::max()) {
206  throw HashJoinFail("Cannot translate null value for kBW_EQ");
207  }
208  std::vector<InnerOuter> inner_outer_pairs;
209  inner_outer_pairs.emplace_back(inner_col, cols.second);
210  auto hashtable_cache_key =
211  HashtableRecycler::getHashtableCacheKey(inner_outer_pairs,
212  qual_bin_oper->get_optype(),
213  join_type,
214  hashtable_build_dag_map,
215  executor);
216  auto hash_key = hashtable_cache_key.first;
217  decltype(std::chrono::steady_clock::now()) ts1, ts2;
218  if (VLOGGING(1)) {
219  ts1 = std::chrono::steady_clock::now();
220  }
221  auto join_hash_table = std::shared_ptr<PerfectJoinHashTable>(
222  new PerfectJoinHashTable(qual_bin_oper,
223  inner_col,
224  query_infos,
225  memory_level,
226  join_type,
227  preferred_hash_type,
228  col_range,
229  column_cache,
230  executor,
231  device_count,
232  hash_key,
233  hashtable_cache_key.second,
234  table_id_to_node_map));
235  try {
236  join_hash_table->reify();
237  } catch (const TableMustBeReplicated& e) {
238  // Throw a runtime error to abort the query
239  join_hash_table->freeHashBufferMemory();
240  throw std::runtime_error(e.what());
241  } catch (const HashJoinFail& e) {
242  // HashJoinFail exceptions log an error and trigger a retry with a join loop (if
243  // possible)
244  join_hash_table->freeHashBufferMemory();
245  throw HashJoinFail(std::string("Could not build a 1-to-1 correspondence for columns "
246  "involved in equijoin | ") +
247  e.what());
248  } catch (const ColumnarConversionNotSupported& e) {
249  throw HashJoinFail(std::string("Could not build hash tables for equijoin | ") +
250  e.what());
251  } catch (const OutOfMemory& e) {
252  throw HashJoinFail(
253  std::string("Ran out of memory while building hash tables for equijoin | ") +
254  e.what());
255  } catch (const std::exception& e) {
256  throw std::runtime_error(
257  std::string("Fatal error while attempting to build hash tables for join: ") +
258  e.what());
259  }
260  if (VLOGGING(1)) {
261  ts2 = std::chrono::steady_clock::now();
262  VLOG(1) << "Built perfect hash table "
263  << getHashTypeString(join_hash_table->getHashType()) << " in "
264  << std::chrono::duration_cast<std::chrono::milliseconds>(ts2 - ts1).count()
265  << " ms";
266  }
267  return join_hash_table;
268 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
HashEntryInfo get_bucketized_hash_entry_info(SQLTypeInfo const &context_ti, ExpressionRange const &col_range, bool const is_bw_eq)
#define IS_EQUIVALENCE(X)
Definition: sqldefs.h:67
static std::pair< QueryPlanHash, HashtableCacheMetaInfo > getHashtableCacheKey(const std::vector< InnerOuter > &inner_outer_pairs, const SQLOps op_type, const JoinType join_type, const HashTableBuildDagMap &hashtable_build_dag_map, Executor *executor)
PerfectJoinHashTable(const std::shared_ptr< Analyzer::BinOper > qual_bin_oper, const Analyzer::ColumnVar *col_var, const std::vector< InputTableInfo > &query_infos, const Data_Namespace::MemoryLevel memory_level, const JoinType join_type, const HashType preferred_hash_type, const ExpressionRange &col_range, ColumnCacheMap &column_cache, Executor *executor, const int device_count, QueryPlanHash hashtable_cache_key, HashtableCacheMetaInfo hashtable_cache_meta_info, const TableIdToNodeMap &table_id_to_node_map)
ExpressionRange getExpressionRange(const Analyzer::BinOper *expr, const std::vector< InputTableInfo > &query_infos, const Executor *, boost::optional< std::list< std::shared_ptr< Analyzer::Expr >>> simple_quals)
static ExpressionRange makeIntRange(const int64_t int_min, const int64_t int_max, const int64_t bucket, const bool has_nulls)
#define VLOGGING(n)
Definition: Logger.h:209
static std::string getHashTypeString(HashType ht) noexcept
Definition: HashJoin.h:134
size_t getNormalizedHashEntryCount() const
#define CHECK(condition)
Definition: Logger.h:211
Definition: sqldefs.h:31
if(yyssp >=yyss+yystacksize-1)
InnerOuter get_cols(const Analyzer::BinOper *qual_bin_oper, const Catalog_Namespace::Catalog &cat, const TemporaryTables *temporary_tables)
Definition: HashJoin.cpp:780
#define VLOG(n)
Definition: Logger.h:305

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Data_Namespace::MemoryLevel PerfectJoinHashTable::getMemoryLevel ( ) const
inlineoverridevirtualnoexcept

Implements HashJoin.

Definition at line 87 of file PerfectJoinHashTable.h.

References memory_level_.

87  {
88  return memory_level_;
89  };
const Data_Namespace::MemoryLevel memory_level_
int PerfectJoinHashTable::initHashTableForDevice ( const ChunkKey chunk_key,
const JoinColumn join_column,
const InnerOuter cols,
const HashType  layout,
const Data_Namespace::MemoryLevel  effective_memory_level,
const int  device_id 
)
private

Definition at line 529 of file PerfectJoinHashTable.cpp.

References PerfectJoinHashTableBuilder::allocateDeviceMemory(), CHECK, CHECK_EQ, CHECK_LE, CHECK_LT, col_range_, count, CPU, DataRecyclerUtil::CPU_DEVICE_IDENTIFIER, cpu_hash_table_buff_mutex_, Data_Namespace::CPU_LEVEL, DEBUG_TIMER, device_count_, executor_, anonymous_namespace{PerfectJoinHashTable.cpp}::get_bucketized_hash_entry_info(), PerfectJoinHashTableBuilder::getHashTable(), HashJoin::getHashTypeString(), GPU, Data_Namespace::GPU_LEVEL, hash_table_layout_cache_, HashJoin::hash_tables_for_device_, hash_type_, hashtable_cache_key_, HT_HASHING_SCHEME, initHashTableOnCpuFromCache(), PerfectJoinHashTableBuilder::initOneToManyHashTableOnCpu(), PerfectJoinHashTableBuilder::initOneToOneHashTableOnCpu(), isBitwiseEq(), HashtableRecycler::isSafeToCacheHashtable(), join_type_, memory_level_, needs_dict_translation_, OneToOne, PERFECT_HT, putHashTableOnCpuToCache(), shardCount(), table_id_to_node_map_, UNREACHABLE, and VLOG.

Referenced by reifyForDevice().

535  {
536  auto timer = DEBUG_TIMER(__func__);
537  const auto inner_col = cols.first;
538  CHECK(inner_col);
539 
540  auto hash_entry_info = get_bucketized_hash_entry_info(
541  inner_col->get_type_info(), col_range_, isBitwiseEq());
542  if (!hash_entry_info && layout == HashType::OneToOne) {
543  // TODO: what is this for?
544  return 0;
545  }
546 
547 #ifndef HAVE_CUDA
548  CHECK_EQ(Data_Namespace::CPU_LEVEL, effective_memory_level);
549 #endif
550  int err{0};
551  const int32_t hash_join_invalid_val{-1};
552  auto hashtable_layout = layout;
553  auto allow_hashtable_recycling = HashtableRecycler::isSafeToCacheHashtable(
554  table_id_to_node_map_, needs_dict_translation_, inner_col->get_table_id());
555  if (allow_hashtable_recycling) {
556  auto cached_hashtable_layout_type = hash_table_layout_cache_->getItemFromCache(
560  {});
561  if (cached_hashtable_layout_type) {
562  hash_type_ = *cached_hashtable_layout_type;
563  hashtable_layout = hash_type_;
564  VLOG(1) << "Recycle hashtable layout: " << getHashTypeString(hashtable_layout);
565  }
566  }
567  if (effective_memory_level == Data_Namespace::CPU_LEVEL) {
568  CHECK(!chunk_key.empty());
569  std::shared_ptr<PerfectHashTable> hash_table{nullptr};
570  if (allow_hashtable_recycling) {
574  }
575  decltype(std::chrono::steady_clock::now()) ts1, ts2;
576  ts1 = std::chrono::steady_clock::now();
577  {
578  std::lock_guard<std::mutex> cpu_hash_table_buff_lock(cpu_hash_table_buff_mutex_);
579  if (!hash_table) {
581  if (hashtable_layout == HashType::OneToOne) {
582  builder.initOneToOneHashTableOnCpu(join_column,
583  col_range_,
584  isBitwiseEq(),
585  cols,
586  join_type_,
587  hashtable_layout,
588  hash_entry_info,
589  hash_join_invalid_val,
590  executor_);
591  hash_table = builder.getHashTable();
592  } else {
593  builder.initOneToManyHashTableOnCpu(join_column,
594  col_range_,
595  isBitwiseEq(),
596  cols,
597  hash_entry_info,
598  hash_join_invalid_val,
599  executor_);
600  hash_table = builder.getHashTable();
601  }
602  ts2 = std::chrono::steady_clock::now();
603  auto build_time =
604  std::chrono::duration_cast<std::chrono::milliseconds>(ts2 - ts1).count();
605  if (allow_hashtable_recycling && hash_table) {
606  // add ht-related items to cache iff we have a valid hashtable
607  hash_table_layout_cache_->putItemToCache(
609  hashtable_layout,
612  0,
613  0,
614  {});
617  hash_table,
619  build_time);
620  }
621  }
622  }
623  // Transfer the hash table on the GPU if we've only built it on CPU
624  // but the query runs on GPU (join on dictionary encoded columns).
626 #ifdef HAVE_CUDA
627  const auto& ti = inner_col->get_type_info();
628  CHECK(ti.is_string());
629  auto data_mgr = executor_->getDataMgr();
630  std::lock_guard<std::mutex> cpu_hash_table_buff_lock(cpu_hash_table_buff_mutex_);
631 
632  PerfectJoinHashTableBuilder gpu_builder;
633  gpu_builder.allocateDeviceMemory(join_column,
634  hash_table->getLayout(),
635  hash_entry_info,
636  shardCount(),
637  device_id,
639  executor_);
640  std::shared_ptr<PerfectHashTable> gpu_hash_table = gpu_builder.getHashTable();
641  CHECK(gpu_hash_table);
642  auto gpu_buffer_ptr = gpu_hash_table->getGpuBuffer();
643  CHECK(gpu_buffer_ptr);
644 
645  CHECK(hash_table);
646  // GPU size returns reserved size
647  CHECK_LE(hash_table->getHashTableBufferSize(ExecutorDeviceType::CPU),
648  gpu_hash_table->getHashTableBufferSize(ExecutorDeviceType::GPU));
649 
650  auto device_allocator = data_mgr->createGpuAllocator(device_id);
651  device_allocator->copyToDevice(
652  gpu_buffer_ptr,
653  hash_table->getCpuBuffer(),
654  hash_table->getHashTableBufferSize(ExecutorDeviceType::CPU));
655  CHECK_LT(size_t(device_id), hash_tables_for_device_.size());
656  hash_tables_for_device_[device_id] = std::move(gpu_hash_table);
657 #else
658  UNREACHABLE();
659 #endif
660  } else {
661  CHECK(hash_table);
662  CHECK_LT(size_t(device_id), hash_tables_for_device_.size());
663  hash_tables_for_device_[device_id] = hash_table;
664  }
665  } else {
666 #ifdef HAVE_CUDA
668  CHECK_EQ(Data_Namespace::GPU_LEVEL, effective_memory_level);
669  builder.allocateDeviceMemory(join_column,
670  hashtable_layout,
671  hash_entry_info,
672  shardCount(),
673  device_id,
674  device_count_,
675  executor_);
676  builder.initHashTableOnGpu(chunk_key,
677  join_column,
678  col_range_,
679  isBitwiseEq(),
680  cols,
681  join_type_,
682  hashtable_layout,
683  hash_entry_info,
684  shardCount(),
685  hash_join_invalid_val,
686  device_id,
687  device_count_,
688  executor_);
689  CHECK_LT(size_t(device_id), hash_tables_for_device_.size());
690  hash_tables_for_device_[device_id] = builder.getHashTable();
691  if (!err && allow_hashtable_recycling && hash_tables_for_device_[device_id]) {
692  // add layout to cache iff we have a valid hashtable
693  hash_table_layout_cache_->putItemToCache(
695  hash_tables_for_device_[device_id]->getLayout(),
698  0,
699  0,
700  {});
701  }
702 #else
703  UNREACHABLE();
704 #endif
705  }
706  return err;
707 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
HashEntryInfo get_bucketized_hash_entry_info(SQLTypeInfo const &context_ti, ExpressionRange const &col_range, bool const is_bw_eq)
const Data_Namespace::MemoryLevel memory_level_
QueryPlanHash hashtable_cache_key_
void allocateDeviceMemory(const JoinColumn &join_column, const HashType layout, HashEntryInfo &hash_entry_info, const size_t shard_count, const int device_id, const int device_count, const Executor *executor)
static bool isSafeToCacheHashtable(const TableIdToNodeMap &table_id_to_node_map, bool need_dict_translation, const int table_id)
const TableIdToNodeMap table_id_to_node_map_
std::vector< std::shared_ptr< HashTable > > hash_tables_for_device_
Definition: HashJoin.h:296
#define UNREACHABLE()
Definition: Logger.h:255
std::shared_ptr< PerfectHashTable > initHashTableOnCpuFromCache(QueryPlanHash key, CacheItemType item_type, DeviceIdentifier device_identifier)
void initOneToManyHashTableOnCpu(const JoinColumn &join_column, const ExpressionRange &col_range, const bool is_bitwise_eq, const std::pair< const Analyzer::ColumnVar *, const Analyzer::Expr * > &cols, const HashEntryInfo hash_entry_info, const int32_t hash_join_invalid_val, const Executor *executor)
int count
static std::unique_ptr< HashingSchemeRecycler > hash_table_layout_cache_
std::unique_ptr< PerfectHashTable > getHashTable()
#define CHECK_LT(x, y)
Definition: Logger.h:221
#define CHECK_LE(x, y)
Definition: Logger.h:222
void putHashTableOnCpuToCache(QueryPlanHash key, CacheItemType item_type, std::shared_ptr< PerfectHashTable > hashtable_ptr, DeviceIdentifier device_identifier, size_t hashtable_building_time)
static std::string getHashTypeString(HashType ht) noexcept
Definition: HashJoin.h:134
#define CHECK(condition)
Definition: Logger.h:211
#define DEBUG_TIMER(name)
Definition: Logger.h:358
static constexpr DeviceIdentifier CPU_DEVICE_IDENTIFIER
Definition: DataRecycler.h:132
#define VLOG(n)
Definition: Logger.h:305
void initOneToOneHashTableOnCpu(const JoinColumn &join_column, const ExpressionRange &col_range, const bool is_bitwise_eq, const InnerOuter &cols, const JoinType join_type, const HashType hash_type, const HashEntryInfo hash_entry_info, const int32_t hash_join_invalid_val, const Executor *executor)
bool isBitwiseEq() const override

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::shared_ptr< PerfectHashTable > PerfectJoinHashTable::initHashTableOnCpuFromCache ( QueryPlanHash  key,
CacheItemType  item_type,
DeviceIdentifier  device_identifier 
)
private

Definition at line 734 of file PerfectJoinHashTable.cpp.

References CHECK, DEBUG_TIMER, and hash_table_cache_.

Referenced by initHashTableForDevice().

737  {
739  auto timer = DEBUG_TIMER(__func__);
740  auto hashtable_ptr =
741  hash_table_cache_->getItemFromCache(key, item_type, device_identifier);
742  if (hashtable_ptr) {
743  return std::dynamic_pointer_cast<PerfectHashTable>(hashtable_ptr);
744  }
745  return nullptr;
746 }
static std::unique_ptr< HashtableRecycler > hash_table_cache_
#define CHECK(condition)
Definition: Logger.h:211
#define DEBUG_TIMER(name)
Definition: Logger.h:358

+ Here is the caller graph for this function:

bool PerfectJoinHashTable::isBitwiseEq ( ) const
overrideprivatevirtual

Implements HashJoin.

Definition at line 1058 of file PerfectJoinHashTable.cpp.

References kBW_EQ, and qual_bin_oper_.

Referenced by codegenMatchingSet(), codegenSlot(), fetchColumnsForDevice(), getHashJoinArgs(), and initHashTableForDevice().

1058  {
1059  return qual_bin_oper_->get_optype() == kBW_EQ;
1060 }
std::shared_ptr< Analyzer::BinOper > qual_bin_oper_
Definition: sqldefs.h:31

+ Here is the caller graph for this function:

size_t PerfectJoinHashTable::offsetBufferOff ( ) const
overridevirtualnoexcept

Implements HashJoin.

Definition at line 870 of file PerfectJoinHashTable.cpp.

Referenced by toSet(), and toString().

870  {
871  return 0;
872 }

+ Here is the caller graph for this function:

size_t PerfectJoinHashTable::payloadBufferOff ( ) const
overridevirtualnoexcept

Implements HashJoin.

Definition at line 878 of file PerfectJoinHashTable.cpp.

References getComponentBufferSize().

Referenced by toSet(), and toString().

878  {
879  return 2 * getComponentBufferSize();
880 }
size_t getComponentBufferSize() const noexceptoverride

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PerfectJoinHashTable::putHashTableOnCpuToCache ( QueryPlanHash  key,
CacheItemType  item_type,
std::shared_ptr< PerfectHashTable hashtable_ptr,
DeviceIdentifier  device_identifier,
size_t  hashtable_building_time 
)
private

Definition at line 748 of file PerfectJoinHashTable.cpp.

References CHECK, CPU, and hash_table_cache_.

Referenced by initHashTableForDevice().

753  {
755  CHECK(hashtable_ptr && !hashtable_ptr->getGpuBuffer());
756  hash_table_cache_->putItemToCache(
757  key,
758  hashtable_ptr,
759  item_type,
760  device_identifier,
761  hashtable_ptr->getHashTableBufferSize(ExecutorDeviceType::CPU),
762  hashtable_building_time);
763 }
static std::unique_ptr< HashtableRecycler > hash_table_cache_
#define CHECK(condition)
Definition: Logger.h:211

+ Here is the caller graph for this function:

void PerfectJoinHashTable::reify ( )
private

Definition at line 326 of file PerfectJoinHashTable.cpp.

References threading_serial::async(), CHECK_EQ, CHECK_LT, HashJoin::checkHashJoinReplicationConstraint(), col_range_, DEBUG_TIMER, device_count_, EMPTY_HASHED_PLAN_DAG_KEY, executor_, fetchColumnsForDevice(), HashJoin::freeHashBufferMemory(), genChunkKey(), anonymous_namespace{HashJoin.cpp}::get_cols(), get_shard_count(), getAlternativeCacheKey(), getInnerQueryInfo(), getInnerTableId(), Data_Namespace::GPU_LEVEL, hash_type_, hashtable_cache_key_, InputTableInfo::info, inner_outer_pairs_, join_type_, memory_level_, OneToMany, only_shards_for_device(), qual_bin_oper_, reifyForDevice(), shardCount(), logger::thread_id(), and VLOG.

326  {
327  auto timer = DEBUG_TIMER(__func__);
329  auto catalog = const_cast<Catalog_Namespace::Catalog*>(executor_->getCatalog());
330  const auto cols =
331  get_cols(qual_bin_oper_.get(), *catalog, executor_->temporary_tables_);
332  const auto inner_col = cols.first;
334  inner_col->get_table_id(),
336  executor_);
337  const auto& query_info = getInnerQueryInfo(inner_col).info;
338  if (query_info.fragments.empty()) {
339  return;
340  }
341  if (query_info.getNumTuplesUpperBound() >
342  static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
343  throw TooManyHashEntries();
344  }
345  std::vector<std::future<void>> init_threads;
346  const int shard_count = shardCount();
347 
348  inner_outer_pairs_.push_back(cols);
349  CHECK_EQ(inner_outer_pairs_.size(), size_t(1));
350 
351  std::vector<ColumnsForDevice> columns_per_device;
352  std::vector<std::unique_ptr<CudaAllocator>> dev_buff_owners;
353  try {
354  auto data_mgr = executor_->getDataMgr();
356  for (int device_id = 0; device_id < device_count_; ++device_id) {
357  dev_buff_owners.emplace_back(
358  std::make_unique<CudaAllocator>(data_mgr, device_id));
359  }
360  }
361  for (int device_id = 0; device_id < device_count_; ++device_id) {
362  const auto fragments =
363  shard_count
364  ? only_shards_for_device(query_info.fragments, device_id, device_count_)
365  : query_info.fragments;
366  const auto columns_for_device =
367  fetchColumnsForDevice(fragments,
368  device_id,
370  ? dev_buff_owners[device_id].get()
371  : nullptr,
372  *catalog);
373  columns_per_device.push_back(columns_for_device);
374  const auto chunk_key = genChunkKey(
375  fragments, inner_outer_pairs_.front().second, inner_outer_pairs_.front().first);
376  if (device_id == 0 && hashtable_cache_key_ == EMPTY_HASHED_PLAN_DAG_KEY &&
377  getInnerTableId() > 0) {
378  // sometimes we cannot retrieve query plan dag, so try to recycler cache
379  // with the old-passioned cache key if we deal with hashtable of non-temporary
380  // table
381  auto outer_col =
382  dynamic_cast<const Analyzer::ColumnVar*>(inner_outer_pairs_.front().second);
383  AlternativeCacheKeyForPerfectHashJoin cache_key{
384  col_range_,
385  inner_col,
386  outer_col ? outer_col : inner_col,
387  chunk_key,
388  columns_per_device[device_id].join_columns.front().num_elems,
389  qual_bin_oper_->get_optype(),
390  join_type_};
392  VLOG(2) << "Use alternative hashtable cache key due to unavailable query plan "
393  "dag extraction";
394  }
395  init_threads.push_back(std::async(std::launch::async,
397  this,
398  chunk_key,
399  columns_per_device[device_id],
400  hash_type_,
401  device_id,
402  logger::thread_id()));
403  }
404  for (auto& init_thread : init_threads) {
405  init_thread.wait();
406  }
407  for (auto& init_thread : init_threads) {
408  init_thread.get();
409  }
410  } catch (const NeedsOneToManyHash& e) {
413  init_threads.clear();
415  CHECK_EQ(dev_buff_owners.size(), size_t(device_count_));
416  }
417  CHECK_EQ(columns_per_device.size(), size_t(device_count_));
418  for (int device_id = 0; device_id < device_count_; ++device_id) {
419  const auto fragments =
420  shard_count
421  ? only_shards_for_device(query_info.fragments, device_id, device_count_)
422  : query_info.fragments;
423  const auto chunk_key = genChunkKey(
424  fragments, inner_outer_pairs_.front().second, inner_outer_pairs_.front().first);
425  init_threads.push_back(std::async(std::launch::async,
427  this,
428  chunk_key,
429  columns_per_device[device_id],
430  hash_type_,
431  device_id,
432  logger::thread_id()));
433  }
434  for (auto& init_thread : init_threads) {
435  init_thread.wait();
436  }
437  for (auto& init_thread : init_threads) {
438  init_thread.get();
439  }
440  }
441 }
void reifyForDevice(const ChunkKey &hash_table_key, const ColumnsForDevice &columns_for_device, const HashType layout, const int device_id, const logger::ThreadId parent_thread_id)
#define CHECK_EQ(x, y)
Definition: Logger.h:219
Fragmenter_Namespace::TableInfo info
Definition: InputMetadata.h:35
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:114
const Data_Namespace::MemoryLevel memory_level_
std::shared_ptr< Analyzer::BinOper > qual_bin_oper_
QueryPlanHash hashtable_cache_key_
ChunkKey genChunkKey(const std::vector< Fragmenter_Namespace::FragmentInfo > &fragments, const Analyzer::Expr *outer_col, const Analyzer::ColumnVar *inner_col) const
constexpr QueryPlanHash EMPTY_HASHED_PLAN_DAG_KEY
const InputTableInfo & getInnerQueryInfo(const Analyzer::ColumnVar *inner_col) const
void freeHashBufferMemory()
Definition: HashJoin.h:283
ColumnsForDevice fetchColumnsForDevice(const std::vector< Fragmenter_Namespace::FragmentInfo > &fragments, const int device_id, DeviceAllocator *dev_buff_owner, const Catalog_Namespace::Catalog &catalog)
future< Result > async(Fn &&fn, Args &&...args)
std::vector< Fragmenter_Namespace::FragmentInfo > only_shards_for_device(const std::vector< Fragmenter_Namespace::FragmentInfo > &fragments, const int device_id, const int device_count)
static void checkHashJoinReplicationConstraint(const int table_id, const size_t shard_count, const Executor *executor)
Definition: HashJoin.cpp:587
std::vector< InnerOuter > inner_outer_pairs_
#define CHECK_LT(x, y)
Definition: Logger.h:221
static QueryPlanHash getAlternativeCacheKey(AlternativeCacheKeyForPerfectHashJoin &info)
int getInnerTableId() const noexceptoverride
ThreadId thread_id()
Definition: Logger.cpp:816
#define DEBUG_TIMER(name)
Definition: Logger.h:358
size_t get_shard_count(const Analyzer::BinOper *join_condition, const Executor *executor)
Definition: HashJoin.cpp:790
InnerOuter get_cols(const Analyzer::BinOper *qual_bin_oper, const Catalog_Namespace::Catalog &cat, const TemporaryTables *temporary_tables)
Definition: HashJoin.cpp:780
#define VLOG(n)
Definition: Logger.h:305

+ Here is the call graph for this function:

void PerfectJoinHashTable::reifyForDevice ( const ChunkKey hash_table_key,
const ColumnsForDevice columns_for_device,
const HashType  layout,
const int  device_id,
const logger::ThreadId  parent_thread_id 
)
private

Definition at line 494 of file PerfectJoinHashTable.cpp.

References CHECK_EQ, DEBUG_TIMER_NEW_THREAD, getEffectiveMemoryLevel(), initHashTableForDevice(), inner_outer_pairs_, ColumnsForDevice::join_columns, OneToMany, OneToOne, and to_string().

Referenced by reify().

498  {
499  DEBUG_TIMER_NEW_THREAD(parent_thread_id);
500  const auto effective_memory_level = getEffectiveMemoryLevel(inner_outer_pairs_);
501 
502  CHECK_EQ(columns_for_device.join_columns.size(), size_t(1));
503  CHECK_EQ(inner_outer_pairs_.size(), size_t(1));
504  auto& join_column = columns_for_device.join_columns.front();
505  if (layout == HashType::OneToOne) {
506  const auto err = initHashTableForDevice(chunk_key,
507  join_column,
508  inner_outer_pairs_.front(),
509  layout,
510  effective_memory_level,
511  device_id);
512  if (err) {
513  throw NeedsOneToManyHash();
514  }
515  } else {
516  const auto err = initHashTableForDevice(chunk_key,
517  join_column,
518  inner_outer_pairs_.front(),
520  effective_memory_level,
521  device_id);
522  if (err) {
523  throw std::runtime_error("Unexpected error building one to many hash table: " +
524  std::to_string(err));
525  }
526  }
527 }
#define CHECK_EQ(x, y)
Definition: Logger.h:219
Data_Namespace::MemoryLevel getEffectiveMemoryLevel(const std::vector< InnerOuter > &inner_outer_pairs) const
#define DEBUG_TIMER_NEW_THREAD(parent_thread_id)
Definition: Logger.h:363
std::string to_string(char const *&&v)
std::vector< InnerOuter > inner_outer_pairs_
int initHashTableForDevice(const ChunkKey &chunk_key, const JoinColumn &join_column, const InnerOuter &cols, const HashType layout, const Data_Namespace::MemoryLevel effective_memory_level, const int device_id)
const std::vector< JoinColumn > join_columns
Definition: HashJoin.h:80

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t PerfectJoinHashTable::shardCount ( ) const
private

Definition at line 1052 of file PerfectJoinHashTable.cpp.

References executor_, get_shard_count(), Data_Namespace::GPU_LEVEL, memory_level_, and qual_bin_oper_.

Referenced by codegenMatchingSet(), codegenSlot(), initHashTableForDevice(), and reify().

1052  {
1055  : 0;
1056 }
const Data_Namespace::MemoryLevel memory_level_
std::shared_ptr< Analyzer::BinOper > qual_bin_oper_
size_t get_shard_count(const Analyzer::BinOper *join_condition, const Executor *executor)
Definition: HashJoin.cpp:790

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::set< DecodedJoinHashBufferEntry > PerfectJoinHashTable::toSet ( const ExecutorDeviceType  device_type,
const int  device_id 
) const
overridevirtual

Implements HashJoin.

Definition at line 934 of file PerfectJoinHashTable.cpp.

References countBufferOff(), executor_, getHashTableForDevice(), HashJoin::getJoinHashBuffer(), HashJoin::getJoinHashBufferSize(), GPU, offsetBufferOff(), payloadBufferOff(), and HashTable::toSet().

936  {
937  auto buffer = getJoinHashBuffer(device_type, device_id);
938  auto buffer_size = getJoinHashBufferSize(device_type, device_id);
939  auto hash_table = getHashTableForDevice(device_id);
940 #ifdef HAVE_CUDA
941  std::unique_ptr<int8_t[]> buffer_copy;
942  if (device_type == ExecutorDeviceType::GPU) {
943  buffer_copy = std::make_unique<int8_t[]>(buffer_size);
944 
945  auto data_mgr = executor_->getDataMgr();
946  auto device_allocator = data_mgr->createGpuAllocator(device_id);
947  device_allocator->copyFromDevice(buffer_copy.get(), buffer, buffer_size);
948  }
949  auto ptr1 = buffer_copy ? buffer_copy.get() : reinterpret_cast<const int8_t*>(buffer);
950 #else
951  auto ptr1 = reinterpret_cast<const int8_t*>(buffer);
952 #endif // HAVE_CUDA
953  auto ptr2 = ptr1 + offsetBufferOff();
954  auto ptr3 = ptr1 + countBufferOff();
955  auto ptr4 = ptr1 + payloadBufferOff();
956  return HashTable::toSet(0,
957  0,
958  hash_table ? hash_table->getEntryCount() : 0,
959  ptr1,
960  ptr2,
961  ptr3,
962  ptr4,
963  buffer_size);
964 }
size_t offsetBufferOff() const noexceptoverride
size_t payloadBufferOff() const noexceptoverride
int8_t * getJoinHashBuffer(const ExecutorDeviceType device_type, const int device_id) const
Definition: HashJoin.h:260
size_t getJoinHashBufferSize(const ExecutorDeviceType device_type)
Definition: HashJoin.h:246
size_t countBufferOff() const noexceptoverride
static DecodedJoinHashBufferSet toSet(size_t key_component_count, size_t key_component_width, size_t entry_count, const int8_t *ptr1, const int8_t *ptr2, const int8_t *ptr3, const int8_t *ptr4, size_t buffer_size)
Decode hash table into a std::set for easy inspection and validation.
Definition: HashTable.cpp:139
HashTable * getHashTableForDevice(const size_t device_id) const

+ Here is the call graph for this function:

std::string PerfectJoinHashTable::toString ( const ExecutorDeviceType  device_type,
const int  device_id = 0,
bool  raw = false 
) const
overridevirtual

Implements HashJoin.

Definition at line 899 of file PerfectJoinHashTable.cpp.

References countBufferOff(), executor_, getHashTableForDevice(), HashJoin::getHashTypeString(), HashJoin::getJoinHashBuffer(), HashJoin::getJoinHashBufferSize(), GPU, hash_type_, offsetBufferOff(), payloadBufferOff(), and HashTable::toString().

Referenced by getAlternativeCacheKey().

901  {
902  auto buffer = getJoinHashBuffer(device_type, device_id);
903  auto buffer_size = getJoinHashBufferSize(device_type, device_id);
904  auto hash_table = getHashTableForDevice(device_id);
905 #ifdef HAVE_CUDA
906  std::unique_ptr<int8_t[]> buffer_copy;
907  if (device_type == ExecutorDeviceType::GPU) {
908  buffer_copy = std::make_unique<int8_t[]>(buffer_size);
909 
910  auto data_mgr = executor_->getDataMgr();
911  auto device_allocator = data_mgr->createGpuAllocator(device_id);
912  device_allocator->copyFromDevice(buffer_copy.get(), buffer, buffer_size);
913  }
914  auto ptr1 = buffer_copy ? buffer_copy.get() : reinterpret_cast<const int8_t*>(buffer);
915 #else
916  auto ptr1 = reinterpret_cast<const int8_t*>(buffer);
917 #endif // HAVE_CUDA
918  auto ptr2 = ptr1 + offsetBufferOff();
919  auto ptr3 = ptr1 + countBufferOff();
920  auto ptr4 = ptr1 + payloadBufferOff();
921  return HashTable::toString("perfect",
923  0,
924  0,
925  hash_table ? hash_table->getEntryCount() : 0,
926  ptr1,
927  ptr2,
928  ptr3,
929  ptr4,
930  buffer_size,
931  raw);
932 }
size_t offsetBufferOff() const noexceptoverride
size_t payloadBufferOff() const noexceptoverride
int8_t * getJoinHashBuffer(const ExecutorDeviceType device_type, const int device_id) const
Definition: HashJoin.h:260
static std::string getHashTypeString(HashType ht) noexcept
Definition: HashJoin.h:134
size_t getJoinHashBufferSize(const ExecutorDeviceType device_type)
Definition: HashJoin.h:246
static std::string toString(const std::string &type, const std::string &layout_type, size_t key_component_count, size_t key_component_width, size_t entry_count, const int8_t *ptr1, const int8_t *ptr2, const int8_t *ptr3, const int8_t *ptr4, size_t buffer_size, bool raw=false)
Decode hash table into a human-readable string.
Definition: HashTable.cpp:226
size_t countBufferOff() const noexceptoverride
HashTable * getHashTableForDevice(const size_t device_id) const

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

ExpressionRange PerfectJoinHashTable::col_range_
private

Definition at line 246 of file PerfectJoinHashTable.h.

Referenced by getHashJoinArgs(), initHashTableForDevice(), and reify().

std::shared_ptr<Analyzer::ColumnVar> PerfectJoinHashTable::col_var_
private

Definition at line 240 of file PerfectJoinHashTable.h.

Referenced by getInnerTableId(), and getInnerTableRteIdx().

ColumnCacheMap& PerfectJoinHashTable::column_cache_
private

Definition at line 248 of file PerfectJoinHashTable.h.

Referenced by fetchColumnsForDevice().

std::mutex PerfectJoinHashTable::cpu_hash_table_buff_mutex_
private

Definition at line 245 of file PerfectJoinHashTable.h.

Referenced by initHashTableForDevice().

const int PerfectJoinHashTable::device_count_
private
std::unique_ptr< HashtableRecycler > PerfectJoinHashTable::hash_table_cache_
staticprivate
std::unique_ptr< HashingSchemeRecycler > PerfectJoinHashTable::hash_table_layout_cache_
staticprivate
Initial value:
=
std::make_unique<HashingSchemeRecycler>()

Definition at line 256 of file PerfectJoinHashTable.h.

Referenced by getCacheInvalidator(), getHashingSchemeCache(), and initHashTableForDevice().

HashType PerfectJoinHashTable::hash_type_
private

Definition at line 243 of file PerfectJoinHashTable.h.

Referenced by getHashType(), initHashTableForDevice(), reify(), and toString().

QueryPlanHash PerfectJoinHashTable::hashtable_cache_key_
private

Definition at line 252 of file PerfectJoinHashTable.h.

Referenced by initHashTableForDevice(), and reify().

HashtableCacheMetaInfo PerfectJoinHashTable::hashtable_cache_meta_info_
private

Definition at line 253 of file PerfectJoinHashTable.h.

std::vector<InnerOuter> PerfectJoinHashTable::inner_outer_pairs_
private

Definition at line 148 of file PerfectJoinHashTable.h.

Referenced by fetchColumnsForDevice(), reify(), and reifyForDevice().

const JoinType PerfectJoinHashTable::join_type_
private

Definition at line 239 of file PerfectJoinHashTable.h.

Referenced by initHashTableForDevice(), and reify().

const Data_Namespace::MemoryLevel PerfectJoinHashTable::memory_level_
private
bool PerfectJoinHashTable::needs_dict_translation_
mutableprivate

Definition at line 250 of file PerfectJoinHashTable.h.

Referenced by getEffectiveMemoryLevel(), and initHashTableForDevice().

std::shared_ptr<Analyzer::BinOper> PerfectJoinHashTable::qual_bin_oper_
private
const std::vector<InputTableInfo>& PerfectJoinHashTable::query_infos_
private

Definition at line 241 of file PerfectJoinHashTable.h.

Referenced by getInnerQueryInfo().

const TableIdToNodeMap PerfectJoinHashTable::table_id_to_node_map_
private

Definition at line 251 of file PerfectJoinHashTable.h.

Referenced by initHashTableForDevice().


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