expressions.hpp
1 /*
2  * Copyright (c) 2020-2022, NVIDIA CORPORATION.
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 #pragma once
17 
18 #include <cudf/scalar/scalar.hpp>
21 #include <cudf/types.hpp>
22 #include <cudf/utilities/error.hpp>
23 
24 #include <cstdint>
25 
26 namespace cudf {
27 namespace ast {
28 
29 // Forward declaration.
30 namespace detail {
31 class expression_parser;
32 }
33 
40 struct expression {
47  virtual cudf::size_type accept(detail::expression_parser& visitor) const = 0;
48 
56  [[nodiscard]] bool may_evaluate_null(table_view const& left, rmm::cuda_stream_view stream) const
57  {
58  return may_evaluate_null(left, left, stream);
59  }
60 
69  [[nodiscard]] virtual bool may_evaluate_null(table_view const& left,
70  table_view const& right,
71  rmm::cuda_stream_view stream) const = 0;
72 
73  virtual ~expression() {}
74 };
75 
79 enum class ast_operator : int32_t {
80  // Binary operators
81  ADD,
82  SUB,
83  MUL,
84  DIV,
85  TRUE_DIV,
86  FLOOR_DIV,
87  MOD,
89  PYMOD,
90  POW,
91  EQUAL,
92  NULL_EQUAL,
93  NOT_EQUAL,
96  LESS,
97  GREATER,
98  LESS_EQUAL,
99  GREATER_EQUAL,
100  BITWISE_AND,
101  BITWISE_OR,
102  BITWISE_XOR,
103  LOGICAL_AND,
104  NULL_LOGICAL_AND,
105  LOGICAL_OR,
109  NULL_LOGICAL_OR,
110  // Unary operators
114  IDENTITY,
115  SIN,
116  COS,
117  TAN,
118  ARCSIN,
119  ARCCOS,
120  ARCTAN,
121  SINH,
122  COSH,
123  TANH,
124  ARCSINH,
125  ARCCOSH,
126  ARCTANH,
127  EXP,
128  LOG,
129  SQRT,
130  CBRT,
131  CEIL,
132  FLOOR,
133  ABS,
134  RINT,
135  BIT_INVERT,
136  NOT,
137  CAST_TO_INT64,
138  CAST_TO_UINT64,
139  CAST_TO_FLOAT64
140 };
141 
147 enum class table_reference {
148  LEFT,
149  RIGHT,
150  OUTPUT
151 };
152 
156 class literal : public expression {
157  public:
164  template <typename T>
166  : scalar(value), value(cudf::get_scalar_device_view(value))
167  {
168  }
169 
176  template <typename T>
178  : scalar(value), value(cudf::get_scalar_device_view(value))
179  {
180  }
181 
188  template <typename T>
190  : scalar(value), value(cudf::get_scalar_device_view(value))
191  {
192  }
193 
199  [[nodiscard]] cudf::data_type get_data_type() const { return get_value().type(); }
200 
207  {
208  return value;
209  }
210 
217  cudf::size_type accept(detail::expression_parser& visitor) const override;
218 
219  [[nodiscard]] bool may_evaluate_null(table_view const& left,
220  table_view const& right,
221  rmm::cuda_stream_view stream) const override
222  {
223  return !is_valid(stream);
224  }
225 
232  [[nodiscard]] bool is_valid(rmm::cuda_stream_view stream) const
233  {
234  return scalar.is_valid(stream);
235  }
236 
237  private:
238  cudf::scalar const& scalar;
240 };
241 
245 class column_reference : public expression {
246  public:
255  table_reference table_source = table_reference::LEFT)
256  : column_index(column_index), table_source(table_source)
257  {
258  }
259 
265  [[nodiscard]] cudf::size_type get_column_index() const { return column_index; }
266 
272  [[nodiscard]] table_reference get_table_source() const { return table_source; }
273 
280  [[nodiscard]] cudf::data_type get_data_type(table_view const& table) const
281  {
282  return table.column(get_column_index()).type();
283  }
284 
292  [[nodiscard]] cudf::data_type get_data_type(table_view const& left_table,
293  table_view const& right_table) const
294  {
295  auto const table = [&] {
296  if (get_table_source() == table_reference::LEFT) {
297  return left_table;
298  } else if (get_table_source() == table_reference::RIGHT) {
299  return right_table;
300  } else {
301  CUDF_FAIL("Column reference data type cannot be determined from unknown table.");
302  }
303  }();
304  return table.column(get_column_index()).type();
305  }
306 
313  cudf::size_type accept(detail::expression_parser& visitor) const override;
314 
315  [[nodiscard]] bool may_evaluate_null(table_view const& left,
316  table_view const& right,
317  rmm::cuda_stream_view stream) const override
318  {
319  return (table_source == table_reference::LEFT ? left : right).column(column_index).has_nulls();
320  }
321 
322  private:
323  cudf::size_type column_index;
324  table_reference table_source;
325 };
326 
330 class operation : public expression {
331  public:
338  operation(ast_operator op, expression const& input);
339 
347  operation(ast_operator op, expression const& left, expression const& right);
348 
349  // operation only stores references to expressions, so it does not accept r-value
350  // references: the calling code must own the expressions.
351  operation(ast_operator op, expression&& input) = delete;
352  operation(ast_operator op, expression&& left, expression&& right) = delete;
353  operation(ast_operator op, expression&& left, expression const& right) = delete;
354  operation(ast_operator op, expression const& left, expression&& right) = delete;
355 
361  [[nodiscard]] ast_operator get_operator() const { return op; }
362 
368  std::vector<std::reference_wrapper<expression const>> get_operands() const { return operands; }
369 
376  cudf::size_type accept(detail::expression_parser& visitor) const override;
377 
378  [[nodiscard]] bool may_evaluate_null(table_view const& left,
379  table_view const& right,
380  rmm::cuda_stream_view stream) const override
381  {
382  return std::any_of(operands.cbegin(),
383  operands.cend(),
384  [&left, &right, &stream](std::reference_wrapper<expression const> subexpr) {
385  return subexpr.get().may_evaluate_null(left, right, stream);
386  });
387  };
388 
389  private:
390  ast_operator const op;
391  std::vector<std::reference_wrapper<expression const>> const operands;
392 };
393 
394 } // namespace ast
395 
396 } // namespace cudf
cudf::ast::column_reference::accept
cudf::size_type accept(detail::expression_parser &visitor) const override
Accepts a visitor class.
cudf::ast::literal::literal
literal(cudf::duration_scalar< T > &value)
Construct a new literal object.
Definition: expressions.hpp:189
table_view.hpp
Class definitions for (mutable)_table_view
cudf::ast::expression::may_evaluate_null
virtual bool may_evaluate_null(table_view const &left, table_view const &right, rmm::cuda_stream_view stream) const =0
Returns true if the expression may evaluate to null.
cudf::timestamp_scalar
An owning class to represent a timestamp value in device memory.
Definition: scalar.hpp:622
cudf::ast::expression::may_evaluate_null
bool may_evaluate_null(table_view const &left, rmm::cuda_stream_view stream) const
Returns true if the expression may evaluate to null.
Definition: expressions.hpp:56
cudf::ast::literal::get_data_type
cudf::data_type get_data_type() const
Get the data type.
Definition: expressions.hpp:199
cudf::ast::column_reference::get_data_type
cudf::data_type get_data_type(table_view const &table) const
Get the data type.
Definition: expressions.hpp:280
scalar.hpp
Class definitions for cudf::scalar.
cudf::size_type
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:80
cudf::ast::operation::operation
operation(ast_operator op, expression const &left, expression const &right)
Construct a new binary operation object.
cudf::ast::operation::get_operator
ast_operator get_operator() const
Get the operator.
Definition: expressions.hpp:361
types.hpp
Type declarations for libcudf.
rmm::cuda_stream_view
CUDF_FAIL
#define CUDF_FAIL(...)
Indicates that an erroneous code path has been taken.
Definition: error.hpp:162
cudf::ast::literal::accept
cudf::size_type accept(detail::expression_parser &visitor) const override
Accepts a visitor class.
cudf::table
A set of cudf::column's of the same size.
Definition: table.hpp:40
cudf::ast::operation::may_evaluate_null
bool may_evaluate_null(table_view const &left, table_view const &right, rmm::cuda_stream_view stream) const override
Returns true if the expression may evaluate to null.
Definition: expressions.hpp:378
cudf::ast::column_reference::get_column_index
cudf::size_type get_column_index() const
Get the column index.
Definition: expressions.hpp:265
cudf::ast::operation::operation
operation(ast_operator op, expression const &input)
Construct a new unary operation object.
cudf::ast::column_reference::get_table_source
table_reference get_table_source() const
Get the table source.
Definition: expressions.hpp:272
cudf::scalar::is_valid
bool is_valid(rmm::cuda_stream_view stream=cudf::get_default_stream()) const
Indicates whether the scalar contains a valid value.
cudf::ast::column_reference::get_data_type
cudf::data_type get_data_type(table_view const &left_table, table_view const &right_table) const
Get the data type.
Definition: expressions.hpp:292
cudf::duration_scalar
An owning class to represent a duration value in device memory.
Definition: scalar.hpp:677
cudf::unary_operator::SIN
@ SIN
Trigonometric sine.
cudf::ast::expression
A generic expression that can be evaluated to return a value.
Definition: expressions.hpp:40
cudf::ast::literal::get_value
cudf::detail::fixed_width_scalar_device_view_base get_value() const
Get the value object.
Definition: expressions.hpp:206
cudf::scalar
An owning class to represent a singular value.
Definition: scalar.hpp:48
cudf::get_scalar_device_view
auto get_scalar_device_view(numeric_scalar< T > &s)
Get the device view of a numeric_scalar.
Definition: scalar_device_view.cuh:391
cudf::numeric_scalar
An owning class to represent a numerical value in device memory.
Definition: scalar.hpp:243
cudf::table_view
A set of cudf::column_view's of the same size.
Definition: table_view.hpp:187
cudf::data_type
Indicator for the logical data type of an element in a column.
Definition: types.hpp:236
cudf::ast::literal::literal
literal(cudf::numeric_scalar< T > &value)
Construct a new literal object.
Definition: expressions.hpp:165
cudf
cuDF interfaces
Definition: aggregation.hpp:34
cudf::ast::operation
An operation expression holds an operator and zero or more operands.
Definition: expressions.hpp:330
cudf::weak_ordering::LESS
@ LESS
Indicates a is less than (ordered before) b
cudf::detail::fixed_width_scalar_device_view_base
A type-erased scalar_device_view where the value is a fixed width type.
Definition: scalar_device_view.cuh:80
cudf::ast::literal
A literal value used in an abstract syntax tree.
Definition: expressions.hpp:156
cudf::ast::column_reference::column_reference
column_reference(cudf::size_type column_index, table_reference table_source=table_reference::LEFT)
Construct a new column reference object.
Definition: expressions.hpp:254
cudf::ast::literal::may_evaluate_null
bool may_evaluate_null(table_view const &left, table_view const &right, rmm::cuda_stream_view stream) const override
Returns true if the expression may evaluate to null.
Definition: expressions.hpp:219
cudf::ast::operation::get_operands
std::vector< std::reference_wrapper< expression const > > get_operands() const
Get the operands.
Definition: expressions.hpp:368
cudf::ast::column_reference
A expression referring to data from a column in a table.
Definition: expressions.hpp:245
cudf::ast::expression::accept
virtual cudf::size_type accept(detail::expression_parser &visitor) const =0
Accepts a visitor class.
cudf::ast::column_reference::may_evaluate_null
bool may_evaluate_null(table_view const &left, table_view const &right, rmm::cuda_stream_view stream) const override
Returns true if the expression may evaluate to null.
Definition: expressions.hpp:315
scalar_device_view.cuh
Scalar device view class definitions.
cudf::ast::operation::accept
cudf::size_type accept(detail::expression_parser &visitor) const override
Accepts a visitor class.
cudf::detail::scalar_device_view_base::type
data_type type() const noexcept
Returns the value type.
Definition: scalar_device_view.cuh:42
cudf::ast::literal::is_valid
bool is_valid(rmm::cuda_stream_view stream) const
Check if the underlying scalar is valid.
Definition: expressions.hpp:232
cudf::ast::literal::literal
literal(cudf::timestamp_scalar< T > &value)
Construct a new literal object.
Definition: expressions.hpp:177
error.hpp