# Question about transform\_iterator of zip\_iterator!

**URL:** <https://forums.developer.nvidia.com/t/question-about-transform-iterator-of-zip-iterator/44599>\
**Category:** CUDA Programming and Performance\
**Created:** [August 28, 2016, 10:31pm UTC](https://forums.developer.nvidia.com/t/question-about-transform-iterator-of-zip-iterator/44599 "2016-08-28T22:31:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![MutantJohn](https://developer.download.nvidia.com/images/forums/profile-default-devtalk-84.png) [@MutantJohn](https://forums.developer.nvidia.com/u/MutantJohn)\
**Post date:** [August 28, 2016, 10:31pm UTC](https://forums.developer.nvidia.com/t/question-about-transform-iterator-of-zip-iterator/44599/1 "2016-08-28T22:31:03Z")

</div>

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
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:

```auto
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
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
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.

---

<div class="post-metadata">

**Author:** ![Robert\_Crovella](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/robert_crovella/32/14043_2.png) [@Robert\_Crovella](https://forums.developer.nvidia.com/u/Robert_Crovella)\
**Post date:** [August 28, 2016, 11:37pm UTC](https://forums.developer.nvidia.com/t/question-about-transform-iterator-of-zip-iterator/44599/2 "2016-08-28T23:37:34Z")

</div>

> [@](#):
>
> 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?

This is pretty much the way all thrust algorithms work. We declare the iterators involved, and thrust dereferences those iterators to produce the values that are consumed by the algorithms.

When you dereference a zip iterator, you produce a tuple (of values, or references to values).

In the case of a transform iterator as an argument to a thrust algorithm, the process is to dereference the iterator provided to the transform iterator, pass that tuple to the functor of the transform iterator (or in this case, the lambda), and then pass the value (or tuple) that results from the application of the functor, to the algorithm.

Maybe I am not understanding the question.

---

<div class="post-metadata">

**Author:** ![BulatZiganshin](https://developer.download.nvidia.com/images/forums/profile-default-devtalk-84.png) [@BulatZiganshin](https://forums.developer.nvidia.com/u/BulatZiganshin)\
**Post date:** [August 29, 2016, 7:00am UTC](https://forums.developer.nvidia.com/t/question-about-transform-iterator-of-zip-iterator/44599/3 "2016-08-29T07:00:20Z")

</div>

i think that abswer is overloading - thrust overloads the exclusive\_scan for tuple and in this particular code it dereferences both parts of the tuple

---

<div class="post-metadata">

**Author:** ![MutantJohn](https://developer.download.nvidia.com/images/forums/profile-default-devtalk-84.png) [@MutantJohn](https://forums.developer.nvidia.com/u/MutantJohn)\
**Post date:** [August 29, 2016, 2:58pm UTC](https://forums.developer.nvidia.com/t/question-about-transform-iterator-of-zip-iterator/44599/4 "2016-08-29T14:58:12Z")

</div>

> [@](#):
>
> Maybe I am not understanding the question.

I think I’m just amazed that it all… Well, that it all works. I do a lot of JavaScript development by day and there, I kind of type things and sort of just see what happens. I tried that here and I was able to ultimately do what I want.

I’m just surprised that Thrust does so much for you! I’m happy I got significantly better at C++ because, wow, I couldn’t imagine doing like half this code if it weren’t for Thrust to help me out along way.

Maybe this is actually just a fanboyism thread?
