Skip to content

[QST] Should datatype equality comparisons traverse nested children? #14494

Closed
@ZelboK

Description

Describe the bug
I have a tendency of running mini "experiments" to better understand functionality behavior through tests. Found some unexpected behavior while writing a test that should (likely?) throw an exception.

EDIT (@wence-):

This doesn't raise because the top-level data type ids match (both the left and right columns are structs). So, question: should datatype equality traverse nested children?

END EDIT

Steps/Code to reproduce bug

TEST_F(JoinTest, AntiJoinPlayground)
{
  auto left_col0 = [] {
    column_wrapper<int32_t> child1{1, 5, 43, 3};
    column_wrapper<int32_t> child2{11, 12, 13, 4};
    column_wrapper<int32_t> child3{90, 812, 513, 54};
    return cudf::test::structs_column_wrapper{{child1, child2, child3}};
  }();
  auto right_col0 = [] {
    column_wrapper<int32_t> child1{1, 5, 43, 3};
    column_wrapper<int32_t> child2{11, 12, 13, 4};
    return cudf::test::structs_column_wrapper{{child1, child2}};
  }();
  auto left  = cudf::table_view{{left_col0}};
  auto right = cudf::table_view{{right_col0}};

  auto result      = cudf::left_anti_join(left, right);
  auto result_span = cudf::device_span<cudf::size_type const>{*result};
  auto result_col  = cudf::column_view{result_span};
  auto expected    = column_wrapper<cudf::size_type>{0, 1};
  CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, result_col);
}

Expected behavior
If you run this test with left_join, it will return an SFINAE error

/home/kashimo/workspace/cudf/cpp/tests/join/join_tests.cpp:1652:63: error: no match for ‘operator*’ (operand type is ‘std::pair<std::unique_ptr<rmm::device_uvector<int> >, std::unique_ptr<rmm::device_uvector<int> > >’)
 1652 |   auto result_span = cudf::device_span<cudf::size_type const>{*result};
      |                                                               ^~~~~~~
/home/kashimo/workspace/cudf/cpp/tests/join/join_tests.cpp:1652:70: error: no matching function for call to ‘cudf::device_span<const int>::device_span(<brace-enclosed initializer list>)’
 1652 |   auto result_span = cudf::device_span<cudf::size_type const>{*result};
      |                                                                      ^
In file included from /home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:20,
                 from /home/kashimo/workspace/cudf/cpp/include/cudf/column/column.hpp:18,
                 from /home/kashimo/workspace/cudf/cpp/tests/join/join_tests.cpp:17:
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:316:13: note: candidate: ‘template<class OtherT, long unsigned int OtherExtent, std::enable_if_t<(((18446744073709551615 == OtherExtent) || (18446744073709551615 == cudf::dynamic_extent)) && is_convertible_v<OtherT (*)[], const int (*)[]>), void>* <anonymous> > constexpr cudf::device_span<T, Extent>::device_span(const cudf::device_span<OtherT, OtherExtent>&) [with OtherT = OtherT; long unsigned int OtherExtent = OtherExtent; std::enable_if_t<(((Extent == OtherExtent) || (Extent == cudf::dynamic_extent)) && is_convertible_v<OtherT (*)[], T (*)[]>), void>* <anonymous> = <anonymous>; T = const int; long unsigned int Extent = 18446744073709551615]’
  316 |   constexpr device_span(device_span<OtherT, OtherExtent> const& other) noexcept
      |             ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:316:13: note:   template argument deduction/substitution failed:
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:305:13: note: candidate: ‘template<class C, std::enable_if_t<(cudf::is_device_span_supported_container<C>::value && is_convertible_v<typename std::remove_pointer<decltype (thrust::raw_pointer_cast(declval<C&>().data()))>::type (*)[], const int (*)[]>), void>* <anonymous> > constexpr cudf::device_span<T, Extent>::device_span(const C&) [with C = C; std::enable_if_t<(cudf::is_device_span_supported_container<C>::value && is_convertible_v<typename std::remove_pointer<decltype (thrust::raw_pointer_cast(declval<C&>().data()))>::type (*)[], T (*)[]>)>* <anonymous> = <anonymous>; T = const int; long unsigned int Extent = 18446744073709551615]’
  305 |   constexpr device_span(C const& in) : base(thrust::raw_pointer_cast(in.data()), in.size())
      |             ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:305:13: note:   template argument deduction/substitution failed:
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:292:13: note: candidate: ‘template<class C, std::enable_if_t<(cudf::is_device_span_supported_container<C>::value && is_convertible_v<typename std::remove_pointer<decltype (thrust::raw_pointer_cast(declval<C&>().data()))>::type (*)[], const int (*)[]>), void>* <anonymous> > constexpr cudf::device_span<T, Extent>::device_span(C&) [with C = C; std::enable_if_t<(cudf::is_device_span_supported_container<C>::value && is_convertible_v<typename std::remove_pointer<decltype (thrust::raw_pointer_cast(declval<C&>().data()))>::type (*)[], T (*)[]>)>* <anonymous> = <anonymous>; T = const int; long unsigned int Extent = 18446744073709551615]’
  292 |   constexpr device_span(C& in) : base(thrust::raw_pointer_cast(in.data()), in.size())
      |             ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:292:13: note:   template argument deduction/substitution failed:
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:68:13: note: candidate: ‘constexpr cudf::detail::span_base<T, Extent, Derived>::span_base(cudf::detail::span_base<T, Extent, Derived>::pointer, cudf::detail::span_base<T, Extent, Derived>::size_type) [with T = const int; long unsigned int Extent = 18446744073709551615; Derived = cudf::device_span<const int>; cudf::detail::span_base<T, Extent, Derived>::pointer = const int*; cudf::detail::span_base<T, Extent, Derived>::size_type = long unsigned int]’
   68 |   constexpr span_base(pointer data, size_type size) : _data(data), _size(size) {}
      |             ^~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:279:15: note:   inherited here
  279 |   using base::base;
      |               ^~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:279:15: note:   candidate expects 2 arguments, 1 provided
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:70:13: note: candidate: ‘constexpr cudf::detail::span_base<T, Extent, Derived>::span_base(const cudf::detail::span_base<T, Extent, Derived>&) [with T = const int; long unsigned int Extent = 18446744073709551615; Derived = cudf::device_span<const int>]’
   70 |   constexpr span_base(span_base const&) noexcept = default;  ///< Copy constructor
      |             ^~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:279:15: note:   inherited here
  279 |   using base::base;
      |               ^~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:279:15: note:   an inherited constructor is not a candidate for initialization from an expression of the same or derived type
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:281:13: note: candidate: ‘constexpr cudf::device_span<T, Extent>::device_span() [with T = const int; long unsigned int Extent = 18446744073709551615]’
  281 |   constexpr device_span() noexcept : base() {}  // required to compile on centos
      |             ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:281:13: note:   candidate expects 0 arguments, 1 provided
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:277:8: note: candidate: ‘constexpr cudf::device_span<const int>::device_span(const cudf::device_span<const int>&)’
  277 | struct device_span : public cudf::detail::span_base<T, Extent, device_span<T, Extent>> {
      |        ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:277:8: note:   conversion of argument 1 would be ill-formed:
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:277:8: note: candidate: ‘constexpr cudf::device_span<const int>::device_span(cudf::device_span<const int>&&)’
/home/kashimo/workspace/cudf/cpp/include/cudf/utilities/span.hpp:277:8: note:   conversion of argument 1 would be ill-formed:
/home/kashimo/workspace/cudf/cpp/tests/join/join_tests.cpp:1653:51: error: no matching function for call to ‘cudf::column_view::column_view(<brace-enclosed initializer list>)’
 1653 |   auto result_col  = cudf::column_view{result_span};
      |                                                   ^
In file included from /home/kashimo/workspace/cudf/cpp/include/cudf/column/column.hpp:18,
                 from /home/kashimo/workspace/cudf/cpp/tests/join/join_tests.cpp:17:
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:420:3: note: candidate: template<class T, std::enable_if_t<(is_numeric<T>() || is_chrono<T>())>* <anonymous> > cudf::column_view::column_view(cudf::device_span<const T>)’
  420 |   column_view(device_span<T const> data)
      |   ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:420:3: note:   template argument deduction/substitution failed:
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:371:3: note: candidate: cudf::column_view::column_view(cudf::data_type, cudf::size_type, const void*, const bitmask_type*, cudf::size_type, cudf::size_type, const std::vector<cudf::column_view>&)’
  371 |   column_view(data_type type,
      |   ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:371:3: note:   candidate expects 7 arguments, 1 provided
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:331:3: note: candidate: cudf::column_view::column_view(cudf::column_view&&)’
  331 |   column_view(column_view&&)      = default;  ///< Move constructor
      |   ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:331:3: note:   conversion of argument 1 would be ill-formed:
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:330:3: note: candidate: cudf::column_view::column_view(const cudf::column_view&)’
  330 |   column_view(column_view const&) = default;  ///< Copy constructor
      |   ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:330:3: note:   conversion of argument 1 would be ill-formed:
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:315:3: note: candidate: constexpr cudf::column_view::column_view()’
  315 |   column_view() = default;
      |   ^~~~~~~~~~~
/home/kashimo/workspace/cudf/cpp/include/cudf/column/column_view.hpp:315:3: note:   candidate expects 0 arguments, 1 provided
gmake[2]: *** [tests/CMakeFiles/JOIN_TEST.dir/build.make:76: tests/CMakeFiles/JOIN_TEST.dir/join/join_tests.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:1445: tests/CMakeFiles/JOIN_TEST.dir/all] Error 2
gmake: *** [Makefile:166: all] Error 2

When I get more time I can look into this more deeply. For now just wanted to mention.

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglibcudfAffects libcudf (C++/CUDA) code.questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions