join.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2024, 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 
17 #pragma once
18 
19 #include <cudf/ast/expressions.hpp>
20 #include <cudf/hashing.hpp>
22 #include <cudf/types.hpp>
24 #include <cudf/utilities/export.hpp>
26 #include <cudf/utilities/span.hpp>
27 
28 #include <rmm/cuda_stream_view.hpp>
29 #include <rmm/device_uvector.hpp>
30 
31 #include <optional>
32 #include <utility>
33 #include <vector>
34 
35 namespace CUDF_EXPORT cudf {
36 
42 enum class has_nested : bool { YES, NO };
43 
44 // forward declaration
45 namespace hashing::detail {
46 
50 template <typename T>
52 } // namespace hashing::detail
53 namespace detail {
54 
58 template <typename T>
59 class hash_join;
60 
64 template <cudf::has_nested HasNested>
66 } // namespace detail
67 
107 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
108  std::unique_ptr<rmm::device_uvector<size_type>>>
109 inner_join(cudf::table_view const& left_keys,
110  cudf::table_view const& right_keys,
111  null_equality compare_nulls = null_equality::EQUAL,
114 
149 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
150  std::unique_ptr<rmm::device_uvector<size_type>>>
151 left_join(cudf::table_view const& left_keys,
152  cudf::table_view const& right_keys,
153  null_equality compare_nulls = null_equality::EQUAL,
156 
190 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
191  std::unique_ptr<rmm::device_uvector<size_type>>>
192 full_join(cudf::table_view const& left_keys,
193  cudf::table_view const& right_keys,
194  null_equality compare_nulls = null_equality::EQUAL,
197 
221 std::unique_ptr<rmm::device_uvector<size_type>> left_semi_join(
222  cudf::table_view const& left_keys,
223  cudf::table_view const& right_keys,
224  null_equality compare_nulls = null_equality::EQUAL,
227 
254 std::unique_ptr<rmm::device_uvector<size_type>> left_anti_join(
255  cudf::table_view const& left_keys,
256  cudf::table_view const& right_keys,
257  null_equality compare_nulls = null_equality::EQUAL,
260 
284 std::unique_ptr<cudf::table> cross_join(
285  cudf::table_view const& left,
286  cudf::table_view const& right,
289 
298 enum class nullable_join : bool { YES, NO };
299 
307 class hash_join {
308  public:
311 
312  hash_join() = delete;
313  ~hash_join();
314  hash_join(hash_join const&) = delete;
315  hash_join(hash_join&&) = delete;
316  hash_join& operator=(hash_join const&) = delete;
317  hash_join& operator=(hash_join&&) = delete;
318 
330  null_equality compare_nulls,
332 
341  null_equality compare_nulls,
343 
362  [[nodiscard]] std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
363  std::unique_ptr<rmm::device_uvector<size_type>>>
365  std::optional<std::size_t> output_size = {},
368 
387  [[nodiscard]] std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
388  std::unique_ptr<rmm::device_uvector<size_type>>>
390  std::optional<std::size_t> output_size = {},
393 
412  [[nodiscard]] std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
413  std::unique_ptr<rmm::device_uvector<size_type>>>
415  std::optional<std::size_t> output_size = {},
418 
432  [[nodiscard]] std::size_t inner_join_size(
433  cudf::table_view const& probe, rmm::cuda_stream_view stream = cudf::get_default_stream()) const;
434 
448  [[nodiscard]] std::size_t left_join_size(
449  cudf::table_view const& probe, rmm::cuda_stream_view stream = cudf::get_default_stream()) const;
450 
466  [[nodiscard]] std::size_t full_join_size(
467  cudf::table_view const& probe,
470 
471  private:
472  const std::unique_ptr<impl_type const> _impl;
473 };
474 
484 // TODO: `HasNested` to be removed via dispatching
485 template <cudf::has_nested HasNested>
487  public:
488  distinct_hash_join() = delete;
490  distinct_hash_join(distinct_hash_join const&) = delete;
492  distinct_hash_join& operator=(distinct_hash_join const&) = delete;
493  distinct_hash_join& operator=(distinct_hash_join&&) = delete;
494 
506  cudf::table_view const& probe,
507  nullable_join has_nulls = nullable_join::YES,
508  null_equality compare_nulls = null_equality::EQUAL,
510 
522  [[nodiscard]] std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
523  std::unique_ptr<rmm::device_uvector<size_type>>>
526 
542  [[nodiscard]] std::unique_ptr<rmm::device_uvector<size_type>> left_join(
545 
546  private:
547  using impl_type = typename cudf::detail::distinct_hash_join<HasNested>;
548 
549  std::unique_ptr<impl_type> _impl;
550 };
551 
588 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
589  std::unique_ptr<rmm::device_uvector<size_type>>>
591  table_view const& right,
592  ast::expression const& binary_predicate,
593  std::optional<std::size_t> output_size = {},
596 
635 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
636  std::unique_ptr<rmm::device_uvector<size_type>>>
638  table_view const& right,
639  ast::expression const& binary_predicate,
640  std::optional<std::size_t> output_size = {},
643 
680 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
681  std::unique_ptr<rmm::device_uvector<size_type>>>
683  table_view const& right,
684  ast::expression const& binary_predicate,
687 
721 std::unique_ptr<rmm::device_uvector<size_type>> conditional_left_semi_join(
722  table_view const& left,
723  table_view const& right,
724  ast::expression const& binary_predicate,
725  std::optional<std::size_t> output_size = {},
728 
762 std::unique_ptr<rmm::device_uvector<size_type>> conditional_left_anti_join(
763  table_view const& left,
764  table_view const& right,
765  ast::expression const& binary_predicate,
766  std::optional<std::size_t> output_size = {},
769 
817 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
818  std::unique_ptr<rmm::device_uvector<size_type>>>
820  table_view const& left_equality,
821  table_view const& right_equality,
822  table_view const& left_conditional,
823  table_view const& right_conditional,
824  ast::expression const& binary_predicate,
825  null_equality compare_nulls = null_equality::EQUAL,
826  std::optional<std::pair<std::size_t, device_span<size_type const>>> output_size_data = {},
829 
879 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
880  std::unique_ptr<rmm::device_uvector<size_type>>>
882  table_view const& left_equality,
883  table_view const& right_equality,
884  table_view const& left_conditional,
885  table_view const& right_conditional,
886  ast::expression const& binary_predicate,
887  null_equality compare_nulls = null_equality::EQUAL,
888  std::optional<std::pair<std::size_t, device_span<size_type const>>> output_size_data = {},
891 
941 std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
942  std::unique_ptr<rmm::device_uvector<size_type>>>
944  table_view const& left_equality,
945  table_view const& right_equality,
946  table_view const& left_conditional,
947  table_view const& right_conditional,
948  ast::expression const& binary_predicate,
949  null_equality compare_nulls = null_equality::EQUAL,
950  std::optional<std::pair<std::size_t, device_span<size_type const>>> output_size_data = {},
953 
993 std::unique_ptr<rmm::device_uvector<size_type>> mixed_left_semi_join(
994  table_view const& left_equality,
995  table_view const& right_equality,
996  table_view const& left_conditional,
997  table_view const& right_conditional,
998  ast::expression const& binary_predicate,
999  null_equality compare_nulls = null_equality::EQUAL,
1002 
1043 std::unique_ptr<rmm::device_uvector<size_type>> mixed_left_anti_join(
1044  table_view const& left_equality,
1045  table_view const& right_equality,
1046  table_view const& left_conditional,
1047  table_view const& right_conditional,
1048  ast::expression const& binary_predicate,
1049  null_equality compare_nulls = null_equality::EQUAL,
1052 
1085 std::pair<std::size_t, std::unique_ptr<rmm::device_uvector<size_type>>> mixed_inner_join_size(
1086  table_view const& left_equality,
1087  table_view const& right_equality,
1088  table_view const& left_conditional,
1089  table_view const& right_conditional,
1090  ast::expression const& binary_predicate,
1091  null_equality compare_nulls = null_equality::EQUAL,
1094 
1127 std::pair<std::size_t, std::unique_ptr<rmm::device_uvector<size_type>>> mixed_left_join_size(
1128  table_view const& left_equality,
1129  table_view const& right_equality,
1130  table_view const& left_conditional,
1131  table_view const& right_conditional,
1132  ast::expression const& binary_predicate,
1133  null_equality compare_nulls = null_equality::EQUAL,
1136 
1156  table_view const& left,
1157  table_view const& right,
1158  ast::expression const& binary_predicate,
1161 
1181  table_view const& left,
1182  table_view const& right,
1183  ast::expression const& binary_predicate,
1186 
1206  table_view const& left,
1207  table_view const& right,
1208  ast::expression const& binary_predicate,
1211 
1231  table_view const& left,
1232  table_view const& right,
1233  ast::expression const& binary_predicate,
1237 } // namespace CUDF_EXPORT cudf
Forward declaration for our distinct hash join.
Definition: join.hpp:65
Forward declaration for our hash join.
Definition: join.hpp:59
Distinct hash join that builds hash table in creation and probes results in subsequent *_join member ...
Definition: join.hpp:486
std::unique_ptr< rmm::device_uvector< size_type > > left_join(rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref()) const
Returns the build table indices that can be used to construct the result of performing a left join be...
distinct_hash_join(cudf::table_view const &build, cudf::table_view const &probe, nullable_join has_nulls=nullable_join::YES, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream())
Constructs a distinct hash join object for subsequent probe calls.
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > inner_join(rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref()) const
Returns the row indices that can be used to construct the result of performing an inner join between ...
Hash join that builds hash table in creation and probes results in subsequent *_join member functions...
Definition: join.hpp:307
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > left_join(cudf::table_view const &probe, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref()) const
hash_join(cudf::table_view const &build, nullable_join has_nulls, null_equality compare_nulls, rmm::cuda_stream_view stream=cudf::get_default_stream())
Construct a hash join object for subsequent probe calls.
typename cudf::detail::hash_join< cudf::hashing::detail::MurmurHash3_x86_32< cudf::hash_value_type > > impl_type
Implementation type.
Definition: join.hpp:310
std::size_t left_join_size(cudf::table_view const &probe, rmm::cuda_stream_view stream=cudf::get_default_stream()) const
std::size_t inner_join_size(cudf::table_view const &probe, rmm::cuda_stream_view stream=cudf::get_default_stream()) const
hash_join(cudf::table_view const &build, null_equality compare_nulls, rmm::cuda_stream_view stream=cudf::get_default_stream())
Construct a hash join object for subsequent probe calls.
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > inner_join(cudf::table_view const &probe, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref()) const
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > full_join(cudf::table_view const &probe, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref()) const
std::size_t full_join_size(cudf::table_view const &probe, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref()) const
Forward declaration for our Murmur Hash 3 implementation.
Definition: join.hpp:51
A set of cudf::column_view's of the same size.
Definition: table_view.hpp:200
std::unique_ptr< rmm::device_uvector< size_type > > mixed_left_anti_join(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns an index vector corresponding to all rows in the left tables for which there is no row in the...
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > conditional_full_join(table_view const &left, table_view const &right, ast::expression const &binary_predicate, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to all pairs of rows between the specified tables w...
std::size_t conditional_inner_join_size(table_view const &left, table_view const &right, ast::expression const &binary_predicate, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the exact number of matches (rows) when performing a conditional inner join between the speci...
std::size_t conditional_left_semi_join_size(table_view const &left, table_view const &right, ast::expression const &binary_predicate, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the exact number of matches (rows) when performing a conditional left semi join between the s...
std::pair< std::size_t, std::unique_ptr< rmm::device_uvector< size_type > > > mixed_inner_join_size(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the exact number of matches (rows) when performing a mixed inner join between the specified t...
std::unique_ptr< rmm::device_uvector< size_type > > mixed_left_semi_join(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns an index vector corresponding to all rows in the left tables where the columns of the equalit...
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > left_join(cudf::table_view const &left_keys, cudf::table_view const &right_keys, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to a left join between the specified tables.
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > full_join(cudf::table_view const &left_keys, cudf::table_view const &right_keys, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to a full join between the specified tables.
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > mixed_full_join(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, std::optional< std::pair< std::size_t, device_span< size_type const >>> output_size_data={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to all pairs of rows between the specified tables w...
std::unique_ptr< rmm::device_uvector< size_type > > left_anti_join(cudf::table_view const &left_keys, cudf::table_view const &right_keys, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a vector of row indices corresponding to a left anti join between the specified tables.
std::unique_ptr< rmm::device_uvector< size_type > > left_semi_join(cudf::table_view const &left_keys, cudf::table_view const &right_keys, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a vector of row indices corresponding to a left semi-join between the specified tables.
std::size_t conditional_left_anti_join_size(table_view const &left, table_view const &right, ast::expression const &binary_predicate, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the exact number of matches (rows) when performing a conditional left anti join between the s...
std::unique_ptr< rmm::device_uvector< size_type > > conditional_left_semi_join(table_view const &left, table_view const &right, ast::expression const &binary_predicate, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns an index vector corresponding to all rows in the left table for which there exists some row i...
std::pair< std::size_t, std::unique_ptr< rmm::device_uvector< size_type > > > mixed_left_join_size(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the exact number of matches (rows) when performing a mixed left join between the specified ta...
has_nested
Enum to indicate whether the distinct join table has nested columns or not.
Definition: join.hpp:42
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > mixed_inner_join(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, std::optional< std::pair< std::size_t, device_span< size_type const >>> output_size_data={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to all pairs of rows between the specified tables w...
nullable_join
The enum class to specify if any of the input join tables (build table and any later probe table) has...
Definition: join.hpp:298
std::size_t conditional_left_join_size(table_view const &left, table_view const &right, ast::expression const &binary_predicate, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the exact number of matches (rows) when performing a conditional left join between the specif...
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > inner_join(cudf::table_view const &left_keys, cudf::table_view const &right_keys, null_equality compare_nulls=null_equality::EQUAL, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to an inner join between the specified tables.
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > conditional_inner_join(table_view const &left, table_view const &right, ast::expression const &binary_predicate, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to all pairs of rows between the specified tables w...
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > mixed_left_join(table_view const &left_equality, table_view const &right_equality, table_view const &left_conditional, table_view const &right_conditional, ast::expression const &binary_predicate, null_equality compare_nulls=null_equality::EQUAL, std::optional< std::pair< std::size_t, device_span< size_type const >>> output_size_data={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to all pairs of rows between the specified tables w...
std::pair< std::unique_ptr< rmm::device_uvector< size_type > >, std::unique_ptr< rmm::device_uvector< size_type > > > conditional_left_join(table_view const &left, table_view const &right, ast::expression const &binary_predicate, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns a pair of row index vectors corresponding to all pairs of rows between the specified tables w...
std::unique_ptr< cudf::table > cross_join(cudf::table_view const &left, cudf::table_view const &right, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Performs a cross join on two tables (left, right)
std::unique_ptr< rmm::device_uvector< size_type > > conditional_left_anti_join(table_view const &left, table_view const &right, ast::expression const &binary_predicate, std::optional< std::size_t > output_size={}, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns an index vector corresponding to all rows in the left table for which there does not exist an...
rmm::cuda_stream_view const get_default_stream()
Get the current default stream.
rmm::device_async_resource_ref get_current_device_resource_ref()
Get the current device memory resource reference.
cuda::mr::async_resource_ref< cuda::mr::device_accessible > device_async_resource_ref
null_equality
Enum to consider two nulls as equal or unequal.
Definition: types.hpp:151
cuDF interfaces
Definition: aggregation.hpp:35
bool has_nulls(table_view const &view)
Returns True if the table has nulls in any of its columns.
APIs for spans.
A generic expression that can be evaluated to return a value.
Definition: expressions.hpp:48
Device version of C++20 std::span with reduced feature set.
Definition: span.hpp:338
Class definitions for (mutable)_table_view
Type declarations for libcudf.