oneDPL icon indicating copy to clipboard operation
oneDPL copied to clipboard

reduce_by_segment compilation failure for non-primitive types

Open upsj opened this issue 3 years ago • 3 comments

Take the following minimal examples of reduce_by_segment calls

#include <oneapi/dpl/algorithm>
#include <oneapi/dpl/execution>

#include <CL/sycl.hpp>

#include <complex>

void foo() {
    int* a = nullptr;
    double* b = nullptr;
    oneapi::dpl::reduce_by_segment(oneapi::dpl::execution::par_unseq, a, a, b, a, b);
}

void bar() {
    int* a = nullptr;
    std::complex<double>* b = nullptr;
    oneapi::dpl::reduce_by_segment(oneapi::dpl::execution::par_unseq, a, a, b, a, b);
}

They only differ in the type of the values being reduced, but while foo compiles fine, bar fails because the algorithm internally attempts to assign complex<double> to unsigned long. This looks like it points to a type confusion in the call to inclusive_scan in glue_numeric_impl.h that only works accidentally with double.

Full compilation output below

In file included from test.cpp:2:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/execution:34:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/glue_algorithm_impl.h:26:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h:21:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/parallel_backend.h:19:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h:24:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/../pstl/iterator_impl.h:24:
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/tuple_impl.h:414:37: error: assigning to 'unsigned long' from incompatible type 'const std::complex<double>'
        holder.value = other.holder.value;
                       ~~~~~~~~~~~~~^~~~~
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:321:19: note: in instantiation of function template specialization 'oneapi::dpl::__internal::tuple<unsigned long &, unsigned long &>::operator=<std::complex<double>, unsigned long>' requested here
        *__result = __tmp;
                  ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/../pstl/glue_numeric_impl.h:261:37: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__pattern_transform_scan<oneapi::dpl::execution::parallel_unsequenced_policy &, oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>, std::integral_constant<bool, true>, std::integral_constant<bool, true>, std::integral_constant<bool, true>>' requested here
    return oneapi::dpl::__internal::__pattern_transform_scan(
                                    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/../pstl/glue_numeric_impl.h:206:12: note: in instantiation of function template specialization 'oneapi::dpl::transform_inclusive_scan<oneapi::dpl::execution::parallel_unsequenced_policy &, oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>>' requested here
    return transform_inclusive_scan(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op,
           ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:109:5: note: in instantiation of function template specialization 'oneapi::dpl::inclusive_scan<oneapi::dpl::execution::parallel_unsequenced_policy &, oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>>' requested here
    inclusive_scan(policy1, make_zip_iterator(first2, _mask.get()), make_zip_iterator(first2, _mask.get()) + n,
    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:209:22: note: in instantiation of function template specialization 'oneapi::dpl::internal::reduce_by_segment_impl<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>, std::plus<std::complex<double>>>' requested here
    return internal::reduce_by_segment_impl(::std::forward<Policy>(policy), first1, last1, first2, result1, result2,
                     ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:221:12: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>, std::plus<std::complex<double>>>' requested here
    return reduce_by_segment(::std::forward<Policy>(policy), first1, last1, first2, result1, result2, binary_pred,
           ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:232:12: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>>' requested here
    return reduce_by_segment(::std::forward<Policy>(policy), first1, last1, first2, result1, result2,
           ^
test.cpp:17:18: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *>' requested here
    oneapi::dpl::reduce_by_segment(oneapi::dpl::execution::par_unseq, a, a, b, a, b);
                 ^
In file included from test.cpp:2:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/execution:34:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/glue_algorithm_impl.h:26:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h:21:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/parallel_backend.h:19:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h:24:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/../pstl/iterator_impl.h:24:
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/tuple_impl.h:266:31: error: non-const lvalue reference to type 'unsigned long' cannot bind to a value of unrelated type 'const std::complex<double>'
    __value_holder(_Up&& t) : value(::std::forward<_Up>(t))
                              ^     ~~~~~~~~~~~~~~~~~~~~~~
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/tuple_impl.h:338:45: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__value_holder<unsigned long &>::__value_holder<const std::complex<double> &>' requested here
    tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next)
                                            ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:188:21: note: in instantiation of function template specialization 'oneapi::dpl::__internal::tuple<unsigned long &, unsigned long &>::tuple<std::complex<double>, unsigned long, void>' requested here
        *__result = __init;
                    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:213:24: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__brick_transform_scan<oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::__internal::tuple<std::complex<double>, unsigned long>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>>' requested here
    return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
                       ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:264:36: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__brick_transform_scan<oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::__internal::tuple<std::complex<double>, unsigned long>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>, std::integral_constant<bool, true>>' requested here
                return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op,
                                   ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:322:16: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__pattern_transform_scan<oneapi::dpl::execution::parallel_unsequenced_policy &, oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::__internal::tuple<std::complex<double>, unsigned long>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>, std::integral_constant<bool, true>, std::integral_constant<bool, true>>' requested here
        return __pattern_transform_scan(::std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result,
               ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/../pstl/glue_numeric_impl.h:261:37: note: (skipping 2 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
    return oneapi::dpl::__internal::__pattern_transform_scan(
                                    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:109:5: note: in instantiation of function template specialization 'oneapi::dpl::inclusive_scan<oneapi::dpl::execution::parallel_unsequenced_policy &, oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>>' requested here
    inclusive_scan(policy1, make_zip_iterator(first2, _mask.get()), make_zip_iterator(first2, _mask.get()) + n,
    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:209:22: note: in instantiation of function template specialization 'oneapi::dpl::internal::reduce_by_segment_impl<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>, std::plus<std::complex<double>>>' requested here
    return internal::reduce_by_segment_impl(::std::forward<Policy>(policy), first1, last1, first2, result1, result2,
                     ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:221:12: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>, std::plus<std::complex<double>>>' requested here
    return reduce_by_segment(::std::forward<Policy>(policy), first1, last1, first2, result1, result2, binary_pred,
           ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:232:12: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>>' requested here
    return reduce_by_segment(::std::forward<Policy>(policy), first1, last1, first2, result1, result2,
           ^
test.cpp:17:18: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *>' requested here
    oneapi::dpl::reduce_by_segment(oneapi::dpl::execution::par_unseq, a, a, b, a, b);
                 ^
In file included from test.cpp:2:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/execution:34:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/glue_algorithm_impl.h:26:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h:21:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/parallel_backend.h:19:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h:24:
In file included from /glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/../pstl/iterator_impl.h:24:
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/tuple_impl.h:266:31: error: binding reference of type 'unsigned long' to value of type 'const unsigned long' drops 'const' qualifier
    __value_holder(_Up&& t) : value(::std::forward<_Up>(t))
                              ^     ~~~~~~~~~~~~~~~~~~~~~~
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/tuple_impl.h:338:45: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__value_holder<unsigned long &>::__value_holder<const unsigned long &>' requested here
    tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next)
                                            ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/tuple_impl.h:338:78: note: in instantiation of function template specialization 'oneapi::dpl::__internal::tuple<unsigned long &>::tuple<unsigned long, void>' requested here
    tuple(const tuple<_U1, _U...>& other) : holder(other.template get<0>()), next(other.next)
                                                                             ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:188:21: note: in instantiation of function template specialization 'oneapi::dpl::__internal::tuple<unsigned long &, unsigned long &>::tuple<std::complex<double>, unsigned long, void>' requested here
        *__result = __init;
                    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:213:24: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__brick_transform_scan<oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::__internal::tuple<std::complex<double>, unsigned long>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>>' requested here
    return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
                       ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:264:36: note: in instantiation of function template specialization 'oneapi::dpl::__internal::__brick_transform_scan<oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::__internal::__no_op, oneapi::dpl::__internal::tuple<std::complex<double>, unsigned long>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>, std::integral_constant<bool, true>>' requested here
                return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op,
                                   ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/pstl/numeric_impl.h:322:16: note: (skipping 3 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
        return __pattern_transform_scan(::std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result,
               ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:109:5: note: in instantiation of function template specialization 'oneapi::dpl::inclusive_scan<oneapi::dpl::execution::parallel_unsequenced_policy &, oneapi::dpl::zip_iterator<std::complex<double> *, unsigned long *>, oneapi::dpl::zip_iterator<unsigned long *, unsigned long *>, oneapi::dpl::internal::segmented_scan_fun<std::complex<double>, unsigned long, std::plus<std::complex<double>>>>' requested here
    inclusive_scan(policy1, make_zip_iterator(first2, _mask.get()), make_zip_iterator(first2, _mask.get()) + n,
    ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:209:22: note: in instantiation of function template specialization 'oneapi::dpl::internal::reduce_by_segment_impl<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>, std::plus<std::complex<double>>>' requested here
    return internal::reduce_by_segment_impl(::std::forward<Policy>(policy), first1, last1, first2, result1, result2,
                     ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:221:12: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>, std::plus<std::complex<double>>>' requested here
    return reduce_by_segment(::std::forward<Policy>(policy), first1, last1, first2, result1, result2, binary_pred,
           ^
/glob/development-tools/versions/oneapi/2022.1.2/oneapi/dpl/2021.6.0/linux/include/oneapi/dpl/internal/reduce_by_segment_impl.h:232:12: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *, std::equal_to<int>>' requested here
    return reduce_by_segment(::std::forward<Policy>(policy), first1, last1, first2, result1, result2,
           ^
test.cpp:17:18: note: in instantiation of function template specialization 'oneapi::dpl::reduce_by_segment<const oneapi::dpl::execution::parallel_unsequenced_policy &, int *, std::complex<double> *, int *, std::complex<double> *>' requested here
    oneapi::dpl::reduce_by_segment(oneapi::dpl::execution::par_unseq, a, a, b, a, b);
                 ^
3 errors generated.

upsj avatar Feb 05 '22 01:02 upsj

Thank you for reporting, we will take a look.

SergeyKopienko avatar Feb 09 '22 09:02 SergeyKopienko

Investigated, we are working on a fix.

SergeyKopienko avatar Feb 14 '22 10:02 SergeyKopienko

Hi, Tobias This issue will be fixed in one of the next releases.

SergeyKopienko avatar Feb 24 '22 07:02 SergeyKopienko

@upsj, this issue were already fixed in https://github.com/oneapi-src/oneDPL/pull/505 Could you please confirm that now all is OK ? P.S. sorry for delay.

SergeyKopienko avatar Feb 10 '23 12:02 SergeyKopienko

@upsj, this issue were fixed in https://github.com/oneapi-src/oneDPL/pull/505 Thank you for info.

SergeyKopienko avatar Feb 15 '23 09:02 SergeyKopienko