Refactor DeviceScan implementation to allow InclusiveScan/Sum to take an initial value
- Dominant language
- C++
- Stars
- 2.5k
- Forks
- 487
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 296
Description
There was reported an issue regarding the internal accumulator type in `cub::DeviceScan::InclusiveSum`. The issue consists in using input data type as accumulator type. Here's the reproducer:
```cuda
#include
#include
int main()
{
thrust::device_vector d_in(260, 1);
thrust::device_vector d_out(260);
std::size_t temp_bytes {};
cub::DeviceScan::InclusiveSum(
nullptr,
temp_bytes,
thrust::raw_pointer_cast(d_in.data()),
thrust::raw_pointer_cast(d_out.data()),
d_in.size());
thrust::device_vector temp_storage(temp_bytes);
cub::DeviceScan::InclusiveSum(
thrust::raw_pointer_cast(temp_storage.data()),
temp_bytes,
thrust::raw_pointer_cast(d_in.data()),
thrust::raw_pointer_cast(d_out.data()),
d_in.size());
thrust::device_vector d_ref(260);
thrust::sequence(d_ref.begin(), d_ref.end(), 1);
if (d_ref != d_out)
{
std::cerr << "Wrong result!" << std::endl;
}
return 0;
}
```
The naive solution would be to [fix the output value type deduction](https://github.com/senior-zero/cub/commit/f412c92a02a6dc0ad9a9f17395ca0d564999f78e#). But this solution doesn't seem to conform STL:
```cuda
std::vector in(260, 1);
std::vector out(260, 1);
// Uses the decltype(*in) as accumulator type
// std::inclusive_scan(in.begin(), in.end(), out.begin());
std::inclusive_scan(in.begin(), in.end(), out.begin(), std::plus<>(), std::uint64_t{0});
std::vector reference(260);
std::iota(reference.begin(), reference.end(), 1);
for (std::size_t i = 0; i < reference.size(); i++)
{
if (out[i] != reference[i])
{
std::cerr << out[i] << " != " << reference[i] << std::endl;
}
}
```
Unlike STL we don't have a way to provide an `InitValue` into the algorithm. So, providing an `InitValue` might be a better way of addressing this issue.
Contributor guide
Assessment
This issue has not been assessed yet.