So, maybe I’m trying to be too fancy for my own good but I’m trying to use make_transform_iterator on a zip_iterator and I have some questions about what seems like black magic performed by Thrust.
Namely, I’m instantiating the zip iterator like this:
auto const zip_begin = thrust::make_zip_iterator(
thrust::make_tuple(
thrust::device_ptr<int const>{pa},
thrust::device_ptr<int const>{la}));
where pa and la are defined as:
int const* __restrict__ pa,
int const* __restrict__ la
My function also has a constant int restricted pointer nm that I’m capturing in an extended lambda. My lambda is defined as:
auto fs = [=] __device__ (thrust::tuple<int const, int const> tup) -> int
{
int const pa_id = thrust::get<0>(tup);
int const la = thrust::get<1>(tup);
int const fracture_size = __popc(static_cast<unsigned int>(la)) - 1;
return nm[pa_id] * fracture_size;
};
I’m using this transformation so that I can do a super awesome exclusive_scan over a transformed pair of ranges of values like this:
auto const zip_begin = thrust::make_zip_iterator(
thrust::make_tuple(
thrust::device_ptr<int const>{pa},
thrust::device_ptr<int const>{la}));
auto const begin = thrust::make_transform_iterator(zip_begin, fs);
// perform our exclusive_scan and write the result to fl
thrust::exclusive_scan(
thrust::device,
begin, begin + assoc_size,
fl);
My surprise comes from the fact that I’m defining the zip iterator with a tuple of device_ptr but then in my lambda, the argument I’m accepting is a tuple of values! How does Thrust know how to do that?
For reference, here’s my source file and here’s the test that proves it gives the output I want.