-
Notifications
You must be signed in to change notification settings - Fork 757
transform_output_iterator (and transform_input_output_iterator) unusable with reduce_by_key
due to missing default constructor
#1804
Comments
I think you're right that the more fundamental problem is that There's no requirement on the Furthermore, making |
Upon reflection, it smells OK to me. Here's why.
I think the semantics are well defined as long as the adapted types and member data types are default constructible.
I would argue it's not uncommon for functors to be default constructible. Let's look at whether it's common for Thrust iterators to be default constructible.
|
Maybe, but this feels wrong:
fwiw, the choice to make it default constructible is orthogonal to the fact that it is definitely a bug in |
Agree on the second point. But iterators aside, a pointer is default constructible. That doesn't mean it's ok to dereference a default constructed pointer! User error. |
Filed #1812 to cover the reduce_by_key bug. |
I have been unable to use a
thrust::transform_output_iterator
as the output iterator forthrust::reduce_by_key
. After much head scratching and digging, I found the cause:Unlike all other Thrust iterators,
transform_output_iterator
andtransform_input_output_iterator
have no default constructor. Andreduce_by_key
constructs an empty pair or iterators for its result:thrust/thrust/system/cuda/detail/reduce_by_key.h
Line 1087 in d3e6fa1
If one of the types in the pair is a
transform_output_iterator
, compilation will fail with:error: no instance of constructor "thrust::transform_output_iterator<UnaryFunction, OutputIterator>::transform_output_iterator [with UnaryFunction = ...]" matches the argument list
.Here's a repro: https://godbolt.org/z/P98YYh1x1
We have found two ways to fix this. The simple way is to add the default constructor. Here's a demo of that. This has a namespace
thrust_fix
which has its owntransform_output_iterator
. https://godbolt.org/z/rK3Ec73bzAnother way is to change the scary self-referential macro
THRUST_INDEX_TYPE_DISPATCH
so that it doesn't require the "Initialize Then Modify" antipattern. Its approach of assigning to the result requires pre-declaring that result, which meansauto
can't be used.thrust/thrust/system/cuda/detail/dispatch.h
Lines 29 to 37 in d3e6fa1
(Not to mention that requiring the caller to inject the renamed
count_fixed
variable into the arguments list is uuuugly.)This could be done differently using an IILE:
This means we no longer have to pre-declare a pair of iterators in reduce_by_key. We just return directly:
There may be limitations of the lambda capture by reference used here that I haven't thought about, and this would impact a lot of Thrust code. So I recommend just adding the default constructors. :)
CC @isVoid
The text was updated successfully, but these errors were encountered: