GCC 6.4 and 7.3 choke on `op::transform` due to failed conversion to `time_single_deferred`
Closed this issue · 3 comments
When building pushmi's examples and tests with GCC 6.4 and GCC 7.3, the compiler chokes on any code that uses op::transform
.
Here's the full log for:
The point of failure for GCC 6.4:
/home/wash/development/iso-c++/pushmi/include/pushmi/o/transform.h:53:31: error: could not convert ‘f’ from ‘const pushmi::overload_fn<p1055::twoway_execute(Executor&&, Function&&) [with Executor = pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>; Function = main()::<lambda()>]::<lambda(auto:71)> >’ to ‘pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>’
::pushmi::on_value(
~~~~~~~~~~~~~~~~~~^
transform_on_value<F>{f}
~~~~~~~~~~~~~~~~~~~~~~~~
// [f](Out& out, auto&& v) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// using V = decltype(v);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
// using Result = decltype(f((V&&) v));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// static_assert(::pushmi::SemiMovable<Result>,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// "none of the functions supplied to transform can convert this value");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// static_assert(::pushmi::SingleReceiver<Out, Result>,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// "Result of value transform cannot be delivered to Out");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ::pushmi::set_value(out, f((V&&) v));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// }
~~~~
)
~
and for GCC 7.3:
/home/wash/development/iso-c++/pushmi/include/pushmi/o/../piping.h:9:1: required by substitution of ‘template<class In, class Op, int (* _pushmi_concept_unique_10)[89], typename std::enable_if<(_pushmi_concept_unique_10 || (bool)(Invocable<Op&, In>)), int>::type <anonymous> > decltype(auto) operator|(In&&, Op) [with In = pushmi::time_single_deferred<pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>, pushmi::on_submit_fn<pushmi::detail::constrained_fn<pushmi::detail::submit_transform_out(FN)::<lambda(auto:23)> [with auto:23 = pushmi::detail::id_fn; In = pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>; FN = pushmi::detail::constrained_fn<pushmi::detail::transform_fn::operator()(FN ...) const::<lambda(auto:69)> [with auto:69 = pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>; FN = {p1055::twoway_execute(Executor&&, Function&&) [with Executor = pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>; Function = main()::<lambda()>]::<lambda(auto:71)>}]::<lambda(auto:70)>, pushmi::ReceiverConcept::Eval<pushmi::detail::placeholder [1]> >; int (* _pushmi_concept_unique_76)[97] = 0; typename std::enable_if<(_pushmi_concept_unique_76 || (bool)((Sender<In> && SemiMovable<FN>))), int>::type <anonymous> = 0]::<lambda(pushmi::time_single_deferred<pushmi::__pool_submit<std::experimental::executors_v1::static_thread_pool::executor_impl<std::experimental::executors_v1::execution::never_blocking_t, std::experimental::executors_v1::execution::not_continuation_t, std::experimental::executors_v1::execution::not_outstanding_work_t, std::allocator<void> > >, pushmi::systemNowF>&, auto:24, auto:25)>, pushmi::ReceiverConcept::Eval<pushmi::detail::placeholder [3]> > >, pushmi::passDNF>; Op = pushmi::detail::get_fn<int>; int (* _pushmi_concept_unique_10)[89] = 0; typename std::enable_if<(_pushmi_concept_unique_10 || (bool)(Invocable<Op&, In>)), int>::type <anonymous> = 0]’
/home/wash/development/iso-c++/pushmi/examples/twoway_execute/twoway_execute_2.cpp:66:63: required from here
/home/wash/development/iso-c++/pushmi/include/pushmi/o/transform.h:53:31: error: use of ‘f’ before deduction of ‘auto’
::pushmi::on_value(
~~~~~~~~~~~~~~~~~~^
transform_on_value<F>{f}
~~~~~~~~~~~~~~~~~~~~~~~~
// [f](Out& out, auto&& v) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// using V = decltype(v);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
// using Result = decltype(f((V&&) v));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// static_assert(::pushmi::SemiMovable<Result>,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// "none of the functions supplied to transform can convert this value");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// static_assert(::pushmi::SingleReceiver<Out, Result>,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// "Result of value transform cannot be delivered to Out");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ::pushmi::set_value(out, f((V&&) v));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// }
~~~~
)
~
I don't see the same issue when compiling with GCC 8.1.
Steps to reproduce:
cmake -DCMAKE_CXX_COMPILER=/path/to/gcc /path/to/pushmi
make
My only guess was that perhaps a make_time_single_deferred
was missing, but I don't think that's right.
Note: this is a problem because NVCC does not support GCC 8 yet, even internally. I could probably hack around it if absolutely needed.
It looks like another generic lambda issue. I had to manually create the transform_on_value to workaround an issue in cuda 9.2 with that particular lambda. I expect this will require that the containing generic lambda also be converted to a hand-built function object.
::pushmi::constrain(::pushmi::lazy::Receiver<::pushmi::_1>, [f](auto out) {. . .}
@brycelelbach Can you pull and try again?