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

#include <Distance.h>

+ Inheritance diagram for spatial_type::Distance:
+ Collaboration diagram for spatial_type::Distance:

Public Member Functions

 Distance (const Analyzer::GeoOperator *geo_operator)
 
size_t size () const final
 
SQLTypeInfo getNullType () const final
 
std::tuple< std::vector
< llvm::Value * >, llvm::Value * > 
codegenLoads (const std::vector< llvm::Value * > &arg_lvs, const std::vector< llvm::Value * > &pos_lvs, CgenState *cgen_state) final
 
std::vector< llvm::Value * > codegen (const std::vector< llvm::Value * > &args, CodeGenerator::NullCheckCodegen *nullcheck_codegen, CgenState *cgen_state, const CompilationOptions &co) final
 
- Public Member Functions inherited from spatial_type::Codegen
 Codegen (const Analyzer::GeoOperator *geo_operator)
 
auto isNullable () const
 
auto getTypeInfo () const
 
std::string getName () const
 
virtual std::unique_ptr
< CodeGenerator::NullCheckCodegen
getNullCheckCodegen (llvm::Value *null_lv, CgenState *cgen_state, Executor *executor)
 
virtual const Analyzer::ExprgetOperand (const size_t index)
 
virtual ~Codegen ()
 

Additional Inherited Members

- Static Public Member Functions inherited from spatial_type::Codegen
static std::unique_ptr< Codegeninit (const Analyzer::GeoOperator *geo_operator)
 
static char const * pointIsNullFunctionName (SQLTypeInfo const &)
 
- Protected Attributes inherited from spatial_type::Codegen
const Analyzer::GeoOperatoroperator_
 
bool is_nullable_ {true}
 

Detailed Description

Definition at line 23 of file Distance.h.

Constructor & Destructor Documentation

spatial_type::Distance::Distance ( const Analyzer::GeoOperator geo_operator)
inline

Definition at line 25 of file Distance.h.

References CHECK_EQ, Analyzer::Expr::get_type_info(), spatial_type::Codegen::is_nullable_, spatial_type::Codegen::operator_, and Analyzer::GeoOperator::size().

25  : Codegen(geo_operator) {
26  CHECK_EQ(operator_->size(), size_t(2));
27  const auto& ti = operator_->get_type_info();
28  is_nullable_ = !ti.get_notnull();
29  }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:69
size_t size() const
Definition: Analyzer.cpp:4211
Codegen(const Analyzer::GeoOperator *geo_operator)
Definition: Codegen.h:28

+ Here is the call graph for this function:

Member Function Documentation

std::vector<llvm::Value*> spatial_type::Distance::codegen ( const std::vector< llvm::Value * > &  args,
CodeGenerator::NullCheckCodegen nullcheck_codegen,
CgenState cgen_state,
const CompilationOptions co 
)
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 155 of file Distance.h.

References run_benchmark_import::args, CHECK, Geospatial::get_compression_scheme(), kDOUBLE, kGEOGRAPHY, kLINESTRING, kMULTILINESTRING, kPOINT, and spatial_type::suffix().

158  {
159  const auto& first_operand_ti = getOperand(0)->get_type_info();
160  const auto& second_operand_ti = getOperand(1)->get_type_info();
161 
162  const bool is_geodesic = first_operand_ti.get_subtype() == kGEOGRAPHY &&
163  first_operand_ti.get_output_srid() == 4326;
164 
165  if (is_geodesic && !((first_operand_ti.get_type() == kPOINT &&
166  second_operand_ti.get_type() == kPOINT) ||
167  (first_operand_ti.get_type() == kLINESTRING &&
168  second_operand_ti.get_type() == kPOINT) ||
169  (first_operand_ti.get_type() == kPOINT &&
170  second_operand_ti.get_type() == kLINESTRING))) {
171  throw std::runtime_error(getName() +
172  " currently doesn't accept non-POINT geographies");
173  }
174 
175  bool unsupported_args = false;
176  if (first_operand_ti.get_type() == kMULTILINESTRING) {
177  unsupported_args = (second_operand_ti.get_type() != kPOINT);
178  } else if (second_operand_ti.get_type() == kMULTILINESTRING) {
179  unsupported_args = (first_operand_ti.get_type() != kPOINT);
180  }
181  if (unsupported_args) {
182  throw std::runtime_error(getName() +
183  " currently doesn't support this argument combination");
184  }
185 
186  std::string func_name = getName() + suffix(first_operand_ti.get_type()) +
187  suffix(second_operand_ti.get_type());
188  if (is_geodesic) {
189  func_name += "_Geodesic";
190  }
191  auto& builder = cgen_state->ir_builder_;
192 
193  std::vector<llvm::Value*> operand_lvs;
194  for (size_t i = 0; i < args.size(); i += 2) {
195  operand_lvs.push_back(args[i]);
196  operand_lvs.push_back(
197  builder.CreateSExt(args[i + 1], llvm::Type::getInt64Ty(cgen_state->context_)));
198  }
199 
200  const auto& ret_ti = operator_->get_type_info();
201  // push back ic, isr, osr for now
202  operand_lvs.push_back(
203  cgen_state->llInt(Geospatial::get_compression_scheme(first_operand_ti))); // ic 1
204  operand_lvs.push_back(
205  cgen_state->llInt(first_operand_ti.get_input_srid())); // in srid 1
206  operand_lvs.push_back(cgen_state->llInt(
207  Geospatial::get_compression_scheme(second_operand_ti))); // ic 2
208  operand_lvs.push_back(
209  cgen_state->llInt(second_operand_ti.get_input_srid())); // in srid 2
210  const auto srid_override = operator_->getOutputSridOverride();
211  operand_lvs.push_back(
212  cgen_state->llInt(srid_override ? *srid_override : 0)); // out srid
213 
214  if (getName() == "ST_Distance" && first_operand_ti.get_subtype() != kGEOGRAPHY &&
215  (first_operand_ti.get_type() != kPOINT ||
216  second_operand_ti.get_type() != kPOINT)) {
217  operand_lvs.push_back(cgen_state->llFp(double(0.0)));
218  }
219 
220  CHECK(ret_ti.get_type() == kDOUBLE);
221  auto ret = cgen_state->emitExternalCall(
222  func_name, llvm::Type::getDoubleTy(cgen_state->context_), operand_lvs);
223  if (is_nullable_) {
224  CHECK(nullcheck_codegen);
225  ret = nullcheck_codegen->finalize(cgen_state->inlineFpNull(ret_ti), ret);
226  }
227  return {ret};
228  }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:392
auto getOutputSridOverride() const
Definition: Analyzer.h:3313
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
int32_t get_compression_scheme(const SQLTypeInfo &ti)
Definition: Compression.cpp:23
std::string suffix(SQLTypes type)
Definition: Codegen.cpp:75
llvm::LLVMContext & context_
Definition: CgenState.h:382
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.cpp:395
llvm::ConstantFP * llFp(const float v) const
Definition: CgenState.h:253
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
const Analyzer::GeoOperator * operator_
Definition: Codegen.h:69
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
llvm::Value * finalize(llvm::Value *null_lv, llvm::Value *notnull_lv)
Definition: IRCodegen.cpp:1530
#define CHECK(condition)
Definition: Logger.h:291
virtual const Analyzer::Expr * getOperand(const size_t index)
Definition: Codegen.cpp:64
std::string getName() const
Definition: Codegen.h:36
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:104

+ Here is the call graph for this function:

std::tuple<std::vector<llvm::Value*>, llvm::Value*> spatial_type::Distance::codegenLoads ( const std::vector< llvm::Value * > &  arg_lvs,
const std::vector< llvm::Value * > &  pos_lvs,
CgenState cgen_state 
)
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 35 of file Distance.h.

References CHECK, CHECK_EQ, CHECK_LT, get_int_type(), spatial_type::Codegen::getOperand(), IS_GEO, is_null(), spatial_type::Codegen::is_nullable_, kPOINT, log2_bytes(), and size().

38  {
39  CHECK_EQ(pos_lvs.size(), size());
40  std::string size_fn_name = "array_size";
41  if (is_nullable_) {
42  size_fn_name += "_nullable";
43  }
44 
45  auto& builder = cgen_state->ir_builder_;
46  llvm::Value* is_null = cgen_state->llBool(false);
47 
48  std::vector<llvm::Value*> operand_lvs;
49  size_t arg_lvs_index{0};
50  for (size_t i = 0; i < size(); i++) {
51  const auto operand = getOperand(i);
52  CHECK(operand);
53  const auto& operand_ti = operand->get_type_info();
54  CHECK(IS_GEO(operand_ti.get_type()));
55  const size_t num_physical_coord_lvs = operand_ti.get_physical_coord_cols();
56 
57  // iterate over column inputs
58  bool is_coords_lv{true};
59  if (dynamic_cast<const Analyzer::ColumnVar*>(operand)) {
60  for (size_t j = 0; j < num_physical_coord_lvs; j++) {
61  CHECK_LT(arg_lvs_index, arg_lvs.size());
62  auto lv = arg_lvs[arg_lvs_index++];
63  // TODO: fast fixlen array buff for coords
64  auto array_buff_lv =
65  cgen_state->emitExternalCall("array_buff",
66  llvm::Type::getInt8PtrTy(cgen_state->context_),
67  {lv, pos_lvs[i]});
68  auto const is_coords = (j == 0);
69  if (!is_coords) {
70  // cast additional columns to i32*
71  array_buff_lv = builder.CreateBitCast(
72  array_buff_lv, llvm::Type::getInt32PtrTy(cgen_state->context_));
73  }
74  operand_lvs.push_back(array_buff_lv);
75 
76  const auto ptr_type = llvm::dyn_cast_or_null<llvm::PointerType>(lv->getType());
77  CHECK(ptr_type);
78  const auto elem_type = ptr_type->getPointerElementType();
79  CHECK(elem_type);
80  auto const shift = log2_bytes(is_coords ? 1 : 4);
81  std::vector<llvm::Value*> array_sz_args{
82  lv, pos_lvs[i], cgen_state->llInt(shift)};
83  if (is_nullable_) { // TODO: should we do this for all arguments, or just
84  // coords?
85  array_sz_args.push_back(cgen_state->llInt(
86  static_cast<int32_t>(inline_int_null_value<int32_t>())));
87  }
88  operand_lvs.push_back(cgen_state->emitExternalCall(
89  size_fn_name, get_int_type(32, cgen_state->context_), array_sz_args));
90  llvm::Value* operand_is_null_lv{nullptr};
91  if (is_nullable_ && is_coords_lv) {
92  if (operand_ti.get_type() == kPOINT) {
93  operand_is_null_lv = cgen_state->emitExternalCall(
94  "point_coord_array_is_null",
95  llvm::Type::getInt1Ty(cgen_state->context_),
96  {lv, pos_lvs[i]});
97  } else {
98  operand_is_null_lv = builder.CreateICmpEQ(
99  operand_lvs.back(),
100  cgen_state->llInt(
101  static_cast<int32_t>(inline_int_null_value<int32_t>())));
102  }
103  CHECK(operand_is_null_lv);
104  is_null = builder.CreateOr(is_null, operand_is_null_lv);
105  }
106  is_coords_lv = false;
107  }
108  } else {
109  for (size_t j = 0; j < num_physical_coord_lvs; j++) {
110  // ptr
111  CHECK_LT(arg_lvs_index, arg_lvs.size());
112  auto array_buff_lv = arg_lvs[arg_lvs_index];
113  if (j == 0) {
114  // cast alloca to i8*
115  array_buff_lv = builder.CreateBitCast(
116  array_buff_lv, llvm::Type::getInt8PtrTy(cgen_state->context_));
117  } else {
118  // cast additional columns to i32*
119  array_buff_lv = builder.CreateBitCast(
120  array_buff_lv, llvm::Type::getInt32PtrTy(cgen_state->context_));
121  }
122  operand_lvs.push_back(array_buff_lv);
123  if (is_nullable_ && is_coords_lv) {
124  auto const geo_oper = dynamic_cast<const Analyzer::GeoOperator*>(operand);
125  if (geo_oper && geo_oper->getName() == "ST_Point") {
126  // ST_Point stores null_sentinel to its storage if it is null
127  CHECK_EQ(operand->get_type_info().get_compression(), kENCODING_NONE);
128  auto null_check_lv =
129  cgen_state->emitCall("point_double_is_null", {arg_lvs[arg_lvs_index]});
130  is_null = builder.CreateOr(is_null, null_check_lv);
131  } else {
132  auto coords_array_type =
133  llvm::dyn_cast<llvm::PointerType>(operand_lvs.back()->getType());
134  CHECK(coords_array_type);
135  is_null = builder.CreateOr(
136  is_null,
137  builder.CreateICmpEQ(
138  operand_lvs.back(),
139  llvm::ConstantPointerNull::get(coords_array_type)));
140  }
141  }
142  arg_lvs_index++;
143  is_coords_lv = false;
144  CHECK_LT(arg_lvs_index, arg_lvs.size());
145  operand_lvs.push_back(arg_lvs[arg_lvs_index++]);
146  }
147  }
148  }
149  CHECK_EQ(arg_lvs_index, arg_lvs.size());
150 
151  // use the points array size argument for nullability
152  return std::make_tuple(operand_lvs, is_nullable_ ? is_null : nullptr);
153  }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
llvm::IRBuilder ir_builder_
Definition: CgenState.h:384
llvm::ConstantInt * llBool(const bool v) const
Definition: CgenState.h:263
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
llvm::LLVMContext & context_
Definition: CgenState.h:382
CONSTEXPR DEVICE bool is_null(const T &value)
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
Definition: CgenState.cpp:395
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:217
#define CHECK_LT(x, y)
Definition: Logger.h:303
size_t size() const final
Definition: Distance.h:31
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:249
#define CHECK(condition)
Definition: Logger.h:291
virtual const Analyzer::Expr * getOperand(const size_t index)
Definition: Codegen.cpp:64
uint32_t log2_bytes(const uint32_t bytes)
Definition: Execute.h:198
#define IS_GEO(T)
Definition: sqltypes.h:310

+ Here is the call graph for this function:

SQLTypeInfo spatial_type::Distance::getNullType ( ) const
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 33 of file Distance.h.

References kBOOLEAN.

33 { return SQLTypeInfo(kBOOLEAN); }
size_t spatial_type::Distance::size ( ) const
inlinefinalvirtual

Implements spatial_type::Codegen.

Definition at line 31 of file Distance.h.

Referenced by codegenLoads().

31 { return 2; }

+ Here is the caller graph for this function:


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