0

When using odeint with thrust, I am developing an observer that will generate a histogram of state-variables while solving many initial condition problems in parallel.

The initial conditions problems run in parallel, populating a device_vector with the data like this.

Trajectory 0, Variable 0, Histogram Bin 0;
Trajectory 0, Variable 0, Histogram Bin 1;
...
Trajectory 0, Variable 1, Histogram Bin 0;
Trajectory 0, Variable 1, Histogram Bin 1;
...
Trajectory 1, Variable 0, Histogram Bin 0;
Trajectory 1, Variable 0, Histogram Bin 1;
...

Or, put more concisely, the indexing of the array will be calculated according to:

trajectoryIndex*N_BINS*N_VARS +varIndex*N_BINS +binIndex

... and later, this vector will be reduced to one histogram for each variable.

The paradigm that I have seen used in odeint + thrust is to have the operator functor called using thrust's make_zip_iterator and make_tuple, thus:

thrust::for_each(
    thrust::make_zip_iterator(
        thrust::make_tuple(
            boost::begin( x ) + 0*m_N,
            boost::begin( x ) + 1*m_N
        ),
    thrust::make_zip_iterator(
        thrust::make_tuple(
            boost::begin( x ) + 1*m_N,
            boost::begin( x ) + 2*m_N
        ),
    observer_functor()
);

which works great when the arguments to the functor are all of the same length. But in my case the histogram-data device_vector that is to be populated as described above is of a different size, and needs to be indexed differently than the other arguments given to the functor (e.g. the state-variables).

Having looked around a bit, I think that the best way to do this is to pass a thrust::counting_iterator that provides the functor with the trajectory-index needed to populate the histogram matrix. I then would also (obviously) have to somehow provide a pointer to the histogram matrix so that it can be populated. Perhaps the best solution for providing the observer_functor with the pointer to the histogram vector would be to provide it as an argument to the constructor of the observer (similar to the solution of another question I posted here).

All of this raised some confusion about how the arrays in the make_zip_iterator / make_tuple paradigm above work when the passed arguments indicate vectors of different length.

QUESTIONS:

  1. Is my proposed use of thrust::counting_iterator and passing a pointer to the output array via the constructor of the functor object the recommended approach?

  2. More generally, how does the make_zip_iterator / make_tuple paradigm above work when the passed arguments indicate vectors of different length?

Community
  • 1
  • 1
weemattisnot
  • 889
  • 5
  • 16
  • Your problem sound more like a reduce or one of its variants. Have a look at the Thrust documentation, they provide a lot of examples. – headmyshoulder Sep 08 '14 at 20:57
  • Another question: Do you need to store the bin data? Isn't it sufficient to calculate the bin number for each variable in each trajectory? Hence you can have transform which maps trajectory_i and variable_j onto the current bin, which is simply an integer. Finally you need to reduce all the bins into final histogram. – headmyshoulder Sep 09 '14 at 07:43
  • You are right that there is a reduction in this problem, (I mention that in the q). But the reduction happens at the end of gathering all of the histogram data. (At least that is how I do it). I am not sure I understand your 2nd comment, but perhaps this clarifies things: the goal is to count the total number of steps that each variable has been in each of its bins. If I have 10 bins for each variable, and 2 variables, I will have at the end 20 values, not 100. My question above is about the best practice for referring to the trajectory index from within the functor. – weemattisnot Sep 09 '14 at 14:57
  • Hmm, I don't understand what the third column in you data layout means. I would expect traj0, var0, binnumber; trac0, var1, binnumber; trac0, var2, binnumber; ...; trac1, var0, binnumber, ... – headmyshoulder Sep 09 '14 at 18:58
  • Each row represents a single data point in the vector, and the third column is just as you have written, the bin number. – weemattisnot Sep 09 '14 at 19:01
  • Shouldn't the indexing then be trajectoryIndex*N_VARS +varIndex. Why do you need the bin index in this data layout? – headmyshoulder Sep 09 '14 at 21:14
  • No, I need to keep a count for how many iterations each variable has been in each bin. – weemattisnot Sep 10 '14 at 19:43

0 Answers0